1 /* Subroutines used for code generation on IBM RS/6000.
2 Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
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"
30 #include "insn-config.h"
31 #include "conditions.h"
32 #include "insn-attr.h"
42 #include "basic-block.h"
43 #include "integrate.h"
44 #include "diagnostic-core.h"
50 #include "target-def.h"
51 #include "langhooks.h"
53 #include "cfglayout.h"
54 #include "sched-int.h"
56 #include "tree-flow.h"
59 #include "tm-constrs.h"
61 #include "xcoffout.h" /* get declarations of xcoff_*_section_name */
64 #include "gstab.h" /* for N_SLINE */
67 #ifndef TARGET_NO_PROTOTYPE
68 #define TARGET_NO_PROTOTYPE 0
71 #define min(A,B) ((A) < (B) ? (A) : (B))
72 #define max(A,B) ((A) > (B) ? (A) : (B))
74 /* Structure used to define the rs6000 stack */
75 typedef struct rs6000_stack
{
76 int first_gp_reg_save
; /* first callee saved GP register used */
77 int first_fp_reg_save
; /* first callee saved FP register used */
78 int first_altivec_reg_save
; /* first callee saved AltiVec register used */
79 int lr_save_p
; /* true if the link reg needs to be saved */
80 int cr_save_p
; /* true if the CR reg needs to be saved */
81 unsigned int vrsave_mask
; /* mask of vec registers to save */
82 int push_p
; /* true if we need to allocate stack space */
83 int calls_p
; /* true if the function makes any calls */
84 int world_save_p
; /* true if we're saving *everything*:
85 r13-r31, cr, f14-f31, vrsave, v20-v31 */
86 enum rs6000_abi abi
; /* which ABI to use */
87 int gp_save_offset
; /* offset to save GP regs from initial SP */
88 int fp_save_offset
; /* offset to save FP regs from initial SP */
89 int altivec_save_offset
; /* offset to save AltiVec regs from initial SP */
90 int lr_save_offset
; /* offset to save LR from initial SP */
91 int cr_save_offset
; /* offset to save CR from initial SP */
92 int vrsave_save_offset
; /* offset to save VRSAVE from initial SP */
93 int spe_gp_save_offset
; /* offset to save spe 64-bit gprs */
94 int varargs_save_offset
; /* offset to save the varargs registers */
95 int ehrd_offset
; /* offset to EH return data */
96 int reg_size
; /* register size (4 or 8) */
97 HOST_WIDE_INT vars_size
; /* variable save area size */
98 int parm_size
; /* outgoing parameter size */
99 int save_size
; /* save area size */
100 int fixed_size
; /* fixed size of stack frame */
101 int gp_size
; /* size of saved GP registers */
102 int fp_size
; /* size of saved FP registers */
103 int altivec_size
; /* size of saved AltiVec registers */
104 int cr_size
; /* size to hold CR if not in save_size */
105 int vrsave_size
; /* size to hold VRSAVE if not in save_size */
106 int altivec_padding_size
; /* size of altivec alignment padding if
108 int spe_gp_size
; /* size of 64-bit GPR save size for SPE */
109 int spe_padding_size
;
110 HOST_WIDE_INT total_size
; /* total bytes allocated for stack */
111 int spe_64bit_regs_used
;
114 /* A C structure for machine-specific, per-function data.
115 This is added to the cfun structure. */
116 typedef struct GTY(()) machine_function
118 /* Some local-dynamic symbol. */
119 const char *some_ld_name
;
120 /* Whether the instruction chain has been scanned already. */
121 int insn_chain_scanned_p
;
122 /* Flags if __builtin_return_address (n) with n >= 1 was used. */
123 int ra_needs_full_frame
;
124 /* Flags if __builtin_return_address (0) was used. */
126 /* Cache lr_save_p after expansion of builtin_eh_return. */
128 /* Offset from virtual_stack_vars_rtx to the start of the ABI_V4
129 varargs save area. */
130 HOST_WIDE_INT varargs_save_offset
;
131 /* Temporary stack slot to use for SDmode copies. This slot is
132 64-bits wide and is allocated early enough so that the offset
133 does not overflow the 16-bit load/store offset field. */
134 rtx sdmode_stack_slot
;
137 /* Target cpu type */
139 enum processor_type rs6000_cpu
;
140 struct rs6000_cpu_select rs6000_select
[3] =
142 /* switch name, tune arch */
143 { (const char *)0, "--with-cpu=", 1, 1 },
144 { (const char *)0, "-mcpu=", 1, 1 },
145 { (const char *)0, "-mtune=", 1, 0 },
148 /* Always emit branch hint bits. */
149 static GTY(()) bool rs6000_always_hint
;
151 /* Schedule instructions for group formation. */
152 static GTY(()) bool rs6000_sched_groups
;
154 /* Align branch targets. */
155 static GTY(()) bool rs6000_align_branch_targets
;
157 /* Support for -msched-costly-dep option. */
158 const char *rs6000_sched_costly_dep_str
;
159 enum rs6000_dependence_cost rs6000_sched_costly_dep
;
161 /* Support for -minsert-sched-nops option. */
162 const char *rs6000_sched_insert_nops_str
;
163 enum rs6000_nop_insertion rs6000_sched_insert_nops
;
165 /* Support targetm.vectorize.builtin_mask_for_load. */
166 static GTY(()) tree altivec_builtin_mask_for_load
;
168 /* Size of long double. */
169 int rs6000_long_double_type_size
;
171 /* IEEE quad extended precision long double. */
174 /* Nonzero to use AltiVec ABI. */
175 int rs6000_altivec_abi
;
177 /* Nonzero if we want SPE SIMD instructions. */
180 /* Nonzero if we want SPE ABI extensions. */
183 /* Nonzero if floating point operations are done in the GPRs. */
184 int rs6000_float_gprs
= 0;
186 /* Nonzero if we want Darwin's struct-by-value-in-regs ABI. */
187 int rs6000_darwin64_abi
;
189 /* Set to nonzero once AIX common-mode calls have been defined. */
190 static GTY(()) int common_mode_defined
;
192 /* Label number of label created for -mrelocatable, to call to so we can
193 get the address of the GOT section */
194 int rs6000_pic_labelno
;
197 /* Which abi to adhere to */
198 const char *rs6000_abi_name
;
200 /* Semantics of the small data area */
201 enum rs6000_sdata_type rs6000_sdata
= SDATA_DATA
;
203 /* Which small data model to use */
204 const char *rs6000_sdata_name
= (char *)0;
206 /* Counter for labels which are to be placed in .fixup. */
207 int fixuplabelno
= 0;
210 /* Bit size of immediate TLS offsets and string from which it is decoded. */
211 int rs6000_tls_size
= 32;
212 const char *rs6000_tls_size_string
;
214 /* ABI enumeration available for subtarget to use. */
215 enum rs6000_abi rs6000_current_abi
;
217 /* Whether to use variant of AIX ABI for PowerPC64 Linux. */
221 const char *rs6000_debug_name
;
222 int rs6000_debug_stack
; /* debug stack applications */
223 int rs6000_debug_arg
; /* debug argument handling */
224 int rs6000_debug_reg
; /* debug register classes */
225 int rs6000_debug_addr
; /* debug memory addressing */
226 int rs6000_debug_cost
; /* debug rtx_costs */
228 /* Specify the machine mode that pointers have. After generation of rtl, the
229 compiler makes no further distinction between pointers and any other objects
230 of this machine mode. The type is unsigned since not all things that
231 include rs6000.h also include machmode.h. */
232 unsigned rs6000_pmode
;
234 /* Width in bits of a pointer. */
235 unsigned rs6000_pointer_size
;
238 /* Value is TRUE if register/mode pair is acceptable. */
239 bool rs6000_hard_regno_mode_ok_p
[NUM_MACHINE_MODES
][FIRST_PSEUDO_REGISTER
];
241 /* Maximum number of registers needed for a given register class and mode. */
242 unsigned char rs6000_class_max_nregs
[NUM_MACHINE_MODES
][LIM_REG_CLASSES
];
244 /* How many registers are needed for a given register and mode. */
245 unsigned char rs6000_hard_regno_nregs
[NUM_MACHINE_MODES
][FIRST_PSEUDO_REGISTER
];
247 /* Map register number to register class. */
248 enum reg_class rs6000_regno_regclass
[FIRST_PSEUDO_REGISTER
];
250 /* Reload functions based on the type and the vector unit. */
251 static enum insn_code rs6000_vector_reload
[NUM_MACHINE_MODES
][2];
253 /* Built in types. */
254 tree rs6000_builtin_types
[RS6000_BTI_MAX
];
255 tree rs6000_builtin_decls
[RS6000_BUILTIN_COUNT
];
257 const char *rs6000_traceback_name
;
259 traceback_default
= 0,
265 /* Flag to say the TOC is initialized */
267 char toc_label_name
[10];
269 /* Cached value of rs6000_variable_issue. This is cached in
270 rs6000_variable_issue hook and returned from rs6000_sched_reorder2. */
271 static short cached_can_issue_more
;
273 static GTY(()) section
*read_only_data_section
;
274 static GTY(()) section
*private_data_section
;
275 static GTY(()) section
*read_only_private_data_section
;
276 static GTY(()) section
*sdata2_section
;
277 static GTY(()) section
*toc_section
;
279 /* Control alignment for fields within structures. */
280 /* String from -malign-XXXXX. */
281 int rs6000_alignment_flags
;
283 /* Code model for 64-bit linux. */
284 enum rs6000_cmodel cmodel
;
286 /* True for any options that were explicitly set. */
288 bool aix_struct_ret
; /* True if -maix-struct-ret was used. */
289 bool alignment
; /* True if -malign- was used. */
290 bool spe_abi
; /* True if -mabi=spe/no-spe was used. */
291 bool altivec_abi
; /* True if -mabi=altivec/no-altivec used. */
292 bool spe
; /* True if -mspe= was used. */
293 bool float_gprs
; /* True if -mfloat-gprs= was used. */
294 bool long_double
; /* True if -mlong-double- was used. */
295 bool ieee
; /* True if -mabi=ieee/ibmlongdouble used. */
296 bool vrsave
; /* True if -mvrsave was used. */
297 bool cmodel
; /* True if -mcmodel was used. */
298 } rs6000_explicit_options
;
300 struct builtin_description
302 /* mask is not const because we're going to alter it below. This
303 nonsense will go away when we rewrite the -march infrastructure
304 to give us more target flag bits. */
306 const enum insn_code icode
;
307 const char *const name
;
308 const enum rs6000_builtins code
;
311 /* Describe the vector unit used for modes. */
312 enum rs6000_vector rs6000_vector_unit
[NUM_MACHINE_MODES
];
313 enum rs6000_vector rs6000_vector_mem
[NUM_MACHINE_MODES
];
315 /* Register classes for various constraints that are based on the target
317 enum reg_class rs6000_constraints
[RS6000_CONSTRAINT_MAX
];
319 /* Describe the alignment of a vector. */
320 int rs6000_vector_align
[NUM_MACHINE_MODES
];
322 /* Map selected modes to types for builtins. */
323 static GTY(()) tree builtin_mode_to_type
[MAX_MACHINE_MODE
][2];
325 /* What modes to automatically generate reciprocal divide estimate (fre) and
326 reciprocal sqrt (frsqrte) for. */
327 unsigned char rs6000_recip_bits
[MAX_MACHINE_MODE
];
329 /* Masks to determine which reciprocal esitmate instructions to generate
331 enum rs6000_recip_mask
{
332 RECIP_SF_DIV
= 0x001, /* Use divide estimate */
333 RECIP_DF_DIV
= 0x002,
334 RECIP_V4SF_DIV
= 0x004,
335 RECIP_V2DF_DIV
= 0x008,
337 RECIP_SF_RSQRT
= 0x010, /* Use reciprocal sqrt estimate. */
338 RECIP_DF_RSQRT
= 0x020,
339 RECIP_V4SF_RSQRT
= 0x040,
340 RECIP_V2DF_RSQRT
= 0x080,
342 /* Various combination of flags for -mrecip=xxx. */
344 RECIP_ALL
= (RECIP_SF_DIV
| RECIP_DF_DIV
| RECIP_V4SF_DIV
345 | RECIP_V2DF_DIV
| RECIP_SF_RSQRT
| RECIP_DF_RSQRT
346 | RECIP_V4SF_RSQRT
| RECIP_V2DF_RSQRT
),
348 RECIP_HIGH_PRECISION
= RECIP_ALL
,
350 /* On low precision machines like the power5, don't enable double precision
351 reciprocal square root estimate, since it isn't accurate enough. */
352 RECIP_LOW_PRECISION
= (RECIP_ALL
& ~(RECIP_DF_RSQRT
| RECIP_V2DF_RSQRT
))
355 static unsigned int rs6000_recip_control
;
356 static const char *rs6000_recip_name
;
358 /* -mrecip options. */
361 const char *string
; /* option name */
362 unsigned int mask
; /* mask bits to set */
363 } recip_options
[] = {
364 { "all", RECIP_ALL
},
365 { "none", RECIP_NONE
},
366 { "div", (RECIP_SF_DIV
| RECIP_DF_DIV
| RECIP_V4SF_DIV
368 { "divf", (RECIP_SF_DIV
| RECIP_V4SF_DIV
) },
369 { "divd", (RECIP_DF_DIV
| RECIP_V2DF_DIV
) },
370 { "rsqrt", (RECIP_SF_RSQRT
| RECIP_DF_RSQRT
| RECIP_V4SF_RSQRT
371 | RECIP_V2DF_RSQRT
) },
372 { "rsqrtf", (RECIP_SF_RSQRT
| RECIP_V4SF_RSQRT
) },
373 { "rsqrtd", (RECIP_DF_RSQRT
| RECIP_V2DF_RSQRT
) },
376 /* 2 argument gen function typedef. */
377 typedef rtx (*gen_2arg_fn_t
) (rtx
, rtx
, rtx
);
380 /* Target cpu costs. */
382 struct processor_costs
{
383 const int mulsi
; /* cost of SImode multiplication. */
384 const int mulsi_const
; /* cost of SImode multiplication by constant. */
385 const int mulsi_const9
; /* cost of SImode mult by short constant. */
386 const int muldi
; /* cost of DImode multiplication. */
387 const int divsi
; /* cost of SImode division. */
388 const int divdi
; /* cost of DImode division. */
389 const int fp
; /* cost of simple SFmode and DFmode insns. */
390 const int dmul
; /* cost of DFmode multiplication (and fmadd). */
391 const int sdiv
; /* cost of SFmode division (fdivs). */
392 const int ddiv
; /* cost of DFmode division (fdiv). */
393 const int cache_line_size
; /* cache line size in bytes. */
394 const int l1_cache_size
; /* size of l1 cache, in kilobytes. */
395 const int l2_cache_size
; /* size of l2 cache, in kilobytes. */
396 const int simultaneous_prefetches
; /* number of parallel prefetch
400 const struct processor_costs
*rs6000_cost
;
402 /* Processor costs (relative to an add) */
404 /* Instruction size costs on 32bit processors. */
406 struct processor_costs size32_cost
= {
407 COSTS_N_INSNS (1), /* mulsi */
408 COSTS_N_INSNS (1), /* mulsi_const */
409 COSTS_N_INSNS (1), /* mulsi_const9 */
410 COSTS_N_INSNS (1), /* muldi */
411 COSTS_N_INSNS (1), /* divsi */
412 COSTS_N_INSNS (1), /* divdi */
413 COSTS_N_INSNS (1), /* fp */
414 COSTS_N_INSNS (1), /* dmul */
415 COSTS_N_INSNS (1), /* sdiv */
416 COSTS_N_INSNS (1), /* ddiv */
423 /* Instruction size costs on 64bit processors. */
425 struct processor_costs size64_cost
= {
426 COSTS_N_INSNS (1), /* mulsi */
427 COSTS_N_INSNS (1), /* mulsi_const */
428 COSTS_N_INSNS (1), /* mulsi_const9 */
429 COSTS_N_INSNS (1), /* muldi */
430 COSTS_N_INSNS (1), /* divsi */
431 COSTS_N_INSNS (1), /* divdi */
432 COSTS_N_INSNS (1), /* fp */
433 COSTS_N_INSNS (1), /* dmul */
434 COSTS_N_INSNS (1), /* sdiv */
435 COSTS_N_INSNS (1), /* ddiv */
442 /* Instruction costs on RIOS1 processors. */
444 struct processor_costs rios1_cost
= {
445 COSTS_N_INSNS (5), /* mulsi */
446 COSTS_N_INSNS (4), /* mulsi_const */
447 COSTS_N_INSNS (3), /* mulsi_const9 */
448 COSTS_N_INSNS (5), /* muldi */
449 COSTS_N_INSNS (19), /* divsi */
450 COSTS_N_INSNS (19), /* divdi */
451 COSTS_N_INSNS (2), /* fp */
452 COSTS_N_INSNS (2), /* dmul */
453 COSTS_N_INSNS (19), /* sdiv */
454 COSTS_N_INSNS (19), /* ddiv */
455 128, /* cache line size */
461 /* Instruction costs on RIOS2 processors. */
463 struct processor_costs rios2_cost
= {
464 COSTS_N_INSNS (2), /* mulsi */
465 COSTS_N_INSNS (2), /* mulsi_const */
466 COSTS_N_INSNS (2), /* mulsi_const9 */
467 COSTS_N_INSNS (2), /* muldi */
468 COSTS_N_INSNS (13), /* divsi */
469 COSTS_N_INSNS (13), /* divdi */
470 COSTS_N_INSNS (2), /* fp */
471 COSTS_N_INSNS (2), /* dmul */
472 COSTS_N_INSNS (17), /* sdiv */
473 COSTS_N_INSNS (17), /* ddiv */
474 256, /* cache line size */
480 /* Instruction costs on RS64A processors. */
482 struct processor_costs rs64a_cost
= {
483 COSTS_N_INSNS (20), /* mulsi */
484 COSTS_N_INSNS (12), /* mulsi_const */
485 COSTS_N_INSNS (8), /* mulsi_const9 */
486 COSTS_N_INSNS (34), /* muldi */
487 COSTS_N_INSNS (65), /* divsi */
488 COSTS_N_INSNS (67), /* divdi */
489 COSTS_N_INSNS (4), /* fp */
490 COSTS_N_INSNS (4), /* dmul */
491 COSTS_N_INSNS (31), /* sdiv */
492 COSTS_N_INSNS (31), /* ddiv */
493 128, /* cache line size */
499 /* Instruction costs on MPCCORE processors. */
501 struct processor_costs mpccore_cost
= {
502 COSTS_N_INSNS (2), /* mulsi */
503 COSTS_N_INSNS (2), /* mulsi_const */
504 COSTS_N_INSNS (2), /* mulsi_const9 */
505 COSTS_N_INSNS (2), /* muldi */
506 COSTS_N_INSNS (6), /* divsi */
507 COSTS_N_INSNS (6), /* divdi */
508 COSTS_N_INSNS (4), /* fp */
509 COSTS_N_INSNS (5), /* dmul */
510 COSTS_N_INSNS (10), /* sdiv */
511 COSTS_N_INSNS (17), /* ddiv */
512 32, /* cache line size */
518 /* Instruction costs on PPC403 processors. */
520 struct processor_costs ppc403_cost
= {
521 COSTS_N_INSNS (4), /* mulsi */
522 COSTS_N_INSNS (4), /* mulsi_const */
523 COSTS_N_INSNS (4), /* mulsi_const9 */
524 COSTS_N_INSNS (4), /* muldi */
525 COSTS_N_INSNS (33), /* divsi */
526 COSTS_N_INSNS (33), /* divdi */
527 COSTS_N_INSNS (11), /* fp */
528 COSTS_N_INSNS (11), /* dmul */
529 COSTS_N_INSNS (11), /* sdiv */
530 COSTS_N_INSNS (11), /* ddiv */
531 32, /* cache line size */
537 /* Instruction costs on PPC405 processors. */
539 struct processor_costs ppc405_cost
= {
540 COSTS_N_INSNS (5), /* mulsi */
541 COSTS_N_INSNS (4), /* mulsi_const */
542 COSTS_N_INSNS (3), /* mulsi_const9 */
543 COSTS_N_INSNS (5), /* muldi */
544 COSTS_N_INSNS (35), /* divsi */
545 COSTS_N_INSNS (35), /* divdi */
546 COSTS_N_INSNS (11), /* fp */
547 COSTS_N_INSNS (11), /* dmul */
548 COSTS_N_INSNS (11), /* sdiv */
549 COSTS_N_INSNS (11), /* ddiv */
550 32, /* cache line size */
556 /* Instruction costs on PPC440 processors. */
558 struct processor_costs ppc440_cost
= {
559 COSTS_N_INSNS (3), /* mulsi */
560 COSTS_N_INSNS (2), /* mulsi_const */
561 COSTS_N_INSNS (2), /* mulsi_const9 */
562 COSTS_N_INSNS (3), /* muldi */
563 COSTS_N_INSNS (34), /* divsi */
564 COSTS_N_INSNS (34), /* divdi */
565 COSTS_N_INSNS (5), /* fp */
566 COSTS_N_INSNS (5), /* dmul */
567 COSTS_N_INSNS (19), /* sdiv */
568 COSTS_N_INSNS (33), /* ddiv */
569 32, /* cache line size */
575 /* Instruction costs on PPC476 processors. */
577 struct processor_costs ppc476_cost
= {
578 COSTS_N_INSNS (4), /* mulsi */
579 COSTS_N_INSNS (4), /* mulsi_const */
580 COSTS_N_INSNS (4), /* mulsi_const9 */
581 COSTS_N_INSNS (4), /* muldi */
582 COSTS_N_INSNS (11), /* divsi */
583 COSTS_N_INSNS (11), /* divdi */
584 COSTS_N_INSNS (6), /* fp */
585 COSTS_N_INSNS (6), /* dmul */
586 COSTS_N_INSNS (19), /* sdiv */
587 COSTS_N_INSNS (33), /* ddiv */
588 32, /* l1 cache line size */
594 /* Instruction costs on PPC601 processors. */
596 struct processor_costs ppc601_cost
= {
597 COSTS_N_INSNS (5), /* mulsi */
598 COSTS_N_INSNS (5), /* mulsi_const */
599 COSTS_N_INSNS (5), /* mulsi_const9 */
600 COSTS_N_INSNS (5), /* muldi */
601 COSTS_N_INSNS (36), /* divsi */
602 COSTS_N_INSNS (36), /* divdi */
603 COSTS_N_INSNS (4), /* fp */
604 COSTS_N_INSNS (5), /* dmul */
605 COSTS_N_INSNS (17), /* sdiv */
606 COSTS_N_INSNS (31), /* ddiv */
607 32, /* cache line size */
613 /* Instruction costs on PPC603 processors. */
615 struct processor_costs ppc603_cost
= {
616 COSTS_N_INSNS (5), /* mulsi */
617 COSTS_N_INSNS (3), /* mulsi_const */
618 COSTS_N_INSNS (2), /* mulsi_const9 */
619 COSTS_N_INSNS (5), /* muldi */
620 COSTS_N_INSNS (37), /* divsi */
621 COSTS_N_INSNS (37), /* divdi */
622 COSTS_N_INSNS (3), /* fp */
623 COSTS_N_INSNS (4), /* dmul */
624 COSTS_N_INSNS (18), /* sdiv */
625 COSTS_N_INSNS (33), /* ddiv */
626 32, /* cache line size */
632 /* Instruction costs on PPC604 processors. */
634 struct processor_costs ppc604_cost
= {
635 COSTS_N_INSNS (4), /* mulsi */
636 COSTS_N_INSNS (4), /* mulsi_const */
637 COSTS_N_INSNS (4), /* mulsi_const9 */
638 COSTS_N_INSNS (4), /* muldi */
639 COSTS_N_INSNS (20), /* divsi */
640 COSTS_N_INSNS (20), /* divdi */
641 COSTS_N_INSNS (3), /* fp */
642 COSTS_N_INSNS (3), /* dmul */
643 COSTS_N_INSNS (18), /* sdiv */
644 COSTS_N_INSNS (32), /* ddiv */
645 32, /* cache line size */
651 /* Instruction costs on PPC604e processors. */
653 struct processor_costs ppc604e_cost
= {
654 COSTS_N_INSNS (2), /* mulsi */
655 COSTS_N_INSNS (2), /* mulsi_const */
656 COSTS_N_INSNS (2), /* mulsi_const9 */
657 COSTS_N_INSNS (2), /* muldi */
658 COSTS_N_INSNS (20), /* divsi */
659 COSTS_N_INSNS (20), /* divdi */
660 COSTS_N_INSNS (3), /* fp */
661 COSTS_N_INSNS (3), /* dmul */
662 COSTS_N_INSNS (18), /* sdiv */
663 COSTS_N_INSNS (32), /* ddiv */
664 32, /* cache line size */
670 /* Instruction costs on PPC620 processors. */
672 struct processor_costs ppc620_cost
= {
673 COSTS_N_INSNS (5), /* mulsi */
674 COSTS_N_INSNS (4), /* mulsi_const */
675 COSTS_N_INSNS (3), /* mulsi_const9 */
676 COSTS_N_INSNS (7), /* muldi */
677 COSTS_N_INSNS (21), /* divsi */
678 COSTS_N_INSNS (37), /* divdi */
679 COSTS_N_INSNS (3), /* fp */
680 COSTS_N_INSNS (3), /* dmul */
681 COSTS_N_INSNS (18), /* sdiv */
682 COSTS_N_INSNS (32), /* ddiv */
683 128, /* cache line size */
689 /* Instruction costs on PPC630 processors. */
691 struct processor_costs ppc630_cost
= {
692 COSTS_N_INSNS (5), /* mulsi */
693 COSTS_N_INSNS (4), /* mulsi_const */
694 COSTS_N_INSNS (3), /* mulsi_const9 */
695 COSTS_N_INSNS (7), /* muldi */
696 COSTS_N_INSNS (21), /* divsi */
697 COSTS_N_INSNS (37), /* divdi */
698 COSTS_N_INSNS (3), /* fp */
699 COSTS_N_INSNS (3), /* dmul */
700 COSTS_N_INSNS (17), /* sdiv */
701 COSTS_N_INSNS (21), /* ddiv */
702 128, /* cache line size */
708 /* Instruction costs on Cell processor. */
709 /* COSTS_N_INSNS (1) ~ one add. */
711 struct processor_costs ppccell_cost
= {
712 COSTS_N_INSNS (9/2)+2, /* mulsi */
713 COSTS_N_INSNS (6/2), /* mulsi_const */
714 COSTS_N_INSNS (6/2), /* mulsi_const9 */
715 COSTS_N_INSNS (15/2)+2, /* muldi */
716 COSTS_N_INSNS (38/2), /* divsi */
717 COSTS_N_INSNS (70/2), /* divdi */
718 COSTS_N_INSNS (10/2), /* fp */
719 COSTS_N_INSNS (10/2), /* dmul */
720 COSTS_N_INSNS (74/2), /* sdiv */
721 COSTS_N_INSNS (74/2), /* ddiv */
722 128, /* cache line size */
728 /* Instruction costs on PPC750 and PPC7400 processors. */
730 struct processor_costs ppc750_cost
= {
731 COSTS_N_INSNS (5), /* mulsi */
732 COSTS_N_INSNS (3), /* mulsi_const */
733 COSTS_N_INSNS (2), /* mulsi_const9 */
734 COSTS_N_INSNS (5), /* muldi */
735 COSTS_N_INSNS (17), /* divsi */
736 COSTS_N_INSNS (17), /* divdi */
737 COSTS_N_INSNS (3), /* fp */
738 COSTS_N_INSNS (3), /* dmul */
739 COSTS_N_INSNS (17), /* sdiv */
740 COSTS_N_INSNS (31), /* ddiv */
741 32, /* cache line size */
747 /* Instruction costs on PPC7450 processors. */
749 struct processor_costs ppc7450_cost
= {
750 COSTS_N_INSNS (4), /* mulsi */
751 COSTS_N_INSNS (3), /* mulsi_const */
752 COSTS_N_INSNS (3), /* mulsi_const9 */
753 COSTS_N_INSNS (4), /* muldi */
754 COSTS_N_INSNS (23), /* divsi */
755 COSTS_N_INSNS (23), /* divdi */
756 COSTS_N_INSNS (5), /* fp */
757 COSTS_N_INSNS (5), /* dmul */
758 COSTS_N_INSNS (21), /* sdiv */
759 COSTS_N_INSNS (35), /* ddiv */
760 32, /* cache line size */
766 /* Instruction costs on PPC8540 processors. */
768 struct processor_costs ppc8540_cost
= {
769 COSTS_N_INSNS (4), /* mulsi */
770 COSTS_N_INSNS (4), /* mulsi_const */
771 COSTS_N_INSNS (4), /* mulsi_const9 */
772 COSTS_N_INSNS (4), /* muldi */
773 COSTS_N_INSNS (19), /* divsi */
774 COSTS_N_INSNS (19), /* divdi */
775 COSTS_N_INSNS (4), /* fp */
776 COSTS_N_INSNS (4), /* dmul */
777 COSTS_N_INSNS (29), /* sdiv */
778 COSTS_N_INSNS (29), /* ddiv */
779 32, /* cache line size */
782 1, /* prefetch streams /*/
785 /* Instruction costs on E300C2 and E300C3 cores. */
787 struct processor_costs ppce300c2c3_cost
= {
788 COSTS_N_INSNS (4), /* mulsi */
789 COSTS_N_INSNS (4), /* mulsi_const */
790 COSTS_N_INSNS (4), /* mulsi_const9 */
791 COSTS_N_INSNS (4), /* muldi */
792 COSTS_N_INSNS (19), /* divsi */
793 COSTS_N_INSNS (19), /* divdi */
794 COSTS_N_INSNS (3), /* fp */
795 COSTS_N_INSNS (4), /* dmul */
796 COSTS_N_INSNS (18), /* sdiv */
797 COSTS_N_INSNS (33), /* ddiv */
801 1, /* prefetch streams /*/
804 /* Instruction costs on PPCE500MC processors. */
806 struct processor_costs ppce500mc_cost
= {
807 COSTS_N_INSNS (4), /* mulsi */
808 COSTS_N_INSNS (4), /* mulsi_const */
809 COSTS_N_INSNS (4), /* mulsi_const9 */
810 COSTS_N_INSNS (4), /* muldi */
811 COSTS_N_INSNS (14), /* divsi */
812 COSTS_N_INSNS (14), /* divdi */
813 COSTS_N_INSNS (8), /* fp */
814 COSTS_N_INSNS (10), /* dmul */
815 COSTS_N_INSNS (36), /* sdiv */
816 COSTS_N_INSNS (66), /* ddiv */
817 64, /* cache line size */
820 1, /* prefetch streams /*/
823 /* Instruction costs on PPCE500MC64 processors. */
825 struct processor_costs ppce500mc64_cost
= {
826 COSTS_N_INSNS (4), /* mulsi */
827 COSTS_N_INSNS (4), /* mulsi_const */
828 COSTS_N_INSNS (4), /* mulsi_const9 */
829 COSTS_N_INSNS (4), /* muldi */
830 COSTS_N_INSNS (14), /* divsi */
831 COSTS_N_INSNS (14), /* divdi */
832 COSTS_N_INSNS (4), /* fp */
833 COSTS_N_INSNS (10), /* dmul */
834 COSTS_N_INSNS (36), /* sdiv */
835 COSTS_N_INSNS (66), /* ddiv */
836 64, /* cache line size */
839 1, /* prefetch streams /*/
842 /* Instruction costs on AppliedMicro Titan processors. */
844 struct processor_costs titan_cost
= {
845 COSTS_N_INSNS (5), /* mulsi */
846 COSTS_N_INSNS (5), /* mulsi_const */
847 COSTS_N_INSNS (5), /* mulsi_const9 */
848 COSTS_N_INSNS (5), /* muldi */
849 COSTS_N_INSNS (18), /* divsi */
850 COSTS_N_INSNS (18), /* divdi */
851 COSTS_N_INSNS (10), /* fp */
852 COSTS_N_INSNS (10), /* dmul */
853 COSTS_N_INSNS (46), /* sdiv */
854 COSTS_N_INSNS (72), /* ddiv */
855 32, /* cache line size */
858 1, /* prefetch streams /*/
861 /* Instruction costs on POWER4 and POWER5 processors. */
863 struct processor_costs power4_cost
= {
864 COSTS_N_INSNS (3), /* mulsi */
865 COSTS_N_INSNS (2), /* mulsi_const */
866 COSTS_N_INSNS (2), /* mulsi_const9 */
867 COSTS_N_INSNS (4), /* muldi */
868 COSTS_N_INSNS (18), /* divsi */
869 COSTS_N_INSNS (34), /* divdi */
870 COSTS_N_INSNS (3), /* fp */
871 COSTS_N_INSNS (3), /* dmul */
872 COSTS_N_INSNS (17), /* sdiv */
873 COSTS_N_INSNS (17), /* ddiv */
874 128, /* cache line size */
877 8, /* prefetch streams /*/
880 /* Instruction costs on POWER6 processors. */
882 struct processor_costs power6_cost
= {
883 COSTS_N_INSNS (8), /* mulsi */
884 COSTS_N_INSNS (8), /* mulsi_const */
885 COSTS_N_INSNS (8), /* mulsi_const9 */
886 COSTS_N_INSNS (8), /* muldi */
887 COSTS_N_INSNS (22), /* divsi */
888 COSTS_N_INSNS (28), /* divdi */
889 COSTS_N_INSNS (3), /* fp */
890 COSTS_N_INSNS (3), /* dmul */
891 COSTS_N_INSNS (13), /* sdiv */
892 COSTS_N_INSNS (16), /* ddiv */
893 128, /* cache line size */
896 16, /* prefetch streams */
899 /* Instruction costs on POWER7 processors. */
901 struct processor_costs power7_cost
= {
902 COSTS_N_INSNS (2), /* mulsi */
903 COSTS_N_INSNS (2), /* mulsi_const */
904 COSTS_N_INSNS (2), /* mulsi_const9 */
905 COSTS_N_INSNS (2), /* muldi */
906 COSTS_N_INSNS (18), /* divsi */
907 COSTS_N_INSNS (34), /* divdi */
908 COSTS_N_INSNS (3), /* fp */
909 COSTS_N_INSNS (3), /* dmul */
910 COSTS_N_INSNS (13), /* sdiv */
911 COSTS_N_INSNS (16), /* ddiv */
912 128, /* cache line size */
915 12, /* prefetch streams */
918 /* Instruction costs on POWER A2 processors. */
920 struct processor_costs ppca2_cost
= {
921 COSTS_N_INSNS (16), /* mulsi */
922 COSTS_N_INSNS (16), /* mulsi_const */
923 COSTS_N_INSNS (16), /* mulsi_const9 */
924 COSTS_N_INSNS (16), /* muldi */
925 COSTS_N_INSNS (22), /* divsi */
926 COSTS_N_INSNS (28), /* divdi */
927 COSTS_N_INSNS (3), /* fp */
928 COSTS_N_INSNS (3), /* dmul */
929 COSTS_N_INSNS (59), /* sdiv */
930 COSTS_N_INSNS (72), /* ddiv */
934 16, /* prefetch streams */
938 /* Table that classifies rs6000 builtin functions (pure, const, etc.). */
939 #undef RS6000_BUILTIN
940 #undef RS6000_BUILTIN_EQUATE
941 #define RS6000_BUILTIN(NAME, TYPE) TYPE,
942 #define RS6000_BUILTIN_EQUATE(NAME, VALUE)
944 static const enum rs6000_btc builtin_classify
[(int)RS6000_BUILTIN_COUNT
] =
946 #include "rs6000-builtin.def"
949 #undef RS6000_BUILTIN
950 #undef RS6000_BUILTIN_EQUATE
952 /* Support for -mveclibabi=<xxx> to control which vector library to use. */
953 static tree (*rs6000_veclib_handler
) (tree
, tree
, tree
);
956 static bool rs6000_function_ok_for_sibcall (tree
, tree
);
957 static const char *rs6000_invalid_within_doloop (const_rtx
);
958 static bool rs6000_legitimate_address_p (enum machine_mode
, rtx
, bool);
959 static bool rs6000_debug_legitimate_address_p (enum machine_mode
, rtx
, bool);
960 static rtx
rs6000_generate_compare (rtx
, enum machine_mode
);
961 static void rs6000_emit_stack_tie (void);
962 static void rs6000_frame_related (rtx
, rtx
, HOST_WIDE_INT
, rtx
, rtx
);
963 static bool spe_func_has_64bit_regs_p (void);
964 static void emit_frame_save (rtx
, rtx
, enum machine_mode
, unsigned int,
966 static rtx
gen_frame_mem_offset (enum machine_mode
, rtx
, int);
967 static unsigned rs6000_hash_constant (rtx
);
968 static unsigned toc_hash_function (const void *);
969 static int toc_hash_eq (const void *, const void *);
970 static bool reg_offset_addressing_ok_p (enum machine_mode
);
971 static bool virtual_stack_registers_memory_p (rtx
);
972 static bool constant_pool_expr_p (rtx
);
973 static bool legitimate_small_data_p (enum machine_mode
, rtx
);
974 static bool legitimate_lo_sum_address_p (enum machine_mode
, rtx
, int);
975 static struct machine_function
* rs6000_init_machine_status (void);
976 static bool rs6000_assemble_integer (rtx
, unsigned int, int);
977 static bool no_global_regs_above (int, bool);
978 #ifdef HAVE_GAS_HIDDEN
979 static void rs6000_assemble_visibility (tree
, int);
981 static int rs6000_ra_ever_killed (void);
982 static bool rs6000_attribute_takes_identifier_p (const_tree
);
983 static tree
rs6000_handle_longcall_attribute (tree
*, tree
, tree
, int, bool *);
984 static tree
rs6000_handle_altivec_attribute (tree
*, tree
, tree
, int, bool *);
985 static bool rs6000_ms_bitfield_layout_p (const_tree
);
986 static tree
rs6000_handle_struct_attribute (tree
*, tree
, tree
, int, bool *);
987 static void rs6000_eliminate_indexed_memrefs (rtx operands
[2]);
988 static const char *rs6000_mangle_type (const_tree
);
989 static void rs6000_set_default_type_attributes (tree
);
990 static rtx
rs6000_savres_routine_sym (rs6000_stack_t
*, bool, bool, bool);
991 static rtx
rs6000_emit_stack_reset (rs6000_stack_t
*, rtx
, rtx
, int, bool);
992 static rtx
rs6000_make_savres_rtx (rs6000_stack_t
*, rtx
, int,
993 enum machine_mode
, bool, bool, bool);
994 static bool rs6000_reg_live_or_pic_offset_p (int);
995 static tree
rs6000_builtin_vectorized_libmass (tree
, tree
, tree
);
996 static tree
rs6000_builtin_vectorized_function (tree
, tree
, tree
);
997 static int rs6000_savres_strategy (rs6000_stack_t
*, bool, int, int);
998 static void rs6000_restore_saved_cr (rtx
, int);
999 static void rs6000_output_function_prologue (FILE *, HOST_WIDE_INT
);
1000 static void rs6000_output_function_epilogue (FILE *, HOST_WIDE_INT
);
1001 static void rs6000_output_mi_thunk (FILE *, tree
, HOST_WIDE_INT
, HOST_WIDE_INT
,
1003 static rtx
rs6000_emit_set_long_const (rtx
, HOST_WIDE_INT
, HOST_WIDE_INT
);
1004 static bool rs6000_return_in_memory (const_tree
, const_tree
);
1005 static rtx
rs6000_function_value (const_tree
, const_tree
, bool);
1006 static void rs6000_file_start (void);
1008 static int rs6000_elf_reloc_rw_mask (void);
1009 static void rs6000_elf_asm_out_constructor (rtx
, int);
1010 static void rs6000_elf_asm_out_destructor (rtx
, int);
1011 static void rs6000_elf_end_indicate_exec_stack (void) ATTRIBUTE_UNUSED
;
1012 static void rs6000_elf_asm_init_sections (void);
1013 static section
*rs6000_elf_select_rtx_section (enum machine_mode
, rtx
,
1014 unsigned HOST_WIDE_INT
);
1015 static void rs6000_elf_encode_section_info (tree
, rtx
, int)
1018 static bool rs6000_use_blocks_for_constant_p (enum machine_mode
, const_rtx
);
1019 static void rs6000_alloc_sdmode_stack_slot (void);
1020 static void rs6000_instantiate_decls (void);
1022 static void rs6000_xcoff_asm_output_anchor (rtx
);
1023 static void rs6000_xcoff_asm_globalize_label (FILE *, const char *);
1024 static void rs6000_xcoff_asm_init_sections (void);
1025 static int rs6000_xcoff_reloc_rw_mask (void);
1026 static void rs6000_xcoff_asm_named_section (const char *, unsigned int, tree
);
1027 static section
*rs6000_xcoff_select_section (tree
, int,
1028 unsigned HOST_WIDE_INT
);
1029 static void rs6000_xcoff_unique_section (tree
, int);
1030 static section
*rs6000_xcoff_select_rtx_section
1031 (enum machine_mode
, rtx
, unsigned HOST_WIDE_INT
);
1032 static const char * rs6000_xcoff_strip_name_encoding (const char *);
1033 static unsigned int rs6000_xcoff_section_type_flags (tree
, const char *, int);
1034 static void rs6000_xcoff_file_start (void);
1035 static void rs6000_xcoff_file_end (void);
1037 static int rs6000_variable_issue (FILE *, int, rtx
, int);
1038 static int rs6000_register_move_cost (enum machine_mode
,
1039 reg_class_t
, reg_class_t
);
1040 static int rs6000_memory_move_cost (enum machine_mode
, reg_class_t
, bool);
1041 static bool rs6000_rtx_costs (rtx
, int, int, int *, bool);
1042 static bool rs6000_debug_rtx_costs (rtx
, int, int, int *, bool);
1043 static int rs6000_debug_address_cost (rtx
, bool);
1044 static int rs6000_adjust_cost (rtx
, rtx
, rtx
, int);
1045 static int rs6000_debug_adjust_cost (rtx
, rtx
, rtx
, int);
1046 static void rs6000_sched_init (FILE *, int, int);
1047 static bool is_microcoded_insn (rtx
);
1048 static bool is_nonpipeline_insn (rtx
);
1049 static bool is_cracked_insn (rtx
);
1050 static bool is_branch_slot_insn (rtx
);
1051 static bool is_load_insn (rtx
);
1052 static rtx
get_store_dest (rtx pat
);
1053 static bool is_store_insn (rtx
);
1054 static bool set_to_load_agen (rtx
,rtx
);
1055 static bool adjacent_mem_locations (rtx
,rtx
);
1056 static int rs6000_adjust_priority (rtx
, int);
1057 static int rs6000_issue_rate (void);
1058 static bool rs6000_is_costly_dependence (dep_t
, int, int);
1059 static rtx
get_next_active_insn (rtx
, rtx
);
1060 static bool insn_terminates_group_p (rtx
, enum group_termination
);
1061 static bool insn_must_be_first_in_group (rtx
);
1062 static bool insn_must_be_last_in_group (rtx
);
1063 static bool is_costly_group (rtx
*, rtx
);
1064 static int force_new_group (int, FILE *, rtx
*, rtx
, bool *, int, int *);
1065 static int redefine_groups (FILE *, int, rtx
, rtx
);
1066 static int pad_groups (FILE *, int, rtx
, rtx
);
1067 static void rs6000_sched_finish (FILE *, int);
1068 static int rs6000_sched_reorder (FILE *, int, rtx
*, int *, int);
1069 static int rs6000_sched_reorder2 (FILE *, int, rtx
*, int *, int);
1070 static int rs6000_use_sched_lookahead (void);
1071 static int rs6000_use_sched_lookahead_guard (rtx
);
1072 static void * rs6000_alloc_sched_context (void);
1073 static void rs6000_init_sched_context (void *, bool);
1074 static void rs6000_set_sched_context (void *);
1075 static void rs6000_free_sched_context (void *);
1076 static tree
rs6000_builtin_reciprocal (unsigned int, bool, bool);
1077 static tree
rs6000_builtin_mask_for_load (void);
1078 static tree
rs6000_builtin_mul_widen_even (tree
);
1079 static tree
rs6000_builtin_mul_widen_odd (tree
);
1080 static tree
rs6000_builtin_conversion (unsigned int, tree
, tree
);
1081 static tree
rs6000_builtin_vec_perm (tree
, tree
*);
1082 static bool rs6000_builtin_support_vector_misalignment (enum
1086 static int rs6000_builtin_vectorization_cost (enum vect_cost_for_stmt
,
1089 static void def_builtin (int, const char *, tree
, int);
1090 static bool rs6000_vector_alignment_reachable (const_tree
, bool);
1091 static void rs6000_init_builtins (void);
1092 static tree
rs6000_builtin_decl (unsigned, bool);
1094 static rtx
rs6000_expand_unop_builtin (enum insn_code
, tree
, rtx
);
1095 static rtx
rs6000_expand_binop_builtin (enum insn_code
, tree
, rtx
);
1096 static rtx
rs6000_expand_ternop_builtin (enum insn_code
, tree
, rtx
);
1097 static rtx
rs6000_expand_builtin (tree
, rtx
, rtx
, enum machine_mode
, int);
1098 static void altivec_init_builtins (void);
1099 static unsigned builtin_hash_function (const void *);
1100 static int builtin_hash_eq (const void *, const void *);
1101 static tree
builtin_function_type (enum machine_mode
, enum machine_mode
,
1102 enum machine_mode
, enum machine_mode
,
1103 enum rs6000_builtins
, const char *name
);
1104 static void rs6000_common_init_builtins (void);
1105 static void rs6000_init_libfuncs (void);
1107 static void paired_init_builtins (void);
1108 static rtx
paired_expand_builtin (tree
, rtx
, bool *);
1109 static rtx
paired_expand_lv_builtin (enum insn_code
, tree
, rtx
);
1110 static rtx
paired_expand_stv_builtin (enum insn_code
, tree
);
1111 static rtx
paired_expand_predicate_builtin (enum insn_code
, tree
, rtx
);
1113 static void enable_mask_for_builtins (struct builtin_description
*, int,
1114 enum rs6000_builtins
,
1115 enum rs6000_builtins
);
1116 static void spe_init_builtins (void);
1117 static rtx
spe_expand_builtin (tree
, rtx
, bool *);
1118 static rtx
spe_expand_stv_builtin (enum insn_code
, tree
);
1119 static rtx
spe_expand_predicate_builtin (enum insn_code
, tree
, rtx
);
1120 static rtx
spe_expand_evsel_builtin (enum insn_code
, tree
, rtx
);
1121 static int rs6000_emit_int_cmove (rtx
, rtx
, rtx
, rtx
);
1122 static rs6000_stack_t
*rs6000_stack_info (void);
1123 static void debug_stack_info (rs6000_stack_t
*);
1125 static rtx
altivec_expand_builtin (tree
, rtx
, bool *);
1126 static rtx
altivec_expand_ld_builtin (tree
, rtx
, bool *);
1127 static rtx
altivec_expand_st_builtin (tree
, rtx
, bool *);
1128 static rtx
altivec_expand_dst_builtin (tree
, rtx
, bool *);
1129 static rtx
altivec_expand_abs_builtin (enum insn_code
, tree
, rtx
);
1130 static rtx
altivec_expand_predicate_builtin (enum insn_code
, tree
, rtx
);
1131 static rtx
altivec_expand_stv_builtin (enum insn_code
, tree
);
1132 static rtx
altivec_expand_vec_init_builtin (tree
, tree
, rtx
);
1133 static rtx
altivec_expand_vec_set_builtin (tree
);
1134 static rtx
altivec_expand_vec_ext_builtin (tree
, rtx
);
1135 static int get_element_number (tree
, tree
);
1136 static bool rs6000_handle_option (size_t, const char *, int);
1137 static void rs6000_parse_tls_size_option (void);
1138 static void rs6000_parse_yes_no_option (const char *, const char *, int *);
1139 static int first_altivec_reg_to_save (void);
1140 static unsigned int compute_vrsave_mask (void);
1141 static void compute_save_world_info (rs6000_stack_t
*info_ptr
);
1142 static void is_altivec_return_reg (rtx
, void *);
1143 static rtx
generate_set_vrsave (rtx
, rs6000_stack_t
*, int);
1144 int easy_vector_constant (rtx
, enum machine_mode
);
1145 static rtx
rs6000_dwarf_register_span (rtx
);
1146 static void rs6000_init_dwarf_reg_sizes_extra (tree
);
1147 static rtx
rs6000_legitimize_address (rtx
, rtx
, enum machine_mode
);
1148 static rtx
rs6000_debug_legitimize_address (rtx
, rtx
, enum machine_mode
);
1149 static rtx
rs6000_legitimize_tls_address (rtx
, enum tls_model
);
1150 static void rs6000_output_dwarf_dtprel (FILE *, int, rtx
) ATTRIBUTE_UNUSED
;
1151 static rtx
rs6000_delegitimize_address (rtx
);
1152 static rtx
rs6000_tls_get_addr (void);
1153 static rtx
rs6000_got_sym (void);
1154 static int rs6000_tls_symbol_ref_1 (rtx
*, void *);
1155 static const char *rs6000_get_some_local_dynamic_name (void);
1156 static int rs6000_get_some_local_dynamic_name_1 (rtx
*, void *);
1157 static rtx
rs6000_complex_function_value (enum machine_mode
);
1158 static rtx
rs6000_spe_function_arg (const CUMULATIVE_ARGS
*,
1159 enum machine_mode
, const_tree
);
1160 static void rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS
*,
1161 HOST_WIDE_INT
, int);
1162 static void rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS
*,
1165 static void rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS
*,
1168 static void rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS
*,
1169 const_tree
, HOST_WIDE_INT
,
1171 static rtx
rs6000_darwin64_record_arg (CUMULATIVE_ARGS
*, const_tree
, bool, bool);
1172 static rtx
rs6000_mixed_function_arg (enum machine_mode
, const_tree
, int);
1173 static void rs6000_function_arg_advance (CUMULATIVE_ARGS
*, enum machine_mode
,
1175 static rtx
rs6000_function_arg (CUMULATIVE_ARGS
*, enum machine_mode
,
1177 static void rs6000_move_block_from_reg (int regno
, rtx x
, int nregs
);
1178 static void setup_incoming_varargs (CUMULATIVE_ARGS
*,
1179 enum machine_mode
, tree
,
1181 static bool rs6000_pass_by_reference (CUMULATIVE_ARGS
*, enum machine_mode
,
1183 static int rs6000_arg_partial_bytes (CUMULATIVE_ARGS
*, enum machine_mode
,
1185 static const char *invalid_arg_for_unprototyped_fn (const_tree
, const_tree
, const_tree
);
1187 static void macho_branch_islands (void);
1188 static int no_previous_def (tree function_name
);
1189 static tree
get_prev_label (tree function_name
);
1190 static void rs6000_darwin_file_start (void);
1193 static tree
rs6000_build_builtin_va_list (void);
1194 static void rs6000_va_start (tree
, rtx
);
1195 static tree
rs6000_gimplify_va_arg (tree
, tree
, gimple_seq
*, gimple_seq
*);
1196 static bool rs6000_must_pass_in_stack (enum machine_mode
, const_tree
);
1197 static bool rs6000_scalar_mode_supported_p (enum machine_mode
);
1198 static bool rs6000_vector_mode_supported_p (enum machine_mode
);
1199 static rtx
rs6000_emit_vector_compare_inner (enum rtx_code
, rtx
, rtx
);
1200 static rtx
rs6000_emit_vector_compare (enum rtx_code
, rtx
, rtx
,
1202 static tree
rs6000_stack_protect_fail (void);
1204 static rtx
rs6000_legitimize_reload_address (rtx
, enum machine_mode
, int, int,
1207 static rtx
rs6000_debug_legitimize_reload_address (rtx
, enum machine_mode
, int,
1210 rtx (*rs6000_legitimize_reload_address_ptr
) (rtx
, enum machine_mode
, int, int,
1212 = rs6000_legitimize_reload_address
;
1214 static bool rs6000_mode_dependent_address_p (const_rtx
);
1215 static bool rs6000_mode_dependent_address (const_rtx
);
1216 static bool rs6000_debug_mode_dependent_address (const_rtx
);
1217 static bool (*rs6000_mode_dependent_address_ptr
) (const_rtx
)
1218 = rs6000_mode_dependent_address
;
1220 static enum reg_class
rs6000_secondary_reload_class (enum reg_class
,
1221 enum machine_mode
, rtx
);
1222 static enum reg_class
rs6000_debug_secondary_reload_class (enum reg_class
,
1225 enum reg_class (*rs6000_secondary_reload_class_ptr
) (enum reg_class
,
1226 enum machine_mode
, rtx
)
1227 = rs6000_secondary_reload_class
;
1229 static enum reg_class
rs6000_preferred_reload_class (rtx
, enum reg_class
);
1230 static enum reg_class
rs6000_debug_preferred_reload_class (rtx
,
1232 enum reg_class (*rs6000_preferred_reload_class_ptr
) (rtx
, enum reg_class
)
1233 = rs6000_preferred_reload_class
;
1235 static bool rs6000_secondary_memory_needed (enum reg_class
, enum reg_class
,
1238 static bool rs6000_debug_secondary_memory_needed (enum reg_class
,
1242 bool (*rs6000_secondary_memory_needed_ptr
) (enum reg_class
, enum reg_class
,
1244 = rs6000_secondary_memory_needed
;
1246 static bool rs6000_cannot_change_mode_class (enum machine_mode
,
1249 static bool rs6000_debug_cannot_change_mode_class (enum machine_mode
,
1253 bool (*rs6000_cannot_change_mode_class_ptr
) (enum machine_mode
,
1256 = rs6000_cannot_change_mode_class
;
1258 static reg_class_t
rs6000_secondary_reload (bool, rtx
, reg_class_t
,
1260 struct secondary_reload_info
*);
1262 static const reg_class_t
*rs6000_ira_cover_classes (void);
1264 const int INSN_NOT_AVAILABLE
= -1;
1265 static enum machine_mode
rs6000_eh_return_filter_mode (void);
1266 static bool rs6000_can_eliminate (const int, const int);
1267 static void rs6000_trampoline_init (rtx
, tree
, rtx
);
1269 /* Hash table stuff for keeping track of TOC entries. */
1271 struct GTY(()) toc_hash_struct
1273 /* `key' will satisfy CONSTANT_P; in fact, it will satisfy
1274 ASM_OUTPUT_SPECIAL_POOL_ENTRY_P. */
1276 enum machine_mode key_mode
;
1280 static GTY ((param_is (struct toc_hash_struct
))) htab_t toc_hash_table
;
1282 /* Hash table to keep track of the argument types for builtin functions. */
1284 struct GTY(()) builtin_hash_struct
1287 enum machine_mode mode
[4]; /* return value + 3 arguments. */
1288 unsigned char uns_p
[4]; /* and whether the types are unsigned. */
1291 static GTY ((param_is (struct builtin_hash_struct
))) htab_t builtin_hash_table
;
1293 /* Default register names. */
1294 char rs6000_reg_names
[][8] =
1296 "0", "1", "2", "3", "4", "5", "6", "7",
1297 "8", "9", "10", "11", "12", "13", "14", "15",
1298 "16", "17", "18", "19", "20", "21", "22", "23",
1299 "24", "25", "26", "27", "28", "29", "30", "31",
1300 "0", "1", "2", "3", "4", "5", "6", "7",
1301 "8", "9", "10", "11", "12", "13", "14", "15",
1302 "16", "17", "18", "19", "20", "21", "22", "23",
1303 "24", "25", "26", "27", "28", "29", "30", "31",
1304 "mq", "lr", "ctr","ap",
1305 "0", "1", "2", "3", "4", "5", "6", "7",
1307 /* AltiVec registers. */
1308 "0", "1", "2", "3", "4", "5", "6", "7",
1309 "8", "9", "10", "11", "12", "13", "14", "15",
1310 "16", "17", "18", "19", "20", "21", "22", "23",
1311 "24", "25", "26", "27", "28", "29", "30", "31",
1313 /* SPE registers. */
1314 "spe_acc", "spefscr",
1315 /* Soft frame pointer. */
1319 #ifdef TARGET_REGNAMES
1320 static const char alt_reg_names
[][8] =
1322 "%r0", "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7",
1323 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15",
1324 "%r16", "%r17", "%r18", "%r19", "%r20", "%r21", "%r22", "%r23",
1325 "%r24", "%r25", "%r26", "%r27", "%r28", "%r29", "%r30", "%r31",
1326 "%f0", "%f1", "%f2", "%f3", "%f4", "%f5", "%f6", "%f7",
1327 "%f8", "%f9", "%f10", "%f11", "%f12", "%f13", "%f14", "%f15",
1328 "%f16", "%f17", "%f18", "%f19", "%f20", "%f21", "%f22", "%f23",
1329 "%f24", "%f25", "%f26", "%f27", "%f28", "%f29", "%f30", "%f31",
1330 "mq", "lr", "ctr", "ap",
1331 "%cr0", "%cr1", "%cr2", "%cr3", "%cr4", "%cr5", "%cr6", "%cr7",
1333 /* AltiVec registers. */
1334 "%v0", "%v1", "%v2", "%v3", "%v4", "%v5", "%v6", "%v7",
1335 "%v8", "%v9", "%v10", "%v11", "%v12", "%v13", "%v14", "%v15",
1336 "%v16", "%v17", "%v18", "%v19", "%v20", "%v21", "%v22", "%v23",
1337 "%v24", "%v25", "%v26", "%v27", "%v28", "%v29", "%v30", "%v31",
1339 /* SPE registers. */
1340 "spe_acc", "spefscr",
1341 /* Soft frame pointer. */
1346 /* Table of valid machine attributes. */
1348 static const struct attribute_spec rs6000_attribute_table
[] =
1350 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
1351 { "altivec", 1, 1, false, true, false, rs6000_handle_altivec_attribute
},
1352 { "longcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute
},
1353 { "shortcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute
},
1354 { "ms_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute
},
1355 { "gcc_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute
},
1356 #ifdef SUBTARGET_ATTRIBUTE_TABLE
1357 SUBTARGET_ATTRIBUTE_TABLE
,
1359 { NULL
, 0, 0, false, false, false, NULL
}
1362 #ifndef MASK_STRICT_ALIGN
1363 #define MASK_STRICT_ALIGN 0
1365 #ifndef TARGET_PROFILE_KERNEL
1366 #define TARGET_PROFILE_KERNEL 0
1369 /* The VRSAVE bitmask puts bit %v0 as the most significant bit. */
1370 #define ALTIVEC_REG_BIT(REGNO) (0x80000000 >> ((REGNO) - FIRST_ALTIVEC_REGNO))
1372 /* Initialize the GCC target structure. */
1373 #undef TARGET_ATTRIBUTE_TABLE
1374 #define TARGET_ATTRIBUTE_TABLE rs6000_attribute_table
1375 #undef TARGET_SET_DEFAULT_TYPE_ATTRIBUTES
1376 #define TARGET_SET_DEFAULT_TYPE_ATTRIBUTES rs6000_set_default_type_attributes
1377 #undef TARGET_ATTRIBUTE_TAKES_IDENTIFIER_P
1378 #define TARGET_ATTRIBUTE_TAKES_IDENTIFIER_P rs6000_attribute_takes_identifier_p
1380 #undef TARGET_ASM_ALIGNED_DI_OP
1381 #define TARGET_ASM_ALIGNED_DI_OP DOUBLE_INT_ASM_OP
1383 /* Default unaligned ops are only provided for ELF. Find the ops needed
1384 for non-ELF systems. */
1385 #ifndef OBJECT_FORMAT_ELF
1387 /* For XCOFF. rs6000_assemble_integer will handle unaligned DIs on
1389 #undef TARGET_ASM_UNALIGNED_HI_OP
1390 #define TARGET_ASM_UNALIGNED_HI_OP "\t.vbyte\t2,"
1391 #undef TARGET_ASM_UNALIGNED_SI_OP
1392 #define TARGET_ASM_UNALIGNED_SI_OP "\t.vbyte\t4,"
1393 #undef TARGET_ASM_UNALIGNED_DI_OP
1394 #define TARGET_ASM_UNALIGNED_DI_OP "\t.vbyte\t8,"
1397 #undef TARGET_ASM_UNALIGNED_HI_OP
1398 #define TARGET_ASM_UNALIGNED_HI_OP "\t.short\t"
1399 #undef TARGET_ASM_UNALIGNED_SI_OP
1400 #define TARGET_ASM_UNALIGNED_SI_OP "\t.long\t"
1401 #undef TARGET_ASM_UNALIGNED_DI_OP
1402 #define TARGET_ASM_UNALIGNED_DI_OP "\t.quad\t"
1403 #undef TARGET_ASM_ALIGNED_DI_OP
1404 #define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t"
1408 /* This hook deals with fixups for relocatable code and DI-mode objects
1410 #undef TARGET_ASM_INTEGER
1411 #define TARGET_ASM_INTEGER rs6000_assemble_integer
1413 #ifdef HAVE_GAS_HIDDEN
1414 #undef TARGET_ASM_ASSEMBLE_VISIBILITY
1415 #define TARGET_ASM_ASSEMBLE_VISIBILITY rs6000_assemble_visibility
1418 #undef TARGET_HAVE_TLS
1419 #define TARGET_HAVE_TLS HAVE_AS_TLS
1421 #undef TARGET_CANNOT_FORCE_CONST_MEM
1422 #define TARGET_CANNOT_FORCE_CONST_MEM rs6000_tls_referenced_p
1424 #undef TARGET_DELEGITIMIZE_ADDRESS
1425 #define TARGET_DELEGITIMIZE_ADDRESS rs6000_delegitimize_address
1427 #undef TARGET_ASM_FUNCTION_PROLOGUE
1428 #define TARGET_ASM_FUNCTION_PROLOGUE rs6000_output_function_prologue
1429 #undef TARGET_ASM_FUNCTION_EPILOGUE
1430 #define TARGET_ASM_FUNCTION_EPILOGUE rs6000_output_function_epilogue
1432 #undef TARGET_LEGITIMIZE_ADDRESS
1433 #define TARGET_LEGITIMIZE_ADDRESS rs6000_legitimize_address
1435 #undef TARGET_SCHED_VARIABLE_ISSUE
1436 #define TARGET_SCHED_VARIABLE_ISSUE rs6000_variable_issue
1438 #undef TARGET_SCHED_ISSUE_RATE
1439 #define TARGET_SCHED_ISSUE_RATE rs6000_issue_rate
1440 #undef TARGET_SCHED_ADJUST_COST
1441 #define TARGET_SCHED_ADJUST_COST rs6000_adjust_cost
1442 #undef TARGET_SCHED_ADJUST_PRIORITY
1443 #define TARGET_SCHED_ADJUST_PRIORITY rs6000_adjust_priority
1444 #undef TARGET_SCHED_IS_COSTLY_DEPENDENCE
1445 #define TARGET_SCHED_IS_COSTLY_DEPENDENCE rs6000_is_costly_dependence
1446 #undef TARGET_SCHED_INIT
1447 #define TARGET_SCHED_INIT rs6000_sched_init
1448 #undef TARGET_SCHED_FINISH
1449 #define TARGET_SCHED_FINISH rs6000_sched_finish
1450 #undef TARGET_SCHED_REORDER
1451 #define TARGET_SCHED_REORDER rs6000_sched_reorder
1452 #undef TARGET_SCHED_REORDER2
1453 #define TARGET_SCHED_REORDER2 rs6000_sched_reorder2
1455 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
1456 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD rs6000_use_sched_lookahead
1458 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD
1459 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD rs6000_use_sched_lookahead_guard
1461 #undef TARGET_SCHED_ALLOC_SCHED_CONTEXT
1462 #define TARGET_SCHED_ALLOC_SCHED_CONTEXT rs6000_alloc_sched_context
1463 #undef TARGET_SCHED_INIT_SCHED_CONTEXT
1464 #define TARGET_SCHED_INIT_SCHED_CONTEXT rs6000_init_sched_context
1465 #undef TARGET_SCHED_SET_SCHED_CONTEXT
1466 #define TARGET_SCHED_SET_SCHED_CONTEXT rs6000_set_sched_context
1467 #undef TARGET_SCHED_FREE_SCHED_CONTEXT
1468 #define TARGET_SCHED_FREE_SCHED_CONTEXT rs6000_free_sched_context
1470 #undef TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD
1471 #define TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD rs6000_builtin_mask_for_load
1472 #undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN
1473 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN rs6000_builtin_mul_widen_even
1474 #undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD
1475 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD rs6000_builtin_mul_widen_odd
1476 #undef TARGET_VECTORIZE_BUILTIN_CONVERSION
1477 #define TARGET_VECTORIZE_BUILTIN_CONVERSION rs6000_builtin_conversion
1478 #undef TARGET_VECTORIZE_BUILTIN_VEC_PERM
1479 #define TARGET_VECTORIZE_BUILTIN_VEC_PERM rs6000_builtin_vec_perm
1480 #undef TARGET_VECTORIZE_SUPPORT_VECTOR_MISALIGNMENT
1481 #define TARGET_VECTORIZE_SUPPORT_VECTOR_MISALIGNMENT \
1482 rs6000_builtin_support_vector_misalignment
1483 #undef TARGET_VECTORIZE_VECTOR_ALIGNMENT_REACHABLE
1484 #define TARGET_VECTORIZE_VECTOR_ALIGNMENT_REACHABLE rs6000_vector_alignment_reachable
1485 #undef TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST
1486 #define TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST \
1487 rs6000_builtin_vectorization_cost
1489 #undef TARGET_INIT_BUILTINS
1490 #define TARGET_INIT_BUILTINS rs6000_init_builtins
1491 #undef TARGET_BUILTIN_DECL
1492 #define TARGET_BUILTIN_DECL rs6000_builtin_decl
1494 #undef TARGET_EXPAND_BUILTIN
1495 #define TARGET_EXPAND_BUILTIN rs6000_expand_builtin
1497 #undef TARGET_MANGLE_TYPE
1498 #define TARGET_MANGLE_TYPE rs6000_mangle_type
1500 #undef TARGET_INIT_LIBFUNCS
1501 #define TARGET_INIT_LIBFUNCS rs6000_init_libfuncs
1504 #undef TARGET_BINDS_LOCAL_P
1505 #define TARGET_BINDS_LOCAL_P darwin_binds_local_p
1508 #undef TARGET_MS_BITFIELD_LAYOUT_P
1509 #define TARGET_MS_BITFIELD_LAYOUT_P rs6000_ms_bitfield_layout_p
1511 #undef TARGET_ASM_OUTPUT_MI_THUNK
1512 #define TARGET_ASM_OUTPUT_MI_THUNK rs6000_output_mi_thunk
1514 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
1515 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true
1517 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
1518 #define TARGET_FUNCTION_OK_FOR_SIBCALL rs6000_function_ok_for_sibcall
1520 #undef TARGET_INVALID_WITHIN_DOLOOP
1521 #define TARGET_INVALID_WITHIN_DOLOOP rs6000_invalid_within_doloop
1523 #undef TARGET_REGISTER_MOVE_COST
1524 #define TARGET_REGISTER_MOVE_COST rs6000_register_move_cost
1525 #undef TARGET_MEMORY_MOVE_COST
1526 #define TARGET_MEMORY_MOVE_COST rs6000_memory_move_cost
1527 #undef TARGET_RTX_COSTS
1528 #define TARGET_RTX_COSTS rs6000_rtx_costs
1529 #undef TARGET_ADDRESS_COST
1530 #define TARGET_ADDRESS_COST hook_int_rtx_bool_0
1532 #undef TARGET_DWARF_REGISTER_SPAN
1533 #define TARGET_DWARF_REGISTER_SPAN rs6000_dwarf_register_span
1535 #undef TARGET_INIT_DWARF_REG_SIZES_EXTRA
1536 #define TARGET_INIT_DWARF_REG_SIZES_EXTRA rs6000_init_dwarf_reg_sizes_extra
1538 /* On rs6000, function arguments are promoted, as are function return
1540 #undef TARGET_PROMOTE_FUNCTION_MODE
1541 #define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote
1543 #undef TARGET_RETURN_IN_MEMORY
1544 #define TARGET_RETURN_IN_MEMORY rs6000_return_in_memory
1546 #undef TARGET_SETUP_INCOMING_VARARGS
1547 #define TARGET_SETUP_INCOMING_VARARGS setup_incoming_varargs
1549 /* Always strict argument naming on rs6000. */
1550 #undef TARGET_STRICT_ARGUMENT_NAMING
1551 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
1552 #undef TARGET_PRETEND_OUTGOING_VARARGS_NAMED
1553 #define TARGET_PRETEND_OUTGOING_VARARGS_NAMED hook_bool_CUMULATIVE_ARGS_true
1554 #undef TARGET_SPLIT_COMPLEX_ARG
1555 #define TARGET_SPLIT_COMPLEX_ARG hook_bool_const_tree_true
1556 #undef TARGET_MUST_PASS_IN_STACK
1557 #define TARGET_MUST_PASS_IN_STACK rs6000_must_pass_in_stack
1558 #undef TARGET_PASS_BY_REFERENCE
1559 #define TARGET_PASS_BY_REFERENCE rs6000_pass_by_reference
1560 #undef TARGET_ARG_PARTIAL_BYTES
1561 #define TARGET_ARG_PARTIAL_BYTES rs6000_arg_partial_bytes
1562 #undef TARGET_FUNCTION_ARG_ADVANCE
1563 #define TARGET_FUNCTION_ARG_ADVANCE rs6000_function_arg_advance
1564 #undef TARGET_FUNCTION_ARG
1565 #define TARGET_FUNCTION_ARG rs6000_function_arg
1567 #undef TARGET_BUILD_BUILTIN_VA_LIST
1568 #define TARGET_BUILD_BUILTIN_VA_LIST rs6000_build_builtin_va_list
1570 #undef TARGET_EXPAND_BUILTIN_VA_START
1571 #define TARGET_EXPAND_BUILTIN_VA_START rs6000_va_start
1573 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
1574 #define TARGET_GIMPLIFY_VA_ARG_EXPR rs6000_gimplify_va_arg
1576 #undef TARGET_EH_RETURN_FILTER_MODE
1577 #define TARGET_EH_RETURN_FILTER_MODE rs6000_eh_return_filter_mode
1579 #undef TARGET_SCALAR_MODE_SUPPORTED_P
1580 #define TARGET_SCALAR_MODE_SUPPORTED_P rs6000_scalar_mode_supported_p
1582 #undef TARGET_VECTOR_MODE_SUPPORTED_P
1583 #define TARGET_VECTOR_MODE_SUPPORTED_P rs6000_vector_mode_supported_p
1585 #undef TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN
1586 #define TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN invalid_arg_for_unprototyped_fn
1588 #undef TARGET_HANDLE_OPTION
1589 #define TARGET_HANDLE_OPTION rs6000_handle_option
1591 #undef TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION
1592 #define TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION \
1593 rs6000_builtin_vectorized_function
1595 #undef TARGET_DEFAULT_TARGET_FLAGS
1596 #define TARGET_DEFAULT_TARGET_FLAGS \
1599 #undef TARGET_STACK_PROTECT_FAIL
1600 #define TARGET_STACK_PROTECT_FAIL rs6000_stack_protect_fail
1602 /* MPC604EUM 3.5.2 Weak Consistency between Multiple Processors
1603 The PowerPC architecture requires only weak consistency among
1604 processors--that is, memory accesses between processors need not be
1605 sequentially consistent and memory accesses among processors can occur
1606 in any order. The ability to order memory accesses weakly provides
1607 opportunities for more efficient use of the system bus. Unless a
1608 dependency exists, the 604e allows read operations to precede store
1610 #undef TARGET_RELAXED_ORDERING
1611 #define TARGET_RELAXED_ORDERING true
1614 #undef TARGET_ASM_OUTPUT_DWARF_DTPREL
1615 #define TARGET_ASM_OUTPUT_DWARF_DTPREL rs6000_output_dwarf_dtprel
1618 /* Use a 32-bit anchor range. This leads to sequences like:
1620 addis tmp,anchor,high
1623 where tmp itself acts as an anchor, and can be shared between
1624 accesses to the same 64k page. */
1625 #undef TARGET_MIN_ANCHOR_OFFSET
1626 #define TARGET_MIN_ANCHOR_OFFSET -0x7fffffff - 1
1627 #undef TARGET_MAX_ANCHOR_OFFSET
1628 #define TARGET_MAX_ANCHOR_OFFSET 0x7fffffff
1629 #undef TARGET_USE_BLOCKS_FOR_CONSTANT_P
1630 #define TARGET_USE_BLOCKS_FOR_CONSTANT_P rs6000_use_blocks_for_constant_p
1632 #undef TARGET_BUILTIN_RECIPROCAL
1633 #define TARGET_BUILTIN_RECIPROCAL rs6000_builtin_reciprocal
1635 #undef TARGET_EXPAND_TO_RTL_HOOK
1636 #define TARGET_EXPAND_TO_RTL_HOOK rs6000_alloc_sdmode_stack_slot
1638 #undef TARGET_INSTANTIATE_DECLS
1639 #define TARGET_INSTANTIATE_DECLS rs6000_instantiate_decls
1641 #undef TARGET_SECONDARY_RELOAD
1642 #define TARGET_SECONDARY_RELOAD rs6000_secondary_reload
1644 #undef TARGET_IRA_COVER_CLASSES
1645 #define TARGET_IRA_COVER_CLASSES rs6000_ira_cover_classes
1647 #undef TARGET_LEGITIMATE_ADDRESS_P
1648 #define TARGET_LEGITIMATE_ADDRESS_P rs6000_legitimate_address_p
1650 #undef TARGET_MODE_DEPENDENT_ADDRESS_P
1651 #define TARGET_MODE_DEPENDENT_ADDRESS_P rs6000_mode_dependent_address_p
1653 #undef TARGET_CAN_ELIMINATE
1654 #define TARGET_CAN_ELIMINATE rs6000_can_eliminate
1656 #undef TARGET_TRAMPOLINE_INIT
1657 #define TARGET_TRAMPOLINE_INIT rs6000_trampoline_init
1659 #undef TARGET_FUNCTION_VALUE
1660 #define TARGET_FUNCTION_VALUE rs6000_function_value
1662 struct gcc_target targetm
= TARGET_INITIALIZER
;
1664 /* Return number of consecutive hard regs needed starting at reg REGNO
1665 to hold something of mode MODE.
1666 This is ordinarily the length in words of a value of mode MODE
1667 but can be less for certain modes in special long registers.
1669 For the SPE, GPRs are 64 bits but only 32 bits are visible in
1670 scalar instructions. The upper 32 bits are only available to the
1673 POWER and PowerPC GPRs hold 32 bits worth;
1674 PowerPC64 GPRs and FPRs point register holds 64 bits worth. */
1677 rs6000_hard_regno_nregs_internal (int regno
, enum machine_mode mode
)
1679 unsigned HOST_WIDE_INT reg_size
;
1681 if (FP_REGNO_P (regno
))
1682 reg_size
= (VECTOR_MEM_VSX_P (mode
)
1683 ? UNITS_PER_VSX_WORD
1684 : UNITS_PER_FP_WORD
);
1686 else if (SPE_SIMD_REGNO_P (regno
) && TARGET_SPE
&& SPE_VECTOR_MODE (mode
))
1687 reg_size
= UNITS_PER_SPE_WORD
;
1689 else if (ALTIVEC_REGNO_P (regno
))
1690 reg_size
= UNITS_PER_ALTIVEC_WORD
;
1692 /* The value returned for SCmode in the E500 double case is 2 for
1693 ABI compatibility; storing an SCmode value in a single register
1694 would require function_arg and rs6000_spe_function_arg to handle
1695 SCmode so as to pass the value correctly in a pair of
1697 else if (TARGET_E500_DOUBLE
&& FLOAT_MODE_P (mode
) && mode
!= SCmode
1698 && !DECIMAL_FLOAT_MODE_P (mode
))
1699 reg_size
= UNITS_PER_FP_WORD
;
1702 reg_size
= UNITS_PER_WORD
;
1704 return (GET_MODE_SIZE (mode
) + reg_size
- 1) / reg_size
;
1707 /* Value is 1 if hard register REGNO can hold a value of machine-mode
1710 rs6000_hard_regno_mode_ok (int regno
, enum machine_mode mode
)
1712 int last_regno
= regno
+ rs6000_hard_regno_nregs
[mode
][regno
] - 1;
1714 /* VSX registers that overlap the FPR registers are larger than for non-VSX
1715 implementations. Don't allow an item to be split between a FP register
1716 and an Altivec register. */
1717 if (VECTOR_MEM_VSX_P (mode
))
1719 if (FP_REGNO_P (regno
))
1720 return FP_REGNO_P (last_regno
);
1722 if (ALTIVEC_REGNO_P (regno
))
1723 return ALTIVEC_REGNO_P (last_regno
);
1726 /* The GPRs can hold any mode, but values bigger than one register
1727 cannot go past R31. */
1728 if (INT_REGNO_P (regno
))
1729 return INT_REGNO_P (last_regno
);
1731 /* The float registers (except for VSX vector modes) can only hold floating
1732 modes and DImode. This excludes the 32-bit decimal float mode for
1734 if (FP_REGNO_P (regno
))
1736 if (SCALAR_FLOAT_MODE_P (mode
)
1737 && (mode
!= TDmode
|| (regno
% 2) == 0)
1738 && FP_REGNO_P (last_regno
))
1741 if (GET_MODE_CLASS (mode
) == MODE_INT
1742 && GET_MODE_SIZE (mode
) == UNITS_PER_FP_WORD
)
1745 if (PAIRED_SIMD_REGNO_P (regno
) && TARGET_PAIRED_FLOAT
1746 && PAIRED_VECTOR_MODE (mode
))
1752 /* The CR register can only hold CC modes. */
1753 if (CR_REGNO_P (regno
))
1754 return GET_MODE_CLASS (mode
) == MODE_CC
;
1756 if (CA_REGNO_P (regno
))
1757 return mode
== BImode
;
1759 /* AltiVec only in AldyVec registers. */
1760 if (ALTIVEC_REGNO_P (regno
))
1761 return VECTOR_MEM_ALTIVEC_OR_VSX_P (mode
);
1763 /* ...but GPRs can hold SIMD data on the SPE in one register. */
1764 if (SPE_SIMD_REGNO_P (regno
) && TARGET_SPE
&& SPE_VECTOR_MODE (mode
))
1767 /* We cannot put TImode anywhere except general register and it must be able
1768 to fit within the register set. In the future, allow TImode in the
1769 Altivec or VSX registers. */
1771 return GET_MODE_SIZE (mode
) <= UNITS_PER_WORD
;
1774 /* Print interesting facts about registers. */
1776 rs6000_debug_reg_print (int first_regno
, int last_regno
, const char *reg_name
)
1780 for (r
= first_regno
; r
<= last_regno
; ++r
)
1782 const char *comma
= "";
1785 if (first_regno
== last_regno
)
1786 fprintf (stderr
, "%s:\t", reg_name
);
1788 fprintf (stderr
, "%s%d:\t", reg_name
, r
- first_regno
);
1791 for (m
= 0; m
< NUM_MACHINE_MODES
; ++m
)
1792 if (rs6000_hard_regno_mode_ok_p
[m
][r
] && rs6000_hard_regno_nregs
[m
][r
])
1796 fprintf (stderr
, ",\n\t");
1801 if (rs6000_hard_regno_nregs
[m
][r
] > 1)
1802 len
+= fprintf (stderr
, "%s%s/%d", comma
, GET_MODE_NAME (m
),
1803 rs6000_hard_regno_nregs
[m
][r
]);
1805 len
+= fprintf (stderr
, "%s%s", comma
, GET_MODE_NAME (m
));
1810 if (call_used_regs
[r
])
1814 fprintf (stderr
, ",\n\t");
1819 len
+= fprintf (stderr
, "%s%s", comma
, "call-used");
1827 fprintf (stderr
, ",\n\t");
1832 len
+= fprintf (stderr
, "%s%s", comma
, "fixed");
1838 fprintf (stderr
, ",\n\t");
1842 fprintf (stderr
, "%sregno = %d\n", comma
, r
);
1846 /* Print various interesting information with -mdebug=reg. */
1848 rs6000_debug_reg_global (void)
1850 const char *nl
= (const char *)0;
1852 char costly_num
[20];
1854 const char *costly_str
;
1855 const char *nop_str
;
1857 /* Map enum rs6000_vector to string. */
1858 static const char *rs6000_debug_vector_unit
[] = {
1867 fprintf (stderr
, "Register information: (last virtual reg = %d)\n",
1868 LAST_VIRTUAL_REGISTER
);
1869 rs6000_debug_reg_print (0, 31, "gr");
1870 rs6000_debug_reg_print (32, 63, "fp");
1871 rs6000_debug_reg_print (FIRST_ALTIVEC_REGNO
,
1874 rs6000_debug_reg_print (LR_REGNO
, LR_REGNO
, "lr");
1875 rs6000_debug_reg_print (CTR_REGNO
, CTR_REGNO
, "ctr");
1876 rs6000_debug_reg_print (CR0_REGNO
, CR7_REGNO
, "cr");
1877 rs6000_debug_reg_print (MQ_REGNO
, MQ_REGNO
, "mq");
1878 rs6000_debug_reg_print (CA_REGNO
, CA_REGNO
, "ca");
1879 rs6000_debug_reg_print (VRSAVE_REGNO
, VRSAVE_REGNO
, "vrsave");
1880 rs6000_debug_reg_print (VSCR_REGNO
, VSCR_REGNO
, "vscr");
1881 rs6000_debug_reg_print (SPE_ACC_REGNO
, SPE_ACC_REGNO
, "spe_a");
1882 rs6000_debug_reg_print (SPEFSCR_REGNO
, SPEFSCR_REGNO
, "spe_f");
1886 "d reg_class = %s\n"
1887 "f reg_class = %s\n"
1888 "v reg_class = %s\n"
1889 "wa reg_class = %s\n"
1890 "wd reg_class = %s\n"
1891 "wf reg_class = %s\n"
1892 "ws reg_class = %s\n\n",
1893 reg_class_names
[rs6000_constraints
[RS6000_CONSTRAINT_d
]],
1894 reg_class_names
[rs6000_constraints
[RS6000_CONSTRAINT_f
]],
1895 reg_class_names
[rs6000_constraints
[RS6000_CONSTRAINT_v
]],
1896 reg_class_names
[rs6000_constraints
[RS6000_CONSTRAINT_wa
]],
1897 reg_class_names
[rs6000_constraints
[RS6000_CONSTRAINT_wd
]],
1898 reg_class_names
[rs6000_constraints
[RS6000_CONSTRAINT_wf
]],
1899 reg_class_names
[rs6000_constraints
[RS6000_CONSTRAINT_ws
]]);
1901 for (m
= 0; m
< NUM_MACHINE_MODES
; ++m
)
1902 if (rs6000_vector_unit
[m
] || rs6000_vector_mem
[m
])
1905 fprintf (stderr
, "Vector mode: %-5s arithmetic: %-8s move: %-8s\n",
1907 rs6000_debug_vector_unit
[ rs6000_vector_unit
[m
] ],
1908 rs6000_debug_vector_unit
[ rs6000_vector_mem
[m
] ]);
1914 if (rs6000_recip_control
)
1916 fprintf (stderr
, "\nReciprocal mask = 0x%x\n", rs6000_recip_control
);
1918 for (m
= 0; m
< NUM_MACHINE_MODES
; ++m
)
1919 if (rs6000_recip_bits
[m
])
1922 "Reciprocal estimate mode: %-5s divide: %s rsqrt: %s\n",
1924 (RS6000_RECIP_AUTO_RE_P (m
)
1926 : (RS6000_RECIP_HAVE_RE_P (m
) ? "have" : "none")),
1927 (RS6000_RECIP_AUTO_RSQRTE_P (m
)
1929 : (RS6000_RECIP_HAVE_RSQRTE_P (m
) ? "have" : "none")));
1932 fputs ("\n", stderr
);
1935 switch (rs6000_sched_costly_dep
)
1937 case max_dep_latency
:
1938 costly_str
= "max_dep_latency";
1942 costly_str
= "no_dep_costly";
1945 case all_deps_costly
:
1946 costly_str
= "all_deps_costly";
1949 case true_store_to_load_dep_costly
:
1950 costly_str
= "true_store_to_load_dep_costly";
1953 case store_to_load_dep_costly
:
1954 costly_str
= "store_to_load_dep_costly";
1958 costly_str
= costly_num
;
1959 sprintf (costly_num
, "%d", (int)rs6000_sched_costly_dep
);
1963 switch (rs6000_sched_insert_nops
)
1965 case sched_finish_regroup_exact
:
1966 nop_str
= "sched_finish_regroup_exact";
1969 case sched_finish_pad_groups
:
1970 nop_str
= "sched_finish_pad_groups";
1973 case sched_finish_none
:
1974 nop_str
= "sched_finish_none";
1979 sprintf (nop_num
, "%d", (int)rs6000_sched_insert_nops
);
1984 "always_hint = %s\n"
1985 "align_branch_targets = %s\n"
1986 "sched_restricted_insns_priority = %d\n"
1987 "sched_costly_dep = %s\n"
1988 "sched_insert_nops = %s\n\n",
1989 rs6000_always_hint
? "true" : "false",
1990 rs6000_align_branch_targets
? "true" : "false",
1991 (int)rs6000_sched_restricted_insns_priority
,
1992 costly_str
, nop_str
);
1995 /* Initialize the various global tables that are based on register size. */
1997 rs6000_init_hard_regno_mode_ok (void)
2003 /* Precalculate REGNO_REG_CLASS. */
2004 rs6000_regno_regclass
[0] = GENERAL_REGS
;
2005 for (r
= 1; r
< 32; ++r
)
2006 rs6000_regno_regclass
[r
] = BASE_REGS
;
2008 for (r
= 32; r
< 64; ++r
)
2009 rs6000_regno_regclass
[r
] = FLOAT_REGS
;
2011 for (r
= 64; r
< FIRST_PSEUDO_REGISTER
; ++r
)
2012 rs6000_regno_regclass
[r
] = NO_REGS
;
2014 for (r
= FIRST_ALTIVEC_REGNO
; r
<= LAST_ALTIVEC_REGNO
; ++r
)
2015 rs6000_regno_regclass
[r
] = ALTIVEC_REGS
;
2017 rs6000_regno_regclass
[CR0_REGNO
] = CR0_REGS
;
2018 for (r
= CR1_REGNO
; r
<= CR7_REGNO
; ++r
)
2019 rs6000_regno_regclass
[r
] = CR_REGS
;
2021 rs6000_regno_regclass
[MQ_REGNO
] = MQ_REGS
;
2022 rs6000_regno_regclass
[LR_REGNO
] = LINK_REGS
;
2023 rs6000_regno_regclass
[CTR_REGNO
] = CTR_REGS
;
2024 rs6000_regno_regclass
[CA_REGNO
] = CA_REGS
;
2025 rs6000_regno_regclass
[VRSAVE_REGNO
] = VRSAVE_REGS
;
2026 rs6000_regno_regclass
[VSCR_REGNO
] = VRSAVE_REGS
;
2027 rs6000_regno_regclass
[SPE_ACC_REGNO
] = SPE_ACC_REGS
;
2028 rs6000_regno_regclass
[SPEFSCR_REGNO
] = SPEFSCR_REGS
;
2029 rs6000_regno_regclass
[ARG_POINTER_REGNUM
] = BASE_REGS
;
2030 rs6000_regno_regclass
[FRAME_POINTER_REGNUM
] = BASE_REGS
;
2032 /* Precalculate vector information, this must be set up before the
2033 rs6000_hard_regno_nregs_internal below. */
2034 for (m
= 0; m
< NUM_MACHINE_MODES
; ++m
)
2036 rs6000_vector_unit
[m
] = rs6000_vector_mem
[m
] = VECTOR_NONE
;
2037 rs6000_vector_reload
[m
][0] = CODE_FOR_nothing
;
2038 rs6000_vector_reload
[m
][1] = CODE_FOR_nothing
;
2041 for (c
= 0; c
< (int)(int)RS6000_CONSTRAINT_MAX
; c
++)
2042 rs6000_constraints
[c
] = NO_REGS
;
2044 /* The VSX hardware allows native alignment for vectors, but control whether the compiler
2045 believes it can use native alignment or still uses 128-bit alignment. */
2046 if (TARGET_VSX
&& !TARGET_VSX_ALIGN_128
)
2057 /* V2DF mode, VSX only. */
2060 rs6000_vector_unit
[V2DFmode
] = VECTOR_VSX
;
2061 rs6000_vector_mem
[V2DFmode
] = VECTOR_VSX
;
2062 rs6000_vector_align
[V2DFmode
] = align64
;
2065 /* V4SF mode, either VSX or Altivec. */
2068 rs6000_vector_unit
[V4SFmode
] = VECTOR_VSX
;
2069 rs6000_vector_mem
[V4SFmode
] = VECTOR_VSX
;
2070 rs6000_vector_align
[V4SFmode
] = align32
;
2072 else if (TARGET_ALTIVEC
)
2074 rs6000_vector_unit
[V4SFmode
] = VECTOR_ALTIVEC
;
2075 rs6000_vector_mem
[V4SFmode
] = VECTOR_ALTIVEC
;
2076 rs6000_vector_align
[V4SFmode
] = align32
;
2079 /* V16QImode, V8HImode, V4SImode are Altivec only, but possibly do VSX loads
2083 rs6000_vector_unit
[V4SImode
] = VECTOR_ALTIVEC
;
2084 rs6000_vector_unit
[V8HImode
] = VECTOR_ALTIVEC
;
2085 rs6000_vector_unit
[V16QImode
] = VECTOR_ALTIVEC
;
2086 rs6000_vector_align
[V4SImode
] = align32
;
2087 rs6000_vector_align
[V8HImode
] = align32
;
2088 rs6000_vector_align
[V16QImode
] = align32
;
2092 rs6000_vector_mem
[V4SImode
] = VECTOR_VSX
;
2093 rs6000_vector_mem
[V8HImode
] = VECTOR_VSX
;
2094 rs6000_vector_mem
[V16QImode
] = VECTOR_VSX
;
2098 rs6000_vector_mem
[V4SImode
] = VECTOR_ALTIVEC
;
2099 rs6000_vector_mem
[V8HImode
] = VECTOR_ALTIVEC
;
2100 rs6000_vector_mem
[V16QImode
] = VECTOR_ALTIVEC
;
2104 /* V2DImode, only allow under VSX, which can do V2DI insert/splat/extract.
2105 Altivec doesn't have 64-bit support. */
2108 rs6000_vector_mem
[V2DImode
] = VECTOR_VSX
;
2109 rs6000_vector_unit
[V2DImode
] = VECTOR_NONE
;
2110 rs6000_vector_align
[V2DImode
] = align64
;
2113 /* DFmode, see if we want to use the VSX unit. */
2114 if (TARGET_VSX
&& TARGET_VSX_SCALAR_DOUBLE
)
2116 rs6000_vector_unit
[DFmode
] = VECTOR_VSX
;
2117 rs6000_vector_mem
[DFmode
]
2118 = (TARGET_VSX_SCALAR_MEMORY
? VECTOR_VSX
: VECTOR_NONE
);
2119 rs6000_vector_align
[DFmode
] = align64
;
2122 /* TODO add SPE and paired floating point vector support. */
2124 /* Register class constaints for the constraints that depend on compile
2126 if (TARGET_HARD_FLOAT
&& TARGET_FPRS
)
2127 rs6000_constraints
[RS6000_CONSTRAINT_f
] = FLOAT_REGS
;
2129 if (TARGET_HARD_FLOAT
&& TARGET_FPRS
&& TARGET_DOUBLE_FLOAT
)
2130 rs6000_constraints
[RS6000_CONSTRAINT_d
] = FLOAT_REGS
;
2134 /* At present, we just use VSX_REGS, but we have different constraints
2135 based on the use, in case we want to fine tune the default register
2136 class used. wa = any VSX register, wf = register class to use for
2137 V4SF, wd = register class to use for V2DF, and ws = register classs to
2138 use for DF scalars. */
2139 rs6000_constraints
[RS6000_CONSTRAINT_wa
] = VSX_REGS
;
2140 rs6000_constraints
[RS6000_CONSTRAINT_wf
] = VSX_REGS
;
2141 rs6000_constraints
[RS6000_CONSTRAINT_wd
] = VSX_REGS
;
2142 rs6000_constraints
[RS6000_CONSTRAINT_ws
] = (TARGET_VSX_SCALAR_MEMORY
2148 rs6000_constraints
[RS6000_CONSTRAINT_v
] = ALTIVEC_REGS
;
2150 /* Set up the reload helper functions. */
2151 if (TARGET_VSX
|| TARGET_ALTIVEC
)
2155 rs6000_vector_reload
[V16QImode
][0] = CODE_FOR_reload_v16qi_di_store
;
2156 rs6000_vector_reload
[V16QImode
][1] = CODE_FOR_reload_v16qi_di_load
;
2157 rs6000_vector_reload
[V8HImode
][0] = CODE_FOR_reload_v8hi_di_store
;
2158 rs6000_vector_reload
[V8HImode
][1] = CODE_FOR_reload_v8hi_di_load
;
2159 rs6000_vector_reload
[V4SImode
][0] = CODE_FOR_reload_v4si_di_store
;
2160 rs6000_vector_reload
[V4SImode
][1] = CODE_FOR_reload_v4si_di_load
;
2161 rs6000_vector_reload
[V2DImode
][0] = CODE_FOR_reload_v2di_di_store
;
2162 rs6000_vector_reload
[V2DImode
][1] = CODE_FOR_reload_v2di_di_load
;
2163 rs6000_vector_reload
[V4SFmode
][0] = CODE_FOR_reload_v4sf_di_store
;
2164 rs6000_vector_reload
[V4SFmode
][1] = CODE_FOR_reload_v4sf_di_load
;
2165 rs6000_vector_reload
[V2DFmode
][0] = CODE_FOR_reload_v2df_di_store
;
2166 rs6000_vector_reload
[V2DFmode
][1] = CODE_FOR_reload_v2df_di_load
;
2170 rs6000_vector_reload
[V16QImode
][0] = CODE_FOR_reload_v16qi_si_store
;
2171 rs6000_vector_reload
[V16QImode
][1] = CODE_FOR_reload_v16qi_si_load
;
2172 rs6000_vector_reload
[V8HImode
][0] = CODE_FOR_reload_v8hi_si_store
;
2173 rs6000_vector_reload
[V8HImode
][1] = CODE_FOR_reload_v8hi_si_load
;
2174 rs6000_vector_reload
[V4SImode
][0] = CODE_FOR_reload_v4si_si_store
;
2175 rs6000_vector_reload
[V4SImode
][1] = CODE_FOR_reload_v4si_si_load
;
2176 rs6000_vector_reload
[V2DImode
][0] = CODE_FOR_reload_v2di_si_store
;
2177 rs6000_vector_reload
[V2DImode
][1] = CODE_FOR_reload_v2di_si_load
;
2178 rs6000_vector_reload
[V4SFmode
][0] = CODE_FOR_reload_v4sf_si_store
;
2179 rs6000_vector_reload
[V4SFmode
][1] = CODE_FOR_reload_v4sf_si_load
;
2180 rs6000_vector_reload
[V2DFmode
][0] = CODE_FOR_reload_v2df_si_store
;
2181 rs6000_vector_reload
[V2DFmode
][1] = CODE_FOR_reload_v2df_si_load
;
2185 /* Precalculate HARD_REGNO_NREGS. */
2186 for (r
= 0; r
< FIRST_PSEUDO_REGISTER
; ++r
)
2187 for (m
= 0; m
< NUM_MACHINE_MODES
; ++m
)
2188 rs6000_hard_regno_nregs
[m
][r
]
2189 = rs6000_hard_regno_nregs_internal (r
, (enum machine_mode
)m
);
2191 /* Precalculate HARD_REGNO_MODE_OK. */
2192 for (r
= 0; r
< FIRST_PSEUDO_REGISTER
; ++r
)
2193 for (m
= 0; m
< NUM_MACHINE_MODES
; ++m
)
2194 if (rs6000_hard_regno_mode_ok (r
, (enum machine_mode
)m
))
2195 rs6000_hard_regno_mode_ok_p
[m
][r
] = true;
2197 /* Precalculate CLASS_MAX_NREGS sizes. */
2198 for (c
= 0; c
< LIM_REG_CLASSES
; ++c
)
2202 if (TARGET_VSX
&& VSX_REG_CLASS_P (c
))
2203 reg_size
= UNITS_PER_VSX_WORD
;
2205 else if (c
== ALTIVEC_REGS
)
2206 reg_size
= UNITS_PER_ALTIVEC_WORD
;
2208 else if (c
== FLOAT_REGS
)
2209 reg_size
= UNITS_PER_FP_WORD
;
2212 reg_size
= UNITS_PER_WORD
;
2214 for (m
= 0; m
< NUM_MACHINE_MODES
; ++m
)
2215 rs6000_class_max_nregs
[m
][c
]
2216 = (GET_MODE_SIZE (m
) + reg_size
- 1) / reg_size
;
2219 if (TARGET_E500_DOUBLE
)
2220 rs6000_class_max_nregs
[DFmode
][GENERAL_REGS
] = 1;
2222 /* Calculate which modes to automatically generate code to use a the
2223 reciprocal divide and square root instructions. In the future, possibly
2224 automatically generate the instructions even if the user did not specify
2225 -mrecip. The older machines double precision reciprocal sqrt estimate is
2226 not accurate enough. */
2227 memset (rs6000_recip_bits
, 0, sizeof (rs6000_recip_bits
));
2229 rs6000_recip_bits
[SFmode
] = RS6000_RECIP_MASK_HAVE_RE
;
2231 rs6000_recip_bits
[DFmode
] = RS6000_RECIP_MASK_HAVE_RE
;
2232 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode
))
2233 rs6000_recip_bits
[V4SFmode
] = RS6000_RECIP_MASK_HAVE_RE
;
2234 if (VECTOR_UNIT_VSX_P (V2DFmode
))
2235 rs6000_recip_bits
[V2DFmode
] = RS6000_RECIP_MASK_HAVE_RE
;
2237 if (TARGET_FRSQRTES
)
2238 rs6000_recip_bits
[SFmode
] |= RS6000_RECIP_MASK_HAVE_RSQRTE
;
2240 rs6000_recip_bits
[DFmode
] |= RS6000_RECIP_MASK_HAVE_RSQRTE
;
2241 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode
))
2242 rs6000_recip_bits
[V4SFmode
] |= RS6000_RECIP_MASK_HAVE_RSQRTE
;
2243 if (VECTOR_UNIT_VSX_P (V2DFmode
))
2244 rs6000_recip_bits
[V2DFmode
] |= RS6000_RECIP_MASK_HAVE_RSQRTE
;
2246 if (rs6000_recip_control
)
2248 if (!TARGET_FUSED_MADD
)
2249 warning (0, "-mrecip requires -mfused-madd");
2250 if (!flag_finite_math_only
)
2251 warning (0, "-mrecip requires -ffinite-math or -ffast-math");
2252 if (flag_trapping_math
)
2253 warning (0, "-mrecip requires -fno-trapping-math or -ffast-math");
2254 if (!flag_reciprocal_math
)
2255 warning (0, "-mrecip requires -freciprocal-math or -ffast-math");
2256 if (TARGET_FUSED_MADD
&& flag_finite_math_only
&& !flag_trapping_math
2257 && flag_reciprocal_math
)
2259 if (RS6000_RECIP_HAVE_RE_P (SFmode
)
2260 && (rs6000_recip_control
& RECIP_SF_DIV
) != 0)
2261 rs6000_recip_bits
[SFmode
] |= RS6000_RECIP_MASK_AUTO_RE
;
2263 if (RS6000_RECIP_HAVE_RE_P (DFmode
)
2264 && (rs6000_recip_control
& RECIP_DF_DIV
) != 0)
2265 rs6000_recip_bits
[DFmode
] |= RS6000_RECIP_MASK_AUTO_RE
;
2267 if (RS6000_RECIP_HAVE_RE_P (V4SFmode
)
2268 && (rs6000_recip_control
& RECIP_V4SF_DIV
) != 0)
2269 rs6000_recip_bits
[V4SFmode
] |= RS6000_RECIP_MASK_AUTO_RE
;
2271 if (RS6000_RECIP_HAVE_RE_P (V2DFmode
)
2272 && (rs6000_recip_control
& RECIP_V2DF_DIV
) != 0)
2273 rs6000_recip_bits
[V2DFmode
] |= RS6000_RECIP_MASK_AUTO_RE
;
2275 if (RS6000_RECIP_HAVE_RSQRTE_P (SFmode
)
2276 && (rs6000_recip_control
& RECIP_SF_RSQRT
) != 0)
2277 rs6000_recip_bits
[SFmode
] |= RS6000_RECIP_MASK_AUTO_RSQRTE
;
2279 if (RS6000_RECIP_HAVE_RSQRTE_P (DFmode
)
2280 && (rs6000_recip_control
& RECIP_DF_RSQRT
) != 0)
2281 rs6000_recip_bits
[DFmode
] |= RS6000_RECIP_MASK_AUTO_RSQRTE
;
2283 if (RS6000_RECIP_HAVE_RSQRTE_P (V4SFmode
)
2284 && (rs6000_recip_control
& RECIP_V4SF_RSQRT
) != 0)
2285 rs6000_recip_bits
[V4SFmode
] |= RS6000_RECIP_MASK_AUTO_RSQRTE
;
2287 if (RS6000_RECIP_HAVE_RSQRTE_P (V2DFmode
)
2288 && (rs6000_recip_control
& RECIP_V2DF_RSQRT
) != 0)
2289 rs6000_recip_bits
[V2DFmode
] |= RS6000_RECIP_MASK_AUTO_RSQRTE
;
2293 if (TARGET_DEBUG_REG
)
2294 rs6000_debug_reg_global ();
2296 if (TARGET_DEBUG_COST
|| TARGET_DEBUG_REG
)
2298 "SImode variable mult cost = %d\n"
2299 "SImode constant mult cost = %d\n"
2300 "SImode short constant mult cost = %d\n"
2301 "DImode multipliciation cost = %d\n"
2302 "SImode division cost = %d\n"
2303 "DImode division cost = %d\n"
2304 "Simple fp operation cost = %d\n"
2305 "DFmode multiplication cost = %d\n"
2306 "SFmode division cost = %d\n"
2307 "DFmode division cost = %d\n"
2308 "cache line size = %d\n"
2309 "l1 cache size = %d\n"
2310 "l2 cache size = %d\n"
2311 "simultaneous prefetches = %d\n"
2314 rs6000_cost
->mulsi_const
,
2315 rs6000_cost
->mulsi_const9
,
2323 rs6000_cost
->cache_line_size
,
2324 rs6000_cost
->l1_cache_size
,
2325 rs6000_cost
->l2_cache_size
,
2326 rs6000_cost
->simultaneous_prefetches
);
2330 /* The Darwin version of SUBTARGET_OVERRIDE_OPTIONS. */
2333 darwin_rs6000_override_options (void)
2335 /* The Darwin ABI always includes AltiVec, can't be (validly) turned
2337 rs6000_altivec_abi
= 1;
2338 TARGET_ALTIVEC_VRSAVE
= 1;
2339 if (DEFAULT_ABI
== ABI_DARWIN
)
2341 if (MACHO_DYNAMIC_NO_PIC_P
)
2344 warning (0, "-mdynamic-no-pic overrides -fpic or -fPIC");
2347 else if (flag_pic
== 1)
2352 darwin_one_byte_bool
= 1;
2354 if (TARGET_64BIT
&& ! TARGET_POWERPC64
)
2356 target_flags
|= MASK_POWERPC64
;
2357 warning (0, "-m64 requires PowerPC64 architecture, enabling");
2361 rs6000_default_long_calls
= 1;
2362 target_flags
|= MASK_SOFT_FLOAT
;
2365 /* Make -m64 imply -maltivec. Darwin's 64-bit ABI includes
2367 if (!flag_mkernel
&& !flag_apple_kext
2369 && ! (target_flags_explicit
& MASK_ALTIVEC
))
2370 target_flags
|= MASK_ALTIVEC
;
2372 /* Unless the user (not the configurer) has explicitly overridden
2373 it with -mcpu=G3 or -mno-altivec, then 10.5+ targets default to
2374 G4 unless targetting the kernel. */
2377 && strverscmp (darwin_macosx_version_min
, "10.5") >= 0
2378 && ! (target_flags_explicit
& MASK_ALTIVEC
)
2379 && ! rs6000_select
[1].string
)
2381 target_flags
|= MASK_ALTIVEC
;
2386 /* If not otherwise specified by a target, make 'long double' equivalent to
2389 #ifndef RS6000_DEFAULT_LONG_DOUBLE_SIZE
2390 #define RS6000_DEFAULT_LONG_DOUBLE_SIZE 64
2393 /* Override command line options. Mostly we process the processor
2394 type and sometimes adjust other TARGET_ options. */
2397 rs6000_override_options (const char *default_cpu
)
2400 struct rs6000_cpu_select
*ptr
;
2403 /* Simplifications for entries below. */
2406 POWERPC_BASE_MASK
= MASK_POWERPC
| MASK_NEW_MNEMONICS
,
2407 POWERPC_7400_MASK
= POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
| MASK_ALTIVEC
2410 /* This table occasionally claims that a processor does not support
2411 a particular feature even though it does, but the feature is slower
2412 than the alternative. Thus, it shouldn't be relied on as a
2413 complete description of the processor's support.
2415 Please keep this list in order, and don't forget to update the
2416 documentation in invoke.texi when adding a new processor or
2420 const char *const name
; /* Canonical processor name. */
2421 const enum processor_type processor
; /* Processor type enum value. */
2422 const int target_enable
; /* Target flags to enable. */
2423 } const processor_target_table
[]
2424 = {{"401", PROCESSOR_PPC403
, POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
},
2425 {"403", PROCESSOR_PPC403
,
2426 POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
| MASK_STRICT_ALIGN
},
2427 {"405", PROCESSOR_PPC405
,
2428 POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
| MASK_MULHW
| MASK_DLMZB
},
2429 {"405fp", PROCESSOR_PPC405
,
2430 POWERPC_BASE_MASK
| MASK_MULHW
| MASK_DLMZB
},
2431 {"440", PROCESSOR_PPC440
,
2432 POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
| MASK_MULHW
| MASK_DLMZB
},
2433 {"440fp", PROCESSOR_PPC440
,
2434 POWERPC_BASE_MASK
| MASK_MULHW
| MASK_DLMZB
},
2435 {"464", PROCESSOR_PPC440
,
2436 POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
| MASK_MULHW
| MASK_DLMZB
},
2437 {"464fp", PROCESSOR_PPC440
,
2438 POWERPC_BASE_MASK
| MASK_MULHW
| MASK_DLMZB
},
2439 {"476", PROCESSOR_PPC476
,
2440 POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
| MASK_PPC_GFXOPT
| MASK_MFCRF
2441 | MASK_POPCNTB
| MASK_FPRND
| MASK_CMPB
| MASK_MULHW
| MASK_DLMZB
},
2442 {"476fp", PROCESSOR_PPC476
,
2443 POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
| MASK_MFCRF
| MASK_POPCNTB
2444 | MASK_FPRND
| MASK_CMPB
| MASK_MULHW
| MASK_DLMZB
},
2445 {"505", PROCESSOR_MPCCORE
, POWERPC_BASE_MASK
},
2446 {"601", PROCESSOR_PPC601
,
2447 MASK_POWER
| POWERPC_BASE_MASK
| MASK_MULTIPLE
| MASK_STRING
},
2448 {"602", PROCESSOR_PPC603
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
2449 {"603", PROCESSOR_PPC603
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
2450 {"603e", PROCESSOR_PPC603
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
2451 {"604", PROCESSOR_PPC604
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
2452 {"604e", PROCESSOR_PPC604e
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
2453 {"620", PROCESSOR_PPC620
,
2454 POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
| MASK_POWERPC64
},
2455 {"630", PROCESSOR_PPC630
,
2456 POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
| MASK_POWERPC64
},
2457 {"740", PROCESSOR_PPC750
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
2458 {"7400", PROCESSOR_PPC7400
, POWERPC_7400_MASK
},
2459 {"7450", PROCESSOR_PPC7450
, POWERPC_7400_MASK
},
2460 {"750", PROCESSOR_PPC750
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
2461 {"801", PROCESSOR_MPCCORE
, POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
},
2462 {"821", PROCESSOR_MPCCORE
, POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
},
2463 {"823", PROCESSOR_MPCCORE
, POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
},
2464 {"8540", PROCESSOR_PPC8540
, POWERPC_BASE_MASK
| MASK_STRICT_ALIGN
2466 /* 8548 has a dummy entry for now. */
2467 {"8548", PROCESSOR_PPC8540
, POWERPC_BASE_MASK
| MASK_STRICT_ALIGN
2469 {"a2", PROCESSOR_PPCA2
,
2470 POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
| MASK_POWERPC64
| MASK_POPCNTB
2471 | MASK_CMPB
| MASK_NO_UPDATE
},
2472 {"e300c2", PROCESSOR_PPCE300C2
, POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
},
2473 {"e300c3", PROCESSOR_PPCE300C3
, POWERPC_BASE_MASK
},
2474 {"e500mc", PROCESSOR_PPCE500MC
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
2476 {"e500mc64", PROCESSOR_PPCE500MC64
, POWERPC_BASE_MASK
| MASK_POWERPC64
2477 | MASK_PPC_GFXOPT
| MASK_ISEL
},
2478 {"860", PROCESSOR_MPCCORE
, POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
},
2479 {"970", PROCESSOR_POWER4
,
2480 POWERPC_7400_MASK
| MASK_PPC_GPOPT
| MASK_MFCRF
| MASK_POWERPC64
},
2481 {"cell", PROCESSOR_CELL
,
2482 POWERPC_7400_MASK
| MASK_PPC_GPOPT
| MASK_MFCRF
| MASK_POWERPC64
},
2483 {"common", PROCESSOR_COMMON
, MASK_NEW_MNEMONICS
},
2484 {"ec603e", PROCESSOR_PPC603
, POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
},
2485 {"G3", PROCESSOR_PPC750
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
2486 {"G4", PROCESSOR_PPC7450
, POWERPC_7400_MASK
},
2487 {"G5", PROCESSOR_POWER4
,
2488 POWERPC_7400_MASK
| MASK_PPC_GPOPT
| MASK_MFCRF
| MASK_POWERPC64
},
2489 {"titan", PROCESSOR_TITAN
,
2490 POWERPC_BASE_MASK
| MASK_MULHW
| MASK_DLMZB
},
2491 {"power", PROCESSOR_POWER
, MASK_POWER
| MASK_MULTIPLE
| MASK_STRING
},
2492 {"power2", PROCESSOR_POWER
,
2493 MASK_POWER
| MASK_POWER2
| MASK_MULTIPLE
| MASK_STRING
},
2494 {"power3", PROCESSOR_PPC630
,
2495 POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
| MASK_POWERPC64
},
2496 {"power4", PROCESSOR_POWER4
,
2497 POWERPC_BASE_MASK
| MASK_POWERPC64
| MASK_PPC_GPOPT
| MASK_PPC_GFXOPT
2499 {"power5", PROCESSOR_POWER5
,
2500 POWERPC_BASE_MASK
| MASK_POWERPC64
| MASK_PPC_GPOPT
| MASK_PPC_GFXOPT
2501 | MASK_MFCRF
| MASK_POPCNTB
},
2502 {"power5+", PROCESSOR_POWER5
,
2503 POWERPC_BASE_MASK
| MASK_POWERPC64
| MASK_PPC_GPOPT
| MASK_PPC_GFXOPT
2504 | MASK_MFCRF
| MASK_POPCNTB
| MASK_FPRND
},
2505 {"power6", PROCESSOR_POWER6
,
2506 POWERPC_BASE_MASK
| MASK_POWERPC64
| MASK_PPC_GPOPT
| MASK_PPC_GFXOPT
2507 | MASK_MFCRF
| MASK_POPCNTB
| MASK_FPRND
| MASK_CMPB
| MASK_DFP
2508 | MASK_RECIP_PRECISION
},
2509 {"power6x", PROCESSOR_POWER6
,
2510 POWERPC_BASE_MASK
| MASK_POWERPC64
| MASK_PPC_GPOPT
| MASK_PPC_GFXOPT
2511 | MASK_MFCRF
| MASK_POPCNTB
| MASK_FPRND
| MASK_CMPB
| MASK_DFP
2512 | MASK_MFPGPR
| MASK_RECIP_PRECISION
},
2513 {"power7", PROCESSOR_POWER7
, /* Don't add MASK_ISEL by default */
2514 POWERPC_7400_MASK
| MASK_POWERPC64
| MASK_PPC_GPOPT
| MASK_MFCRF
2515 | MASK_POPCNTB
| MASK_FPRND
| MASK_CMPB
| MASK_DFP
| MASK_POPCNTD
2516 | MASK_VSX
| MASK_RECIP_PRECISION
},
2517 {"powerpc", PROCESSOR_POWERPC
, POWERPC_BASE_MASK
},
2518 {"powerpc64", PROCESSOR_POWERPC64
,
2519 POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
| MASK_POWERPC64
},
2520 {"rios", PROCESSOR_RIOS1
, MASK_POWER
| MASK_MULTIPLE
| MASK_STRING
},
2521 {"rios1", PROCESSOR_RIOS1
, MASK_POWER
| MASK_MULTIPLE
| MASK_STRING
},
2522 {"rios2", PROCESSOR_RIOS2
,
2523 MASK_POWER
| MASK_POWER2
| MASK_MULTIPLE
| MASK_STRING
},
2524 {"rsc", PROCESSOR_PPC601
, MASK_POWER
| MASK_MULTIPLE
| MASK_STRING
},
2525 {"rsc1", PROCESSOR_PPC601
, MASK_POWER
| MASK_MULTIPLE
| MASK_STRING
},
2526 {"rs64", PROCESSOR_RS64A
,
2527 POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
| MASK_POWERPC64
}
2530 const size_t ptt_size
= ARRAY_SIZE (processor_target_table
);
2532 /* Some OSs don't support saving the high part of 64-bit registers on
2533 context switch. Other OSs don't support saving Altivec registers.
2534 On those OSs, we don't touch the MASK_POWERPC64 or MASK_ALTIVEC
2535 settings; if the user wants either, the user must explicitly specify
2536 them and we won't interfere with the user's specification. */
2539 POWER_MASKS
= MASK_POWER
| MASK_POWER2
| MASK_MULTIPLE
| MASK_STRING
,
2540 POWERPC_MASKS
= (POWERPC_BASE_MASK
| MASK_PPC_GPOPT
| MASK_STRICT_ALIGN
2541 | MASK_PPC_GFXOPT
| MASK_POWERPC64
| MASK_ALTIVEC
2542 | MASK_MFCRF
| MASK_POPCNTB
| MASK_FPRND
| MASK_MULHW
2543 | MASK_DLMZB
| MASK_CMPB
| MASK_MFPGPR
| MASK_DFP
2544 | MASK_POPCNTD
| MASK_VSX
| MASK_ISEL
| MASK_NO_UPDATE
2545 | MASK_RECIP_PRECISION
)
2548 /* Masks for instructions set at various powerpc ISAs. */
2550 ISA_2_1_MASKS
= MASK_MFCRF
,
2551 ISA_2_2_MASKS
= (ISA_2_1_MASKS
| MASK_POPCNTB
| MASK_FPRND
),
2553 /* For ISA 2.05, do not add MFPGPR, since it isn't in ISA 2.06, and don't
2554 add ALTIVEC, since in general it isn't a win on power6. In ISA 2.04,
2555 fsel, fre, fsqrt, etc. were no longer documented as optional. Group
2556 masks by server and embedded. */
2557 ISA_2_5_MASKS_EMBEDDED
= (ISA_2_2_MASKS
| MASK_CMPB
| MASK_RECIP_PRECISION
2558 | MASK_PPC_GFXOPT
| MASK_PPC_GPOPT
),
2559 ISA_2_5_MASKS_SERVER
= (ISA_2_5_MASKS_EMBEDDED
| MASK_DFP
),
2561 /* For ISA 2.06, don't add ISEL, since in general it isn't a win, but
2562 altivec is a win so enable it. */
2563 ISA_2_6_MASKS_EMBEDDED
= (ISA_2_5_MASKS_EMBEDDED
| MASK_POPCNTD
),
2564 ISA_2_6_MASKS_SERVER
= (ISA_2_5_MASKS_SERVER
| MASK_POPCNTD
| MASK_ALTIVEC
2568 /* Numerous experiment shows that IRA based loop pressure
2569 calculation works better for RTL loop invariant motion on targets
2570 with enough (>= 32) registers. It is an expensive optimization.
2571 So it is on only for peak performance. */
2573 flag_ira_loop_pressure
= 1;
2575 /* Set the pointer size. */
2578 rs6000_pmode
= (int)DImode
;
2579 rs6000_pointer_size
= 64;
2583 rs6000_pmode
= (int)SImode
;
2584 rs6000_pointer_size
= 32;
2587 set_masks
= POWER_MASKS
| POWERPC_MASKS
| MASK_SOFT_FLOAT
;
2588 #ifdef OS_MISSING_POWERPC64
2589 if (OS_MISSING_POWERPC64
)
2590 set_masks
&= ~MASK_POWERPC64
;
2592 #ifdef OS_MISSING_ALTIVEC
2593 if (OS_MISSING_ALTIVEC
)
2594 set_masks
&= ~MASK_ALTIVEC
;
2597 /* Don't override by the processor default if given explicitly. */
2598 set_masks
&= ~target_flags_explicit
;
2600 /* Identify the processor type. */
2601 rs6000_select
[0].string
= default_cpu
;
2602 rs6000_cpu
= TARGET_POWERPC64
? PROCESSOR_DEFAULT64
: PROCESSOR_DEFAULT
;
2604 for (i
= 0; i
< ARRAY_SIZE (rs6000_select
); i
++)
2606 ptr
= &rs6000_select
[i
];
2607 if (ptr
->string
!= (char *)0 && ptr
->string
[0] != '\0')
2609 for (j
= 0; j
< ptt_size
; j
++)
2610 if (! strcmp (ptr
->string
, processor_target_table
[j
].name
))
2612 if (ptr
->set_tune_p
)
2613 rs6000_cpu
= processor_target_table
[j
].processor
;
2615 if (ptr
->set_arch_p
)
2617 target_flags
&= ~set_masks
;
2618 target_flags
|= (processor_target_table
[j
].target_enable
2625 error ("bad value (%s) for %s switch", ptr
->string
, ptr
->name
);
2629 if (rs6000_cpu
== PROCESSOR_PPCE300C2
|| rs6000_cpu
== PROCESSOR_PPCE300C3
2630 || rs6000_cpu
== PROCESSOR_PPCE500MC
|| rs6000_cpu
== PROCESSOR_PPCE500MC64
)
2633 error ("AltiVec not supported in this target");
2635 error ("Spe not supported in this target");
2638 /* Disable Cell microcode if we are optimizing for the Cell
2639 and not optimizing for size. */
2640 if (rs6000_gen_cell_microcode
== -1)
2641 rs6000_gen_cell_microcode
= !(rs6000_cpu
== PROCESSOR_CELL
2644 /* If we are optimizing big endian systems for space and it's OK to
2645 use instructions that would be microcoded on the Cell, use the
2646 load/store multiple and string instructions. */
2647 if (BYTES_BIG_ENDIAN
&& optimize_size
&& rs6000_gen_cell_microcode
)
2648 target_flags
|= ~target_flags_explicit
& (MASK_MULTIPLE
| MASK_STRING
);
2650 /* Don't allow -mmultiple or -mstring on little endian systems
2651 unless the cpu is a 750, because the hardware doesn't support the
2652 instructions used in little endian mode, and causes an alignment
2653 trap. The 750 does not cause an alignment trap (except when the
2654 target is unaligned). */
2656 if (!BYTES_BIG_ENDIAN
&& rs6000_cpu
!= PROCESSOR_PPC750
)
2658 if (TARGET_MULTIPLE
)
2660 target_flags
&= ~MASK_MULTIPLE
;
2661 if ((target_flags_explicit
& MASK_MULTIPLE
) != 0)
2662 warning (0, "-mmultiple is not supported on little endian systems");
2667 target_flags
&= ~MASK_STRING
;
2668 if ((target_flags_explicit
& MASK_STRING
) != 0)
2669 warning (0, "-mstring is not supported on little endian systems");
2673 /* Add some warnings for VSX. */
2676 const char *msg
= NULL
;
2677 if (!TARGET_HARD_FLOAT
|| !TARGET_FPRS
2678 || !TARGET_SINGLE_FLOAT
|| !TARGET_DOUBLE_FLOAT
)
2680 if (target_flags_explicit
& MASK_VSX
)
2681 msg
= N_("-mvsx requires hardware floating point");
2683 target_flags
&= ~ MASK_VSX
;
2685 else if (TARGET_PAIRED_FLOAT
)
2686 msg
= N_("-mvsx and -mpaired are incompatible");
2687 /* The hardware will allow VSX and little endian, but until we make sure
2688 things like vector select, etc. work don't allow VSX on little endian
2689 systems at this point. */
2690 else if (!BYTES_BIG_ENDIAN
)
2691 msg
= N_("-mvsx used with little endian code");
2692 else if (TARGET_AVOID_XFORM
> 0)
2693 msg
= N_("-mvsx needs indexed addressing");
2694 else if (!TARGET_ALTIVEC
&& (target_flags_explicit
& MASK_ALTIVEC
))
2696 if (target_flags_explicit
& MASK_VSX
)
2697 msg
= N_("-mvsx and -mno-altivec are incompatible");
2699 msg
= N_("-mno-altivec disables vsx");
2705 target_flags
&= ~ MASK_VSX
;
2706 target_flags_explicit
|= MASK_VSX
;
2710 /* For the newer switches (vsx, dfp, etc.) set some of the older options,
2711 unless the user explicitly used the -mno-<option> to disable the code. */
2713 target_flags
|= (ISA_2_6_MASKS_SERVER
& ~target_flags_explicit
);
2714 else if (TARGET_POPCNTD
)
2715 target_flags
|= (ISA_2_6_MASKS_EMBEDDED
& ~target_flags_explicit
);
2716 else if (TARGET_DFP
)
2717 target_flags
|= (ISA_2_5_MASKS_SERVER
& ~target_flags_explicit
);
2718 else if (TARGET_CMPB
)
2719 target_flags
|= (ISA_2_5_MASKS_EMBEDDED
& ~target_flags_explicit
);
2720 else if (TARGET_POPCNTB
|| TARGET_FPRND
)
2721 target_flags
|= (ISA_2_2_MASKS
& ~target_flags_explicit
);
2722 else if (TARGET_ALTIVEC
)
2723 target_flags
|= (MASK_PPC_GFXOPT
& ~target_flags_explicit
);
2725 /* E500mc does "better" if we inline more aggressively. Respect the
2726 user's opinion, though. */
2727 if (rs6000_block_move_inline_limit
== 0
2728 && (rs6000_cpu
== PROCESSOR_PPCE500MC
2729 || rs6000_cpu
== PROCESSOR_PPCE500MC64
))
2730 rs6000_block_move_inline_limit
= 128;
2732 /* store_one_arg depends on expand_block_move to handle at least the
2733 size of reg_parm_stack_space. */
2734 if (rs6000_block_move_inline_limit
< (TARGET_POWERPC64
? 64 : 32))
2735 rs6000_block_move_inline_limit
= (TARGET_POWERPC64
? 64 : 32);
2737 /* Set debug flags */
2738 if (rs6000_debug_name
)
2740 if (! strcmp (rs6000_debug_name
, "all"))
2741 rs6000_debug_stack
= rs6000_debug_arg
= rs6000_debug_reg
2742 = rs6000_debug_addr
= rs6000_debug_cost
= 1;
2743 else if (! strcmp (rs6000_debug_name
, "stack"))
2744 rs6000_debug_stack
= 1;
2745 else if (! strcmp (rs6000_debug_name
, "arg"))
2746 rs6000_debug_arg
= 1;
2747 else if (! strcmp (rs6000_debug_name
, "reg"))
2748 rs6000_debug_reg
= 1;
2749 else if (! strcmp (rs6000_debug_name
, "addr"))
2750 rs6000_debug_addr
= 1;
2751 else if (! strcmp (rs6000_debug_name
, "cost"))
2752 rs6000_debug_cost
= 1;
2754 error ("unknown -mdebug-%s switch", rs6000_debug_name
);
2756 /* If the appropriate debug option is enabled, replace the target hooks
2757 with debug versions that call the real version and then prints
2758 debugging information. */
2759 if (TARGET_DEBUG_COST
)
2761 targetm
.rtx_costs
= rs6000_debug_rtx_costs
;
2762 targetm
.address_cost
= rs6000_debug_address_cost
;
2763 targetm
.sched
.adjust_cost
= rs6000_debug_adjust_cost
;
2766 if (TARGET_DEBUG_ADDR
)
2768 targetm
.legitimate_address_p
= rs6000_debug_legitimate_address_p
;
2769 targetm
.legitimize_address
= rs6000_debug_legitimize_address
;
2770 rs6000_secondary_reload_class_ptr
2771 = rs6000_debug_secondary_reload_class
;
2772 rs6000_secondary_memory_needed_ptr
2773 = rs6000_debug_secondary_memory_needed
;
2774 rs6000_cannot_change_mode_class_ptr
2775 = rs6000_debug_cannot_change_mode_class
;
2776 rs6000_preferred_reload_class_ptr
2777 = rs6000_debug_preferred_reload_class
;
2778 rs6000_legitimize_reload_address_ptr
2779 = rs6000_debug_legitimize_reload_address
;
2780 rs6000_mode_dependent_address_ptr
2781 = rs6000_debug_mode_dependent_address
;
2785 if (rs6000_traceback_name
)
2787 if (! strncmp (rs6000_traceback_name
, "full", 4))
2788 rs6000_traceback
= traceback_full
;
2789 else if (! strncmp (rs6000_traceback_name
, "part", 4))
2790 rs6000_traceback
= traceback_part
;
2791 else if (! strncmp (rs6000_traceback_name
, "no", 2))
2792 rs6000_traceback
= traceback_none
;
2794 error ("unknown -mtraceback arg %qs; expecting %<full%>, %<partial%> or %<none%>",
2795 rs6000_traceback_name
);
2798 if (rs6000_veclibabi_name
)
2800 if (strcmp (rs6000_veclibabi_name
, "mass") == 0)
2801 rs6000_veclib_handler
= rs6000_builtin_vectorized_libmass
;
2803 error ("unknown vectorization library ABI type (%s) for "
2804 "-mveclibabi= switch", rs6000_veclibabi_name
);
2807 if (!rs6000_explicit_options
.long_double
)
2808 rs6000_long_double_type_size
= RS6000_DEFAULT_LONG_DOUBLE_SIZE
;
2810 #ifndef POWERPC_LINUX
2811 if (!rs6000_explicit_options
.ieee
)
2812 rs6000_ieeequad
= 1;
2815 /* Enable Altivec ABI for AIX -maltivec. */
2816 if (TARGET_XCOFF
&& (TARGET_ALTIVEC
|| TARGET_VSX
))
2817 rs6000_altivec_abi
= 1;
2819 /* The AltiVec ABI is the default for PowerPC-64 GNU/Linux. For
2820 PowerPC-32 GNU/Linux, -maltivec implies the AltiVec ABI. It can
2821 be explicitly overridden in either case. */
2824 if (!rs6000_explicit_options
.altivec_abi
2825 && (TARGET_64BIT
|| TARGET_ALTIVEC
|| TARGET_VSX
))
2826 rs6000_altivec_abi
= 1;
2828 /* Enable VRSAVE for AltiVec ABI, unless explicitly overridden. */
2829 if (!rs6000_explicit_options
.vrsave
)
2830 TARGET_ALTIVEC_VRSAVE
= rs6000_altivec_abi
;
2833 /* Set the Darwin64 ABI as default for 64-bit Darwin.
2834 So far, the only darwin64 targets are also MACH-O. */
2836 && DEFAULT_ABI
== ABI_DARWIN
2839 rs6000_darwin64_abi
= 1;
2840 /* Default to natural alignment, for better performance. */
2841 rs6000_alignment_flags
= MASK_ALIGN_NATURAL
;
2844 /* Place FP constants in the constant pool instead of TOC
2845 if section anchors enabled. */
2846 if (flag_section_anchors
)
2847 TARGET_NO_FP_IN_TOC
= 1;
2849 /* Handle -mtls-size option. */
2850 rs6000_parse_tls_size_option ();
2852 #ifdef SUBTARGET_OVERRIDE_OPTIONS
2853 SUBTARGET_OVERRIDE_OPTIONS
;
2855 #ifdef SUBSUBTARGET_OVERRIDE_OPTIONS
2856 SUBSUBTARGET_OVERRIDE_OPTIONS
;
2858 #ifdef SUB3TARGET_OVERRIDE_OPTIONS
2859 SUB3TARGET_OVERRIDE_OPTIONS
;
2862 if (TARGET_E500
|| rs6000_cpu
== PROCESSOR_PPCE500MC
2863 || rs6000_cpu
== PROCESSOR_PPCE500MC64
)
2865 /* The e500 and e500mc do not have string instructions, and we set
2866 MASK_STRING above when optimizing for size. */
2867 if ((target_flags
& MASK_STRING
) != 0)
2868 target_flags
= target_flags
& ~MASK_STRING
;
2870 else if (rs6000_select
[1].string
!= NULL
)
2872 /* For the powerpc-eabispe configuration, we set all these by
2873 default, so let's unset them if we manually set another
2874 CPU that is not the E500. */
2875 if (!rs6000_explicit_options
.spe_abi
)
2877 if (!rs6000_explicit_options
.spe
)
2879 if (!rs6000_explicit_options
.float_gprs
)
2880 rs6000_float_gprs
= 0;
2881 if (!(target_flags_explicit
& MASK_ISEL
))
2882 target_flags
&= ~MASK_ISEL
;
2885 /* Detect invalid option combinations with E500. */
2888 rs6000_always_hint
= (rs6000_cpu
!= PROCESSOR_POWER4
2889 && rs6000_cpu
!= PROCESSOR_POWER5
2890 && rs6000_cpu
!= PROCESSOR_POWER6
2891 && rs6000_cpu
!= PROCESSOR_POWER7
2892 && rs6000_cpu
!= PROCESSOR_PPCA2
2893 && rs6000_cpu
!= PROCESSOR_CELL
);
2894 rs6000_sched_groups
= (rs6000_cpu
== PROCESSOR_POWER4
2895 || rs6000_cpu
== PROCESSOR_POWER5
2896 || rs6000_cpu
== PROCESSOR_POWER7
);
2897 rs6000_align_branch_targets
= (rs6000_cpu
== PROCESSOR_POWER4
2898 || rs6000_cpu
== PROCESSOR_POWER5
2899 || rs6000_cpu
== PROCESSOR_POWER6
2900 || rs6000_cpu
== PROCESSOR_POWER7
2901 || rs6000_cpu
== PROCESSOR_PPCE500MC
2902 || rs6000_cpu
== PROCESSOR_PPCE500MC64
);
2904 /* Allow debug switches to override the above settings. */
2905 if (TARGET_ALWAYS_HINT
> 0)
2906 rs6000_always_hint
= TARGET_ALWAYS_HINT
;
2908 if (TARGET_SCHED_GROUPS
> 0)
2909 rs6000_sched_groups
= TARGET_SCHED_GROUPS
;
2911 if (TARGET_ALIGN_BRANCH_TARGETS
> 0)
2912 rs6000_align_branch_targets
= TARGET_ALIGN_BRANCH_TARGETS
;
2914 rs6000_sched_restricted_insns_priority
2915 = (rs6000_sched_groups
? 1 : 0);
2917 /* Handle -msched-costly-dep option. */
2918 rs6000_sched_costly_dep
2919 = (rs6000_sched_groups
? store_to_load_dep_costly
: no_dep_costly
);
2921 if (rs6000_sched_costly_dep_str
)
2923 if (! strcmp (rs6000_sched_costly_dep_str
, "no"))
2924 rs6000_sched_costly_dep
= no_dep_costly
;
2925 else if (! strcmp (rs6000_sched_costly_dep_str
, "all"))
2926 rs6000_sched_costly_dep
= all_deps_costly
;
2927 else if (! strcmp (rs6000_sched_costly_dep_str
, "true_store_to_load"))
2928 rs6000_sched_costly_dep
= true_store_to_load_dep_costly
;
2929 else if (! strcmp (rs6000_sched_costly_dep_str
, "store_to_load"))
2930 rs6000_sched_costly_dep
= store_to_load_dep_costly
;
2932 rs6000_sched_costly_dep
= ((enum rs6000_dependence_cost
)
2933 atoi (rs6000_sched_costly_dep_str
));
2936 /* Handle -minsert-sched-nops option. */
2937 rs6000_sched_insert_nops
2938 = (rs6000_sched_groups
? sched_finish_regroup_exact
: sched_finish_none
);
2940 if (rs6000_sched_insert_nops_str
)
2942 if (! strcmp (rs6000_sched_insert_nops_str
, "no"))
2943 rs6000_sched_insert_nops
= sched_finish_none
;
2944 else if (! strcmp (rs6000_sched_insert_nops_str
, "pad"))
2945 rs6000_sched_insert_nops
= sched_finish_pad_groups
;
2946 else if (! strcmp (rs6000_sched_insert_nops_str
, "regroup_exact"))
2947 rs6000_sched_insert_nops
= sched_finish_regroup_exact
;
2949 rs6000_sched_insert_nops
= ((enum rs6000_nop_insertion
)
2950 atoi (rs6000_sched_insert_nops_str
));
2953 #ifdef TARGET_REGNAMES
2954 /* If the user desires alternate register names, copy in the
2955 alternate names now. */
2956 if (TARGET_REGNAMES
)
2957 memcpy (rs6000_reg_names
, alt_reg_names
, sizeof (rs6000_reg_names
));
2960 /* Set aix_struct_return last, after the ABI is determined.
2961 If -maix-struct-return or -msvr4-struct-return was explicitly
2962 used, don't override with the ABI default. */
2963 if (!rs6000_explicit_options
.aix_struct_ret
)
2964 aix_struct_return
= (DEFAULT_ABI
!= ABI_V4
|| DRAFT_V4_STRUCT_RET
);
2967 /* IBM XL compiler defaults to unsigned bitfields. */
2968 if (TARGET_XL_COMPAT
)
2969 flag_signed_bitfields
= 0;
2972 if (TARGET_LONG_DOUBLE_128
&& !TARGET_IEEEQUAD
)
2973 REAL_MODE_FORMAT (TFmode
) = &ibm_extended_format
;
2976 ASM_GENERATE_INTERNAL_LABEL (toc_label_name
, "LCTOC", 1);
2978 /* We can only guarantee the availability of DI pseudo-ops when
2979 assembling for 64-bit targets. */
2982 targetm
.asm_out
.aligned_op
.di
= NULL
;
2983 targetm
.asm_out
.unaligned_op
.di
= NULL
;
2986 /* Set branch target alignment, if not optimizing for size. */
2989 /* Cell wants to be aligned 8byte for dual issue. Titan wants to be
2990 aligned 8byte to avoid misprediction by the branch predictor. */
2991 if (rs6000_cpu
== PROCESSOR_TITAN
2992 || rs6000_cpu
== PROCESSOR_CELL
)
2994 if (align_functions
<= 0)
2995 align_functions
= 8;
2996 if (align_jumps
<= 0)
2998 if (align_loops
<= 0)
3001 if (rs6000_align_branch_targets
)
3003 if (align_functions
<= 0)
3004 align_functions
= 16;
3005 if (align_jumps
<= 0)
3007 if (align_loops
<= 0)
3010 if (align_jumps_max_skip
<= 0)
3011 align_jumps_max_skip
= 15;
3012 if (align_loops_max_skip
<= 0)
3013 align_loops_max_skip
= 15;
3016 /* Arrange to save and restore machine status around nested functions. */
3017 init_machine_status
= rs6000_init_machine_status
;
3019 /* We should always be splitting complex arguments, but we can't break
3020 Linux and Darwin ABIs at the moment. For now, only AIX is fixed. */
3021 if (DEFAULT_ABI
!= ABI_AIX
)
3022 targetm
.calls
.split_complex_arg
= NULL
;
3024 /* Initialize rs6000_cost with the appropriate target costs. */
3026 rs6000_cost
= TARGET_POWERPC64
? &size64_cost
: &size32_cost
;
3030 case PROCESSOR_RIOS1
:
3031 rs6000_cost
= &rios1_cost
;
3034 case PROCESSOR_RIOS2
:
3035 rs6000_cost
= &rios2_cost
;
3038 case PROCESSOR_RS64A
:
3039 rs6000_cost
= &rs64a_cost
;
3042 case PROCESSOR_MPCCORE
:
3043 rs6000_cost
= &mpccore_cost
;
3046 case PROCESSOR_PPC403
:
3047 rs6000_cost
= &ppc403_cost
;
3050 case PROCESSOR_PPC405
:
3051 rs6000_cost
= &ppc405_cost
;
3054 case PROCESSOR_PPC440
:
3055 rs6000_cost
= &ppc440_cost
;
3058 case PROCESSOR_PPC476
:
3059 rs6000_cost
= &ppc476_cost
;
3062 case PROCESSOR_PPC601
:
3063 rs6000_cost
= &ppc601_cost
;
3066 case PROCESSOR_PPC603
:
3067 rs6000_cost
= &ppc603_cost
;
3070 case PROCESSOR_PPC604
:
3071 rs6000_cost
= &ppc604_cost
;
3074 case PROCESSOR_PPC604e
:
3075 rs6000_cost
= &ppc604e_cost
;
3078 case PROCESSOR_PPC620
:
3079 rs6000_cost
= &ppc620_cost
;
3082 case PROCESSOR_PPC630
:
3083 rs6000_cost
= &ppc630_cost
;
3086 case PROCESSOR_CELL
:
3087 rs6000_cost
= &ppccell_cost
;
3090 case PROCESSOR_PPC750
:
3091 case PROCESSOR_PPC7400
:
3092 rs6000_cost
= &ppc750_cost
;
3095 case PROCESSOR_PPC7450
:
3096 rs6000_cost
= &ppc7450_cost
;
3099 case PROCESSOR_PPC8540
:
3100 rs6000_cost
= &ppc8540_cost
;
3103 case PROCESSOR_PPCE300C2
:
3104 case PROCESSOR_PPCE300C3
:
3105 rs6000_cost
= &ppce300c2c3_cost
;
3108 case PROCESSOR_PPCE500MC
:
3109 rs6000_cost
= &ppce500mc_cost
;
3112 case PROCESSOR_PPCE500MC64
:
3113 rs6000_cost
= &ppce500mc64_cost
;
3116 case PROCESSOR_TITAN
:
3117 rs6000_cost
= &titan_cost
;
3120 case PROCESSOR_POWER4
:
3121 case PROCESSOR_POWER5
:
3122 rs6000_cost
= &power4_cost
;
3125 case PROCESSOR_POWER6
:
3126 rs6000_cost
= &power6_cost
;
3129 case PROCESSOR_POWER7
:
3130 rs6000_cost
= &power7_cost
;
3133 case PROCESSOR_PPCA2
:
3134 rs6000_cost
= &ppca2_cost
;
3141 if (!PARAM_SET_P (PARAM_SIMULTANEOUS_PREFETCHES
))
3142 set_param_value ("simultaneous-prefetches",
3143 rs6000_cost
->simultaneous_prefetches
);
3144 if (!PARAM_SET_P (PARAM_L1_CACHE_SIZE
))
3145 set_param_value ("l1-cache-size", rs6000_cost
->l1_cache_size
);
3146 if (!PARAM_SET_P (PARAM_L1_CACHE_LINE_SIZE
))
3147 set_param_value ("l1-cache-line-size", rs6000_cost
->cache_line_size
);
3148 if (!PARAM_SET_P (PARAM_L2_CACHE_SIZE
))
3149 set_param_value ("l2-cache-size", rs6000_cost
->l2_cache_size
);
3151 /* If using typedef char *va_list, signal that __builtin_va_start (&ap, 0)
3152 can be optimized to ap = __builtin_next_arg (0). */
3153 if (DEFAULT_ABI
!= ABI_V4
)
3154 targetm
.expand_builtin_va_start
= NULL
;
3156 /* Set up single/double float flags.
3157 If TARGET_HARD_FLOAT is set, but neither single or double is set,
3158 then set both flags. */
3159 if (TARGET_HARD_FLOAT
&& TARGET_FPRS
3160 && rs6000_single_float
== 0 && rs6000_double_float
== 0)
3161 rs6000_single_float
= rs6000_double_float
= 1;
3163 /* Reset single and double FP flags if target is E500. */
3166 rs6000_single_float
= rs6000_double_float
= 0;
3167 if (TARGET_E500_SINGLE
)
3168 rs6000_single_float
= 1;
3169 if (TARGET_E500_DOUBLE
)
3170 rs6000_single_float
= rs6000_double_float
= 1;
3173 /* If not explicitly specified via option, decide whether to generate indexed
3174 load/store instructions. */
3175 if (TARGET_AVOID_XFORM
== -1)
3176 /* Avoid indexed addressing when targeting Power6 in order to avoid
3177 the DERAT mispredict penalty. */
3178 TARGET_AVOID_XFORM
= (rs6000_cpu
== PROCESSOR_POWER6
&& TARGET_CMPB
);
3180 /* Set the -mrecip options. */
3181 if (rs6000_recip_name
)
3183 char *p
= ASTRDUP (rs6000_recip_name
);
3185 unsigned int mask
, i
;
3188 while ((q
= strtok (p
, ",")) != NULL
)
3199 if (!strcmp (q
, "default"))
3200 mask
= ((TARGET_RECIP_PRECISION
)
3201 ? RECIP_HIGH_PRECISION
: RECIP_LOW_PRECISION
);
3204 for (i
= 0; i
< ARRAY_SIZE (recip_options
); i
++)
3205 if (!strcmp (q
, recip_options
[i
].string
))
3207 mask
= recip_options
[i
].mask
;
3211 if (i
== ARRAY_SIZE (recip_options
))
3213 error ("Unknown option for -mrecip=%s", q
);
3220 rs6000_recip_control
&= ~mask
;
3222 rs6000_recip_control
|= mask
;
3226 rs6000_init_hard_regno_mode_ok ();
3229 /* Implement targetm.vectorize.builtin_mask_for_load. */
3231 rs6000_builtin_mask_for_load (void)
3233 if (TARGET_ALTIVEC
|| TARGET_VSX
)
3234 return altivec_builtin_mask_for_load
;
3239 /* Implement targetm.vectorize.builtin_conversion.
3240 Returns a decl of a function that implements conversion of an integer vector
3241 into a floating-point vector, or vice-versa. DEST_TYPE is the
3242 destination type and SRC_TYPE the source type of the conversion.
3243 Return NULL_TREE if it is not available. */
3245 rs6000_builtin_conversion (unsigned int tcode
, tree dest_type
, tree src_type
)
3247 enum tree_code code
= (enum tree_code
) tcode
;
3251 case FIX_TRUNC_EXPR
:
3252 switch (TYPE_MODE (dest_type
))
3255 if (!VECTOR_UNIT_VSX_P (V2DFmode
))
3258 return TYPE_UNSIGNED (dest_type
)
3259 ? rs6000_builtin_decls
[VSX_BUILTIN_XVCVDPUXDS_UNS
]
3260 : rs6000_builtin_decls
[VSX_BUILTIN_XVCVDPSXDS
];
3263 if (VECTOR_UNIT_NONE_P (V4SImode
) || VECTOR_UNIT_NONE_P (V4SFmode
))
3266 return TYPE_UNSIGNED (dest_type
)
3267 ? rs6000_builtin_decls
[VECTOR_BUILTIN_FIXUNS_V4SF_V4SI
]
3268 : rs6000_builtin_decls
[VECTOR_BUILTIN_FIX_V4SF_V4SI
];
3275 switch (TYPE_MODE (src_type
))
3278 if (!VECTOR_UNIT_VSX_P (V2DFmode
))
3281 return TYPE_UNSIGNED (src_type
)
3282 ? rs6000_builtin_decls
[VSX_BUILTIN_XVCVUXDDP
]
3283 : rs6000_builtin_decls
[VSX_BUILTIN_XVCVSXDDP
];
3286 if (VECTOR_UNIT_NONE_P (V4SImode
) || VECTOR_UNIT_NONE_P (V4SFmode
))
3289 return TYPE_UNSIGNED (src_type
)
3290 ? rs6000_builtin_decls
[VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF
]
3291 : rs6000_builtin_decls
[VECTOR_BUILTIN_FLOAT_V4SI_V4SF
];
3302 /* Implement targetm.vectorize.builtin_mul_widen_even. */
3304 rs6000_builtin_mul_widen_even (tree type
)
3306 if (!TARGET_ALTIVEC
)
3309 switch (TYPE_MODE (type
))
3312 return TYPE_UNSIGNED (type
)
3313 ? rs6000_builtin_decls
[ALTIVEC_BUILTIN_VMULEUH_UNS
]
3314 : rs6000_builtin_decls
[ALTIVEC_BUILTIN_VMULESH
];
3317 return TYPE_UNSIGNED (type
)
3318 ? rs6000_builtin_decls
[ALTIVEC_BUILTIN_VMULEUB_UNS
]
3319 : rs6000_builtin_decls
[ALTIVEC_BUILTIN_VMULESB
];
3325 /* Implement targetm.vectorize.builtin_mul_widen_odd. */
3327 rs6000_builtin_mul_widen_odd (tree type
)
3329 if (!TARGET_ALTIVEC
)
3332 switch (TYPE_MODE (type
))
3335 return TYPE_UNSIGNED (type
)
3336 ? rs6000_builtin_decls
[ALTIVEC_BUILTIN_VMULOUH_UNS
]
3337 : rs6000_builtin_decls
[ALTIVEC_BUILTIN_VMULOSH
];
3340 return TYPE_UNSIGNED (type
)
3341 ? rs6000_builtin_decls
[ALTIVEC_BUILTIN_VMULOUB_UNS
]
3342 : rs6000_builtin_decls
[ALTIVEC_BUILTIN_VMULOSB
];
3349 /* Return true iff, data reference of TYPE can reach vector alignment (16)
3350 after applying N number of iterations. This routine does not determine
3351 how may iterations are required to reach desired alignment. */
3354 rs6000_vector_alignment_reachable (const_tree type ATTRIBUTE_UNUSED
, bool is_packed
)
3361 if (rs6000_alignment_flags
== MASK_ALIGN_NATURAL
)
3364 if (rs6000_alignment_flags
== MASK_ALIGN_POWER
)
3374 /* Assuming that all other types are naturally aligned. CHECKME! */
3379 /* Return true if the vector misalignment factor is supported by the
3382 rs6000_builtin_support_vector_misalignment (enum machine_mode mode
,
3389 /* Return if movmisalign pattern is not supported for this mode. */
3390 if (optab_handler (movmisalign_optab
, mode
) == CODE_FOR_nothing
)
3393 if (misalignment
== -1)
3395 /* Misalignment factor is unknown at compile time but we know
3396 it's word aligned. */
3397 if (rs6000_vector_alignment_reachable (type
, is_packed
))
3399 int element_size
= TREE_INT_CST_LOW (TYPE_SIZE (type
));
3401 if (element_size
== 64 || element_size
== 32)
3408 /* VSX supports word-aligned vector. */
3409 if (misalignment
% 4 == 0)
3415 /* Implement targetm.vectorize.builtin_vec_perm. */
3417 rs6000_builtin_vec_perm (tree type
, tree
*mask_element_type
)
3419 tree inner_type
= TREE_TYPE (type
);
3420 bool uns_p
= TYPE_UNSIGNED (inner_type
);
3423 *mask_element_type
= unsigned_char_type_node
;
3425 switch (TYPE_MODE (type
))
3429 ? rs6000_builtin_decls
[ALTIVEC_BUILTIN_VPERM_16QI_UNS
]
3430 : rs6000_builtin_decls
[ALTIVEC_BUILTIN_VPERM_16QI
]);
3435 ? rs6000_builtin_decls
[ALTIVEC_BUILTIN_VPERM_8HI_UNS
]
3436 : rs6000_builtin_decls
[ALTIVEC_BUILTIN_VPERM_8HI
]);
3441 ? rs6000_builtin_decls
[ALTIVEC_BUILTIN_VPERM_4SI_UNS
]
3442 : rs6000_builtin_decls
[ALTIVEC_BUILTIN_VPERM_4SI
]);
3446 d
= rs6000_builtin_decls
[ALTIVEC_BUILTIN_VPERM_4SF
];
3450 if (!TARGET_ALLOW_DF_PERMUTE
)
3453 d
= rs6000_builtin_decls
[ALTIVEC_BUILTIN_VPERM_2DF
];
3457 if (!TARGET_ALLOW_DF_PERMUTE
)
3461 ? rs6000_builtin_decls
[ALTIVEC_BUILTIN_VPERM_2DI_UNS
]
3462 : rs6000_builtin_decls
[ALTIVEC_BUILTIN_VPERM_2DI
]);
3474 /* Implement targetm.vectorize.builtin_vectorization_cost. */
3476 rs6000_builtin_vectorization_cost (enum vect_cost_for_stmt type_of_cost
,
3477 tree vectype
, int misalign
)
3481 switch (type_of_cost
)
3491 case cond_branch_not_taken
:
3495 case cond_branch_taken
:
3498 case unaligned_load
:
3499 if (TARGET_VSX
&& TARGET_ALLOW_MOVMISALIGN
)
3501 elements
= TYPE_VECTOR_SUBPARTS (vectype
);
3503 /* Double word aligned. */
3511 /* Double word aligned. */
3515 /* Unknown misalignment. */
3528 /* Misaligned loads are not supported. */
3533 case unaligned_store
:
3534 if (TARGET_VSX
&& TARGET_ALLOW_MOVMISALIGN
)
3536 elements
= TYPE_VECTOR_SUBPARTS (vectype
);
3538 /* Double word aligned. */
3546 /* Double word aligned. */
3550 /* Unknown misalignment. */
3563 /* Misaligned stores are not supported. */
3573 /* Handle generic options of the form -mfoo=yes/no.
3574 NAME is the option name.
3575 VALUE is the option value.
3576 FLAG is the pointer to the flag where to store a 1 or 0, depending on
3577 whether the option value is 'yes' or 'no' respectively. */
3579 rs6000_parse_yes_no_option (const char *name
, const char *value
, int *flag
)
3583 else if (!strcmp (value
, "yes"))
3585 else if (!strcmp (value
, "no"))
3588 error ("unknown -m%s= option specified: '%s'", name
, value
);
3591 /* Validate and record the size specified with the -mtls-size option. */
3594 rs6000_parse_tls_size_option (void)
3596 if (rs6000_tls_size_string
== 0)
3598 else if (strcmp (rs6000_tls_size_string
, "16") == 0)
3599 rs6000_tls_size
= 16;
3600 else if (strcmp (rs6000_tls_size_string
, "32") == 0)
3601 rs6000_tls_size
= 32;
3602 else if (strcmp (rs6000_tls_size_string
, "64") == 0)
3603 rs6000_tls_size
= 64;
3605 error ("bad value %qs for -mtls-size switch", rs6000_tls_size_string
);
3609 optimization_options (int level ATTRIBUTE_UNUSED
, int size ATTRIBUTE_UNUSED
)
3611 if (DEFAULT_ABI
== ABI_DARWIN
)
3612 /* The Darwin libraries never set errno, so we might as well
3613 avoid calling them when that's the only reason we would. */
3614 flag_errno_math
= 0;
3616 /* Double growth factor to counter reduced min jump length. */
3617 set_param_value ("max-grow-copy-bb-insns", 16);
3619 /* Enable section anchors by default.
3620 Skip section anchors for Objective C and Objective C++
3621 until front-ends fixed. */
3622 if (!TARGET_MACHO
&& lang_hooks
.name
[4] != 'O')
3623 flag_section_anchors
= 2;
3626 static enum fpu_type_t
3627 rs6000_parse_fpu_option (const char *option
)
3629 if (!strcmp("none", option
)) return FPU_NONE
;
3630 if (!strcmp("sp_lite", option
)) return FPU_SF_LITE
;
3631 if (!strcmp("dp_lite", option
)) return FPU_DF_LITE
;
3632 if (!strcmp("sp_full", option
)) return FPU_SF_FULL
;
3633 if (!strcmp("dp_full", option
)) return FPU_DF_FULL
;
3634 error("unknown value %s for -mfpu", option
);
3639 /* Handler for the Mathematical Acceleration Subsystem (mass) interface to a
3640 library with vectorized intrinsics. */
3643 rs6000_builtin_vectorized_libmass (tree fndecl
, tree type_out
, tree type_in
)
3646 const char *suffix
= NULL
;
3647 tree fntype
, new_fndecl
, bdecl
= NULL_TREE
;
3650 enum machine_mode el_mode
, in_mode
;
3653 /* Libmass is suitable for unsafe math only as it does not correctly support
3654 parts of IEEE with the required precision such as denormals. Only support
3655 it if we have VSX to use the simd d2 or f4 functions.
3656 XXX: Add variable length support. */
3657 if (!flag_unsafe_math_optimizations
|| !TARGET_VSX
)
3660 el_mode
= TYPE_MODE (TREE_TYPE (type_out
));
3661 n
= TYPE_VECTOR_SUBPARTS (type_out
);
3662 in_mode
= TYPE_MODE (TREE_TYPE (type_in
));
3663 in_n
= TYPE_VECTOR_SUBPARTS (type_in
);
3664 if (el_mode
!= in_mode
3668 if (DECL_BUILT_IN_CLASS (fndecl
) == BUILT_IN_NORMAL
)
3670 enum built_in_function fn
= DECL_FUNCTION_CODE (fndecl
);
3673 case BUILT_IN_ATAN2
:
3674 case BUILT_IN_HYPOT
:
3680 case BUILT_IN_ACOSH
:
3682 case BUILT_IN_ASINH
:
3684 case BUILT_IN_ATANH
:
3692 case BUILT_IN_EXPM1
:
3693 case BUILT_IN_LGAMMA
:
3694 case BUILT_IN_LOG10
:
3695 case BUILT_IN_LOG1P
:
3703 bdecl
= implicit_built_in_decls
[fn
];
3704 suffix
= "d2"; /* pow -> powd2 */
3705 if (el_mode
!= DFmode
3710 case BUILT_IN_ATAN2F
:
3711 case BUILT_IN_HYPOTF
:
3716 case BUILT_IN_ACOSF
:
3717 case BUILT_IN_ACOSHF
:
3718 case BUILT_IN_ASINF
:
3719 case BUILT_IN_ASINHF
:
3720 case BUILT_IN_ATANF
:
3721 case BUILT_IN_ATANHF
:
3722 case BUILT_IN_CBRTF
:
3724 case BUILT_IN_COSHF
:
3726 case BUILT_IN_ERFCF
:
3727 case BUILT_IN_EXP2F
:
3729 case BUILT_IN_EXPM1F
:
3730 case BUILT_IN_LGAMMAF
:
3731 case BUILT_IN_LOG10F
:
3732 case BUILT_IN_LOG1PF
:
3733 case BUILT_IN_LOG2F
:
3736 case BUILT_IN_SINHF
:
3737 case BUILT_IN_SQRTF
:
3739 case BUILT_IN_TANHF
:
3740 bdecl
= implicit_built_in_decls
[fn
];
3741 suffix
= "4"; /* powf -> powf4 */
3742 if (el_mode
!= SFmode
3754 gcc_assert (suffix
!= NULL
);
3755 bname
= IDENTIFIER_POINTER (DECL_NAME (bdecl
));
3756 strcpy (name
, bname
+ sizeof ("__builtin_") - 1);
3757 strcat (name
, suffix
);
3760 fntype
= build_function_type_list (type_out
, type_in
, NULL
);
3761 else if (n_args
== 2)
3762 fntype
= build_function_type_list (type_out
, type_in
, type_in
, NULL
);
3766 /* Build a function declaration for the vectorized function. */
3767 new_fndecl
= build_decl (BUILTINS_LOCATION
,
3768 FUNCTION_DECL
, get_identifier (name
), fntype
);
3769 TREE_PUBLIC (new_fndecl
) = 1;
3770 DECL_EXTERNAL (new_fndecl
) = 1;
3771 DECL_IS_NOVOPS (new_fndecl
) = 1;
3772 TREE_READONLY (new_fndecl
) = 1;
3777 /* Returns a function decl for a vectorized version of the builtin function
3778 with builtin function code FN and the result vector type TYPE, or NULL_TREE
3779 if it is not available. */
3782 rs6000_builtin_vectorized_function (tree fndecl
, tree type_out
,
3785 enum machine_mode in_mode
, out_mode
;
3788 if (TREE_CODE (type_out
) != VECTOR_TYPE
3789 || TREE_CODE (type_in
) != VECTOR_TYPE
3790 || !TARGET_VECTORIZE_BUILTINS
)
3793 out_mode
= TYPE_MODE (TREE_TYPE (type_out
));
3794 out_n
= TYPE_VECTOR_SUBPARTS (type_out
);
3795 in_mode
= TYPE_MODE (TREE_TYPE (type_in
));
3796 in_n
= TYPE_VECTOR_SUBPARTS (type_in
);
3798 if (DECL_BUILT_IN_CLASS (fndecl
) == BUILT_IN_NORMAL
)
3800 enum built_in_function fn
= DECL_FUNCTION_CODE (fndecl
);
3803 case BUILT_IN_COPYSIGN
:
3804 if (VECTOR_UNIT_VSX_P (V2DFmode
)
3805 && out_mode
== DFmode
&& out_n
== 2
3806 && in_mode
== DFmode
&& in_n
== 2)
3807 return rs6000_builtin_decls
[VSX_BUILTIN_CPSGNDP
];
3809 case BUILT_IN_COPYSIGNF
:
3810 if (out_mode
!= SFmode
|| out_n
!= 4
3811 || in_mode
!= SFmode
|| in_n
!= 4)
3813 if (VECTOR_UNIT_VSX_P (V4SFmode
))
3814 return rs6000_builtin_decls
[VSX_BUILTIN_CPSGNSP
];
3815 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode
))
3816 return rs6000_builtin_decls
[ALTIVEC_BUILTIN_COPYSIGN_V4SF
];
3819 if (VECTOR_UNIT_VSX_P (V2DFmode
)
3820 && out_mode
== DFmode
&& out_n
== 2
3821 && in_mode
== DFmode
&& in_n
== 2)
3822 return rs6000_builtin_decls
[VSX_BUILTIN_XVSQRTDP
];
3824 case BUILT_IN_SQRTF
:
3825 if (VECTOR_UNIT_VSX_P (V4SFmode
)
3826 && out_mode
== SFmode
&& out_n
== 4
3827 && in_mode
== SFmode
&& in_n
== 4)
3828 return rs6000_builtin_decls
[VSX_BUILTIN_XVSQRTSP
];
3831 if (VECTOR_UNIT_VSX_P (V2DFmode
)
3832 && out_mode
== DFmode
&& out_n
== 2
3833 && in_mode
== DFmode
&& in_n
== 2)
3834 return rs6000_builtin_decls
[VSX_BUILTIN_XVRDPIP
];
3836 case BUILT_IN_CEILF
:
3837 if (out_mode
!= SFmode
|| out_n
!= 4
3838 || in_mode
!= SFmode
|| in_n
!= 4)
3840 if (VECTOR_UNIT_VSX_P (V4SFmode
))
3841 return rs6000_builtin_decls
[VSX_BUILTIN_XVRSPIP
];
3842 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode
))
3843 return rs6000_builtin_decls
[ALTIVEC_BUILTIN_VRFIP
];
3845 case BUILT_IN_FLOOR
:
3846 if (VECTOR_UNIT_VSX_P (V2DFmode
)
3847 && out_mode
== DFmode
&& out_n
== 2
3848 && in_mode
== DFmode
&& in_n
== 2)
3849 return rs6000_builtin_decls
[VSX_BUILTIN_XVRDPIM
];
3851 case BUILT_IN_FLOORF
:
3852 if (out_mode
!= SFmode
|| out_n
!= 4
3853 || in_mode
!= SFmode
|| in_n
!= 4)
3855 if (VECTOR_UNIT_VSX_P (V4SFmode
))
3856 return rs6000_builtin_decls
[VSX_BUILTIN_XVRSPIM
];
3857 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode
))
3858 return rs6000_builtin_decls
[ALTIVEC_BUILTIN_VRFIM
];
3860 case BUILT_IN_TRUNC
:
3861 if (VECTOR_UNIT_VSX_P (V2DFmode
)
3862 && out_mode
== DFmode
&& out_n
== 2
3863 && in_mode
== DFmode
&& in_n
== 2)
3864 return rs6000_builtin_decls
[VSX_BUILTIN_XVRDPIZ
];
3866 case BUILT_IN_TRUNCF
:
3867 if (out_mode
!= SFmode
|| out_n
!= 4
3868 || in_mode
!= SFmode
|| in_n
!= 4)
3870 if (VECTOR_UNIT_VSX_P (V4SFmode
))
3871 return rs6000_builtin_decls
[VSX_BUILTIN_XVRSPIZ
];
3872 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode
))
3873 return rs6000_builtin_decls
[ALTIVEC_BUILTIN_VRFIZ
];
3875 case BUILT_IN_NEARBYINT
:
3876 if (VECTOR_UNIT_VSX_P (V2DFmode
)
3877 && flag_unsafe_math_optimizations
3878 && out_mode
== DFmode
&& out_n
== 2
3879 && in_mode
== DFmode
&& in_n
== 2)
3880 return rs6000_builtin_decls
[VSX_BUILTIN_XVRDPI
];
3882 case BUILT_IN_NEARBYINTF
:
3883 if (VECTOR_UNIT_VSX_P (V4SFmode
)
3884 && flag_unsafe_math_optimizations
3885 && out_mode
== SFmode
&& out_n
== 4
3886 && in_mode
== SFmode
&& in_n
== 4)
3887 return rs6000_builtin_decls
[VSX_BUILTIN_XVRSPI
];
3890 if (VECTOR_UNIT_VSX_P (V2DFmode
)
3891 && !flag_trapping_math
3892 && out_mode
== DFmode
&& out_n
== 2
3893 && in_mode
== DFmode
&& in_n
== 2)
3894 return rs6000_builtin_decls
[VSX_BUILTIN_XVRDPIC
];
3896 case BUILT_IN_RINTF
:
3897 if (VECTOR_UNIT_VSX_P (V4SFmode
)
3898 && !flag_trapping_math
3899 && out_mode
== SFmode
&& out_n
== 4
3900 && in_mode
== SFmode
&& in_n
== 4)
3901 return rs6000_builtin_decls
[VSX_BUILTIN_XVRSPIC
];
3908 else if (DECL_BUILT_IN_CLASS (fndecl
) == BUILT_IN_MD
)
3910 enum rs6000_builtins fn
3911 = (enum rs6000_builtins
)DECL_FUNCTION_CODE (fndecl
);
3914 case RS6000_BUILTIN_RSQRTF
:
3915 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode
)
3916 && out_mode
== SFmode
&& out_n
== 4
3917 && in_mode
== SFmode
&& in_n
== 4)
3918 return rs6000_builtin_decls
[ALTIVEC_BUILTIN_VRSQRTFP
];
3920 case RS6000_BUILTIN_RSQRT
:
3921 if (VECTOR_UNIT_VSX_P (V2DFmode
)
3922 && out_mode
== DFmode
&& out_n
== 2
3923 && in_mode
== DFmode
&& in_n
== 2)
3924 return rs6000_builtin_decls
[VSX_BUILTIN_VEC_RSQRT_V2DF
];
3926 case RS6000_BUILTIN_RECIPF
:
3927 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode
)
3928 && out_mode
== SFmode
&& out_n
== 4
3929 && in_mode
== SFmode
&& in_n
== 4)
3930 return rs6000_builtin_decls
[ALTIVEC_BUILTIN_VRECIPFP
];
3932 case RS6000_BUILTIN_RECIP
:
3933 if (VECTOR_UNIT_VSX_P (V2DFmode
)
3934 && out_mode
== DFmode
&& out_n
== 2
3935 && in_mode
== DFmode
&& in_n
== 2)
3936 return rs6000_builtin_decls
[VSX_BUILTIN_RECIP_V2DF
];
3943 /* Generate calls to libmass if appropriate. */
3944 if (rs6000_veclib_handler
)
3945 return rs6000_veclib_handler (fndecl
, type_out
, type_in
);
3951 /* Implement TARGET_HANDLE_OPTION. */
3954 rs6000_handle_option (size_t code
, const char *arg
, int value
)
3956 enum fpu_type_t fpu_type
= FPU_NONE
;
3962 g_switch_value
= value
;
3963 g_switch_set
= true;
3967 target_flags
&= ~(MASK_POWER
| MASK_POWER2
3968 | MASK_MULTIPLE
| MASK_STRING
);
3969 target_flags_explicit
|= (MASK_POWER
| MASK_POWER2
3970 | MASK_MULTIPLE
| MASK_STRING
);
3972 case OPT_mno_powerpc
:
3973 target_flags
&= ~(MASK_POWERPC
| MASK_PPC_GPOPT
3974 | MASK_PPC_GFXOPT
| MASK_POWERPC64
);
3975 target_flags_explicit
|= (MASK_POWERPC
| MASK_PPC_GPOPT
3976 | MASK_PPC_GFXOPT
| MASK_POWERPC64
);
3979 target_flags
&= ~MASK_MINIMAL_TOC
;
3980 TARGET_NO_FP_IN_TOC
= 0;
3981 TARGET_NO_SUM_IN_TOC
= 0;
3982 target_flags_explicit
|= MASK_MINIMAL_TOC
;
3983 #ifdef TARGET_USES_SYSV4_OPT
3984 /* Note, V.4 no longer uses a normal TOC, so make -mfull-toc, be
3985 just the same as -mminimal-toc. */
3986 target_flags
|= MASK_MINIMAL_TOC
;
3987 target_flags_explicit
|= MASK_MINIMAL_TOC
;
3991 #ifdef TARGET_USES_SYSV4_OPT
3993 /* Make -mtoc behave like -mminimal-toc. */
3994 target_flags
|= MASK_MINIMAL_TOC
;
3995 target_flags_explicit
|= MASK_MINIMAL_TOC
;
3999 #if defined (HAVE_LD_LARGE_TOC) && defined (TARGET_USES_LINUX64_OPT)
4001 if (strcmp (arg
, "small") == 0)
4002 cmodel
= CMODEL_SMALL
;
4003 else if (strcmp (arg
, "large") == 0)
4004 cmodel
= CMODEL_LARGE
;
4007 error ("invalid option for -mcmodel: '%s'", arg
);
4010 rs6000_explicit_options
.cmodel
= true;
4013 #ifdef TARGET_USES_AIX64_OPT
4018 target_flags
|= MASK_POWERPC64
| MASK_POWERPC
;
4019 target_flags
|= ~target_flags_explicit
& MASK_PPC_GFXOPT
;
4020 target_flags_explicit
|= MASK_POWERPC64
| MASK_POWERPC
;
4023 #ifdef TARGET_USES_AIX64_OPT
4028 target_flags
&= ~MASK_POWERPC64
;
4029 target_flags_explicit
|= MASK_POWERPC64
;
4032 case OPT_minsert_sched_nops_
:
4033 rs6000_sched_insert_nops_str
= arg
;
4036 case OPT_mminimal_toc
:
4039 TARGET_NO_FP_IN_TOC
= 0;
4040 TARGET_NO_SUM_IN_TOC
= 0;
4047 target_flags
|= (MASK_MULTIPLE
| MASK_STRING
);
4048 target_flags_explicit
|= (MASK_MULTIPLE
| MASK_STRING
);
4055 target_flags
|= (MASK_POWER
| MASK_MULTIPLE
| MASK_STRING
);
4056 target_flags_explicit
|= (MASK_POWER
| MASK_MULTIPLE
| MASK_STRING
);
4060 case OPT_mpowerpc_gpopt
:
4061 case OPT_mpowerpc_gfxopt
:
4064 target_flags
|= MASK_POWERPC
;
4065 target_flags_explicit
|= MASK_POWERPC
;
4069 case OPT_maix_struct_return
:
4070 case OPT_msvr4_struct_return
:
4071 rs6000_explicit_options
.aix_struct_ret
= true;
4075 rs6000_explicit_options
.vrsave
= true;
4076 TARGET_ALTIVEC_VRSAVE
= value
;
4080 rs6000_explicit_options
.vrsave
= true;
4081 rs6000_parse_yes_no_option ("vrsave", arg
, &(TARGET_ALTIVEC_VRSAVE
));
4085 target_flags_explicit
|= MASK_ISEL
;
4087 rs6000_parse_yes_no_option ("isel", arg
, &isel
);
4089 target_flags
|= MASK_ISEL
;
4091 target_flags
&= ~MASK_ISEL
;
4095 rs6000_explicit_options
.spe
= true;
4100 rs6000_explicit_options
.spe
= true;
4101 rs6000_parse_yes_no_option ("spe", arg
, &(rs6000_spe
));
4105 rs6000_debug_name
= arg
;
4108 #ifdef TARGET_USES_SYSV4_OPT
4110 rs6000_abi_name
= arg
;
4114 rs6000_sdata_name
= arg
;
4117 case OPT_mtls_size_
:
4118 rs6000_tls_size_string
= arg
;
4121 case OPT_mrelocatable
:
4124 target_flags
|= MASK_MINIMAL_TOC
;
4125 target_flags_explicit
|= MASK_MINIMAL_TOC
;
4126 TARGET_NO_FP_IN_TOC
= 1;
4130 case OPT_mrelocatable_lib
:
4133 target_flags
|= MASK_RELOCATABLE
| MASK_MINIMAL_TOC
;
4134 target_flags_explicit
|= MASK_RELOCATABLE
| MASK_MINIMAL_TOC
;
4135 TARGET_NO_FP_IN_TOC
= 1;
4139 target_flags
&= ~MASK_RELOCATABLE
;
4140 target_flags_explicit
|= MASK_RELOCATABLE
;
4146 if (!strcmp (arg
, "altivec"))
4148 rs6000_explicit_options
.altivec_abi
= true;
4149 rs6000_altivec_abi
= 1;
4151 /* Enabling the AltiVec ABI turns off the SPE ABI. */
4154 else if (! strcmp (arg
, "no-altivec"))
4156 rs6000_explicit_options
.altivec_abi
= true;
4157 rs6000_altivec_abi
= 0;
4159 else if (! strcmp (arg
, "spe"))
4161 rs6000_explicit_options
.spe_abi
= true;
4163 rs6000_altivec_abi
= 0;
4164 if (!TARGET_SPE_ABI
)
4165 error ("not configured for ABI: '%s'", arg
);
4167 else if (! strcmp (arg
, "no-spe"))
4169 rs6000_explicit_options
.spe_abi
= true;
4173 /* These are here for testing during development only, do not
4174 document in the manual please. */
4175 else if (! strcmp (arg
, "d64"))
4177 rs6000_darwin64_abi
= 1;
4178 warning (0, "Using darwin64 ABI");
4180 else if (! strcmp (arg
, "d32"))
4182 rs6000_darwin64_abi
= 0;
4183 warning (0, "Using old darwin ABI");
4186 else if (! strcmp (arg
, "ibmlongdouble"))
4188 rs6000_explicit_options
.ieee
= true;
4189 rs6000_ieeequad
= 0;
4190 warning (0, "Using IBM extended precision long double");
4192 else if (! strcmp (arg
, "ieeelongdouble"))
4194 rs6000_explicit_options
.ieee
= true;
4195 rs6000_ieeequad
= 1;
4196 warning (0, "Using IEEE extended precision long double");
4201 error ("unknown ABI specified: '%s'", arg
);
4207 rs6000_select
[1].string
= arg
;
4211 rs6000_select
[2].string
= arg
;
4214 case OPT_mtraceback_
:
4215 rs6000_traceback_name
= arg
;
4218 case OPT_mfloat_gprs_
:
4219 rs6000_explicit_options
.float_gprs
= true;
4220 if (! strcmp (arg
, "yes") || ! strcmp (arg
, "single"))
4221 rs6000_float_gprs
= 1;
4222 else if (! strcmp (arg
, "double"))
4223 rs6000_float_gprs
= 2;
4224 else if (! strcmp (arg
, "no"))
4225 rs6000_float_gprs
= 0;
4228 error ("invalid option for -mfloat-gprs: '%s'", arg
);
4233 case OPT_mlong_double_
:
4234 rs6000_explicit_options
.long_double
= true;
4235 rs6000_long_double_type_size
= RS6000_DEFAULT_LONG_DOUBLE_SIZE
;
4236 if (value
!= 64 && value
!= 128)
4238 error ("Unknown switch -mlong-double-%s", arg
);
4239 rs6000_long_double_type_size
= RS6000_DEFAULT_LONG_DOUBLE_SIZE
;
4243 rs6000_long_double_type_size
= value
;
4246 case OPT_msched_costly_dep_
:
4247 rs6000_sched_costly_dep_str
= arg
;
4251 rs6000_explicit_options
.alignment
= true;
4252 if (! strcmp (arg
, "power"))
4254 /* On 64-bit Darwin, power alignment is ABI-incompatible with
4255 some C library functions, so warn about it. The flag may be
4256 useful for performance studies from time to time though, so
4257 don't disable it entirely. */
4258 if (DEFAULT_ABI
== ABI_DARWIN
&& TARGET_64BIT
)
4259 warning (0, "-malign-power is not supported for 64-bit Darwin;"
4260 " it is incompatible with the installed C and C++ libraries");
4261 rs6000_alignment_flags
= MASK_ALIGN_POWER
;
4263 else if (! strcmp (arg
, "natural"))
4264 rs6000_alignment_flags
= MASK_ALIGN_NATURAL
;
4267 error ("unknown -malign-XXXXX option specified: '%s'", arg
);
4272 case OPT_msingle_float
:
4273 if (!TARGET_SINGLE_FPU
)
4274 warning (0, "-msingle-float option equivalent to -mhard-float");
4275 /* -msingle-float implies -mno-double-float and TARGET_HARD_FLOAT. */
4276 rs6000_double_float
= 0;
4277 target_flags
&= ~MASK_SOFT_FLOAT
;
4278 target_flags_explicit
|= MASK_SOFT_FLOAT
;
4281 case OPT_mdouble_float
:
4282 /* -mdouble-float implies -msingle-float and TARGET_HARD_FLOAT. */
4283 rs6000_single_float
= 1;
4284 target_flags
&= ~MASK_SOFT_FLOAT
;
4285 target_flags_explicit
|= MASK_SOFT_FLOAT
;
4288 case OPT_msimple_fpu
:
4289 if (!TARGET_SINGLE_FPU
)
4290 warning (0, "-msimple-fpu option ignored");
4293 case OPT_mhard_float
:
4294 /* -mhard_float implies -msingle-float and -mdouble-float. */
4295 rs6000_single_float
= rs6000_double_float
= 1;
4298 case OPT_msoft_float
:
4299 /* -msoft_float implies -mnosingle-float and -mnodouble-float. */
4300 rs6000_single_float
= rs6000_double_float
= 0;
4304 fpu_type
= rs6000_parse_fpu_option(arg
);
4305 if (fpu_type
!= FPU_NONE
)
4306 /* If -mfpu is not none, then turn off SOFT_FLOAT, turn on HARD_FLOAT. */
4308 target_flags
&= ~MASK_SOFT_FLOAT
;
4309 target_flags_explicit
|= MASK_SOFT_FLOAT
;
4310 rs6000_xilinx_fpu
= 1;
4311 if (fpu_type
== FPU_SF_LITE
|| fpu_type
== FPU_SF_FULL
)
4312 rs6000_single_float
= 1;
4313 if (fpu_type
== FPU_DF_LITE
|| fpu_type
== FPU_DF_FULL
)
4314 rs6000_single_float
= rs6000_double_float
= 1;
4315 if (fpu_type
== FPU_SF_LITE
|| fpu_type
== FPU_DF_LITE
)
4316 rs6000_simple_fpu
= 1;
4320 /* -mfpu=none is equivalent to -msoft-float */
4321 target_flags
|= MASK_SOFT_FLOAT
;
4322 target_flags_explicit
|= MASK_SOFT_FLOAT
;
4323 rs6000_single_float
= rs6000_double_float
= 0;
4327 rs6000_recip_name
= (value
) ? "default" : "none";
4331 rs6000_recip_name
= arg
;
4337 /* Do anything needed at the start of the asm file. */
4340 rs6000_file_start (void)
4344 const char *start
= buffer
;
4345 struct rs6000_cpu_select
*ptr
;
4346 const char *default_cpu
= TARGET_CPU_DEFAULT
;
4347 FILE *file
= asm_out_file
;
4349 default_file_start ();
4351 #ifdef TARGET_BI_ARCH
4352 if ((TARGET_DEFAULT
^ target_flags
) & MASK_64BIT
)
4356 if (flag_verbose_asm
)
4358 sprintf (buffer
, "\n%s rs6000/powerpc options:", ASM_COMMENT_START
);
4359 rs6000_select
[0].string
= default_cpu
;
4361 for (i
= 0; i
< ARRAY_SIZE (rs6000_select
); i
++)
4363 ptr
= &rs6000_select
[i
];
4364 if (ptr
->string
!= (char *)0 && ptr
->string
[0] != '\0')
4366 fprintf (file
, "%s %s%s", start
, ptr
->name
, ptr
->string
);
4371 if (PPC405_ERRATUM77
)
4373 fprintf (file
, "%s PPC405CR_ERRATUM77", start
);
4377 #ifdef USING_ELFOS_H
4378 switch (rs6000_sdata
)
4380 case SDATA_NONE
: fprintf (file
, "%s -msdata=none", start
); start
= ""; break;
4381 case SDATA_DATA
: fprintf (file
, "%s -msdata=data", start
); start
= ""; break;
4382 case SDATA_SYSV
: fprintf (file
, "%s -msdata=sysv", start
); start
= ""; break;
4383 case SDATA_EABI
: fprintf (file
, "%s -msdata=eabi", start
); start
= ""; break;
4386 if (rs6000_sdata
&& g_switch_value
)
4388 fprintf (file
, "%s -G " HOST_WIDE_INT_PRINT_UNSIGNED
, start
,
4398 #ifdef HAVE_AS_GNU_ATTRIBUTE
4399 if (TARGET_32BIT
&& DEFAULT_ABI
== ABI_V4
)
4401 fprintf (file
, "\t.gnu_attribute 4, %d\n",
4402 ((TARGET_HARD_FLOAT
&& TARGET_FPRS
&& TARGET_DOUBLE_FLOAT
) ? 1
4403 : (TARGET_HARD_FLOAT
&& TARGET_FPRS
&& TARGET_SINGLE_FLOAT
) ? 3
4405 fprintf (file
, "\t.gnu_attribute 8, %d\n",
4406 (TARGET_ALTIVEC_ABI
? 2
4407 : TARGET_SPE_ABI
? 3
4409 fprintf (file
, "\t.gnu_attribute 12, %d\n",
4410 aix_struct_return
? 2 : 1);
4415 if (DEFAULT_ABI
== ABI_AIX
|| (TARGET_ELF
&& flag_pic
== 2))
4417 switch_to_section (toc_section
);
4418 switch_to_section (text_section
);
4423 /* Return nonzero if this function is known to have a null epilogue. */
4426 direct_return (void)
4428 if (reload_completed
)
4430 rs6000_stack_t
*info
= rs6000_stack_info ();
4432 if (info
->first_gp_reg_save
== 32
4433 && info
->first_fp_reg_save
== 64
4434 && info
->first_altivec_reg_save
== LAST_ALTIVEC_REGNO
+ 1
4435 && ! info
->lr_save_p
4436 && ! info
->cr_save_p
4437 && info
->vrsave_mask
== 0
4445 /* Return the number of instructions it takes to form a constant in an
4446 integer register. */
4449 num_insns_constant_wide (HOST_WIDE_INT value
)
4451 /* signed constant loadable with {cal|addi} */
4452 if ((unsigned HOST_WIDE_INT
) (value
+ 0x8000) < 0x10000)
4455 /* constant loadable with {cau|addis} */
4456 else if ((value
& 0xffff) == 0
4457 && (value
>> 31 == -1 || value
>> 31 == 0))
4460 #if HOST_BITS_PER_WIDE_INT == 64
4461 else if (TARGET_POWERPC64
)
4463 HOST_WIDE_INT low
= ((value
& 0xffffffff) ^ 0x80000000) - 0x80000000;
4464 HOST_WIDE_INT high
= value
>> 31;
4466 if (high
== 0 || high
== -1)
4472 return num_insns_constant_wide (high
) + 1;
4474 return num_insns_constant_wide (low
) + 1;
4476 return (num_insns_constant_wide (high
)
4477 + num_insns_constant_wide (low
) + 1);
4486 num_insns_constant (rtx op
, enum machine_mode mode
)
4488 HOST_WIDE_INT low
, high
;
4490 switch (GET_CODE (op
))
4493 #if HOST_BITS_PER_WIDE_INT == 64
4494 if ((INTVAL (op
) >> 31) != 0 && (INTVAL (op
) >> 31) != -1
4495 && mask64_operand (op
, mode
))
4499 return num_insns_constant_wide (INTVAL (op
));
4502 if (mode
== SFmode
|| mode
== SDmode
)
4507 REAL_VALUE_FROM_CONST_DOUBLE (rv
, op
);
4508 if (DECIMAL_FLOAT_MODE_P (mode
))
4509 REAL_VALUE_TO_TARGET_DECIMAL32 (rv
, l
);
4511 REAL_VALUE_TO_TARGET_SINGLE (rv
, l
);
4512 return num_insns_constant_wide ((HOST_WIDE_INT
) l
);
4515 if (mode
== VOIDmode
|| mode
== DImode
)
4517 high
= CONST_DOUBLE_HIGH (op
);
4518 low
= CONST_DOUBLE_LOW (op
);
4525 REAL_VALUE_FROM_CONST_DOUBLE (rv
, op
);
4526 if (DECIMAL_FLOAT_MODE_P (mode
))
4527 REAL_VALUE_TO_TARGET_DECIMAL64 (rv
, l
);
4529 REAL_VALUE_TO_TARGET_DOUBLE (rv
, l
);
4530 high
= l
[WORDS_BIG_ENDIAN
== 0];
4531 low
= l
[WORDS_BIG_ENDIAN
!= 0];
4535 return (num_insns_constant_wide (low
)
4536 + num_insns_constant_wide (high
));
4539 if ((high
== 0 && low
>= 0)
4540 || (high
== -1 && low
< 0))
4541 return num_insns_constant_wide (low
);
4543 else if (mask64_operand (op
, mode
))
4547 return num_insns_constant_wide (high
) + 1;
4550 return (num_insns_constant_wide (high
)
4551 + num_insns_constant_wide (low
) + 1);
4559 /* Interpret element ELT of the CONST_VECTOR OP as an integer value.
4560 If the mode of OP is MODE_VECTOR_INT, this simply returns the
4561 corresponding element of the vector, but for V4SFmode and V2SFmode,
4562 the corresponding "float" is interpreted as an SImode integer. */
4565 const_vector_elt_as_int (rtx op
, unsigned int elt
)
4567 rtx tmp
= CONST_VECTOR_ELT (op
, elt
);
4568 if (GET_MODE (op
) == V4SFmode
4569 || GET_MODE (op
) == V2SFmode
)
4570 tmp
= gen_lowpart (SImode
, tmp
);
4571 return INTVAL (tmp
);
4574 /* Return true if OP can be synthesized with a particular vspltisb, vspltish
4575 or vspltisw instruction. OP is a CONST_VECTOR. Which instruction is used
4576 depends on STEP and COPIES, one of which will be 1. If COPIES > 1,
4577 all items are set to the same value and contain COPIES replicas of the
4578 vsplt's operand; if STEP > 1, one in STEP elements is set to the vsplt's
4579 operand and the others are set to the value of the operand's msb. */
4582 vspltis_constant (rtx op
, unsigned step
, unsigned copies
)
4584 enum machine_mode mode
= GET_MODE (op
);
4585 enum machine_mode inner
= GET_MODE_INNER (mode
);
4588 unsigned nunits
= GET_MODE_NUNITS (mode
);
4589 unsigned bitsize
= GET_MODE_BITSIZE (inner
);
4590 unsigned mask
= GET_MODE_MASK (inner
);
4592 HOST_WIDE_INT val
= const_vector_elt_as_int (op
, nunits
- 1);
4593 HOST_WIDE_INT splat_val
= val
;
4594 HOST_WIDE_INT msb_val
= val
> 0 ? 0 : -1;
4596 /* Construct the value to be splatted, if possible. If not, return 0. */
4597 for (i
= 2; i
<= copies
; i
*= 2)
4599 HOST_WIDE_INT small_val
;
4601 small_val
= splat_val
>> bitsize
;
4603 if (splat_val
!= ((small_val
<< bitsize
) | (small_val
& mask
)))
4605 splat_val
= small_val
;
4608 /* Check if SPLAT_VAL can really be the operand of a vspltis[bhw]. */
4609 if (EASY_VECTOR_15 (splat_val
))
4612 /* Also check if we can splat, and then add the result to itself. Do so if
4613 the value is positive, of if the splat instruction is using OP's mode;
4614 for splat_val < 0, the splat and the add should use the same mode. */
4615 else if (EASY_VECTOR_15_ADD_SELF (splat_val
)
4616 && (splat_val
>= 0 || (step
== 1 && copies
== 1)))
4619 /* Also check if are loading up the most significant bit which can be done by
4620 loading up -1 and shifting the value left by -1. */
4621 else if (EASY_VECTOR_MSB (splat_val
, inner
))
4627 /* Check if VAL is present in every STEP-th element, and the
4628 other elements are filled with its most significant bit. */
4629 for (i
= 0; i
< nunits
- 1; ++i
)
4631 HOST_WIDE_INT desired_val
;
4632 if (((i
+ 1) & (step
- 1)) == 0)
4635 desired_val
= msb_val
;
4637 if (desired_val
!= const_vector_elt_as_int (op
, i
))
4645 /* Return true if OP is of the given MODE and can be synthesized
4646 with a vspltisb, vspltish or vspltisw. */
4649 easy_altivec_constant (rtx op
, enum machine_mode mode
)
4651 unsigned step
, copies
;
4653 if (mode
== VOIDmode
)
4654 mode
= GET_MODE (op
);
4655 else if (mode
!= GET_MODE (op
))
4658 /* Start with a vspltisw. */
4659 step
= GET_MODE_NUNITS (mode
) / 4;
4662 if (vspltis_constant (op
, step
, copies
))
4665 /* Then try with a vspltish. */
4671 if (vspltis_constant (op
, step
, copies
))
4674 /* And finally a vspltisb. */
4680 if (vspltis_constant (op
, step
, copies
))
4686 /* Generate a VEC_DUPLICATE representing a vspltis[bhw] instruction whose
4687 result is OP. Abort if it is not possible. */
4690 gen_easy_altivec_constant (rtx op
)
4692 enum machine_mode mode
= GET_MODE (op
);
4693 int nunits
= GET_MODE_NUNITS (mode
);
4694 rtx last
= CONST_VECTOR_ELT (op
, nunits
- 1);
4695 unsigned step
= nunits
/ 4;
4696 unsigned copies
= 1;
4698 /* Start with a vspltisw. */
4699 if (vspltis_constant (op
, step
, copies
))
4700 return gen_rtx_VEC_DUPLICATE (V4SImode
, gen_lowpart (SImode
, last
));
4702 /* Then try with a vspltish. */
4708 if (vspltis_constant (op
, step
, copies
))
4709 return gen_rtx_VEC_DUPLICATE (V8HImode
, gen_lowpart (HImode
, last
));
4711 /* And finally a vspltisb. */
4717 if (vspltis_constant (op
, step
, copies
))
4718 return gen_rtx_VEC_DUPLICATE (V16QImode
, gen_lowpart (QImode
, last
));
4724 output_vec_const_move (rtx
*operands
)
4727 enum machine_mode mode
;
4732 mode
= GET_MODE (dest
);
4734 if (TARGET_VSX
&& zero_constant (vec
, mode
))
4735 return "xxlxor %x0,%x0,%x0";
4740 if (zero_constant (vec
, mode
))
4741 return "vxor %0,%0,%0";
4743 splat_vec
= gen_easy_altivec_constant (vec
);
4744 gcc_assert (GET_CODE (splat_vec
) == VEC_DUPLICATE
);
4745 operands
[1] = XEXP (splat_vec
, 0);
4746 if (!EASY_VECTOR_15 (INTVAL (operands
[1])))
4749 switch (GET_MODE (splat_vec
))
4752 return "vspltisw %0,%1";
4755 return "vspltish %0,%1";
4758 return "vspltisb %0,%1";
4765 gcc_assert (TARGET_SPE
);
4767 /* Vector constant 0 is handled as a splitter of V2SI, and in the
4768 pattern of V1DI, V4HI, and V2SF.
4770 FIXME: We should probably return # and add post reload
4771 splitters for these, but this way is so easy ;-). */
4772 cst
= INTVAL (CONST_VECTOR_ELT (vec
, 0));
4773 cst2
= INTVAL (CONST_VECTOR_ELT (vec
, 1));
4774 operands
[1] = CONST_VECTOR_ELT (vec
, 0);
4775 operands
[2] = CONST_VECTOR_ELT (vec
, 1);
4777 return "li %0,%1\n\tevmergelo %0,%0,%0";
4779 return "li %0,%1\n\tevmergelo %0,%0,%0\n\tli %0,%2";
4782 /* Initialize TARGET of vector PAIRED to VALS. */
4785 paired_expand_vector_init (rtx target
, rtx vals
)
4787 enum machine_mode mode
= GET_MODE (target
);
4788 int n_elts
= GET_MODE_NUNITS (mode
);
4790 rtx x
, new_rtx
, tmp
, constant_op
, op1
, op2
;
4793 for (i
= 0; i
< n_elts
; ++i
)
4795 x
= XVECEXP (vals
, 0, i
);
4796 if (!CONSTANT_P (x
))
4801 /* Load from constant pool. */
4802 emit_move_insn (target
, gen_rtx_CONST_VECTOR (mode
, XVEC (vals
, 0)));
4808 /* The vector is initialized only with non-constants. */
4809 new_rtx
= gen_rtx_VEC_CONCAT (V2SFmode
, XVECEXP (vals
, 0, 0),
4810 XVECEXP (vals
, 0, 1));
4812 emit_move_insn (target
, new_rtx
);
4816 /* One field is non-constant and the other one is a constant. Load the
4817 constant from the constant pool and use ps_merge instruction to
4818 construct the whole vector. */
4819 op1
= XVECEXP (vals
, 0, 0);
4820 op2
= XVECEXP (vals
, 0, 1);
4822 constant_op
= (CONSTANT_P (op1
)) ? op1
: op2
;
4824 tmp
= gen_reg_rtx (GET_MODE (constant_op
));
4825 emit_move_insn (tmp
, constant_op
);
4827 if (CONSTANT_P (op1
))
4828 new_rtx
= gen_rtx_VEC_CONCAT (V2SFmode
, tmp
, op2
);
4830 new_rtx
= gen_rtx_VEC_CONCAT (V2SFmode
, op1
, tmp
);
4832 emit_move_insn (target
, new_rtx
);
4836 paired_expand_vector_move (rtx operands
[])
4838 rtx op0
= operands
[0], op1
= operands
[1];
4840 emit_move_insn (op0
, op1
);
4843 /* Emit vector compare for code RCODE. DEST is destination, OP1 and
4844 OP2 are two VEC_COND_EXPR operands, CC_OP0 and CC_OP1 are the two
4845 operands for the relation operation COND. This is a recursive
4849 paired_emit_vector_compare (enum rtx_code rcode
,
4850 rtx dest
, rtx op0
, rtx op1
,
4851 rtx cc_op0
, rtx cc_op1
)
4853 rtx tmp
= gen_reg_rtx (V2SFmode
);
4856 gcc_assert (TARGET_PAIRED_FLOAT
);
4857 gcc_assert (GET_MODE (op0
) == GET_MODE (op1
));
4863 paired_emit_vector_compare (GE
, dest
, op1
, op0
, cc_op0
, cc_op1
);
4867 emit_insn (gen_subv2sf3 (tmp
, cc_op0
, cc_op1
));
4868 emit_insn (gen_selv2sf4 (dest
, tmp
, op0
, op1
, CONST0_RTX (SFmode
)));
4872 paired_emit_vector_compare (GE
, dest
, op0
, op1
, cc_op1
, cc_op0
);
4875 paired_emit_vector_compare (LE
, dest
, op1
, op0
, cc_op0
, cc_op1
);
4878 tmp1
= gen_reg_rtx (V2SFmode
);
4879 max
= gen_reg_rtx (V2SFmode
);
4880 min
= gen_reg_rtx (V2SFmode
);
4881 gen_reg_rtx (V2SFmode
);
4883 emit_insn (gen_subv2sf3 (tmp
, cc_op0
, cc_op1
));
4884 emit_insn (gen_selv2sf4
4885 (max
, tmp
, cc_op0
, cc_op1
, CONST0_RTX (SFmode
)));
4886 emit_insn (gen_subv2sf3 (tmp
, cc_op1
, cc_op0
));
4887 emit_insn (gen_selv2sf4
4888 (min
, tmp
, cc_op0
, cc_op1
, CONST0_RTX (SFmode
)));
4889 emit_insn (gen_subv2sf3 (tmp1
, min
, max
));
4890 emit_insn (gen_selv2sf4 (dest
, tmp1
, op0
, op1
, CONST0_RTX (SFmode
)));
4893 paired_emit_vector_compare (EQ
, dest
, op1
, op0
, cc_op0
, cc_op1
);
4896 paired_emit_vector_compare (LE
, dest
, op1
, op0
, cc_op0
, cc_op1
);
4899 paired_emit_vector_compare (LT
, dest
, op1
, op0
, cc_op0
, cc_op1
);
4902 paired_emit_vector_compare (GE
, dest
, op1
, op0
, cc_op0
, cc_op1
);
4905 paired_emit_vector_compare (GT
, dest
, op1
, op0
, cc_op0
, cc_op1
);
4914 /* Emit vector conditional expression.
4915 DEST is destination. OP1 and OP2 are two VEC_COND_EXPR operands.
4916 CC_OP0 and CC_OP1 are the two operands for the relation operation COND. */
4919 paired_emit_vector_cond_expr (rtx dest
, rtx op1
, rtx op2
,
4920 rtx cond
, rtx cc_op0
, rtx cc_op1
)
4922 enum rtx_code rcode
= GET_CODE (cond
);
4924 if (!TARGET_PAIRED_FLOAT
)
4927 paired_emit_vector_compare (rcode
, dest
, op1
, op2
, cc_op0
, cc_op1
);
4932 /* Initialize vector TARGET to VALS. */
4935 rs6000_expand_vector_init (rtx target
, rtx vals
)
4937 enum machine_mode mode
= GET_MODE (target
);
4938 enum machine_mode inner_mode
= GET_MODE_INNER (mode
);
4939 int n_elts
= GET_MODE_NUNITS (mode
);
4940 int n_var
= 0, one_var
= -1;
4941 bool all_same
= true, all_const_zero
= true;
4945 for (i
= 0; i
< n_elts
; ++i
)
4947 x
= XVECEXP (vals
, 0, i
);
4948 if (!CONSTANT_P (x
))
4949 ++n_var
, one_var
= i
;
4950 else if (x
!= CONST0_RTX (inner_mode
))
4951 all_const_zero
= false;
4953 if (i
> 0 && !rtx_equal_p (x
, XVECEXP (vals
, 0, 0)))
4959 rtx const_vec
= gen_rtx_CONST_VECTOR (mode
, XVEC (vals
, 0));
4960 bool int_vector_p
= (GET_MODE_CLASS (mode
) == MODE_VECTOR_INT
);
4961 if ((int_vector_p
|| TARGET_VSX
) && all_const_zero
)
4963 /* Zero register. */
4964 emit_insn (gen_rtx_SET (VOIDmode
, target
,
4965 gen_rtx_XOR (mode
, target
, target
)));
4968 else if (int_vector_p
&& easy_vector_constant (const_vec
, mode
))
4970 /* Splat immediate. */
4971 emit_insn (gen_rtx_SET (VOIDmode
, target
, const_vec
));
4976 /* Load from constant pool. */
4977 emit_move_insn (target
, const_vec
);
4982 /* Double word values on VSX can use xxpermdi or lxvdsx. */
4983 if (VECTOR_MEM_VSX_P (mode
) && (mode
== V2DFmode
|| mode
== V2DImode
))
4987 rtx element
= XVECEXP (vals
, 0, 0);
4988 if (mode
== V2DFmode
)
4989 emit_insn (gen_vsx_splat_v2df (target
, element
));
4991 emit_insn (gen_vsx_splat_v2di (target
, element
));
4995 rtx op0
= copy_to_reg (XVECEXP (vals
, 0, 0));
4996 rtx op1
= copy_to_reg (XVECEXP (vals
, 0, 1));
4997 if (mode
== V2DFmode
)
4998 emit_insn (gen_vsx_concat_v2df (target
, op0
, op1
));
5000 emit_insn (gen_vsx_concat_v2di (target
, op0
, op1
));
5005 /* With single precision floating point on VSX, know that internally single
5006 precision is actually represented as a double, and either make 2 V2DF
5007 vectors, and convert these vectors to single precision, or do one
5008 conversion, and splat the result to the other elements. */
5009 if (mode
== V4SFmode
&& VECTOR_MEM_VSX_P (mode
))
5013 rtx freg
= gen_reg_rtx (V4SFmode
);
5014 rtx sreg
= copy_to_reg (XVECEXP (vals
, 0, 0));
5016 emit_insn (gen_vsx_xscvdpsp_scalar (freg
, sreg
));
5017 emit_insn (gen_vsx_xxspltw_v4sf (target
, freg
, const0_rtx
));
5021 rtx dbl_even
= gen_reg_rtx (V2DFmode
);
5022 rtx dbl_odd
= gen_reg_rtx (V2DFmode
);
5023 rtx flt_even
= gen_reg_rtx (V4SFmode
);
5024 rtx flt_odd
= gen_reg_rtx (V4SFmode
);
5026 emit_insn (gen_vsx_concat_v2sf (dbl_even
,
5027 copy_to_reg (XVECEXP (vals
, 0, 0)),
5028 copy_to_reg (XVECEXP (vals
, 0, 1))));
5029 emit_insn (gen_vsx_concat_v2sf (dbl_odd
,
5030 copy_to_reg (XVECEXP (vals
, 0, 2)),
5031 copy_to_reg (XVECEXP (vals
, 0, 3))));
5032 emit_insn (gen_vsx_xvcvdpsp (flt_even
, dbl_even
));
5033 emit_insn (gen_vsx_xvcvdpsp (flt_odd
, dbl_odd
));
5034 emit_insn (gen_vec_extract_evenv4sf (target
, flt_even
, flt_odd
));
5039 /* Store value to stack temp. Load vector element. Splat. However, splat
5040 of 64-bit items is not supported on Altivec. */
5041 if (all_same
&& GET_MODE_SIZE (mode
) <= 4)
5043 mem
= assign_stack_temp (mode
, GET_MODE_SIZE (inner_mode
), 0);
5044 emit_move_insn (adjust_address_nv (mem
, inner_mode
, 0),
5045 XVECEXP (vals
, 0, 0));
5046 x
= gen_rtx_UNSPEC (VOIDmode
,
5047 gen_rtvec (1, const0_rtx
), UNSPEC_LVE
);
5048 emit_insn (gen_rtx_PARALLEL (VOIDmode
,
5050 gen_rtx_SET (VOIDmode
,
5053 x
= gen_rtx_VEC_SELECT (inner_mode
, target
,
5054 gen_rtx_PARALLEL (VOIDmode
,
5055 gen_rtvec (1, const0_rtx
)));
5056 emit_insn (gen_rtx_SET (VOIDmode
, target
,
5057 gen_rtx_VEC_DUPLICATE (mode
, x
)));
5061 /* One field is non-constant. Load constant then overwrite
5065 rtx copy
= copy_rtx (vals
);
5067 /* Load constant part of vector, substitute neighboring value for
5069 XVECEXP (copy
, 0, one_var
) = XVECEXP (vals
, 0, (one_var
+ 1) % n_elts
);
5070 rs6000_expand_vector_init (target
, copy
);
5072 /* Insert variable. */
5073 rs6000_expand_vector_set (target
, XVECEXP (vals
, 0, one_var
), one_var
);
5077 /* Construct the vector in memory one field at a time
5078 and load the whole vector. */
5079 mem
= assign_stack_temp (mode
, GET_MODE_SIZE (mode
), 0);
5080 for (i
= 0; i
< n_elts
; i
++)
5081 emit_move_insn (adjust_address_nv (mem
, inner_mode
,
5082 i
* GET_MODE_SIZE (inner_mode
)),
5083 XVECEXP (vals
, 0, i
));
5084 emit_move_insn (target
, mem
);
5087 /* Set field ELT of TARGET to VAL. */
5090 rs6000_expand_vector_set (rtx target
, rtx val
, int elt
)
5092 enum machine_mode mode
= GET_MODE (target
);
5093 enum machine_mode inner_mode
= GET_MODE_INNER (mode
);
5094 rtx reg
= gen_reg_rtx (mode
);
5096 int width
= GET_MODE_SIZE (inner_mode
);
5099 if (VECTOR_MEM_VSX_P (mode
) && (mode
== V2DFmode
|| mode
== V2DImode
))
5101 rtx (*set_func
) (rtx
, rtx
, rtx
, rtx
)
5102 = ((mode
== V2DFmode
) ? gen_vsx_set_v2df
: gen_vsx_set_v2di
);
5103 emit_insn (set_func (target
, target
, val
, GEN_INT (elt
)));
5107 /* Load single variable value. */
5108 mem
= assign_stack_temp (mode
, GET_MODE_SIZE (inner_mode
), 0);
5109 emit_move_insn (adjust_address_nv (mem
, inner_mode
, 0), val
);
5110 x
= gen_rtx_UNSPEC (VOIDmode
,
5111 gen_rtvec (1, const0_rtx
), UNSPEC_LVE
);
5112 emit_insn (gen_rtx_PARALLEL (VOIDmode
,
5114 gen_rtx_SET (VOIDmode
,
5118 /* Linear sequence. */
5119 mask
= gen_rtx_PARALLEL (V16QImode
, rtvec_alloc (16));
5120 for (i
= 0; i
< 16; ++i
)
5121 XVECEXP (mask
, 0, i
) = GEN_INT (i
);
5123 /* Set permute mask to insert element into target. */
5124 for (i
= 0; i
< width
; ++i
)
5125 XVECEXP (mask
, 0, elt
*width
+ i
)
5126 = GEN_INT (i
+ 0x10);
5127 x
= gen_rtx_CONST_VECTOR (V16QImode
, XVEC (mask
, 0));
5128 x
= gen_rtx_UNSPEC (mode
,
5129 gen_rtvec (3, target
, reg
,
5130 force_reg (V16QImode
, x
)),
5132 emit_insn (gen_rtx_SET (VOIDmode
, target
, x
));
5135 /* Extract field ELT from VEC into TARGET. */
5138 rs6000_expand_vector_extract (rtx target
, rtx vec
, int elt
)
5140 enum machine_mode mode
= GET_MODE (vec
);
5141 enum machine_mode inner_mode
= GET_MODE_INNER (mode
);
5144 if (VECTOR_MEM_VSX_P (mode
) && (mode
== V2DFmode
|| mode
== V2DImode
))
5146 rtx (*extract_func
) (rtx
, rtx
, rtx
)
5147 = ((mode
== V2DFmode
) ? gen_vsx_extract_v2df
: gen_vsx_extract_v2di
);
5148 emit_insn (extract_func (target
, vec
, GEN_INT (elt
)));
5152 /* Allocate mode-sized buffer. */
5153 mem
= assign_stack_temp (mode
, GET_MODE_SIZE (mode
), 0);
5155 /* Add offset to field within buffer matching vector element. */
5156 mem
= adjust_address_nv (mem
, mode
, elt
* GET_MODE_SIZE (inner_mode
));
5158 /* Store single field into mode-sized buffer. */
5159 x
= gen_rtx_UNSPEC (VOIDmode
,
5160 gen_rtvec (1, const0_rtx
), UNSPEC_STVE
);
5161 emit_insn (gen_rtx_PARALLEL (VOIDmode
,
5163 gen_rtx_SET (VOIDmode
,
5166 emit_move_insn (target
, adjust_address_nv (mem
, inner_mode
, 0));
5169 /* Generates shifts and masks for a pair of rldicl or rldicr insns to
5170 implement ANDing by the mask IN. */
5172 build_mask64_2_operands (rtx in
, rtx
*out
)
5174 #if HOST_BITS_PER_WIDE_INT >= 64
5175 unsigned HOST_WIDE_INT c
, lsb
, m1
, m2
;
5178 gcc_assert (GET_CODE (in
) == CONST_INT
);
5183 /* Assume c initially something like 0x00fff000000fffff. The idea
5184 is to rotate the word so that the middle ^^^^^^ group of zeros
5185 is at the MS end and can be cleared with an rldicl mask. We then
5186 rotate back and clear off the MS ^^ group of zeros with a
5188 c
= ~c
; /* c == 0xff000ffffff00000 */
5189 lsb
= c
& -c
; /* lsb == 0x0000000000100000 */
5190 m1
= -lsb
; /* m1 == 0xfffffffffff00000 */
5191 c
= ~c
; /* c == 0x00fff000000fffff */
5192 c
&= -lsb
; /* c == 0x00fff00000000000 */
5193 lsb
= c
& -c
; /* lsb == 0x0000100000000000 */
5194 c
= ~c
; /* c == 0xff000fffffffffff */
5195 c
&= -lsb
; /* c == 0xff00000000000000 */
5197 while ((lsb
>>= 1) != 0)
5198 shift
++; /* shift == 44 on exit from loop */
5199 m1
<<= 64 - shift
; /* m1 == 0xffffff0000000000 */
5200 m1
= ~m1
; /* m1 == 0x000000ffffffffff */
5201 m2
= ~c
; /* m2 == 0x00ffffffffffffff */
5205 /* Assume c initially something like 0xff000f0000000000. The idea
5206 is to rotate the word so that the ^^^ middle group of zeros
5207 is at the LS end and can be cleared with an rldicr mask. We then
5208 rotate back and clear off the LS group of ^^^^^^^^^^ zeros with
5210 lsb
= c
& -c
; /* lsb == 0x0000010000000000 */
5211 m2
= -lsb
; /* m2 == 0xffffff0000000000 */
5212 c
= ~c
; /* c == 0x00fff0ffffffffff */
5213 c
&= -lsb
; /* c == 0x00fff00000000000 */
5214 lsb
= c
& -c
; /* lsb == 0x0000100000000000 */
5215 c
= ~c
; /* c == 0xff000fffffffffff */
5216 c
&= -lsb
; /* c == 0xff00000000000000 */
5218 while ((lsb
>>= 1) != 0)
5219 shift
++; /* shift == 44 on exit from loop */
5220 m1
= ~c
; /* m1 == 0x00ffffffffffffff */
5221 m1
>>= shift
; /* m1 == 0x0000000000000fff */
5222 m1
= ~m1
; /* m1 == 0xfffffffffffff000 */
5225 /* Note that when we only have two 0->1 and 1->0 transitions, one of the
5226 masks will be all 1's. We are guaranteed more than one transition. */
5227 out
[0] = GEN_INT (64 - shift
);
5228 out
[1] = GEN_INT (m1
);
5229 out
[2] = GEN_INT (shift
);
5230 out
[3] = GEN_INT (m2
);
5238 /* Return TRUE if OP is an invalid SUBREG operation on the e500. */
5241 invalid_e500_subreg (rtx op
, enum machine_mode mode
)
5243 if (TARGET_E500_DOUBLE
)
5245 /* Reject (subreg:SI (reg:DF)); likewise with subreg:DI or
5246 subreg:TI and reg:TF. Decimal float modes are like integer
5247 modes (only low part of each register used) for this
5249 if (GET_CODE (op
) == SUBREG
5250 && (mode
== SImode
|| mode
== DImode
|| mode
== TImode
5251 || mode
== DDmode
|| mode
== TDmode
)
5252 && REG_P (SUBREG_REG (op
))
5253 && (GET_MODE (SUBREG_REG (op
)) == DFmode
5254 || GET_MODE (SUBREG_REG (op
)) == TFmode
))
5257 /* Reject (subreg:DF (reg:DI)); likewise with subreg:TF and
5259 if (GET_CODE (op
) == SUBREG
5260 && (mode
== DFmode
|| mode
== TFmode
)
5261 && REG_P (SUBREG_REG (op
))
5262 && (GET_MODE (SUBREG_REG (op
)) == DImode
5263 || GET_MODE (SUBREG_REG (op
)) == TImode
5264 || GET_MODE (SUBREG_REG (op
)) == DDmode
5265 || GET_MODE (SUBREG_REG (op
)) == TDmode
))
5270 && GET_CODE (op
) == SUBREG
5272 && REG_P (SUBREG_REG (op
))
5273 && SPE_VECTOR_MODE (GET_MODE (SUBREG_REG (op
))))
5279 /* AIX increases natural record alignment to doubleword if the first
5280 field is an FP double while the FP fields remain word aligned. */
5283 rs6000_special_round_type_align (tree type
, unsigned int computed
,
5284 unsigned int specified
)
5286 unsigned int align
= MAX (computed
, specified
);
5287 tree field
= TYPE_FIELDS (type
);
5289 /* Skip all non field decls */
5290 while (field
!= NULL
&& TREE_CODE (field
) != FIELD_DECL
)
5291 field
= DECL_CHAIN (field
);
5293 if (field
!= NULL
&& field
!= type
)
5295 type
= TREE_TYPE (field
);
5296 while (TREE_CODE (type
) == ARRAY_TYPE
)
5297 type
= TREE_TYPE (type
);
5299 if (type
!= error_mark_node
&& TYPE_MODE (type
) == DFmode
)
5300 align
= MAX (align
, 64);
5306 /* Darwin increases record alignment to the natural alignment of
5310 darwin_rs6000_special_round_type_align (tree type
, unsigned int computed
,
5311 unsigned int specified
)
5313 unsigned int align
= MAX (computed
, specified
);
5315 if (TYPE_PACKED (type
))
5318 /* Find the first field, looking down into aggregates. */
5320 tree field
= TYPE_FIELDS (type
);
5321 /* Skip all non field decls */
5322 while (field
!= NULL
&& TREE_CODE (field
) != FIELD_DECL
)
5323 field
= DECL_CHAIN (field
);
5326 /* A packed field does not contribute any extra alignment. */
5327 if (DECL_PACKED (field
))
5329 type
= TREE_TYPE (field
);
5330 while (TREE_CODE (type
) == ARRAY_TYPE
)
5331 type
= TREE_TYPE (type
);
5332 } while (AGGREGATE_TYPE_P (type
));
5334 if (! AGGREGATE_TYPE_P (type
) && type
!= error_mark_node
)
5335 align
= MAX (align
, TYPE_ALIGN (type
));
5340 /* Return 1 for an operand in small memory on V.4/eabi. */
5343 small_data_operand (rtx op ATTRIBUTE_UNUSED
,
5344 enum machine_mode mode ATTRIBUTE_UNUSED
)
5349 if (rs6000_sdata
== SDATA_NONE
|| rs6000_sdata
== SDATA_DATA
)
5352 if (DEFAULT_ABI
!= ABI_V4
)
5355 /* Vector and float memory instructions have a limited offset on the
5356 SPE, so using a vector or float variable directly as an operand is
5359 && (SPE_VECTOR_MODE (mode
) || FLOAT_MODE_P (mode
)))
5362 if (GET_CODE (op
) == SYMBOL_REF
)
5365 else if (GET_CODE (op
) != CONST
5366 || GET_CODE (XEXP (op
, 0)) != PLUS
5367 || GET_CODE (XEXP (XEXP (op
, 0), 0)) != SYMBOL_REF
5368 || GET_CODE (XEXP (XEXP (op
, 0), 1)) != CONST_INT
)
5373 rtx sum
= XEXP (op
, 0);
5374 HOST_WIDE_INT summand
;
5376 /* We have to be careful here, because it is the referenced address
5377 that must be 32k from _SDA_BASE_, not just the symbol. */
5378 summand
= INTVAL (XEXP (sum
, 1));
5379 if (summand
< 0 || (unsigned HOST_WIDE_INT
) summand
> g_switch_value
)
5382 sym_ref
= XEXP (sum
, 0);
5385 return SYMBOL_REF_SMALL_P (sym_ref
);
5391 /* Return true if either operand is a general purpose register. */
5394 gpr_or_gpr_p (rtx op0
, rtx op1
)
5396 return ((REG_P (op0
) && INT_REGNO_P (REGNO (op0
)))
5397 || (REG_P (op1
) && INT_REGNO_P (REGNO (op1
))));
5401 /* Subroutines of rs6000_legitimize_address and rs6000_legitimate_address_p. */
5404 reg_offset_addressing_ok_p (enum machine_mode mode
)
5414 /* AltiVec/VSX vector modes. Only reg+reg addressing is valid. */
5415 if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode
))
5423 /* Paired vector modes. Only reg+reg addressing is valid. */
5424 if (TARGET_PAIRED_FLOAT
)
5436 virtual_stack_registers_memory_p (rtx op
)
5440 if (GET_CODE (op
) == REG
)
5441 regnum
= REGNO (op
);
5443 else if (GET_CODE (op
) == PLUS
5444 && GET_CODE (XEXP (op
, 0)) == REG
5445 && GET_CODE (XEXP (op
, 1)) == CONST_INT
)
5446 regnum
= REGNO (XEXP (op
, 0));
5451 return (regnum
>= FIRST_VIRTUAL_REGISTER
5452 && regnum
<= LAST_VIRTUAL_REGISTER
);
5456 constant_pool_expr_p (rtx op
)
5460 split_const (op
, &base
, &offset
);
5461 return (GET_CODE (base
) == SYMBOL_REF
5462 && CONSTANT_POOL_ADDRESS_P (base
)
5463 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (base
), Pmode
));
5466 static rtx tocrel_base
, tocrel_offset
;
5469 toc_relative_expr_p (rtx op
)
5471 if (GET_CODE (op
) != CONST
)
5474 split_const (op
, &tocrel_base
, &tocrel_offset
);
5475 return (GET_CODE (tocrel_base
) == UNSPEC
5476 && XINT (tocrel_base
, 1) == UNSPEC_TOCREL
);
5480 legitimate_constant_pool_address_p (const_rtx x
, bool strict
)
5483 && (GET_CODE (x
) == PLUS
|| GET_CODE (x
) == LO_SUM
)
5484 && GET_CODE (XEXP (x
, 0)) == REG
5485 && (REGNO (XEXP (x
, 0)) == TOC_REGISTER
5486 || ((TARGET_MINIMAL_TOC
5487 || TARGET_CMODEL
!= CMODEL_SMALL
)
5488 && INT_REG_OK_FOR_BASE_P (XEXP (x
, 0), strict
)))
5489 && toc_relative_expr_p (XEXP (x
, 1)));
5493 legitimate_small_data_p (enum machine_mode mode
, rtx x
)
5495 return (DEFAULT_ABI
== ABI_V4
5496 && !flag_pic
&& !TARGET_TOC
5497 && (GET_CODE (x
) == SYMBOL_REF
|| GET_CODE (x
) == CONST
)
5498 && small_data_operand (x
, mode
));
5501 /* SPE offset addressing is limited to 5-bits worth of double words. */
5502 #define SPE_CONST_OFFSET_OK(x) (((x) & ~0xf8) == 0)
5505 rs6000_legitimate_offset_address_p (enum machine_mode mode
, rtx x
, int strict
)
5507 unsigned HOST_WIDE_INT offset
, extra
;
5509 if (GET_CODE (x
) != PLUS
)
5511 if (GET_CODE (XEXP (x
, 0)) != REG
)
5513 if (!INT_REG_OK_FOR_BASE_P (XEXP (x
, 0), strict
))
5515 if (!reg_offset_addressing_ok_p (mode
))
5516 return virtual_stack_registers_memory_p (x
);
5517 if (legitimate_constant_pool_address_p (x
, strict
))
5519 if (GET_CODE (XEXP (x
, 1)) != CONST_INT
)
5522 offset
= INTVAL (XEXP (x
, 1));
5530 /* SPE vector modes. */
5531 return SPE_CONST_OFFSET_OK (offset
);
5534 if (TARGET_E500_DOUBLE
)
5535 return SPE_CONST_OFFSET_OK (offset
);
5537 /* If we are using VSX scalar loads, restrict ourselves to reg+reg
5539 if (VECTOR_MEM_VSX_P (DFmode
))
5544 /* On e500v2, we may have:
5546 (subreg:DF (mem:DI (plus (reg) (const_int))) 0).
5548 Which gets addressed with evldd instructions. */
5549 if (TARGET_E500_DOUBLE
)
5550 return SPE_CONST_OFFSET_OK (offset
);
5552 if (mode
== DFmode
|| mode
== DDmode
|| !TARGET_POWERPC64
)
5554 else if (offset
& 3)
5559 if (TARGET_E500_DOUBLE
)
5560 return (SPE_CONST_OFFSET_OK (offset
)
5561 && SPE_CONST_OFFSET_OK (offset
+ 8));
5565 if (mode
== TFmode
|| mode
== TDmode
|| !TARGET_POWERPC64
)
5567 else if (offset
& 3)
5578 return (offset
< 0x10000) && (offset
+ extra
< 0x10000);
5582 legitimate_indexed_address_p (rtx x
, int strict
)
5586 if (GET_CODE (x
) != PLUS
)
5592 /* Recognize the rtl generated by reload which we know will later be
5593 replaced with proper base and index regs. */
5595 && reload_in_progress
5596 && (REG_P (op0
) || GET_CODE (op0
) == PLUS
)
5600 return (REG_P (op0
) && REG_P (op1
)
5601 && ((INT_REG_OK_FOR_BASE_P (op0
, strict
)
5602 && INT_REG_OK_FOR_INDEX_P (op1
, strict
))
5603 || (INT_REG_OK_FOR_BASE_P (op1
, strict
)
5604 && INT_REG_OK_FOR_INDEX_P (op0
, strict
))));
5608 avoiding_indexed_address_p (enum machine_mode mode
)
5610 /* Avoid indexed addressing for modes that have non-indexed
5611 load/store instruction forms. */
5612 return (TARGET_AVOID_XFORM
&& VECTOR_MEM_NONE_P (mode
));
5616 legitimate_indirect_address_p (rtx x
, int strict
)
5618 return GET_CODE (x
) == REG
&& INT_REG_OK_FOR_BASE_P (x
, strict
);
5622 macho_lo_sum_memory_operand (rtx x
, enum machine_mode mode
)
5624 if (!TARGET_MACHO
|| !flag_pic
5625 || mode
!= SImode
|| GET_CODE (x
) != MEM
)
5629 if (GET_CODE (x
) != LO_SUM
)
5631 if (GET_CODE (XEXP (x
, 0)) != REG
)
5633 if (!INT_REG_OK_FOR_BASE_P (XEXP (x
, 0), 0))
5637 return CONSTANT_P (x
);
5641 legitimate_lo_sum_address_p (enum machine_mode mode
, rtx x
, int strict
)
5643 if (GET_CODE (x
) != LO_SUM
)
5645 if (GET_CODE (XEXP (x
, 0)) != REG
)
5647 if (!INT_REG_OK_FOR_BASE_P (XEXP (x
, 0), strict
))
5649 /* Restrict addressing for DI because of our SUBREG hackery. */
5650 if (TARGET_E500_DOUBLE
&& (mode
== DFmode
|| mode
== TFmode
5651 || mode
== DDmode
|| mode
== TDmode
5656 if (TARGET_ELF
|| TARGET_MACHO
)
5658 if (DEFAULT_ABI
!= ABI_AIX
&& DEFAULT_ABI
!= ABI_DARWIN
&& flag_pic
)
5662 if (GET_MODE_NUNITS (mode
) != 1)
5664 if (GET_MODE_BITSIZE (mode
) > 64
5665 || (GET_MODE_BITSIZE (mode
) > 32 && !TARGET_POWERPC64
5666 && !(TARGET_HARD_FLOAT
&& TARGET_FPRS
&& TARGET_DOUBLE_FLOAT
5667 && (mode
== DFmode
|| mode
== DDmode
))))
5670 return CONSTANT_P (x
);
5677 /* Try machine-dependent ways of modifying an illegitimate address
5678 to be legitimate. If we find one, return the new, valid address.
5679 This is used from only one place: `memory_address' in explow.c.
5681 OLDX is the address as it was before break_out_memory_refs was
5682 called. In some cases it is useful to look at this to decide what
5685 It is always safe for this function to do nothing. It exists to
5686 recognize opportunities to optimize the output.
5688 On RS/6000, first check for the sum of a register with a constant
5689 integer that is out of range. If so, generate code to add the
5690 constant with the low-order 16 bits masked to the register and force
5691 this result into another register (this can be done with `cau').
5692 Then generate an address of REG+(CONST&0xffff), allowing for the
5693 possibility of bit 16 being a one.
5695 Then check for the sum of a register and something not constant, try to
5696 load the other things into a register and return the sum. */
5699 rs6000_legitimize_address (rtx x
, rtx oldx ATTRIBUTE_UNUSED
,
5700 enum machine_mode mode
)
5702 unsigned int extra
= 0;
5704 if (!reg_offset_addressing_ok_p (mode
))
5706 if (virtual_stack_registers_memory_p (x
))
5709 /* In theory we should not be seeing addresses of the form reg+0,
5710 but just in case it is generated, optimize it away. */
5711 if (GET_CODE (x
) == PLUS
&& XEXP (x
, 1) == const0_rtx
)
5712 return force_reg (Pmode
, XEXP (x
, 0));
5714 /* Make sure both operands are registers. */
5715 else if (GET_CODE (x
) == PLUS
)
5716 return gen_rtx_PLUS (Pmode
,
5717 force_reg (Pmode
, XEXP (x
, 0)),
5718 force_reg (Pmode
, XEXP (x
, 1)));
5720 return force_reg (Pmode
, x
);
5722 if (GET_CODE (x
) == SYMBOL_REF
)
5724 enum tls_model model
= SYMBOL_REF_TLS_MODEL (x
);
5726 return rs6000_legitimize_tls_address (x
, model
);
5736 if (!TARGET_POWERPC64
)
5744 extra
= TARGET_POWERPC64
? 8 : 12;
5750 if (GET_CODE (x
) == PLUS
5751 && GET_CODE (XEXP (x
, 0)) == REG
5752 && GET_CODE (XEXP (x
, 1)) == CONST_INT
5753 && ((unsigned HOST_WIDE_INT
) (INTVAL (XEXP (x
, 1)) + 0x8000)
5755 && !((TARGET_POWERPC64
5756 && (mode
== DImode
|| mode
== TImode
)
5757 && (INTVAL (XEXP (x
, 1)) & 3) != 0)
5758 || SPE_VECTOR_MODE (mode
)
5759 || (TARGET_E500_DOUBLE
&& (mode
== DFmode
|| mode
== TFmode
5760 || mode
== DImode
|| mode
== DDmode
5761 || mode
== TDmode
))))
5763 HOST_WIDE_INT high_int
, low_int
;
5765 low_int
= ((INTVAL (XEXP (x
, 1)) & 0xffff) ^ 0x8000) - 0x8000;
5766 if (low_int
>= 0x8000 - extra
)
5768 high_int
= INTVAL (XEXP (x
, 1)) - low_int
;
5769 sum
= force_operand (gen_rtx_PLUS (Pmode
, XEXP (x
, 0),
5770 GEN_INT (high_int
)), 0);
5771 return plus_constant (sum
, low_int
);
5773 else if (GET_CODE (x
) == PLUS
5774 && GET_CODE (XEXP (x
, 0)) == REG
5775 && GET_CODE (XEXP (x
, 1)) != CONST_INT
5776 && GET_MODE_NUNITS (mode
) == 1
5777 && ((TARGET_HARD_FLOAT
&& TARGET_FPRS
&& TARGET_DOUBLE_FLOAT
)
5779 || ((mode
!= DImode
&& mode
!= DFmode
&& mode
!= DDmode
)
5780 || (TARGET_E500_DOUBLE
&& mode
!= DDmode
)))
5781 && (TARGET_POWERPC64
|| mode
!= DImode
)
5782 && !avoiding_indexed_address_p (mode
)
5787 return gen_rtx_PLUS (Pmode
, XEXP (x
, 0),
5788 force_reg (Pmode
, force_operand (XEXP (x
, 1), 0)));
5790 else if (SPE_VECTOR_MODE (mode
)
5791 || (TARGET_E500_DOUBLE
&& (mode
== DFmode
|| mode
== TFmode
5792 || mode
== DDmode
|| mode
== TDmode
5793 || mode
== DImode
)))
5797 /* We accept [reg + reg] and [reg + OFFSET]. */
5799 if (GET_CODE (x
) == PLUS
)
5801 rtx op1
= XEXP (x
, 0);
5802 rtx op2
= XEXP (x
, 1);
5805 op1
= force_reg (Pmode
, op1
);
5807 if (GET_CODE (op2
) != REG
5808 && (GET_CODE (op2
) != CONST_INT
5809 || !SPE_CONST_OFFSET_OK (INTVAL (op2
))
5810 || (GET_MODE_SIZE (mode
) > 8
5811 && !SPE_CONST_OFFSET_OK (INTVAL (op2
) + 8))))
5812 op2
= force_reg (Pmode
, op2
);
5814 /* We can't always do [reg + reg] for these, because [reg +
5815 reg + offset] is not a legitimate addressing mode. */
5816 y
= gen_rtx_PLUS (Pmode
, op1
, op2
);
5818 if ((GET_MODE_SIZE (mode
) > 8 || mode
== DDmode
) && REG_P (op2
))
5819 return force_reg (Pmode
, y
);
5824 return force_reg (Pmode
, x
);
5830 && GET_CODE (x
) != CONST_INT
5831 && GET_CODE (x
) != CONST_DOUBLE
5833 && GET_MODE_NUNITS (mode
) == 1
5834 && (GET_MODE_BITSIZE (mode
) <= 32
5835 || ((TARGET_HARD_FLOAT
&& TARGET_FPRS
&& TARGET_DOUBLE_FLOAT
)
5836 && (mode
== DFmode
|| mode
== DDmode
))))
5838 rtx reg
= gen_reg_rtx (Pmode
);
5839 emit_insn (gen_elf_high (reg
, x
));
5840 return gen_rtx_LO_SUM (Pmode
, reg
, x
);
5842 else if (TARGET_MACHO
&& TARGET_32BIT
&& TARGET_NO_TOC
5845 && ! MACHO_DYNAMIC_NO_PIC_P
5847 && GET_CODE (x
) != CONST_INT
5848 && GET_CODE (x
) != CONST_DOUBLE
5850 && GET_MODE_NUNITS (mode
) == 1
5851 && ((TARGET_HARD_FLOAT
&& TARGET_FPRS
&& TARGET_DOUBLE_FLOAT
)
5852 || (mode
!= DFmode
&& mode
!= DDmode
))
5856 rtx reg
= gen_reg_rtx (Pmode
);
5857 emit_insn (gen_macho_high (reg
, x
));
5858 return gen_rtx_LO_SUM (Pmode
, reg
, x
);
5861 && GET_CODE (x
) == SYMBOL_REF
5862 && constant_pool_expr_p (x
)
5863 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x
), Pmode
))
5865 rtx reg
= TARGET_CMODEL
!= CMODEL_SMALL
? gen_reg_rtx (Pmode
) : NULL_RTX
;
5866 return create_TOC_reference (x
, reg
);
5872 /* Debug version of rs6000_legitimize_address. */
5874 rs6000_debug_legitimize_address (rtx x
, rtx oldx
, enum machine_mode mode
)
5880 ret
= rs6000_legitimize_address (x
, oldx
, mode
);
5881 insns
= get_insns ();
5887 "\nrs6000_legitimize_address: mode %s, old code %s, "
5888 "new code %s, modified\n",
5889 GET_MODE_NAME (mode
), GET_RTX_NAME (GET_CODE (x
)),
5890 GET_RTX_NAME (GET_CODE (ret
)));
5892 fprintf (stderr
, "Original address:\n");
5895 fprintf (stderr
, "oldx:\n");
5898 fprintf (stderr
, "New address:\n");
5903 fprintf (stderr
, "Insns added:\n");
5904 debug_rtx_list (insns
, 20);
5910 "\nrs6000_legitimize_address: mode %s, code %s, no change:\n",
5911 GET_MODE_NAME (mode
), GET_RTX_NAME (GET_CODE (x
)));
5922 /* This is called from dwarf2out.c via TARGET_ASM_OUTPUT_DWARF_DTPREL.
5923 We need to emit DTP-relative relocations. */
5926 rs6000_output_dwarf_dtprel (FILE *file
, int size
, rtx x
)
5931 fputs ("\t.long\t", file
);
5934 fputs (DOUBLE_INT_ASM_OP
, file
);
5939 output_addr_const (file
, x
);
5940 fputs ("@dtprel+0x8000", file
);
5943 /* In the name of slightly smaller debug output, and to cater to
5944 general assembler lossage, recognize various UNSPEC sequences
5945 and turn them back into a direct symbol reference. */
5948 rs6000_delegitimize_address (rtx orig_x
)
5952 orig_x
= delegitimize_mem_from_attrs (orig_x
);
5957 if ((GET_CODE (x
) == PLUS
5958 || GET_CODE (x
) == LO_SUM
)
5959 && GET_CODE (XEXP (x
, 0)) == REG
5960 && (REGNO (XEXP (x
, 0)) == TOC_REGISTER
5961 || TARGET_MINIMAL_TOC
5962 || TARGET_CMODEL
!= CMODEL_SMALL
)
5963 && GET_CODE (XEXP (x
, 1)) == CONST
)
5965 y
= XEXP (XEXP (x
, 1), 0);
5966 if (GET_CODE (y
) == UNSPEC
5967 && XINT (y
, 1) == UNSPEC_TOCREL
)
5969 y
= XVECEXP (y
, 0, 0);
5970 if (!MEM_P (orig_x
))
5973 return replace_equiv_address_nv (orig_x
, y
);
5978 && GET_CODE (orig_x
) == LO_SUM
5979 && GET_CODE (XEXP (x
, 1)) == CONST
)
5981 y
= XEXP (XEXP (x
, 1), 0);
5982 if (GET_CODE (y
) == UNSPEC
5983 && XINT (y
, 1) == UNSPEC_MACHOPIC_OFFSET
)
5984 return XVECEXP (y
, 0, 0);
5990 /* Construct the SYMBOL_REF for the tls_get_addr function. */
5992 static GTY(()) rtx rs6000_tls_symbol
;
5994 rs6000_tls_get_addr (void)
5996 if (!rs6000_tls_symbol
)
5997 rs6000_tls_symbol
= init_one_libfunc ("__tls_get_addr");
5999 return rs6000_tls_symbol
;
6002 /* Construct the SYMBOL_REF for TLS GOT references. */
6004 static GTY(()) rtx rs6000_got_symbol
;
6006 rs6000_got_sym (void)
6008 if (!rs6000_got_symbol
)
6010 rs6000_got_symbol
= gen_rtx_SYMBOL_REF (Pmode
, "_GLOBAL_OFFSET_TABLE_");
6011 SYMBOL_REF_FLAGS (rs6000_got_symbol
) |= SYMBOL_FLAG_LOCAL
;
6012 SYMBOL_REF_FLAGS (rs6000_got_symbol
) |= SYMBOL_FLAG_EXTERNAL
;
6015 return rs6000_got_symbol
;
6018 /* ADDR contains a thread-local SYMBOL_REF. Generate code to compute
6019 this (thread-local) address. */
6022 rs6000_legitimize_tls_address (rtx addr
, enum tls_model model
)
6026 dest
= gen_reg_rtx (Pmode
);
6027 if (model
== TLS_MODEL_LOCAL_EXEC
&& rs6000_tls_size
== 16)
6033 tlsreg
= gen_rtx_REG (Pmode
, 13);
6034 insn
= gen_tls_tprel_64 (dest
, tlsreg
, addr
);
6038 tlsreg
= gen_rtx_REG (Pmode
, 2);
6039 insn
= gen_tls_tprel_32 (dest
, tlsreg
, addr
);
6043 else if (model
== TLS_MODEL_LOCAL_EXEC
&& rs6000_tls_size
== 32)
6047 tmp
= gen_reg_rtx (Pmode
);
6050 tlsreg
= gen_rtx_REG (Pmode
, 13);
6051 insn
= gen_tls_tprel_ha_64 (tmp
, tlsreg
, addr
);
6055 tlsreg
= gen_rtx_REG (Pmode
, 2);
6056 insn
= gen_tls_tprel_ha_32 (tmp
, tlsreg
, addr
);
6060 insn
= gen_tls_tprel_lo_64 (dest
, tmp
, addr
);
6062 insn
= gen_tls_tprel_lo_32 (dest
, tmp
, addr
);
6067 rtx r3
, got
, tga
, tmp1
, tmp2
, call_insn
;
6069 /* We currently use relocations like @got@tlsgd for tls, which
6070 means the linker will handle allocation of tls entries, placing
6071 them in the .got section. So use a pointer to the .got section,
6072 not one to secondary TOC sections used by 64-bit -mminimal-toc,
6073 or to secondary GOT sections used by 32-bit -fPIC. */
6075 got
= gen_rtx_REG (Pmode
, 2);
6079 got
= gen_rtx_REG (Pmode
, RS6000_PIC_OFFSET_TABLE_REGNUM
);
6082 rtx gsym
= rs6000_got_sym ();
6083 got
= gen_reg_rtx (Pmode
);
6085 rs6000_emit_move (got
, gsym
, Pmode
);
6090 tmp1
= gen_reg_rtx (Pmode
);
6091 tmp2
= gen_reg_rtx (Pmode
);
6092 mem
= gen_const_mem (Pmode
, tmp1
);
6093 lab
= gen_label_rtx ();
6094 emit_insn (gen_load_toc_v4_PIC_1b (gsym
, lab
));
6095 emit_move_insn (tmp1
, gen_rtx_REG (Pmode
, LR_REGNO
));
6096 emit_move_insn (tmp2
, mem
);
6097 last
= emit_insn (gen_addsi3 (got
, tmp1
, tmp2
));
6098 set_unique_reg_note (last
, REG_EQUAL
, gsym
);
6103 if (model
== TLS_MODEL_GLOBAL_DYNAMIC
)
6105 r3
= gen_rtx_REG (Pmode
, 3);
6106 tga
= rs6000_tls_get_addr ();
6107 emit_library_call_value (tga
, dest
, LCT_CONST
, Pmode
, 1, r3
, Pmode
);
6109 if (DEFAULT_ABI
== ABI_AIX
&& TARGET_64BIT
)
6110 insn
= gen_tls_gd_aix64 (r3
, got
, addr
, tga
, const0_rtx
);
6111 else if (DEFAULT_ABI
== ABI_AIX
&& !TARGET_64BIT
)
6112 insn
= gen_tls_gd_aix32 (r3
, got
, addr
, tga
, const0_rtx
);
6113 else if (DEFAULT_ABI
== ABI_V4
)
6114 insn
= gen_tls_gd_sysvsi (r3
, got
, addr
, tga
, const0_rtx
);
6117 call_insn
= last_call_insn ();
6118 PATTERN (call_insn
) = insn
;
6119 if (DEFAULT_ABI
== ABI_V4
&& TARGET_SECURE_PLT
&& flag_pic
)
6120 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn
),
6121 pic_offset_table_rtx
);
6123 else if (model
== TLS_MODEL_LOCAL_DYNAMIC
)
6125 r3
= gen_rtx_REG (Pmode
, 3);
6126 tga
= rs6000_tls_get_addr ();
6127 tmp1
= gen_reg_rtx (Pmode
);
6128 emit_library_call_value (tga
, tmp1
, LCT_CONST
, Pmode
, 1, r3
, Pmode
);
6130 if (DEFAULT_ABI
== ABI_AIX
&& TARGET_64BIT
)
6131 insn
= gen_tls_ld_aix64 (r3
, got
, tga
, const0_rtx
);
6132 else if (DEFAULT_ABI
== ABI_AIX
&& !TARGET_64BIT
)
6133 insn
= gen_tls_ld_aix32 (r3
, got
, tga
, const0_rtx
);
6134 else if (DEFAULT_ABI
== ABI_V4
)
6135 insn
= gen_tls_ld_sysvsi (r3
, got
, tga
, const0_rtx
);
6138 call_insn
= last_call_insn ();
6139 PATTERN (call_insn
) = insn
;
6140 if (DEFAULT_ABI
== ABI_V4
&& TARGET_SECURE_PLT
&& flag_pic
)
6141 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn
),
6142 pic_offset_table_rtx
);
6144 if (rs6000_tls_size
== 16)
6147 insn
= gen_tls_dtprel_64 (dest
, tmp1
, addr
);
6149 insn
= gen_tls_dtprel_32 (dest
, tmp1
, addr
);
6151 else if (rs6000_tls_size
== 32)
6153 tmp2
= gen_reg_rtx (Pmode
);
6155 insn
= gen_tls_dtprel_ha_64 (tmp2
, tmp1
, addr
);
6157 insn
= gen_tls_dtprel_ha_32 (tmp2
, tmp1
, addr
);
6160 insn
= gen_tls_dtprel_lo_64 (dest
, tmp2
, addr
);
6162 insn
= gen_tls_dtprel_lo_32 (dest
, tmp2
, addr
);
6166 tmp2
= gen_reg_rtx (Pmode
);
6168 insn
= gen_tls_got_dtprel_64 (tmp2
, got
, addr
);
6170 insn
= gen_tls_got_dtprel_32 (tmp2
, got
, addr
);
6172 insn
= gen_rtx_SET (Pmode
, dest
,
6173 gen_rtx_PLUS (Pmode
, tmp2
, tmp1
));
6179 /* IE, or 64-bit offset LE. */
6180 tmp2
= gen_reg_rtx (Pmode
);
6182 insn
= gen_tls_got_tprel_64 (tmp2
, got
, addr
);
6184 insn
= gen_tls_got_tprel_32 (tmp2
, got
, addr
);
6187 insn
= gen_tls_tls_64 (dest
, tmp2
, addr
);
6189 insn
= gen_tls_tls_32 (dest
, tmp2
, addr
);
6197 /* Return 1 if X contains a thread-local symbol. */
6200 rs6000_tls_referenced_p (rtx x
)
6202 if (! TARGET_HAVE_TLS
)
6205 return for_each_rtx (&x
, &rs6000_tls_symbol_ref_1
, 0);
6208 /* Return 1 if *X is a thread-local symbol. This is the same as
6209 rs6000_tls_symbol_ref except for the type of the unused argument. */
6212 rs6000_tls_symbol_ref_1 (rtx
*x
, void *data ATTRIBUTE_UNUSED
)
6214 return RS6000_SYMBOL_REF_TLS_P (*x
);
6217 /* Our implementation of LEGITIMIZE_RELOAD_ADDRESS. Returns a value to
6218 replace the input X, or the original X if no replacement is called for.
6219 The output parameter *WIN is 1 if the calling macro should goto WIN,
6222 For RS/6000, we wish to handle large displacements off a base
6223 register by splitting the addend across an addiu/addis and the mem insn.
6224 This cuts number of extra insns needed from 3 to 1.
6226 On Darwin, we use this to generate code for floating point constants.
6227 A movsf_low is generated so we wind up with 2 instructions rather than 3.
6228 The Darwin code is inside #if TARGET_MACHO because only then are the
6229 machopic_* functions defined. */
6231 rs6000_legitimize_reload_address (rtx x
, enum machine_mode mode
,
6232 int opnum
, int type
,
6233 int ind_levels ATTRIBUTE_UNUSED
, int *win
)
6235 bool reg_offset_p
= reg_offset_addressing_ok_p (mode
);
6237 /* We must recognize output that we have already generated ourselves. */
6238 if (GET_CODE (x
) == PLUS
6239 && GET_CODE (XEXP (x
, 0)) == PLUS
6240 && GET_CODE (XEXP (XEXP (x
, 0), 0)) == REG
6241 && GET_CODE (XEXP (XEXP (x
, 0), 1)) == CONST_INT
6242 && GET_CODE (XEXP (x
, 1)) == CONST_INT
)
6244 push_reload (XEXP (x
, 0), NULL_RTX
, &XEXP (x
, 0), NULL
,
6245 BASE_REG_CLASS
, GET_MODE (x
), VOIDmode
, 0, 0,
6246 opnum
, (enum reload_type
)type
);
6251 /* Likewise for (lo_sum (high ...) ...) output we have generated. */
6252 if (GET_CODE (x
) == LO_SUM
6253 && GET_CODE (XEXP (x
, 0)) == HIGH
)
6255 push_reload (XEXP (x
, 0), NULL_RTX
, &XEXP (x
, 0), NULL
,
6256 BASE_REG_CLASS
, Pmode
, VOIDmode
, 0, 0,
6257 opnum
, (enum reload_type
)type
);
6263 if (DEFAULT_ABI
== ABI_DARWIN
&& flag_pic
6264 && GET_CODE (x
) == LO_SUM
6265 && GET_CODE (XEXP (x
, 0)) == PLUS
6266 && XEXP (XEXP (x
, 0), 0) == pic_offset_table_rtx
6267 && GET_CODE (XEXP (XEXP (x
, 0), 1)) == HIGH
6268 && XEXP (XEXP (XEXP (x
, 0), 1), 0) == XEXP (x
, 1)
6269 && machopic_operand_p (XEXP (x
, 1)))
6271 /* Result of previous invocation of this function on Darwin
6272 floating point constant. */
6273 push_reload (XEXP (x
, 0), NULL_RTX
, &XEXP (x
, 0), NULL
,
6274 BASE_REG_CLASS
, Pmode
, VOIDmode
, 0, 0,
6275 opnum
, (enum reload_type
)type
);
6281 if (TARGET_CMODEL
!= CMODEL_SMALL
6282 && GET_CODE (x
) == LO_SUM
6283 && GET_CODE (XEXP (x
, 0)) == PLUS
6284 && GET_CODE (XEXP (XEXP (x
, 0), 0)) == REG
6285 && REGNO (XEXP (XEXP (x
, 0), 0)) == TOC_REGISTER
6286 && GET_CODE (XEXP (XEXP (x
, 0), 1)) == HIGH
6287 && GET_CODE (XEXP (x
, 1)) == CONST
6288 && GET_CODE (XEXP (XEXP (x
, 1), 0)) == UNSPEC
6289 && XINT (XEXP (XEXP (x
, 1), 0), 1) == UNSPEC_TOCREL
6290 && rtx_equal_p (XEXP (XEXP (XEXP (x
, 0), 1), 0), XEXP (x
, 1)))
6292 push_reload (XEXP (x
, 0), NULL_RTX
, &XEXP (x
, 0), NULL
,
6293 BASE_REG_CLASS
, Pmode
, VOIDmode
, 0, 0,
6294 opnum
, (enum reload_type
) type
);
6299 /* Force ld/std non-word aligned offset into base register by wrapping
6301 if (GET_CODE (x
) == PLUS
6302 && GET_CODE (XEXP (x
, 0)) == REG
6303 && REGNO (XEXP (x
, 0)) < 32
6304 && INT_REG_OK_FOR_BASE_P (XEXP (x
, 0), 1)
6305 && GET_CODE (XEXP (x
, 1)) == CONST_INT
6307 && (INTVAL (XEXP (x
, 1)) & 3) != 0
6308 && VECTOR_MEM_NONE_P (mode
)
6309 && GET_MODE_SIZE (mode
) >= UNITS_PER_WORD
6310 && TARGET_POWERPC64
)
6312 x
= gen_rtx_PLUS (GET_MODE (x
), x
, GEN_INT (0));
6313 push_reload (XEXP (x
, 0), NULL_RTX
, &XEXP (x
, 0), NULL
,
6314 BASE_REG_CLASS
, GET_MODE (x
), VOIDmode
, 0, 0,
6315 opnum
, (enum reload_type
) type
);
6320 if (GET_CODE (x
) == PLUS
6321 && GET_CODE (XEXP (x
, 0)) == REG
6322 && REGNO (XEXP (x
, 0)) < FIRST_PSEUDO_REGISTER
6323 && INT_REG_OK_FOR_BASE_P (XEXP (x
, 0), 1)
6324 && GET_CODE (XEXP (x
, 1)) == CONST_INT
6326 && !SPE_VECTOR_MODE (mode
)
6327 && !(TARGET_E500_DOUBLE
&& (mode
== DFmode
|| mode
== TFmode
6328 || mode
== DDmode
|| mode
== TDmode
6330 && VECTOR_MEM_NONE_P (mode
))
6332 HOST_WIDE_INT val
= INTVAL (XEXP (x
, 1));
6333 HOST_WIDE_INT low
= ((val
& 0xffff) ^ 0x8000) - 0x8000;
6335 = (((val
- low
) & 0xffffffff) ^ 0x80000000) - 0x80000000;
6337 /* Check for 32-bit overflow. */
6338 if (high
+ low
!= val
)
6344 /* Reload the high part into a base reg; leave the low part
6345 in the mem directly. */
6347 x
= gen_rtx_PLUS (GET_MODE (x
),
6348 gen_rtx_PLUS (GET_MODE (x
), XEXP (x
, 0),
6352 push_reload (XEXP (x
, 0), NULL_RTX
, &XEXP (x
, 0), NULL
,
6353 BASE_REG_CLASS
, GET_MODE (x
), VOIDmode
, 0, 0,
6354 opnum
, (enum reload_type
)type
);
6359 if (GET_CODE (x
) == SYMBOL_REF
6361 && VECTOR_MEM_NONE_P (mode
)
6362 && !SPE_VECTOR_MODE (mode
)
6364 && DEFAULT_ABI
== ABI_DARWIN
6365 && (flag_pic
|| MACHO_DYNAMIC_NO_PIC_P
)
6367 && DEFAULT_ABI
== ABI_V4
6370 /* Don't do this for TFmode or TDmode, since the result isn't offsettable.
6371 The same goes for DImode without 64-bit gprs and DFmode and DDmode
6375 && (mode
!= DImode
|| TARGET_POWERPC64
)
6376 && ((mode
!= DFmode
&& mode
!= DDmode
) || TARGET_POWERPC64
6377 || (TARGET_HARD_FLOAT
&& TARGET_FPRS
&& TARGET_DOUBLE_FLOAT
)))
6382 rtx offset
= machopic_gen_offset (x
);
6383 x
= gen_rtx_LO_SUM (GET_MODE (x
),
6384 gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
,
6385 gen_rtx_HIGH (Pmode
, offset
)), offset
);
6389 x
= gen_rtx_LO_SUM (GET_MODE (x
),
6390 gen_rtx_HIGH (Pmode
, x
), x
);
6392 push_reload (XEXP (x
, 0), NULL_RTX
, &XEXP (x
, 0), NULL
,
6393 BASE_REG_CLASS
, Pmode
, VOIDmode
, 0, 0,
6394 opnum
, (enum reload_type
)type
);
6399 /* Reload an offset address wrapped by an AND that represents the
6400 masking of the lower bits. Strip the outer AND and let reload
6401 convert the offset address into an indirect address. For VSX,
6402 force reload to create the address with an AND in a separate
6403 register, because we can't guarantee an altivec register will
6405 if (VECTOR_MEM_ALTIVEC_P (mode
)
6406 && GET_CODE (x
) == AND
6407 && GET_CODE (XEXP (x
, 0)) == PLUS
6408 && GET_CODE (XEXP (XEXP (x
, 0), 0)) == REG
6409 && GET_CODE (XEXP (XEXP (x
, 0), 1)) == CONST_INT
6410 && GET_CODE (XEXP (x
, 1)) == CONST_INT
6411 && INTVAL (XEXP (x
, 1)) == -16)
6420 && GET_CODE (x
) == SYMBOL_REF
6421 && constant_pool_expr_p (x
)
6422 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x
), mode
))
6424 x
= create_TOC_reference (x
, NULL_RTX
);
6425 if (TARGET_CMODEL
!= CMODEL_SMALL
)
6426 push_reload (XEXP (x
, 0), NULL_RTX
, &XEXP (x
, 0), NULL
,
6427 BASE_REG_CLASS
, Pmode
, VOIDmode
, 0, 0,
6428 opnum
, (enum reload_type
) type
);
6436 /* Debug version of rs6000_legitimize_reload_address. */
6438 rs6000_debug_legitimize_reload_address (rtx x
, enum machine_mode mode
,
6439 int opnum
, int type
,
6440 int ind_levels
, int *win
)
6442 rtx ret
= rs6000_legitimize_reload_address (x
, mode
, opnum
, type
,
6445 "\nrs6000_legitimize_reload_address: mode = %s, opnum = %d, "
6446 "type = %d, ind_levels = %d, win = %d, original addr:\n",
6447 GET_MODE_NAME (mode
), opnum
, type
, ind_levels
, *win
);
6451 fprintf (stderr
, "Same address returned\n");
6453 fprintf (stderr
, "NULL returned\n");
6456 fprintf (stderr
, "New address:\n");
6463 /* TARGET_LEGITIMATE_ADDRESS_P recognizes an RTL expression
6464 that is a valid memory address for an instruction.
6465 The MODE argument is the machine mode for the MEM expression
6466 that wants to use this address.
6468 On the RS/6000, there are four valid address: a SYMBOL_REF that
6469 refers to a constant pool entry of an address (or the sum of it
6470 plus a constant), a short (16-bit signed) constant plus a register,
6471 the sum of two registers, or a register indirect, possibly with an
6472 auto-increment. For DFmode, DDmode and DImode with a constant plus
6473 register, we must ensure that both words are addressable or PowerPC64
6474 with offset word aligned.
6476 For modes spanning multiple registers (DFmode and DDmode in 32-bit GPRs,
6477 32-bit DImode, TImode, TFmode, TDmode), indexed addressing cannot be used
6478 because adjacent memory cells are accessed by adding word-sized offsets
6479 during assembly output. */
6481 rs6000_legitimate_address_p (enum machine_mode mode
, rtx x
, bool reg_ok_strict
)
6483 bool reg_offset_p
= reg_offset_addressing_ok_p (mode
);
6485 /* If this is an unaligned stvx/ldvx type address, discard the outer AND. */
6486 if (VECTOR_MEM_ALTIVEC_P (mode
)
6487 && GET_CODE (x
) == AND
6488 && GET_CODE (XEXP (x
, 1)) == CONST_INT
6489 && INTVAL (XEXP (x
, 1)) == -16)
6492 if (RS6000_SYMBOL_REF_TLS_P (x
))
6494 if (legitimate_indirect_address_p (x
, reg_ok_strict
))
6496 if ((GET_CODE (x
) == PRE_INC
|| GET_CODE (x
) == PRE_DEC
)
6497 && !VECTOR_MEM_ALTIVEC_OR_VSX_P (mode
)
6498 && !SPE_VECTOR_MODE (mode
)
6501 /* Restrict addressing for DI because of our SUBREG hackery. */
6502 && !(TARGET_E500_DOUBLE
6503 && (mode
== DFmode
|| mode
== DDmode
|| mode
== DImode
))
6505 && legitimate_indirect_address_p (XEXP (x
, 0), reg_ok_strict
))
6507 if (virtual_stack_registers_memory_p (x
))
6509 if (reg_offset_p
&& legitimate_small_data_p (mode
, x
))
6511 if (reg_offset_p
&& legitimate_constant_pool_address_p (x
, reg_ok_strict
))
6513 /* If not REG_OK_STRICT (before reload) let pass any stack offset. */
6516 && GET_CODE (x
) == PLUS
6517 && GET_CODE (XEXP (x
, 0)) == REG
6518 && (XEXP (x
, 0) == virtual_stack_vars_rtx
6519 || XEXP (x
, 0) == arg_pointer_rtx
)
6520 && GET_CODE (XEXP (x
, 1)) == CONST_INT
)
6522 if (rs6000_legitimate_offset_address_p (mode
, x
, reg_ok_strict
))
6527 && ((TARGET_HARD_FLOAT
&& TARGET_FPRS
&& TARGET_DOUBLE_FLOAT
)
6529 || (mode
!= DFmode
&& mode
!= DDmode
)
6530 || (TARGET_E500_DOUBLE
&& mode
!= DDmode
))
6531 && (TARGET_POWERPC64
|| mode
!= DImode
)
6532 && !avoiding_indexed_address_p (mode
)
6533 && legitimate_indexed_address_p (x
, reg_ok_strict
))
6535 if (GET_CODE (x
) == PRE_MODIFY
6539 && ((TARGET_HARD_FLOAT
&& TARGET_FPRS
&& TARGET_DOUBLE_FLOAT
)
6541 || ((mode
!= DFmode
&& mode
!= DDmode
) || TARGET_E500_DOUBLE
))
6542 && (TARGET_POWERPC64
|| mode
!= DImode
)
6543 && !VECTOR_MEM_ALTIVEC_OR_VSX_P (mode
)
6544 && !SPE_VECTOR_MODE (mode
)
6545 /* Restrict addressing for DI because of our SUBREG hackery. */
6546 && !(TARGET_E500_DOUBLE
6547 && (mode
== DFmode
|| mode
== DDmode
|| mode
== DImode
))
6549 && legitimate_indirect_address_p (XEXP (x
, 0), reg_ok_strict
)
6550 && (rs6000_legitimate_offset_address_p (mode
, XEXP (x
, 1), reg_ok_strict
)
6551 || (!avoiding_indexed_address_p (mode
)
6552 && legitimate_indexed_address_p (XEXP (x
, 1), reg_ok_strict
)))
6553 && rtx_equal_p (XEXP (XEXP (x
, 1), 0), XEXP (x
, 0)))
6555 if (reg_offset_p
&& legitimate_lo_sum_address_p (mode
, x
, reg_ok_strict
))
6560 /* Debug version of rs6000_legitimate_address_p. */
6562 rs6000_debug_legitimate_address_p (enum machine_mode mode
, rtx x
,
6565 bool ret
= rs6000_legitimate_address_p (mode
, x
, reg_ok_strict
);
6567 "\nrs6000_legitimate_address_p: return = %s, mode = %s, "
6568 "strict = %d, code = %s\n",
6569 ret
? "true" : "false",
6570 GET_MODE_NAME (mode
),
6572 GET_RTX_NAME (GET_CODE (x
)));
6578 /* Implement TARGET_MODE_DEPENDENT_ADDRESS_P. */
6581 rs6000_mode_dependent_address_p (const_rtx addr
)
6583 return rs6000_mode_dependent_address_ptr (addr
);
6586 /* Go to LABEL if ADDR (a legitimate address expression)
6587 has an effect that depends on the machine mode it is used for.
6589 On the RS/6000 this is true of all integral offsets (since AltiVec
6590 and VSX modes don't allow them) or is a pre-increment or decrement.
6592 ??? Except that due to conceptual problems in offsettable_address_p
6593 we can't really report the problems of integral offsets. So leave
6594 this assuming that the adjustable offset must be valid for the
6595 sub-words of a TFmode operand, which is what we had before. */
6598 rs6000_mode_dependent_address (const_rtx addr
)
6600 switch (GET_CODE (addr
))
6603 /* Any offset from virtual_stack_vars_rtx and arg_pointer_rtx
6604 is considered a legitimate address before reload, so there
6605 are no offset restrictions in that case. Note that this
6606 condition is safe in strict mode because any address involving
6607 virtual_stack_vars_rtx or arg_pointer_rtx would already have
6608 been rejected as illegitimate. */
6609 if (XEXP (addr
, 0) != virtual_stack_vars_rtx
6610 && XEXP (addr
, 0) != arg_pointer_rtx
6611 && GET_CODE (XEXP (addr
, 1)) == CONST_INT
)
6613 unsigned HOST_WIDE_INT val
= INTVAL (XEXP (addr
, 1));
6614 return val
+ 12 + 0x8000 >= 0x10000;
6619 /* Anything in the constant pool is sufficiently aligned that
6620 all bytes have the same high part address. */
6621 return !legitimate_constant_pool_address_p (addr
, false);
6623 /* Auto-increment cases are now treated generically in recog.c. */
6625 return TARGET_UPDATE
;
6627 /* AND is only allowed in Altivec loads. */
6638 /* Debug version of rs6000_mode_dependent_address. */
6640 rs6000_debug_mode_dependent_address (const_rtx addr
)
6642 bool ret
= rs6000_mode_dependent_address (addr
);
6644 fprintf (stderr
, "\nrs6000_mode_dependent_address: ret = %s\n",
6645 ret
? "true" : "false");
6651 /* Implement FIND_BASE_TERM. */
6654 rs6000_find_base_term (rtx op
)
6658 split_const (op
, &base
, &offset
);
6659 if (GET_CODE (base
) == UNSPEC
)
6660 switch (XINT (base
, 1))
6663 case UNSPEC_MACHOPIC_OFFSET
:
6664 /* OP represents SYM [+ OFFSET] - ANCHOR. SYM is the base term
6665 for aliasing purposes. */
6666 return XVECEXP (base
, 0, 0);
6672 /* More elaborate version of recog's offsettable_memref_p predicate
6673 that works around the ??? note of rs6000_mode_dependent_address.
6674 In particular it accepts
6676 (mem:DI (plus:SI (reg/f:SI 31 31) (const_int 32760 [0x7ff8])))
6678 in 32-bit mode, that the recog predicate rejects. */
6681 rs6000_offsettable_memref_p (rtx op
)
6686 /* First mimic offsettable_memref_p. */
6687 if (offsettable_address_p (1, GET_MODE (op
), XEXP (op
, 0)))
6690 /* offsettable_address_p invokes rs6000_mode_dependent_address, but
6691 the latter predicate knows nothing about the mode of the memory
6692 reference and, therefore, assumes that it is the largest supported
6693 mode (TFmode). As a consequence, legitimate offsettable memory
6694 references are rejected. rs6000_legitimate_offset_address_p contains
6695 the correct logic for the PLUS case of rs6000_mode_dependent_address. */
6696 return rs6000_legitimate_offset_address_p (GET_MODE (op
), XEXP (op
, 0), 1);
6699 /* Change register usage conditional on target flags. */
6701 rs6000_conditional_register_usage (void)
6705 /* Set MQ register fixed (already call_used) if not POWER
6706 architecture (RIOS1, RIOS2, RSC, and PPC601) so that it will not
6711 /* 64-bit AIX and Linux reserve GPR13 for thread-private data. */
6713 fixed_regs
[13] = call_used_regs
[13]
6714 = call_really_used_regs
[13] = 1;
6716 /* Conditionally disable FPRs. */
6717 if (TARGET_SOFT_FLOAT
|| !TARGET_FPRS
)
6718 for (i
= 32; i
< 64; i
++)
6719 fixed_regs
[i
] = call_used_regs
[i
]
6720 = call_really_used_regs
[i
] = 1;
6722 /* The TOC register is not killed across calls in a way that is
6723 visible to the compiler. */
6724 if (DEFAULT_ABI
== ABI_AIX
)
6725 call_really_used_regs
[2] = 0;
6727 if (DEFAULT_ABI
== ABI_V4
6728 && PIC_OFFSET_TABLE_REGNUM
!= INVALID_REGNUM
6730 fixed_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
] = 1;
6732 if (DEFAULT_ABI
== ABI_V4
6733 && PIC_OFFSET_TABLE_REGNUM
!= INVALID_REGNUM
6735 fixed_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
]
6736 = call_used_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
]
6737 = call_really_used_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
] = 1;
6739 if (DEFAULT_ABI
== ABI_DARWIN
6740 && PIC_OFFSET_TABLE_REGNUM
!= INVALID_REGNUM
)
6741 fixed_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
]
6742 = call_used_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
]
6743 = call_really_used_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
] = 1;
6745 if (TARGET_TOC
&& TARGET_MINIMAL_TOC
)
6746 fixed_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
]
6747 = call_used_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
] = 1;
6751 global_regs
[SPEFSCR_REGNO
] = 1;
6752 /* We used to use r14 as FIXED_SCRATCH to address SPE 64-bit
6753 registers in prologues and epilogues. We no longer use r14
6754 for FIXED_SCRATCH, but we're keeping r14 out of the allocation
6755 pool for link-compatibility with older versions of GCC. Once
6756 "old" code has died out, we can return r14 to the allocation
6759 = call_used_regs
[14]
6760 = call_really_used_regs
[14] = 1;
6763 if (!TARGET_ALTIVEC
&& !TARGET_VSX
)
6765 for (i
= FIRST_ALTIVEC_REGNO
; i
<= LAST_ALTIVEC_REGNO
; ++i
)
6766 fixed_regs
[i
] = call_used_regs
[i
] = call_really_used_regs
[i
] = 1;
6767 call_really_used_regs
[VRSAVE_REGNO
] = 1;
6770 if (TARGET_ALTIVEC
|| TARGET_VSX
)
6771 global_regs
[VSCR_REGNO
] = 1;
6773 if (TARGET_ALTIVEC_ABI
)
6775 for (i
= FIRST_ALTIVEC_REGNO
; i
< FIRST_ALTIVEC_REGNO
+ 20; ++i
)
6776 call_used_regs
[i
] = call_really_used_regs
[i
] = 1;
6778 /* AIX reserves VR20:31 in non-extended ABI mode. */
6780 for (i
= FIRST_ALTIVEC_REGNO
+ 20; i
< FIRST_ALTIVEC_REGNO
+ 32; ++i
)
6781 fixed_regs
[i
] = call_used_regs
[i
] = call_really_used_regs
[i
] = 1;
6785 /* Try to output insns to set TARGET equal to the constant C if it can
6786 be done in less than N insns. Do all computations in MODE.
6787 Returns the place where the output has been placed if it can be
6788 done and the insns have been emitted. If it would take more than N
6789 insns, zero is returned and no insns and emitted. */
6792 rs6000_emit_set_const (rtx dest
, enum machine_mode mode
,
6793 rtx source
, int n ATTRIBUTE_UNUSED
)
6795 rtx result
, insn
, set
;
6796 HOST_WIDE_INT c0
, c1
;
6803 dest
= gen_reg_rtx (mode
);
6804 emit_insn (gen_rtx_SET (VOIDmode
, dest
, source
));
6808 result
= !can_create_pseudo_p () ? dest
: gen_reg_rtx (SImode
);
6810 emit_insn (gen_rtx_SET (VOIDmode
, copy_rtx (result
),
6811 GEN_INT (INTVAL (source
)
6812 & (~ (HOST_WIDE_INT
) 0xffff))));
6813 emit_insn (gen_rtx_SET (VOIDmode
, dest
,
6814 gen_rtx_IOR (SImode
, copy_rtx (result
),
6815 GEN_INT (INTVAL (source
) & 0xffff))));
6820 switch (GET_CODE (source
))
6823 c0
= INTVAL (source
);
6828 #if HOST_BITS_PER_WIDE_INT >= 64
6829 c0
= CONST_DOUBLE_LOW (source
);
6832 c0
= CONST_DOUBLE_LOW (source
);
6833 c1
= CONST_DOUBLE_HIGH (source
);
6841 result
= rs6000_emit_set_long_const (dest
, c0
, c1
);
6848 insn
= get_last_insn ();
6849 set
= single_set (insn
);
6850 if (! CONSTANT_P (SET_SRC (set
)))
6851 set_unique_reg_note (insn
, REG_EQUAL
, source
);
6856 /* Having failed to find a 3 insn sequence in rs6000_emit_set_const,
6857 fall back to a straight forward decomposition. We do this to avoid
6858 exponential run times encountered when looking for longer sequences
6859 with rs6000_emit_set_const. */
6861 rs6000_emit_set_long_const (rtx dest
, HOST_WIDE_INT c1
, HOST_WIDE_INT c2
)
6863 if (!TARGET_POWERPC64
)
6865 rtx operand1
, operand2
;
6867 operand1
= operand_subword_force (dest
, WORDS_BIG_ENDIAN
== 0,
6869 operand2
= operand_subword_force (copy_rtx (dest
), WORDS_BIG_ENDIAN
!= 0,
6871 emit_move_insn (operand1
, GEN_INT (c1
));
6872 emit_move_insn (operand2
, GEN_INT (c2
));
6876 HOST_WIDE_INT ud1
, ud2
, ud3
, ud4
;
6879 ud2
= (c1
& 0xffff0000) >> 16;
6880 #if HOST_BITS_PER_WIDE_INT >= 64
6884 ud4
= (c2
& 0xffff0000) >> 16;
6886 if ((ud4
== 0xffff && ud3
== 0xffff && ud2
== 0xffff && (ud1
& 0x8000))
6887 || (ud4
== 0 && ud3
== 0 && ud2
== 0 && ! (ud1
& 0x8000)))
6890 emit_move_insn (dest
, GEN_INT (((ud1
^ 0x8000) - 0x8000)));
6892 emit_move_insn (dest
, GEN_INT (ud1
));
6895 else if ((ud4
== 0xffff && ud3
== 0xffff && (ud2
& 0x8000))
6896 || (ud4
== 0 && ud3
== 0 && ! (ud2
& 0x8000)))
6899 emit_move_insn (dest
, GEN_INT (((ud2
<< 16) ^ 0x80000000)
6902 emit_move_insn (dest
, GEN_INT (ud2
<< 16));
6904 emit_move_insn (copy_rtx (dest
),
6905 gen_rtx_IOR (DImode
, copy_rtx (dest
),
6908 else if (ud3
== 0 && ud4
== 0)
6910 gcc_assert (ud2
& 0x8000);
6911 emit_move_insn (dest
, GEN_INT (((ud2
<< 16) ^ 0x80000000)
6914 emit_move_insn (copy_rtx (dest
),
6915 gen_rtx_IOR (DImode
, copy_rtx (dest
),
6917 emit_move_insn (copy_rtx (dest
),
6918 gen_rtx_ZERO_EXTEND (DImode
,
6919 gen_lowpart (SImode
,
6922 else if ((ud4
== 0xffff && (ud3
& 0x8000))
6923 || (ud4
== 0 && ! (ud3
& 0x8000)))
6926 emit_move_insn (dest
, GEN_INT (((ud3
<< 16) ^ 0x80000000)
6929 emit_move_insn (dest
, GEN_INT (ud3
<< 16));
6932 emit_move_insn (copy_rtx (dest
),
6933 gen_rtx_IOR (DImode
, copy_rtx (dest
),
6935 emit_move_insn (copy_rtx (dest
),
6936 gen_rtx_ASHIFT (DImode
, copy_rtx (dest
),
6939 emit_move_insn (copy_rtx (dest
),
6940 gen_rtx_IOR (DImode
, copy_rtx (dest
),
6946 emit_move_insn (dest
, GEN_INT (((ud4
<< 16) ^ 0x80000000)
6949 emit_move_insn (dest
, GEN_INT (ud4
<< 16));
6952 emit_move_insn (copy_rtx (dest
),
6953 gen_rtx_IOR (DImode
, copy_rtx (dest
),
6956 emit_move_insn (copy_rtx (dest
),
6957 gen_rtx_ASHIFT (DImode
, copy_rtx (dest
),
6960 emit_move_insn (copy_rtx (dest
),
6961 gen_rtx_IOR (DImode
, copy_rtx (dest
),
6962 GEN_INT (ud2
<< 16)));
6964 emit_move_insn (copy_rtx (dest
),
6965 gen_rtx_IOR (DImode
, copy_rtx (dest
), GEN_INT (ud1
)));
6971 /* Helper for the following. Get rid of [r+r] memory refs
6972 in cases where it won't work (TImode, TFmode, TDmode). */
6975 rs6000_eliminate_indexed_memrefs (rtx operands
[2])
6977 if (reload_in_progress
)
6980 if (GET_CODE (operands
[0]) == MEM
6981 && GET_CODE (XEXP (operands
[0], 0)) != REG
6982 && ! legitimate_constant_pool_address_p (XEXP (operands
[0], 0), false))
6984 = replace_equiv_address (operands
[0],
6985 copy_addr_to_reg (XEXP (operands
[0], 0)));
6987 if (GET_CODE (operands
[1]) == MEM
6988 && GET_CODE (XEXP (operands
[1], 0)) != REG
6989 && ! legitimate_constant_pool_address_p (XEXP (operands
[1], 0), false))
6991 = replace_equiv_address (operands
[1],
6992 copy_addr_to_reg (XEXP (operands
[1], 0)));
6995 /* Emit a move from SOURCE to DEST in mode MODE. */
6997 rs6000_emit_move (rtx dest
, rtx source
, enum machine_mode mode
)
7001 operands
[1] = source
;
7003 if (TARGET_DEBUG_ADDR
)
7006 "\nrs6000_emit_move: mode = %s, reload_in_progress = %d, "
7007 "reload_completed = %d, can_create_pseudos = %d.\ndest:\n",
7008 GET_MODE_NAME (mode
),
7011 can_create_pseudo_p ());
7013 fprintf (stderr
, "source:\n");
7017 /* Sanity checks. Check that we get CONST_DOUBLE only when we should. */
7018 if (GET_CODE (operands
[1]) == CONST_DOUBLE
7019 && ! FLOAT_MODE_P (mode
)
7020 && GET_MODE_BITSIZE (mode
) <= HOST_BITS_PER_WIDE_INT
)
7022 /* FIXME. This should never happen. */
7023 /* Since it seems that it does, do the safe thing and convert
7025 operands
[1] = gen_int_mode (CONST_DOUBLE_LOW (operands
[1]), mode
);
7027 gcc_assert (GET_CODE (operands
[1]) != CONST_DOUBLE
7028 || FLOAT_MODE_P (mode
)
7029 || ((CONST_DOUBLE_HIGH (operands
[1]) != 0
7030 || CONST_DOUBLE_LOW (operands
[1]) < 0)
7031 && (CONST_DOUBLE_HIGH (operands
[1]) != -1
7032 || CONST_DOUBLE_LOW (operands
[1]) >= 0)));
7034 /* Check if GCC is setting up a block move that will end up using FP
7035 registers as temporaries. We must make sure this is acceptable. */
7036 if (GET_CODE (operands
[0]) == MEM
7037 && GET_CODE (operands
[1]) == MEM
7039 && (SLOW_UNALIGNED_ACCESS (DImode
, MEM_ALIGN (operands
[0]))
7040 || SLOW_UNALIGNED_ACCESS (DImode
, MEM_ALIGN (operands
[1])))
7041 && ! (SLOW_UNALIGNED_ACCESS (SImode
, (MEM_ALIGN (operands
[0]) > 32
7042 ? 32 : MEM_ALIGN (operands
[0])))
7043 || SLOW_UNALIGNED_ACCESS (SImode
, (MEM_ALIGN (operands
[1]) > 32
7045 : MEM_ALIGN (operands
[1]))))
7046 && ! MEM_VOLATILE_P (operands
[0])
7047 && ! MEM_VOLATILE_P (operands
[1]))
7049 emit_move_insn (adjust_address (operands
[0], SImode
, 0),
7050 adjust_address (operands
[1], SImode
, 0));
7051 emit_move_insn (adjust_address (copy_rtx (operands
[0]), SImode
, 4),
7052 adjust_address (copy_rtx (operands
[1]), SImode
, 4));
7056 if (can_create_pseudo_p () && GET_CODE (operands
[0]) == MEM
7057 && !gpc_reg_operand (operands
[1], mode
))
7058 operands
[1] = force_reg (mode
, operands
[1]);
7060 if (mode
== SFmode
&& ! TARGET_POWERPC
7061 && TARGET_HARD_FLOAT
&& TARGET_FPRS
&& TARGET_DOUBLE_FLOAT
7062 && GET_CODE (operands
[0]) == MEM
)
7066 if (reload_in_progress
|| reload_completed
)
7067 regnum
= true_regnum (operands
[1]);
7068 else if (GET_CODE (operands
[1]) == REG
)
7069 regnum
= REGNO (operands
[1]);
7073 /* If operands[1] is a register, on POWER it may have
7074 double-precision data in it, so truncate it to single
7076 if (FP_REGNO_P (regnum
) || regnum
>= FIRST_PSEUDO_REGISTER
)
7079 newreg
= (!can_create_pseudo_p () ? copy_rtx (operands
[1])
7080 : gen_reg_rtx (mode
));
7081 emit_insn (gen_aux_truncdfsf2 (newreg
, operands
[1]));
7082 operands
[1] = newreg
;
7086 /* Recognize the case where operand[1] is a reference to thread-local
7087 data and load its address to a register. */
7088 if (rs6000_tls_referenced_p (operands
[1]))
7090 enum tls_model model
;
7091 rtx tmp
= operands
[1];
7094 if (GET_CODE (tmp
) == CONST
&& GET_CODE (XEXP (tmp
, 0)) == PLUS
)
7096 addend
= XEXP (XEXP (tmp
, 0), 1);
7097 tmp
= XEXP (XEXP (tmp
, 0), 0);
7100 gcc_assert (GET_CODE (tmp
) == SYMBOL_REF
);
7101 model
= SYMBOL_REF_TLS_MODEL (tmp
);
7102 gcc_assert (model
!= 0);
7104 tmp
= rs6000_legitimize_tls_address (tmp
, model
);
7107 tmp
= gen_rtx_PLUS (mode
, tmp
, addend
);
7108 tmp
= force_operand (tmp
, operands
[0]);
7113 /* Handle the case where reload calls us with an invalid address. */
7114 if (reload_in_progress
&& mode
== Pmode
7115 && (! general_operand (operands
[1], mode
)
7116 || ! nonimmediate_operand (operands
[0], mode
)))
7119 /* 128-bit constant floating-point values on Darwin should really be
7120 loaded as two parts. */
7121 if (!TARGET_IEEEQUAD
&& TARGET_LONG_DOUBLE_128
7122 && mode
== TFmode
&& GET_CODE (operands
[1]) == CONST_DOUBLE
)
7124 /* DImode is used, not DFmode, because simplify_gen_subreg doesn't
7125 know how to get a DFmode SUBREG of a TFmode. */
7126 enum machine_mode imode
= (TARGET_E500_DOUBLE
? DFmode
: DImode
);
7127 rs6000_emit_move (simplify_gen_subreg (imode
, operands
[0], mode
, 0),
7128 simplify_gen_subreg (imode
, operands
[1], mode
, 0),
7130 rs6000_emit_move (simplify_gen_subreg (imode
, operands
[0], mode
,
7131 GET_MODE_SIZE (imode
)),
7132 simplify_gen_subreg (imode
, operands
[1], mode
,
7133 GET_MODE_SIZE (imode
)),
7138 if (reload_in_progress
&& cfun
->machine
->sdmode_stack_slot
!= NULL_RTX
)
7139 cfun
->machine
->sdmode_stack_slot
=
7140 eliminate_regs (cfun
->machine
->sdmode_stack_slot
, VOIDmode
, NULL_RTX
);
7142 if (reload_in_progress
7144 && MEM_P (operands
[0])
7145 && rtx_equal_p (operands
[0], cfun
->machine
->sdmode_stack_slot
)
7146 && REG_P (operands
[1]))
7148 if (FP_REGNO_P (REGNO (operands
[1])))
7150 rtx mem
= adjust_address_nv (operands
[0], DDmode
, 0);
7151 mem
= eliminate_regs (mem
, VOIDmode
, NULL_RTX
);
7152 emit_insn (gen_movsd_store (mem
, operands
[1]));
7154 else if (INT_REGNO_P (REGNO (operands
[1])))
7156 rtx mem
= adjust_address_nv (operands
[0], mode
, 4);
7157 mem
= eliminate_regs (mem
, VOIDmode
, NULL_RTX
);
7158 emit_insn (gen_movsd_hardfloat (mem
, operands
[1]));
7164 if (reload_in_progress
7166 && REG_P (operands
[0])
7167 && MEM_P (operands
[1])
7168 && rtx_equal_p (operands
[1], cfun
->machine
->sdmode_stack_slot
))
7170 if (FP_REGNO_P (REGNO (operands
[0])))
7172 rtx mem
= adjust_address_nv (operands
[1], DDmode
, 0);
7173 mem
= eliminate_regs (mem
, VOIDmode
, NULL_RTX
);
7174 emit_insn (gen_movsd_load (operands
[0], mem
));
7176 else if (INT_REGNO_P (REGNO (operands
[0])))
7178 rtx mem
= adjust_address_nv (operands
[1], mode
, 4);
7179 mem
= eliminate_regs (mem
, VOIDmode
, NULL_RTX
);
7180 emit_insn (gen_movsd_hardfloat (operands
[0], mem
));
7187 /* FIXME: In the long term, this switch statement should go away
7188 and be replaced by a sequence of tests based on things like
7194 if (CONSTANT_P (operands
[1])
7195 && GET_CODE (operands
[1]) != CONST_INT
)
7196 operands
[1] = force_const_mem (mode
, operands
[1]);
7201 rs6000_eliminate_indexed_memrefs (operands
);
7208 if (CONSTANT_P (operands
[1])
7209 && ! easy_fp_constant (operands
[1], mode
))
7210 operands
[1] = force_const_mem (mode
, operands
[1]);
7223 if (CONSTANT_P (operands
[1])
7224 && !easy_vector_constant (operands
[1], mode
))
7225 operands
[1] = force_const_mem (mode
, operands
[1]);
7230 /* Use default pattern for address of ELF small data */
7233 && DEFAULT_ABI
== ABI_V4
7234 && (GET_CODE (operands
[1]) == SYMBOL_REF
7235 || GET_CODE (operands
[1]) == CONST
)
7236 && small_data_operand (operands
[1], mode
))
7238 emit_insn (gen_rtx_SET (VOIDmode
, operands
[0], operands
[1]));
7242 if (DEFAULT_ABI
== ABI_V4
7243 && mode
== Pmode
&& mode
== SImode
7244 && flag_pic
== 1 && got_operand (operands
[1], mode
))
7246 emit_insn (gen_movsi_got (operands
[0], operands
[1]));
7250 if ((TARGET_ELF
|| DEFAULT_ABI
== ABI_DARWIN
)
7254 && CONSTANT_P (operands
[1])
7255 && GET_CODE (operands
[1]) != HIGH
7256 && GET_CODE (operands
[1]) != CONST_INT
)
7258 rtx target
= (!can_create_pseudo_p ()
7260 : gen_reg_rtx (mode
));
7262 /* If this is a function address on -mcall-aixdesc,
7263 convert it to the address of the descriptor. */
7264 if (DEFAULT_ABI
== ABI_AIX
7265 && GET_CODE (operands
[1]) == SYMBOL_REF
7266 && XSTR (operands
[1], 0)[0] == '.')
7268 const char *name
= XSTR (operands
[1], 0);
7270 while (*name
== '.')
7272 new_ref
= gen_rtx_SYMBOL_REF (Pmode
, name
);
7273 CONSTANT_POOL_ADDRESS_P (new_ref
)
7274 = CONSTANT_POOL_ADDRESS_P (operands
[1]);
7275 SYMBOL_REF_FLAGS (new_ref
) = SYMBOL_REF_FLAGS (operands
[1]);
7276 SYMBOL_REF_USED (new_ref
) = SYMBOL_REF_USED (operands
[1]);
7277 SYMBOL_REF_DATA (new_ref
) = SYMBOL_REF_DATA (operands
[1]);
7278 operands
[1] = new_ref
;
7281 if (DEFAULT_ABI
== ABI_DARWIN
)
7284 if (MACHO_DYNAMIC_NO_PIC_P
)
7286 /* Take care of any required data indirection. */
7287 operands
[1] = rs6000_machopic_legitimize_pic_address (
7288 operands
[1], mode
, operands
[0]);
7289 if (operands
[0] != operands
[1])
7290 emit_insn (gen_rtx_SET (VOIDmode
,
7291 operands
[0], operands
[1]));
7295 emit_insn (gen_macho_high (target
, operands
[1]));
7296 emit_insn (gen_macho_low (operands
[0], target
, operands
[1]));
7300 emit_insn (gen_elf_high (target
, operands
[1]));
7301 emit_insn (gen_elf_low (operands
[0], target
, operands
[1]));
7305 /* If this is a SYMBOL_REF that refers to a constant pool entry,
7306 and we have put it in the TOC, we just need to make a TOC-relative
7309 && GET_CODE (operands
[1]) == SYMBOL_REF
7310 && constant_pool_expr_p (operands
[1])
7311 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (operands
[1]),
7312 get_pool_mode (operands
[1])))
7315 if (TARGET_CMODEL
!= CMODEL_SMALL
)
7317 if (can_create_pseudo_p ())
7318 reg
= gen_reg_rtx (Pmode
);
7322 operands
[1] = create_TOC_reference (operands
[1], reg
);
7324 else if (mode
== Pmode
7325 && CONSTANT_P (operands
[1])
7326 && ((GET_CODE (operands
[1]) != CONST_INT
7327 && ! easy_fp_constant (operands
[1], mode
))
7328 || (GET_CODE (operands
[1]) == CONST_INT
7329 && (num_insns_constant (operands
[1], mode
)
7330 > (TARGET_CMODEL
!= CMODEL_SMALL
? 3 : 2)))
7331 || (GET_CODE (operands
[0]) == REG
7332 && FP_REGNO_P (REGNO (operands
[0]))))
7333 && GET_CODE (operands
[1]) != HIGH
7334 && ! legitimate_constant_pool_address_p (operands
[1], false)
7335 && ! toc_relative_expr_p (operands
[1])
7336 && (TARGET_CMODEL
== CMODEL_SMALL
7337 || can_create_pseudo_p ()
7338 || (REG_P (operands
[0])
7339 && INT_REG_OK_FOR_BASE_P (operands
[0], true))))
7343 /* Darwin uses a special PIC legitimizer. */
7344 if (DEFAULT_ABI
== ABI_DARWIN
&& MACHOPIC_INDIRECT
)
7347 rs6000_machopic_legitimize_pic_address (operands
[1], mode
,
7349 if (operands
[0] != operands
[1])
7350 emit_insn (gen_rtx_SET (VOIDmode
, operands
[0], operands
[1]));
7355 /* If we are to limit the number of things we put in the TOC and
7356 this is a symbol plus a constant we can add in one insn,
7357 just put the symbol in the TOC and add the constant. Don't do
7358 this if reload is in progress. */
7359 if (GET_CODE (operands
[1]) == CONST
7360 && TARGET_NO_SUM_IN_TOC
&& ! reload_in_progress
7361 && GET_CODE (XEXP (operands
[1], 0)) == PLUS
7362 && add_operand (XEXP (XEXP (operands
[1], 0), 1), mode
)
7363 && (GET_CODE (XEXP (XEXP (operands
[1], 0), 0)) == LABEL_REF
7364 || GET_CODE (XEXP (XEXP (operands
[1], 0), 0)) == SYMBOL_REF
)
7365 && ! side_effects_p (operands
[0]))
7368 force_const_mem (mode
, XEXP (XEXP (operands
[1], 0), 0));
7369 rtx other
= XEXP (XEXP (operands
[1], 0), 1);
7371 sym
= force_reg (mode
, sym
);
7372 emit_insn (gen_add3_insn (operands
[0], sym
, other
));
7376 operands
[1] = force_const_mem (mode
, operands
[1]);
7379 && GET_CODE (XEXP (operands
[1], 0)) == SYMBOL_REF
7380 && constant_pool_expr_p (XEXP (operands
[1], 0))
7381 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (
7382 get_pool_constant (XEXP (operands
[1], 0)),
7383 get_pool_mode (XEXP (operands
[1], 0))))
7387 if (TARGET_CMODEL
!= CMODEL_SMALL
)
7389 if (can_create_pseudo_p ())
7390 reg
= gen_reg_rtx (Pmode
);
7394 tocref
= create_TOC_reference (XEXP (operands
[1], 0), reg
);
7395 operands
[1] = gen_const_mem (mode
, tocref
);
7396 set_mem_alias_set (operands
[1], get_TOC_alias_set ());
7402 rs6000_eliminate_indexed_memrefs (operands
);
7406 emit_insn (gen_rtx_PARALLEL (VOIDmode
,
7408 gen_rtx_SET (VOIDmode
,
7409 operands
[0], operands
[1]),
7410 gen_rtx_CLOBBER (VOIDmode
,
7411 gen_rtx_SCRATCH (SImode
)))));
7417 fatal_insn ("bad move", gen_rtx_SET (VOIDmode
, dest
, source
));
7420 /* Above, we may have called force_const_mem which may have returned
7421 an invalid address. If we can, fix this up; otherwise, reload will
7422 have to deal with it. */
7423 if (GET_CODE (operands
[1]) == MEM
&& ! reload_in_progress
)
7424 operands
[1] = validize_mem (operands
[1]);
7427 emit_insn (gen_rtx_SET (VOIDmode
, operands
[0], operands
[1]));
7430 /* Nonzero if we can use a floating-point register to pass this arg. */
7431 #define USE_FP_FOR_ARG_P(CUM,MODE,TYPE) \
7432 (SCALAR_FLOAT_MODE_P (MODE) \
7433 && (CUM)->fregno <= FP_ARG_MAX_REG \
7434 && TARGET_HARD_FLOAT && TARGET_FPRS)
7436 /* Nonzero if we can use an AltiVec register to pass this arg. */
7437 #define USE_ALTIVEC_FOR_ARG_P(CUM,MODE,TYPE,NAMED) \
7438 ((ALTIVEC_VECTOR_MODE (MODE) || VSX_VECTOR_MODE (MODE)) \
7439 && (CUM)->vregno <= ALTIVEC_ARG_MAX_REG \
7440 && TARGET_ALTIVEC_ABI \
7443 /* Return a nonzero value to say to return the function value in
7444 memory, just as large structures are always returned. TYPE will be
7445 the data type of the value, and FNTYPE will be the type of the
7446 function doing the returning, or @code{NULL} for libcalls.
7448 The AIX ABI for the RS/6000 specifies that all structures are
7449 returned in memory. The Darwin ABI does the same.
7451 For the Darwin 64 Bit ABI, a function result can be returned in
7452 registers or in memory, depending on the size of the return data
7453 type. If it is returned in registers, the value occupies the same
7454 registers as it would if it were the first and only function
7455 argument. Otherwise, the function places its result in memory at
7456 the location pointed to by GPR3.
7458 The SVR4 ABI specifies that structures <= 8 bytes are returned in r3/r4,
7459 but a draft put them in memory, and GCC used to implement the draft
7460 instead of the final standard. Therefore, aix_struct_return
7461 controls this instead of DEFAULT_ABI; V.4 targets needing backward
7462 compatibility can change DRAFT_V4_STRUCT_RET to override the
7463 default, and -m switches get the final word. See
7464 rs6000_override_options for more details.
7466 The PPC32 SVR4 ABI uses IEEE double extended for long double, if 128-bit
7467 long double support is enabled. These values are returned in memory.
7469 int_size_in_bytes returns -1 for variable size objects, which go in
7470 memory always. The cast to unsigned makes -1 > 8. */
7473 rs6000_return_in_memory (const_tree type
, const_tree fntype ATTRIBUTE_UNUSED
)
7475 /* For the Darwin64 ABI, test if we can fit the return value in regs. */
7477 && rs6000_darwin64_abi
7478 && TREE_CODE (type
) == RECORD_TYPE
7479 && int_size_in_bytes (type
) > 0)
7481 CUMULATIVE_ARGS valcum
;
7485 valcum
.fregno
= FP_ARG_MIN_REG
;
7486 valcum
.vregno
= ALTIVEC_ARG_MIN_REG
;
7487 /* Do a trial code generation as if this were going to be passed
7488 as an argument; if any part goes in memory, we return NULL. */
7489 valret
= rs6000_darwin64_record_arg (&valcum
, type
, true, true);
7492 /* Otherwise fall through to more conventional ABI rules. */
7495 if (AGGREGATE_TYPE_P (type
)
7496 && (aix_struct_return
7497 || (unsigned HOST_WIDE_INT
) int_size_in_bytes (type
) > 8))
7500 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
7501 modes only exist for GCC vector types if -maltivec. */
7502 if (TARGET_32BIT
&& !TARGET_ALTIVEC_ABI
7503 && ALTIVEC_VECTOR_MODE (TYPE_MODE (type
)))
7506 /* Return synthetic vectors in memory. */
7507 if (TREE_CODE (type
) == VECTOR_TYPE
7508 && int_size_in_bytes (type
) > (TARGET_ALTIVEC_ABI
? 16 : 8))
7510 static bool warned_for_return_big_vectors
= false;
7511 if (!warned_for_return_big_vectors
)
7513 warning (0, "GCC vector returned by reference: "
7514 "non-standard ABI extension with no compatibility guarantee");
7515 warned_for_return_big_vectors
= true;
7520 if (DEFAULT_ABI
== ABI_V4
&& TARGET_IEEEQUAD
&& TYPE_MODE (type
) == TFmode
)
7526 /* Initialize a variable CUM of type CUMULATIVE_ARGS
7527 for a call to a function whose data type is FNTYPE.
7528 For a library call, FNTYPE is 0.
7530 For incoming args we set the number of arguments in the prototype large
7531 so we never return a PARALLEL. */
7534 init_cumulative_args (CUMULATIVE_ARGS
*cum
, tree fntype
,
7535 rtx libname ATTRIBUTE_UNUSED
, int incoming
,
7536 int libcall
, int n_named_args
)
7538 static CUMULATIVE_ARGS zero_cumulative
;
7540 *cum
= zero_cumulative
;
7542 cum
->fregno
= FP_ARG_MIN_REG
;
7543 cum
->vregno
= ALTIVEC_ARG_MIN_REG
;
7544 cum
->prototype
= (fntype
&& TYPE_ARG_TYPES (fntype
));
7545 cum
->call_cookie
= ((DEFAULT_ABI
== ABI_V4
&& libcall
)
7546 ? CALL_LIBCALL
: CALL_NORMAL
);
7547 cum
->sysv_gregno
= GP_ARG_MIN_REG
;
7548 cum
->stdarg
= stdarg_p (fntype
);
7550 cum
->nargs_prototype
= 0;
7551 if (incoming
|| cum
->prototype
)
7552 cum
->nargs_prototype
= n_named_args
;
7554 /* Check for a longcall attribute. */
7555 if ((!fntype
&& rs6000_default_long_calls
)
7557 && lookup_attribute ("longcall", TYPE_ATTRIBUTES (fntype
))
7558 && !lookup_attribute ("shortcall", TYPE_ATTRIBUTES (fntype
))))
7559 cum
->call_cookie
|= CALL_LONG
;
7561 if (TARGET_DEBUG_ARG
)
7563 fprintf (stderr
, "\ninit_cumulative_args:");
7566 tree ret_type
= TREE_TYPE (fntype
);
7567 fprintf (stderr
, " ret code = %s,",
7568 tree_code_name
[ (int)TREE_CODE (ret_type
) ]);
7571 if (cum
->call_cookie
& CALL_LONG
)
7572 fprintf (stderr
, " longcall,");
7574 fprintf (stderr
, " proto = %d, nargs = %d\n",
7575 cum
->prototype
, cum
->nargs_prototype
);
7580 && TARGET_ALTIVEC_ABI
7581 && ALTIVEC_VECTOR_MODE (TYPE_MODE (TREE_TYPE (fntype
))))
7583 error ("cannot return value in vector register because"
7584 " altivec instructions are disabled, use -maltivec"
7589 /* Return true if TYPE must be passed on the stack and not in registers. */
7592 rs6000_must_pass_in_stack (enum machine_mode mode
, const_tree type
)
7594 if (DEFAULT_ABI
== ABI_AIX
|| TARGET_64BIT
)
7595 return must_pass_in_stack_var_size (mode
, type
);
7597 return must_pass_in_stack_var_size_or_pad (mode
, type
);
7600 /* If defined, a C expression which determines whether, and in which
7601 direction, to pad out an argument with extra space. The value
7602 should be of type `enum direction': either `upward' to pad above
7603 the argument, `downward' to pad below, or `none' to inhibit
7606 For the AIX ABI structs are always stored left shifted in their
7610 function_arg_padding (enum machine_mode mode
, const_tree type
)
7612 #ifndef AGGREGATE_PADDING_FIXED
7613 #define AGGREGATE_PADDING_FIXED 0
7615 #ifndef AGGREGATES_PAD_UPWARD_ALWAYS
7616 #define AGGREGATES_PAD_UPWARD_ALWAYS 0
7619 if (!AGGREGATE_PADDING_FIXED
)
7621 /* GCC used to pass structures of the same size as integer types as
7622 if they were in fact integers, ignoring FUNCTION_ARG_PADDING.
7623 i.e. Structures of size 1 or 2 (or 4 when TARGET_64BIT) were
7624 passed padded downward, except that -mstrict-align further
7625 muddied the water in that multi-component structures of 2 and 4
7626 bytes in size were passed padded upward.
7628 The following arranges for best compatibility with previous
7629 versions of gcc, but removes the -mstrict-align dependency. */
7630 if (BYTES_BIG_ENDIAN
)
7632 HOST_WIDE_INT size
= 0;
7634 if (mode
== BLKmode
)
7636 if (type
&& TREE_CODE (TYPE_SIZE (type
)) == INTEGER_CST
)
7637 size
= int_size_in_bytes (type
);
7640 size
= GET_MODE_SIZE (mode
);
7642 if (size
== 1 || size
== 2 || size
== 4)
7648 if (AGGREGATES_PAD_UPWARD_ALWAYS
)
7650 if (type
!= 0 && AGGREGATE_TYPE_P (type
))
7654 /* Fall back to the default. */
7655 return DEFAULT_FUNCTION_ARG_PADDING (mode
, type
);
7658 /* If defined, a C expression that gives the alignment boundary, in bits,
7659 of an argument with the specified mode and type. If it is not defined,
7660 PARM_BOUNDARY is used for all arguments.
7662 V.4 wants long longs and doubles to be double word aligned. Just
7663 testing the mode size is a boneheaded way to do this as it means
7664 that other types such as complex int are also double word aligned.
7665 However, we're stuck with this because changing the ABI might break
7666 existing library interfaces.
7668 Doubleword align SPE vectors.
7669 Quadword align Altivec vectors.
7670 Quadword align large synthetic vector types. */
7673 function_arg_boundary (enum machine_mode mode
, const_tree type
)
7675 if (DEFAULT_ABI
== ABI_V4
7676 && (GET_MODE_SIZE (mode
) == 8
7677 || (TARGET_HARD_FLOAT
7679 && (mode
== TFmode
|| mode
== TDmode
))))
7681 else if (SPE_VECTOR_MODE (mode
)
7682 || (type
&& TREE_CODE (type
) == VECTOR_TYPE
7683 && int_size_in_bytes (type
) >= 8
7684 && int_size_in_bytes (type
) < 16))
7686 else if ((ALTIVEC_VECTOR_MODE (mode
) || VSX_VECTOR_MODE (mode
))
7687 || (type
&& TREE_CODE (type
) == VECTOR_TYPE
7688 && int_size_in_bytes (type
) >= 16))
7690 else if (TARGET_MACHO
7691 && rs6000_darwin64_abi
7693 && type
&& TYPE_ALIGN (type
) > 64)
7696 return PARM_BOUNDARY
;
7699 /* For a function parm of MODE and TYPE, return the starting word in
7700 the parameter area. NWORDS of the parameter area are already used. */
7703 rs6000_parm_start (enum machine_mode mode
, const_tree type
,
7704 unsigned int nwords
)
7707 unsigned int parm_offset
;
7709 align
= function_arg_boundary (mode
, type
) / PARM_BOUNDARY
- 1;
7710 parm_offset
= DEFAULT_ABI
== ABI_V4
? 2 : 6;
7711 return nwords
+ (-(parm_offset
+ nwords
) & align
);
7714 /* Compute the size (in words) of a function argument. */
7716 static unsigned long
7717 rs6000_arg_size (enum machine_mode mode
, const_tree type
)
7721 if (mode
!= BLKmode
)
7722 size
= GET_MODE_SIZE (mode
);
7724 size
= int_size_in_bytes (type
);
7727 return (size
+ 3) >> 2;
7729 return (size
+ 7) >> 3;
7732 /* Use this to flush pending int fields. */
7735 rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS
*cum
,
7736 HOST_WIDE_INT bitpos
, int final
)
7738 unsigned int startbit
, endbit
;
7739 int intregs
, intoffset
;
7740 enum machine_mode mode
;
7742 /* Handle the situations where a float is taking up the first half
7743 of the GPR, and the other half is empty (typically due to
7744 alignment restrictions). We can detect this by a 8-byte-aligned
7745 int field, or by seeing that this is the final flush for this
7746 argument. Count the word and continue on. */
7747 if (cum
->floats_in_gpr
== 1
7748 && (cum
->intoffset
% 64 == 0
7749 || (cum
->intoffset
== -1 && final
)))
7752 cum
->floats_in_gpr
= 0;
7755 if (cum
->intoffset
== -1)
7758 intoffset
= cum
->intoffset
;
7759 cum
->intoffset
= -1;
7760 cum
->floats_in_gpr
= 0;
7762 if (intoffset
% BITS_PER_WORD
!= 0)
7764 mode
= mode_for_size (BITS_PER_WORD
- intoffset
% BITS_PER_WORD
,
7766 if (mode
== BLKmode
)
7768 /* We couldn't find an appropriate mode, which happens,
7769 e.g., in packed structs when there are 3 bytes to load.
7770 Back intoffset back to the beginning of the word in this
7772 intoffset
= intoffset
& -BITS_PER_WORD
;
7776 startbit
= intoffset
& -BITS_PER_WORD
;
7777 endbit
= (bitpos
+ BITS_PER_WORD
- 1) & -BITS_PER_WORD
;
7778 intregs
= (endbit
- startbit
) / BITS_PER_WORD
;
7779 cum
->words
+= intregs
;
7780 /* words should be unsigned. */
7781 if ((unsigned)cum
->words
< (endbit
/BITS_PER_WORD
))
7783 int pad
= (endbit
/BITS_PER_WORD
) - cum
->words
;
7788 /* The darwin64 ABI calls for us to recurse down through structs,
7789 looking for elements passed in registers. Unfortunately, we have
7790 to track int register count here also because of misalignments
7791 in powerpc alignment mode. */
7794 rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS
*cum
,
7796 HOST_WIDE_INT startbitpos
)
7800 for (f
= TYPE_FIELDS (type
); f
; f
= DECL_CHAIN (f
))
7801 if (TREE_CODE (f
) == FIELD_DECL
)
7803 HOST_WIDE_INT bitpos
= startbitpos
;
7804 tree ftype
= TREE_TYPE (f
);
7805 enum machine_mode mode
;
7806 if (ftype
== error_mark_node
)
7808 mode
= TYPE_MODE (ftype
);
7810 if (DECL_SIZE (f
) != 0
7811 && host_integerp (bit_position (f
), 1))
7812 bitpos
+= int_bit_position (f
);
7814 /* ??? FIXME: else assume zero offset. */
7816 if (TREE_CODE (ftype
) == RECORD_TYPE
)
7817 rs6000_darwin64_record_arg_advance_recurse (cum
, ftype
, bitpos
);
7818 else if (USE_FP_FOR_ARG_P (cum
, mode
, ftype
))
7820 rs6000_darwin64_record_arg_advance_flush (cum
, bitpos
, 0);
7821 cum
->fregno
+= (GET_MODE_SIZE (mode
) + 7) >> 3;
7822 /* Single-precision floats present a special problem for
7823 us, because they are smaller than an 8-byte GPR, and so
7824 the structure-packing rules combined with the standard
7825 varargs behavior mean that we want to pack float/float
7826 and float/int combinations into a single register's
7827 space. This is complicated by the arg advance flushing,
7828 which works on arbitrarily large groups of int-type
7832 if (cum
->floats_in_gpr
== 1)
7834 /* Two floats in a word; count the word and reset
7837 cum
->floats_in_gpr
= 0;
7839 else if (bitpos
% 64 == 0)
7841 /* A float at the beginning of an 8-byte word;
7842 count it and put off adjusting cum->words until
7843 we see if a arg advance flush is going to do it
7845 cum
->floats_in_gpr
++;
7849 /* The float is at the end of a word, preceded
7850 by integer fields, so the arg advance flush
7851 just above has already set cum->words and
7852 everything is taken care of. */
7856 cum
->words
+= (GET_MODE_SIZE (mode
) + 7) >> 3;
7858 else if (USE_ALTIVEC_FOR_ARG_P (cum
, mode
, type
, 1))
7860 rs6000_darwin64_record_arg_advance_flush (cum
, bitpos
, 0);
7864 else if (cum
->intoffset
== -1)
7865 cum
->intoffset
= bitpos
;
7869 /* Check for an item that needs to be considered specially under the darwin 64
7870 bit ABI. These are record types where the mode is BLK or the structure is
7873 rs6000_darwin64_struct_check_p (enum machine_mode mode
, const_tree type
)
7875 return rs6000_darwin64_abi
7876 && ((mode
== BLKmode
7877 && TREE_CODE (type
) == RECORD_TYPE
7878 && int_size_in_bytes (type
) > 0)
7879 || (type
&& TREE_CODE (type
) == RECORD_TYPE
7880 && int_size_in_bytes (type
) == 8)) ? 1 : 0;
7883 /* Update the data in CUM to advance over an argument
7884 of mode MODE and data type TYPE.
7885 (TYPE is null for libcalls where that information may not be available.)
7887 Note that for args passed by reference, function_arg will be called
7888 with MODE and TYPE set to that of the pointer to the arg, not the arg
7892 rs6000_function_arg_advance_1 (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
,
7893 const_tree type
, bool named
, int depth
)
7896 /* Only tick off an argument if we're not recursing. */
7898 cum
->nargs_prototype
--;
7900 if (TARGET_ALTIVEC_ABI
7901 && (ALTIVEC_VECTOR_MODE (mode
)
7902 || VSX_VECTOR_MODE (mode
)
7903 || (type
&& TREE_CODE (type
) == VECTOR_TYPE
7904 && int_size_in_bytes (type
) == 16)))
7908 if (USE_ALTIVEC_FOR_ARG_P (cum
, mode
, type
, named
))
7911 if (!TARGET_ALTIVEC
)
7912 error ("cannot pass argument in vector register because"
7913 " altivec instructions are disabled, use -maltivec"
7916 /* PowerPC64 Linux and AIX allocate GPRs for a vector argument
7917 even if it is going to be passed in a vector register.
7918 Darwin does the same for variable-argument functions. */
7919 if ((DEFAULT_ABI
== ABI_AIX
&& TARGET_64BIT
)
7920 || (cum
->stdarg
&& DEFAULT_ABI
!= ABI_V4
))
7930 /* Vector parameters must be 16-byte aligned. This places
7931 them at 2 mod 4 in terms of words in 32-bit mode, since
7932 the parameter save area starts at offset 24 from the
7933 stack. In 64-bit mode, they just have to start on an
7934 even word, since the parameter save area is 16-byte
7935 aligned. Space for GPRs is reserved even if the argument
7936 will be passed in memory. */
7938 align
= (2 - cum
->words
) & 3;
7940 align
= cum
->words
& 1;
7941 cum
->words
+= align
+ rs6000_arg_size (mode
, type
);
7943 if (TARGET_DEBUG_ARG
)
7945 fprintf (stderr
, "function_adv: words = %2d, align=%d, ",
7947 fprintf (stderr
, "nargs = %4d, proto = %d, mode = %4s\n",
7948 cum
->nargs_prototype
, cum
->prototype
,
7949 GET_MODE_NAME (mode
));
7953 else if (TARGET_SPE_ABI
&& TARGET_SPE
&& SPE_VECTOR_MODE (mode
)
7955 && cum
->sysv_gregno
<= GP_ARG_MAX_REG
)
7958 else if (TARGET_MACHO
&& rs6000_darwin64_struct_check_p (mode
, type
))
7960 int size
= int_size_in_bytes (type
);
7961 /* Variable sized types have size == -1 and are
7962 treated as if consisting entirely of ints.
7963 Pad to 16 byte boundary if needed. */
7964 if (TYPE_ALIGN (type
) >= 2 * BITS_PER_WORD
7965 && (cum
->words
% 2) != 0)
7967 /* For varargs, we can just go up by the size of the struct. */
7969 cum
->words
+= (size
+ 7) / 8;
7972 /* It is tempting to say int register count just goes up by
7973 sizeof(type)/8, but this is wrong in a case such as
7974 { int; double; int; } [powerpc alignment]. We have to
7975 grovel through the fields for these too. */
7977 cum
->floats_in_gpr
= 0;
7978 rs6000_darwin64_record_arg_advance_recurse (cum
, type
, 0);
7979 rs6000_darwin64_record_arg_advance_flush (cum
,
7980 size
* BITS_PER_UNIT
, 1);
7982 if (TARGET_DEBUG_ARG
)
7984 fprintf (stderr
, "function_adv: words = %2d, align=%d, size=%d",
7985 cum
->words
, TYPE_ALIGN (type
), size
);
7987 "nargs = %4d, proto = %d, mode = %4s (darwin64 abi)\n",
7988 cum
->nargs_prototype
, cum
->prototype
,
7989 GET_MODE_NAME (mode
));
7992 else if (DEFAULT_ABI
== ABI_V4
)
7994 if (TARGET_HARD_FLOAT
&& TARGET_FPRS
7995 && ((TARGET_SINGLE_FLOAT
&& mode
== SFmode
)
7996 || (TARGET_DOUBLE_FLOAT
&& mode
== DFmode
)
7997 || (mode
== TFmode
&& !TARGET_IEEEQUAD
)
7998 || mode
== SDmode
|| mode
== DDmode
|| mode
== TDmode
))
8000 /* _Decimal128 must use an even/odd register pair. This assumes
8001 that the register number is odd when fregno is odd. */
8002 if (mode
== TDmode
&& (cum
->fregno
% 2) == 1)
8005 if (cum
->fregno
+ (mode
== TFmode
|| mode
== TDmode
? 1 : 0)
8006 <= FP_ARG_V4_MAX_REG
)
8007 cum
->fregno
+= (GET_MODE_SIZE (mode
) + 7) >> 3;
8010 cum
->fregno
= FP_ARG_V4_MAX_REG
+ 1;
8011 if (mode
== DFmode
|| mode
== TFmode
8012 || mode
== DDmode
|| mode
== TDmode
)
8013 cum
->words
+= cum
->words
& 1;
8014 cum
->words
+= rs6000_arg_size (mode
, type
);
8019 int n_words
= rs6000_arg_size (mode
, type
);
8020 int gregno
= cum
->sysv_gregno
;
8022 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
8023 (r7,r8) or (r9,r10). As does any other 2 word item such
8024 as complex int due to a historical mistake. */
8026 gregno
+= (1 - gregno
) & 1;
8028 /* Multi-reg args are not split between registers and stack. */
8029 if (gregno
+ n_words
- 1 > GP_ARG_MAX_REG
)
8031 /* Long long and SPE vectors are aligned on the stack.
8032 So are other 2 word items such as complex int due to
8033 a historical mistake. */
8035 cum
->words
+= cum
->words
& 1;
8036 cum
->words
+= n_words
;
8039 /* Note: continuing to accumulate gregno past when we've started
8040 spilling to the stack indicates the fact that we've started
8041 spilling to the stack to expand_builtin_saveregs. */
8042 cum
->sysv_gregno
= gregno
+ n_words
;
8045 if (TARGET_DEBUG_ARG
)
8047 fprintf (stderr
, "function_adv: words = %2d, fregno = %2d, ",
8048 cum
->words
, cum
->fregno
);
8049 fprintf (stderr
, "gregno = %2d, nargs = %4d, proto = %d, ",
8050 cum
->sysv_gregno
, cum
->nargs_prototype
, cum
->prototype
);
8051 fprintf (stderr
, "mode = %4s, named = %d\n",
8052 GET_MODE_NAME (mode
), named
);
8057 int n_words
= rs6000_arg_size (mode
, type
);
8058 int start_words
= cum
->words
;
8059 int align_words
= rs6000_parm_start (mode
, type
, start_words
);
8061 cum
->words
= align_words
+ n_words
;
8063 if (SCALAR_FLOAT_MODE_P (mode
)
8064 && TARGET_HARD_FLOAT
&& TARGET_FPRS
)
8066 /* _Decimal128 must be passed in an even/odd float register pair.
8067 This assumes that the register number is odd when fregno is
8069 if (mode
== TDmode
&& (cum
->fregno
% 2) == 1)
8071 cum
->fregno
+= (GET_MODE_SIZE (mode
) + 7) >> 3;
8074 if (TARGET_DEBUG_ARG
)
8076 fprintf (stderr
, "function_adv: words = %2d, fregno = %2d, ",
8077 cum
->words
, cum
->fregno
);
8078 fprintf (stderr
, "nargs = %4d, proto = %d, mode = %4s, ",
8079 cum
->nargs_prototype
, cum
->prototype
, GET_MODE_NAME (mode
));
8080 fprintf (stderr
, "named = %d, align = %d, depth = %d\n",
8081 named
, align_words
- start_words
, depth
);
8087 rs6000_function_arg_advance (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
,
8088 const_tree type
, bool named
)
8090 rs6000_function_arg_advance_1 (cum
, mode
, type
, named
, 0);
8094 spe_build_register_parallel (enum machine_mode mode
, int gregno
)
8101 r1
= gen_rtx_REG (DImode
, gregno
);
8102 r1
= gen_rtx_EXPR_LIST (VOIDmode
, r1
, const0_rtx
);
8103 return gen_rtx_PARALLEL (mode
, gen_rtvec (1, r1
));
8107 r1
= gen_rtx_REG (DImode
, gregno
);
8108 r1
= gen_rtx_EXPR_LIST (VOIDmode
, r1
, const0_rtx
);
8109 r3
= gen_rtx_REG (DImode
, gregno
+ 2);
8110 r3
= gen_rtx_EXPR_LIST (VOIDmode
, r3
, GEN_INT (8));
8111 return gen_rtx_PARALLEL (mode
, gen_rtvec (2, r1
, r3
));
8114 r1
= gen_rtx_REG (DImode
, gregno
);
8115 r1
= gen_rtx_EXPR_LIST (VOIDmode
, r1
, const0_rtx
);
8116 r3
= gen_rtx_REG (DImode
, gregno
+ 2);
8117 r3
= gen_rtx_EXPR_LIST (VOIDmode
, r3
, GEN_INT (8));
8118 r5
= gen_rtx_REG (DImode
, gregno
+ 4);
8119 r5
= gen_rtx_EXPR_LIST (VOIDmode
, r5
, GEN_INT (16));
8120 r7
= gen_rtx_REG (DImode
, gregno
+ 6);
8121 r7
= gen_rtx_EXPR_LIST (VOIDmode
, r7
, GEN_INT (24));
8122 return gen_rtx_PARALLEL (mode
, gen_rtvec (4, r1
, r3
, r5
, r7
));
8129 /* Determine where to put a SIMD argument on the SPE. */
8131 rs6000_spe_function_arg (const CUMULATIVE_ARGS
*cum
, enum machine_mode mode
,
8134 int gregno
= cum
->sysv_gregno
;
8136 /* On E500 v2, double arithmetic is done on the full 64-bit GPR, but
8137 are passed and returned in a pair of GPRs for ABI compatibility. */
8138 if (TARGET_E500_DOUBLE
&& (mode
== DFmode
|| mode
== TFmode
8139 || mode
== DCmode
|| mode
== TCmode
))
8141 int n_words
= rs6000_arg_size (mode
, type
);
8143 /* Doubles go in an odd/even register pair (r5/r6, etc). */
8145 gregno
+= (1 - gregno
) & 1;
8147 /* Multi-reg args are not split between registers and stack. */
8148 if (gregno
+ n_words
- 1 > GP_ARG_MAX_REG
)
8151 return spe_build_register_parallel (mode
, gregno
);
8155 int n_words
= rs6000_arg_size (mode
, type
);
8157 /* SPE vectors are put in odd registers. */
8158 if (n_words
== 2 && (gregno
& 1) == 0)
8161 if (gregno
+ n_words
- 1 <= GP_ARG_MAX_REG
)
8164 enum machine_mode m
= SImode
;
8166 r1
= gen_rtx_REG (m
, gregno
);
8167 r1
= gen_rtx_EXPR_LIST (m
, r1
, const0_rtx
);
8168 r2
= gen_rtx_REG (m
, gregno
+ 1);
8169 r2
= gen_rtx_EXPR_LIST (m
, r2
, GEN_INT (4));
8170 return gen_rtx_PARALLEL (mode
, gen_rtvec (2, r1
, r2
));
8177 if (gregno
<= GP_ARG_MAX_REG
)
8178 return gen_rtx_REG (mode
, gregno
);
8184 /* A subroutine of rs6000_darwin64_record_arg. Assign the bits of the
8185 structure between cum->intoffset and bitpos to integer registers. */
8188 rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS
*cum
,
8189 HOST_WIDE_INT bitpos
, rtx rvec
[], int *k
)
8191 enum machine_mode mode
;
8193 unsigned int startbit
, endbit
;
8194 int this_regno
, intregs
, intoffset
;
8197 if (cum
->intoffset
== -1)
8200 intoffset
= cum
->intoffset
;
8201 cum
->intoffset
= -1;
8203 /* If this is the trailing part of a word, try to only load that
8204 much into the register. Otherwise load the whole register. Note
8205 that in the latter case we may pick up unwanted bits. It's not a
8206 problem at the moment but may wish to revisit. */
8208 if (intoffset
% BITS_PER_WORD
!= 0)
8210 mode
= mode_for_size (BITS_PER_WORD
- intoffset
% BITS_PER_WORD
,
8212 if (mode
== BLKmode
)
8214 /* We couldn't find an appropriate mode, which happens,
8215 e.g., in packed structs when there are 3 bytes to load.
8216 Back intoffset back to the beginning of the word in this
8218 intoffset
= intoffset
& -BITS_PER_WORD
;
8225 startbit
= intoffset
& -BITS_PER_WORD
;
8226 endbit
= (bitpos
+ BITS_PER_WORD
- 1) & -BITS_PER_WORD
;
8227 intregs
= (endbit
- startbit
) / BITS_PER_WORD
;
8228 this_regno
= cum
->words
+ intoffset
/ BITS_PER_WORD
;
8230 if (intregs
> 0 && intregs
> GP_ARG_NUM_REG
- this_regno
)
8233 intregs
= MIN (intregs
, GP_ARG_NUM_REG
- this_regno
);
8237 intoffset
/= BITS_PER_UNIT
;
8240 regno
= GP_ARG_MIN_REG
+ this_regno
;
8241 reg
= gen_rtx_REG (mode
, regno
);
8243 gen_rtx_EXPR_LIST (VOIDmode
, reg
, GEN_INT (intoffset
));
8246 intoffset
= (intoffset
| (UNITS_PER_WORD
-1)) + 1;
8250 while (intregs
> 0);
8253 /* Recursive workhorse for the following. */
8256 rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS
*cum
, const_tree type
,
8257 HOST_WIDE_INT startbitpos
, rtx rvec
[],
8262 for (f
= TYPE_FIELDS (type
); f
; f
= DECL_CHAIN (f
))
8263 if (TREE_CODE (f
) == FIELD_DECL
)
8265 HOST_WIDE_INT bitpos
= startbitpos
;
8266 tree ftype
= TREE_TYPE (f
);
8267 enum machine_mode mode
;
8268 if (ftype
== error_mark_node
)
8270 mode
= TYPE_MODE (ftype
);
8272 if (DECL_SIZE (f
) != 0
8273 && host_integerp (bit_position (f
), 1))
8274 bitpos
+= int_bit_position (f
);
8276 /* ??? FIXME: else assume zero offset. */
8278 if (TREE_CODE (ftype
) == RECORD_TYPE
)
8279 rs6000_darwin64_record_arg_recurse (cum
, ftype
, bitpos
, rvec
, k
);
8280 else if (cum
->named
&& USE_FP_FOR_ARG_P (cum
, mode
, ftype
))
8285 case SCmode
: mode
= SFmode
; break;
8286 case DCmode
: mode
= DFmode
; break;
8287 case TCmode
: mode
= TFmode
; break;
8291 rs6000_darwin64_record_arg_flush (cum
, bitpos
, rvec
, k
);
8293 = gen_rtx_EXPR_LIST (VOIDmode
,
8294 gen_rtx_REG (mode
, cum
->fregno
++),
8295 GEN_INT (bitpos
/ BITS_PER_UNIT
));
8296 if (mode
== TFmode
|| mode
== TDmode
)
8299 else if (cum
->named
&& USE_ALTIVEC_FOR_ARG_P (cum
, mode
, ftype
, 1))
8301 rs6000_darwin64_record_arg_flush (cum
, bitpos
, rvec
, k
);
8303 = gen_rtx_EXPR_LIST (VOIDmode
,
8304 gen_rtx_REG (mode
, cum
->vregno
++),
8305 GEN_INT (bitpos
/ BITS_PER_UNIT
));
8307 else if (cum
->intoffset
== -1)
8308 cum
->intoffset
= bitpos
;
8312 /* For the darwin64 ABI, we want to construct a PARALLEL consisting of
8313 the register(s) to be used for each field and subfield of a struct
8314 being passed by value, along with the offset of where the
8315 register's value may be found in the block. FP fields go in FP
8316 register, vector fields go in vector registers, and everything
8317 else goes in int registers, packed as in memory.
8319 This code is also used for function return values. RETVAL indicates
8320 whether this is the case.
8322 Much of this is taken from the SPARC V9 port, which has a similar
8323 calling convention. */
8326 rs6000_darwin64_record_arg (CUMULATIVE_ARGS
*orig_cum
, const_tree type
,
8327 bool named
, bool retval
)
8329 rtx rvec
[FIRST_PSEUDO_REGISTER
];
8330 int k
= 1, kbase
= 1;
8331 HOST_WIDE_INT typesize
= int_size_in_bytes (type
);
8332 /* This is a copy; modifications are not visible to our caller. */
8333 CUMULATIVE_ARGS copy_cum
= *orig_cum
;
8334 CUMULATIVE_ARGS
*cum
= ©_cum
;
8336 /* Pad to 16 byte boundary if needed. */
8337 if (!retval
&& TYPE_ALIGN (type
) >= 2 * BITS_PER_WORD
8338 && (cum
->words
% 2) != 0)
8345 /* Put entries into rvec[] for individual FP and vector fields, and
8346 for the chunks of memory that go in int regs. Note we start at
8347 element 1; 0 is reserved for an indication of using memory, and
8348 may or may not be filled in below. */
8349 rs6000_darwin64_record_arg_recurse (cum
, type
, 0, rvec
, &k
);
8350 rs6000_darwin64_record_arg_flush (cum
, typesize
* BITS_PER_UNIT
, rvec
, &k
);
8352 /* If any part of the struct went on the stack put all of it there.
8353 This hack is because the generic code for
8354 FUNCTION_ARG_PARTIAL_NREGS cannot handle cases where the register
8355 parts of the struct are not at the beginning. */
8359 return NULL_RTX
; /* doesn't go in registers at all */
8361 rvec
[0] = gen_rtx_EXPR_LIST (VOIDmode
, NULL_RTX
, const0_rtx
);
8363 if (k
> 1 || cum
->use_stack
)
8364 return gen_rtx_PARALLEL (BLKmode
, gen_rtvec_v (k
- kbase
, &rvec
[kbase
]));
8369 /* Determine where to place an argument in 64-bit mode with 32-bit ABI. */
8372 rs6000_mixed_function_arg (enum machine_mode mode
, const_tree type
,
8377 rtx rvec
[GP_ARG_NUM_REG
+ 1];
8379 if (align_words
>= GP_ARG_NUM_REG
)
8382 n_units
= rs6000_arg_size (mode
, type
);
8384 /* Optimize the simple case where the arg fits in one gpr, except in
8385 the case of BLKmode due to assign_parms assuming that registers are
8386 BITS_PER_WORD wide. */
8388 || (n_units
== 1 && mode
!= BLKmode
))
8389 return gen_rtx_REG (mode
, GP_ARG_MIN_REG
+ align_words
);
8392 if (align_words
+ n_units
> GP_ARG_NUM_REG
)
8393 /* Not all of the arg fits in gprs. Say that it goes in memory too,
8394 using a magic NULL_RTX component.
8395 This is not strictly correct. Only some of the arg belongs in
8396 memory, not all of it. However, the normal scheme using
8397 function_arg_partial_nregs can result in unusual subregs, eg.
8398 (subreg:SI (reg:DF) 4), which are not handled well. The code to
8399 store the whole arg to memory is often more efficient than code
8400 to store pieces, and we know that space is available in the right
8401 place for the whole arg. */
8402 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, NULL_RTX
, const0_rtx
);
8407 rtx r
= gen_rtx_REG (SImode
, GP_ARG_MIN_REG
+ align_words
);
8408 rtx off
= GEN_INT (i
++ * 4);
8409 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, r
, off
);
8411 while (++align_words
< GP_ARG_NUM_REG
&& --n_units
!= 0);
8413 return gen_rtx_PARALLEL (mode
, gen_rtvec_v (k
, rvec
));
8416 /* Determine where to put an argument to a function.
8417 Value is zero to push the argument on the stack,
8418 or a hard register in which to store the argument.
8420 MODE is the argument's machine mode.
8421 TYPE is the data type of the argument (as a tree).
8422 This is null for libcalls where that information may
8424 CUM is a variable of type CUMULATIVE_ARGS which gives info about
8425 the preceding args and about the function being called. It is
8426 not modified in this routine.
8427 NAMED is nonzero if this argument is a named parameter
8428 (otherwise it is an extra parameter matching an ellipsis).
8430 On RS/6000 the first eight words of non-FP are normally in registers
8431 and the rest are pushed. Under AIX, the first 13 FP args are in registers.
8432 Under V.4, the first 8 FP args are in registers.
8434 If this is floating-point and no prototype is specified, we use
8435 both an FP and integer register (or possibly FP reg and stack). Library
8436 functions (when CALL_LIBCALL is set) always have the proper types for args,
8437 so we can pass the FP value just in one register. emit_library_function
8438 doesn't support PARALLEL anyway.
8440 Note that for args passed by reference, function_arg will be called
8441 with MODE and TYPE set to that of the pointer to the arg, not the arg
8445 rs6000_function_arg (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
,
8446 const_tree type
, bool named
)
8448 enum rs6000_abi abi
= DEFAULT_ABI
;
8450 /* Return a marker to indicate whether CR1 needs to set or clear the
8451 bit that V.4 uses to say fp args were passed in registers.
8452 Assume that we don't need the marker for software floating point,
8453 or compiler generated library calls. */
8454 if (mode
== VOIDmode
)
8457 && (cum
->call_cookie
& CALL_LIBCALL
) == 0
8459 || (cum
->nargs_prototype
< 0
8460 && (cum
->prototype
|| TARGET_NO_PROTOTYPE
))))
8462 /* For the SPE, we need to crxor CR6 always. */
8464 return GEN_INT (cum
->call_cookie
| CALL_V4_SET_FP_ARGS
);
8465 else if (TARGET_HARD_FLOAT
&& TARGET_FPRS
)
8466 return GEN_INT (cum
->call_cookie
8467 | ((cum
->fregno
== FP_ARG_MIN_REG
)
8468 ? CALL_V4_SET_FP_ARGS
8469 : CALL_V4_CLEAR_FP_ARGS
));
8472 return GEN_INT (cum
->call_cookie
);
8475 if (TARGET_MACHO
&& rs6000_darwin64_struct_check_p (mode
, type
))
8477 rtx rslt
= rs6000_darwin64_record_arg (cum
, type
, named
, false);
8478 if (rslt
!= NULL_RTX
)
8480 /* Else fall through to usual handling. */
8483 if (USE_ALTIVEC_FOR_ARG_P (cum
, mode
, type
, named
))
8484 if (TARGET_64BIT
&& ! cum
->prototype
)
8486 /* Vector parameters get passed in vector register
8487 and also in GPRs or memory, in absence of prototype. */
8490 align_words
= (cum
->words
+ 1) & ~1;
8492 if (align_words
>= GP_ARG_NUM_REG
)
8498 slot
= gen_rtx_REG (mode
, GP_ARG_MIN_REG
+ align_words
);
8500 return gen_rtx_PARALLEL (mode
,
8502 gen_rtx_EXPR_LIST (VOIDmode
,
8504 gen_rtx_EXPR_LIST (VOIDmode
,
8505 gen_rtx_REG (mode
, cum
->vregno
),
8509 return gen_rtx_REG (mode
, cum
->vregno
);
8510 else if (TARGET_ALTIVEC_ABI
8511 && (ALTIVEC_VECTOR_MODE (mode
)
8512 || VSX_VECTOR_MODE (mode
)
8513 || (type
&& TREE_CODE (type
) == VECTOR_TYPE
8514 && int_size_in_bytes (type
) == 16)))
8516 if (named
|| abi
== ABI_V4
)
8520 /* Vector parameters to varargs functions under AIX or Darwin
8521 get passed in memory and possibly also in GPRs. */
8522 int align
, align_words
, n_words
;
8523 enum machine_mode part_mode
;
8525 /* Vector parameters must be 16-byte aligned. This places them at
8526 2 mod 4 in terms of words in 32-bit mode, since the parameter
8527 save area starts at offset 24 from the stack. In 64-bit mode,
8528 they just have to start on an even word, since the parameter
8529 save area is 16-byte aligned. */
8531 align
= (2 - cum
->words
) & 3;
8533 align
= cum
->words
& 1;
8534 align_words
= cum
->words
+ align
;
8536 /* Out of registers? Memory, then. */
8537 if (align_words
>= GP_ARG_NUM_REG
)
8540 if (TARGET_32BIT
&& TARGET_POWERPC64
)
8541 return rs6000_mixed_function_arg (mode
, type
, align_words
);
8543 /* The vector value goes in GPRs. Only the part of the
8544 value in GPRs is reported here. */
8546 n_words
= rs6000_arg_size (mode
, type
);
8547 if (align_words
+ n_words
> GP_ARG_NUM_REG
)
8548 /* Fortunately, there are only two possibilities, the value
8549 is either wholly in GPRs or half in GPRs and half not. */
8552 return gen_rtx_REG (part_mode
, GP_ARG_MIN_REG
+ align_words
);
8555 else if (TARGET_SPE_ABI
&& TARGET_SPE
8556 && (SPE_VECTOR_MODE (mode
)
8557 || (TARGET_E500_DOUBLE
&& (mode
== DFmode
8560 || mode
== TCmode
))))
8561 return rs6000_spe_function_arg (cum
, mode
, type
);
8563 else if (abi
== ABI_V4
)
8565 if (TARGET_HARD_FLOAT
&& TARGET_FPRS
8566 && ((TARGET_SINGLE_FLOAT
&& mode
== SFmode
)
8567 || (TARGET_DOUBLE_FLOAT
&& mode
== DFmode
)
8568 || (mode
== TFmode
&& !TARGET_IEEEQUAD
)
8569 || mode
== SDmode
|| mode
== DDmode
|| mode
== TDmode
))
8571 /* _Decimal128 must use an even/odd register pair. This assumes
8572 that the register number is odd when fregno is odd. */
8573 if (mode
== TDmode
&& (cum
->fregno
% 2) == 1)
8576 if (cum
->fregno
+ (mode
== TFmode
|| mode
== TDmode
? 1 : 0)
8577 <= FP_ARG_V4_MAX_REG
)
8578 return gen_rtx_REG (mode
, cum
->fregno
);
8584 int n_words
= rs6000_arg_size (mode
, type
);
8585 int gregno
= cum
->sysv_gregno
;
8587 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
8588 (r7,r8) or (r9,r10). As does any other 2 word item such
8589 as complex int due to a historical mistake. */
8591 gregno
+= (1 - gregno
) & 1;
8593 /* Multi-reg args are not split between registers and stack. */
8594 if (gregno
+ n_words
- 1 > GP_ARG_MAX_REG
)
8597 if (TARGET_32BIT
&& TARGET_POWERPC64
)
8598 return rs6000_mixed_function_arg (mode
, type
,
8599 gregno
- GP_ARG_MIN_REG
);
8600 return gen_rtx_REG (mode
, gregno
);
8605 int align_words
= rs6000_parm_start (mode
, type
, cum
->words
);
8607 /* _Decimal128 must be passed in an even/odd float register pair.
8608 This assumes that the register number is odd when fregno is odd. */
8609 if (mode
== TDmode
&& (cum
->fregno
% 2) == 1)
8612 if (USE_FP_FOR_ARG_P (cum
, mode
, type
))
8614 rtx rvec
[GP_ARG_NUM_REG
+ 1];
8618 enum machine_mode fmode
= mode
;
8619 unsigned long n_fpreg
= (GET_MODE_SIZE (mode
) + 7) >> 3;
8621 if (cum
->fregno
+ n_fpreg
> FP_ARG_MAX_REG
+ 1)
8623 /* Currently, we only ever need one reg here because complex
8624 doubles are split. */
8625 gcc_assert (cum
->fregno
== FP_ARG_MAX_REG
8626 && (fmode
== TFmode
|| fmode
== TDmode
));
8628 /* Long double or _Decimal128 split over regs and memory. */
8629 fmode
= DECIMAL_FLOAT_MODE_P (fmode
) ? DDmode
: DFmode
;
8632 /* Do we also need to pass this arg in the parameter save
8635 && (cum
->nargs_prototype
<= 0
8636 || (DEFAULT_ABI
== ABI_AIX
8638 && align_words
>= GP_ARG_NUM_REG
)));
8640 if (!needs_psave
&& mode
== fmode
)
8641 return gen_rtx_REG (fmode
, cum
->fregno
);
8646 /* Describe the part that goes in gprs or the stack.
8647 This piece must come first, before the fprs. */
8648 if (align_words
< GP_ARG_NUM_REG
)
8650 unsigned long n_words
= rs6000_arg_size (mode
, type
);
8652 if (align_words
+ n_words
> GP_ARG_NUM_REG
8653 || (TARGET_32BIT
&& TARGET_POWERPC64
))
8655 /* If this is partially on the stack, then we only
8656 include the portion actually in registers here. */
8657 enum machine_mode rmode
= TARGET_32BIT
? SImode
: DImode
;
8660 if (align_words
+ n_words
> GP_ARG_NUM_REG
)
8661 /* Not all of the arg fits in gprs. Say that it
8662 goes in memory too, using a magic NULL_RTX
8663 component. Also see comment in
8664 rs6000_mixed_function_arg for why the normal
8665 function_arg_partial_nregs scheme doesn't work
8667 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, NULL_RTX
,
8671 r
= gen_rtx_REG (rmode
,
8672 GP_ARG_MIN_REG
+ align_words
);
8673 off
= GEN_INT (i
++ * GET_MODE_SIZE (rmode
));
8674 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, r
, off
);
8676 while (++align_words
< GP_ARG_NUM_REG
&& --n_words
!= 0);
8680 /* The whole arg fits in gprs. */
8681 r
= gen_rtx_REG (mode
, GP_ARG_MIN_REG
+ align_words
);
8682 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, r
, const0_rtx
);
8686 /* It's entirely in memory. */
8687 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, NULL_RTX
, const0_rtx
);
8690 /* Describe where this piece goes in the fprs. */
8691 r
= gen_rtx_REG (fmode
, cum
->fregno
);
8692 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, r
, const0_rtx
);
8694 return gen_rtx_PARALLEL (mode
, gen_rtvec_v (k
, rvec
));
8696 else if (align_words
< GP_ARG_NUM_REG
)
8698 if (TARGET_32BIT
&& TARGET_POWERPC64
)
8699 return rs6000_mixed_function_arg (mode
, type
, align_words
);
8701 if (mode
== BLKmode
)
8704 return gen_rtx_REG (mode
, GP_ARG_MIN_REG
+ align_words
);
8711 /* For an arg passed partly in registers and partly in memory, this is
8712 the number of bytes passed in registers. For args passed entirely in
8713 registers or entirely in memory, zero. When an arg is described by a
8714 PARALLEL, perhaps using more than one register type, this function
8715 returns the number of bytes used by the first element of the PARALLEL. */
8718 rs6000_arg_partial_bytes (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
,
8719 tree type
, bool named
)
8724 if (DEFAULT_ABI
== ABI_V4
)
8727 if (USE_ALTIVEC_FOR_ARG_P (cum
, mode
, type
, named
)
8728 && cum
->nargs_prototype
>= 0)
8731 /* In this complicated case we just disable the partial_nregs code. */
8732 if (TARGET_MACHO
&& rs6000_darwin64_struct_check_p (mode
, type
))
8735 align_words
= rs6000_parm_start (mode
, type
, cum
->words
);
8737 if (USE_FP_FOR_ARG_P (cum
, mode
, type
))
8739 /* If we are passing this arg in the fixed parameter save area
8740 (gprs or memory) as well as fprs, then this function should
8741 return the number of partial bytes passed in the parameter
8742 save area rather than partial bytes passed in fprs. */
8744 && (cum
->nargs_prototype
<= 0
8745 || (DEFAULT_ABI
== ABI_AIX
8747 && align_words
>= GP_ARG_NUM_REG
)))
8749 else if (cum
->fregno
+ ((GET_MODE_SIZE (mode
) + 7) >> 3)
8750 > FP_ARG_MAX_REG
+ 1)
8751 ret
= (FP_ARG_MAX_REG
+ 1 - cum
->fregno
) * 8;
8752 else if (cum
->nargs_prototype
>= 0)
8756 if (align_words
< GP_ARG_NUM_REG
8757 && GP_ARG_NUM_REG
< align_words
+ rs6000_arg_size (mode
, type
))
8758 ret
= (GP_ARG_NUM_REG
- align_words
) * (TARGET_32BIT
? 4 : 8);
8760 if (ret
!= 0 && TARGET_DEBUG_ARG
)
8761 fprintf (stderr
, "rs6000_arg_partial_bytes: %d\n", ret
);
8766 /* A C expression that indicates when an argument must be passed by
8767 reference. If nonzero for an argument, a copy of that argument is
8768 made in memory and a pointer to the argument is passed instead of
8769 the argument itself. The pointer is passed in whatever way is
8770 appropriate for passing a pointer to that type.
8772 Under V.4, aggregates and long double are passed by reference.
8774 As an extension to all 32-bit ABIs, AltiVec vectors are passed by
8775 reference unless the AltiVec vector extension ABI is in force.
8777 As an extension to all ABIs, variable sized types are passed by
8781 rs6000_pass_by_reference (CUMULATIVE_ARGS
*cum ATTRIBUTE_UNUSED
,
8782 enum machine_mode mode
, const_tree type
,
8783 bool named ATTRIBUTE_UNUSED
)
8785 if (DEFAULT_ABI
== ABI_V4
&& TARGET_IEEEQUAD
&& mode
== TFmode
)
8787 if (TARGET_DEBUG_ARG
)
8788 fprintf (stderr
, "function_arg_pass_by_reference: V4 long double\n");
8795 if (DEFAULT_ABI
== ABI_V4
&& AGGREGATE_TYPE_P (type
))
8797 if (TARGET_DEBUG_ARG
)
8798 fprintf (stderr
, "function_arg_pass_by_reference: V4 aggregate\n");
8802 if (int_size_in_bytes (type
) < 0)
8804 if (TARGET_DEBUG_ARG
)
8805 fprintf (stderr
, "function_arg_pass_by_reference: variable size\n");
8809 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
8810 modes only exist for GCC vector types if -maltivec. */
8811 if (TARGET_32BIT
&& !TARGET_ALTIVEC_ABI
&& ALTIVEC_VECTOR_MODE (mode
))
8813 if (TARGET_DEBUG_ARG
)
8814 fprintf (stderr
, "function_arg_pass_by_reference: AltiVec\n");
8818 /* Pass synthetic vectors in memory. */
8819 if (TREE_CODE (type
) == VECTOR_TYPE
8820 && int_size_in_bytes (type
) > (TARGET_ALTIVEC_ABI
? 16 : 8))
8822 static bool warned_for_pass_big_vectors
= false;
8823 if (TARGET_DEBUG_ARG
)
8824 fprintf (stderr
, "function_arg_pass_by_reference: synthetic vector\n");
8825 if (!warned_for_pass_big_vectors
)
8827 warning (0, "GCC vector passed by reference: "
8828 "non-standard ABI extension with no compatibility guarantee");
8829 warned_for_pass_big_vectors
= true;
8838 rs6000_move_block_from_reg (int regno
, rtx x
, int nregs
)
8841 enum machine_mode reg_mode
= TARGET_32BIT
? SImode
: DImode
;
8846 for (i
= 0; i
< nregs
; i
++)
8848 rtx tem
= adjust_address_nv (x
, reg_mode
, i
* GET_MODE_SIZE (reg_mode
));
8849 if (reload_completed
)
8851 if (! strict_memory_address_p (reg_mode
, XEXP (tem
, 0)))
8854 tem
= simplify_gen_subreg (reg_mode
, x
, BLKmode
,
8855 i
* GET_MODE_SIZE (reg_mode
));
8858 tem
= replace_equiv_address (tem
, XEXP (tem
, 0));
8862 emit_move_insn (tem
, gen_rtx_REG (reg_mode
, regno
+ i
));
8866 /* Perform any needed actions needed for a function that is receiving a
8867 variable number of arguments.
8871 MODE and TYPE are the mode and type of the current parameter.
8873 PRETEND_SIZE is a variable that should be set to the amount of stack
8874 that must be pushed by the prolog to pretend that our caller pushed
8877 Normally, this macro will push all remaining incoming registers on the
8878 stack and set PRETEND_SIZE to the length of the registers pushed. */
8881 setup_incoming_varargs (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
,
8882 tree type
, int *pretend_size ATTRIBUTE_UNUSED
,
8885 CUMULATIVE_ARGS next_cum
;
8886 int reg_size
= TARGET_32BIT
? 4 : 8;
8887 rtx save_area
= NULL_RTX
, mem
;
8888 int first_reg_offset
;
8891 /* Skip the last named argument. */
8893 rs6000_function_arg_advance_1 (&next_cum
, mode
, type
, true, 0);
8895 if (DEFAULT_ABI
== ABI_V4
)
8897 first_reg_offset
= next_cum
.sysv_gregno
- GP_ARG_MIN_REG
;
8901 int gpr_reg_num
= 0, gpr_size
= 0, fpr_size
= 0;
8902 HOST_WIDE_INT offset
= 0;
8904 /* Try to optimize the size of the varargs save area.
8905 The ABI requires that ap.reg_save_area is doubleword
8906 aligned, but we don't need to allocate space for all
8907 the bytes, only those to which we actually will save
8909 if (cfun
->va_list_gpr_size
&& first_reg_offset
< GP_ARG_NUM_REG
)
8910 gpr_reg_num
= GP_ARG_NUM_REG
- first_reg_offset
;
8911 if (TARGET_HARD_FLOAT
&& TARGET_FPRS
8912 && next_cum
.fregno
<= FP_ARG_V4_MAX_REG
8913 && cfun
->va_list_fpr_size
)
8916 fpr_size
= (next_cum
.fregno
- FP_ARG_MIN_REG
)
8917 * UNITS_PER_FP_WORD
;
8918 if (cfun
->va_list_fpr_size
8919 < FP_ARG_V4_MAX_REG
+ 1 - next_cum
.fregno
)
8920 fpr_size
+= cfun
->va_list_fpr_size
* UNITS_PER_FP_WORD
;
8922 fpr_size
+= (FP_ARG_V4_MAX_REG
+ 1 - next_cum
.fregno
)
8923 * UNITS_PER_FP_WORD
;
8927 offset
= -((first_reg_offset
* reg_size
) & ~7);
8928 if (!fpr_size
&& gpr_reg_num
> cfun
->va_list_gpr_size
)
8930 gpr_reg_num
= cfun
->va_list_gpr_size
;
8931 if (reg_size
== 4 && (first_reg_offset
& 1))
8934 gpr_size
= (gpr_reg_num
* reg_size
+ 7) & ~7;
8937 offset
= - (int) (next_cum
.fregno
- FP_ARG_MIN_REG
)
8939 - (int) (GP_ARG_NUM_REG
* reg_size
);
8941 if (gpr_size
+ fpr_size
)
8944 = assign_stack_local (BLKmode
, gpr_size
+ fpr_size
, 64);
8945 gcc_assert (GET_CODE (reg_save_area
) == MEM
);
8946 reg_save_area
= XEXP (reg_save_area
, 0);
8947 if (GET_CODE (reg_save_area
) == PLUS
)
8949 gcc_assert (XEXP (reg_save_area
, 0)
8950 == virtual_stack_vars_rtx
);
8951 gcc_assert (GET_CODE (XEXP (reg_save_area
, 1)) == CONST_INT
);
8952 offset
+= INTVAL (XEXP (reg_save_area
, 1));
8955 gcc_assert (reg_save_area
== virtual_stack_vars_rtx
);
8958 cfun
->machine
->varargs_save_offset
= offset
;
8959 save_area
= plus_constant (virtual_stack_vars_rtx
, offset
);
8964 first_reg_offset
= next_cum
.words
;
8965 save_area
= virtual_incoming_args_rtx
;
8967 if (targetm
.calls
.must_pass_in_stack (mode
, type
))
8968 first_reg_offset
+= rs6000_arg_size (TYPE_MODE (type
), type
);
8971 set
= get_varargs_alias_set ();
8972 if (! no_rtl
&& first_reg_offset
< GP_ARG_NUM_REG
8973 && cfun
->va_list_gpr_size
)
8975 int nregs
= GP_ARG_NUM_REG
- first_reg_offset
;
8977 if (va_list_gpr_counter_field
)
8979 /* V4 va_list_gpr_size counts number of registers needed. */
8980 if (nregs
> cfun
->va_list_gpr_size
)
8981 nregs
= cfun
->va_list_gpr_size
;
8985 /* char * va_list instead counts number of bytes needed. */
8986 if (nregs
> cfun
->va_list_gpr_size
/ reg_size
)
8987 nregs
= cfun
->va_list_gpr_size
/ reg_size
;
8990 mem
= gen_rtx_MEM (BLKmode
,
8991 plus_constant (save_area
,
8992 first_reg_offset
* reg_size
));
8993 MEM_NOTRAP_P (mem
) = 1;
8994 set_mem_alias_set (mem
, set
);
8995 set_mem_align (mem
, BITS_PER_WORD
);
8997 rs6000_move_block_from_reg (GP_ARG_MIN_REG
+ first_reg_offset
, mem
,
9001 /* Save FP registers if needed. */
9002 if (DEFAULT_ABI
== ABI_V4
9003 && TARGET_HARD_FLOAT
&& TARGET_FPRS
9005 && next_cum
.fregno
<= FP_ARG_V4_MAX_REG
9006 && cfun
->va_list_fpr_size
)
9008 int fregno
= next_cum
.fregno
, nregs
;
9009 rtx cr1
= gen_rtx_REG (CCmode
, CR1_REGNO
);
9010 rtx lab
= gen_label_rtx ();
9011 int off
= (GP_ARG_NUM_REG
* reg_size
) + ((fregno
- FP_ARG_MIN_REG
)
9012 * UNITS_PER_FP_WORD
);
9015 (gen_rtx_SET (VOIDmode
,
9017 gen_rtx_IF_THEN_ELSE (VOIDmode
,
9018 gen_rtx_NE (VOIDmode
, cr1
,
9020 gen_rtx_LABEL_REF (VOIDmode
, lab
),
9024 fregno
<= FP_ARG_V4_MAX_REG
&& nregs
< cfun
->va_list_fpr_size
;
9025 fregno
++, off
+= UNITS_PER_FP_WORD
, nregs
++)
9027 mem
= gen_rtx_MEM ((TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
)
9029 plus_constant (save_area
, off
));
9030 MEM_NOTRAP_P (mem
) = 1;
9031 set_mem_alias_set (mem
, set
);
9032 set_mem_align (mem
, GET_MODE_ALIGNMENT (
9033 (TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
)
9034 ? DFmode
: SFmode
));
9035 emit_move_insn (mem
, gen_rtx_REG (
9036 (TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
)
9037 ? DFmode
: SFmode
, fregno
));
9044 /* Create the va_list data type. */
9047 rs6000_build_builtin_va_list (void)
9049 tree f_gpr
, f_fpr
, f_res
, f_ovf
, f_sav
, record
, type_decl
;
9051 /* For AIX, prefer 'char *' because that's what the system
9052 header files like. */
9053 if (DEFAULT_ABI
!= ABI_V4
)
9054 return build_pointer_type (char_type_node
);
9056 record
= (*lang_hooks
.types
.make_type
) (RECORD_TYPE
);
9057 type_decl
= build_decl (BUILTINS_LOCATION
, TYPE_DECL
,
9058 get_identifier ("__va_list_tag"), record
);
9060 f_gpr
= build_decl (BUILTINS_LOCATION
, FIELD_DECL
, get_identifier ("gpr"),
9061 unsigned_char_type_node
);
9062 f_fpr
= build_decl (BUILTINS_LOCATION
, FIELD_DECL
, get_identifier ("fpr"),
9063 unsigned_char_type_node
);
9064 /* Give the two bytes of padding a name, so that -Wpadded won't warn on
9066 f_res
= build_decl (BUILTINS_LOCATION
, FIELD_DECL
,
9067 get_identifier ("reserved"), short_unsigned_type_node
);
9068 f_ovf
= build_decl (BUILTINS_LOCATION
, FIELD_DECL
,
9069 get_identifier ("overflow_arg_area"),
9071 f_sav
= build_decl (BUILTINS_LOCATION
, FIELD_DECL
,
9072 get_identifier ("reg_save_area"),
9075 va_list_gpr_counter_field
= f_gpr
;
9076 va_list_fpr_counter_field
= f_fpr
;
9078 DECL_FIELD_CONTEXT (f_gpr
) = record
;
9079 DECL_FIELD_CONTEXT (f_fpr
) = record
;
9080 DECL_FIELD_CONTEXT (f_res
) = record
;
9081 DECL_FIELD_CONTEXT (f_ovf
) = record
;
9082 DECL_FIELD_CONTEXT (f_sav
) = record
;
9084 TREE_CHAIN (record
) = type_decl
;
9085 TYPE_NAME (record
) = type_decl
;
9086 TYPE_FIELDS (record
) = f_gpr
;
9087 DECL_CHAIN (f_gpr
) = f_fpr
;
9088 DECL_CHAIN (f_fpr
) = f_res
;
9089 DECL_CHAIN (f_res
) = f_ovf
;
9090 DECL_CHAIN (f_ovf
) = f_sav
;
9092 layout_type (record
);
9094 /* The correct type is an array type of one element. */
9095 return build_array_type (record
, build_index_type (size_zero_node
));
9098 /* Implement va_start. */
9101 rs6000_va_start (tree valist
, rtx nextarg
)
9103 HOST_WIDE_INT words
, n_gpr
, n_fpr
;
9104 tree f_gpr
, f_fpr
, f_res
, f_ovf
, f_sav
;
9105 tree gpr
, fpr
, ovf
, sav
, t
;
9107 /* Only SVR4 needs something special. */
9108 if (DEFAULT_ABI
!= ABI_V4
)
9110 std_expand_builtin_va_start (valist
, nextarg
);
9114 f_gpr
= TYPE_FIELDS (TREE_TYPE (va_list_type_node
));
9115 f_fpr
= DECL_CHAIN (f_gpr
);
9116 f_res
= DECL_CHAIN (f_fpr
);
9117 f_ovf
= DECL_CHAIN (f_res
);
9118 f_sav
= DECL_CHAIN (f_ovf
);
9120 valist
= build_va_arg_indirect_ref (valist
);
9121 gpr
= build3 (COMPONENT_REF
, TREE_TYPE (f_gpr
), valist
, f_gpr
, NULL_TREE
);
9122 fpr
= build3 (COMPONENT_REF
, TREE_TYPE (f_fpr
), unshare_expr (valist
),
9124 ovf
= build3 (COMPONENT_REF
, TREE_TYPE (f_ovf
), unshare_expr (valist
),
9126 sav
= build3 (COMPONENT_REF
, TREE_TYPE (f_sav
), unshare_expr (valist
),
9129 /* Count number of gp and fp argument registers used. */
9130 words
= crtl
->args
.info
.words
;
9131 n_gpr
= MIN (crtl
->args
.info
.sysv_gregno
- GP_ARG_MIN_REG
,
9133 n_fpr
= MIN (crtl
->args
.info
.fregno
- FP_ARG_MIN_REG
,
9136 if (TARGET_DEBUG_ARG
)
9137 fprintf (stderr
, "va_start: words = "HOST_WIDE_INT_PRINT_DEC
", n_gpr = "
9138 HOST_WIDE_INT_PRINT_DEC
", n_fpr = "HOST_WIDE_INT_PRINT_DEC
"\n",
9139 words
, n_gpr
, n_fpr
);
9141 if (cfun
->va_list_gpr_size
)
9143 t
= build2 (MODIFY_EXPR
, TREE_TYPE (gpr
), gpr
,
9144 build_int_cst (NULL_TREE
, n_gpr
));
9145 TREE_SIDE_EFFECTS (t
) = 1;
9146 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
9149 if (cfun
->va_list_fpr_size
)
9151 t
= build2 (MODIFY_EXPR
, TREE_TYPE (fpr
), fpr
,
9152 build_int_cst (NULL_TREE
, n_fpr
));
9153 TREE_SIDE_EFFECTS (t
) = 1;
9154 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
9157 /* Find the overflow area. */
9158 t
= make_tree (TREE_TYPE (ovf
), virtual_incoming_args_rtx
);
9160 t
= build2 (POINTER_PLUS_EXPR
, TREE_TYPE (ovf
), t
,
9161 size_int (words
* UNITS_PER_WORD
));
9162 t
= build2 (MODIFY_EXPR
, TREE_TYPE (ovf
), ovf
, t
);
9163 TREE_SIDE_EFFECTS (t
) = 1;
9164 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
9166 /* If there were no va_arg invocations, don't set up the register
9168 if (!cfun
->va_list_gpr_size
9169 && !cfun
->va_list_fpr_size
9170 && n_gpr
< GP_ARG_NUM_REG
9171 && n_fpr
< FP_ARG_V4_MAX_REG
)
9174 /* Find the register save area. */
9175 t
= make_tree (TREE_TYPE (sav
), virtual_stack_vars_rtx
);
9176 if (cfun
->machine
->varargs_save_offset
)
9177 t
= build2 (POINTER_PLUS_EXPR
, TREE_TYPE (sav
), t
,
9178 size_int (cfun
->machine
->varargs_save_offset
));
9179 t
= build2 (MODIFY_EXPR
, TREE_TYPE (sav
), sav
, t
);
9180 TREE_SIDE_EFFECTS (t
) = 1;
9181 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
9184 /* Implement va_arg. */
9187 rs6000_gimplify_va_arg (tree valist
, tree type
, gimple_seq
*pre_p
,
9190 tree f_gpr
, f_fpr
, f_res
, f_ovf
, f_sav
;
9191 tree gpr
, fpr
, ovf
, sav
, reg
, t
, u
;
9192 int size
, rsize
, n_reg
, sav_ofs
, sav_scale
;
9193 tree lab_false
, lab_over
, addr
;
9195 tree ptrtype
= build_pointer_type_for_mode (type
, ptr_mode
, true);
9199 if (pass_by_reference (NULL
, TYPE_MODE (type
), type
, false))
9201 t
= rs6000_gimplify_va_arg (valist
, ptrtype
, pre_p
, post_p
);
9202 return build_va_arg_indirect_ref (t
);
9205 /* We need to deal with the fact that the darwin ppc64 ABI is defined by an
9206 earlier version of gcc, with the property that it always applied alignment
9207 adjustments to the va-args (even for zero-sized types). The cheapest way
9208 to deal with this is to replicate the effect of the part of
9209 std_gimplify_va_arg_expr that carries out the align adjust, for the case
9211 We don't need to check for pass-by-reference because of the test above.
9212 We can return a simplifed answer, since we know there's no offset to add. */
9215 && rs6000_darwin64_abi
9216 && integer_zerop (TYPE_SIZE (type
)))
9218 unsigned HOST_WIDE_INT align
, boundary
;
9219 tree valist_tmp
= get_initialized_tmp_var (valist
, pre_p
, NULL
);
9220 align
= PARM_BOUNDARY
/ BITS_PER_UNIT
;
9221 boundary
= FUNCTION_ARG_BOUNDARY (TYPE_MODE (type
), type
);
9222 if (boundary
> MAX_SUPPORTED_STACK_ALIGNMENT
)
9223 boundary
= MAX_SUPPORTED_STACK_ALIGNMENT
;
9224 boundary
/= BITS_PER_UNIT
;
9225 if (boundary
> align
)
9228 /* This updates arg ptr by the amount that would be necessary
9229 to align the zero-sized (but not zero-alignment) item. */
9230 t
= build2 (MODIFY_EXPR
, TREE_TYPE (valist
), valist_tmp
,
9231 fold_build2 (POINTER_PLUS_EXPR
,
9233 valist_tmp
, size_int (boundary
- 1)));
9234 gimplify_and_add (t
, pre_p
);
9236 t
= fold_convert (sizetype
, valist_tmp
);
9237 t
= build2 (MODIFY_EXPR
, TREE_TYPE (valist
), valist_tmp
,
9238 fold_convert (TREE_TYPE (valist
),
9239 fold_build2 (BIT_AND_EXPR
, sizetype
, t
,
9240 size_int (-boundary
))));
9241 t
= build2 (MODIFY_EXPR
, TREE_TYPE (valist
), valist
, t
);
9242 gimplify_and_add (t
, pre_p
);
9244 /* Since it is zero-sized there's no increment for the item itself. */
9245 valist_tmp
= fold_convert (build_pointer_type (type
), valist_tmp
);
9246 return build_va_arg_indirect_ref (valist_tmp
);
9249 if (DEFAULT_ABI
!= ABI_V4
)
9251 if (targetm
.calls
.split_complex_arg
&& TREE_CODE (type
) == COMPLEX_TYPE
)
9253 tree elem_type
= TREE_TYPE (type
);
9254 enum machine_mode elem_mode
= TYPE_MODE (elem_type
);
9255 int elem_size
= GET_MODE_SIZE (elem_mode
);
9257 if (elem_size
< UNITS_PER_WORD
)
9259 tree real_part
, imag_part
;
9260 gimple_seq post
= NULL
;
9262 real_part
= rs6000_gimplify_va_arg (valist
, elem_type
, pre_p
,
9264 /* Copy the value into a temporary, lest the formal temporary
9265 be reused out from under us. */
9266 real_part
= get_initialized_tmp_var (real_part
, pre_p
, &post
);
9267 gimple_seq_add_seq (pre_p
, post
);
9269 imag_part
= rs6000_gimplify_va_arg (valist
, elem_type
, pre_p
,
9272 return build2 (COMPLEX_EXPR
, type
, real_part
, imag_part
);
9276 return std_gimplify_va_arg_expr (valist
, type
, pre_p
, post_p
);
9279 f_gpr
= TYPE_FIELDS (TREE_TYPE (va_list_type_node
));
9280 f_fpr
= DECL_CHAIN (f_gpr
);
9281 f_res
= DECL_CHAIN (f_fpr
);
9282 f_ovf
= DECL_CHAIN (f_res
);
9283 f_sav
= DECL_CHAIN (f_ovf
);
9285 valist
= build_va_arg_indirect_ref (valist
);
9286 gpr
= build3 (COMPONENT_REF
, TREE_TYPE (f_gpr
), valist
, f_gpr
, NULL_TREE
);
9287 fpr
= build3 (COMPONENT_REF
, TREE_TYPE (f_fpr
), unshare_expr (valist
),
9289 ovf
= build3 (COMPONENT_REF
, TREE_TYPE (f_ovf
), unshare_expr (valist
),
9291 sav
= build3 (COMPONENT_REF
, TREE_TYPE (f_sav
), unshare_expr (valist
),
9294 size
= int_size_in_bytes (type
);
9295 rsize
= (size
+ 3) / 4;
9298 if (TARGET_HARD_FLOAT
&& TARGET_FPRS
9299 && ((TARGET_SINGLE_FLOAT
&& TYPE_MODE (type
) == SFmode
)
9300 || (TARGET_DOUBLE_FLOAT
9301 && (TYPE_MODE (type
) == DFmode
9302 || TYPE_MODE (type
) == TFmode
9303 || TYPE_MODE (type
) == SDmode
9304 || TYPE_MODE (type
) == DDmode
9305 || TYPE_MODE (type
) == TDmode
))))
9307 /* FP args go in FP registers, if present. */
9309 n_reg
= (size
+ 7) / 8;
9310 sav_ofs
= ((TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
) ? 8 : 4) * 4;
9311 sav_scale
= ((TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
) ? 8 : 4);
9312 if (TYPE_MODE (type
) != SFmode
&& TYPE_MODE (type
) != SDmode
)
9317 /* Otherwise into GP registers. */
9326 /* Pull the value out of the saved registers.... */
9329 addr
= create_tmp_var (ptr_type_node
, "addr");
9331 /* AltiVec vectors never go in registers when -mabi=altivec. */
9332 if (TARGET_ALTIVEC_ABI
&& ALTIVEC_VECTOR_MODE (TYPE_MODE (type
)))
9336 lab_false
= create_artificial_label (input_location
);
9337 lab_over
= create_artificial_label (input_location
);
9339 /* Long long and SPE vectors are aligned in the registers.
9340 As are any other 2 gpr item such as complex int due to a
9341 historical mistake. */
9343 if (n_reg
== 2 && reg
== gpr
)
9346 u
= build2 (BIT_AND_EXPR
, TREE_TYPE (reg
), unshare_expr (reg
),
9347 build_int_cst (TREE_TYPE (reg
), n_reg
- 1));
9348 u
= build2 (POSTINCREMENT_EXPR
, TREE_TYPE (reg
),
9349 unshare_expr (reg
), u
);
9351 /* _Decimal128 is passed in even/odd fpr pairs; the stored
9352 reg number is 0 for f1, so we want to make it odd. */
9353 else if (reg
== fpr
&& TYPE_MODE (type
) == TDmode
)
9355 t
= build2 (BIT_IOR_EXPR
, TREE_TYPE (reg
), unshare_expr (reg
),
9356 build_int_cst (TREE_TYPE (reg
), 1));
9357 u
= build2 (MODIFY_EXPR
, void_type_node
, unshare_expr (reg
), t
);
9360 t
= fold_convert (TREE_TYPE (reg
), size_int (8 - n_reg
+ 1));
9361 t
= build2 (GE_EXPR
, boolean_type_node
, u
, t
);
9362 u
= build1 (GOTO_EXPR
, void_type_node
, lab_false
);
9363 t
= build3 (COND_EXPR
, void_type_node
, t
, u
, NULL_TREE
);
9364 gimplify_and_add (t
, pre_p
);
9368 t
= build2 (POINTER_PLUS_EXPR
, ptr_type_node
, sav
, size_int (sav_ofs
));
9370 u
= build2 (POSTINCREMENT_EXPR
, TREE_TYPE (reg
), unshare_expr (reg
),
9371 build_int_cst (TREE_TYPE (reg
), n_reg
));
9372 u
= fold_convert (sizetype
, u
);
9373 u
= build2 (MULT_EXPR
, sizetype
, u
, size_int (sav_scale
));
9374 t
= build2 (POINTER_PLUS_EXPR
, ptr_type_node
, t
, u
);
9376 /* _Decimal32 varargs are located in the second word of the 64-bit
9377 FP register for 32-bit binaries. */
9378 if (!TARGET_POWERPC64
9379 && TARGET_HARD_FLOAT
&& TARGET_FPRS
9380 && TYPE_MODE (type
) == SDmode
)
9381 t
= build2 (POINTER_PLUS_EXPR
, TREE_TYPE (t
), t
, size_int (size
));
9383 gimplify_assign (addr
, t
, pre_p
);
9385 gimple_seq_add_stmt (pre_p
, gimple_build_goto (lab_over
));
9387 stmt
= gimple_build_label (lab_false
);
9388 gimple_seq_add_stmt (pre_p
, stmt
);
9390 if ((n_reg
== 2 && !regalign
) || n_reg
> 2)
9392 /* Ensure that we don't find any more args in regs.
9393 Alignment has taken care of for special cases. */
9394 gimplify_assign (reg
, build_int_cst (TREE_TYPE (reg
), 8), pre_p
);
9398 /* ... otherwise out of the overflow area. */
9400 /* Care for on-stack alignment if needed. */
9404 t
= build2 (POINTER_PLUS_EXPR
, TREE_TYPE (t
), t
, size_int (align
- 1));
9405 t
= fold_convert (sizetype
, t
);
9406 t
= build2 (BIT_AND_EXPR
, TREE_TYPE (t
), t
,
9408 t
= fold_convert (TREE_TYPE (ovf
), t
);
9410 gimplify_expr (&t
, pre_p
, NULL
, is_gimple_val
, fb_rvalue
);
9412 gimplify_assign (unshare_expr (addr
), t
, pre_p
);
9414 t
= build2 (POINTER_PLUS_EXPR
, TREE_TYPE (t
), t
, size_int (size
));
9415 gimplify_assign (unshare_expr (ovf
), t
, pre_p
);
9419 stmt
= gimple_build_label (lab_over
);
9420 gimple_seq_add_stmt (pre_p
, stmt
);
9423 if (STRICT_ALIGNMENT
9424 && (TYPE_ALIGN (type
)
9425 > (unsigned) BITS_PER_UNIT
* (align
< 4 ? 4 : align
)))
9427 /* The value (of type complex double, for example) may not be
9428 aligned in memory in the saved registers, so copy via a
9429 temporary. (This is the same code as used for SPARC.) */
9430 tree tmp
= create_tmp_var (type
, "va_arg_tmp");
9431 tree dest_addr
= build_fold_addr_expr (tmp
);
9433 tree copy
= build_call_expr (implicit_built_in_decls
[BUILT_IN_MEMCPY
],
9434 3, dest_addr
, addr
, size_int (rsize
* 4));
9436 gimplify_and_add (copy
, pre_p
);
9440 addr
= fold_convert (ptrtype
, addr
);
9441 return build_va_arg_indirect_ref (addr
);
9447 def_builtin (int mask
, const char *name
, tree type
, int code
)
9449 if ((mask
& target_flags
) || TARGET_PAIRED_FLOAT
)
9452 if (rs6000_builtin_decls
[code
])
9453 fatal_error ("internal error: builtin function to %s already processed.",
9456 rs6000_builtin_decls
[code
] = t
=
9457 add_builtin_function (name
, type
, code
, BUILT_IN_MD
,
9460 gcc_assert (code
>= 0 && code
< (int)RS6000_BUILTIN_COUNT
);
9461 switch (builtin_classify
[code
])
9466 /* assume builtin can do anything. */
9467 case RS6000_BTC_MISC
:
9470 /* const function, function only depends on the inputs. */
9471 case RS6000_BTC_CONST
:
9472 TREE_READONLY (t
) = 1;
9473 TREE_NOTHROW (t
) = 1;
9476 /* pure function, function can read global memory. */
9477 case RS6000_BTC_PURE
:
9478 DECL_PURE_P (t
) = 1;
9479 TREE_NOTHROW (t
) = 1;
9482 /* Function is a math function. If rounding mode is on, then treat
9483 the function as not reading global memory, but it can have
9484 arbitrary side effects. If it is off, then assume the function is
9485 a const function. This mimics the ATTR_MATHFN_FPROUNDING
9486 attribute in builtin-attribute.def that is used for the math
9488 case RS6000_BTC_FP_PURE
:
9489 TREE_NOTHROW (t
) = 1;
9490 if (flag_rounding_math
)
9492 DECL_PURE_P (t
) = 1;
9493 DECL_IS_NOVOPS (t
) = 1;
9496 TREE_READONLY (t
) = 1;
9502 /* Simple ternary operations: VECd = foo (VECa, VECb, VECc). */
9504 static const struct builtin_description bdesc_3arg
[] =
9506 { MASK_ALTIVEC
, CODE_FOR_altivec_vmaddfp
, "__builtin_altivec_vmaddfp", ALTIVEC_BUILTIN_VMADDFP
},
9507 { MASK_ALTIVEC
, CODE_FOR_altivec_vmhaddshs
, "__builtin_altivec_vmhaddshs", ALTIVEC_BUILTIN_VMHADDSHS
},
9508 { MASK_ALTIVEC
, CODE_FOR_altivec_vmhraddshs
, "__builtin_altivec_vmhraddshs", ALTIVEC_BUILTIN_VMHRADDSHS
},
9509 { MASK_ALTIVEC
, CODE_FOR_altivec_vmladduhm
, "__builtin_altivec_vmladduhm", ALTIVEC_BUILTIN_VMLADDUHM
},
9510 { MASK_ALTIVEC
, CODE_FOR_altivec_vmsumubm
, "__builtin_altivec_vmsumubm", ALTIVEC_BUILTIN_VMSUMUBM
},
9511 { MASK_ALTIVEC
, CODE_FOR_altivec_vmsummbm
, "__builtin_altivec_vmsummbm", ALTIVEC_BUILTIN_VMSUMMBM
},
9512 { MASK_ALTIVEC
, CODE_FOR_altivec_vmsumuhm
, "__builtin_altivec_vmsumuhm", ALTIVEC_BUILTIN_VMSUMUHM
},
9513 { MASK_ALTIVEC
, CODE_FOR_altivec_vmsumshm
, "__builtin_altivec_vmsumshm", ALTIVEC_BUILTIN_VMSUMSHM
},
9514 { MASK_ALTIVEC
, CODE_FOR_altivec_vmsumuhs
, "__builtin_altivec_vmsumuhs", ALTIVEC_BUILTIN_VMSUMUHS
},
9515 { MASK_ALTIVEC
, CODE_FOR_altivec_vmsumshs
, "__builtin_altivec_vmsumshs", ALTIVEC_BUILTIN_VMSUMSHS
},
9516 { MASK_ALTIVEC
, CODE_FOR_altivec_vnmsubfp
, "__builtin_altivec_vnmsubfp", ALTIVEC_BUILTIN_VNMSUBFP
},
9517 { MASK_ALTIVEC
, CODE_FOR_altivec_vperm_v2df
, "__builtin_altivec_vperm_2df", ALTIVEC_BUILTIN_VPERM_2DF
},
9518 { MASK_ALTIVEC
, CODE_FOR_altivec_vperm_v2di
, "__builtin_altivec_vperm_2di", ALTIVEC_BUILTIN_VPERM_2DI
},
9519 { MASK_ALTIVEC
, CODE_FOR_altivec_vperm_v4sf
, "__builtin_altivec_vperm_4sf", ALTIVEC_BUILTIN_VPERM_4SF
},
9520 { MASK_ALTIVEC
, CODE_FOR_altivec_vperm_v4si
, "__builtin_altivec_vperm_4si", ALTIVEC_BUILTIN_VPERM_4SI
},
9521 { MASK_ALTIVEC
, CODE_FOR_altivec_vperm_v8hi
, "__builtin_altivec_vperm_8hi", ALTIVEC_BUILTIN_VPERM_8HI
},
9522 { MASK_ALTIVEC
, CODE_FOR_altivec_vperm_v16qi_uns
, "__builtin_altivec_vperm_16qi", ALTIVEC_BUILTIN_VPERM_16QI
},
9523 { MASK_ALTIVEC
, CODE_FOR_altivec_vperm_v2di_uns
, "__builtin_altivec_vperm_2di_uns", ALTIVEC_BUILTIN_VPERM_2DI_UNS
},
9524 { MASK_ALTIVEC
, CODE_FOR_altivec_vperm_v4si_uns
, "__builtin_altivec_vperm_4si_uns", ALTIVEC_BUILTIN_VPERM_4SI_UNS
},
9525 { MASK_ALTIVEC
, CODE_FOR_altivec_vperm_v8hi_uns
, "__builtin_altivec_vperm_8hi_uns", ALTIVEC_BUILTIN_VPERM_8HI_UNS
},
9526 { MASK_ALTIVEC
, CODE_FOR_altivec_vperm_v16qi_uns
, "__builtin_altivec_vperm_16qi_uns", ALTIVEC_BUILTIN_VPERM_16QI_UNS
},
9527 { MASK_ALTIVEC
, CODE_FOR_vector_select_v4sf
, "__builtin_altivec_vsel_4sf", ALTIVEC_BUILTIN_VSEL_4SF
},
9528 { MASK_ALTIVEC
, CODE_FOR_vector_select_v4si
, "__builtin_altivec_vsel_4si", ALTIVEC_BUILTIN_VSEL_4SI
},
9529 { MASK_ALTIVEC
, CODE_FOR_vector_select_v8hi
, "__builtin_altivec_vsel_8hi", ALTIVEC_BUILTIN_VSEL_8HI
},
9530 { MASK_ALTIVEC
, CODE_FOR_vector_select_v16qi
, "__builtin_altivec_vsel_16qi", ALTIVEC_BUILTIN_VSEL_16QI
},
9531 { MASK_ALTIVEC
, CODE_FOR_vector_select_v2df
, "__builtin_altivec_vsel_2df", ALTIVEC_BUILTIN_VSEL_2DF
},
9532 { MASK_ALTIVEC
, CODE_FOR_vector_select_v2di
, "__builtin_altivec_vsel_2di", ALTIVEC_BUILTIN_VSEL_2DI
},
9533 { MASK_ALTIVEC
, CODE_FOR_vector_select_v4si_uns
, "__builtin_altivec_vsel_4si_uns", ALTIVEC_BUILTIN_VSEL_4SI_UNS
},
9534 { MASK_ALTIVEC
, CODE_FOR_vector_select_v8hi_uns
, "__builtin_altivec_vsel_8hi_uns", ALTIVEC_BUILTIN_VSEL_8HI_UNS
},
9535 { MASK_ALTIVEC
, CODE_FOR_vector_select_v16qi_uns
, "__builtin_altivec_vsel_16qi_uns", ALTIVEC_BUILTIN_VSEL_16QI_UNS
},
9536 { MASK_ALTIVEC
, CODE_FOR_vector_select_v2di_uns
, "__builtin_altivec_vsel_2di_uns", ALTIVEC_BUILTIN_VSEL_2DI_UNS
},
9537 { MASK_ALTIVEC
, CODE_FOR_altivec_vsldoi_v16qi
, "__builtin_altivec_vsldoi_16qi", ALTIVEC_BUILTIN_VSLDOI_16QI
},
9538 { MASK_ALTIVEC
, CODE_FOR_altivec_vsldoi_v8hi
, "__builtin_altivec_vsldoi_8hi", ALTIVEC_BUILTIN_VSLDOI_8HI
},
9539 { MASK_ALTIVEC
, CODE_FOR_altivec_vsldoi_v4si
, "__builtin_altivec_vsldoi_4si", ALTIVEC_BUILTIN_VSLDOI_4SI
},
9540 { MASK_ALTIVEC
, CODE_FOR_altivec_vsldoi_v4sf
, "__builtin_altivec_vsldoi_4sf", ALTIVEC_BUILTIN_VSLDOI_4SF
},
9542 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_madd", ALTIVEC_BUILTIN_VEC_MADD
},
9543 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_madds", ALTIVEC_BUILTIN_VEC_MADDS
},
9544 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_mladd", ALTIVEC_BUILTIN_VEC_MLADD
},
9545 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_mradds", ALTIVEC_BUILTIN_VEC_MRADDS
},
9546 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_msum", ALTIVEC_BUILTIN_VEC_MSUM
},
9547 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmsumshm", ALTIVEC_BUILTIN_VEC_VMSUMSHM
},
9548 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmsumuhm", ALTIVEC_BUILTIN_VEC_VMSUMUHM
},
9549 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmsummbm", ALTIVEC_BUILTIN_VEC_VMSUMMBM
},
9550 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmsumubm", ALTIVEC_BUILTIN_VEC_VMSUMUBM
},
9551 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_msums", ALTIVEC_BUILTIN_VEC_MSUMS
},
9552 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmsumshs", ALTIVEC_BUILTIN_VEC_VMSUMSHS
},
9553 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmsumuhs", ALTIVEC_BUILTIN_VEC_VMSUMUHS
},
9554 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_nmsub", ALTIVEC_BUILTIN_VEC_NMSUB
},
9555 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_perm", ALTIVEC_BUILTIN_VEC_PERM
},
9556 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sel", ALTIVEC_BUILTIN_VEC_SEL
},
9558 { MASK_VSX
, CODE_FOR_vsx_fmaddv2df4
, "__builtin_vsx_xvmadddp", VSX_BUILTIN_XVMADDDP
},
9559 { MASK_VSX
, CODE_FOR_vsx_fmsubv2df4
, "__builtin_vsx_xvmsubdp", VSX_BUILTIN_XVMSUBDP
},
9560 { MASK_VSX
, CODE_FOR_vsx_fnmaddv2df4
, "__builtin_vsx_xvnmadddp", VSX_BUILTIN_XVNMADDDP
},
9561 { MASK_VSX
, CODE_FOR_vsx_fnmsubv2df4
, "__builtin_vsx_xvnmsubdp", VSX_BUILTIN_XVNMSUBDP
},
9563 { MASK_VSX
, CODE_FOR_vsx_fmaddv4sf4
, "__builtin_vsx_xvmaddsp", VSX_BUILTIN_XVMADDSP
},
9564 { MASK_VSX
, CODE_FOR_vsx_fmsubv4sf4
, "__builtin_vsx_xvmsubsp", VSX_BUILTIN_XVMSUBSP
},
9565 { MASK_VSX
, CODE_FOR_vsx_fnmaddv4sf4
, "__builtin_vsx_xvnmaddsp", VSX_BUILTIN_XVNMADDSP
},
9566 { MASK_VSX
, CODE_FOR_vsx_fnmsubv4sf4
, "__builtin_vsx_xvnmsubsp", VSX_BUILTIN_XVNMSUBSP
},
9568 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_msub", VSX_BUILTIN_VEC_MSUB
},
9569 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_nmadd", VSX_BUILTIN_VEC_NMADD
},
9571 { MASK_VSX
, CODE_FOR_vector_select_v2di
, "__builtin_vsx_xxsel_2di", VSX_BUILTIN_XXSEL_2DI
},
9572 { MASK_VSX
, CODE_FOR_vector_select_v2df
, "__builtin_vsx_xxsel_2df", VSX_BUILTIN_XXSEL_2DF
},
9573 { MASK_VSX
, CODE_FOR_vector_select_v4sf
, "__builtin_vsx_xxsel_4sf", VSX_BUILTIN_XXSEL_4SF
},
9574 { MASK_VSX
, CODE_FOR_vector_select_v4si
, "__builtin_vsx_xxsel_4si", VSX_BUILTIN_XXSEL_4SI
},
9575 { MASK_VSX
, CODE_FOR_vector_select_v8hi
, "__builtin_vsx_xxsel_8hi", VSX_BUILTIN_XXSEL_8HI
},
9576 { MASK_VSX
, CODE_FOR_vector_select_v16qi
, "__builtin_vsx_xxsel_16qi", VSX_BUILTIN_XXSEL_16QI
},
9577 { MASK_VSX
, CODE_FOR_vector_select_v2di_uns
, "__builtin_vsx_xxsel_2di_uns", VSX_BUILTIN_XXSEL_2DI_UNS
},
9578 { MASK_VSX
, CODE_FOR_vector_select_v4si_uns
, "__builtin_vsx_xxsel_4si_uns", VSX_BUILTIN_XXSEL_4SI_UNS
},
9579 { MASK_VSX
, CODE_FOR_vector_select_v8hi_uns
, "__builtin_vsx_xxsel_8hi_uns", VSX_BUILTIN_XXSEL_8HI_UNS
},
9580 { MASK_VSX
, CODE_FOR_vector_select_v16qi_uns
, "__builtin_vsx_xxsel_16qi_uns", VSX_BUILTIN_XXSEL_16QI_UNS
},
9582 { MASK_VSX
, CODE_FOR_altivec_vperm_v2di
, "__builtin_vsx_vperm_2di", VSX_BUILTIN_VPERM_2DI
},
9583 { MASK_VSX
, CODE_FOR_altivec_vperm_v2df
, "__builtin_vsx_vperm_2df", VSX_BUILTIN_VPERM_2DF
},
9584 { MASK_VSX
, CODE_FOR_altivec_vperm_v4sf
, "__builtin_vsx_vperm_4sf", VSX_BUILTIN_VPERM_4SF
},
9585 { MASK_VSX
, CODE_FOR_altivec_vperm_v4si
, "__builtin_vsx_vperm_4si", VSX_BUILTIN_VPERM_4SI
},
9586 { MASK_VSX
, CODE_FOR_altivec_vperm_v8hi
, "__builtin_vsx_vperm_8hi", VSX_BUILTIN_VPERM_8HI
},
9587 { MASK_VSX
, CODE_FOR_altivec_vperm_v16qi
, "__builtin_vsx_vperm_16qi", VSX_BUILTIN_VPERM_16QI
},
9588 { MASK_VSX
, CODE_FOR_altivec_vperm_v2di_uns
, "__builtin_vsx_vperm_2di_uns", VSX_BUILTIN_VPERM_2DI_UNS
},
9589 { MASK_VSX
, CODE_FOR_altivec_vperm_v4si_uns
, "__builtin_vsx_vperm_4si_uns", VSX_BUILTIN_VPERM_4SI_UNS
},
9590 { MASK_VSX
, CODE_FOR_altivec_vperm_v8hi_uns
, "__builtin_vsx_vperm_8hi_uns", VSX_BUILTIN_VPERM_8HI_UNS
},
9591 { MASK_VSX
, CODE_FOR_altivec_vperm_v16qi_uns
, "__builtin_vsx_vperm_16qi_uns", VSX_BUILTIN_VPERM_16QI_UNS
},
9593 { MASK_VSX
, CODE_FOR_vsx_xxpermdi_v2df
, "__builtin_vsx_xxpermdi_2df", VSX_BUILTIN_XXPERMDI_2DF
},
9594 { MASK_VSX
, CODE_FOR_vsx_xxpermdi_v2di
, "__builtin_vsx_xxpermdi_2di", VSX_BUILTIN_XXPERMDI_2DI
},
9595 { MASK_VSX
, CODE_FOR_vsx_xxpermdi_v4sf
, "__builtin_vsx_xxpermdi_4sf", VSX_BUILTIN_XXPERMDI_4SF
},
9596 { MASK_VSX
, CODE_FOR_vsx_xxpermdi_v4si
, "__builtin_vsx_xxpermdi_4si", VSX_BUILTIN_XXPERMDI_4SI
},
9597 { MASK_VSX
, CODE_FOR_vsx_xxpermdi_v8hi
, "__builtin_vsx_xxpermdi_8hi", VSX_BUILTIN_XXPERMDI_8HI
},
9598 { MASK_VSX
, CODE_FOR_vsx_xxpermdi_v16qi
, "__builtin_vsx_xxpermdi_16qi", VSX_BUILTIN_XXPERMDI_16QI
},
9599 { MASK_VSX
, CODE_FOR_nothing
, "__builtin_vsx_xxpermdi", VSX_BUILTIN_VEC_XXPERMDI
},
9600 { MASK_VSX
, CODE_FOR_vsx_set_v2df
, "__builtin_vsx_set_2df", VSX_BUILTIN_SET_2DF
},
9601 { MASK_VSX
, CODE_FOR_vsx_set_v2di
, "__builtin_vsx_set_2di", VSX_BUILTIN_SET_2DI
},
9603 { MASK_VSX
, CODE_FOR_vsx_xxsldwi_v2di
, "__builtin_vsx_xxsldwi_2di", VSX_BUILTIN_XXSLDWI_2DI
},
9604 { MASK_VSX
, CODE_FOR_vsx_xxsldwi_v2df
, "__builtin_vsx_xxsldwi_2df", VSX_BUILTIN_XXSLDWI_2DF
},
9605 { MASK_VSX
, CODE_FOR_vsx_xxsldwi_v4sf
, "__builtin_vsx_xxsldwi_4sf", VSX_BUILTIN_XXSLDWI_4SF
},
9606 { MASK_VSX
, CODE_FOR_vsx_xxsldwi_v4si
, "__builtin_vsx_xxsldwi_4si", VSX_BUILTIN_XXSLDWI_4SI
},
9607 { MASK_VSX
, CODE_FOR_vsx_xxsldwi_v8hi
, "__builtin_vsx_xxsldwi_8hi", VSX_BUILTIN_XXSLDWI_8HI
},
9608 { MASK_VSX
, CODE_FOR_vsx_xxsldwi_v16qi
, "__builtin_vsx_xxsldwi_16qi", VSX_BUILTIN_XXSLDWI_16QI
},
9609 { MASK_VSX
, CODE_FOR_nothing
, "__builtin_vsx_xxsldwi", VSX_BUILTIN_VEC_XXSLDWI
},
9611 { 0, CODE_FOR_paired_msub
, "__builtin_paired_msub", PAIRED_BUILTIN_MSUB
},
9612 { 0, CODE_FOR_paired_madd
, "__builtin_paired_madd", PAIRED_BUILTIN_MADD
},
9613 { 0, CODE_FOR_paired_madds0
, "__builtin_paired_madds0", PAIRED_BUILTIN_MADDS0
},
9614 { 0, CODE_FOR_paired_madds1
, "__builtin_paired_madds1", PAIRED_BUILTIN_MADDS1
},
9615 { 0, CODE_FOR_paired_nmsub
, "__builtin_paired_nmsub", PAIRED_BUILTIN_NMSUB
},
9616 { 0, CODE_FOR_paired_nmadd
, "__builtin_paired_nmadd", PAIRED_BUILTIN_NMADD
},
9617 { 0, CODE_FOR_paired_sum0
, "__builtin_paired_sum0", PAIRED_BUILTIN_SUM0
},
9618 { 0, CODE_FOR_paired_sum1
, "__builtin_paired_sum1", PAIRED_BUILTIN_SUM1
},
9619 { 0, CODE_FOR_selv2sf4
, "__builtin_paired_selv2sf4", PAIRED_BUILTIN_SELV2SF4
},
9622 /* DST operations: void foo (void *, const int, const char). */
9624 static const struct builtin_description bdesc_dst
[] =
9626 { MASK_ALTIVEC
, CODE_FOR_altivec_dst
, "__builtin_altivec_dst", ALTIVEC_BUILTIN_DST
},
9627 { MASK_ALTIVEC
, CODE_FOR_altivec_dstt
, "__builtin_altivec_dstt", ALTIVEC_BUILTIN_DSTT
},
9628 { MASK_ALTIVEC
, CODE_FOR_altivec_dstst
, "__builtin_altivec_dstst", ALTIVEC_BUILTIN_DSTST
},
9629 { MASK_ALTIVEC
, CODE_FOR_altivec_dststt
, "__builtin_altivec_dststt", ALTIVEC_BUILTIN_DSTSTT
},
9631 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_dst", ALTIVEC_BUILTIN_VEC_DST
},
9632 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_dstt", ALTIVEC_BUILTIN_VEC_DSTT
},
9633 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_dstst", ALTIVEC_BUILTIN_VEC_DSTST
},
9634 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_dststt", ALTIVEC_BUILTIN_VEC_DSTSTT
}
9637 /* Simple binary operations: VECc = foo (VECa, VECb). */
9639 static struct builtin_description bdesc_2arg
[] =
9641 { MASK_ALTIVEC
, CODE_FOR_addv16qi3
, "__builtin_altivec_vaddubm", ALTIVEC_BUILTIN_VADDUBM
},
9642 { MASK_ALTIVEC
, CODE_FOR_addv8hi3
, "__builtin_altivec_vadduhm", ALTIVEC_BUILTIN_VADDUHM
},
9643 { MASK_ALTIVEC
, CODE_FOR_addv4si3
, "__builtin_altivec_vadduwm", ALTIVEC_BUILTIN_VADDUWM
},
9644 { MASK_ALTIVEC
, CODE_FOR_addv4sf3
, "__builtin_altivec_vaddfp", ALTIVEC_BUILTIN_VADDFP
},
9645 { MASK_ALTIVEC
, CODE_FOR_altivec_vaddcuw
, "__builtin_altivec_vaddcuw", ALTIVEC_BUILTIN_VADDCUW
},
9646 { MASK_ALTIVEC
, CODE_FOR_altivec_vaddubs
, "__builtin_altivec_vaddubs", ALTIVEC_BUILTIN_VADDUBS
},
9647 { MASK_ALTIVEC
, CODE_FOR_altivec_vaddsbs
, "__builtin_altivec_vaddsbs", ALTIVEC_BUILTIN_VADDSBS
},
9648 { MASK_ALTIVEC
, CODE_FOR_altivec_vadduhs
, "__builtin_altivec_vadduhs", ALTIVEC_BUILTIN_VADDUHS
},
9649 { MASK_ALTIVEC
, CODE_FOR_altivec_vaddshs
, "__builtin_altivec_vaddshs", ALTIVEC_BUILTIN_VADDSHS
},
9650 { MASK_ALTIVEC
, CODE_FOR_altivec_vadduws
, "__builtin_altivec_vadduws", ALTIVEC_BUILTIN_VADDUWS
},
9651 { MASK_ALTIVEC
, CODE_FOR_altivec_vaddsws
, "__builtin_altivec_vaddsws", ALTIVEC_BUILTIN_VADDSWS
},
9652 { MASK_ALTIVEC
, CODE_FOR_andv4si3
, "__builtin_altivec_vand", ALTIVEC_BUILTIN_VAND
},
9653 { MASK_ALTIVEC
, CODE_FOR_andcv4si3
, "__builtin_altivec_vandc", ALTIVEC_BUILTIN_VANDC
},
9654 { MASK_ALTIVEC
, CODE_FOR_altivec_vavgub
, "__builtin_altivec_vavgub", ALTIVEC_BUILTIN_VAVGUB
},
9655 { MASK_ALTIVEC
, CODE_FOR_altivec_vavgsb
, "__builtin_altivec_vavgsb", ALTIVEC_BUILTIN_VAVGSB
},
9656 { MASK_ALTIVEC
, CODE_FOR_altivec_vavguh
, "__builtin_altivec_vavguh", ALTIVEC_BUILTIN_VAVGUH
},
9657 { MASK_ALTIVEC
, CODE_FOR_altivec_vavgsh
, "__builtin_altivec_vavgsh", ALTIVEC_BUILTIN_VAVGSH
},
9658 { MASK_ALTIVEC
, CODE_FOR_altivec_vavguw
, "__builtin_altivec_vavguw", ALTIVEC_BUILTIN_VAVGUW
},
9659 { MASK_ALTIVEC
, CODE_FOR_altivec_vavgsw
, "__builtin_altivec_vavgsw", ALTIVEC_BUILTIN_VAVGSW
},
9660 { MASK_ALTIVEC
, CODE_FOR_altivec_vcfux
, "__builtin_altivec_vcfux", ALTIVEC_BUILTIN_VCFUX
},
9661 { MASK_ALTIVEC
, CODE_FOR_altivec_vcfsx
, "__builtin_altivec_vcfsx", ALTIVEC_BUILTIN_VCFSX
},
9662 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpbfp
, "__builtin_altivec_vcmpbfp", ALTIVEC_BUILTIN_VCMPBFP
},
9663 { MASK_ALTIVEC
, CODE_FOR_vector_eqv16qi
, "__builtin_altivec_vcmpequb", ALTIVEC_BUILTIN_VCMPEQUB
},
9664 { MASK_ALTIVEC
, CODE_FOR_vector_eqv8hi
, "__builtin_altivec_vcmpequh", ALTIVEC_BUILTIN_VCMPEQUH
},
9665 { MASK_ALTIVEC
, CODE_FOR_vector_eqv4si
, "__builtin_altivec_vcmpequw", ALTIVEC_BUILTIN_VCMPEQUW
},
9666 { MASK_ALTIVEC
, CODE_FOR_vector_eqv4sf
, "__builtin_altivec_vcmpeqfp", ALTIVEC_BUILTIN_VCMPEQFP
},
9667 { MASK_ALTIVEC
, CODE_FOR_vector_gev4sf
, "__builtin_altivec_vcmpgefp", ALTIVEC_BUILTIN_VCMPGEFP
},
9668 { MASK_ALTIVEC
, CODE_FOR_vector_gtuv16qi
, "__builtin_altivec_vcmpgtub", ALTIVEC_BUILTIN_VCMPGTUB
},
9669 { MASK_ALTIVEC
, CODE_FOR_vector_gtv16qi
, "__builtin_altivec_vcmpgtsb", ALTIVEC_BUILTIN_VCMPGTSB
},
9670 { MASK_ALTIVEC
, CODE_FOR_vector_gtuv8hi
, "__builtin_altivec_vcmpgtuh", ALTIVEC_BUILTIN_VCMPGTUH
},
9671 { MASK_ALTIVEC
, CODE_FOR_vector_gtv8hi
, "__builtin_altivec_vcmpgtsh", ALTIVEC_BUILTIN_VCMPGTSH
},
9672 { MASK_ALTIVEC
, CODE_FOR_vector_gtuv4si
, "__builtin_altivec_vcmpgtuw", ALTIVEC_BUILTIN_VCMPGTUW
},
9673 { MASK_ALTIVEC
, CODE_FOR_vector_gtv4si
, "__builtin_altivec_vcmpgtsw", ALTIVEC_BUILTIN_VCMPGTSW
},
9674 { MASK_ALTIVEC
, CODE_FOR_vector_gtv4sf
, "__builtin_altivec_vcmpgtfp", ALTIVEC_BUILTIN_VCMPGTFP
},
9675 { MASK_ALTIVEC
, CODE_FOR_altivec_vctsxs
, "__builtin_altivec_vctsxs", ALTIVEC_BUILTIN_VCTSXS
},
9676 { MASK_ALTIVEC
, CODE_FOR_altivec_vctuxs
, "__builtin_altivec_vctuxs", ALTIVEC_BUILTIN_VCTUXS
},
9677 { MASK_ALTIVEC
, CODE_FOR_umaxv16qi3
, "__builtin_altivec_vmaxub", ALTIVEC_BUILTIN_VMAXUB
},
9678 { MASK_ALTIVEC
, CODE_FOR_smaxv16qi3
, "__builtin_altivec_vmaxsb", ALTIVEC_BUILTIN_VMAXSB
},
9679 { MASK_ALTIVEC
, CODE_FOR_umaxv8hi3
, "__builtin_altivec_vmaxuh", ALTIVEC_BUILTIN_VMAXUH
},
9680 { MASK_ALTIVEC
, CODE_FOR_smaxv8hi3
, "__builtin_altivec_vmaxsh", ALTIVEC_BUILTIN_VMAXSH
},
9681 { MASK_ALTIVEC
, CODE_FOR_umaxv4si3
, "__builtin_altivec_vmaxuw", ALTIVEC_BUILTIN_VMAXUW
},
9682 { MASK_ALTIVEC
, CODE_FOR_smaxv4si3
, "__builtin_altivec_vmaxsw", ALTIVEC_BUILTIN_VMAXSW
},
9683 { MASK_ALTIVEC
, CODE_FOR_smaxv4sf3
, "__builtin_altivec_vmaxfp", ALTIVEC_BUILTIN_VMAXFP
},
9684 { MASK_ALTIVEC
, CODE_FOR_altivec_vmrghb
, "__builtin_altivec_vmrghb", ALTIVEC_BUILTIN_VMRGHB
},
9685 { MASK_ALTIVEC
, CODE_FOR_altivec_vmrghh
, "__builtin_altivec_vmrghh", ALTIVEC_BUILTIN_VMRGHH
},
9686 { MASK_ALTIVEC
, CODE_FOR_altivec_vmrghw
, "__builtin_altivec_vmrghw", ALTIVEC_BUILTIN_VMRGHW
},
9687 { MASK_ALTIVEC
, CODE_FOR_altivec_vmrglb
, "__builtin_altivec_vmrglb", ALTIVEC_BUILTIN_VMRGLB
},
9688 { MASK_ALTIVEC
, CODE_FOR_altivec_vmrglh
, "__builtin_altivec_vmrglh", ALTIVEC_BUILTIN_VMRGLH
},
9689 { MASK_ALTIVEC
, CODE_FOR_altivec_vmrglw
, "__builtin_altivec_vmrglw", ALTIVEC_BUILTIN_VMRGLW
},
9690 { MASK_ALTIVEC
, CODE_FOR_uminv16qi3
, "__builtin_altivec_vminub", ALTIVEC_BUILTIN_VMINUB
},
9691 { MASK_ALTIVEC
, CODE_FOR_sminv16qi3
, "__builtin_altivec_vminsb", ALTIVEC_BUILTIN_VMINSB
},
9692 { MASK_ALTIVEC
, CODE_FOR_uminv8hi3
, "__builtin_altivec_vminuh", ALTIVEC_BUILTIN_VMINUH
},
9693 { MASK_ALTIVEC
, CODE_FOR_sminv8hi3
, "__builtin_altivec_vminsh", ALTIVEC_BUILTIN_VMINSH
},
9694 { MASK_ALTIVEC
, CODE_FOR_uminv4si3
, "__builtin_altivec_vminuw", ALTIVEC_BUILTIN_VMINUW
},
9695 { MASK_ALTIVEC
, CODE_FOR_sminv4si3
, "__builtin_altivec_vminsw", ALTIVEC_BUILTIN_VMINSW
},
9696 { MASK_ALTIVEC
, CODE_FOR_sminv4sf3
, "__builtin_altivec_vminfp", ALTIVEC_BUILTIN_VMINFP
},
9697 { MASK_ALTIVEC
, CODE_FOR_altivec_vmuleub
, "__builtin_altivec_vmuleub", ALTIVEC_BUILTIN_VMULEUB
},
9698 { MASK_ALTIVEC
, CODE_FOR_altivec_vmuleub
, "__builtin_altivec_vmuleub_uns", ALTIVEC_BUILTIN_VMULEUB_UNS
},
9699 { MASK_ALTIVEC
, CODE_FOR_altivec_vmulesb
, "__builtin_altivec_vmulesb", ALTIVEC_BUILTIN_VMULESB
},
9700 { MASK_ALTIVEC
, CODE_FOR_altivec_vmuleuh
, "__builtin_altivec_vmuleuh", ALTIVEC_BUILTIN_VMULEUH
},
9701 { MASK_ALTIVEC
, CODE_FOR_altivec_vmuleuh
, "__builtin_altivec_vmuleuh_uns", ALTIVEC_BUILTIN_VMULEUH_UNS
},
9702 { MASK_ALTIVEC
, CODE_FOR_altivec_vmulesh
, "__builtin_altivec_vmulesh", ALTIVEC_BUILTIN_VMULESH
},
9703 { MASK_ALTIVEC
, CODE_FOR_altivec_vmuloub
, "__builtin_altivec_vmuloub", ALTIVEC_BUILTIN_VMULOUB
},
9704 { MASK_ALTIVEC
, CODE_FOR_altivec_vmuloub
, "__builtin_altivec_vmuloub_uns", ALTIVEC_BUILTIN_VMULOUB_UNS
},
9705 { MASK_ALTIVEC
, CODE_FOR_altivec_vmulosb
, "__builtin_altivec_vmulosb", ALTIVEC_BUILTIN_VMULOSB
},
9706 { MASK_ALTIVEC
, CODE_FOR_altivec_vmulouh
, "__builtin_altivec_vmulouh", ALTIVEC_BUILTIN_VMULOUH
},
9707 { MASK_ALTIVEC
, CODE_FOR_altivec_vmulouh
, "__builtin_altivec_vmulouh_uns", ALTIVEC_BUILTIN_VMULOUH_UNS
},
9708 { MASK_ALTIVEC
, CODE_FOR_altivec_vmulosh
, "__builtin_altivec_vmulosh", ALTIVEC_BUILTIN_VMULOSH
},
9709 { MASK_ALTIVEC
, CODE_FOR_norv4si3
, "__builtin_altivec_vnor", ALTIVEC_BUILTIN_VNOR
},
9710 { MASK_ALTIVEC
, CODE_FOR_iorv4si3
, "__builtin_altivec_vor", ALTIVEC_BUILTIN_VOR
},
9711 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkuhum
, "__builtin_altivec_vpkuhum", ALTIVEC_BUILTIN_VPKUHUM
},
9712 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkuwum
, "__builtin_altivec_vpkuwum", ALTIVEC_BUILTIN_VPKUWUM
},
9713 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkpx
, "__builtin_altivec_vpkpx", ALTIVEC_BUILTIN_VPKPX
},
9714 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkshss
, "__builtin_altivec_vpkshss", ALTIVEC_BUILTIN_VPKSHSS
},
9715 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkswss
, "__builtin_altivec_vpkswss", ALTIVEC_BUILTIN_VPKSWSS
},
9716 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkuhus
, "__builtin_altivec_vpkuhus", ALTIVEC_BUILTIN_VPKUHUS
},
9717 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkshus
, "__builtin_altivec_vpkshus", ALTIVEC_BUILTIN_VPKSHUS
},
9718 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkuwus
, "__builtin_altivec_vpkuwus", ALTIVEC_BUILTIN_VPKUWUS
},
9719 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkswus
, "__builtin_altivec_vpkswus", ALTIVEC_BUILTIN_VPKSWUS
},
9720 { MASK_ALTIVEC
, CODE_FOR_recipv4sf3
, "__builtin_altivec_vrecipdivfp", ALTIVEC_BUILTIN_VRECIPFP
},
9721 { MASK_ALTIVEC
, CODE_FOR_vrotlv16qi3
, "__builtin_altivec_vrlb", ALTIVEC_BUILTIN_VRLB
},
9722 { MASK_ALTIVEC
, CODE_FOR_vrotlv8hi3
, "__builtin_altivec_vrlh", ALTIVEC_BUILTIN_VRLH
},
9723 { MASK_ALTIVEC
, CODE_FOR_vrotlv4si3
, "__builtin_altivec_vrlw", ALTIVEC_BUILTIN_VRLW
},
9724 { MASK_ALTIVEC
, CODE_FOR_vashlv16qi3
, "__builtin_altivec_vslb", ALTIVEC_BUILTIN_VSLB
},
9725 { MASK_ALTIVEC
, CODE_FOR_vashlv8hi3
, "__builtin_altivec_vslh", ALTIVEC_BUILTIN_VSLH
},
9726 { MASK_ALTIVEC
, CODE_FOR_vashlv4si3
, "__builtin_altivec_vslw", ALTIVEC_BUILTIN_VSLW
},
9727 { MASK_ALTIVEC
, CODE_FOR_altivec_vsl
, "__builtin_altivec_vsl", ALTIVEC_BUILTIN_VSL
},
9728 { MASK_ALTIVEC
, CODE_FOR_altivec_vslo
, "__builtin_altivec_vslo", ALTIVEC_BUILTIN_VSLO
},
9729 { MASK_ALTIVEC
, CODE_FOR_altivec_vspltb
, "__builtin_altivec_vspltb", ALTIVEC_BUILTIN_VSPLTB
},
9730 { MASK_ALTIVEC
, CODE_FOR_altivec_vsplth
, "__builtin_altivec_vsplth", ALTIVEC_BUILTIN_VSPLTH
},
9731 { MASK_ALTIVEC
, CODE_FOR_altivec_vspltw
, "__builtin_altivec_vspltw", ALTIVEC_BUILTIN_VSPLTW
},
9732 { MASK_ALTIVEC
, CODE_FOR_vlshrv16qi3
, "__builtin_altivec_vsrb", ALTIVEC_BUILTIN_VSRB
},
9733 { MASK_ALTIVEC
, CODE_FOR_vlshrv8hi3
, "__builtin_altivec_vsrh", ALTIVEC_BUILTIN_VSRH
},
9734 { MASK_ALTIVEC
, CODE_FOR_vlshrv4si3
, "__builtin_altivec_vsrw", ALTIVEC_BUILTIN_VSRW
},
9735 { MASK_ALTIVEC
, CODE_FOR_vashrv16qi3
, "__builtin_altivec_vsrab", ALTIVEC_BUILTIN_VSRAB
},
9736 { MASK_ALTIVEC
, CODE_FOR_vashrv8hi3
, "__builtin_altivec_vsrah", ALTIVEC_BUILTIN_VSRAH
},
9737 { MASK_ALTIVEC
, CODE_FOR_vashrv4si3
, "__builtin_altivec_vsraw", ALTIVEC_BUILTIN_VSRAW
},
9738 { MASK_ALTIVEC
, CODE_FOR_altivec_vsr
, "__builtin_altivec_vsr", ALTIVEC_BUILTIN_VSR
},
9739 { MASK_ALTIVEC
, CODE_FOR_altivec_vsro
, "__builtin_altivec_vsro", ALTIVEC_BUILTIN_VSRO
},
9740 { MASK_ALTIVEC
, CODE_FOR_subv16qi3
, "__builtin_altivec_vsububm", ALTIVEC_BUILTIN_VSUBUBM
},
9741 { MASK_ALTIVEC
, CODE_FOR_subv8hi3
, "__builtin_altivec_vsubuhm", ALTIVEC_BUILTIN_VSUBUHM
},
9742 { MASK_ALTIVEC
, CODE_FOR_subv4si3
, "__builtin_altivec_vsubuwm", ALTIVEC_BUILTIN_VSUBUWM
},
9743 { MASK_ALTIVEC
, CODE_FOR_subv4sf3
, "__builtin_altivec_vsubfp", ALTIVEC_BUILTIN_VSUBFP
},
9744 { MASK_ALTIVEC
, CODE_FOR_altivec_vsubcuw
, "__builtin_altivec_vsubcuw", ALTIVEC_BUILTIN_VSUBCUW
},
9745 { MASK_ALTIVEC
, CODE_FOR_altivec_vsububs
, "__builtin_altivec_vsububs", ALTIVEC_BUILTIN_VSUBUBS
},
9746 { MASK_ALTIVEC
, CODE_FOR_altivec_vsubsbs
, "__builtin_altivec_vsubsbs", ALTIVEC_BUILTIN_VSUBSBS
},
9747 { MASK_ALTIVEC
, CODE_FOR_altivec_vsubuhs
, "__builtin_altivec_vsubuhs", ALTIVEC_BUILTIN_VSUBUHS
},
9748 { MASK_ALTIVEC
, CODE_FOR_altivec_vsubshs
, "__builtin_altivec_vsubshs", ALTIVEC_BUILTIN_VSUBSHS
},
9749 { MASK_ALTIVEC
, CODE_FOR_altivec_vsubuws
, "__builtin_altivec_vsubuws", ALTIVEC_BUILTIN_VSUBUWS
},
9750 { MASK_ALTIVEC
, CODE_FOR_altivec_vsubsws
, "__builtin_altivec_vsubsws", ALTIVEC_BUILTIN_VSUBSWS
},
9751 { MASK_ALTIVEC
, CODE_FOR_altivec_vsum4ubs
, "__builtin_altivec_vsum4ubs", ALTIVEC_BUILTIN_VSUM4UBS
},
9752 { MASK_ALTIVEC
, CODE_FOR_altivec_vsum4sbs
, "__builtin_altivec_vsum4sbs", ALTIVEC_BUILTIN_VSUM4SBS
},
9753 { MASK_ALTIVEC
, CODE_FOR_altivec_vsum4shs
, "__builtin_altivec_vsum4shs", ALTIVEC_BUILTIN_VSUM4SHS
},
9754 { MASK_ALTIVEC
, CODE_FOR_altivec_vsum2sws
, "__builtin_altivec_vsum2sws", ALTIVEC_BUILTIN_VSUM2SWS
},
9755 { MASK_ALTIVEC
, CODE_FOR_altivec_vsumsws
, "__builtin_altivec_vsumsws", ALTIVEC_BUILTIN_VSUMSWS
},
9756 { MASK_ALTIVEC
, CODE_FOR_xorv4si3
, "__builtin_altivec_vxor", ALTIVEC_BUILTIN_VXOR
},
9757 { MASK_ALTIVEC
, CODE_FOR_vector_copysignv4sf3
, "__builtin_altivec_copysignfp", ALTIVEC_BUILTIN_COPYSIGN_V4SF
},
9759 { MASK_VSX
, CODE_FOR_addv2df3
, "__builtin_vsx_xvadddp", VSX_BUILTIN_XVADDDP
},
9760 { MASK_VSX
, CODE_FOR_subv2df3
, "__builtin_vsx_xvsubdp", VSX_BUILTIN_XVSUBDP
},
9761 { MASK_VSX
, CODE_FOR_mulv2df3
, "__builtin_vsx_xvmuldp", VSX_BUILTIN_XVMULDP
},
9762 { MASK_VSX
, CODE_FOR_divv2df3
, "__builtin_vsx_xvdivdp", VSX_BUILTIN_XVDIVDP
},
9763 { MASK_VSX
, CODE_FOR_recipv2df3
, "__builtin_vsx_xvrecipdivdp", VSX_BUILTIN_RECIP_V2DF
},
9764 { MASK_VSX
, CODE_FOR_sminv2df3
, "__builtin_vsx_xvmindp", VSX_BUILTIN_XVMINDP
},
9765 { MASK_VSX
, CODE_FOR_smaxv2df3
, "__builtin_vsx_xvmaxdp", VSX_BUILTIN_XVMAXDP
},
9766 { MASK_VSX
, CODE_FOR_vsx_tdivv2df3_fe
, "__builtin_vsx_xvtdivdp_fe", VSX_BUILTIN_XVTDIVDP_FE
},
9767 { MASK_VSX
, CODE_FOR_vsx_tdivv2df3_fg
, "__builtin_vsx_xvtdivdp_fg", VSX_BUILTIN_XVTDIVDP_FG
},
9768 { MASK_VSX
, CODE_FOR_vector_eqv2df
, "__builtin_vsx_xvcmpeqdp", VSX_BUILTIN_XVCMPEQDP
},
9769 { MASK_VSX
, CODE_FOR_vector_gtv2df
, "__builtin_vsx_xvcmpgtdp", VSX_BUILTIN_XVCMPGTDP
},
9770 { MASK_VSX
, CODE_FOR_vector_gev2df
, "__builtin_vsx_xvcmpgedp", VSX_BUILTIN_XVCMPGEDP
},
9772 { MASK_VSX
, CODE_FOR_addv4sf3
, "__builtin_vsx_xvaddsp", VSX_BUILTIN_XVADDSP
},
9773 { MASK_VSX
, CODE_FOR_subv4sf3
, "__builtin_vsx_xvsubsp", VSX_BUILTIN_XVSUBSP
},
9774 { MASK_VSX
, CODE_FOR_mulv4sf3
, "__builtin_vsx_xvmulsp", VSX_BUILTIN_XVMULSP
},
9775 { MASK_VSX
, CODE_FOR_divv4sf3
, "__builtin_vsx_xvdivsp", VSX_BUILTIN_XVDIVSP
},
9776 { MASK_VSX
, CODE_FOR_recipv4sf3
, "__builtin_vsx_xvrecipdivsp", VSX_BUILTIN_RECIP_V4SF
},
9777 { MASK_VSX
, CODE_FOR_sminv4sf3
, "__builtin_vsx_xvminsp", VSX_BUILTIN_XVMINSP
},
9778 { MASK_VSX
, CODE_FOR_smaxv4sf3
, "__builtin_vsx_xvmaxsp", VSX_BUILTIN_XVMAXSP
},
9779 { MASK_VSX
, CODE_FOR_vsx_tdivv4sf3_fe
, "__builtin_vsx_xvtdivsp_fe", VSX_BUILTIN_XVTDIVSP_FE
},
9780 { MASK_VSX
, CODE_FOR_vsx_tdivv4sf3_fg
, "__builtin_vsx_xvtdivsp_fg", VSX_BUILTIN_XVTDIVSP_FG
},
9781 { MASK_VSX
, CODE_FOR_vector_eqv4sf
, "__builtin_vsx_xvcmpeqsp", VSX_BUILTIN_XVCMPEQSP
},
9782 { MASK_VSX
, CODE_FOR_vector_gtv4sf
, "__builtin_vsx_xvcmpgtsp", VSX_BUILTIN_XVCMPGTSP
},
9783 { MASK_VSX
, CODE_FOR_vector_gev4sf
, "__builtin_vsx_xvcmpgesp", VSX_BUILTIN_XVCMPGESP
},
9785 { MASK_VSX
, CODE_FOR_smindf3
, "__builtin_vsx_xsmindp", VSX_BUILTIN_XSMINDP
},
9786 { MASK_VSX
, CODE_FOR_smaxdf3
, "__builtin_vsx_xsmaxdp", VSX_BUILTIN_XSMAXDP
},
9787 { MASK_VSX
, CODE_FOR_vsx_tdivdf3_fe
, "__builtin_vsx_xstdivdp_fe", VSX_BUILTIN_XSTDIVDP_FE
},
9788 { MASK_VSX
, CODE_FOR_vsx_tdivdf3_fg
, "__builtin_vsx_xstdivdp_fg", VSX_BUILTIN_XSTDIVDP_FG
},
9789 { MASK_VSX
, CODE_FOR_vector_copysignv2df3
, "__builtin_vsx_cpsgndp", VSX_BUILTIN_CPSGNDP
},
9790 { MASK_VSX
, CODE_FOR_vector_copysignv4sf3
, "__builtin_vsx_cpsgnsp", VSX_BUILTIN_CPSGNSP
},
9792 { MASK_VSX
, CODE_FOR_vsx_concat_v2df
, "__builtin_vsx_concat_2df", VSX_BUILTIN_CONCAT_2DF
},
9793 { MASK_VSX
, CODE_FOR_vsx_concat_v2di
, "__builtin_vsx_concat_2di", VSX_BUILTIN_CONCAT_2DI
},
9794 { MASK_VSX
, CODE_FOR_vsx_splat_v2df
, "__builtin_vsx_splat_2df", VSX_BUILTIN_SPLAT_2DF
},
9795 { MASK_VSX
, CODE_FOR_vsx_splat_v2di
, "__builtin_vsx_splat_2di", VSX_BUILTIN_SPLAT_2DI
},
9796 { MASK_VSX
, CODE_FOR_vsx_xxmrghw_v4sf
, "__builtin_vsx_xxmrghw", VSX_BUILTIN_XXMRGHW_4SF
},
9797 { MASK_VSX
, CODE_FOR_vsx_xxmrghw_v4si
, "__builtin_vsx_xxmrghw_4si", VSX_BUILTIN_XXMRGHW_4SI
},
9798 { MASK_VSX
, CODE_FOR_vsx_xxmrglw_v4sf
, "__builtin_vsx_xxmrglw", VSX_BUILTIN_XXMRGLW_4SF
},
9799 { MASK_VSX
, CODE_FOR_vsx_xxmrglw_v4si
, "__builtin_vsx_xxmrglw_4si", VSX_BUILTIN_XXMRGLW_4SI
},
9800 { MASK_VSX
, CODE_FOR_vec_interleave_lowv2df
, "__builtin_vsx_mergel_2df", VSX_BUILTIN_VEC_MERGEL_V2DF
},
9801 { MASK_VSX
, CODE_FOR_vec_interleave_lowv2di
, "__builtin_vsx_mergel_2di", VSX_BUILTIN_VEC_MERGEL_V2DI
},
9802 { MASK_VSX
, CODE_FOR_vec_interleave_highv2df
, "__builtin_vsx_mergeh_2df", VSX_BUILTIN_VEC_MERGEH_V2DF
},
9803 { MASK_VSX
, CODE_FOR_vec_interleave_highv2di
, "__builtin_vsx_mergeh_2di", VSX_BUILTIN_VEC_MERGEH_V2DI
},
9805 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_add", ALTIVEC_BUILTIN_VEC_ADD
},
9806 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_vaddfp", ALTIVEC_BUILTIN_VEC_VADDFP
},
9807 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vadduwm", ALTIVEC_BUILTIN_VEC_VADDUWM
},
9808 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vadduhm", ALTIVEC_BUILTIN_VEC_VADDUHM
},
9809 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vaddubm", ALTIVEC_BUILTIN_VEC_VADDUBM
},
9810 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_addc", ALTIVEC_BUILTIN_VEC_ADDC
},
9811 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_adds", ALTIVEC_BUILTIN_VEC_ADDS
},
9812 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vaddsws", ALTIVEC_BUILTIN_VEC_VADDSWS
},
9813 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vadduws", ALTIVEC_BUILTIN_VEC_VADDUWS
},
9814 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vaddshs", ALTIVEC_BUILTIN_VEC_VADDSHS
},
9815 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vadduhs", ALTIVEC_BUILTIN_VEC_VADDUHS
},
9816 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vaddsbs", ALTIVEC_BUILTIN_VEC_VADDSBS
},
9817 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vaddubs", ALTIVEC_BUILTIN_VEC_VADDUBS
},
9818 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_and", ALTIVEC_BUILTIN_VEC_AND
},
9819 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_andc", ALTIVEC_BUILTIN_VEC_ANDC
},
9820 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_avg", ALTIVEC_BUILTIN_VEC_AVG
},
9821 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vavgsw", ALTIVEC_BUILTIN_VEC_VAVGSW
},
9822 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vavguw", ALTIVEC_BUILTIN_VEC_VAVGUW
},
9823 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vavgsh", ALTIVEC_BUILTIN_VEC_VAVGSH
},
9824 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vavguh", ALTIVEC_BUILTIN_VEC_VAVGUH
},
9825 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vavgsb", ALTIVEC_BUILTIN_VEC_VAVGSB
},
9826 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vavgub", ALTIVEC_BUILTIN_VEC_VAVGUB
},
9827 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_cmpb", ALTIVEC_BUILTIN_VEC_CMPB
},
9828 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_cmpeq", ALTIVEC_BUILTIN_VEC_CMPEQ
},
9829 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpeqfp", ALTIVEC_BUILTIN_VEC_VCMPEQFP
},
9830 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpequw", ALTIVEC_BUILTIN_VEC_VCMPEQUW
},
9831 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpequh", ALTIVEC_BUILTIN_VEC_VCMPEQUH
},
9832 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpequb", ALTIVEC_BUILTIN_VEC_VCMPEQUB
},
9833 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_cmpge", ALTIVEC_BUILTIN_VEC_CMPGE
},
9834 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_cmpgt", ALTIVEC_BUILTIN_VEC_CMPGT
},
9835 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpgtfp", ALTIVEC_BUILTIN_VEC_VCMPGTFP
},
9836 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpgtsw", ALTIVEC_BUILTIN_VEC_VCMPGTSW
},
9837 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpgtuw", ALTIVEC_BUILTIN_VEC_VCMPGTUW
},
9838 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpgtsh", ALTIVEC_BUILTIN_VEC_VCMPGTSH
},
9839 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpgtuh", ALTIVEC_BUILTIN_VEC_VCMPGTUH
},
9840 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpgtsb", ALTIVEC_BUILTIN_VEC_VCMPGTSB
},
9841 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpgtub", ALTIVEC_BUILTIN_VEC_VCMPGTUB
},
9842 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_cmple", ALTIVEC_BUILTIN_VEC_CMPLE
},
9843 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_cmplt", ALTIVEC_BUILTIN_VEC_CMPLT
},
9844 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_copysign", ALTIVEC_BUILTIN_VEC_COPYSIGN
},
9845 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_max", ALTIVEC_BUILTIN_VEC_MAX
},
9846 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_vmaxfp", ALTIVEC_BUILTIN_VEC_VMAXFP
},
9847 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmaxsw", ALTIVEC_BUILTIN_VEC_VMAXSW
},
9848 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmaxuw", ALTIVEC_BUILTIN_VEC_VMAXUW
},
9849 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmaxsh", ALTIVEC_BUILTIN_VEC_VMAXSH
},
9850 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmaxuh", ALTIVEC_BUILTIN_VEC_VMAXUH
},
9851 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmaxsb", ALTIVEC_BUILTIN_VEC_VMAXSB
},
9852 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmaxub", ALTIVEC_BUILTIN_VEC_VMAXUB
},
9853 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_mergeh", ALTIVEC_BUILTIN_VEC_MERGEH
},
9854 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmrghw", ALTIVEC_BUILTIN_VEC_VMRGHW
},
9855 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmrghh", ALTIVEC_BUILTIN_VEC_VMRGHH
},
9856 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmrghb", ALTIVEC_BUILTIN_VEC_VMRGHB
},
9857 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_mergel", ALTIVEC_BUILTIN_VEC_MERGEL
},
9858 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmrglw", ALTIVEC_BUILTIN_VEC_VMRGLW
},
9859 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmrglh", ALTIVEC_BUILTIN_VEC_VMRGLH
},
9860 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmrglb", ALTIVEC_BUILTIN_VEC_VMRGLB
},
9861 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_min", ALTIVEC_BUILTIN_VEC_MIN
},
9862 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_vminfp", ALTIVEC_BUILTIN_VEC_VMINFP
},
9863 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vminsw", ALTIVEC_BUILTIN_VEC_VMINSW
},
9864 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vminuw", ALTIVEC_BUILTIN_VEC_VMINUW
},
9865 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vminsh", ALTIVEC_BUILTIN_VEC_VMINSH
},
9866 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vminuh", ALTIVEC_BUILTIN_VEC_VMINUH
},
9867 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vminsb", ALTIVEC_BUILTIN_VEC_VMINSB
},
9868 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vminub", ALTIVEC_BUILTIN_VEC_VMINUB
},
9869 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_mule", ALTIVEC_BUILTIN_VEC_MULE
},
9870 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmuleub", ALTIVEC_BUILTIN_VEC_VMULEUB
},
9871 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmulesb", ALTIVEC_BUILTIN_VEC_VMULESB
},
9872 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmuleuh", ALTIVEC_BUILTIN_VEC_VMULEUH
},
9873 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmulesh", ALTIVEC_BUILTIN_VEC_VMULESH
},
9874 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_mulo", ALTIVEC_BUILTIN_VEC_MULO
},
9875 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmulosh", ALTIVEC_BUILTIN_VEC_VMULOSH
},
9876 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmulouh", ALTIVEC_BUILTIN_VEC_VMULOUH
},
9877 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmulosb", ALTIVEC_BUILTIN_VEC_VMULOSB
},
9878 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmuloub", ALTIVEC_BUILTIN_VEC_VMULOUB
},
9879 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_nor", ALTIVEC_BUILTIN_VEC_NOR
},
9880 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_or", ALTIVEC_BUILTIN_VEC_OR
},
9881 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_pack", ALTIVEC_BUILTIN_VEC_PACK
},
9882 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkuwum", ALTIVEC_BUILTIN_VEC_VPKUWUM
},
9883 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkuhum", ALTIVEC_BUILTIN_VEC_VPKUHUM
},
9884 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_packpx", ALTIVEC_BUILTIN_VEC_PACKPX
},
9885 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_packs", ALTIVEC_BUILTIN_VEC_PACKS
},
9886 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkswss", ALTIVEC_BUILTIN_VEC_VPKSWSS
},
9887 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkuwus", ALTIVEC_BUILTIN_VEC_VPKUWUS
},
9888 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkshss", ALTIVEC_BUILTIN_VEC_VPKSHSS
},
9889 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkuhus", ALTIVEC_BUILTIN_VEC_VPKUHUS
},
9890 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_packsu", ALTIVEC_BUILTIN_VEC_PACKSU
},
9891 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkswus", ALTIVEC_BUILTIN_VEC_VPKSWUS
},
9892 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkshus", ALTIVEC_BUILTIN_VEC_VPKSHUS
},
9893 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_recipdiv", ALTIVEC_BUILTIN_VEC_RECIP
},
9894 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_rl", ALTIVEC_BUILTIN_VEC_RL
},
9895 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vrlw", ALTIVEC_BUILTIN_VEC_VRLW
},
9896 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vrlh", ALTIVEC_BUILTIN_VEC_VRLH
},
9897 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vrlb", ALTIVEC_BUILTIN_VEC_VRLB
},
9898 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sl", ALTIVEC_BUILTIN_VEC_SL
},
9899 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vslw", ALTIVEC_BUILTIN_VEC_VSLW
},
9900 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vslh", ALTIVEC_BUILTIN_VEC_VSLH
},
9901 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vslb", ALTIVEC_BUILTIN_VEC_VSLB
},
9902 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sll", ALTIVEC_BUILTIN_VEC_SLL
},
9903 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_slo", ALTIVEC_BUILTIN_VEC_SLO
},
9904 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sr", ALTIVEC_BUILTIN_VEC_SR
},
9905 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsrw", ALTIVEC_BUILTIN_VEC_VSRW
},
9906 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsrh", ALTIVEC_BUILTIN_VEC_VSRH
},
9907 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsrb", ALTIVEC_BUILTIN_VEC_VSRB
},
9908 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sra", ALTIVEC_BUILTIN_VEC_SRA
},
9909 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsraw", ALTIVEC_BUILTIN_VEC_VSRAW
},
9910 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsrah", ALTIVEC_BUILTIN_VEC_VSRAH
},
9911 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsrab", ALTIVEC_BUILTIN_VEC_VSRAB
},
9912 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_srl", ALTIVEC_BUILTIN_VEC_SRL
},
9913 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sro", ALTIVEC_BUILTIN_VEC_SRO
},
9914 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_sub", ALTIVEC_BUILTIN_VEC_SUB
},
9915 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_vsubfp", ALTIVEC_BUILTIN_VEC_VSUBFP
},
9916 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubuwm", ALTIVEC_BUILTIN_VEC_VSUBUWM
},
9917 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubuhm", ALTIVEC_BUILTIN_VEC_VSUBUHM
},
9918 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsububm", ALTIVEC_BUILTIN_VEC_VSUBUBM
},
9919 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_subc", ALTIVEC_BUILTIN_VEC_SUBC
},
9920 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_subs", ALTIVEC_BUILTIN_VEC_SUBS
},
9921 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubsws", ALTIVEC_BUILTIN_VEC_VSUBSWS
},
9922 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubuws", ALTIVEC_BUILTIN_VEC_VSUBUWS
},
9923 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubshs", ALTIVEC_BUILTIN_VEC_VSUBSHS
},
9924 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubuhs", ALTIVEC_BUILTIN_VEC_VSUBUHS
},
9925 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubsbs", ALTIVEC_BUILTIN_VEC_VSUBSBS
},
9926 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsububs", ALTIVEC_BUILTIN_VEC_VSUBUBS
},
9927 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sum4s", ALTIVEC_BUILTIN_VEC_SUM4S
},
9928 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsum4shs", ALTIVEC_BUILTIN_VEC_VSUM4SHS
},
9929 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsum4sbs", ALTIVEC_BUILTIN_VEC_VSUM4SBS
},
9930 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsum4ubs", ALTIVEC_BUILTIN_VEC_VSUM4UBS
},
9931 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sum2s", ALTIVEC_BUILTIN_VEC_SUM2S
},
9932 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sums", ALTIVEC_BUILTIN_VEC_SUMS
},
9933 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_xor", ALTIVEC_BUILTIN_VEC_XOR
},
9935 { MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_mul", VSX_BUILTIN_VEC_MUL
},
9936 { MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_div", VSX_BUILTIN_VEC_DIV
},
9938 { 0, CODE_FOR_paired_divv2sf3
, "__builtin_paired_divv2sf3", PAIRED_BUILTIN_DIVV2SF3
},
9939 { 0, CODE_FOR_paired_addv2sf3
, "__builtin_paired_addv2sf3", PAIRED_BUILTIN_ADDV2SF3
},
9940 { 0, CODE_FOR_paired_subv2sf3
, "__builtin_paired_subv2sf3", PAIRED_BUILTIN_SUBV2SF3
},
9941 { 0, CODE_FOR_paired_mulv2sf3
, "__builtin_paired_mulv2sf3", PAIRED_BUILTIN_MULV2SF3
},
9942 { 0, CODE_FOR_paired_muls0
, "__builtin_paired_muls0", PAIRED_BUILTIN_MULS0
},
9943 { 0, CODE_FOR_paired_muls1
, "__builtin_paired_muls1", PAIRED_BUILTIN_MULS1
},
9944 { 0, CODE_FOR_paired_merge00
, "__builtin_paired_merge00", PAIRED_BUILTIN_MERGE00
},
9945 { 0, CODE_FOR_paired_merge01
, "__builtin_paired_merge01", PAIRED_BUILTIN_MERGE01
},
9946 { 0, CODE_FOR_paired_merge10
, "__builtin_paired_merge10", PAIRED_BUILTIN_MERGE10
},
9947 { 0, CODE_FOR_paired_merge11
, "__builtin_paired_merge11", PAIRED_BUILTIN_MERGE11
},
9949 /* Place holder, leave as first spe builtin. */
9950 { 0, CODE_FOR_addv2si3
, "__builtin_spe_evaddw", SPE_BUILTIN_EVADDW
},
9951 { 0, CODE_FOR_andv2si3
, "__builtin_spe_evand", SPE_BUILTIN_EVAND
},
9952 { 0, CODE_FOR_spe_evandc
, "__builtin_spe_evandc", SPE_BUILTIN_EVANDC
},
9953 { 0, CODE_FOR_divv2si3
, "__builtin_spe_evdivws", SPE_BUILTIN_EVDIVWS
},
9954 { 0, CODE_FOR_spe_evdivwu
, "__builtin_spe_evdivwu", SPE_BUILTIN_EVDIVWU
},
9955 { 0, CODE_FOR_spe_eveqv
, "__builtin_spe_eveqv", SPE_BUILTIN_EVEQV
},
9956 { 0, CODE_FOR_spe_evfsadd
, "__builtin_spe_evfsadd", SPE_BUILTIN_EVFSADD
},
9957 { 0, CODE_FOR_spe_evfsdiv
, "__builtin_spe_evfsdiv", SPE_BUILTIN_EVFSDIV
},
9958 { 0, CODE_FOR_spe_evfsmul
, "__builtin_spe_evfsmul", SPE_BUILTIN_EVFSMUL
},
9959 { 0, CODE_FOR_spe_evfssub
, "__builtin_spe_evfssub", SPE_BUILTIN_EVFSSUB
},
9960 { 0, CODE_FOR_spe_evmergehi
, "__builtin_spe_evmergehi", SPE_BUILTIN_EVMERGEHI
},
9961 { 0, CODE_FOR_spe_evmergehilo
, "__builtin_spe_evmergehilo", SPE_BUILTIN_EVMERGEHILO
},
9962 { 0, CODE_FOR_spe_evmergelo
, "__builtin_spe_evmergelo", SPE_BUILTIN_EVMERGELO
},
9963 { 0, CODE_FOR_spe_evmergelohi
, "__builtin_spe_evmergelohi", SPE_BUILTIN_EVMERGELOHI
},
9964 { 0, CODE_FOR_spe_evmhegsmfaa
, "__builtin_spe_evmhegsmfaa", SPE_BUILTIN_EVMHEGSMFAA
},
9965 { 0, CODE_FOR_spe_evmhegsmfan
, "__builtin_spe_evmhegsmfan", SPE_BUILTIN_EVMHEGSMFAN
},
9966 { 0, CODE_FOR_spe_evmhegsmiaa
, "__builtin_spe_evmhegsmiaa", SPE_BUILTIN_EVMHEGSMIAA
},
9967 { 0, CODE_FOR_spe_evmhegsmian
, "__builtin_spe_evmhegsmian", SPE_BUILTIN_EVMHEGSMIAN
},
9968 { 0, CODE_FOR_spe_evmhegumiaa
, "__builtin_spe_evmhegumiaa", SPE_BUILTIN_EVMHEGUMIAA
},
9969 { 0, CODE_FOR_spe_evmhegumian
, "__builtin_spe_evmhegumian", SPE_BUILTIN_EVMHEGUMIAN
},
9970 { 0, CODE_FOR_spe_evmhesmf
, "__builtin_spe_evmhesmf", SPE_BUILTIN_EVMHESMF
},
9971 { 0, CODE_FOR_spe_evmhesmfa
, "__builtin_spe_evmhesmfa", SPE_BUILTIN_EVMHESMFA
},
9972 { 0, CODE_FOR_spe_evmhesmfaaw
, "__builtin_spe_evmhesmfaaw", SPE_BUILTIN_EVMHESMFAAW
},
9973 { 0, CODE_FOR_spe_evmhesmfanw
, "__builtin_spe_evmhesmfanw", SPE_BUILTIN_EVMHESMFANW
},
9974 { 0, CODE_FOR_spe_evmhesmi
, "__builtin_spe_evmhesmi", SPE_BUILTIN_EVMHESMI
},
9975 { 0, CODE_FOR_spe_evmhesmia
, "__builtin_spe_evmhesmia", SPE_BUILTIN_EVMHESMIA
},
9976 { 0, CODE_FOR_spe_evmhesmiaaw
, "__builtin_spe_evmhesmiaaw", SPE_BUILTIN_EVMHESMIAAW
},
9977 { 0, CODE_FOR_spe_evmhesmianw
, "__builtin_spe_evmhesmianw", SPE_BUILTIN_EVMHESMIANW
},
9978 { 0, CODE_FOR_spe_evmhessf
, "__builtin_spe_evmhessf", SPE_BUILTIN_EVMHESSF
},
9979 { 0, CODE_FOR_spe_evmhessfa
, "__builtin_spe_evmhessfa", SPE_BUILTIN_EVMHESSFA
},
9980 { 0, CODE_FOR_spe_evmhessfaaw
, "__builtin_spe_evmhessfaaw", SPE_BUILTIN_EVMHESSFAAW
},
9981 { 0, CODE_FOR_spe_evmhessfanw
, "__builtin_spe_evmhessfanw", SPE_BUILTIN_EVMHESSFANW
},
9982 { 0, CODE_FOR_spe_evmhessiaaw
, "__builtin_spe_evmhessiaaw", SPE_BUILTIN_EVMHESSIAAW
},
9983 { 0, CODE_FOR_spe_evmhessianw
, "__builtin_spe_evmhessianw", SPE_BUILTIN_EVMHESSIANW
},
9984 { 0, CODE_FOR_spe_evmheumi
, "__builtin_spe_evmheumi", SPE_BUILTIN_EVMHEUMI
},
9985 { 0, CODE_FOR_spe_evmheumia
, "__builtin_spe_evmheumia", SPE_BUILTIN_EVMHEUMIA
},
9986 { 0, CODE_FOR_spe_evmheumiaaw
, "__builtin_spe_evmheumiaaw", SPE_BUILTIN_EVMHEUMIAAW
},
9987 { 0, CODE_FOR_spe_evmheumianw
, "__builtin_spe_evmheumianw", SPE_BUILTIN_EVMHEUMIANW
},
9988 { 0, CODE_FOR_spe_evmheusiaaw
, "__builtin_spe_evmheusiaaw", SPE_BUILTIN_EVMHEUSIAAW
},
9989 { 0, CODE_FOR_spe_evmheusianw
, "__builtin_spe_evmheusianw", SPE_BUILTIN_EVMHEUSIANW
},
9990 { 0, CODE_FOR_spe_evmhogsmfaa
, "__builtin_spe_evmhogsmfaa", SPE_BUILTIN_EVMHOGSMFAA
},
9991 { 0, CODE_FOR_spe_evmhogsmfan
, "__builtin_spe_evmhogsmfan", SPE_BUILTIN_EVMHOGSMFAN
},
9992 { 0, CODE_FOR_spe_evmhogsmiaa
, "__builtin_spe_evmhogsmiaa", SPE_BUILTIN_EVMHOGSMIAA
},
9993 { 0, CODE_FOR_spe_evmhogsmian
, "__builtin_spe_evmhogsmian", SPE_BUILTIN_EVMHOGSMIAN
},
9994 { 0, CODE_FOR_spe_evmhogumiaa
, "__builtin_spe_evmhogumiaa", SPE_BUILTIN_EVMHOGUMIAA
},
9995 { 0, CODE_FOR_spe_evmhogumian
, "__builtin_spe_evmhogumian", SPE_BUILTIN_EVMHOGUMIAN
},
9996 { 0, CODE_FOR_spe_evmhosmf
, "__builtin_spe_evmhosmf", SPE_BUILTIN_EVMHOSMF
},
9997 { 0, CODE_FOR_spe_evmhosmfa
, "__builtin_spe_evmhosmfa", SPE_BUILTIN_EVMHOSMFA
},
9998 { 0, CODE_FOR_spe_evmhosmfaaw
, "__builtin_spe_evmhosmfaaw", SPE_BUILTIN_EVMHOSMFAAW
},
9999 { 0, CODE_FOR_spe_evmhosmfanw
, "__builtin_spe_evmhosmfanw", SPE_BUILTIN_EVMHOSMFANW
},
10000 { 0, CODE_FOR_spe_evmhosmi
, "__builtin_spe_evmhosmi", SPE_BUILTIN_EVMHOSMI
},
10001 { 0, CODE_FOR_spe_evmhosmia
, "__builtin_spe_evmhosmia", SPE_BUILTIN_EVMHOSMIA
},
10002 { 0, CODE_FOR_spe_evmhosmiaaw
, "__builtin_spe_evmhosmiaaw", SPE_BUILTIN_EVMHOSMIAAW
},
10003 { 0, CODE_FOR_spe_evmhosmianw
, "__builtin_spe_evmhosmianw", SPE_BUILTIN_EVMHOSMIANW
},
10004 { 0, CODE_FOR_spe_evmhossf
, "__builtin_spe_evmhossf", SPE_BUILTIN_EVMHOSSF
},
10005 { 0, CODE_FOR_spe_evmhossfa
, "__builtin_spe_evmhossfa", SPE_BUILTIN_EVMHOSSFA
},
10006 { 0, CODE_FOR_spe_evmhossfaaw
, "__builtin_spe_evmhossfaaw", SPE_BUILTIN_EVMHOSSFAAW
},
10007 { 0, CODE_FOR_spe_evmhossfanw
, "__builtin_spe_evmhossfanw", SPE_BUILTIN_EVMHOSSFANW
},
10008 { 0, CODE_FOR_spe_evmhossiaaw
, "__builtin_spe_evmhossiaaw", SPE_BUILTIN_EVMHOSSIAAW
},
10009 { 0, CODE_FOR_spe_evmhossianw
, "__builtin_spe_evmhossianw", SPE_BUILTIN_EVMHOSSIANW
},
10010 { 0, CODE_FOR_spe_evmhoumi
, "__builtin_spe_evmhoumi", SPE_BUILTIN_EVMHOUMI
},
10011 { 0, CODE_FOR_spe_evmhoumia
, "__builtin_spe_evmhoumia", SPE_BUILTIN_EVMHOUMIA
},
10012 { 0, CODE_FOR_spe_evmhoumiaaw
, "__builtin_spe_evmhoumiaaw", SPE_BUILTIN_EVMHOUMIAAW
},
10013 { 0, CODE_FOR_spe_evmhoumianw
, "__builtin_spe_evmhoumianw", SPE_BUILTIN_EVMHOUMIANW
},
10014 { 0, CODE_FOR_spe_evmhousiaaw
, "__builtin_spe_evmhousiaaw", SPE_BUILTIN_EVMHOUSIAAW
},
10015 { 0, CODE_FOR_spe_evmhousianw
, "__builtin_spe_evmhousianw", SPE_BUILTIN_EVMHOUSIANW
},
10016 { 0, CODE_FOR_spe_evmwhsmf
, "__builtin_spe_evmwhsmf", SPE_BUILTIN_EVMWHSMF
},
10017 { 0, CODE_FOR_spe_evmwhsmfa
, "__builtin_spe_evmwhsmfa", SPE_BUILTIN_EVMWHSMFA
},
10018 { 0, CODE_FOR_spe_evmwhsmi
, "__builtin_spe_evmwhsmi", SPE_BUILTIN_EVMWHSMI
},
10019 { 0, CODE_FOR_spe_evmwhsmia
, "__builtin_spe_evmwhsmia", SPE_BUILTIN_EVMWHSMIA
},
10020 { 0, CODE_FOR_spe_evmwhssf
, "__builtin_spe_evmwhssf", SPE_BUILTIN_EVMWHSSF
},
10021 { 0, CODE_FOR_spe_evmwhssfa
, "__builtin_spe_evmwhssfa", SPE_BUILTIN_EVMWHSSFA
},
10022 { 0, CODE_FOR_spe_evmwhumi
, "__builtin_spe_evmwhumi", SPE_BUILTIN_EVMWHUMI
},
10023 { 0, CODE_FOR_spe_evmwhumia
, "__builtin_spe_evmwhumia", SPE_BUILTIN_EVMWHUMIA
},
10024 { 0, CODE_FOR_spe_evmwlsmiaaw
, "__builtin_spe_evmwlsmiaaw", SPE_BUILTIN_EVMWLSMIAAW
},
10025 { 0, CODE_FOR_spe_evmwlsmianw
, "__builtin_spe_evmwlsmianw", SPE_BUILTIN_EVMWLSMIANW
},
10026 { 0, CODE_FOR_spe_evmwlssiaaw
, "__builtin_spe_evmwlssiaaw", SPE_BUILTIN_EVMWLSSIAAW
},
10027 { 0, CODE_FOR_spe_evmwlssianw
, "__builtin_spe_evmwlssianw", SPE_BUILTIN_EVMWLSSIANW
},
10028 { 0, CODE_FOR_spe_evmwlumi
, "__builtin_spe_evmwlumi", SPE_BUILTIN_EVMWLUMI
},
10029 { 0, CODE_FOR_spe_evmwlumia
, "__builtin_spe_evmwlumia", SPE_BUILTIN_EVMWLUMIA
},
10030 { 0, CODE_FOR_spe_evmwlumiaaw
, "__builtin_spe_evmwlumiaaw", SPE_BUILTIN_EVMWLUMIAAW
},
10031 { 0, CODE_FOR_spe_evmwlumianw
, "__builtin_spe_evmwlumianw", SPE_BUILTIN_EVMWLUMIANW
},
10032 { 0, CODE_FOR_spe_evmwlusiaaw
, "__builtin_spe_evmwlusiaaw", SPE_BUILTIN_EVMWLUSIAAW
},
10033 { 0, CODE_FOR_spe_evmwlusianw
, "__builtin_spe_evmwlusianw", SPE_BUILTIN_EVMWLUSIANW
},
10034 { 0, CODE_FOR_spe_evmwsmf
, "__builtin_spe_evmwsmf", SPE_BUILTIN_EVMWSMF
},
10035 { 0, CODE_FOR_spe_evmwsmfa
, "__builtin_spe_evmwsmfa", SPE_BUILTIN_EVMWSMFA
},
10036 { 0, CODE_FOR_spe_evmwsmfaa
, "__builtin_spe_evmwsmfaa", SPE_BUILTIN_EVMWSMFAA
},
10037 { 0, CODE_FOR_spe_evmwsmfan
, "__builtin_spe_evmwsmfan", SPE_BUILTIN_EVMWSMFAN
},
10038 { 0, CODE_FOR_spe_evmwsmi
, "__builtin_spe_evmwsmi", SPE_BUILTIN_EVMWSMI
},
10039 { 0, CODE_FOR_spe_evmwsmia
, "__builtin_spe_evmwsmia", SPE_BUILTIN_EVMWSMIA
},
10040 { 0, CODE_FOR_spe_evmwsmiaa
, "__builtin_spe_evmwsmiaa", SPE_BUILTIN_EVMWSMIAA
},
10041 { 0, CODE_FOR_spe_evmwsmian
, "__builtin_spe_evmwsmian", SPE_BUILTIN_EVMWSMIAN
},
10042 { 0, CODE_FOR_spe_evmwssf
, "__builtin_spe_evmwssf", SPE_BUILTIN_EVMWSSF
},
10043 { 0, CODE_FOR_spe_evmwssfa
, "__builtin_spe_evmwssfa", SPE_BUILTIN_EVMWSSFA
},
10044 { 0, CODE_FOR_spe_evmwssfaa
, "__builtin_spe_evmwssfaa", SPE_BUILTIN_EVMWSSFAA
},
10045 { 0, CODE_FOR_spe_evmwssfan
, "__builtin_spe_evmwssfan", SPE_BUILTIN_EVMWSSFAN
},
10046 { 0, CODE_FOR_spe_evmwumi
, "__builtin_spe_evmwumi", SPE_BUILTIN_EVMWUMI
},
10047 { 0, CODE_FOR_spe_evmwumia
, "__builtin_spe_evmwumia", SPE_BUILTIN_EVMWUMIA
},
10048 { 0, CODE_FOR_spe_evmwumiaa
, "__builtin_spe_evmwumiaa", SPE_BUILTIN_EVMWUMIAA
},
10049 { 0, CODE_FOR_spe_evmwumian
, "__builtin_spe_evmwumian", SPE_BUILTIN_EVMWUMIAN
},
10050 { 0, CODE_FOR_spe_evnand
, "__builtin_spe_evnand", SPE_BUILTIN_EVNAND
},
10051 { 0, CODE_FOR_spe_evnor
, "__builtin_spe_evnor", SPE_BUILTIN_EVNOR
},
10052 { 0, CODE_FOR_spe_evor
, "__builtin_spe_evor", SPE_BUILTIN_EVOR
},
10053 { 0, CODE_FOR_spe_evorc
, "__builtin_spe_evorc", SPE_BUILTIN_EVORC
},
10054 { 0, CODE_FOR_spe_evrlw
, "__builtin_spe_evrlw", SPE_BUILTIN_EVRLW
},
10055 { 0, CODE_FOR_spe_evslw
, "__builtin_spe_evslw", SPE_BUILTIN_EVSLW
},
10056 { 0, CODE_FOR_spe_evsrws
, "__builtin_spe_evsrws", SPE_BUILTIN_EVSRWS
},
10057 { 0, CODE_FOR_spe_evsrwu
, "__builtin_spe_evsrwu", SPE_BUILTIN_EVSRWU
},
10058 { 0, CODE_FOR_subv2si3
, "__builtin_spe_evsubfw", SPE_BUILTIN_EVSUBFW
},
10060 /* SPE binary operations expecting a 5-bit unsigned literal. */
10061 { 0, CODE_FOR_spe_evaddiw
, "__builtin_spe_evaddiw", SPE_BUILTIN_EVADDIW
},
10063 { 0, CODE_FOR_spe_evrlwi
, "__builtin_spe_evrlwi", SPE_BUILTIN_EVRLWI
},
10064 { 0, CODE_FOR_spe_evslwi
, "__builtin_spe_evslwi", SPE_BUILTIN_EVSLWI
},
10065 { 0, CODE_FOR_spe_evsrwis
, "__builtin_spe_evsrwis", SPE_BUILTIN_EVSRWIS
},
10066 { 0, CODE_FOR_spe_evsrwiu
, "__builtin_spe_evsrwiu", SPE_BUILTIN_EVSRWIU
},
10067 { 0, CODE_FOR_spe_evsubifw
, "__builtin_spe_evsubifw", SPE_BUILTIN_EVSUBIFW
},
10068 { 0, CODE_FOR_spe_evmwhssfaa
, "__builtin_spe_evmwhssfaa", SPE_BUILTIN_EVMWHSSFAA
},
10069 { 0, CODE_FOR_spe_evmwhssmaa
, "__builtin_spe_evmwhssmaa", SPE_BUILTIN_EVMWHSSMAA
},
10070 { 0, CODE_FOR_spe_evmwhsmfaa
, "__builtin_spe_evmwhsmfaa", SPE_BUILTIN_EVMWHSMFAA
},
10071 { 0, CODE_FOR_spe_evmwhsmiaa
, "__builtin_spe_evmwhsmiaa", SPE_BUILTIN_EVMWHSMIAA
},
10072 { 0, CODE_FOR_spe_evmwhusiaa
, "__builtin_spe_evmwhusiaa", SPE_BUILTIN_EVMWHUSIAA
},
10073 { 0, CODE_FOR_spe_evmwhumiaa
, "__builtin_spe_evmwhumiaa", SPE_BUILTIN_EVMWHUMIAA
},
10074 { 0, CODE_FOR_spe_evmwhssfan
, "__builtin_spe_evmwhssfan", SPE_BUILTIN_EVMWHSSFAN
},
10075 { 0, CODE_FOR_spe_evmwhssian
, "__builtin_spe_evmwhssian", SPE_BUILTIN_EVMWHSSIAN
},
10076 { 0, CODE_FOR_spe_evmwhsmfan
, "__builtin_spe_evmwhsmfan", SPE_BUILTIN_EVMWHSMFAN
},
10077 { 0, CODE_FOR_spe_evmwhsmian
, "__builtin_spe_evmwhsmian", SPE_BUILTIN_EVMWHSMIAN
},
10078 { 0, CODE_FOR_spe_evmwhusian
, "__builtin_spe_evmwhusian", SPE_BUILTIN_EVMWHUSIAN
},
10079 { 0, CODE_FOR_spe_evmwhumian
, "__builtin_spe_evmwhumian", SPE_BUILTIN_EVMWHUMIAN
},
10080 { 0, CODE_FOR_spe_evmwhgssfaa
, "__builtin_spe_evmwhgssfaa", SPE_BUILTIN_EVMWHGSSFAA
},
10081 { 0, CODE_FOR_spe_evmwhgsmfaa
, "__builtin_spe_evmwhgsmfaa", SPE_BUILTIN_EVMWHGSMFAA
},
10082 { 0, CODE_FOR_spe_evmwhgsmiaa
, "__builtin_spe_evmwhgsmiaa", SPE_BUILTIN_EVMWHGSMIAA
},
10083 { 0, CODE_FOR_spe_evmwhgumiaa
, "__builtin_spe_evmwhgumiaa", SPE_BUILTIN_EVMWHGUMIAA
},
10084 { 0, CODE_FOR_spe_evmwhgssfan
, "__builtin_spe_evmwhgssfan", SPE_BUILTIN_EVMWHGSSFAN
},
10085 { 0, CODE_FOR_spe_evmwhgsmfan
, "__builtin_spe_evmwhgsmfan", SPE_BUILTIN_EVMWHGSMFAN
},
10086 { 0, CODE_FOR_spe_evmwhgsmian
, "__builtin_spe_evmwhgsmian", SPE_BUILTIN_EVMWHGSMIAN
},
10087 { 0, CODE_FOR_spe_evmwhgumian
, "__builtin_spe_evmwhgumian", SPE_BUILTIN_EVMWHGUMIAN
},
10088 { 0, CODE_FOR_spe_brinc
, "__builtin_spe_brinc", SPE_BUILTIN_BRINC
},
10090 /* Place-holder. Leave as last binary SPE builtin. */
10091 { 0, CODE_FOR_xorv2si3
, "__builtin_spe_evxor", SPE_BUILTIN_EVXOR
}
10094 /* AltiVec predicates. */
10096 struct builtin_description_predicates
10098 const unsigned int mask
;
10099 const enum insn_code icode
;
10100 const char *const name
;
10101 const enum rs6000_builtins code
;
10104 static const struct builtin_description_predicates bdesc_altivec_preds
[] =
10106 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpbfp_p
, "__builtin_altivec_vcmpbfp_p",
10107 ALTIVEC_BUILTIN_VCMPBFP_P
},
10108 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_vector_eq_v4sf_p
,
10109 "__builtin_altivec_vcmpeqfp_p", ALTIVEC_BUILTIN_VCMPEQFP_P
},
10110 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_vector_ge_v4sf_p
,
10111 "__builtin_altivec_vcmpgefp_p", ALTIVEC_BUILTIN_VCMPGEFP_P
},
10112 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_vector_gt_v4sf_p
,
10113 "__builtin_altivec_vcmpgtfp_p", ALTIVEC_BUILTIN_VCMPGTFP_P
},
10114 { MASK_ALTIVEC
, CODE_FOR_vector_eq_v4si_p
, "__builtin_altivec_vcmpequw_p",
10115 ALTIVEC_BUILTIN_VCMPEQUW_P
},
10116 { MASK_ALTIVEC
, CODE_FOR_vector_gt_v4si_p
, "__builtin_altivec_vcmpgtsw_p",
10117 ALTIVEC_BUILTIN_VCMPGTSW_P
},
10118 { MASK_ALTIVEC
, CODE_FOR_vector_gtu_v4si_p
, "__builtin_altivec_vcmpgtuw_p",
10119 ALTIVEC_BUILTIN_VCMPGTUW_P
},
10120 { MASK_ALTIVEC
, CODE_FOR_vector_eq_v8hi_p
, "__builtin_altivec_vcmpequh_p",
10121 ALTIVEC_BUILTIN_VCMPEQUH_P
},
10122 { MASK_ALTIVEC
, CODE_FOR_vector_gt_v8hi_p
, "__builtin_altivec_vcmpgtsh_p",
10123 ALTIVEC_BUILTIN_VCMPGTSH_P
},
10124 { MASK_ALTIVEC
, CODE_FOR_vector_gtu_v8hi_p
, "__builtin_altivec_vcmpgtuh_p",
10125 ALTIVEC_BUILTIN_VCMPGTUH_P
},
10126 { MASK_ALTIVEC
, CODE_FOR_vector_eq_v16qi_p
, "__builtin_altivec_vcmpequb_p",
10127 ALTIVEC_BUILTIN_VCMPEQUB_P
},
10128 { MASK_ALTIVEC
, CODE_FOR_vector_gt_v16qi_p
, "__builtin_altivec_vcmpgtsb_p",
10129 ALTIVEC_BUILTIN_VCMPGTSB_P
},
10130 { MASK_ALTIVEC
, CODE_FOR_vector_gtu_v16qi_p
, "__builtin_altivec_vcmpgtub_p",
10131 ALTIVEC_BUILTIN_VCMPGTUB_P
},
10133 { MASK_VSX
, CODE_FOR_vector_eq_v4sf_p
, "__builtin_vsx_xvcmpeqsp_p",
10134 VSX_BUILTIN_XVCMPEQSP_P
},
10135 { MASK_VSX
, CODE_FOR_vector_ge_v4sf_p
, "__builtin_vsx_xvcmpgesp_p",
10136 VSX_BUILTIN_XVCMPGESP_P
},
10137 { MASK_VSX
, CODE_FOR_vector_gt_v4sf_p
, "__builtin_vsx_xvcmpgtsp_p",
10138 VSX_BUILTIN_XVCMPGTSP_P
},
10139 { MASK_VSX
, CODE_FOR_vector_eq_v2df_p
, "__builtin_vsx_xvcmpeqdp_p",
10140 VSX_BUILTIN_XVCMPEQDP_P
},
10141 { MASK_VSX
, CODE_FOR_vector_ge_v2df_p
, "__builtin_vsx_xvcmpgedp_p",
10142 VSX_BUILTIN_XVCMPGEDP_P
},
10143 { MASK_VSX
, CODE_FOR_vector_gt_v2df_p
, "__builtin_vsx_xvcmpgtdp_p",
10144 VSX_BUILTIN_XVCMPGTDP_P
},
10146 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_vcmpeq_p",
10147 ALTIVEC_BUILTIN_VCMPEQ_P
},
10148 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_vcmpgt_p",
10149 ALTIVEC_BUILTIN_VCMPGT_P
},
10150 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_vcmpge_p",
10151 ALTIVEC_BUILTIN_VCMPGE_P
}
10154 /* SPE predicates. */
10155 static struct builtin_description bdesc_spe_predicates
[] =
10157 /* Place-holder. Leave as first. */
10158 { 0, CODE_FOR_spe_evcmpeq
, "__builtin_spe_evcmpeq", SPE_BUILTIN_EVCMPEQ
},
10159 { 0, CODE_FOR_spe_evcmpgts
, "__builtin_spe_evcmpgts", SPE_BUILTIN_EVCMPGTS
},
10160 { 0, CODE_FOR_spe_evcmpgtu
, "__builtin_spe_evcmpgtu", SPE_BUILTIN_EVCMPGTU
},
10161 { 0, CODE_FOR_spe_evcmplts
, "__builtin_spe_evcmplts", SPE_BUILTIN_EVCMPLTS
},
10162 { 0, CODE_FOR_spe_evcmpltu
, "__builtin_spe_evcmpltu", SPE_BUILTIN_EVCMPLTU
},
10163 { 0, CODE_FOR_spe_evfscmpeq
, "__builtin_spe_evfscmpeq", SPE_BUILTIN_EVFSCMPEQ
},
10164 { 0, CODE_FOR_spe_evfscmpgt
, "__builtin_spe_evfscmpgt", SPE_BUILTIN_EVFSCMPGT
},
10165 { 0, CODE_FOR_spe_evfscmplt
, "__builtin_spe_evfscmplt", SPE_BUILTIN_EVFSCMPLT
},
10166 { 0, CODE_FOR_spe_evfststeq
, "__builtin_spe_evfststeq", SPE_BUILTIN_EVFSTSTEQ
},
10167 { 0, CODE_FOR_spe_evfststgt
, "__builtin_spe_evfststgt", SPE_BUILTIN_EVFSTSTGT
},
10168 /* Place-holder. Leave as last. */
10169 { 0, CODE_FOR_spe_evfststlt
, "__builtin_spe_evfststlt", SPE_BUILTIN_EVFSTSTLT
},
10172 /* SPE evsel predicates. */
10173 static struct builtin_description bdesc_spe_evsel
[] =
10175 /* Place-holder. Leave as first. */
10176 { 0, CODE_FOR_spe_evcmpgts
, "__builtin_spe_evsel_gts", SPE_BUILTIN_EVSEL_CMPGTS
},
10177 { 0, CODE_FOR_spe_evcmpgtu
, "__builtin_spe_evsel_gtu", SPE_BUILTIN_EVSEL_CMPGTU
},
10178 { 0, CODE_FOR_spe_evcmplts
, "__builtin_spe_evsel_lts", SPE_BUILTIN_EVSEL_CMPLTS
},
10179 { 0, CODE_FOR_spe_evcmpltu
, "__builtin_spe_evsel_ltu", SPE_BUILTIN_EVSEL_CMPLTU
},
10180 { 0, CODE_FOR_spe_evcmpeq
, "__builtin_spe_evsel_eq", SPE_BUILTIN_EVSEL_CMPEQ
},
10181 { 0, CODE_FOR_spe_evfscmpgt
, "__builtin_spe_evsel_fsgt", SPE_BUILTIN_EVSEL_FSCMPGT
},
10182 { 0, CODE_FOR_spe_evfscmplt
, "__builtin_spe_evsel_fslt", SPE_BUILTIN_EVSEL_FSCMPLT
},
10183 { 0, CODE_FOR_spe_evfscmpeq
, "__builtin_spe_evsel_fseq", SPE_BUILTIN_EVSEL_FSCMPEQ
},
10184 { 0, CODE_FOR_spe_evfststgt
, "__builtin_spe_evsel_fststgt", SPE_BUILTIN_EVSEL_FSTSTGT
},
10185 { 0, CODE_FOR_spe_evfststlt
, "__builtin_spe_evsel_fststlt", SPE_BUILTIN_EVSEL_FSTSTLT
},
10186 /* Place-holder. Leave as last. */
10187 { 0, CODE_FOR_spe_evfststeq
, "__builtin_spe_evsel_fststeq", SPE_BUILTIN_EVSEL_FSTSTEQ
},
10190 /* PAIRED predicates. */
10191 static const struct builtin_description bdesc_paired_preds
[] =
10193 /* Place-holder. Leave as first. */
10194 { 0, CODE_FOR_paired_cmpu0
, "__builtin_paired_cmpu0", PAIRED_BUILTIN_CMPU0
},
10195 /* Place-holder. Leave as last. */
10196 { 0, CODE_FOR_paired_cmpu1
, "__builtin_paired_cmpu1", PAIRED_BUILTIN_CMPU1
},
10199 /* ABS* operations. */
10201 static const struct builtin_description bdesc_abs
[] =
10203 { MASK_ALTIVEC
, CODE_FOR_absv4si2
, "__builtin_altivec_abs_v4si", ALTIVEC_BUILTIN_ABS_V4SI
},
10204 { MASK_ALTIVEC
, CODE_FOR_absv8hi2
, "__builtin_altivec_abs_v8hi", ALTIVEC_BUILTIN_ABS_V8HI
},
10205 { MASK_ALTIVEC
, CODE_FOR_absv4sf2
, "__builtin_altivec_abs_v4sf", ALTIVEC_BUILTIN_ABS_V4SF
},
10206 { MASK_ALTIVEC
, CODE_FOR_absv16qi2
, "__builtin_altivec_abs_v16qi", ALTIVEC_BUILTIN_ABS_V16QI
},
10207 { MASK_ALTIVEC
, CODE_FOR_altivec_abss_v4si
, "__builtin_altivec_abss_v4si", ALTIVEC_BUILTIN_ABSS_V4SI
},
10208 { MASK_ALTIVEC
, CODE_FOR_altivec_abss_v8hi
, "__builtin_altivec_abss_v8hi", ALTIVEC_BUILTIN_ABSS_V8HI
},
10209 { MASK_ALTIVEC
, CODE_FOR_altivec_abss_v16qi
, "__builtin_altivec_abss_v16qi", ALTIVEC_BUILTIN_ABSS_V16QI
},
10210 { MASK_VSX
, CODE_FOR_absv2df2
, "__builtin_vsx_xvabsdp", VSX_BUILTIN_XVABSDP
},
10211 { MASK_VSX
, CODE_FOR_vsx_nabsv2df2
, "__builtin_vsx_xvnabsdp", VSX_BUILTIN_XVNABSDP
},
10212 { MASK_VSX
, CODE_FOR_absv4sf2
, "__builtin_vsx_xvabssp", VSX_BUILTIN_XVABSSP
},
10213 { MASK_VSX
, CODE_FOR_vsx_nabsv4sf2
, "__builtin_vsx_xvnabssp", VSX_BUILTIN_XVNABSSP
},
10216 /* Simple unary operations: VECb = foo (unsigned literal) or VECb =
10219 static struct builtin_description bdesc_1arg
[] =
10221 { MASK_ALTIVEC
, CODE_FOR_altivec_vexptefp
, "__builtin_altivec_vexptefp", ALTIVEC_BUILTIN_VEXPTEFP
},
10222 { MASK_ALTIVEC
, CODE_FOR_altivec_vlogefp
, "__builtin_altivec_vlogefp", ALTIVEC_BUILTIN_VLOGEFP
},
10223 { MASK_ALTIVEC
, CODE_FOR_rev4sf2
, "__builtin_altivec_vrefp", ALTIVEC_BUILTIN_VREFP
},
10224 { MASK_ALTIVEC
, CODE_FOR_vector_floorv4sf2
, "__builtin_altivec_vrfim", ALTIVEC_BUILTIN_VRFIM
},
10225 { MASK_ALTIVEC
, CODE_FOR_altivec_vrfin
, "__builtin_altivec_vrfin", ALTIVEC_BUILTIN_VRFIN
},
10226 { MASK_ALTIVEC
, CODE_FOR_vector_ceilv4sf2
, "__builtin_altivec_vrfip", ALTIVEC_BUILTIN_VRFIP
},
10227 { MASK_ALTIVEC
, CODE_FOR_vector_btruncv4sf2
, "__builtin_altivec_vrfiz", ALTIVEC_BUILTIN_VRFIZ
},
10228 { MASK_ALTIVEC
, CODE_FOR_rsqrtv4sf2
, "__builtin_altivec_vrsqrtfp", ALTIVEC_BUILTIN_VRSQRTFP
},
10229 { MASK_ALTIVEC
, CODE_FOR_rsqrtev4sf2
, "__builtin_altivec_vrsqrtefp", ALTIVEC_BUILTIN_VRSQRTEFP
},
10230 { MASK_ALTIVEC
, CODE_FOR_altivec_vspltisb
, "__builtin_altivec_vspltisb", ALTIVEC_BUILTIN_VSPLTISB
},
10231 { MASK_ALTIVEC
, CODE_FOR_altivec_vspltish
, "__builtin_altivec_vspltish", ALTIVEC_BUILTIN_VSPLTISH
},
10232 { MASK_ALTIVEC
, CODE_FOR_altivec_vspltisw
, "__builtin_altivec_vspltisw", ALTIVEC_BUILTIN_VSPLTISW
},
10233 { MASK_ALTIVEC
, CODE_FOR_altivec_vupkhsb
, "__builtin_altivec_vupkhsb", ALTIVEC_BUILTIN_VUPKHSB
},
10234 { MASK_ALTIVEC
, CODE_FOR_altivec_vupkhpx
, "__builtin_altivec_vupkhpx", ALTIVEC_BUILTIN_VUPKHPX
},
10235 { MASK_ALTIVEC
, CODE_FOR_altivec_vupkhsh
, "__builtin_altivec_vupkhsh", ALTIVEC_BUILTIN_VUPKHSH
},
10236 { MASK_ALTIVEC
, CODE_FOR_altivec_vupklsb
, "__builtin_altivec_vupklsb", ALTIVEC_BUILTIN_VUPKLSB
},
10237 { MASK_ALTIVEC
, CODE_FOR_altivec_vupklpx
, "__builtin_altivec_vupklpx", ALTIVEC_BUILTIN_VUPKLPX
},
10238 { MASK_ALTIVEC
, CODE_FOR_altivec_vupklsh
, "__builtin_altivec_vupklsh", ALTIVEC_BUILTIN_VUPKLSH
},
10240 { MASK_VSX
, CODE_FOR_negv2df2
, "__builtin_vsx_xvnegdp", VSX_BUILTIN_XVNEGDP
},
10241 { MASK_VSX
, CODE_FOR_sqrtv2df2
, "__builtin_vsx_xvsqrtdp", VSX_BUILTIN_XVSQRTDP
},
10242 { MASK_VSX
, CODE_FOR_rsqrtv2df2
, "__builtin_vsx_xvrsqrtdp", VSX_BUILTIN_VEC_RSQRT_V2DF
},
10243 { MASK_VSX
, CODE_FOR_rsqrtev2df2
, "__builtin_vsx_xvrsqrtedp", VSX_BUILTIN_XVRSQRTEDP
},
10244 { MASK_VSX
, CODE_FOR_vsx_tsqrtv2df2_fe
, "__builtin_vsx_xvtsqrtdp_fe", VSX_BUILTIN_XVTSQRTDP_FE
},
10245 { MASK_VSX
, CODE_FOR_vsx_tsqrtv2df2_fg
, "__builtin_vsx_xvtsqrtdp_fg", VSX_BUILTIN_XVTSQRTDP_FG
},
10246 { MASK_VSX
, CODE_FOR_vsx_frev2df2
, "__builtin_vsx_xvredp", VSX_BUILTIN_XVREDP
},
10248 { MASK_VSX
, CODE_FOR_negv4sf2
, "__builtin_vsx_xvnegsp", VSX_BUILTIN_XVNEGSP
},
10249 { MASK_VSX
, CODE_FOR_sqrtv4sf2
, "__builtin_vsx_xvsqrtsp", VSX_BUILTIN_XVSQRTSP
},
10250 { MASK_VSX
, CODE_FOR_rsqrtv4sf2
, "__builtin_vsx_xvrsqrtsp", VSX_BUILTIN_VEC_RSQRT_V4SF
},
10251 { MASK_VSX
, CODE_FOR_rsqrtev4sf2
, "__builtin_vsx_xvrsqrtesp", VSX_BUILTIN_XVRSQRTESP
},
10252 { MASK_VSX
, CODE_FOR_vsx_tsqrtv4sf2_fe
, "__builtin_vsx_xvtsqrtsp_fe", VSX_BUILTIN_XVTSQRTSP_FE
},
10253 { MASK_VSX
, CODE_FOR_vsx_tsqrtv4sf2_fg
, "__builtin_vsx_xvtsqrtsp_fg", VSX_BUILTIN_XVTSQRTSP_FG
},
10254 { MASK_VSX
, CODE_FOR_vsx_frev4sf2
, "__builtin_vsx_xvresp", VSX_BUILTIN_XVRESP
},
10256 { MASK_VSX
, CODE_FOR_vsx_xscvdpsp
, "__builtin_vsx_xscvdpsp", VSX_BUILTIN_XSCVDPSP
},
10257 { MASK_VSX
, CODE_FOR_vsx_xscvdpsp
, "__builtin_vsx_xscvspdp", VSX_BUILTIN_XSCVSPDP
},
10258 { MASK_VSX
, CODE_FOR_vsx_xvcvdpsp
, "__builtin_vsx_xvcvdpsp", VSX_BUILTIN_XVCVDPSP
},
10259 { MASK_VSX
, CODE_FOR_vsx_xvcvspdp
, "__builtin_vsx_xvcvspdp", VSX_BUILTIN_XVCVSPDP
},
10260 { MASK_VSX
, CODE_FOR_vsx_tsqrtdf2_fe
, "__builtin_vsx_xstsqrtdp_fe", VSX_BUILTIN_XSTSQRTDP_FE
},
10261 { MASK_VSX
, CODE_FOR_vsx_tsqrtdf2_fg
, "__builtin_vsx_xstsqrtdp_fg", VSX_BUILTIN_XSTSQRTDP_FG
},
10263 { MASK_VSX
, CODE_FOR_vsx_fix_truncv2dfv2di2
, "__builtin_vsx_xvcvdpsxds", VSX_BUILTIN_XVCVDPSXDS
},
10264 { MASK_VSX
, CODE_FOR_vsx_fixuns_truncv2dfv2di2
, "__builtin_vsx_xvcvdpuxds", VSX_BUILTIN_XVCVDPUXDS
},
10265 { MASK_VSX
, CODE_FOR_vsx_fixuns_truncv2dfv2di2
, "__builtin_vsx_xvcvdpuxds_uns", VSX_BUILTIN_XVCVDPUXDS_UNS
},
10266 { MASK_VSX
, CODE_FOR_vsx_floatv2div2df2
, "__builtin_vsx_xvcvsxddp", VSX_BUILTIN_XVCVSXDDP
},
10267 { MASK_VSX
, CODE_FOR_vsx_floatunsv2div2df2
, "__builtin_vsx_xvcvuxddp", VSX_BUILTIN_XVCVUXDDP
},
10268 { MASK_VSX
, CODE_FOR_vsx_floatunsv2div2df2
, "__builtin_vsx_xvcvuxddp_uns", VSX_BUILTIN_XVCVUXDDP_UNS
},
10270 { MASK_VSX
, CODE_FOR_vsx_fix_truncv4sfv4si2
, "__builtin_vsx_xvcvspsxws", VSX_BUILTIN_XVCVSPSXWS
},
10271 { MASK_VSX
, CODE_FOR_vsx_fixuns_truncv4sfv4si2
, "__builtin_vsx_xvcvspuxws", VSX_BUILTIN_XVCVSPUXWS
},
10272 { MASK_VSX
, CODE_FOR_vsx_floatv4siv4sf2
, "__builtin_vsx_xvcvsxwsp", VSX_BUILTIN_XVCVSXWSP
},
10273 { MASK_VSX
, CODE_FOR_vsx_floatunsv4siv4sf2
, "__builtin_vsx_xvcvuxwsp", VSX_BUILTIN_XVCVUXWSP
},
10275 { MASK_VSX
, CODE_FOR_vsx_xvcvdpsxws
, "__builtin_vsx_xvcvdpsxws", VSX_BUILTIN_XVCVDPSXWS
},
10276 { MASK_VSX
, CODE_FOR_vsx_xvcvdpuxws
, "__builtin_vsx_xvcvdpuxws", VSX_BUILTIN_XVCVDPUXWS
},
10277 { MASK_VSX
, CODE_FOR_vsx_xvcvsxwdp
, "__builtin_vsx_xvcvsxwdp", VSX_BUILTIN_XVCVSXWDP
},
10278 { MASK_VSX
, CODE_FOR_vsx_xvcvuxwdp
, "__builtin_vsx_xvcvuxwdp", VSX_BUILTIN_XVCVUXWDP
},
10279 { MASK_VSX
, CODE_FOR_vsx_xvrdpi
, "__builtin_vsx_xvrdpi", VSX_BUILTIN_XVRDPI
},
10280 { MASK_VSX
, CODE_FOR_vsx_xvrdpic
, "__builtin_vsx_xvrdpic", VSX_BUILTIN_XVRDPIC
},
10281 { MASK_VSX
, CODE_FOR_vsx_floorv2df2
, "__builtin_vsx_xvrdpim", VSX_BUILTIN_XVRDPIM
},
10282 { MASK_VSX
, CODE_FOR_vsx_ceilv2df2
, "__builtin_vsx_xvrdpip", VSX_BUILTIN_XVRDPIP
},
10283 { MASK_VSX
, CODE_FOR_vsx_btruncv2df2
, "__builtin_vsx_xvrdpiz", VSX_BUILTIN_XVRDPIZ
},
10285 { MASK_VSX
, CODE_FOR_vsx_xvcvspsxds
, "__builtin_vsx_xvcvspsxds", VSX_BUILTIN_XVCVSPSXDS
},
10286 { MASK_VSX
, CODE_FOR_vsx_xvcvspuxds
, "__builtin_vsx_xvcvspuxds", VSX_BUILTIN_XVCVSPUXDS
},
10287 { MASK_VSX
, CODE_FOR_vsx_xvcvsxdsp
, "__builtin_vsx_xvcvsxdsp", VSX_BUILTIN_XVCVSXDSP
},
10288 { MASK_VSX
, CODE_FOR_vsx_xvcvuxdsp
, "__builtin_vsx_xvcvuxdsp", VSX_BUILTIN_XVCVUXDSP
},
10289 { MASK_VSX
, CODE_FOR_vsx_xvrspi
, "__builtin_vsx_xvrspi", VSX_BUILTIN_XVRSPI
},
10290 { MASK_VSX
, CODE_FOR_vsx_xvrspic
, "__builtin_vsx_xvrspic", VSX_BUILTIN_XVRSPIC
},
10291 { MASK_VSX
, CODE_FOR_vsx_floorv4sf2
, "__builtin_vsx_xvrspim", VSX_BUILTIN_XVRSPIM
},
10292 { MASK_VSX
, CODE_FOR_vsx_ceilv4sf2
, "__builtin_vsx_xvrspip", VSX_BUILTIN_XVRSPIP
},
10293 { MASK_VSX
, CODE_FOR_vsx_btruncv4sf2
, "__builtin_vsx_xvrspiz", VSX_BUILTIN_XVRSPIZ
},
10295 { MASK_VSX
, CODE_FOR_vsx_xsrdpi
, "__builtin_vsx_xsrdpi", VSX_BUILTIN_XSRDPI
},
10296 { MASK_VSX
, CODE_FOR_vsx_xsrdpic
, "__builtin_vsx_xsrdpic", VSX_BUILTIN_XSRDPIC
},
10297 { MASK_VSX
, CODE_FOR_vsx_floordf2
, "__builtin_vsx_xsrdpim", VSX_BUILTIN_XSRDPIM
},
10298 { MASK_VSX
, CODE_FOR_vsx_ceildf2
, "__builtin_vsx_xsrdpip", VSX_BUILTIN_XSRDPIP
},
10299 { MASK_VSX
, CODE_FOR_vsx_btruncdf2
, "__builtin_vsx_xsrdpiz", VSX_BUILTIN_XSRDPIZ
},
10301 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_abs", ALTIVEC_BUILTIN_VEC_ABS
},
10302 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_abss", ALTIVEC_BUILTIN_VEC_ABSS
},
10303 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_ceil", ALTIVEC_BUILTIN_VEC_CEIL
},
10304 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_expte", ALTIVEC_BUILTIN_VEC_EXPTE
},
10305 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_floor", ALTIVEC_BUILTIN_VEC_FLOOR
},
10306 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_loge", ALTIVEC_BUILTIN_VEC_LOGE
},
10307 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_mtvscr", ALTIVEC_BUILTIN_VEC_MTVSCR
},
10308 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_re", ALTIVEC_BUILTIN_VEC_RE
},
10309 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_round", ALTIVEC_BUILTIN_VEC_ROUND
},
10310 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_rsqrt", ALTIVEC_BUILTIN_VEC_RSQRT
},
10311 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_rsqrte", ALTIVEC_BUILTIN_VEC_RSQRTE
},
10312 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_trunc", ALTIVEC_BUILTIN_VEC_TRUNC
},
10313 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_unpackh", ALTIVEC_BUILTIN_VEC_UNPACKH
},
10314 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vupkhsh", ALTIVEC_BUILTIN_VEC_VUPKHSH
},
10315 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vupkhpx", ALTIVEC_BUILTIN_VEC_VUPKHPX
},
10316 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vupkhsb", ALTIVEC_BUILTIN_VEC_VUPKHSB
},
10317 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_unpackl", ALTIVEC_BUILTIN_VEC_UNPACKL
},
10318 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vupklpx", ALTIVEC_BUILTIN_VEC_VUPKLPX
},
10319 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vupklsh", ALTIVEC_BUILTIN_VEC_VUPKLSH
},
10320 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vupklsb", ALTIVEC_BUILTIN_VEC_VUPKLSB
},
10322 { MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_nearbyint", ALTIVEC_BUILTIN_VEC_NEARBYINT
},
10323 { MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_rint", ALTIVEC_BUILTIN_VEC_RINT
},
10324 { MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_sqrt", ALTIVEC_BUILTIN_VEC_SQRT
},
10326 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_floatv4siv4sf2
, "__builtin_vec_float_sisf", VECTOR_BUILTIN_FLOAT_V4SI_V4SF
},
10327 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_unsigned_floatv4siv4sf2
, "__builtin_vec_uns_float_sisf", VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF
},
10328 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_fix_truncv4sfv4si2
, "__builtin_vec_fix_sfsi", VECTOR_BUILTIN_FIX_V4SF_V4SI
},
10329 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_fixuns_truncv4sfv4si2
, "__builtin_vec_fixuns_sfsi", VECTOR_BUILTIN_FIXUNS_V4SF_V4SI
},
10331 /* The SPE unary builtins must start with SPE_BUILTIN_EVABS and
10332 end with SPE_BUILTIN_EVSUBFUSIAAW. */
10333 { 0, CODE_FOR_absv2si2
, "__builtin_spe_evabs", SPE_BUILTIN_EVABS
},
10334 { 0, CODE_FOR_spe_evaddsmiaaw
, "__builtin_spe_evaddsmiaaw", SPE_BUILTIN_EVADDSMIAAW
},
10335 { 0, CODE_FOR_spe_evaddssiaaw
, "__builtin_spe_evaddssiaaw", SPE_BUILTIN_EVADDSSIAAW
},
10336 { 0, CODE_FOR_spe_evaddumiaaw
, "__builtin_spe_evaddumiaaw", SPE_BUILTIN_EVADDUMIAAW
},
10337 { 0, CODE_FOR_spe_evaddusiaaw
, "__builtin_spe_evaddusiaaw", SPE_BUILTIN_EVADDUSIAAW
},
10338 { 0, CODE_FOR_spe_evcntlsw
, "__builtin_spe_evcntlsw", SPE_BUILTIN_EVCNTLSW
},
10339 { 0, CODE_FOR_spe_evcntlzw
, "__builtin_spe_evcntlzw", SPE_BUILTIN_EVCNTLZW
},
10340 { 0, CODE_FOR_spe_evextsb
, "__builtin_spe_evextsb", SPE_BUILTIN_EVEXTSB
},
10341 { 0, CODE_FOR_spe_evextsh
, "__builtin_spe_evextsh", SPE_BUILTIN_EVEXTSH
},
10342 { 0, CODE_FOR_spe_evfsabs
, "__builtin_spe_evfsabs", SPE_BUILTIN_EVFSABS
},
10343 { 0, CODE_FOR_spe_evfscfsf
, "__builtin_spe_evfscfsf", SPE_BUILTIN_EVFSCFSF
},
10344 { 0, CODE_FOR_spe_evfscfsi
, "__builtin_spe_evfscfsi", SPE_BUILTIN_EVFSCFSI
},
10345 { 0, CODE_FOR_spe_evfscfuf
, "__builtin_spe_evfscfuf", SPE_BUILTIN_EVFSCFUF
},
10346 { 0, CODE_FOR_spe_evfscfui
, "__builtin_spe_evfscfui", SPE_BUILTIN_EVFSCFUI
},
10347 { 0, CODE_FOR_spe_evfsctsf
, "__builtin_spe_evfsctsf", SPE_BUILTIN_EVFSCTSF
},
10348 { 0, CODE_FOR_spe_evfsctsi
, "__builtin_spe_evfsctsi", SPE_BUILTIN_EVFSCTSI
},
10349 { 0, CODE_FOR_spe_evfsctsiz
, "__builtin_spe_evfsctsiz", SPE_BUILTIN_EVFSCTSIZ
},
10350 { 0, CODE_FOR_spe_evfsctuf
, "__builtin_spe_evfsctuf", SPE_BUILTIN_EVFSCTUF
},
10351 { 0, CODE_FOR_spe_evfsctui
, "__builtin_spe_evfsctui", SPE_BUILTIN_EVFSCTUI
},
10352 { 0, CODE_FOR_spe_evfsctuiz
, "__builtin_spe_evfsctuiz", SPE_BUILTIN_EVFSCTUIZ
},
10353 { 0, CODE_FOR_spe_evfsnabs
, "__builtin_spe_evfsnabs", SPE_BUILTIN_EVFSNABS
},
10354 { 0, CODE_FOR_spe_evfsneg
, "__builtin_spe_evfsneg", SPE_BUILTIN_EVFSNEG
},
10355 { 0, CODE_FOR_spe_evmra
, "__builtin_spe_evmra", SPE_BUILTIN_EVMRA
},
10356 { 0, CODE_FOR_negv2si2
, "__builtin_spe_evneg", SPE_BUILTIN_EVNEG
},
10357 { 0, CODE_FOR_spe_evrndw
, "__builtin_spe_evrndw", SPE_BUILTIN_EVRNDW
},
10358 { 0, CODE_FOR_spe_evsubfsmiaaw
, "__builtin_spe_evsubfsmiaaw", SPE_BUILTIN_EVSUBFSMIAAW
},
10359 { 0, CODE_FOR_spe_evsubfssiaaw
, "__builtin_spe_evsubfssiaaw", SPE_BUILTIN_EVSUBFSSIAAW
},
10360 { 0, CODE_FOR_spe_evsubfumiaaw
, "__builtin_spe_evsubfumiaaw", SPE_BUILTIN_EVSUBFUMIAAW
},
10362 /* Place-holder. Leave as last unary SPE builtin. */
10363 { 0, CODE_FOR_spe_evsubfusiaaw
, "__builtin_spe_evsubfusiaaw", SPE_BUILTIN_EVSUBFUSIAAW
},
10365 { 0, CODE_FOR_paired_absv2sf2
, "__builtin_paired_absv2sf2", PAIRED_BUILTIN_ABSV2SF2
},
10366 { 0, CODE_FOR_nabsv2sf2
, "__builtin_paired_nabsv2sf2", PAIRED_BUILTIN_NABSV2SF2
},
10367 { 0, CODE_FOR_paired_negv2sf2
, "__builtin_paired_negv2sf2", PAIRED_BUILTIN_NEGV2SF2
},
10368 { 0, CODE_FOR_sqrtv2sf2
, "__builtin_paired_sqrtv2sf2", PAIRED_BUILTIN_SQRTV2SF2
},
10369 { 0, CODE_FOR_resv2sf2
, "__builtin_paired_resv2sf2", PAIRED_BUILTIN_RESV2SF2
}
10373 rs6000_expand_unop_builtin (enum insn_code icode
, tree exp
, rtx target
)
10376 tree arg0
= CALL_EXPR_ARG (exp
, 0);
10377 rtx op0
= expand_normal (arg0
);
10378 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
10379 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
10381 if (icode
== CODE_FOR_nothing
)
10382 /* Builtin not supported on this processor. */
10385 /* If we got invalid arguments bail out before generating bad rtl. */
10386 if (arg0
== error_mark_node
)
10389 if (icode
== CODE_FOR_altivec_vspltisb
10390 || icode
== CODE_FOR_altivec_vspltish
10391 || icode
== CODE_FOR_altivec_vspltisw
10392 || icode
== CODE_FOR_spe_evsplatfi
10393 || icode
== CODE_FOR_spe_evsplati
)
10395 /* Only allow 5-bit *signed* literals. */
10396 if (GET_CODE (op0
) != CONST_INT
10397 || INTVAL (op0
) > 15
10398 || INTVAL (op0
) < -16)
10400 error ("argument 1 must be a 5-bit signed literal");
10406 || GET_MODE (target
) != tmode
10407 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
10408 target
= gen_reg_rtx (tmode
);
10410 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
10411 op0
= copy_to_mode_reg (mode0
, op0
);
10413 pat
= GEN_FCN (icode
) (target
, op0
);
10422 altivec_expand_abs_builtin (enum insn_code icode
, tree exp
, rtx target
)
10424 rtx pat
, scratch1
, scratch2
;
10425 tree arg0
= CALL_EXPR_ARG (exp
, 0);
10426 rtx op0
= expand_normal (arg0
);
10427 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
10428 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
10430 /* If we have invalid arguments, bail out before generating bad rtl. */
10431 if (arg0
== error_mark_node
)
10435 || GET_MODE (target
) != tmode
10436 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
10437 target
= gen_reg_rtx (tmode
);
10439 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
10440 op0
= copy_to_mode_reg (mode0
, op0
);
10442 scratch1
= gen_reg_rtx (mode0
);
10443 scratch2
= gen_reg_rtx (mode0
);
10445 pat
= GEN_FCN (icode
) (target
, op0
, scratch1
, scratch2
);
10454 rs6000_expand_binop_builtin (enum insn_code icode
, tree exp
, rtx target
)
10457 tree arg0
= CALL_EXPR_ARG (exp
, 0);
10458 tree arg1
= CALL_EXPR_ARG (exp
, 1);
10459 rtx op0
= expand_normal (arg0
);
10460 rtx op1
= expand_normal (arg1
);
10461 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
10462 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
10463 enum machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
10465 if (icode
== CODE_FOR_nothing
)
10466 /* Builtin not supported on this processor. */
10469 /* If we got invalid arguments bail out before generating bad rtl. */
10470 if (arg0
== error_mark_node
|| arg1
== error_mark_node
)
10473 if (icode
== CODE_FOR_altivec_vcfux
10474 || icode
== CODE_FOR_altivec_vcfsx
10475 || icode
== CODE_FOR_altivec_vctsxs
10476 || icode
== CODE_FOR_altivec_vctuxs
10477 || icode
== CODE_FOR_altivec_vspltb
10478 || icode
== CODE_FOR_altivec_vsplth
10479 || icode
== CODE_FOR_altivec_vspltw
10480 || icode
== CODE_FOR_spe_evaddiw
10481 || icode
== CODE_FOR_spe_evldd
10482 || icode
== CODE_FOR_spe_evldh
10483 || icode
== CODE_FOR_spe_evldw
10484 || icode
== CODE_FOR_spe_evlhhesplat
10485 || icode
== CODE_FOR_spe_evlhhossplat
10486 || icode
== CODE_FOR_spe_evlhhousplat
10487 || icode
== CODE_FOR_spe_evlwhe
10488 || icode
== CODE_FOR_spe_evlwhos
10489 || icode
== CODE_FOR_spe_evlwhou
10490 || icode
== CODE_FOR_spe_evlwhsplat
10491 || icode
== CODE_FOR_spe_evlwwsplat
10492 || icode
== CODE_FOR_spe_evrlwi
10493 || icode
== CODE_FOR_spe_evslwi
10494 || icode
== CODE_FOR_spe_evsrwis
10495 || icode
== CODE_FOR_spe_evsubifw
10496 || icode
== CODE_FOR_spe_evsrwiu
)
10498 /* Only allow 5-bit unsigned literals. */
10500 if (TREE_CODE (arg1
) != INTEGER_CST
10501 || TREE_INT_CST_LOW (arg1
) & ~0x1f)
10503 error ("argument 2 must be a 5-bit unsigned literal");
10509 || GET_MODE (target
) != tmode
10510 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
10511 target
= gen_reg_rtx (tmode
);
10513 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
10514 op0
= copy_to_mode_reg (mode0
, op0
);
10515 if (! (*insn_data
[icode
].operand
[2].predicate
) (op1
, mode1
))
10516 op1
= copy_to_mode_reg (mode1
, op1
);
10518 pat
= GEN_FCN (icode
) (target
, op0
, op1
);
10527 altivec_expand_predicate_builtin (enum insn_code icode
, tree exp
, rtx target
)
10530 tree cr6_form
= CALL_EXPR_ARG (exp
, 0);
10531 tree arg0
= CALL_EXPR_ARG (exp
, 1);
10532 tree arg1
= CALL_EXPR_ARG (exp
, 2);
10533 rtx op0
= expand_normal (arg0
);
10534 rtx op1
= expand_normal (arg1
);
10535 enum machine_mode tmode
= SImode
;
10536 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
10537 enum machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
10540 if (TREE_CODE (cr6_form
) != INTEGER_CST
)
10542 error ("argument 1 of __builtin_altivec_predicate must be a constant");
10546 cr6_form_int
= TREE_INT_CST_LOW (cr6_form
);
10548 gcc_assert (mode0
== mode1
);
10550 /* If we have invalid arguments, bail out before generating bad rtl. */
10551 if (arg0
== error_mark_node
|| arg1
== error_mark_node
)
10555 || GET_MODE (target
) != tmode
10556 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
10557 target
= gen_reg_rtx (tmode
);
10559 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
10560 op0
= copy_to_mode_reg (mode0
, op0
);
10561 if (! (*insn_data
[icode
].operand
[2].predicate
) (op1
, mode1
))
10562 op1
= copy_to_mode_reg (mode1
, op1
);
10564 scratch
= gen_reg_rtx (mode0
);
10566 pat
= GEN_FCN (icode
) (scratch
, op0
, op1
);
10571 /* The vec_any* and vec_all* predicates use the same opcodes for two
10572 different operations, but the bits in CR6 will be different
10573 depending on what information we want. So we have to play tricks
10574 with CR6 to get the right bits out.
10576 If you think this is disgusting, look at the specs for the
10577 AltiVec predicates. */
10579 switch (cr6_form_int
)
10582 emit_insn (gen_cr6_test_for_zero (target
));
10585 emit_insn (gen_cr6_test_for_zero_reverse (target
));
10588 emit_insn (gen_cr6_test_for_lt (target
));
10591 emit_insn (gen_cr6_test_for_lt_reverse (target
));
10594 error ("argument 1 of __builtin_altivec_predicate is out of range");
10602 paired_expand_lv_builtin (enum insn_code icode
, tree exp
, rtx target
)
10605 tree arg0
= CALL_EXPR_ARG (exp
, 0);
10606 tree arg1
= CALL_EXPR_ARG (exp
, 1);
10607 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
10608 enum machine_mode mode0
= Pmode
;
10609 enum machine_mode mode1
= Pmode
;
10610 rtx op0
= expand_normal (arg0
);
10611 rtx op1
= expand_normal (arg1
);
10613 if (icode
== CODE_FOR_nothing
)
10614 /* Builtin not supported on this processor. */
10617 /* If we got invalid arguments bail out before generating bad rtl. */
10618 if (arg0
== error_mark_node
|| arg1
== error_mark_node
)
10622 || GET_MODE (target
) != tmode
10623 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
10624 target
= gen_reg_rtx (tmode
);
10626 op1
= copy_to_mode_reg (mode1
, op1
);
10628 if (op0
== const0_rtx
)
10630 addr
= gen_rtx_MEM (tmode
, op1
);
10634 op0
= copy_to_mode_reg (mode0
, op0
);
10635 addr
= gen_rtx_MEM (tmode
, gen_rtx_PLUS (Pmode
, op0
, op1
));
10638 pat
= GEN_FCN (icode
) (target
, addr
);
10648 altivec_expand_lv_builtin (enum insn_code icode
, tree exp
, rtx target
, bool blk
)
10651 tree arg0
= CALL_EXPR_ARG (exp
, 0);
10652 tree arg1
= CALL_EXPR_ARG (exp
, 1);
10653 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
10654 enum machine_mode mode0
= Pmode
;
10655 enum machine_mode mode1
= Pmode
;
10656 rtx op0
= expand_normal (arg0
);
10657 rtx op1
= expand_normal (arg1
);
10659 if (icode
== CODE_FOR_nothing
)
10660 /* Builtin not supported on this processor. */
10663 /* If we got invalid arguments bail out before generating bad rtl. */
10664 if (arg0
== error_mark_node
|| arg1
== error_mark_node
)
10668 || GET_MODE (target
) != tmode
10669 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
10670 target
= gen_reg_rtx (tmode
);
10672 op1
= copy_to_mode_reg (mode1
, op1
);
10674 if (op0
== const0_rtx
)
10676 addr
= gen_rtx_MEM (blk
? BLKmode
: tmode
, op1
);
10680 op0
= copy_to_mode_reg (mode0
, op0
);
10681 addr
= gen_rtx_MEM (blk
? BLKmode
: tmode
, gen_rtx_PLUS (Pmode
, op0
, op1
));
10684 pat
= GEN_FCN (icode
) (target
, addr
);
10694 spe_expand_stv_builtin (enum insn_code icode
, tree exp
)
10696 tree arg0
= CALL_EXPR_ARG (exp
, 0);
10697 tree arg1
= CALL_EXPR_ARG (exp
, 1);
10698 tree arg2
= CALL_EXPR_ARG (exp
, 2);
10699 rtx op0
= expand_normal (arg0
);
10700 rtx op1
= expand_normal (arg1
);
10701 rtx op2
= expand_normal (arg2
);
10703 enum machine_mode mode0
= insn_data
[icode
].operand
[0].mode
;
10704 enum machine_mode mode1
= insn_data
[icode
].operand
[1].mode
;
10705 enum machine_mode mode2
= insn_data
[icode
].operand
[2].mode
;
10707 /* Invalid arguments. Bail before doing anything stoopid! */
10708 if (arg0
== error_mark_node
10709 || arg1
== error_mark_node
10710 || arg2
== error_mark_node
)
10713 if (! (*insn_data
[icode
].operand
[2].predicate
) (op0
, mode2
))
10714 op0
= copy_to_mode_reg (mode2
, op0
);
10715 if (! (*insn_data
[icode
].operand
[0].predicate
) (op1
, mode0
))
10716 op1
= copy_to_mode_reg (mode0
, op1
);
10717 if (! (*insn_data
[icode
].operand
[1].predicate
) (op2
, mode1
))
10718 op2
= copy_to_mode_reg (mode1
, op2
);
10720 pat
= GEN_FCN (icode
) (op1
, op2
, op0
);
10727 paired_expand_stv_builtin (enum insn_code icode
, tree exp
)
10729 tree arg0
= CALL_EXPR_ARG (exp
, 0);
10730 tree arg1
= CALL_EXPR_ARG (exp
, 1);
10731 tree arg2
= CALL_EXPR_ARG (exp
, 2);
10732 rtx op0
= expand_normal (arg0
);
10733 rtx op1
= expand_normal (arg1
);
10734 rtx op2
= expand_normal (arg2
);
10736 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
10737 enum machine_mode mode1
= Pmode
;
10738 enum machine_mode mode2
= Pmode
;
10740 /* Invalid arguments. Bail before doing anything stoopid! */
10741 if (arg0
== error_mark_node
10742 || arg1
== error_mark_node
10743 || arg2
== error_mark_node
)
10746 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, tmode
))
10747 op0
= copy_to_mode_reg (tmode
, op0
);
10749 op2
= copy_to_mode_reg (mode2
, op2
);
10751 if (op1
== const0_rtx
)
10753 addr
= gen_rtx_MEM (tmode
, op2
);
10757 op1
= copy_to_mode_reg (mode1
, op1
);
10758 addr
= gen_rtx_MEM (tmode
, gen_rtx_PLUS (Pmode
, op1
, op2
));
10761 pat
= GEN_FCN (icode
) (addr
, op0
);
10768 altivec_expand_stv_builtin (enum insn_code icode
, tree exp
)
10770 tree arg0
= CALL_EXPR_ARG (exp
, 0);
10771 tree arg1
= CALL_EXPR_ARG (exp
, 1);
10772 tree arg2
= CALL_EXPR_ARG (exp
, 2);
10773 rtx op0
= expand_normal (arg0
);
10774 rtx op1
= expand_normal (arg1
);
10775 rtx op2
= expand_normal (arg2
);
10777 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
10778 enum machine_mode mode1
= Pmode
;
10779 enum machine_mode mode2
= Pmode
;
10781 /* Invalid arguments. Bail before doing anything stoopid! */
10782 if (arg0
== error_mark_node
10783 || arg1
== error_mark_node
10784 || arg2
== error_mark_node
)
10787 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, tmode
))
10788 op0
= copy_to_mode_reg (tmode
, op0
);
10790 op2
= copy_to_mode_reg (mode2
, op2
);
10792 if (op1
== const0_rtx
)
10794 addr
= gen_rtx_MEM (tmode
, op2
);
10798 op1
= copy_to_mode_reg (mode1
, op1
);
10799 addr
= gen_rtx_MEM (tmode
, gen_rtx_PLUS (Pmode
, op1
, op2
));
10802 pat
= GEN_FCN (icode
) (addr
, op0
);
10809 rs6000_expand_ternop_builtin (enum insn_code icode
, tree exp
, rtx target
)
10812 tree arg0
= CALL_EXPR_ARG (exp
, 0);
10813 tree arg1
= CALL_EXPR_ARG (exp
, 1);
10814 tree arg2
= CALL_EXPR_ARG (exp
, 2);
10815 rtx op0
= expand_normal (arg0
);
10816 rtx op1
= expand_normal (arg1
);
10817 rtx op2
= expand_normal (arg2
);
10818 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
10819 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
10820 enum machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
10821 enum machine_mode mode2
= insn_data
[icode
].operand
[3].mode
;
10823 if (icode
== CODE_FOR_nothing
)
10824 /* Builtin not supported on this processor. */
10827 /* If we got invalid arguments bail out before generating bad rtl. */
10828 if (arg0
== error_mark_node
10829 || arg1
== error_mark_node
10830 || arg2
== error_mark_node
)
10835 case CODE_FOR_altivec_vsldoi_v4sf
:
10836 case CODE_FOR_altivec_vsldoi_v4si
:
10837 case CODE_FOR_altivec_vsldoi_v8hi
:
10838 case CODE_FOR_altivec_vsldoi_v16qi
:
10839 /* Only allow 4-bit unsigned literals. */
10841 if (TREE_CODE (arg2
) != INTEGER_CST
10842 || TREE_INT_CST_LOW (arg2
) & ~0xf)
10844 error ("argument 3 must be a 4-bit unsigned literal");
10849 case CODE_FOR_vsx_xxpermdi_v2df
:
10850 case CODE_FOR_vsx_xxpermdi_v2di
:
10851 case CODE_FOR_vsx_xxsldwi_v16qi
:
10852 case CODE_FOR_vsx_xxsldwi_v8hi
:
10853 case CODE_FOR_vsx_xxsldwi_v4si
:
10854 case CODE_FOR_vsx_xxsldwi_v4sf
:
10855 case CODE_FOR_vsx_xxsldwi_v2di
:
10856 case CODE_FOR_vsx_xxsldwi_v2df
:
10857 /* Only allow 2-bit unsigned literals. */
10859 if (TREE_CODE (arg2
) != INTEGER_CST
10860 || TREE_INT_CST_LOW (arg2
) & ~0x3)
10862 error ("argument 3 must be a 2-bit unsigned literal");
10867 case CODE_FOR_vsx_set_v2df
:
10868 case CODE_FOR_vsx_set_v2di
:
10869 /* Only allow 1-bit unsigned literals. */
10871 if (TREE_CODE (arg2
) != INTEGER_CST
10872 || TREE_INT_CST_LOW (arg2
) & ~0x1)
10874 error ("argument 3 must be a 1-bit unsigned literal");
10884 || GET_MODE (target
) != tmode
10885 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
10886 target
= gen_reg_rtx (tmode
);
10888 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
10889 op0
= copy_to_mode_reg (mode0
, op0
);
10890 if (! (*insn_data
[icode
].operand
[2].predicate
) (op1
, mode1
))
10891 op1
= copy_to_mode_reg (mode1
, op1
);
10892 if (! (*insn_data
[icode
].operand
[3].predicate
) (op2
, mode2
))
10893 op2
= copy_to_mode_reg (mode2
, op2
);
10895 if (TARGET_PAIRED_FLOAT
&& icode
== CODE_FOR_selv2sf4
)
10896 pat
= GEN_FCN (icode
) (target
, op0
, op1
, op2
, CONST0_RTX (SFmode
));
10898 pat
= GEN_FCN (icode
) (target
, op0
, op1
, op2
);
10906 /* Expand the lvx builtins. */
10908 altivec_expand_ld_builtin (tree exp
, rtx target
, bool *expandedp
)
10910 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
10911 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
10913 enum machine_mode tmode
, mode0
;
10915 enum insn_code icode
;
10919 case ALTIVEC_BUILTIN_LD_INTERNAL_16qi
:
10920 icode
= CODE_FOR_vector_load_v16qi
;
10922 case ALTIVEC_BUILTIN_LD_INTERNAL_8hi
:
10923 icode
= CODE_FOR_vector_load_v8hi
;
10925 case ALTIVEC_BUILTIN_LD_INTERNAL_4si
:
10926 icode
= CODE_FOR_vector_load_v4si
;
10928 case ALTIVEC_BUILTIN_LD_INTERNAL_4sf
:
10929 icode
= CODE_FOR_vector_load_v4sf
;
10932 *expandedp
= false;
10938 arg0
= CALL_EXPR_ARG (exp
, 0);
10939 op0
= expand_normal (arg0
);
10940 tmode
= insn_data
[icode
].operand
[0].mode
;
10941 mode0
= insn_data
[icode
].operand
[1].mode
;
10944 || GET_MODE (target
) != tmode
10945 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
10946 target
= gen_reg_rtx (tmode
);
10948 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
10949 op0
= gen_rtx_MEM (mode0
, copy_to_mode_reg (Pmode
, op0
));
10951 pat
= GEN_FCN (icode
) (target
, op0
);
10958 /* Expand the stvx builtins. */
10960 altivec_expand_st_builtin (tree exp
, rtx target ATTRIBUTE_UNUSED
,
10963 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
10964 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
10966 enum machine_mode mode0
, mode1
;
10968 enum insn_code icode
;
10972 case ALTIVEC_BUILTIN_ST_INTERNAL_16qi
:
10973 icode
= CODE_FOR_vector_store_v16qi
;
10975 case ALTIVEC_BUILTIN_ST_INTERNAL_8hi
:
10976 icode
= CODE_FOR_vector_store_v8hi
;
10978 case ALTIVEC_BUILTIN_ST_INTERNAL_4si
:
10979 icode
= CODE_FOR_vector_store_v4si
;
10981 case ALTIVEC_BUILTIN_ST_INTERNAL_4sf
:
10982 icode
= CODE_FOR_vector_store_v4sf
;
10985 *expandedp
= false;
10989 arg0
= CALL_EXPR_ARG (exp
, 0);
10990 arg1
= CALL_EXPR_ARG (exp
, 1);
10991 op0
= expand_normal (arg0
);
10992 op1
= expand_normal (arg1
);
10993 mode0
= insn_data
[icode
].operand
[0].mode
;
10994 mode1
= insn_data
[icode
].operand
[1].mode
;
10996 if (! (*insn_data
[icode
].operand
[0].predicate
) (op0
, mode0
))
10997 op0
= gen_rtx_MEM (mode0
, copy_to_mode_reg (Pmode
, op0
));
10998 if (! (*insn_data
[icode
].operand
[1].predicate
) (op1
, mode1
))
10999 op1
= copy_to_mode_reg (mode1
, op1
);
11001 pat
= GEN_FCN (icode
) (op0
, op1
);
11009 /* Expand the dst builtins. */
11011 altivec_expand_dst_builtin (tree exp
, rtx target ATTRIBUTE_UNUSED
,
11014 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
11015 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
11016 tree arg0
, arg1
, arg2
;
11017 enum machine_mode mode0
, mode1
;
11018 rtx pat
, op0
, op1
, op2
;
11019 const struct builtin_description
*d
;
11022 *expandedp
= false;
11024 /* Handle DST variants. */
11026 for (i
= 0; i
< ARRAY_SIZE (bdesc_dst
); i
++, d
++)
11027 if (d
->code
== fcode
)
11029 arg0
= CALL_EXPR_ARG (exp
, 0);
11030 arg1
= CALL_EXPR_ARG (exp
, 1);
11031 arg2
= CALL_EXPR_ARG (exp
, 2);
11032 op0
= expand_normal (arg0
);
11033 op1
= expand_normal (arg1
);
11034 op2
= expand_normal (arg2
);
11035 mode0
= insn_data
[d
->icode
].operand
[0].mode
;
11036 mode1
= insn_data
[d
->icode
].operand
[1].mode
;
11038 /* Invalid arguments, bail out before generating bad rtl. */
11039 if (arg0
== error_mark_node
11040 || arg1
== error_mark_node
11041 || arg2
== error_mark_node
)
11046 if (TREE_CODE (arg2
) != INTEGER_CST
11047 || TREE_INT_CST_LOW (arg2
) & ~0x3)
11049 error ("argument to %qs must be a 2-bit unsigned literal", d
->name
);
11053 if (! (*insn_data
[d
->icode
].operand
[0].predicate
) (op0
, mode0
))
11054 op0
= copy_to_mode_reg (Pmode
, op0
);
11055 if (! (*insn_data
[d
->icode
].operand
[1].predicate
) (op1
, mode1
))
11056 op1
= copy_to_mode_reg (mode1
, op1
);
11058 pat
= GEN_FCN (d
->icode
) (op0
, op1
, op2
);
11068 /* Expand vec_init builtin. */
11070 altivec_expand_vec_init_builtin (tree type
, tree exp
, rtx target
)
11072 enum machine_mode tmode
= TYPE_MODE (type
);
11073 enum machine_mode inner_mode
= GET_MODE_INNER (tmode
);
11074 int i
, n_elt
= GET_MODE_NUNITS (tmode
);
11075 rtvec v
= rtvec_alloc (n_elt
);
11077 gcc_assert (VECTOR_MODE_P (tmode
));
11078 gcc_assert (n_elt
== call_expr_nargs (exp
));
11080 for (i
= 0; i
< n_elt
; ++i
)
11082 rtx x
= expand_normal (CALL_EXPR_ARG (exp
, i
));
11083 RTVEC_ELT (v
, i
) = gen_lowpart (inner_mode
, x
);
11086 if (!target
|| !register_operand (target
, tmode
))
11087 target
= gen_reg_rtx (tmode
);
11089 rs6000_expand_vector_init (target
, gen_rtx_PARALLEL (tmode
, v
));
11093 /* Return the integer constant in ARG. Constrain it to be in the range
11094 of the subparts of VEC_TYPE; issue an error if not. */
11097 get_element_number (tree vec_type
, tree arg
)
11099 unsigned HOST_WIDE_INT elt
, max
= TYPE_VECTOR_SUBPARTS (vec_type
) - 1;
11101 if (!host_integerp (arg
, 1)
11102 || (elt
= tree_low_cst (arg
, 1), elt
> max
))
11104 error ("selector must be an integer constant in the range 0..%wi", max
);
11111 /* Expand vec_set builtin. */
11113 altivec_expand_vec_set_builtin (tree exp
)
11115 enum machine_mode tmode
, mode1
;
11116 tree arg0
, arg1
, arg2
;
11120 arg0
= CALL_EXPR_ARG (exp
, 0);
11121 arg1
= CALL_EXPR_ARG (exp
, 1);
11122 arg2
= CALL_EXPR_ARG (exp
, 2);
11124 tmode
= TYPE_MODE (TREE_TYPE (arg0
));
11125 mode1
= TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0
)));
11126 gcc_assert (VECTOR_MODE_P (tmode
));
11128 op0
= expand_expr (arg0
, NULL_RTX
, tmode
, EXPAND_NORMAL
);
11129 op1
= expand_expr (arg1
, NULL_RTX
, mode1
, EXPAND_NORMAL
);
11130 elt
= get_element_number (TREE_TYPE (arg0
), arg2
);
11132 if (GET_MODE (op1
) != mode1
&& GET_MODE (op1
) != VOIDmode
)
11133 op1
= convert_modes (mode1
, GET_MODE (op1
), op1
, true);
11135 op0
= force_reg (tmode
, op0
);
11136 op1
= force_reg (mode1
, op1
);
11138 rs6000_expand_vector_set (op0
, op1
, elt
);
11143 /* Expand vec_ext builtin. */
11145 altivec_expand_vec_ext_builtin (tree exp
, rtx target
)
11147 enum machine_mode tmode
, mode0
;
11152 arg0
= CALL_EXPR_ARG (exp
, 0);
11153 arg1
= CALL_EXPR_ARG (exp
, 1);
11155 op0
= expand_normal (arg0
);
11156 elt
= get_element_number (TREE_TYPE (arg0
), arg1
);
11158 tmode
= TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0
)));
11159 mode0
= TYPE_MODE (TREE_TYPE (arg0
));
11160 gcc_assert (VECTOR_MODE_P (mode0
));
11162 op0
= force_reg (mode0
, op0
);
11164 if (optimize
|| !target
|| !register_operand (target
, tmode
))
11165 target
= gen_reg_rtx (tmode
);
11167 rs6000_expand_vector_extract (target
, op0
, elt
);
11172 /* Expand the builtin in EXP and store the result in TARGET. Store
11173 true in *EXPANDEDP if we found a builtin to expand. */
11175 altivec_expand_builtin (tree exp
, rtx target
, bool *expandedp
)
11177 const struct builtin_description
*d
;
11178 const struct builtin_description_predicates
*dp
;
11180 enum insn_code icode
;
11181 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
11184 enum machine_mode tmode
, mode0
;
11185 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
11187 if ((fcode
>= ALTIVEC_BUILTIN_OVERLOADED_FIRST
11188 && fcode
<= ALTIVEC_BUILTIN_OVERLOADED_LAST
)
11189 || (fcode
>= VSX_BUILTIN_OVERLOADED_FIRST
11190 && fcode
<= VSX_BUILTIN_OVERLOADED_LAST
))
11193 error ("unresolved overload for Altivec builtin %qF", fndecl
);
11197 target
= altivec_expand_ld_builtin (exp
, target
, expandedp
);
11201 target
= altivec_expand_st_builtin (exp
, target
, expandedp
);
11205 target
= altivec_expand_dst_builtin (exp
, target
, expandedp
);
11213 case ALTIVEC_BUILTIN_STVX
:
11214 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx
, exp
);
11215 case ALTIVEC_BUILTIN_STVEBX
:
11216 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvebx
, exp
);
11217 case ALTIVEC_BUILTIN_STVEHX
:
11218 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvehx
, exp
);
11219 case ALTIVEC_BUILTIN_STVEWX
:
11220 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvewx
, exp
);
11221 case ALTIVEC_BUILTIN_STVXL
:
11222 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvxl
, exp
);
11224 case ALTIVEC_BUILTIN_STVLX
:
11225 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlx
, exp
);
11226 case ALTIVEC_BUILTIN_STVLXL
:
11227 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlxl
, exp
);
11228 case ALTIVEC_BUILTIN_STVRX
:
11229 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrx
, exp
);
11230 case ALTIVEC_BUILTIN_STVRXL
:
11231 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrxl
, exp
);
11233 case ALTIVEC_BUILTIN_MFVSCR
:
11234 icode
= CODE_FOR_altivec_mfvscr
;
11235 tmode
= insn_data
[icode
].operand
[0].mode
;
11238 || GET_MODE (target
) != tmode
11239 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
11240 target
= gen_reg_rtx (tmode
);
11242 pat
= GEN_FCN (icode
) (target
);
11248 case ALTIVEC_BUILTIN_MTVSCR
:
11249 icode
= CODE_FOR_altivec_mtvscr
;
11250 arg0
= CALL_EXPR_ARG (exp
, 0);
11251 op0
= expand_normal (arg0
);
11252 mode0
= insn_data
[icode
].operand
[0].mode
;
11254 /* If we got invalid arguments bail out before generating bad rtl. */
11255 if (arg0
== error_mark_node
)
11258 if (! (*insn_data
[icode
].operand
[0].predicate
) (op0
, mode0
))
11259 op0
= copy_to_mode_reg (mode0
, op0
);
11261 pat
= GEN_FCN (icode
) (op0
);
11266 case ALTIVEC_BUILTIN_DSSALL
:
11267 emit_insn (gen_altivec_dssall ());
11270 case ALTIVEC_BUILTIN_DSS
:
11271 icode
= CODE_FOR_altivec_dss
;
11272 arg0
= CALL_EXPR_ARG (exp
, 0);
11274 op0
= expand_normal (arg0
);
11275 mode0
= insn_data
[icode
].operand
[0].mode
;
11277 /* If we got invalid arguments bail out before generating bad rtl. */
11278 if (arg0
== error_mark_node
)
11281 if (TREE_CODE (arg0
) != INTEGER_CST
11282 || TREE_INT_CST_LOW (arg0
) & ~0x3)
11284 error ("argument to dss must be a 2-bit unsigned literal");
11288 if (! (*insn_data
[icode
].operand
[0].predicate
) (op0
, mode0
))
11289 op0
= copy_to_mode_reg (mode0
, op0
);
11291 emit_insn (gen_altivec_dss (op0
));
11294 case ALTIVEC_BUILTIN_VEC_INIT_V4SI
:
11295 case ALTIVEC_BUILTIN_VEC_INIT_V8HI
:
11296 case ALTIVEC_BUILTIN_VEC_INIT_V16QI
:
11297 case ALTIVEC_BUILTIN_VEC_INIT_V4SF
:
11298 case VSX_BUILTIN_VEC_INIT_V2DF
:
11299 case VSX_BUILTIN_VEC_INIT_V2DI
:
11300 return altivec_expand_vec_init_builtin (TREE_TYPE (exp
), exp
, target
);
11302 case ALTIVEC_BUILTIN_VEC_SET_V4SI
:
11303 case ALTIVEC_BUILTIN_VEC_SET_V8HI
:
11304 case ALTIVEC_BUILTIN_VEC_SET_V16QI
:
11305 case ALTIVEC_BUILTIN_VEC_SET_V4SF
:
11306 case VSX_BUILTIN_VEC_SET_V2DF
:
11307 case VSX_BUILTIN_VEC_SET_V2DI
:
11308 return altivec_expand_vec_set_builtin (exp
);
11310 case ALTIVEC_BUILTIN_VEC_EXT_V4SI
:
11311 case ALTIVEC_BUILTIN_VEC_EXT_V8HI
:
11312 case ALTIVEC_BUILTIN_VEC_EXT_V16QI
:
11313 case ALTIVEC_BUILTIN_VEC_EXT_V4SF
:
11314 case VSX_BUILTIN_VEC_EXT_V2DF
:
11315 case VSX_BUILTIN_VEC_EXT_V2DI
:
11316 return altivec_expand_vec_ext_builtin (exp
, target
);
11320 /* Fall through. */
11323 /* Expand abs* operations. */
11325 for (i
= 0; i
< ARRAY_SIZE (bdesc_abs
); i
++, d
++)
11326 if (d
->code
== fcode
)
11327 return altivec_expand_abs_builtin (d
->icode
, exp
, target
);
11329 /* Expand the AltiVec predicates. */
11330 dp
= bdesc_altivec_preds
;
11331 for (i
= 0; i
< ARRAY_SIZE (bdesc_altivec_preds
); i
++, dp
++)
11332 if (dp
->code
== fcode
)
11333 return altivec_expand_predicate_builtin (dp
->icode
, exp
, target
);
11335 /* LV* are funky. We initialized them differently. */
11338 case ALTIVEC_BUILTIN_LVSL
:
11339 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsl
,
11340 exp
, target
, false);
11341 case ALTIVEC_BUILTIN_LVSR
:
11342 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsr
,
11343 exp
, target
, false);
11344 case ALTIVEC_BUILTIN_LVEBX
:
11345 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvebx
,
11346 exp
, target
, false);
11347 case ALTIVEC_BUILTIN_LVEHX
:
11348 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvehx
,
11349 exp
, target
, false);
11350 case ALTIVEC_BUILTIN_LVEWX
:
11351 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvewx
,
11352 exp
, target
, false);
11353 case ALTIVEC_BUILTIN_LVXL
:
11354 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvxl
,
11355 exp
, target
, false);
11356 case ALTIVEC_BUILTIN_LVX
:
11357 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx
,
11358 exp
, target
, false);
11359 case ALTIVEC_BUILTIN_LVLX
:
11360 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlx
,
11361 exp
, target
, true);
11362 case ALTIVEC_BUILTIN_LVLXL
:
11363 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlxl
,
11364 exp
, target
, true);
11365 case ALTIVEC_BUILTIN_LVRX
:
11366 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrx
,
11367 exp
, target
, true);
11368 case ALTIVEC_BUILTIN_LVRXL
:
11369 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrxl
,
11370 exp
, target
, true);
11373 /* Fall through. */
11376 *expandedp
= false;
11380 /* Expand the builtin in EXP and store the result in TARGET. Store
11381 true in *EXPANDEDP if we found a builtin to expand. */
11383 paired_expand_builtin (tree exp
, rtx target
, bool * expandedp
)
11385 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
11386 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
11387 const struct builtin_description
*d
;
11394 case PAIRED_BUILTIN_STX
:
11395 return paired_expand_stv_builtin (CODE_FOR_paired_stx
, exp
);
11396 case PAIRED_BUILTIN_LX
:
11397 return paired_expand_lv_builtin (CODE_FOR_paired_lx
, exp
, target
);
11400 /* Fall through. */
11403 /* Expand the paired predicates. */
11404 d
= bdesc_paired_preds
;
11405 for (i
= 0; i
< ARRAY_SIZE (bdesc_paired_preds
); i
++, d
++)
11406 if (d
->code
== fcode
)
11407 return paired_expand_predicate_builtin (d
->icode
, exp
, target
);
11409 *expandedp
= false;
11413 /* Binops that need to be initialized manually, but can be expanded
11414 automagically by rs6000_expand_binop_builtin. */
11415 static struct builtin_description bdesc_2arg_spe
[] =
11417 { 0, CODE_FOR_spe_evlddx
, "__builtin_spe_evlddx", SPE_BUILTIN_EVLDDX
},
11418 { 0, CODE_FOR_spe_evldwx
, "__builtin_spe_evldwx", SPE_BUILTIN_EVLDWX
},
11419 { 0, CODE_FOR_spe_evldhx
, "__builtin_spe_evldhx", SPE_BUILTIN_EVLDHX
},
11420 { 0, CODE_FOR_spe_evlwhex
, "__builtin_spe_evlwhex", SPE_BUILTIN_EVLWHEX
},
11421 { 0, CODE_FOR_spe_evlwhoux
, "__builtin_spe_evlwhoux", SPE_BUILTIN_EVLWHOUX
},
11422 { 0, CODE_FOR_spe_evlwhosx
, "__builtin_spe_evlwhosx", SPE_BUILTIN_EVLWHOSX
},
11423 { 0, CODE_FOR_spe_evlwwsplatx
, "__builtin_spe_evlwwsplatx", SPE_BUILTIN_EVLWWSPLATX
},
11424 { 0, CODE_FOR_spe_evlwhsplatx
, "__builtin_spe_evlwhsplatx", SPE_BUILTIN_EVLWHSPLATX
},
11425 { 0, CODE_FOR_spe_evlhhesplatx
, "__builtin_spe_evlhhesplatx", SPE_BUILTIN_EVLHHESPLATX
},
11426 { 0, CODE_FOR_spe_evlhhousplatx
, "__builtin_spe_evlhhousplatx", SPE_BUILTIN_EVLHHOUSPLATX
},
11427 { 0, CODE_FOR_spe_evlhhossplatx
, "__builtin_spe_evlhhossplatx", SPE_BUILTIN_EVLHHOSSPLATX
},
11428 { 0, CODE_FOR_spe_evldd
, "__builtin_spe_evldd", SPE_BUILTIN_EVLDD
},
11429 { 0, CODE_FOR_spe_evldw
, "__builtin_spe_evldw", SPE_BUILTIN_EVLDW
},
11430 { 0, CODE_FOR_spe_evldh
, "__builtin_spe_evldh", SPE_BUILTIN_EVLDH
},
11431 { 0, CODE_FOR_spe_evlwhe
, "__builtin_spe_evlwhe", SPE_BUILTIN_EVLWHE
},
11432 { 0, CODE_FOR_spe_evlwhou
, "__builtin_spe_evlwhou", SPE_BUILTIN_EVLWHOU
},
11433 { 0, CODE_FOR_spe_evlwhos
, "__builtin_spe_evlwhos", SPE_BUILTIN_EVLWHOS
},
11434 { 0, CODE_FOR_spe_evlwwsplat
, "__builtin_spe_evlwwsplat", SPE_BUILTIN_EVLWWSPLAT
},
11435 { 0, CODE_FOR_spe_evlwhsplat
, "__builtin_spe_evlwhsplat", SPE_BUILTIN_EVLWHSPLAT
},
11436 { 0, CODE_FOR_spe_evlhhesplat
, "__builtin_spe_evlhhesplat", SPE_BUILTIN_EVLHHESPLAT
},
11437 { 0, CODE_FOR_spe_evlhhousplat
, "__builtin_spe_evlhhousplat", SPE_BUILTIN_EVLHHOUSPLAT
},
11438 { 0, CODE_FOR_spe_evlhhossplat
, "__builtin_spe_evlhhossplat", SPE_BUILTIN_EVLHHOSSPLAT
}
11441 /* Expand the builtin in EXP and store the result in TARGET. Store
11442 true in *EXPANDEDP if we found a builtin to expand.
11444 This expands the SPE builtins that are not simple unary and binary
11447 spe_expand_builtin (tree exp
, rtx target
, bool *expandedp
)
11449 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
11451 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
11452 enum insn_code icode
;
11453 enum machine_mode tmode
, mode0
;
11455 struct builtin_description
*d
;
11460 /* Syntax check for a 5-bit unsigned immediate. */
11463 case SPE_BUILTIN_EVSTDD
:
11464 case SPE_BUILTIN_EVSTDH
:
11465 case SPE_BUILTIN_EVSTDW
:
11466 case SPE_BUILTIN_EVSTWHE
:
11467 case SPE_BUILTIN_EVSTWHO
:
11468 case SPE_BUILTIN_EVSTWWE
:
11469 case SPE_BUILTIN_EVSTWWO
:
11470 arg1
= CALL_EXPR_ARG (exp
, 2);
11471 if (TREE_CODE (arg1
) != INTEGER_CST
11472 || TREE_INT_CST_LOW (arg1
) & ~0x1f)
11474 error ("argument 2 must be a 5-bit unsigned literal");
11482 /* The evsplat*i instructions are not quite generic. */
11485 case SPE_BUILTIN_EVSPLATFI
:
11486 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplatfi
,
11488 case SPE_BUILTIN_EVSPLATI
:
11489 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplati
,
11495 d
= (struct builtin_description
*) bdesc_2arg_spe
;
11496 for (i
= 0; i
< ARRAY_SIZE (bdesc_2arg_spe
); ++i
, ++d
)
11497 if (d
->code
== fcode
)
11498 return rs6000_expand_binop_builtin (d
->icode
, exp
, target
);
11500 d
= (struct builtin_description
*) bdesc_spe_predicates
;
11501 for (i
= 0; i
< ARRAY_SIZE (bdesc_spe_predicates
); ++i
, ++d
)
11502 if (d
->code
== fcode
)
11503 return spe_expand_predicate_builtin (d
->icode
, exp
, target
);
11505 d
= (struct builtin_description
*) bdesc_spe_evsel
;
11506 for (i
= 0; i
< ARRAY_SIZE (bdesc_spe_evsel
); ++i
, ++d
)
11507 if (d
->code
== fcode
)
11508 return spe_expand_evsel_builtin (d
->icode
, exp
, target
);
11512 case SPE_BUILTIN_EVSTDDX
:
11513 return spe_expand_stv_builtin (CODE_FOR_spe_evstddx
, exp
);
11514 case SPE_BUILTIN_EVSTDHX
:
11515 return spe_expand_stv_builtin (CODE_FOR_spe_evstdhx
, exp
);
11516 case SPE_BUILTIN_EVSTDWX
:
11517 return spe_expand_stv_builtin (CODE_FOR_spe_evstdwx
, exp
);
11518 case SPE_BUILTIN_EVSTWHEX
:
11519 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhex
, exp
);
11520 case SPE_BUILTIN_EVSTWHOX
:
11521 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhox
, exp
);
11522 case SPE_BUILTIN_EVSTWWEX
:
11523 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwex
, exp
);
11524 case SPE_BUILTIN_EVSTWWOX
:
11525 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwox
, exp
);
11526 case SPE_BUILTIN_EVSTDD
:
11527 return spe_expand_stv_builtin (CODE_FOR_spe_evstdd
, exp
);
11528 case SPE_BUILTIN_EVSTDH
:
11529 return spe_expand_stv_builtin (CODE_FOR_spe_evstdh
, exp
);
11530 case SPE_BUILTIN_EVSTDW
:
11531 return spe_expand_stv_builtin (CODE_FOR_spe_evstdw
, exp
);
11532 case SPE_BUILTIN_EVSTWHE
:
11533 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhe
, exp
);
11534 case SPE_BUILTIN_EVSTWHO
:
11535 return spe_expand_stv_builtin (CODE_FOR_spe_evstwho
, exp
);
11536 case SPE_BUILTIN_EVSTWWE
:
11537 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwe
, exp
);
11538 case SPE_BUILTIN_EVSTWWO
:
11539 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwo
, exp
);
11540 case SPE_BUILTIN_MFSPEFSCR
:
11541 icode
= CODE_FOR_spe_mfspefscr
;
11542 tmode
= insn_data
[icode
].operand
[0].mode
;
11545 || GET_MODE (target
) != tmode
11546 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
11547 target
= gen_reg_rtx (tmode
);
11549 pat
= GEN_FCN (icode
) (target
);
11554 case SPE_BUILTIN_MTSPEFSCR
:
11555 icode
= CODE_FOR_spe_mtspefscr
;
11556 arg0
= CALL_EXPR_ARG (exp
, 0);
11557 op0
= expand_normal (arg0
);
11558 mode0
= insn_data
[icode
].operand
[0].mode
;
11560 if (arg0
== error_mark_node
)
11563 if (! (*insn_data
[icode
].operand
[0].predicate
) (op0
, mode0
))
11564 op0
= copy_to_mode_reg (mode0
, op0
);
11566 pat
= GEN_FCN (icode
) (op0
);
11574 *expandedp
= false;
11579 paired_expand_predicate_builtin (enum insn_code icode
, tree exp
, rtx target
)
11581 rtx pat
, scratch
, tmp
;
11582 tree form
= CALL_EXPR_ARG (exp
, 0);
11583 tree arg0
= CALL_EXPR_ARG (exp
, 1);
11584 tree arg1
= CALL_EXPR_ARG (exp
, 2);
11585 rtx op0
= expand_normal (arg0
);
11586 rtx op1
= expand_normal (arg1
);
11587 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
11588 enum machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
11590 enum rtx_code code
;
11592 if (TREE_CODE (form
) != INTEGER_CST
)
11594 error ("argument 1 of __builtin_paired_predicate must be a constant");
11598 form_int
= TREE_INT_CST_LOW (form
);
11600 gcc_assert (mode0
== mode1
);
11602 if (arg0
== error_mark_node
|| arg1
== error_mark_node
)
11606 || GET_MODE (target
) != SImode
11607 || !(*insn_data
[icode
].operand
[0].predicate
) (target
, SImode
))
11608 target
= gen_reg_rtx (SImode
);
11609 if (!(*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
11610 op0
= copy_to_mode_reg (mode0
, op0
);
11611 if (!(*insn_data
[icode
].operand
[2].predicate
) (op1
, mode1
))
11612 op1
= copy_to_mode_reg (mode1
, op1
);
11614 scratch
= gen_reg_rtx (CCFPmode
);
11616 pat
= GEN_FCN (icode
) (scratch
, op0
, op1
);
11638 emit_insn (gen_move_from_CR_ov_bit (target
, scratch
));
11641 error ("argument 1 of __builtin_paired_predicate is out of range");
11645 tmp
= gen_rtx_fmt_ee (code
, SImode
, scratch
, const0_rtx
);
11646 emit_move_insn (target
, tmp
);
11651 spe_expand_predicate_builtin (enum insn_code icode
, tree exp
, rtx target
)
11653 rtx pat
, scratch
, tmp
;
11654 tree form
= CALL_EXPR_ARG (exp
, 0);
11655 tree arg0
= CALL_EXPR_ARG (exp
, 1);
11656 tree arg1
= CALL_EXPR_ARG (exp
, 2);
11657 rtx op0
= expand_normal (arg0
);
11658 rtx op1
= expand_normal (arg1
);
11659 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
11660 enum machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
11662 enum rtx_code code
;
11664 if (TREE_CODE (form
) != INTEGER_CST
)
11666 error ("argument 1 of __builtin_spe_predicate must be a constant");
11670 form_int
= TREE_INT_CST_LOW (form
);
11672 gcc_assert (mode0
== mode1
);
11674 if (arg0
== error_mark_node
|| arg1
== error_mark_node
)
11678 || GET_MODE (target
) != SImode
11679 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, SImode
))
11680 target
= gen_reg_rtx (SImode
);
11682 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
11683 op0
= copy_to_mode_reg (mode0
, op0
);
11684 if (! (*insn_data
[icode
].operand
[2].predicate
) (op1
, mode1
))
11685 op1
= copy_to_mode_reg (mode1
, op1
);
11687 scratch
= gen_reg_rtx (CCmode
);
11689 pat
= GEN_FCN (icode
) (scratch
, op0
, op1
);
11694 /* There are 4 variants for each predicate: _any_, _all_, _upper_,
11695 _lower_. We use one compare, but look in different bits of the
11696 CR for each variant.
11698 There are 2 elements in each SPE simd type (upper/lower). The CR
11699 bits are set as follows:
11701 BIT0 | BIT 1 | BIT 2 | BIT 3
11702 U | L | (U | L) | (U & L)
11704 So, for an "all" relationship, BIT 3 would be set.
11705 For an "any" relationship, BIT 2 would be set. Etc.
11707 Following traditional nomenclature, these bits map to:
11709 BIT0 | BIT 1 | BIT 2 | BIT 3
11712 Later, we will generate rtl to look in the LT/EQ/EQ/OV bits.
11717 /* All variant. OV bit. */
11719 /* We need to get to the OV bit, which is the ORDERED bit. We
11720 could generate (ordered:SI (reg:CC xx) (const_int 0)), but
11721 that's ugly and will make validate_condition_mode die.
11722 So let's just use another pattern. */
11723 emit_insn (gen_move_from_CR_ov_bit (target
, scratch
));
11725 /* Any variant. EQ bit. */
11729 /* Upper variant. LT bit. */
11733 /* Lower variant. GT bit. */
11738 error ("argument 1 of __builtin_spe_predicate is out of range");
11742 tmp
= gen_rtx_fmt_ee (code
, SImode
, scratch
, const0_rtx
);
11743 emit_move_insn (target
, tmp
);
11748 /* The evsel builtins look like this:
11750 e = __builtin_spe_evsel_OP (a, b, c, d);
11752 and work like this:
11754 e[upper] = a[upper] *OP* b[upper] ? c[upper] : d[upper];
11755 e[lower] = a[lower] *OP* b[lower] ? c[lower] : d[lower];
11759 spe_expand_evsel_builtin (enum insn_code icode
, tree exp
, rtx target
)
11762 tree arg0
= CALL_EXPR_ARG (exp
, 0);
11763 tree arg1
= CALL_EXPR_ARG (exp
, 1);
11764 tree arg2
= CALL_EXPR_ARG (exp
, 2);
11765 tree arg3
= CALL_EXPR_ARG (exp
, 3);
11766 rtx op0
= expand_normal (arg0
);
11767 rtx op1
= expand_normal (arg1
);
11768 rtx op2
= expand_normal (arg2
);
11769 rtx op3
= expand_normal (arg3
);
11770 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
11771 enum machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
11773 gcc_assert (mode0
== mode1
);
11775 if (arg0
== error_mark_node
|| arg1
== error_mark_node
11776 || arg2
== error_mark_node
|| arg3
== error_mark_node
)
11780 || GET_MODE (target
) != mode0
11781 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, mode0
))
11782 target
= gen_reg_rtx (mode0
);
11784 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
11785 op0
= copy_to_mode_reg (mode0
, op0
);
11786 if (! (*insn_data
[icode
].operand
[1].predicate
) (op1
, mode1
))
11787 op1
= copy_to_mode_reg (mode0
, op1
);
11788 if (! (*insn_data
[icode
].operand
[1].predicate
) (op2
, mode1
))
11789 op2
= copy_to_mode_reg (mode0
, op2
);
11790 if (! (*insn_data
[icode
].operand
[1].predicate
) (op3
, mode1
))
11791 op3
= copy_to_mode_reg (mode0
, op3
);
11793 /* Generate the compare. */
11794 scratch
= gen_reg_rtx (CCmode
);
11795 pat
= GEN_FCN (icode
) (scratch
, op0
, op1
);
11800 if (mode0
== V2SImode
)
11801 emit_insn (gen_spe_evsel (target
, op2
, op3
, scratch
));
11803 emit_insn (gen_spe_evsel_fs (target
, op2
, op3
, scratch
));
11808 /* Expand an expression EXP that calls a built-in function,
11809 with result going to TARGET if that's convenient
11810 (and in mode MODE if that's convenient).
11811 SUBTARGET may be used as the target for computing one of EXP's operands.
11812 IGNORE is nonzero if the value is to be ignored. */
11815 rs6000_expand_builtin (tree exp
, rtx target
, rtx subtarget ATTRIBUTE_UNUSED
,
11816 enum machine_mode mode ATTRIBUTE_UNUSED
,
11817 int ignore ATTRIBUTE_UNUSED
)
11819 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
11820 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
11821 const struct builtin_description
*d
;
11828 case RS6000_BUILTIN_RECIP
:
11829 return rs6000_expand_binop_builtin (CODE_FOR_recipdf3
, exp
, target
);
11831 case RS6000_BUILTIN_RECIPF
:
11832 return rs6000_expand_binop_builtin (CODE_FOR_recipsf3
, exp
, target
);
11834 case RS6000_BUILTIN_RSQRTF
:
11835 return rs6000_expand_unop_builtin (CODE_FOR_rsqrtsf2
, exp
, target
);
11837 case RS6000_BUILTIN_RSQRT
:
11838 return rs6000_expand_unop_builtin (CODE_FOR_rsqrtdf2
, exp
, target
);
11840 case RS6000_BUILTIN_BSWAP_HI
:
11841 return rs6000_expand_unop_builtin (CODE_FOR_bswaphi2
, exp
, target
);
11843 case POWER7_BUILTIN_BPERMD
:
11844 return rs6000_expand_binop_builtin (((TARGET_64BIT
)
11845 ? CODE_FOR_bpermd_di
11846 : CODE_FOR_bpermd_si
), exp
, target
);
11848 case ALTIVEC_BUILTIN_MASK_FOR_LOAD
:
11849 case ALTIVEC_BUILTIN_MASK_FOR_STORE
:
11851 int icode
= (int) CODE_FOR_altivec_lvsr
;
11852 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
11853 enum machine_mode mode
= insn_data
[icode
].operand
[1].mode
;
11857 gcc_assert (TARGET_ALTIVEC
);
11859 arg
= CALL_EXPR_ARG (exp
, 0);
11860 gcc_assert (POINTER_TYPE_P (TREE_TYPE (arg
)));
11861 op
= expand_expr (arg
, NULL_RTX
, Pmode
, EXPAND_NORMAL
);
11862 addr
= memory_address (mode
, op
);
11863 if (fcode
== ALTIVEC_BUILTIN_MASK_FOR_STORE
)
11867 /* For the load case need to negate the address. */
11868 op
= gen_reg_rtx (GET_MODE (addr
));
11869 emit_insn (gen_rtx_SET (VOIDmode
, op
,
11870 gen_rtx_NEG (GET_MODE (addr
), addr
)));
11872 op
= gen_rtx_MEM (mode
, op
);
11875 || GET_MODE (target
) != tmode
11876 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
11877 target
= gen_reg_rtx (tmode
);
11879 /*pat = gen_altivec_lvsr (target, op);*/
11880 pat
= GEN_FCN (icode
) (target
, op
);
11888 case ALTIVEC_BUILTIN_VCFUX
:
11889 case ALTIVEC_BUILTIN_VCFSX
:
11890 case ALTIVEC_BUILTIN_VCTUXS
:
11891 case ALTIVEC_BUILTIN_VCTSXS
:
11892 /* FIXME: There's got to be a nicer way to handle this case than
11893 constructing a new CALL_EXPR. */
11894 if (call_expr_nargs (exp
) == 1)
11896 exp
= build_call_nary (TREE_TYPE (exp
), CALL_EXPR_FN (exp
),
11897 2, CALL_EXPR_ARG (exp
, 0), integer_zero_node
);
11905 if (TARGET_ALTIVEC
)
11907 ret
= altivec_expand_builtin (exp
, target
, &success
);
11914 ret
= spe_expand_builtin (exp
, target
, &success
);
11919 if (TARGET_PAIRED_FLOAT
)
11921 ret
= paired_expand_builtin (exp
, target
, &success
);
11927 gcc_assert (TARGET_ALTIVEC
|| TARGET_VSX
|| TARGET_SPE
|| TARGET_PAIRED_FLOAT
);
11929 /* Handle simple unary operations. */
11930 d
= (struct builtin_description
*) bdesc_1arg
;
11931 for (i
= 0; i
< ARRAY_SIZE (bdesc_1arg
); i
++, d
++)
11932 if (d
->code
== fcode
)
11933 return rs6000_expand_unop_builtin (d
->icode
, exp
, target
);
11935 /* Handle simple binary operations. */
11936 d
= (struct builtin_description
*) bdesc_2arg
;
11937 for (i
= 0; i
< ARRAY_SIZE (bdesc_2arg
); i
++, d
++)
11938 if (d
->code
== fcode
)
11939 return rs6000_expand_binop_builtin (d
->icode
, exp
, target
);
11941 /* Handle simple ternary operations. */
11943 for (i
= 0; i
< ARRAY_SIZE (bdesc_3arg
); i
++, d
++)
11944 if (d
->code
== fcode
)
11945 return rs6000_expand_ternop_builtin (d
->icode
, exp
, target
);
11947 gcc_unreachable ();
11951 rs6000_init_builtins (void)
11956 V2SI_type_node
= build_vector_type (intSI_type_node
, 2);
11957 V2SF_type_node
= build_vector_type (float_type_node
, 2);
11958 V2DI_type_node
= build_vector_type (intDI_type_node
, 2);
11959 V2DF_type_node
= build_vector_type (double_type_node
, 2);
11960 V4HI_type_node
= build_vector_type (intHI_type_node
, 4);
11961 V4SI_type_node
= build_vector_type (intSI_type_node
, 4);
11962 V4SF_type_node
= build_vector_type (float_type_node
, 4);
11963 V8HI_type_node
= build_vector_type (intHI_type_node
, 8);
11964 V16QI_type_node
= build_vector_type (intQI_type_node
, 16);
11966 unsigned_V16QI_type_node
= build_vector_type (unsigned_intQI_type_node
, 16);
11967 unsigned_V8HI_type_node
= build_vector_type (unsigned_intHI_type_node
, 8);
11968 unsigned_V4SI_type_node
= build_vector_type (unsigned_intSI_type_node
, 4);
11969 unsigned_V2DI_type_node
= build_vector_type (unsigned_intDI_type_node
, 2);
11971 opaque_V2SF_type_node
= build_opaque_vector_type (float_type_node
, 2);
11972 opaque_V2SI_type_node
= build_opaque_vector_type (intSI_type_node
, 2);
11973 opaque_p_V2SI_type_node
= build_pointer_type (opaque_V2SI_type_node
);
11974 opaque_V4SI_type_node
= build_opaque_vector_type (intSI_type_node
, 4);
11976 /* The 'vector bool ...' types must be kept distinct from 'vector unsigned ...'
11977 types, especially in C++ land. Similarly, 'vector pixel' is distinct from
11978 'vector unsigned short'. */
11980 bool_char_type_node
= build_distinct_type_copy (unsigned_intQI_type_node
);
11981 bool_short_type_node
= build_distinct_type_copy (unsigned_intHI_type_node
);
11982 bool_int_type_node
= build_distinct_type_copy (unsigned_intSI_type_node
);
11983 bool_long_type_node
= build_distinct_type_copy (unsigned_intDI_type_node
);
11984 pixel_type_node
= build_distinct_type_copy (unsigned_intHI_type_node
);
11986 long_integer_type_internal_node
= long_integer_type_node
;
11987 long_unsigned_type_internal_node
= long_unsigned_type_node
;
11988 intQI_type_internal_node
= intQI_type_node
;
11989 uintQI_type_internal_node
= unsigned_intQI_type_node
;
11990 intHI_type_internal_node
= intHI_type_node
;
11991 uintHI_type_internal_node
= unsigned_intHI_type_node
;
11992 intSI_type_internal_node
= intSI_type_node
;
11993 uintSI_type_internal_node
= unsigned_intSI_type_node
;
11994 intDI_type_internal_node
= intDI_type_node
;
11995 uintDI_type_internal_node
= unsigned_intDI_type_node
;
11996 float_type_internal_node
= float_type_node
;
11997 double_type_internal_node
= float_type_node
;
11998 void_type_internal_node
= void_type_node
;
12000 /* Initialize the modes for builtin_function_type, mapping a machine mode to
12002 builtin_mode_to_type
[QImode
][0] = integer_type_node
;
12003 builtin_mode_to_type
[HImode
][0] = integer_type_node
;
12004 builtin_mode_to_type
[SImode
][0] = intSI_type_node
;
12005 builtin_mode_to_type
[SImode
][1] = unsigned_intSI_type_node
;
12006 builtin_mode_to_type
[DImode
][0] = intDI_type_node
;
12007 builtin_mode_to_type
[DImode
][1] = unsigned_intDI_type_node
;
12008 builtin_mode_to_type
[SFmode
][0] = float_type_node
;
12009 builtin_mode_to_type
[DFmode
][0] = double_type_node
;
12010 builtin_mode_to_type
[V2SImode
][0] = V2SI_type_node
;
12011 builtin_mode_to_type
[V2SFmode
][0] = V2SF_type_node
;
12012 builtin_mode_to_type
[V2DImode
][0] = V2DI_type_node
;
12013 builtin_mode_to_type
[V2DImode
][1] = unsigned_V2DI_type_node
;
12014 builtin_mode_to_type
[V2DFmode
][0] = V2DF_type_node
;
12015 builtin_mode_to_type
[V4HImode
][0] = V4HI_type_node
;
12016 builtin_mode_to_type
[V4SImode
][0] = V4SI_type_node
;
12017 builtin_mode_to_type
[V4SImode
][1] = unsigned_V4SI_type_node
;
12018 builtin_mode_to_type
[V4SFmode
][0] = V4SF_type_node
;
12019 builtin_mode_to_type
[V8HImode
][0] = V8HI_type_node
;
12020 builtin_mode_to_type
[V8HImode
][1] = unsigned_V8HI_type_node
;
12021 builtin_mode_to_type
[V16QImode
][0] = V16QI_type_node
;
12022 builtin_mode_to_type
[V16QImode
][1] = unsigned_V16QI_type_node
;
12024 tdecl
= build_decl (BUILTINS_LOCATION
, TYPE_DECL
,
12025 get_identifier ("__bool char"),
12026 bool_char_type_node
);
12027 TYPE_NAME (bool_char_type_node
) = tdecl
;
12028 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
12029 tdecl
= build_decl (BUILTINS_LOCATION
, TYPE_DECL
,
12030 get_identifier ("__bool short"),
12031 bool_short_type_node
);
12032 TYPE_NAME (bool_short_type_node
) = tdecl
;
12033 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
12034 tdecl
= build_decl (BUILTINS_LOCATION
, TYPE_DECL
,
12035 get_identifier ("__bool int"),
12036 bool_int_type_node
);
12037 TYPE_NAME (bool_int_type_node
) = tdecl
;
12038 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
12039 tdecl
= build_decl (BUILTINS_LOCATION
, TYPE_DECL
, get_identifier ("__pixel"),
12041 TYPE_NAME (pixel_type_node
) = tdecl
;
12042 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
12044 bool_V16QI_type_node
= build_vector_type (bool_char_type_node
, 16);
12045 bool_V8HI_type_node
= build_vector_type (bool_short_type_node
, 8);
12046 bool_V4SI_type_node
= build_vector_type (bool_int_type_node
, 4);
12047 bool_V2DI_type_node
= build_vector_type (bool_long_type_node
, 2);
12048 pixel_V8HI_type_node
= build_vector_type (pixel_type_node
, 8);
12050 tdecl
= build_decl (BUILTINS_LOCATION
, TYPE_DECL
,
12051 get_identifier ("__vector unsigned char"),
12052 unsigned_V16QI_type_node
);
12053 TYPE_NAME (unsigned_V16QI_type_node
) = tdecl
;
12054 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
12055 tdecl
= build_decl (BUILTINS_LOCATION
,
12056 TYPE_DECL
, get_identifier ("__vector signed char"),
12058 TYPE_NAME (V16QI_type_node
) = tdecl
;
12059 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
12060 tdecl
= build_decl (BUILTINS_LOCATION
,
12061 TYPE_DECL
, get_identifier ("__vector __bool char"),
12062 bool_V16QI_type_node
);
12063 TYPE_NAME ( bool_V16QI_type_node
) = tdecl
;
12064 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
12066 tdecl
= build_decl (BUILTINS_LOCATION
,
12067 TYPE_DECL
, get_identifier ("__vector unsigned short"),
12068 unsigned_V8HI_type_node
);
12069 TYPE_NAME (unsigned_V8HI_type_node
) = tdecl
;
12070 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
12071 tdecl
= build_decl (BUILTINS_LOCATION
,
12072 TYPE_DECL
, get_identifier ("__vector signed short"),
12074 TYPE_NAME (V8HI_type_node
) = tdecl
;
12075 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
12076 tdecl
= build_decl (BUILTINS_LOCATION
, TYPE_DECL
,
12077 get_identifier ("__vector __bool short"),
12078 bool_V8HI_type_node
);
12079 TYPE_NAME (bool_V8HI_type_node
) = tdecl
;
12080 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
12082 tdecl
= build_decl (BUILTINS_LOCATION
, TYPE_DECL
,
12083 get_identifier ("__vector unsigned int"),
12084 unsigned_V4SI_type_node
);
12085 TYPE_NAME (unsigned_V4SI_type_node
) = tdecl
;
12086 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
12087 tdecl
= build_decl (BUILTINS_LOCATION
,
12088 TYPE_DECL
, get_identifier ("__vector signed int"),
12090 TYPE_NAME (V4SI_type_node
) = tdecl
;
12091 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
12092 tdecl
= build_decl (BUILTINS_LOCATION
,
12093 TYPE_DECL
, get_identifier ("__vector __bool int"),
12094 bool_V4SI_type_node
);
12095 TYPE_NAME (bool_V4SI_type_node
) = tdecl
;
12096 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
12098 tdecl
= build_decl (BUILTINS_LOCATION
,
12099 TYPE_DECL
, get_identifier ("__vector float"),
12101 TYPE_NAME (V4SF_type_node
) = tdecl
;
12102 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
12103 tdecl
= build_decl (BUILTINS_LOCATION
,
12104 TYPE_DECL
, get_identifier ("__vector __pixel"),
12105 pixel_V8HI_type_node
);
12106 TYPE_NAME (pixel_V8HI_type_node
) = tdecl
;
12107 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
12111 tdecl
= build_decl (BUILTINS_LOCATION
,
12112 TYPE_DECL
, get_identifier ("__vector double"),
12114 TYPE_NAME (V2DF_type_node
) = tdecl
;
12115 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
12117 tdecl
= build_decl (BUILTINS_LOCATION
,
12118 TYPE_DECL
, get_identifier ("__vector long"),
12120 TYPE_NAME (V2DI_type_node
) = tdecl
;
12121 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
12123 tdecl
= build_decl (BUILTINS_LOCATION
,
12124 TYPE_DECL
, get_identifier ("__vector unsigned long"),
12125 unsigned_V2DI_type_node
);
12126 TYPE_NAME (unsigned_V2DI_type_node
) = tdecl
;
12127 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
12129 tdecl
= build_decl (BUILTINS_LOCATION
,
12130 TYPE_DECL
, get_identifier ("__vector __bool long"),
12131 bool_V2DI_type_node
);
12132 TYPE_NAME (bool_V2DI_type_node
) = tdecl
;
12133 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
12136 if (TARGET_PAIRED_FLOAT
)
12137 paired_init_builtins ();
12139 spe_init_builtins ();
12140 if (TARGET_ALTIVEC
)
12141 altivec_init_builtins ();
12142 if (TARGET_ALTIVEC
|| TARGET_SPE
|| TARGET_PAIRED_FLOAT
|| TARGET_VSX
)
12143 rs6000_common_init_builtins ();
12146 ftype
= builtin_function_type (DFmode
, DFmode
, DFmode
, VOIDmode
,
12147 RS6000_BUILTIN_RECIP
,
12148 "__builtin_recipdiv");
12149 def_builtin (MASK_POPCNTB
, "__builtin_recipdiv", ftype
,
12150 RS6000_BUILTIN_RECIP
);
12154 ftype
= builtin_function_type (SFmode
, SFmode
, SFmode
, VOIDmode
,
12155 RS6000_BUILTIN_RECIPF
,
12156 "__builtin_recipdivf");
12157 def_builtin (MASK_PPC_GFXOPT
, "__builtin_recipdivf", ftype
,
12158 RS6000_BUILTIN_RECIPF
);
12160 if (TARGET_FRSQRTE
)
12162 ftype
= builtin_function_type (DFmode
, DFmode
, VOIDmode
, VOIDmode
,
12163 RS6000_BUILTIN_RSQRT
,
12164 "__builtin_rsqrt");
12165 def_builtin (MASK_PPC_GFXOPT
, "__builtin_rsqrt", ftype
,
12166 RS6000_BUILTIN_RSQRT
);
12168 if (TARGET_FRSQRTES
)
12170 ftype
= builtin_function_type (SFmode
, SFmode
, VOIDmode
, VOIDmode
,
12171 RS6000_BUILTIN_RSQRTF
,
12172 "__builtin_rsqrtf");
12173 def_builtin (MASK_PPC_GFXOPT
, "__builtin_rsqrtf", ftype
,
12174 RS6000_BUILTIN_RSQRTF
);
12176 if (TARGET_POPCNTD
)
12178 enum machine_mode mode
= (TARGET_64BIT
) ? DImode
: SImode
;
12179 tree ftype
= builtin_function_type (mode
, mode
, mode
, VOIDmode
,
12180 POWER7_BUILTIN_BPERMD
,
12181 "__builtin_bpermd");
12182 def_builtin (MASK_POPCNTD
, "__builtin_bpermd", ftype
,
12183 POWER7_BUILTIN_BPERMD
);
12185 if (TARGET_POWERPC
)
12187 /* Don't use builtin_function_type here, as it maps HI/QI to SI. */
12188 tree ftype
= build_function_type_list (unsigned_intHI_type_node
,
12189 unsigned_intHI_type_node
,
12191 def_builtin (MASK_POWERPC
, "__builtin_bswap16", ftype
,
12192 RS6000_BUILTIN_BSWAP_HI
);
12196 /* AIX libm provides clog as __clog. */
12197 if (built_in_decls
[BUILT_IN_CLOG
])
12198 set_user_assembler_name (built_in_decls
[BUILT_IN_CLOG
], "__clog");
12201 #ifdef SUBTARGET_INIT_BUILTINS
12202 SUBTARGET_INIT_BUILTINS
;
12206 /* Returns the rs6000 builtin decl for CODE. */
12209 rs6000_builtin_decl (unsigned code
, bool initialize_p ATTRIBUTE_UNUSED
)
12211 if (code
>= RS6000_BUILTIN_COUNT
)
12212 return error_mark_node
;
12214 return rs6000_builtin_decls
[code
];
12217 /* Search through a set of builtins and enable the mask bits.
12218 DESC is an array of builtins.
12219 SIZE is the total number of builtins.
12220 START is the builtin enum at which to start.
12221 END is the builtin enum at which to end. */
12223 enable_mask_for_builtins (struct builtin_description
*desc
, int size
,
12224 enum rs6000_builtins start
,
12225 enum rs6000_builtins end
)
12229 for (i
= 0; i
< size
; ++i
)
12230 if (desc
[i
].code
== start
)
12236 for (; i
< size
; ++i
)
12238 /* Flip all the bits on. */
12239 desc
[i
].mask
= target_flags
;
12240 if (desc
[i
].code
== end
)
12246 spe_init_builtins (void)
12248 tree endlink
= void_list_node
;
12249 tree puint_type_node
= build_pointer_type (unsigned_type_node
);
12250 tree pushort_type_node
= build_pointer_type (short_unsigned_type_node
);
12251 struct builtin_description
*d
;
12254 tree v2si_ftype_4_v2si
12255 = build_function_type
12256 (opaque_V2SI_type_node
,
12257 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
12258 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
12259 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
12260 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
12263 tree v2sf_ftype_4_v2sf
12264 = build_function_type
12265 (opaque_V2SF_type_node
,
12266 tree_cons (NULL_TREE
, opaque_V2SF_type_node
,
12267 tree_cons (NULL_TREE
, opaque_V2SF_type_node
,
12268 tree_cons (NULL_TREE
, opaque_V2SF_type_node
,
12269 tree_cons (NULL_TREE
, opaque_V2SF_type_node
,
12272 tree int_ftype_int_v2si_v2si
12273 = build_function_type
12274 (integer_type_node
,
12275 tree_cons (NULL_TREE
, integer_type_node
,
12276 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
12277 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
12280 tree int_ftype_int_v2sf_v2sf
12281 = build_function_type
12282 (integer_type_node
,
12283 tree_cons (NULL_TREE
, integer_type_node
,
12284 tree_cons (NULL_TREE
, opaque_V2SF_type_node
,
12285 tree_cons (NULL_TREE
, opaque_V2SF_type_node
,
12288 tree void_ftype_v2si_puint_int
12289 = build_function_type (void_type_node
,
12290 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
12291 tree_cons (NULL_TREE
, puint_type_node
,
12292 tree_cons (NULL_TREE
,
12296 tree void_ftype_v2si_puint_char
12297 = build_function_type (void_type_node
,
12298 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
12299 tree_cons (NULL_TREE
, puint_type_node
,
12300 tree_cons (NULL_TREE
,
12304 tree void_ftype_v2si_pv2si_int
12305 = build_function_type (void_type_node
,
12306 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
12307 tree_cons (NULL_TREE
, opaque_p_V2SI_type_node
,
12308 tree_cons (NULL_TREE
,
12312 tree void_ftype_v2si_pv2si_char
12313 = build_function_type (void_type_node
,
12314 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
12315 tree_cons (NULL_TREE
, opaque_p_V2SI_type_node
,
12316 tree_cons (NULL_TREE
,
12320 tree void_ftype_int
12321 = build_function_type (void_type_node
,
12322 tree_cons (NULL_TREE
, integer_type_node
, endlink
));
12324 tree int_ftype_void
12325 = build_function_type (integer_type_node
, endlink
);
12327 tree v2si_ftype_pv2si_int
12328 = build_function_type (opaque_V2SI_type_node
,
12329 tree_cons (NULL_TREE
, opaque_p_V2SI_type_node
,
12330 tree_cons (NULL_TREE
, integer_type_node
,
12333 tree v2si_ftype_puint_int
12334 = build_function_type (opaque_V2SI_type_node
,
12335 tree_cons (NULL_TREE
, puint_type_node
,
12336 tree_cons (NULL_TREE
, integer_type_node
,
12339 tree v2si_ftype_pushort_int
12340 = build_function_type (opaque_V2SI_type_node
,
12341 tree_cons (NULL_TREE
, pushort_type_node
,
12342 tree_cons (NULL_TREE
, integer_type_node
,
12345 tree v2si_ftype_signed_char
12346 = build_function_type (opaque_V2SI_type_node
,
12347 tree_cons (NULL_TREE
, signed_char_type_node
,
12350 /* The initialization of the simple binary and unary builtins is
12351 done in rs6000_common_init_builtins, but we have to enable the
12352 mask bits here manually because we have run out of `target_flags'
12353 bits. We really need to redesign this mask business. */
12355 enable_mask_for_builtins ((struct builtin_description
*) bdesc_2arg
,
12356 ARRAY_SIZE (bdesc_2arg
),
12357 SPE_BUILTIN_EVADDW
,
12358 SPE_BUILTIN_EVXOR
);
12359 enable_mask_for_builtins ((struct builtin_description
*) bdesc_1arg
,
12360 ARRAY_SIZE (bdesc_1arg
),
12362 SPE_BUILTIN_EVSUBFUSIAAW
);
12363 enable_mask_for_builtins ((struct builtin_description
*) bdesc_spe_predicates
,
12364 ARRAY_SIZE (bdesc_spe_predicates
),
12365 SPE_BUILTIN_EVCMPEQ
,
12366 SPE_BUILTIN_EVFSTSTLT
);
12367 enable_mask_for_builtins ((struct builtin_description
*) bdesc_spe_evsel
,
12368 ARRAY_SIZE (bdesc_spe_evsel
),
12369 SPE_BUILTIN_EVSEL_CMPGTS
,
12370 SPE_BUILTIN_EVSEL_FSTSTEQ
);
12372 (*lang_hooks
.decls
.pushdecl
)
12373 (build_decl (BUILTINS_LOCATION
, TYPE_DECL
,
12374 get_identifier ("__ev64_opaque__"),
12375 opaque_V2SI_type_node
));
12377 /* Initialize irregular SPE builtins. */
12379 def_builtin (target_flags
, "__builtin_spe_mtspefscr", void_ftype_int
, SPE_BUILTIN_MTSPEFSCR
);
12380 def_builtin (target_flags
, "__builtin_spe_mfspefscr", int_ftype_void
, SPE_BUILTIN_MFSPEFSCR
);
12381 def_builtin (target_flags
, "__builtin_spe_evstddx", void_ftype_v2si_pv2si_int
, SPE_BUILTIN_EVSTDDX
);
12382 def_builtin (target_flags
, "__builtin_spe_evstdhx", void_ftype_v2si_pv2si_int
, SPE_BUILTIN_EVSTDHX
);
12383 def_builtin (target_flags
, "__builtin_spe_evstdwx", void_ftype_v2si_pv2si_int
, SPE_BUILTIN_EVSTDWX
);
12384 def_builtin (target_flags
, "__builtin_spe_evstwhex", void_ftype_v2si_puint_int
, SPE_BUILTIN_EVSTWHEX
);
12385 def_builtin (target_flags
, "__builtin_spe_evstwhox", void_ftype_v2si_puint_int
, SPE_BUILTIN_EVSTWHOX
);
12386 def_builtin (target_flags
, "__builtin_spe_evstwwex", void_ftype_v2si_puint_int
, SPE_BUILTIN_EVSTWWEX
);
12387 def_builtin (target_flags
, "__builtin_spe_evstwwox", void_ftype_v2si_puint_int
, SPE_BUILTIN_EVSTWWOX
);
12388 def_builtin (target_flags
, "__builtin_spe_evstdd", void_ftype_v2si_pv2si_char
, SPE_BUILTIN_EVSTDD
);
12389 def_builtin (target_flags
, "__builtin_spe_evstdh", void_ftype_v2si_pv2si_char
, SPE_BUILTIN_EVSTDH
);
12390 def_builtin (target_flags
, "__builtin_spe_evstdw", void_ftype_v2si_pv2si_char
, SPE_BUILTIN_EVSTDW
);
12391 def_builtin (target_flags
, "__builtin_spe_evstwhe", void_ftype_v2si_puint_char
, SPE_BUILTIN_EVSTWHE
);
12392 def_builtin (target_flags
, "__builtin_spe_evstwho", void_ftype_v2si_puint_char
, SPE_BUILTIN_EVSTWHO
);
12393 def_builtin (target_flags
, "__builtin_spe_evstwwe", void_ftype_v2si_puint_char
, SPE_BUILTIN_EVSTWWE
);
12394 def_builtin (target_flags
, "__builtin_spe_evstwwo", void_ftype_v2si_puint_char
, SPE_BUILTIN_EVSTWWO
);
12395 def_builtin (target_flags
, "__builtin_spe_evsplatfi", v2si_ftype_signed_char
, SPE_BUILTIN_EVSPLATFI
);
12396 def_builtin (target_flags
, "__builtin_spe_evsplati", v2si_ftype_signed_char
, SPE_BUILTIN_EVSPLATI
);
12399 def_builtin (target_flags
, "__builtin_spe_evlddx", v2si_ftype_pv2si_int
, SPE_BUILTIN_EVLDDX
);
12400 def_builtin (target_flags
, "__builtin_spe_evldwx", v2si_ftype_pv2si_int
, SPE_BUILTIN_EVLDWX
);
12401 def_builtin (target_flags
, "__builtin_spe_evldhx", v2si_ftype_pv2si_int
, SPE_BUILTIN_EVLDHX
);
12402 def_builtin (target_flags
, "__builtin_spe_evlwhex", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHEX
);
12403 def_builtin (target_flags
, "__builtin_spe_evlwhoux", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHOUX
);
12404 def_builtin (target_flags
, "__builtin_spe_evlwhosx", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHOSX
);
12405 def_builtin (target_flags
, "__builtin_spe_evlwwsplatx", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWWSPLATX
);
12406 def_builtin (target_flags
, "__builtin_spe_evlwhsplatx", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHSPLATX
);
12407 def_builtin (target_flags
, "__builtin_spe_evlhhesplatx", v2si_ftype_pushort_int
, SPE_BUILTIN_EVLHHESPLATX
);
12408 def_builtin (target_flags
, "__builtin_spe_evlhhousplatx", v2si_ftype_pushort_int
, SPE_BUILTIN_EVLHHOUSPLATX
);
12409 def_builtin (target_flags
, "__builtin_spe_evlhhossplatx", v2si_ftype_pushort_int
, SPE_BUILTIN_EVLHHOSSPLATX
);
12410 def_builtin (target_flags
, "__builtin_spe_evldd", v2si_ftype_pv2si_int
, SPE_BUILTIN_EVLDD
);
12411 def_builtin (target_flags
, "__builtin_spe_evldw", v2si_ftype_pv2si_int
, SPE_BUILTIN_EVLDW
);
12412 def_builtin (target_flags
, "__builtin_spe_evldh", v2si_ftype_pv2si_int
, SPE_BUILTIN_EVLDH
);
12413 def_builtin (target_flags
, "__builtin_spe_evlhhesplat", v2si_ftype_pushort_int
, SPE_BUILTIN_EVLHHESPLAT
);
12414 def_builtin (target_flags
, "__builtin_spe_evlhhossplat", v2si_ftype_pushort_int
, SPE_BUILTIN_EVLHHOSSPLAT
);
12415 def_builtin (target_flags
, "__builtin_spe_evlhhousplat", v2si_ftype_pushort_int
, SPE_BUILTIN_EVLHHOUSPLAT
);
12416 def_builtin (target_flags
, "__builtin_spe_evlwhe", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHE
);
12417 def_builtin (target_flags
, "__builtin_spe_evlwhos", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHOS
);
12418 def_builtin (target_flags
, "__builtin_spe_evlwhou", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHOU
);
12419 def_builtin (target_flags
, "__builtin_spe_evlwhsplat", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHSPLAT
);
12420 def_builtin (target_flags
, "__builtin_spe_evlwwsplat", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWWSPLAT
);
12423 d
= (struct builtin_description
*) bdesc_spe_predicates
;
12424 for (i
= 0; i
< ARRAY_SIZE (bdesc_spe_predicates
); ++i
, d
++)
12428 switch (insn_data
[d
->icode
].operand
[1].mode
)
12431 type
= int_ftype_int_v2si_v2si
;
12434 type
= int_ftype_int_v2sf_v2sf
;
12437 gcc_unreachable ();
12440 def_builtin (d
->mask
, d
->name
, type
, d
->code
);
12443 /* Evsel predicates. */
12444 d
= (struct builtin_description
*) bdesc_spe_evsel
;
12445 for (i
= 0; i
< ARRAY_SIZE (bdesc_spe_evsel
); ++i
, d
++)
12449 switch (insn_data
[d
->icode
].operand
[1].mode
)
12452 type
= v2si_ftype_4_v2si
;
12455 type
= v2sf_ftype_4_v2sf
;
12458 gcc_unreachable ();
12461 def_builtin (d
->mask
, d
->name
, type
, d
->code
);
12466 paired_init_builtins (void)
12468 const struct builtin_description
*d
;
12470 tree endlink
= void_list_node
;
12472 tree int_ftype_int_v2sf_v2sf
12473 = build_function_type
12474 (integer_type_node
,
12475 tree_cons (NULL_TREE
, integer_type_node
,
12476 tree_cons (NULL_TREE
, V2SF_type_node
,
12477 tree_cons (NULL_TREE
, V2SF_type_node
,
12479 tree pcfloat_type_node
=
12480 build_pointer_type (build_qualified_type
12481 (float_type_node
, TYPE_QUAL_CONST
));
12483 tree v2sf_ftype_long_pcfloat
= build_function_type_list (V2SF_type_node
,
12484 long_integer_type_node
,
12487 tree void_ftype_v2sf_long_pcfloat
=
12488 build_function_type_list (void_type_node
,
12490 long_integer_type_node
,
12495 def_builtin (0, "__builtin_paired_lx", v2sf_ftype_long_pcfloat
,
12496 PAIRED_BUILTIN_LX
);
12499 def_builtin (0, "__builtin_paired_stx", void_ftype_v2sf_long_pcfloat
,
12500 PAIRED_BUILTIN_STX
);
12503 d
= bdesc_paired_preds
;
12504 for (i
= 0; i
< ARRAY_SIZE (bdesc_paired_preds
); ++i
, d
++)
12508 switch (insn_data
[d
->icode
].operand
[1].mode
)
12511 type
= int_ftype_int_v2sf_v2sf
;
12514 gcc_unreachable ();
12517 def_builtin (d
->mask
, d
->name
, type
, d
->code
);
12522 altivec_init_builtins (void)
12524 const struct builtin_description
*d
;
12525 const struct builtin_description_predicates
*dp
;
12529 tree pfloat_type_node
= build_pointer_type (float_type_node
);
12530 tree pint_type_node
= build_pointer_type (integer_type_node
);
12531 tree pshort_type_node
= build_pointer_type (short_integer_type_node
);
12532 tree pchar_type_node
= build_pointer_type (char_type_node
);
12534 tree pvoid_type_node
= build_pointer_type (void_type_node
);
12536 tree pcfloat_type_node
= build_pointer_type (build_qualified_type (float_type_node
, TYPE_QUAL_CONST
));
12537 tree pcint_type_node
= build_pointer_type (build_qualified_type (integer_type_node
, TYPE_QUAL_CONST
));
12538 tree pcshort_type_node
= build_pointer_type (build_qualified_type (short_integer_type_node
, TYPE_QUAL_CONST
));
12539 tree pcchar_type_node
= build_pointer_type (build_qualified_type (char_type_node
, TYPE_QUAL_CONST
));
12541 tree pcvoid_type_node
= build_pointer_type (build_qualified_type (void_type_node
, TYPE_QUAL_CONST
));
12543 tree int_ftype_opaque
12544 = build_function_type_list (integer_type_node
,
12545 opaque_V4SI_type_node
, NULL_TREE
);
12546 tree opaque_ftype_opaque
12547 = build_function_type (integer_type_node
,
12549 tree opaque_ftype_opaque_int
12550 = build_function_type_list (opaque_V4SI_type_node
,
12551 opaque_V4SI_type_node
, integer_type_node
, NULL_TREE
);
12552 tree opaque_ftype_opaque_opaque_int
12553 = build_function_type_list (opaque_V4SI_type_node
,
12554 opaque_V4SI_type_node
, opaque_V4SI_type_node
,
12555 integer_type_node
, NULL_TREE
);
12556 tree int_ftype_int_opaque_opaque
12557 = build_function_type_list (integer_type_node
,
12558 integer_type_node
, opaque_V4SI_type_node
,
12559 opaque_V4SI_type_node
, NULL_TREE
);
12560 tree int_ftype_int_v4si_v4si
12561 = build_function_type_list (integer_type_node
,
12562 integer_type_node
, V4SI_type_node
,
12563 V4SI_type_node
, NULL_TREE
);
12564 tree v4sf_ftype_pcfloat
12565 = build_function_type_list (V4SF_type_node
, pcfloat_type_node
, NULL_TREE
);
12566 tree void_ftype_pfloat_v4sf
12567 = build_function_type_list (void_type_node
,
12568 pfloat_type_node
, V4SF_type_node
, NULL_TREE
);
12569 tree v4si_ftype_pcint
12570 = build_function_type_list (V4SI_type_node
, pcint_type_node
, NULL_TREE
);
12571 tree void_ftype_pint_v4si
12572 = build_function_type_list (void_type_node
,
12573 pint_type_node
, V4SI_type_node
, NULL_TREE
);
12574 tree v8hi_ftype_pcshort
12575 = build_function_type_list (V8HI_type_node
, pcshort_type_node
, NULL_TREE
);
12576 tree void_ftype_pshort_v8hi
12577 = build_function_type_list (void_type_node
,
12578 pshort_type_node
, V8HI_type_node
, NULL_TREE
);
12579 tree v16qi_ftype_pcchar
12580 = build_function_type_list (V16QI_type_node
, pcchar_type_node
, NULL_TREE
);
12581 tree void_ftype_pchar_v16qi
12582 = build_function_type_list (void_type_node
,
12583 pchar_type_node
, V16QI_type_node
, NULL_TREE
);
12584 tree void_ftype_v4si
12585 = build_function_type_list (void_type_node
, V4SI_type_node
, NULL_TREE
);
12586 tree v8hi_ftype_void
12587 = build_function_type (V8HI_type_node
, void_list_node
);
12588 tree void_ftype_void
12589 = build_function_type (void_type_node
, void_list_node
);
12590 tree void_ftype_int
12591 = build_function_type_list (void_type_node
, integer_type_node
, NULL_TREE
);
12593 tree opaque_ftype_long_pcvoid
12594 = build_function_type_list (opaque_V4SI_type_node
,
12595 long_integer_type_node
, pcvoid_type_node
, NULL_TREE
);
12596 tree v16qi_ftype_long_pcvoid
12597 = build_function_type_list (V16QI_type_node
,
12598 long_integer_type_node
, pcvoid_type_node
, NULL_TREE
);
12599 tree v8hi_ftype_long_pcvoid
12600 = build_function_type_list (V8HI_type_node
,
12601 long_integer_type_node
, pcvoid_type_node
, NULL_TREE
);
12602 tree v4si_ftype_long_pcvoid
12603 = build_function_type_list (V4SI_type_node
,
12604 long_integer_type_node
, pcvoid_type_node
, NULL_TREE
);
12606 tree void_ftype_opaque_long_pvoid
12607 = build_function_type_list (void_type_node
,
12608 opaque_V4SI_type_node
, long_integer_type_node
,
12609 pvoid_type_node
, NULL_TREE
);
12610 tree void_ftype_v4si_long_pvoid
12611 = build_function_type_list (void_type_node
,
12612 V4SI_type_node
, long_integer_type_node
,
12613 pvoid_type_node
, NULL_TREE
);
12614 tree void_ftype_v16qi_long_pvoid
12615 = build_function_type_list (void_type_node
,
12616 V16QI_type_node
, long_integer_type_node
,
12617 pvoid_type_node
, NULL_TREE
);
12618 tree void_ftype_v8hi_long_pvoid
12619 = build_function_type_list (void_type_node
,
12620 V8HI_type_node
, long_integer_type_node
,
12621 pvoid_type_node
, NULL_TREE
);
12622 tree int_ftype_int_v8hi_v8hi
12623 = build_function_type_list (integer_type_node
,
12624 integer_type_node
, V8HI_type_node
,
12625 V8HI_type_node
, NULL_TREE
);
12626 tree int_ftype_int_v16qi_v16qi
12627 = build_function_type_list (integer_type_node
,
12628 integer_type_node
, V16QI_type_node
,
12629 V16QI_type_node
, NULL_TREE
);
12630 tree int_ftype_int_v4sf_v4sf
12631 = build_function_type_list (integer_type_node
,
12632 integer_type_node
, V4SF_type_node
,
12633 V4SF_type_node
, NULL_TREE
);
12634 tree int_ftype_int_v2df_v2df
12635 = build_function_type_list (integer_type_node
,
12636 integer_type_node
, V2DF_type_node
,
12637 V2DF_type_node
, NULL_TREE
);
12638 tree v4si_ftype_v4si
12639 = build_function_type_list (V4SI_type_node
, V4SI_type_node
, NULL_TREE
);
12640 tree v8hi_ftype_v8hi
12641 = build_function_type_list (V8HI_type_node
, V8HI_type_node
, NULL_TREE
);
12642 tree v16qi_ftype_v16qi
12643 = build_function_type_list (V16QI_type_node
, V16QI_type_node
, NULL_TREE
);
12644 tree v4sf_ftype_v4sf
12645 = build_function_type_list (V4SF_type_node
, V4SF_type_node
, NULL_TREE
);
12646 tree v2df_ftype_v2df
12647 = build_function_type_list (V2DF_type_node
, V2DF_type_node
, NULL_TREE
);
12648 tree void_ftype_pcvoid_int_int
12649 = build_function_type_list (void_type_node
,
12650 pcvoid_type_node
, integer_type_node
,
12651 integer_type_node
, NULL_TREE
);
12653 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_ld_internal_4sf", v4sf_ftype_pcfloat
,
12654 ALTIVEC_BUILTIN_LD_INTERNAL_4sf
);
12655 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_st_internal_4sf", void_ftype_pfloat_v4sf
,
12656 ALTIVEC_BUILTIN_ST_INTERNAL_4sf
);
12657 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_ld_internal_4si", v4si_ftype_pcint
,
12658 ALTIVEC_BUILTIN_LD_INTERNAL_4si
);
12659 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_st_internal_4si", void_ftype_pint_v4si
,
12660 ALTIVEC_BUILTIN_ST_INTERNAL_4si
);
12661 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_ld_internal_8hi", v8hi_ftype_pcshort
,
12662 ALTIVEC_BUILTIN_LD_INTERNAL_8hi
);
12663 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_st_internal_8hi", void_ftype_pshort_v8hi
,
12664 ALTIVEC_BUILTIN_ST_INTERNAL_8hi
);
12665 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_ld_internal_16qi", v16qi_ftype_pcchar
,
12666 ALTIVEC_BUILTIN_LD_INTERNAL_16qi
);
12667 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_st_internal_16qi", void_ftype_pchar_v16qi
,
12668 ALTIVEC_BUILTIN_ST_INTERNAL_16qi
);
12669 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_mtvscr", void_ftype_v4si
, ALTIVEC_BUILTIN_MTVSCR
);
12670 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_mfvscr", v8hi_ftype_void
, ALTIVEC_BUILTIN_MFVSCR
);
12671 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_dssall", void_ftype_void
, ALTIVEC_BUILTIN_DSSALL
);
12672 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_dss", void_ftype_int
, ALTIVEC_BUILTIN_DSS
);
12673 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvsl", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVSL
);
12674 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvsr", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVSR
);
12675 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvebx", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVEBX
);
12676 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvehx", v8hi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVEHX
);
12677 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvewx", v4si_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVEWX
);
12678 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvxl", v4si_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVXL
);
12679 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvx", v4si_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVX
);
12680 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_stvx", void_ftype_v4si_long_pvoid
, ALTIVEC_BUILTIN_STVX
);
12681 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_stvewx", void_ftype_v4si_long_pvoid
, ALTIVEC_BUILTIN_STVEWX
);
12682 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_stvxl", void_ftype_v4si_long_pvoid
, ALTIVEC_BUILTIN_STVXL
);
12683 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_stvebx", void_ftype_v16qi_long_pvoid
, ALTIVEC_BUILTIN_STVEBX
);
12684 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_stvehx", void_ftype_v8hi_long_pvoid
, ALTIVEC_BUILTIN_STVEHX
);
12685 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ld", opaque_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LD
);
12686 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lde", opaque_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LDE
);
12687 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ldl", opaque_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LDL
);
12688 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lvsl", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVSL
);
12689 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lvsr", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVSR
);
12690 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lvebx", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVEBX
);
12691 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lvehx", v8hi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVEHX
);
12692 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lvewx", v4si_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVEWX
);
12693 def_builtin (MASK_ALTIVEC
, "__builtin_vec_st", void_ftype_opaque_long_pvoid
, ALTIVEC_BUILTIN_VEC_ST
);
12694 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ste", void_ftype_opaque_long_pvoid
, ALTIVEC_BUILTIN_VEC_STE
);
12695 def_builtin (MASK_ALTIVEC
, "__builtin_vec_stl", void_ftype_opaque_long_pvoid
, ALTIVEC_BUILTIN_VEC_STL
);
12696 def_builtin (MASK_ALTIVEC
, "__builtin_vec_stvewx", void_ftype_opaque_long_pvoid
, ALTIVEC_BUILTIN_VEC_STVEWX
);
12697 def_builtin (MASK_ALTIVEC
, "__builtin_vec_stvebx", void_ftype_opaque_long_pvoid
, ALTIVEC_BUILTIN_VEC_STVEBX
);
12698 def_builtin (MASK_ALTIVEC
, "__builtin_vec_stvehx", void_ftype_opaque_long_pvoid
, ALTIVEC_BUILTIN_VEC_STVEHX
);
12700 if (rs6000_cpu
== PROCESSOR_CELL
)
12702 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvlx", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVLX
);
12703 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvlxl", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVLXL
);
12704 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvrx", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVRX
);
12705 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvrxl", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVRXL
);
12707 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lvlx", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVLX
);
12708 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lvlxl", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVLXL
);
12709 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lvrx", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVRX
);
12710 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lvrxl", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVRXL
);
12712 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_stvlx", void_ftype_v16qi_long_pvoid
, ALTIVEC_BUILTIN_STVLX
);
12713 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_stvlxl", void_ftype_v16qi_long_pvoid
, ALTIVEC_BUILTIN_STVLXL
);
12714 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_stvrx", void_ftype_v16qi_long_pvoid
, ALTIVEC_BUILTIN_STVRX
);
12715 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_stvrxl", void_ftype_v16qi_long_pvoid
, ALTIVEC_BUILTIN_STVRXL
);
12717 def_builtin (MASK_ALTIVEC
, "__builtin_vec_stvlx", void_ftype_v16qi_long_pvoid
, ALTIVEC_BUILTIN_VEC_STVLX
);
12718 def_builtin (MASK_ALTIVEC
, "__builtin_vec_stvlxl", void_ftype_v16qi_long_pvoid
, ALTIVEC_BUILTIN_VEC_STVLXL
);
12719 def_builtin (MASK_ALTIVEC
, "__builtin_vec_stvrx", void_ftype_v16qi_long_pvoid
, ALTIVEC_BUILTIN_VEC_STVRX
);
12720 def_builtin (MASK_ALTIVEC
, "__builtin_vec_stvrxl", void_ftype_v16qi_long_pvoid
, ALTIVEC_BUILTIN_VEC_STVRXL
);
12722 def_builtin (MASK_ALTIVEC
, "__builtin_vec_step", int_ftype_opaque
, ALTIVEC_BUILTIN_VEC_STEP
);
12723 def_builtin (MASK_ALTIVEC
, "__builtin_vec_splats", opaque_ftype_opaque
, ALTIVEC_BUILTIN_VEC_SPLATS
);
12724 def_builtin (MASK_ALTIVEC
, "__builtin_vec_promote", opaque_ftype_opaque
, ALTIVEC_BUILTIN_VEC_PROMOTE
);
12726 def_builtin (MASK_ALTIVEC
, "__builtin_vec_sld", opaque_ftype_opaque_opaque_int
, ALTIVEC_BUILTIN_VEC_SLD
);
12727 def_builtin (MASK_ALTIVEC
, "__builtin_vec_splat", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_SPLAT
);
12728 def_builtin (MASK_ALTIVEC
, "__builtin_vec_extract", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_EXTRACT
);
12729 def_builtin (MASK_ALTIVEC
, "__builtin_vec_insert", opaque_ftype_opaque_opaque_int
, ALTIVEC_BUILTIN_VEC_INSERT
);
12730 def_builtin (MASK_ALTIVEC
, "__builtin_vec_vspltw", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_VSPLTW
);
12731 def_builtin (MASK_ALTIVEC
, "__builtin_vec_vsplth", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_VSPLTH
);
12732 def_builtin (MASK_ALTIVEC
, "__builtin_vec_vspltb", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_VSPLTB
);
12733 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ctf", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_CTF
);
12734 def_builtin (MASK_ALTIVEC
, "__builtin_vec_vcfsx", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_VCFSX
);
12735 def_builtin (MASK_ALTIVEC
, "__builtin_vec_vcfux", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_VCFUX
);
12736 def_builtin (MASK_ALTIVEC
, "__builtin_vec_cts", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_CTS
);
12737 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ctu", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_CTU
);
12739 /* Add the DST variants. */
12741 for (i
= 0; i
< ARRAY_SIZE (bdesc_dst
); i
++, d
++)
12742 def_builtin (d
->mask
, d
->name
, void_ftype_pcvoid_int_int
, d
->code
);
12744 /* Initialize the predicates. */
12745 dp
= bdesc_altivec_preds
;
12746 for (i
= 0; i
< ARRAY_SIZE (bdesc_altivec_preds
); i
++, dp
++)
12748 enum machine_mode mode1
;
12750 bool is_overloaded
= ((dp
->code
>= ALTIVEC_BUILTIN_OVERLOADED_FIRST
12751 && dp
->code
<= ALTIVEC_BUILTIN_OVERLOADED_LAST
)
12752 || (dp
->code
>= VSX_BUILTIN_OVERLOADED_FIRST
12753 && dp
->code
<= VSX_BUILTIN_OVERLOADED_LAST
));
12758 mode1
= insn_data
[dp
->icode
].operand
[1].mode
;
12763 type
= int_ftype_int_opaque_opaque
;
12766 type
= int_ftype_int_v4si_v4si
;
12769 type
= int_ftype_int_v8hi_v8hi
;
12772 type
= int_ftype_int_v16qi_v16qi
;
12775 type
= int_ftype_int_v4sf_v4sf
;
12778 type
= int_ftype_int_v2df_v2df
;
12781 gcc_unreachable ();
12784 def_builtin (dp
->mask
, dp
->name
, type
, dp
->code
);
12787 /* Initialize the abs* operators. */
12789 for (i
= 0; i
< ARRAY_SIZE (bdesc_abs
); i
++, d
++)
12791 enum machine_mode mode0
;
12794 mode0
= insn_data
[d
->icode
].operand
[0].mode
;
12799 type
= v4si_ftype_v4si
;
12802 type
= v8hi_ftype_v8hi
;
12805 type
= v16qi_ftype_v16qi
;
12808 type
= v4sf_ftype_v4sf
;
12811 type
= v2df_ftype_v2df
;
12814 gcc_unreachable ();
12817 def_builtin (d
->mask
, d
->name
, type
, d
->code
);
12820 if (TARGET_ALTIVEC
)
12824 /* Initialize target builtin that implements
12825 targetm.vectorize.builtin_mask_for_load. */
12827 decl
= add_builtin_function ("__builtin_altivec_mask_for_load",
12828 v16qi_ftype_long_pcvoid
,
12829 ALTIVEC_BUILTIN_MASK_FOR_LOAD
,
12830 BUILT_IN_MD
, NULL
, NULL_TREE
);
12831 TREE_READONLY (decl
) = 1;
12832 /* Record the decl. Will be used by rs6000_builtin_mask_for_load. */
12833 altivec_builtin_mask_for_load
= decl
;
12836 /* Access to the vec_init patterns. */
12837 ftype
= build_function_type_list (V4SI_type_node
, integer_type_node
,
12838 integer_type_node
, integer_type_node
,
12839 integer_type_node
, NULL_TREE
);
12840 def_builtin (MASK_ALTIVEC
, "__builtin_vec_init_v4si", ftype
,
12841 ALTIVEC_BUILTIN_VEC_INIT_V4SI
);
12843 ftype
= build_function_type_list (V8HI_type_node
, short_integer_type_node
,
12844 short_integer_type_node
,
12845 short_integer_type_node
,
12846 short_integer_type_node
,
12847 short_integer_type_node
,
12848 short_integer_type_node
,
12849 short_integer_type_node
,
12850 short_integer_type_node
, NULL_TREE
);
12851 def_builtin (MASK_ALTIVEC
, "__builtin_vec_init_v8hi", ftype
,
12852 ALTIVEC_BUILTIN_VEC_INIT_V8HI
);
12854 ftype
= build_function_type_list (V16QI_type_node
, char_type_node
,
12855 char_type_node
, char_type_node
,
12856 char_type_node
, char_type_node
,
12857 char_type_node
, char_type_node
,
12858 char_type_node
, char_type_node
,
12859 char_type_node
, char_type_node
,
12860 char_type_node
, char_type_node
,
12861 char_type_node
, char_type_node
,
12862 char_type_node
, NULL_TREE
);
12863 def_builtin (MASK_ALTIVEC
, "__builtin_vec_init_v16qi", ftype
,
12864 ALTIVEC_BUILTIN_VEC_INIT_V16QI
);
12866 ftype
= build_function_type_list (V4SF_type_node
, float_type_node
,
12867 float_type_node
, float_type_node
,
12868 float_type_node
, NULL_TREE
);
12869 def_builtin (MASK_ALTIVEC
, "__builtin_vec_init_v4sf", ftype
,
12870 ALTIVEC_BUILTIN_VEC_INIT_V4SF
);
12874 ftype
= build_function_type_list (V2DF_type_node
, double_type_node
,
12875 double_type_node
, NULL_TREE
);
12876 def_builtin (MASK_VSX
, "__builtin_vec_init_v2df", ftype
,
12877 VSX_BUILTIN_VEC_INIT_V2DF
);
12879 ftype
= build_function_type_list (V2DI_type_node
, intDI_type_node
,
12880 intDI_type_node
, NULL_TREE
);
12881 def_builtin (MASK_VSX
, "__builtin_vec_init_v2di", ftype
,
12882 VSX_BUILTIN_VEC_INIT_V2DI
);
12885 /* Access to the vec_set patterns. */
12886 ftype
= build_function_type_list (V4SI_type_node
, V4SI_type_node
,
12888 integer_type_node
, NULL_TREE
);
12889 def_builtin (MASK_ALTIVEC
, "__builtin_vec_set_v4si", ftype
,
12890 ALTIVEC_BUILTIN_VEC_SET_V4SI
);
12892 ftype
= build_function_type_list (V8HI_type_node
, V8HI_type_node
,
12894 integer_type_node
, NULL_TREE
);
12895 def_builtin (MASK_ALTIVEC
, "__builtin_vec_set_v8hi", ftype
,
12896 ALTIVEC_BUILTIN_VEC_SET_V8HI
);
12898 ftype
= build_function_type_list (V16QI_type_node
, V16QI_type_node
,
12900 integer_type_node
, NULL_TREE
);
12901 def_builtin (MASK_ALTIVEC
, "__builtin_vec_set_v16qi", ftype
,
12902 ALTIVEC_BUILTIN_VEC_SET_V16QI
);
12904 ftype
= build_function_type_list (V4SF_type_node
, V4SF_type_node
,
12906 integer_type_node
, NULL_TREE
);
12907 def_builtin (MASK_ALTIVEC
|MASK_VSX
, "__builtin_vec_set_v4sf", ftype
,
12908 ALTIVEC_BUILTIN_VEC_SET_V4SF
);
12912 ftype
= build_function_type_list (V2DF_type_node
, V2DF_type_node
,
12914 integer_type_node
, NULL_TREE
);
12915 def_builtin (MASK_VSX
, "__builtin_vec_set_v2df", ftype
,
12916 VSX_BUILTIN_VEC_SET_V2DF
);
12918 ftype
= build_function_type_list (V2DI_type_node
, V2DI_type_node
,
12920 integer_type_node
, NULL_TREE
);
12921 def_builtin (MASK_VSX
, "__builtin_vec_set_v2di", ftype
,
12922 VSX_BUILTIN_VEC_SET_V2DI
);
12925 /* Access to the vec_extract patterns. */
12926 ftype
= build_function_type_list (intSI_type_node
, V4SI_type_node
,
12927 integer_type_node
, NULL_TREE
);
12928 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ext_v4si", ftype
,
12929 ALTIVEC_BUILTIN_VEC_EXT_V4SI
);
12931 ftype
= build_function_type_list (intHI_type_node
, V8HI_type_node
,
12932 integer_type_node
, NULL_TREE
);
12933 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ext_v8hi", ftype
,
12934 ALTIVEC_BUILTIN_VEC_EXT_V8HI
);
12936 ftype
= build_function_type_list (intQI_type_node
, V16QI_type_node
,
12937 integer_type_node
, NULL_TREE
);
12938 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ext_v16qi", ftype
,
12939 ALTIVEC_BUILTIN_VEC_EXT_V16QI
);
12941 ftype
= build_function_type_list (float_type_node
, V4SF_type_node
,
12942 integer_type_node
, NULL_TREE
);
12943 def_builtin (MASK_ALTIVEC
|MASK_VSX
, "__builtin_vec_ext_v4sf", ftype
,
12944 ALTIVEC_BUILTIN_VEC_EXT_V4SF
);
12948 ftype
= build_function_type_list (double_type_node
, V2DF_type_node
,
12949 integer_type_node
, NULL_TREE
);
12950 def_builtin (MASK_VSX
, "__builtin_vec_ext_v2df", ftype
,
12951 VSX_BUILTIN_VEC_EXT_V2DF
);
12953 ftype
= build_function_type_list (intDI_type_node
, V2DI_type_node
,
12954 integer_type_node
, NULL_TREE
);
12955 def_builtin (MASK_VSX
, "__builtin_vec_ext_v2di", ftype
,
12956 VSX_BUILTIN_VEC_EXT_V2DI
);
12960 /* Hash function for builtin functions with up to 3 arguments and a return
12963 builtin_hash_function (const void *hash_entry
)
12967 const struct builtin_hash_struct
*bh
=
12968 (const struct builtin_hash_struct
*) hash_entry
;
12970 for (i
= 0; i
< 4; i
++)
12972 ret
= (ret
* (unsigned)MAX_MACHINE_MODE
) + ((unsigned)bh
->mode
[i
]);
12973 ret
= (ret
* 2) + bh
->uns_p
[i
];
12979 /* Compare builtin hash entries H1 and H2 for equivalence. */
12981 builtin_hash_eq (const void *h1
, const void *h2
)
12983 const struct builtin_hash_struct
*p1
= (const struct builtin_hash_struct
*) h1
;
12984 const struct builtin_hash_struct
*p2
= (const struct builtin_hash_struct
*) h2
;
12986 return ((p1
->mode
[0] == p2
->mode
[0])
12987 && (p1
->mode
[1] == p2
->mode
[1])
12988 && (p1
->mode
[2] == p2
->mode
[2])
12989 && (p1
->mode
[3] == p2
->mode
[3])
12990 && (p1
->uns_p
[0] == p2
->uns_p
[0])
12991 && (p1
->uns_p
[1] == p2
->uns_p
[1])
12992 && (p1
->uns_p
[2] == p2
->uns_p
[2])
12993 && (p1
->uns_p
[3] == p2
->uns_p
[3]));
12996 /* Map types for builtin functions with an explicit return type and up to 3
12997 arguments. Functions with fewer than 3 arguments use VOIDmode as the type
12998 of the argument. */
13000 builtin_function_type (enum machine_mode mode_ret
, enum machine_mode mode_arg0
,
13001 enum machine_mode mode_arg1
, enum machine_mode mode_arg2
,
13002 enum rs6000_builtins builtin
, const char *name
)
13004 struct builtin_hash_struct h
;
13005 struct builtin_hash_struct
*h2
;
13009 tree ret_type
= NULL_TREE
;
13010 tree arg_type
[3] = { NULL_TREE
, NULL_TREE
, NULL_TREE
};
13013 /* Create builtin_hash_table. */
13014 if (builtin_hash_table
== NULL
)
13015 builtin_hash_table
= htab_create_ggc (1500, builtin_hash_function
,
13016 builtin_hash_eq
, NULL
);
13018 h
.type
= NULL_TREE
;
13019 h
.mode
[0] = mode_ret
;
13020 h
.mode
[1] = mode_arg0
;
13021 h
.mode
[2] = mode_arg1
;
13022 h
.mode
[3] = mode_arg2
;
13028 /* If the builtin is a type that produces unsigned results or takes unsigned
13029 arguments, and it is returned as a decl for the vectorizer (such as
13030 widening multiplies, permute), make sure the arguments and return value
13031 are type correct. */
13034 /* unsigned 2 argument functions. */
13035 case ALTIVEC_BUILTIN_VMULEUB_UNS
:
13036 case ALTIVEC_BUILTIN_VMULEUH_UNS
:
13037 case ALTIVEC_BUILTIN_VMULOUB_UNS
:
13038 case ALTIVEC_BUILTIN_VMULOUH_UNS
:
13044 /* unsigned 3 argument functions. */
13045 case ALTIVEC_BUILTIN_VPERM_16QI_UNS
:
13046 case ALTIVEC_BUILTIN_VPERM_8HI_UNS
:
13047 case ALTIVEC_BUILTIN_VPERM_4SI_UNS
:
13048 case ALTIVEC_BUILTIN_VPERM_2DI_UNS
:
13049 case ALTIVEC_BUILTIN_VSEL_16QI_UNS
:
13050 case ALTIVEC_BUILTIN_VSEL_8HI_UNS
:
13051 case ALTIVEC_BUILTIN_VSEL_4SI_UNS
:
13052 case ALTIVEC_BUILTIN_VSEL_2DI_UNS
:
13053 case VSX_BUILTIN_VPERM_16QI_UNS
:
13054 case VSX_BUILTIN_VPERM_8HI_UNS
:
13055 case VSX_BUILTIN_VPERM_4SI_UNS
:
13056 case VSX_BUILTIN_VPERM_2DI_UNS
:
13057 case VSX_BUILTIN_XXSEL_16QI_UNS
:
13058 case VSX_BUILTIN_XXSEL_8HI_UNS
:
13059 case VSX_BUILTIN_XXSEL_4SI_UNS
:
13060 case VSX_BUILTIN_XXSEL_2DI_UNS
:
13067 /* signed permute functions with unsigned char mask. */
13068 case ALTIVEC_BUILTIN_VPERM_16QI
:
13069 case ALTIVEC_BUILTIN_VPERM_8HI
:
13070 case ALTIVEC_BUILTIN_VPERM_4SI
:
13071 case ALTIVEC_BUILTIN_VPERM_4SF
:
13072 case ALTIVEC_BUILTIN_VPERM_2DI
:
13073 case ALTIVEC_BUILTIN_VPERM_2DF
:
13074 case VSX_BUILTIN_VPERM_16QI
:
13075 case VSX_BUILTIN_VPERM_8HI
:
13076 case VSX_BUILTIN_VPERM_4SI
:
13077 case VSX_BUILTIN_VPERM_4SF
:
13078 case VSX_BUILTIN_VPERM_2DI
:
13079 case VSX_BUILTIN_VPERM_2DF
:
13083 /* unsigned args, signed return. */
13084 case VSX_BUILTIN_XVCVUXDDP_UNS
:
13085 case VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF
:
13089 /* signed args, unsigned return. */
13090 case VSX_BUILTIN_XVCVDPUXDS_UNS
:
13091 case VECTOR_BUILTIN_FIXUNS_V4SF_V4SI
:
13099 /* Figure out how many args are present. */
13100 while (num_args
> 0 && h
.mode
[num_args
] == VOIDmode
)
13104 fatal_error ("internal error: builtin function %s had no type", name
);
13106 ret_type
= builtin_mode_to_type
[h
.mode
[0]][h
.uns_p
[0]];
13107 if (!ret_type
&& h
.uns_p
[0])
13108 ret_type
= builtin_mode_to_type
[h
.mode
[0]][0];
13111 fatal_error ("internal error: builtin function %s had an unexpected "
13112 "return type %s", name
, GET_MODE_NAME (h
.mode
[0]));
13114 for (i
= 0; i
< num_args
; i
++)
13116 int m
= (int) h
.mode
[i
+1];
13117 int uns_p
= h
.uns_p
[i
+1];
13119 arg_type
[i
] = builtin_mode_to_type
[m
][uns_p
];
13120 if (!arg_type
[i
] && uns_p
)
13121 arg_type
[i
] = builtin_mode_to_type
[m
][0];
13124 fatal_error ("internal error: builtin function %s, argument %d "
13125 "had unexpected argument type %s", name
, i
,
13126 GET_MODE_NAME (m
));
13129 found
= htab_find_slot (builtin_hash_table
, &h
, INSERT
);
13130 if (*found
== NULL
)
13132 h2
= ggc_alloc_builtin_hash_struct ();
13134 *found
= (void *)h2
;
13135 args
= void_list_node
;
13137 for (i
= num_args
- 1; i
>= 0; i
--)
13138 args
= tree_cons (NULL_TREE
, arg_type
[i
], args
);
13140 h2
->type
= build_function_type (ret_type
, args
);
13143 return ((struct builtin_hash_struct
*)(*found
))->type
;
13147 rs6000_common_init_builtins (void)
13149 const struct builtin_description
*d
;
13152 tree opaque_ftype_opaque
= NULL_TREE
;
13153 tree opaque_ftype_opaque_opaque
= NULL_TREE
;
13154 tree opaque_ftype_opaque_opaque_opaque
= NULL_TREE
;
13155 tree v2si_ftype_qi
= NULL_TREE
;
13156 tree v2si_ftype_v2si_qi
= NULL_TREE
;
13157 tree v2si_ftype_int_qi
= NULL_TREE
;
13159 if (!TARGET_PAIRED_FLOAT
)
13161 builtin_mode_to_type
[V2SImode
][0] = opaque_V2SI_type_node
;
13162 builtin_mode_to_type
[V2SFmode
][0] = opaque_V2SF_type_node
;
13165 /* Add the ternary operators. */
13167 for (i
= 0; i
< ARRAY_SIZE (bdesc_3arg
); i
++, d
++)
13170 int mask
= d
->mask
;
13172 if ((mask
!= 0 && (mask
& target_flags
) == 0)
13173 || (mask
== 0 && !TARGET_PAIRED_FLOAT
))
13176 if ((d
->code
>= ALTIVEC_BUILTIN_OVERLOADED_FIRST
13177 && d
->code
<= ALTIVEC_BUILTIN_OVERLOADED_LAST
)
13178 || (d
->code
>= VSX_BUILTIN_OVERLOADED_FIRST
13179 && d
->code
<= VSX_BUILTIN_OVERLOADED_LAST
))
13181 if (! (type
= opaque_ftype_opaque_opaque_opaque
))
13182 type
= opaque_ftype_opaque_opaque_opaque
13183 = build_function_type_list (opaque_V4SI_type_node
,
13184 opaque_V4SI_type_node
,
13185 opaque_V4SI_type_node
,
13186 opaque_V4SI_type_node
,
13191 enum insn_code icode
= d
->icode
;
13192 if (d
->name
== 0 || icode
== CODE_FOR_nothing
)
13195 type
= builtin_function_type (insn_data
[icode
].operand
[0].mode
,
13196 insn_data
[icode
].operand
[1].mode
,
13197 insn_data
[icode
].operand
[2].mode
,
13198 insn_data
[icode
].operand
[3].mode
,
13202 def_builtin (d
->mask
, d
->name
, type
, d
->code
);
13205 /* Add the binary operators. */
13207 for (i
= 0; i
< ARRAY_SIZE (bdesc_2arg
); i
++, d
++)
13209 enum machine_mode mode0
, mode1
, mode2
;
13211 int mask
= d
->mask
;
13213 if ((mask
!= 0 && (mask
& target_flags
) == 0)
13214 || (mask
== 0 && !TARGET_PAIRED_FLOAT
))
13217 if ((d
->code
>= ALTIVEC_BUILTIN_OVERLOADED_FIRST
13218 && d
->code
<= ALTIVEC_BUILTIN_OVERLOADED_LAST
)
13219 || (d
->code
>= VSX_BUILTIN_OVERLOADED_FIRST
13220 && d
->code
<= VSX_BUILTIN_OVERLOADED_LAST
))
13222 if (! (type
= opaque_ftype_opaque_opaque
))
13223 type
= opaque_ftype_opaque_opaque
13224 = build_function_type_list (opaque_V4SI_type_node
,
13225 opaque_V4SI_type_node
,
13226 opaque_V4SI_type_node
,
13231 enum insn_code icode
= d
->icode
;
13232 if (d
->name
== 0 || icode
== CODE_FOR_nothing
)
13235 mode0
= insn_data
[icode
].operand
[0].mode
;
13236 mode1
= insn_data
[icode
].operand
[1].mode
;
13237 mode2
= insn_data
[icode
].operand
[2].mode
;
13239 if (mode0
== V2SImode
&& mode1
== V2SImode
&& mode2
== QImode
)
13241 if (! (type
= v2si_ftype_v2si_qi
))
13242 type
= v2si_ftype_v2si_qi
13243 = build_function_type_list (opaque_V2SI_type_node
,
13244 opaque_V2SI_type_node
,
13249 else if (mode0
== V2SImode
&& GET_MODE_CLASS (mode1
) == MODE_INT
13250 && mode2
== QImode
)
13252 if (! (type
= v2si_ftype_int_qi
))
13253 type
= v2si_ftype_int_qi
13254 = build_function_type_list (opaque_V2SI_type_node
,
13261 type
= builtin_function_type (mode0
, mode1
, mode2
, VOIDmode
,
13265 def_builtin (d
->mask
, d
->name
, type
, d
->code
);
13268 /* Add the simple unary operators. */
13269 d
= (struct builtin_description
*) bdesc_1arg
;
13270 for (i
= 0; i
< ARRAY_SIZE (bdesc_1arg
); i
++, d
++)
13272 enum machine_mode mode0
, mode1
;
13274 int mask
= d
->mask
;
13276 if ((mask
!= 0 && (mask
& target_flags
) == 0)
13277 || (mask
== 0 && !TARGET_PAIRED_FLOAT
))
13280 if ((d
->code
>= ALTIVEC_BUILTIN_OVERLOADED_FIRST
13281 && d
->code
<= ALTIVEC_BUILTIN_OVERLOADED_LAST
)
13282 || (d
->code
>= VSX_BUILTIN_OVERLOADED_FIRST
13283 && d
->code
<= VSX_BUILTIN_OVERLOADED_LAST
))
13285 if (! (type
= opaque_ftype_opaque
))
13286 type
= opaque_ftype_opaque
13287 = build_function_type_list (opaque_V4SI_type_node
,
13288 opaque_V4SI_type_node
,
13293 enum insn_code icode
= d
->icode
;
13294 if (d
->name
== 0 || icode
== CODE_FOR_nothing
)
13297 mode0
= insn_data
[icode
].operand
[0].mode
;
13298 mode1
= insn_data
[icode
].operand
[1].mode
;
13300 if (mode0
== V2SImode
&& mode1
== QImode
)
13302 if (! (type
= v2si_ftype_qi
))
13303 type
= v2si_ftype_qi
13304 = build_function_type_list (opaque_V2SI_type_node
,
13310 type
= builtin_function_type (mode0
, mode1
, VOIDmode
, VOIDmode
,
13314 def_builtin (d
->mask
, d
->name
, type
, d
->code
);
13319 rs6000_init_libfuncs (void)
13321 if (DEFAULT_ABI
!= ABI_V4
&& TARGET_XCOFF
13322 && !TARGET_POWER2
&& !TARGET_POWERPC
)
13324 /* AIX library routines for float->int conversion. */
13325 set_conv_libfunc (sfix_optab
, SImode
, DFmode
, "__itrunc");
13326 set_conv_libfunc (ufix_optab
, SImode
, DFmode
, "__uitrunc");
13327 set_conv_libfunc (sfix_optab
, SImode
, TFmode
, "_qitrunc");
13328 set_conv_libfunc (ufix_optab
, SImode
, TFmode
, "_quitrunc");
13331 if (!TARGET_IEEEQUAD
)
13332 /* AIX/Darwin/64-bit Linux quad floating point routines. */
13333 if (!TARGET_XL_COMPAT
)
13335 set_optab_libfunc (add_optab
, TFmode
, "__gcc_qadd");
13336 set_optab_libfunc (sub_optab
, TFmode
, "__gcc_qsub");
13337 set_optab_libfunc (smul_optab
, TFmode
, "__gcc_qmul");
13338 set_optab_libfunc (sdiv_optab
, TFmode
, "__gcc_qdiv");
13340 if (!(TARGET_HARD_FLOAT
&& (TARGET_FPRS
|| TARGET_E500_DOUBLE
)))
13342 set_optab_libfunc (neg_optab
, TFmode
, "__gcc_qneg");
13343 set_optab_libfunc (eq_optab
, TFmode
, "__gcc_qeq");
13344 set_optab_libfunc (ne_optab
, TFmode
, "__gcc_qne");
13345 set_optab_libfunc (gt_optab
, TFmode
, "__gcc_qgt");
13346 set_optab_libfunc (ge_optab
, TFmode
, "__gcc_qge");
13347 set_optab_libfunc (lt_optab
, TFmode
, "__gcc_qlt");
13348 set_optab_libfunc (le_optab
, TFmode
, "__gcc_qle");
13350 set_conv_libfunc (sext_optab
, TFmode
, SFmode
, "__gcc_stoq");
13351 set_conv_libfunc (sext_optab
, TFmode
, DFmode
, "__gcc_dtoq");
13352 set_conv_libfunc (trunc_optab
, SFmode
, TFmode
, "__gcc_qtos");
13353 set_conv_libfunc (trunc_optab
, DFmode
, TFmode
, "__gcc_qtod");
13354 set_conv_libfunc (sfix_optab
, SImode
, TFmode
, "__gcc_qtoi");
13355 set_conv_libfunc (ufix_optab
, SImode
, TFmode
, "__gcc_qtou");
13356 set_conv_libfunc (sfloat_optab
, TFmode
, SImode
, "__gcc_itoq");
13357 set_conv_libfunc (ufloat_optab
, TFmode
, SImode
, "__gcc_utoq");
13360 if (!(TARGET_HARD_FLOAT
&& TARGET_FPRS
))
13361 set_optab_libfunc (unord_optab
, TFmode
, "__gcc_qunord");
13365 set_optab_libfunc (add_optab
, TFmode
, "_xlqadd");
13366 set_optab_libfunc (sub_optab
, TFmode
, "_xlqsub");
13367 set_optab_libfunc (smul_optab
, TFmode
, "_xlqmul");
13368 set_optab_libfunc (sdiv_optab
, TFmode
, "_xlqdiv");
13372 /* 32-bit SVR4 quad floating point routines. */
13374 set_optab_libfunc (add_optab
, TFmode
, "_q_add");
13375 set_optab_libfunc (sub_optab
, TFmode
, "_q_sub");
13376 set_optab_libfunc (neg_optab
, TFmode
, "_q_neg");
13377 set_optab_libfunc (smul_optab
, TFmode
, "_q_mul");
13378 set_optab_libfunc (sdiv_optab
, TFmode
, "_q_div");
13379 if (TARGET_PPC_GPOPT
|| TARGET_POWER2
)
13380 set_optab_libfunc (sqrt_optab
, TFmode
, "_q_sqrt");
13382 set_optab_libfunc (eq_optab
, TFmode
, "_q_feq");
13383 set_optab_libfunc (ne_optab
, TFmode
, "_q_fne");
13384 set_optab_libfunc (gt_optab
, TFmode
, "_q_fgt");
13385 set_optab_libfunc (ge_optab
, TFmode
, "_q_fge");
13386 set_optab_libfunc (lt_optab
, TFmode
, "_q_flt");
13387 set_optab_libfunc (le_optab
, TFmode
, "_q_fle");
13389 set_conv_libfunc (sext_optab
, TFmode
, SFmode
, "_q_stoq");
13390 set_conv_libfunc (sext_optab
, TFmode
, DFmode
, "_q_dtoq");
13391 set_conv_libfunc (trunc_optab
, SFmode
, TFmode
, "_q_qtos");
13392 set_conv_libfunc (trunc_optab
, DFmode
, TFmode
, "_q_qtod");
13393 set_conv_libfunc (sfix_optab
, SImode
, TFmode
, "_q_qtoi");
13394 set_conv_libfunc (ufix_optab
, SImode
, TFmode
, "_q_qtou");
13395 set_conv_libfunc (sfloat_optab
, TFmode
, SImode
, "_q_itoq");
13396 set_conv_libfunc (ufloat_optab
, TFmode
, SImode
, "_q_utoq");
13401 /* Expand a block clear operation, and return 1 if successful. Return 0
13402 if we should let the compiler generate normal code.
13404 operands[0] is the destination
13405 operands[1] is the length
13406 operands[3] is the alignment */
13409 expand_block_clear (rtx operands
[])
13411 rtx orig_dest
= operands
[0];
13412 rtx bytes_rtx
= operands
[1];
13413 rtx align_rtx
= operands
[3];
13414 bool constp
= (GET_CODE (bytes_rtx
) == CONST_INT
);
13415 HOST_WIDE_INT align
;
13416 HOST_WIDE_INT bytes
;
13421 /* If this is not a fixed size move, just call memcpy */
13425 /* This must be a fixed size alignment */
13426 gcc_assert (GET_CODE (align_rtx
) == CONST_INT
);
13427 align
= INTVAL (align_rtx
) * BITS_PER_UNIT
;
13429 /* Anything to clear? */
13430 bytes
= INTVAL (bytes_rtx
);
13434 /* Use the builtin memset after a point, to avoid huge code bloat.
13435 When optimize_size, avoid any significant code bloat; calling
13436 memset is about 4 instructions, so allow for one instruction to
13437 load zero and three to do clearing. */
13438 if (TARGET_ALTIVEC
&& align
>= 128)
13440 else if (TARGET_POWERPC64
&& align
>= 32)
13442 else if (TARGET_SPE
&& align
>= 64)
13447 if (optimize_size
&& bytes
> 3 * clear_step
)
13449 if (! optimize_size
&& bytes
> 8 * clear_step
)
13452 for (offset
= 0; bytes
> 0; offset
+= clear_bytes
, bytes
-= clear_bytes
)
13454 enum machine_mode mode
= BLKmode
;
13457 if (bytes
>= 16 && TARGET_ALTIVEC
&& align
>= 128)
13462 else if (bytes
>= 8 && TARGET_SPE
&& align
>= 64)
13467 else if (bytes
>= 8 && TARGET_POWERPC64
13468 /* 64-bit loads and stores require word-aligned
13470 && (align
>= 64 || (!STRICT_ALIGNMENT
&& align
>= 32)))
13475 else if (bytes
>= 4 && (align
>= 32 || !STRICT_ALIGNMENT
))
13476 { /* move 4 bytes */
13480 else if (bytes
>= 2 && (align
>= 16 || !STRICT_ALIGNMENT
))
13481 { /* move 2 bytes */
13485 else /* move 1 byte at a time */
13491 dest
= adjust_address (orig_dest
, mode
, offset
);
13493 emit_move_insn (dest
, CONST0_RTX (mode
));
13500 /* Expand a block move operation, and return 1 if successful. Return 0
13501 if we should let the compiler generate normal code.
13503 operands[0] is the destination
13504 operands[1] is the source
13505 operands[2] is the length
13506 operands[3] is the alignment */
13508 #define MAX_MOVE_REG 4
13511 expand_block_move (rtx operands
[])
13513 rtx orig_dest
= operands
[0];
13514 rtx orig_src
= operands
[1];
13515 rtx bytes_rtx
= operands
[2];
13516 rtx align_rtx
= operands
[3];
13517 int constp
= (GET_CODE (bytes_rtx
) == CONST_INT
);
13522 rtx stores
[MAX_MOVE_REG
];
13525 /* If this is not a fixed size move, just call memcpy */
13529 /* This must be a fixed size alignment */
13530 gcc_assert (GET_CODE (align_rtx
) == CONST_INT
);
13531 align
= INTVAL (align_rtx
) * BITS_PER_UNIT
;
13533 /* Anything to move? */
13534 bytes
= INTVAL (bytes_rtx
);
13538 if (bytes
> rs6000_block_move_inline_limit
)
13541 for (offset
= 0; bytes
> 0; offset
+= move_bytes
, bytes
-= move_bytes
)
13544 rtx (*movmemsi
) (rtx
, rtx
, rtx
, rtx
);
13545 rtx (*mov
) (rtx
, rtx
);
13547 enum machine_mode mode
= BLKmode
;
13550 /* Altivec first, since it will be faster than a string move
13551 when it applies, and usually not significantly larger. */
13552 if (TARGET_ALTIVEC
&& bytes
>= 16 && align
>= 128)
13556 gen_func
.mov
= gen_movv4si
;
13558 else if (TARGET_SPE
&& bytes
>= 8 && align
>= 64)
13562 gen_func
.mov
= gen_movv2si
;
13564 else if (TARGET_STRING
13565 && bytes
> 24 /* move up to 32 bytes at a time */
13571 && ! fixed_regs
[10]
13572 && ! fixed_regs
[11]
13573 && ! fixed_regs
[12])
13575 move_bytes
= (bytes
> 32) ? 32 : bytes
;
13576 gen_func
.movmemsi
= gen_movmemsi_8reg
;
13578 else if (TARGET_STRING
13579 && bytes
> 16 /* move up to 24 bytes at a time */
13585 && ! fixed_regs
[10])
13587 move_bytes
= (bytes
> 24) ? 24 : bytes
;
13588 gen_func
.movmemsi
= gen_movmemsi_6reg
;
13590 else if (TARGET_STRING
13591 && bytes
> 8 /* move up to 16 bytes at a time */
13595 && ! fixed_regs
[8])
13597 move_bytes
= (bytes
> 16) ? 16 : bytes
;
13598 gen_func
.movmemsi
= gen_movmemsi_4reg
;
13600 else if (bytes
>= 8 && TARGET_POWERPC64
13601 /* 64-bit loads and stores require word-aligned
13603 && (align
>= 64 || (!STRICT_ALIGNMENT
&& align
>= 32)))
13607 gen_func
.mov
= gen_movdi
;
13609 else if (TARGET_STRING
&& bytes
> 4 && !TARGET_POWERPC64
)
13610 { /* move up to 8 bytes at a time */
13611 move_bytes
= (bytes
> 8) ? 8 : bytes
;
13612 gen_func
.movmemsi
= gen_movmemsi_2reg
;
13614 else if (bytes
>= 4 && (align
>= 32 || !STRICT_ALIGNMENT
))
13615 { /* move 4 bytes */
13618 gen_func
.mov
= gen_movsi
;
13620 else if (bytes
>= 2 && (align
>= 16 || !STRICT_ALIGNMENT
))
13621 { /* move 2 bytes */
13624 gen_func
.mov
= gen_movhi
;
13626 else if (TARGET_STRING
&& bytes
> 1)
13627 { /* move up to 4 bytes at a time */
13628 move_bytes
= (bytes
> 4) ? 4 : bytes
;
13629 gen_func
.movmemsi
= gen_movmemsi_1reg
;
13631 else /* move 1 byte at a time */
13635 gen_func
.mov
= gen_movqi
;
13638 src
= adjust_address (orig_src
, mode
, offset
);
13639 dest
= adjust_address (orig_dest
, mode
, offset
);
13641 if (mode
!= BLKmode
)
13643 rtx tmp_reg
= gen_reg_rtx (mode
);
13645 emit_insn ((*gen_func
.mov
) (tmp_reg
, src
));
13646 stores
[num_reg
++] = (*gen_func
.mov
) (dest
, tmp_reg
);
13649 if (mode
== BLKmode
|| num_reg
>= MAX_MOVE_REG
|| bytes
== move_bytes
)
13652 for (i
= 0; i
< num_reg
; i
++)
13653 emit_insn (stores
[i
]);
13657 if (mode
== BLKmode
)
13659 /* Move the address into scratch registers. The movmemsi
13660 patterns require zero offset. */
13661 if (!REG_P (XEXP (src
, 0)))
13663 rtx src_reg
= copy_addr_to_reg (XEXP (src
, 0));
13664 src
= replace_equiv_address (src
, src_reg
);
13666 set_mem_size (src
, GEN_INT (move_bytes
));
13668 if (!REG_P (XEXP (dest
, 0)))
13670 rtx dest_reg
= copy_addr_to_reg (XEXP (dest
, 0));
13671 dest
= replace_equiv_address (dest
, dest_reg
);
13673 set_mem_size (dest
, GEN_INT (move_bytes
));
13675 emit_insn ((*gen_func
.movmemsi
) (dest
, src
,
13676 GEN_INT (move_bytes
& 31),
13685 /* Return a string to perform a load_multiple operation.
13686 operands[0] is the vector.
13687 operands[1] is the source address.
13688 operands[2] is the first destination register. */
13691 rs6000_output_load_multiple (rtx operands
[3])
13693 /* We have to handle the case where the pseudo used to contain the address
13694 is assigned to one of the output registers. */
13696 int words
= XVECLEN (operands
[0], 0);
13699 if (XVECLEN (operands
[0], 0) == 1)
13700 return "{l|lwz} %2,0(%1)";
13702 for (i
= 0; i
< words
; i
++)
13703 if (refers_to_regno_p (REGNO (operands
[2]) + i
,
13704 REGNO (operands
[2]) + i
+ 1, operands
[1], 0))
13708 xop
[0] = GEN_INT (4 * (words
-1));
13709 xop
[1] = operands
[1];
13710 xop
[2] = operands
[2];
13711 output_asm_insn ("{lsi|lswi} %2,%1,%0\n\t{l|lwz} %1,%0(%1)", xop
);
13716 xop
[0] = GEN_INT (4 * (words
-1));
13717 xop
[1] = operands
[1];
13718 xop
[2] = gen_rtx_REG (SImode
, REGNO (operands
[2]) + 1);
13719 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
);
13724 for (j
= 0; j
< words
; j
++)
13727 xop
[0] = GEN_INT (j
* 4);
13728 xop
[1] = operands
[1];
13729 xop
[2] = gen_rtx_REG (SImode
, REGNO (operands
[2]) + j
);
13730 output_asm_insn ("{l|lwz} %2,%0(%1)", xop
);
13732 xop
[0] = GEN_INT (i
* 4);
13733 xop
[1] = operands
[1];
13734 output_asm_insn ("{l|lwz} %1,%0(%1)", xop
);
13739 return "{lsi|lswi} %2,%1,%N0";
13743 /* A validation routine: say whether CODE, a condition code, and MODE
13744 match. The other alternatives either don't make sense or should
13745 never be generated. */
13748 validate_condition_mode (enum rtx_code code
, enum machine_mode mode
)
13750 gcc_assert ((GET_RTX_CLASS (code
) == RTX_COMPARE
13751 || GET_RTX_CLASS (code
) == RTX_COMM_COMPARE
)
13752 && GET_MODE_CLASS (mode
) == MODE_CC
);
13754 /* These don't make sense. */
13755 gcc_assert ((code
!= GT
&& code
!= LT
&& code
!= GE
&& code
!= LE
)
13756 || mode
!= CCUNSmode
);
13758 gcc_assert ((code
!= GTU
&& code
!= LTU
&& code
!= GEU
&& code
!= LEU
)
13759 || mode
== CCUNSmode
);
13761 gcc_assert (mode
== CCFPmode
13762 || (code
!= ORDERED
&& code
!= UNORDERED
13763 && code
!= UNEQ
&& code
!= LTGT
13764 && code
!= UNGT
&& code
!= UNLT
13765 && code
!= UNGE
&& code
!= UNLE
));
13767 /* These should never be generated except for
13768 flag_finite_math_only. */
13769 gcc_assert (mode
!= CCFPmode
13770 || flag_finite_math_only
13771 || (code
!= LE
&& code
!= GE
13772 && code
!= UNEQ
&& code
!= LTGT
13773 && code
!= UNGT
&& code
!= UNLT
));
13775 /* These are invalid; the information is not there. */
13776 gcc_assert (mode
!= CCEQmode
|| code
== EQ
|| code
== NE
);
13780 /* Return 1 if ANDOP is a mask that has no bits on that are not in the
13781 mask required to convert the result of a rotate insn into a shift
13782 left insn of SHIFTOP bits. Both are known to be SImode CONST_INT. */
13785 includes_lshift_p (rtx shiftop
, rtx andop
)
13787 unsigned HOST_WIDE_INT shift_mask
= ~(unsigned HOST_WIDE_INT
) 0;
13789 shift_mask
<<= INTVAL (shiftop
);
13791 return (INTVAL (andop
) & 0xffffffff & ~shift_mask
) == 0;
13794 /* Similar, but for right shift. */
13797 includes_rshift_p (rtx shiftop
, rtx andop
)
13799 unsigned HOST_WIDE_INT shift_mask
= ~(unsigned HOST_WIDE_INT
) 0;
13801 shift_mask
>>= INTVAL (shiftop
);
13803 return (INTVAL (andop
) & 0xffffffff & ~shift_mask
) == 0;
13806 /* Return 1 if ANDOP is a mask suitable for use with an rldic insn
13807 to perform a left shift. It must have exactly SHIFTOP least
13808 significant 0's, then one or more 1's, then zero or more 0's. */
13811 includes_rldic_lshift_p (rtx shiftop
, rtx andop
)
13813 if (GET_CODE (andop
) == CONST_INT
)
13815 HOST_WIDE_INT c
, lsb
, shift_mask
;
13817 c
= INTVAL (andop
);
13818 if (c
== 0 || c
== ~0)
13822 shift_mask
<<= INTVAL (shiftop
);
13824 /* Find the least significant one bit. */
13827 /* It must coincide with the LSB of the shift mask. */
13828 if (-lsb
!= shift_mask
)
13831 /* Invert to look for the next transition (if any). */
13834 /* Remove the low group of ones (originally low group of zeros). */
13837 /* Again find the lsb, and check we have all 1's above. */
13841 else if (GET_CODE (andop
) == CONST_DOUBLE
13842 && (GET_MODE (andop
) == VOIDmode
|| GET_MODE (andop
) == DImode
))
13844 HOST_WIDE_INT low
, high
, lsb
;
13845 HOST_WIDE_INT shift_mask_low
, shift_mask_high
;
13847 low
= CONST_DOUBLE_LOW (andop
);
13848 if (HOST_BITS_PER_WIDE_INT
< 64)
13849 high
= CONST_DOUBLE_HIGH (andop
);
13851 if ((low
== 0 && (HOST_BITS_PER_WIDE_INT
>= 64 || high
== 0))
13852 || (low
== ~0 && (HOST_BITS_PER_WIDE_INT
>= 64 || high
== ~0)))
13855 if (HOST_BITS_PER_WIDE_INT
< 64 && low
== 0)
13857 shift_mask_high
= ~0;
13858 if (INTVAL (shiftop
) > 32)
13859 shift_mask_high
<<= INTVAL (shiftop
) - 32;
13861 lsb
= high
& -high
;
13863 if (-lsb
!= shift_mask_high
|| INTVAL (shiftop
) < 32)
13869 lsb
= high
& -high
;
13870 return high
== -lsb
;
13873 shift_mask_low
= ~0;
13874 shift_mask_low
<<= INTVAL (shiftop
);
13878 if (-lsb
!= shift_mask_low
)
13881 if (HOST_BITS_PER_WIDE_INT
< 64)
13886 if (HOST_BITS_PER_WIDE_INT
< 64 && low
== 0)
13888 lsb
= high
& -high
;
13889 return high
== -lsb
;
13893 return low
== -lsb
&& (HOST_BITS_PER_WIDE_INT
>= 64 || high
== ~0);
13899 /* Return 1 if ANDOP is a mask suitable for use with an rldicr insn
13900 to perform a left shift. It must have SHIFTOP or more least
13901 significant 0's, with the remainder of the word 1's. */
13904 includes_rldicr_lshift_p (rtx shiftop
, rtx andop
)
13906 if (GET_CODE (andop
) == CONST_INT
)
13908 HOST_WIDE_INT c
, lsb
, shift_mask
;
13911 shift_mask
<<= INTVAL (shiftop
);
13912 c
= INTVAL (andop
);
13914 /* Find the least significant one bit. */
13917 /* It must be covered by the shift mask.
13918 This test also rejects c == 0. */
13919 if ((lsb
& shift_mask
) == 0)
13922 /* Check we have all 1's above the transition, and reject all 1's. */
13923 return c
== -lsb
&& lsb
!= 1;
13925 else if (GET_CODE (andop
) == CONST_DOUBLE
13926 && (GET_MODE (andop
) == VOIDmode
|| GET_MODE (andop
) == DImode
))
13928 HOST_WIDE_INT low
, lsb
, shift_mask_low
;
13930 low
= CONST_DOUBLE_LOW (andop
);
13932 if (HOST_BITS_PER_WIDE_INT
< 64)
13934 HOST_WIDE_INT high
, shift_mask_high
;
13936 high
= CONST_DOUBLE_HIGH (andop
);
13940 shift_mask_high
= ~0;
13941 if (INTVAL (shiftop
) > 32)
13942 shift_mask_high
<<= INTVAL (shiftop
) - 32;
13944 lsb
= high
& -high
;
13946 if ((lsb
& shift_mask_high
) == 0)
13949 return high
== -lsb
;
13955 shift_mask_low
= ~0;
13956 shift_mask_low
<<= INTVAL (shiftop
);
13960 if ((lsb
& shift_mask_low
) == 0)
13963 return low
== -lsb
&& lsb
!= 1;
13969 /* Return 1 if operands will generate a valid arguments to rlwimi
13970 instruction for insert with right shift in 64-bit mode. The mask may
13971 not start on the first bit or stop on the last bit because wrap-around
13972 effects of instruction do not correspond to semantics of RTL insn. */
13975 insvdi_rshift_rlwimi_p (rtx sizeop
, rtx startop
, rtx shiftop
)
13977 if (INTVAL (startop
) > 32
13978 && INTVAL (startop
) < 64
13979 && INTVAL (sizeop
) > 1
13980 && INTVAL (sizeop
) + INTVAL (startop
) < 64
13981 && INTVAL (shiftop
) > 0
13982 && INTVAL (sizeop
) + INTVAL (shiftop
) < 32
13983 && (64 - (INTVAL (shiftop
) & 63)) >= INTVAL (sizeop
))
13989 /* Return 1 if REGNO (reg1) == REGNO (reg2) - 1 making them candidates
13990 for lfq and stfq insns iff the registers are hard registers. */
13993 registers_ok_for_quad_peep (rtx reg1
, rtx reg2
)
13995 /* We might have been passed a SUBREG. */
13996 if (GET_CODE (reg1
) != REG
|| GET_CODE (reg2
) != REG
)
13999 /* We might have been passed non floating point registers. */
14000 if (!FP_REGNO_P (REGNO (reg1
))
14001 || !FP_REGNO_P (REGNO (reg2
)))
14004 return (REGNO (reg1
) == REGNO (reg2
) - 1);
14007 /* Return 1 if addr1 and addr2 are suitable for lfq or stfq insn.
14008 addr1 and addr2 must be in consecutive memory locations
14009 (addr2 == addr1 + 8). */
14012 mems_ok_for_quad_peep (rtx mem1
, rtx mem2
)
14015 unsigned int reg1
, reg2
;
14016 int offset1
, offset2
;
14018 /* The mems cannot be volatile. */
14019 if (MEM_VOLATILE_P (mem1
) || MEM_VOLATILE_P (mem2
))
14022 addr1
= XEXP (mem1
, 0);
14023 addr2
= XEXP (mem2
, 0);
14025 /* Extract an offset (if used) from the first addr. */
14026 if (GET_CODE (addr1
) == PLUS
)
14028 /* If not a REG, return zero. */
14029 if (GET_CODE (XEXP (addr1
, 0)) != REG
)
14033 reg1
= REGNO (XEXP (addr1
, 0));
14034 /* The offset must be constant! */
14035 if (GET_CODE (XEXP (addr1
, 1)) != CONST_INT
)
14037 offset1
= INTVAL (XEXP (addr1
, 1));
14040 else if (GET_CODE (addr1
) != REG
)
14044 reg1
= REGNO (addr1
);
14045 /* This was a simple (mem (reg)) expression. Offset is 0. */
14049 /* And now for the second addr. */
14050 if (GET_CODE (addr2
) == PLUS
)
14052 /* If not a REG, return zero. */
14053 if (GET_CODE (XEXP (addr2
, 0)) != REG
)
14057 reg2
= REGNO (XEXP (addr2
, 0));
14058 /* The offset must be constant. */
14059 if (GET_CODE (XEXP (addr2
, 1)) != CONST_INT
)
14061 offset2
= INTVAL (XEXP (addr2
, 1));
14064 else if (GET_CODE (addr2
) != REG
)
14068 reg2
= REGNO (addr2
);
14069 /* This was a simple (mem (reg)) expression. Offset is 0. */
14073 /* Both of these must have the same base register. */
14077 /* The offset for the second addr must be 8 more than the first addr. */
14078 if (offset2
!= offset1
+ 8)
14081 /* All the tests passed. addr1 and addr2 are valid for lfq or stfq
14088 rs6000_secondary_memory_needed_rtx (enum machine_mode mode
)
14090 static bool eliminated
= false;
14093 if (mode
!= SDmode
)
14094 ret
= assign_stack_local (mode
, GET_MODE_SIZE (mode
), 0);
14097 rtx mem
= cfun
->machine
->sdmode_stack_slot
;
14098 gcc_assert (mem
!= NULL_RTX
);
14102 mem
= eliminate_regs (mem
, VOIDmode
, NULL_RTX
);
14103 cfun
->machine
->sdmode_stack_slot
= mem
;
14109 if (TARGET_DEBUG_ADDR
)
14111 fprintf (stderr
, "\nrs6000_secondary_memory_needed_rtx, mode %s, rtx:\n",
14112 GET_MODE_NAME (mode
));
14114 fprintf (stderr
, "\tNULL_RTX\n");
14123 rs6000_check_sdmode (tree
*tp
, int *walk_subtrees
, void *data ATTRIBUTE_UNUSED
)
14125 /* Don't walk into types. */
14126 if (*tp
== NULL_TREE
|| *tp
== error_mark_node
|| TYPE_P (*tp
))
14128 *walk_subtrees
= 0;
14132 switch (TREE_CODE (*tp
))
14141 case MISALIGNED_INDIRECT_REF
:
14142 case VIEW_CONVERT_EXPR
:
14143 if (TYPE_MODE (TREE_TYPE (*tp
)) == SDmode
)
14153 enum reload_reg_type
{
14155 VECTOR_REGISTER_TYPE
,
14156 OTHER_REGISTER_TYPE
14159 static enum reload_reg_type
14160 rs6000_reload_register_type (enum reg_class rclass
)
14166 return GPR_REGISTER_TYPE
;
14171 return VECTOR_REGISTER_TYPE
;
14174 return OTHER_REGISTER_TYPE
;
14178 /* Inform reload about cases where moving X with a mode MODE to a register in
14179 RCLASS requires an extra scratch or immediate register. Return the class
14180 needed for the immediate register.
14182 For VSX and Altivec, we may need a register to convert sp+offset into
14186 rs6000_secondary_reload (bool in_p
,
14188 reg_class_t rclass_i
,
14189 enum machine_mode mode
,
14190 secondary_reload_info
*sri
)
14192 enum reg_class rclass
= (enum reg_class
) rclass_i
;
14193 reg_class_t ret
= ALL_REGS
;
14194 enum insn_code icode
;
14195 bool default_p
= false;
14197 sri
->icode
= CODE_FOR_nothing
;
14199 /* Convert vector loads and stores into gprs to use an additional base
14201 icode
= rs6000_vector_reload
[mode
][in_p
!= false];
14202 if (icode
!= CODE_FOR_nothing
)
14205 sri
->icode
= CODE_FOR_nothing
;
14206 sri
->extra_cost
= 0;
14208 if (GET_CODE (x
) == MEM
)
14210 rtx addr
= XEXP (x
, 0);
14212 /* Loads to and stores from gprs can do reg+offset, and wouldn't need
14213 an extra register in that case, but it would need an extra
14214 register if the addressing is reg+reg or (reg+reg)&(-16). */
14215 if (rclass
== GENERAL_REGS
|| rclass
== BASE_REGS
)
14217 if (!legitimate_indirect_address_p (addr
, false)
14218 && !rs6000_legitimate_offset_address_p (TImode
, addr
, false))
14220 sri
->icode
= icode
;
14221 /* account for splitting the loads, and converting the
14222 address from reg+reg to reg. */
14223 sri
->extra_cost
= (((TARGET_64BIT
) ? 3 : 5)
14224 + ((GET_CODE (addr
) == AND
) ? 1 : 0));
14227 /* Loads to and stores from vector registers can only do reg+reg
14228 addressing. Altivec registers can also do (reg+reg)&(-16). */
14229 else if (rclass
== VSX_REGS
|| rclass
== ALTIVEC_REGS
14230 || rclass
== FLOAT_REGS
|| rclass
== NO_REGS
)
14232 if (!VECTOR_MEM_ALTIVEC_P (mode
)
14233 && GET_CODE (addr
) == AND
14234 && GET_CODE (XEXP (addr
, 1)) == CONST_INT
14235 && INTVAL (XEXP (addr
, 1)) == -16
14236 && (legitimate_indirect_address_p (XEXP (addr
, 0), false)
14237 || legitimate_indexed_address_p (XEXP (addr
, 0), false)))
14239 sri
->icode
= icode
;
14240 sri
->extra_cost
= ((GET_CODE (XEXP (addr
, 0)) == PLUS
)
14243 else if (!legitimate_indirect_address_p (addr
, false)
14244 && (rclass
== NO_REGS
14245 || !legitimate_indexed_address_p (addr
, false)))
14247 sri
->icode
= icode
;
14248 sri
->extra_cost
= 1;
14251 icode
= CODE_FOR_nothing
;
14253 /* Any other loads, including to pseudo registers which haven't been
14254 assigned to a register yet, default to require a scratch
14258 sri
->icode
= icode
;
14259 sri
->extra_cost
= 2;
14262 else if (REG_P (x
))
14264 int regno
= true_regnum (x
);
14266 icode
= CODE_FOR_nothing
;
14267 if (regno
< 0 || regno
>= FIRST_PSEUDO_REGISTER
)
14271 enum reg_class xclass
= REGNO_REG_CLASS (regno
);
14272 enum reload_reg_type rtype1
= rs6000_reload_register_type (rclass
);
14273 enum reload_reg_type rtype2
= rs6000_reload_register_type (xclass
);
14275 /* If memory is needed, use default_secondary_reload to create the
14277 if (rtype1
!= rtype2
|| rtype1
== OTHER_REGISTER_TYPE
)
14290 ret
= default_secondary_reload (in_p
, x
, rclass
, mode
, sri
);
14292 gcc_assert (ret
!= ALL_REGS
);
14294 if (TARGET_DEBUG_ADDR
)
14297 "\nrs6000_secondary_reload, return %s, in_p = %s, rclass = %s, "
14299 reg_class_names
[ret
],
14300 in_p
? "true" : "false",
14301 reg_class_names
[rclass
],
14302 GET_MODE_NAME (mode
));
14305 fprintf (stderr
, ", default secondary reload");
14307 if (sri
->icode
!= CODE_FOR_nothing
)
14308 fprintf (stderr
, ", reload func = %s, extra cost = %d\n",
14309 insn_data
[sri
->icode
].name
, sri
->extra_cost
);
14311 fprintf (stderr
, "\n");
14319 /* Fixup reload addresses for Altivec or VSX loads/stores to change SP+offset
14320 to SP+reg addressing. */
14323 rs6000_secondary_reload_inner (rtx reg
, rtx mem
, rtx scratch
, bool store_p
)
14325 int regno
= true_regnum (reg
);
14326 enum machine_mode mode
= GET_MODE (reg
);
14327 enum reg_class rclass
;
14329 rtx and_op2
= NULL_RTX
;
14332 rtx scratch_or_premodify
= scratch
;
14336 if (TARGET_DEBUG_ADDR
)
14338 fprintf (stderr
, "\nrs6000_secondary_reload_inner, type = %s\n",
14339 store_p
? "store" : "load");
14340 fprintf (stderr
, "reg:\n");
14342 fprintf (stderr
, "mem:\n");
14344 fprintf (stderr
, "scratch:\n");
14345 debug_rtx (scratch
);
14348 gcc_assert (regno
>= 0 && regno
< FIRST_PSEUDO_REGISTER
);
14349 gcc_assert (GET_CODE (mem
) == MEM
);
14350 rclass
= REGNO_REG_CLASS (regno
);
14351 addr
= XEXP (mem
, 0);
14355 /* GPRs can handle reg + small constant, all other addresses need to use
14356 the scratch register. */
14359 if (GET_CODE (addr
) == AND
)
14361 and_op2
= XEXP (addr
, 1);
14362 addr
= XEXP (addr
, 0);
14365 if (GET_CODE (addr
) == PRE_MODIFY
)
14367 scratch_or_premodify
= XEXP (addr
, 0);
14368 gcc_assert (REG_P (scratch_or_premodify
));
14369 gcc_assert (GET_CODE (XEXP (addr
, 1)) == PLUS
);
14370 addr
= XEXP (addr
, 1);
14373 if (GET_CODE (addr
) == PLUS
14374 && (!rs6000_legitimate_offset_address_p (TImode
, addr
, false)
14375 || and_op2
!= NULL_RTX
))
14377 addr_op1
= XEXP (addr
, 0);
14378 addr_op2
= XEXP (addr
, 1);
14379 gcc_assert (legitimate_indirect_address_p (addr_op1
, false));
14381 if (!REG_P (addr_op2
)
14382 && (GET_CODE (addr_op2
) != CONST_INT
14383 || !satisfies_constraint_I (addr_op2
)))
14385 if (TARGET_DEBUG_ADDR
)
14388 "\nMove plus addr to register %s, mode = %s: ",
14389 rs6000_reg_names
[REGNO (scratch
)],
14390 GET_MODE_NAME (mode
));
14391 debug_rtx (addr_op2
);
14393 rs6000_emit_move (scratch
, addr_op2
, Pmode
);
14394 addr_op2
= scratch
;
14397 emit_insn (gen_rtx_SET (VOIDmode
,
14398 scratch_or_premodify
,
14399 gen_rtx_PLUS (Pmode
,
14403 addr
= scratch_or_premodify
;
14404 scratch_or_premodify
= scratch
;
14406 else if (!legitimate_indirect_address_p (addr
, false)
14407 && !rs6000_legitimate_offset_address_p (TImode
, addr
, false))
14409 if (TARGET_DEBUG_ADDR
)
14411 fprintf (stderr
, "\nMove addr to register %s, mode = %s: ",
14412 rs6000_reg_names
[REGNO (scratch_or_premodify
)],
14413 GET_MODE_NAME (mode
));
14416 rs6000_emit_move (scratch_or_premodify
, addr
, Pmode
);
14417 addr
= scratch_or_premodify
;
14418 scratch_or_premodify
= scratch
;
14422 /* Float/Altivec registers can only handle reg+reg addressing. Move
14423 other addresses into a scratch register. */
14428 /* With float regs, we need to handle the AND ourselves, since we can't
14429 use the Altivec instruction with an implicit AND -16. Allow scalar
14430 loads to float registers to use reg+offset even if VSX. */
14431 if (GET_CODE (addr
) == AND
14432 && (rclass
!= ALTIVEC_REGS
|| GET_MODE_SIZE (mode
) != 16
14433 || GET_CODE (XEXP (addr
, 1)) != CONST_INT
14434 || INTVAL (XEXP (addr
, 1)) != -16
14435 || !VECTOR_MEM_ALTIVEC_P (mode
)))
14437 and_op2
= XEXP (addr
, 1);
14438 addr
= XEXP (addr
, 0);
14441 /* If we aren't using a VSX load, save the PRE_MODIFY register and use it
14442 as the address later. */
14443 if (GET_CODE (addr
) == PRE_MODIFY
14444 && (!VECTOR_MEM_VSX_P (mode
)
14445 || and_op2
!= NULL_RTX
14446 || !legitimate_indexed_address_p (XEXP (addr
, 1), false)))
14448 scratch_or_premodify
= XEXP (addr
, 0);
14449 gcc_assert (legitimate_indirect_address_p (scratch_or_premodify
,
14451 gcc_assert (GET_CODE (XEXP (addr
, 1)) == PLUS
);
14452 addr
= XEXP (addr
, 1);
14455 if (legitimate_indirect_address_p (addr
, false) /* reg */
14456 || legitimate_indexed_address_p (addr
, false) /* reg+reg */
14457 || GET_CODE (addr
) == PRE_MODIFY
/* VSX pre-modify */
14458 || (GET_CODE (addr
) == AND
/* Altivec memory */
14459 && GET_CODE (XEXP (addr
, 1)) == CONST_INT
14460 && INTVAL (XEXP (addr
, 1)) == -16
14461 && VECTOR_MEM_ALTIVEC_P (mode
))
14462 || (rclass
== FLOAT_REGS
/* legacy float mem */
14463 && GET_MODE_SIZE (mode
) == 8
14464 && and_op2
== NULL_RTX
14465 && scratch_or_premodify
== scratch
14466 && rs6000_legitimate_offset_address_p (mode
, addr
, false)))
14469 else if (GET_CODE (addr
) == PLUS
)
14471 addr_op1
= XEXP (addr
, 0);
14472 addr_op2
= XEXP (addr
, 1);
14473 gcc_assert (REG_P (addr_op1
));
14475 if (TARGET_DEBUG_ADDR
)
14477 fprintf (stderr
, "\nMove plus addr to register %s, mode = %s: ",
14478 rs6000_reg_names
[REGNO (scratch
)], GET_MODE_NAME (mode
));
14479 debug_rtx (addr_op2
);
14481 rs6000_emit_move (scratch
, addr_op2
, Pmode
);
14482 emit_insn (gen_rtx_SET (VOIDmode
,
14483 scratch_or_premodify
,
14484 gen_rtx_PLUS (Pmode
,
14487 addr
= scratch_or_premodify
;
14488 scratch_or_premodify
= scratch
;
14491 else if (GET_CODE (addr
) == SYMBOL_REF
|| GET_CODE (addr
) == CONST
14492 || GET_CODE (addr
) == CONST_INT
|| REG_P (addr
))
14494 if (TARGET_DEBUG_ADDR
)
14496 fprintf (stderr
, "\nMove addr to register %s, mode = %s: ",
14497 rs6000_reg_names
[REGNO (scratch_or_premodify
)],
14498 GET_MODE_NAME (mode
));
14502 rs6000_emit_move (scratch_or_premodify
, addr
, Pmode
);
14503 addr
= scratch_or_premodify
;
14504 scratch_or_premodify
= scratch
;
14508 gcc_unreachable ();
14513 gcc_unreachable ();
14516 /* If the original address involved a pre-modify that we couldn't use the VSX
14517 memory instruction with update, and we haven't taken care of already,
14518 store the address in the pre-modify register and use that as the
14520 if (scratch_or_premodify
!= scratch
&& scratch_or_premodify
!= addr
)
14522 emit_insn (gen_rtx_SET (VOIDmode
, scratch_or_premodify
, addr
));
14523 addr
= scratch_or_premodify
;
14526 /* If the original address involved an AND -16 and we couldn't use an ALTIVEC
14527 memory instruction, recreate the AND now, including the clobber which is
14528 generated by the general ANDSI3/ANDDI3 patterns for the
14529 andi. instruction. */
14530 if (and_op2
!= NULL_RTX
)
14532 if (! legitimate_indirect_address_p (addr
, false))
14534 emit_insn (gen_rtx_SET (VOIDmode
, scratch
, addr
));
14538 if (TARGET_DEBUG_ADDR
)
14540 fprintf (stderr
, "\nAnd addr to register %s, mode = %s: ",
14541 rs6000_reg_names
[REGNO (scratch
)], GET_MODE_NAME (mode
));
14542 debug_rtx (and_op2
);
14545 and_rtx
= gen_rtx_SET (VOIDmode
,
14547 gen_rtx_AND (Pmode
,
14551 cc_clobber
= gen_rtx_CLOBBER (CCmode
, gen_rtx_SCRATCH (CCmode
));
14552 emit_insn (gen_rtx_PARALLEL (VOIDmode
,
14553 gen_rtvec (2, and_rtx
, cc_clobber
)));
14557 /* Adjust the address if it changed. */
14558 if (addr
!= XEXP (mem
, 0))
14560 mem
= change_address (mem
, mode
, addr
);
14561 if (TARGET_DEBUG_ADDR
)
14562 fprintf (stderr
, "\nrs6000_secondary_reload_inner, mem adjusted.\n");
14565 /* Now create the move. */
14567 emit_insn (gen_rtx_SET (VOIDmode
, mem
, reg
));
14569 emit_insn (gen_rtx_SET (VOIDmode
, reg
, mem
));
14574 /* Target hook to return the cover classes for Integrated Register Allocator.
14575 Cover classes is a set of non-intersected register classes covering all hard
14576 registers used for register allocation purpose. Any move between two
14577 registers of a cover class should be cheaper than load or store of the
14578 registers. The value is array of register classes with LIM_REG_CLASSES used
14581 We need two IRA_COVER_CLASSES, one for pre-VSX, and the other for VSX to
14582 account for the Altivec and Floating registers being subsets of the VSX
14583 register set under VSX, but distinct register sets on pre-VSX machines. */
14585 static const reg_class_t
*
14586 rs6000_ira_cover_classes (void)
14588 static const reg_class_t cover_pre_vsx
[] = IRA_COVER_CLASSES_PRE_VSX
;
14589 static const reg_class_t cover_vsx
[] = IRA_COVER_CLASSES_VSX
;
14591 return (TARGET_VSX
) ? cover_vsx
: cover_pre_vsx
;
14594 /* Allocate a 64-bit stack slot to be used for copying SDmode
14595 values through if this function has any SDmode references. */
14598 rs6000_alloc_sdmode_stack_slot (void)
14602 gimple_stmt_iterator gsi
;
14604 gcc_assert (cfun
->machine
->sdmode_stack_slot
== NULL_RTX
);
14607 for (gsi
= gsi_start_bb (bb
); !gsi_end_p (gsi
); gsi_next (&gsi
))
14609 tree ret
= walk_gimple_op (gsi_stmt (gsi
), rs6000_check_sdmode
, NULL
);
14612 rtx stack
= assign_stack_local (DDmode
, GET_MODE_SIZE (DDmode
), 0);
14613 cfun
->machine
->sdmode_stack_slot
= adjust_address_nv (stack
,
14619 /* Check for any SDmode parameters of the function. */
14620 for (t
= DECL_ARGUMENTS (cfun
->decl
); t
; t
= DECL_CHAIN (t
))
14622 if (TREE_TYPE (t
) == error_mark_node
)
14625 if (TYPE_MODE (TREE_TYPE (t
)) == SDmode
14626 || TYPE_MODE (DECL_ARG_TYPE (t
)) == SDmode
)
14628 rtx stack
= assign_stack_local (DDmode
, GET_MODE_SIZE (DDmode
), 0);
14629 cfun
->machine
->sdmode_stack_slot
= adjust_address_nv (stack
,
14637 rs6000_instantiate_decls (void)
14639 if (cfun
->machine
->sdmode_stack_slot
!= NULL_RTX
)
14640 instantiate_decl_rtl (cfun
->machine
->sdmode_stack_slot
);
14643 /* Given an rtx X being reloaded into a reg required to be
14644 in class CLASS, return the class of reg to actually use.
14645 In general this is just CLASS; but on some machines
14646 in some cases it is preferable to use a more restrictive class.
14648 On the RS/6000, we have to return NO_REGS when we want to reload a
14649 floating-point CONST_DOUBLE to force it to be copied to memory.
14651 We also don't want to reload integer values into floating-point
14652 registers if we can at all help it. In fact, this can
14653 cause reload to die, if it tries to generate a reload of CTR
14654 into a FP register and discovers it doesn't have the memory location
14657 ??? Would it be a good idea to have reload do the converse, that is
14658 try to reload floating modes into FP registers if possible?
14661 static enum reg_class
14662 rs6000_preferred_reload_class (rtx x
, enum reg_class rclass
)
14664 enum machine_mode mode
= GET_MODE (x
);
14666 if (VECTOR_UNIT_VSX_P (mode
)
14667 && x
== CONST0_RTX (mode
) && VSX_REG_CLASS_P (rclass
))
14670 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode
)
14671 && (rclass
== ALTIVEC_REGS
|| rclass
== VSX_REGS
)
14672 && easy_vector_constant (x
, mode
))
14673 return ALTIVEC_REGS
;
14675 if (CONSTANT_P (x
) && reg_classes_intersect_p (rclass
, FLOAT_REGS
))
14678 if (GET_MODE_CLASS (mode
) == MODE_INT
&& rclass
== NON_SPECIAL_REGS
)
14679 return GENERAL_REGS
;
14681 /* For VSX, prefer the traditional registers for 64-bit values because we can
14682 use the non-VSX loads. Prefer the Altivec registers if Altivec is
14683 handling the vector operations (i.e. V16QI, V8HI, and V4SI), or if we
14684 prefer Altivec loads.. */
14685 if (rclass
== VSX_REGS
)
14687 if (GET_MODE_SIZE (mode
) <= 8)
14690 if (VECTOR_UNIT_ALTIVEC_P (mode
) || VECTOR_MEM_ALTIVEC_P (mode
))
14691 return ALTIVEC_REGS
;
14699 /* Debug version of rs6000_preferred_reload_class. */
14700 static enum reg_class
14701 rs6000_debug_preferred_reload_class (rtx x
, enum reg_class rclass
)
14703 enum reg_class ret
= rs6000_preferred_reload_class (x
, rclass
);
14706 "\nrs6000_preferred_reload_class, return %s, rclass = %s, "
14708 reg_class_names
[ret
], reg_class_names
[rclass
],
14709 GET_MODE_NAME (GET_MODE (x
)));
14715 /* If we are copying between FP or AltiVec registers and anything else, we need
14716 a memory location. The exception is when we are targeting ppc64 and the
14717 move to/from fpr to gpr instructions are available. Also, under VSX, you
14718 can copy vector registers from the FP register set to the Altivec register
14719 set and vice versa. */
14722 rs6000_secondary_memory_needed (enum reg_class class1
,
14723 enum reg_class class2
,
14724 enum machine_mode mode
)
14726 if (class1
== class2
)
14729 /* Under VSX, there are 3 register classes that values could be in (VSX_REGS,
14730 ALTIVEC_REGS, and FLOAT_REGS). We don't need to use memory to copy
14731 between these classes. But we need memory for other things that can go in
14732 FLOAT_REGS like SFmode. */
14734 && (VECTOR_MEM_VSX_P (mode
) || VECTOR_UNIT_VSX_P (mode
))
14735 && (class1
== VSX_REGS
|| class1
== ALTIVEC_REGS
14736 || class1
== FLOAT_REGS
))
14737 return (class2
!= VSX_REGS
&& class2
!= ALTIVEC_REGS
14738 && class2
!= FLOAT_REGS
);
14740 if (class1
== VSX_REGS
|| class2
== VSX_REGS
)
14743 if (class1
== FLOAT_REGS
14744 && (!TARGET_MFPGPR
|| !TARGET_POWERPC64
14745 || ((mode
!= DFmode
)
14746 && (mode
!= DDmode
)
14747 && (mode
!= DImode
))))
14750 if (class2
== FLOAT_REGS
14751 && (!TARGET_MFPGPR
|| !TARGET_POWERPC64
14752 || ((mode
!= DFmode
)
14753 && (mode
!= DDmode
)
14754 && (mode
!= DImode
))))
14757 if (class1
== ALTIVEC_REGS
|| class2
== ALTIVEC_REGS
)
14763 /* Debug version of rs6000_secondary_memory_needed. */
14765 rs6000_debug_secondary_memory_needed (enum reg_class class1
,
14766 enum reg_class class2
,
14767 enum machine_mode mode
)
14769 bool ret
= rs6000_secondary_memory_needed (class1
, class2
, mode
);
14772 "rs6000_secondary_memory_needed, return: %s, class1 = %s, "
14773 "class2 = %s, mode = %s\n",
14774 ret
? "true" : "false", reg_class_names
[class1
],
14775 reg_class_names
[class2
], GET_MODE_NAME (mode
));
14780 /* Return the register class of a scratch register needed to copy IN into
14781 or out of a register in RCLASS in MODE. If it can be done directly,
14782 NO_REGS is returned. */
14784 static enum reg_class
14785 rs6000_secondary_reload_class (enum reg_class rclass
, enum machine_mode mode
,
14790 if (TARGET_ELF
|| (DEFAULT_ABI
== ABI_DARWIN
14792 && MACHOPIC_INDIRECT
14796 /* We cannot copy a symbolic operand directly into anything
14797 other than BASE_REGS for TARGET_ELF. So indicate that a
14798 register from BASE_REGS is needed as an intermediate
14801 On Darwin, pic addresses require a load from memory, which
14802 needs a base register. */
14803 if (rclass
!= BASE_REGS
14804 && (GET_CODE (in
) == SYMBOL_REF
14805 || GET_CODE (in
) == HIGH
14806 || GET_CODE (in
) == LABEL_REF
14807 || GET_CODE (in
) == CONST
))
14811 if (GET_CODE (in
) == REG
)
14813 regno
= REGNO (in
);
14814 if (regno
>= FIRST_PSEUDO_REGISTER
)
14816 regno
= true_regnum (in
);
14817 if (regno
>= FIRST_PSEUDO_REGISTER
)
14821 else if (GET_CODE (in
) == SUBREG
)
14823 regno
= true_regnum (in
);
14824 if (regno
>= FIRST_PSEUDO_REGISTER
)
14830 /* We can place anything into GENERAL_REGS and can put GENERAL_REGS
14832 if (rclass
== GENERAL_REGS
|| rclass
== BASE_REGS
14833 || (regno
>= 0 && INT_REGNO_P (regno
)))
14836 /* Constants, memory, and FP registers can go into FP registers. */
14837 if ((regno
== -1 || FP_REGNO_P (regno
))
14838 && (rclass
== FLOAT_REGS
|| rclass
== NON_SPECIAL_REGS
))
14839 return (mode
!= SDmode
) ? NO_REGS
: GENERAL_REGS
;
14841 /* Memory, and FP/altivec registers can go into fp/altivec registers under
14844 && (regno
== -1 || VSX_REGNO_P (regno
))
14845 && VSX_REG_CLASS_P (rclass
))
14848 /* Memory, and AltiVec registers can go into AltiVec registers. */
14849 if ((regno
== -1 || ALTIVEC_REGNO_P (regno
))
14850 && rclass
== ALTIVEC_REGS
)
14853 /* We can copy among the CR registers. */
14854 if ((rclass
== CR_REGS
|| rclass
== CR0_REGS
)
14855 && regno
>= 0 && CR_REGNO_P (regno
))
14858 /* Otherwise, we need GENERAL_REGS. */
14859 return GENERAL_REGS
;
14862 /* Debug version of rs6000_secondary_reload_class. */
14863 static enum reg_class
14864 rs6000_debug_secondary_reload_class (enum reg_class rclass
,
14865 enum machine_mode mode
, rtx in
)
14867 enum reg_class ret
= rs6000_secondary_reload_class (rclass
, mode
, in
);
14869 "\nrs6000_secondary_reload_class, return %s, rclass = %s, "
14870 "mode = %s, input rtx:\n",
14871 reg_class_names
[ret
], reg_class_names
[rclass
],
14872 GET_MODE_NAME (mode
));
14878 /* Return nonzero if for CLASS a mode change from FROM to TO is invalid. */
14881 rs6000_cannot_change_mode_class (enum machine_mode from
,
14882 enum machine_mode to
,
14883 enum reg_class rclass
)
14885 unsigned from_size
= GET_MODE_SIZE (from
);
14886 unsigned to_size
= GET_MODE_SIZE (to
);
14888 if (from_size
!= to_size
)
14890 enum reg_class xclass
= (TARGET_VSX
) ? VSX_REGS
: FLOAT_REGS
;
14891 return ((from_size
< 8 || to_size
< 8 || TARGET_IEEEQUAD
)
14892 && reg_classes_intersect_p (xclass
, rclass
));
14895 if (TARGET_E500_DOUBLE
14896 && ((((to
) == DFmode
) + ((from
) == DFmode
)) == 1
14897 || (((to
) == TFmode
) + ((from
) == TFmode
)) == 1
14898 || (((to
) == DDmode
) + ((from
) == DDmode
)) == 1
14899 || (((to
) == TDmode
) + ((from
) == TDmode
)) == 1
14900 || (((to
) == DImode
) + ((from
) == DImode
)) == 1))
14903 /* Since the VSX register set includes traditional floating point registers
14904 and altivec registers, just check for the size being different instead of
14905 trying to check whether the modes are vector modes. Otherwise it won't
14906 allow say DF and DI to change classes. */
14907 if (TARGET_VSX
&& VSX_REG_CLASS_P (rclass
))
14908 return (from_size
!= 8 && from_size
!= 16);
14910 if (TARGET_ALTIVEC
&& rclass
== ALTIVEC_REGS
14911 && (ALTIVEC_VECTOR_MODE (from
) + ALTIVEC_VECTOR_MODE (to
)) == 1)
14914 if (TARGET_SPE
&& (SPE_VECTOR_MODE (from
) + SPE_VECTOR_MODE (to
)) == 1
14915 && reg_classes_intersect_p (GENERAL_REGS
, rclass
))
14921 /* Debug version of rs6000_cannot_change_mode_class. */
14923 rs6000_debug_cannot_change_mode_class (enum machine_mode from
,
14924 enum machine_mode to
,
14925 enum reg_class rclass
)
14927 bool ret
= rs6000_cannot_change_mode_class (from
, to
, rclass
);
14930 "rs6000_cannot_change_mode_class, return %s, from = %s, "
14931 "to = %s, rclass = %s\n",
14932 ret
? "true" : "false",
14933 GET_MODE_NAME (from
), GET_MODE_NAME (to
),
14934 reg_class_names
[rclass
]);
14939 /* Given a comparison operation, return the bit number in CCR to test. We
14940 know this is a valid comparison.
14942 SCC_P is 1 if this is for an scc. That means that %D will have been
14943 used instead of %C, so the bits will be in different places.
14945 Return -1 if OP isn't a valid comparison for some reason. */
14948 ccr_bit (rtx op
, int scc_p
)
14950 enum rtx_code code
= GET_CODE (op
);
14951 enum machine_mode cc_mode
;
14956 if (!COMPARISON_P (op
))
14959 reg
= XEXP (op
, 0);
14961 gcc_assert (GET_CODE (reg
) == REG
&& CR_REGNO_P (REGNO (reg
)));
14963 cc_mode
= GET_MODE (reg
);
14964 cc_regnum
= REGNO (reg
);
14965 base_bit
= 4 * (cc_regnum
- CR0_REGNO
);
14967 validate_condition_mode (code
, cc_mode
);
14969 /* When generating a sCOND operation, only positive conditions are
14972 || code
== EQ
|| code
== GT
|| code
== LT
|| code
== UNORDERED
14973 || code
== GTU
|| code
== LTU
);
14978 return scc_p
? base_bit
+ 3 : base_bit
+ 2;
14980 return base_bit
+ 2;
14981 case GT
: case GTU
: case UNLE
:
14982 return base_bit
+ 1;
14983 case LT
: case LTU
: case UNGE
:
14985 case ORDERED
: case UNORDERED
:
14986 return base_bit
+ 3;
14989 /* If scc, we will have done a cror to put the bit in the
14990 unordered position. So test that bit. For integer, this is ! LT
14991 unless this is an scc insn. */
14992 return scc_p
? base_bit
+ 3 : base_bit
;
14995 return scc_p
? base_bit
+ 3 : base_bit
+ 1;
14998 gcc_unreachable ();
15002 /* Return the GOT register. */
15005 rs6000_got_register (rtx value ATTRIBUTE_UNUSED
)
15007 /* The second flow pass currently (June 1999) can't update
15008 regs_ever_live without disturbing other parts of the compiler, so
15009 update it here to make the prolog/epilogue code happy. */
15010 if (!can_create_pseudo_p ()
15011 && !df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM
))
15012 df_set_regs_ever_live (RS6000_PIC_OFFSET_TABLE_REGNUM
, true);
15014 crtl
->uses_pic_offset_table
= 1;
15016 return pic_offset_table_rtx
;
15019 /* Function to init struct machine_function.
15020 This will be called, via a pointer variable,
15021 from push_function_context. */
15023 static struct machine_function
*
15024 rs6000_init_machine_status (void)
15026 return ggc_alloc_cleared_machine_function ();
15029 /* These macros test for integers and extract the low-order bits. */
15031 ((GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST_DOUBLE) \
15032 && GET_MODE (X) == VOIDmode)
15034 #define INT_LOWPART(X) \
15035 (GET_CODE (X) == CONST_INT ? INTVAL (X) : CONST_DOUBLE_LOW (X))
15038 extract_MB (rtx op
)
15041 unsigned long val
= INT_LOWPART (op
);
15043 /* If the high bit is zero, the value is the first 1 bit we find
15045 if ((val
& 0x80000000) == 0)
15047 gcc_assert (val
& 0xffffffff);
15050 while (((val
<<= 1) & 0x80000000) == 0)
15055 /* If the high bit is set and the low bit is not, or the mask is all
15056 1's, the value is zero. */
15057 if ((val
& 1) == 0 || (val
& 0xffffffff) == 0xffffffff)
15060 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
15063 while (((val
>>= 1) & 1) != 0)
15070 extract_ME (rtx op
)
15073 unsigned long val
= INT_LOWPART (op
);
15075 /* If the low bit is zero, the value is the first 1 bit we find from
15077 if ((val
& 1) == 0)
15079 gcc_assert (val
& 0xffffffff);
15082 while (((val
>>= 1) & 1) == 0)
15088 /* If the low bit is set and the high bit is not, or the mask is all
15089 1's, the value is 31. */
15090 if ((val
& 0x80000000) == 0 || (val
& 0xffffffff) == 0xffffffff)
15093 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
15096 while (((val
<<= 1) & 0x80000000) != 0)
15102 /* Locate some local-dynamic symbol still in use by this function
15103 so that we can print its name in some tls_ld pattern. */
15105 static const char *
15106 rs6000_get_some_local_dynamic_name (void)
15110 if (cfun
->machine
->some_ld_name
)
15111 return cfun
->machine
->some_ld_name
;
15113 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
15115 && for_each_rtx (&PATTERN (insn
),
15116 rs6000_get_some_local_dynamic_name_1
, 0))
15117 return cfun
->machine
->some_ld_name
;
15119 gcc_unreachable ();
15122 /* Helper function for rs6000_get_some_local_dynamic_name. */
15125 rs6000_get_some_local_dynamic_name_1 (rtx
*px
, void *data ATTRIBUTE_UNUSED
)
15129 if (GET_CODE (x
) == SYMBOL_REF
)
15131 const char *str
= XSTR (x
, 0);
15132 if (SYMBOL_REF_TLS_MODEL (x
) == TLS_MODEL_LOCAL_DYNAMIC
)
15134 cfun
->machine
->some_ld_name
= str
;
15142 /* Write out a function code label. */
15145 rs6000_output_function_entry (FILE *file
, const char *fname
)
15147 if (fname
[0] != '.')
15149 switch (DEFAULT_ABI
)
15152 gcc_unreachable ();
15158 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file
, "L.");
15167 RS6000_OUTPUT_BASENAME (file
, fname
);
15170 /* Print an operand. Recognize special options, documented below. */
15173 #define SMALL_DATA_RELOC ((rs6000_sdata == SDATA_EABI) ? "sda21" : "sdarel")
15174 #define SMALL_DATA_REG ((rs6000_sdata == SDATA_EABI) ? 0 : 13)
15176 #define SMALL_DATA_RELOC "sda21"
15177 #define SMALL_DATA_REG 0
15181 print_operand (FILE *file
, rtx x
, int code
)
15185 unsigned HOST_WIDE_INT uval
;
15190 /* Write out an instruction after the call which may be replaced
15191 with glue code by the loader. This depends on the AIX version. */
15192 asm_fprintf (file
, RS6000_CALL_GLUE
);
15195 /* %a is output_address. */
15198 /* If X is a constant integer whose low-order 5 bits are zero,
15199 write 'l'. Otherwise, write 'r'. This is a kludge to fix a bug
15200 in the AIX assembler where "sri" with a zero shift count
15201 writes a trash instruction. */
15202 if (GET_CODE (x
) == CONST_INT
&& (INTVAL (x
) & 31) == 0)
15209 /* If constant, low-order 16 bits of constant, unsigned.
15210 Otherwise, write normally. */
15212 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INT_LOWPART (x
) & 0xffff);
15214 print_operand (file
, x
, 0);
15218 /* If the low-order bit is zero, write 'r'; otherwise, write 'l'
15219 for 64-bit mask direction. */
15220 putc (((INT_LOWPART (x
) & 1) == 0 ? 'r' : 'l'), file
);
15223 /* %c is output_addr_const if a CONSTANT_ADDRESS_P, otherwise
15227 /* X is a CR register. Print the number of the GT bit of the CR. */
15228 if (GET_CODE (x
) != REG
|| ! CR_REGNO_P (REGNO (x
)))
15229 output_operand_lossage ("invalid %%c value");
15231 fprintf (file
, "%d", 4 * (REGNO (x
) - CR0_REGNO
) + 1);
15235 /* Like 'J' but get to the GT bit only. */
15236 gcc_assert (GET_CODE (x
) == REG
);
15238 /* Bit 1 is GT bit. */
15239 i
= 4 * (REGNO (x
) - CR0_REGNO
) + 1;
15241 /* Add one for shift count in rlinm for scc. */
15242 fprintf (file
, "%d", i
+ 1);
15246 /* X is a CR register. Print the number of the EQ bit of the CR */
15247 if (GET_CODE (x
) != REG
|| ! CR_REGNO_P (REGNO (x
)))
15248 output_operand_lossage ("invalid %%E value");
15250 fprintf (file
, "%d", 4 * (REGNO (x
) - CR0_REGNO
) + 2);
15254 /* X is a CR register. Print the shift count needed to move it
15255 to the high-order four bits. */
15256 if (GET_CODE (x
) != REG
|| ! CR_REGNO_P (REGNO (x
)))
15257 output_operand_lossage ("invalid %%f value");
15259 fprintf (file
, "%d", 4 * (REGNO (x
) - CR0_REGNO
));
15263 /* Similar, but print the count for the rotate in the opposite
15265 if (GET_CODE (x
) != REG
|| ! CR_REGNO_P (REGNO (x
)))
15266 output_operand_lossage ("invalid %%F value");
15268 fprintf (file
, "%d", 32 - 4 * (REGNO (x
) - CR0_REGNO
));
15272 /* X is a constant integer. If it is negative, print "m",
15273 otherwise print "z". This is to make an aze or ame insn. */
15274 if (GET_CODE (x
) != CONST_INT
)
15275 output_operand_lossage ("invalid %%G value");
15276 else if (INTVAL (x
) >= 0)
15283 /* If constant, output low-order five bits. Otherwise, write
15286 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INT_LOWPART (x
) & 31);
15288 print_operand (file
, x
, 0);
15292 /* If constant, output low-order six bits. Otherwise, write
15295 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INT_LOWPART (x
) & 63);
15297 print_operand (file
, x
, 0);
15301 /* Print `i' if this is a constant, else nothing. */
15307 /* Write the bit number in CCR for jump. */
15308 i
= ccr_bit (x
, 0);
15310 output_operand_lossage ("invalid %%j code");
15312 fprintf (file
, "%d", i
);
15316 /* Similar, but add one for shift count in rlinm for scc and pass
15317 scc flag to `ccr_bit'. */
15318 i
= ccr_bit (x
, 1);
15320 output_operand_lossage ("invalid %%J code");
15322 /* If we want bit 31, write a shift count of zero, not 32. */
15323 fprintf (file
, "%d", i
== 31 ? 0 : i
+ 1);
15327 /* X must be a constant. Write the 1's complement of the
15330 output_operand_lossage ("invalid %%k value");
15332 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, ~ INT_LOWPART (x
));
15336 /* X must be a symbolic constant on ELF. Write an
15337 expression suitable for an 'addi' that adds in the low 16
15338 bits of the MEM. */
15339 if (GET_CODE (x
) == CONST
)
15341 if (GET_CODE (XEXP (x
, 0)) != PLUS
15342 || (GET_CODE (XEXP (XEXP (x
, 0), 0)) != SYMBOL_REF
15343 && GET_CODE (XEXP (XEXP (x
, 0), 0)) != LABEL_REF
)
15344 || GET_CODE (XEXP (XEXP (x
, 0), 1)) != CONST_INT
)
15345 output_operand_lossage ("invalid %%K value");
15347 print_operand_address (file
, x
);
15348 fputs ("@l", file
);
15351 /* %l is output_asm_label. */
15354 /* Write second word of DImode or DFmode reference. Works on register
15355 or non-indexed memory only. */
15356 if (GET_CODE (x
) == REG
)
15357 fputs (reg_names
[REGNO (x
) + 1], file
);
15358 else if (GET_CODE (x
) == MEM
)
15360 /* Handle possible auto-increment. Since it is pre-increment and
15361 we have already done it, we can just use an offset of word. */
15362 if (GET_CODE (XEXP (x
, 0)) == PRE_INC
15363 || GET_CODE (XEXP (x
, 0)) == PRE_DEC
)
15364 output_address (plus_constant (XEXP (XEXP (x
, 0), 0),
15366 else if (GET_CODE (XEXP (x
, 0)) == PRE_MODIFY
)
15367 output_address (plus_constant (XEXP (XEXP (x
, 0), 0),
15370 output_address (XEXP (adjust_address_nv (x
, SImode
,
15374 if (small_data_operand (x
, GET_MODE (x
)))
15375 fprintf (file
, "@%s(%s)", SMALL_DATA_RELOC
,
15376 reg_names
[SMALL_DATA_REG
]);
15381 /* MB value for a mask operand. */
15382 if (! mask_operand (x
, SImode
))
15383 output_operand_lossage ("invalid %%m value");
15385 fprintf (file
, "%d", extract_MB (x
));
15389 /* ME value for a mask operand. */
15390 if (! mask_operand (x
, SImode
))
15391 output_operand_lossage ("invalid %%M value");
15393 fprintf (file
, "%d", extract_ME (x
));
15396 /* %n outputs the negative of its operand. */
15399 /* Write the number of elements in the vector times 4. */
15400 if (GET_CODE (x
) != PARALLEL
)
15401 output_operand_lossage ("invalid %%N value");
15403 fprintf (file
, "%d", XVECLEN (x
, 0) * 4);
15407 /* Similar, but subtract 1 first. */
15408 if (GET_CODE (x
) != PARALLEL
)
15409 output_operand_lossage ("invalid %%O value");
15411 fprintf (file
, "%d", (XVECLEN (x
, 0) - 1) * 4);
15415 /* X is a CONST_INT that is a power of two. Output the logarithm. */
15417 || INT_LOWPART (x
) < 0
15418 || (i
= exact_log2 (INT_LOWPART (x
))) < 0)
15419 output_operand_lossage ("invalid %%p value");
15421 fprintf (file
, "%d", i
);
15425 /* The operand must be an indirect memory reference. The result
15426 is the register name. */
15427 if (GET_CODE (x
) != MEM
|| GET_CODE (XEXP (x
, 0)) != REG
15428 || REGNO (XEXP (x
, 0)) >= 32)
15429 output_operand_lossage ("invalid %%P value");
15431 fputs (reg_names
[REGNO (XEXP (x
, 0))], file
);
15435 /* This outputs the logical code corresponding to a boolean
15436 expression. The expression may have one or both operands
15437 negated (if one, only the first one). For condition register
15438 logical operations, it will also treat the negated
15439 CR codes as NOTs, but not handle NOTs of them. */
15441 const char *const *t
= 0;
15443 enum rtx_code code
= GET_CODE (x
);
15444 static const char * const tbl
[3][3] = {
15445 { "and", "andc", "nor" },
15446 { "or", "orc", "nand" },
15447 { "xor", "eqv", "xor" } };
15451 else if (code
== IOR
)
15453 else if (code
== XOR
)
15456 output_operand_lossage ("invalid %%q value");
15458 if (GET_CODE (XEXP (x
, 0)) != NOT
)
15462 if (GET_CODE (XEXP (x
, 1)) == NOT
)
15480 /* X is a CR register. Print the mask for `mtcrf'. */
15481 if (GET_CODE (x
) != REG
|| ! CR_REGNO_P (REGNO (x
)))
15482 output_operand_lossage ("invalid %%R value");
15484 fprintf (file
, "%d", 128 >> (REGNO (x
) - CR0_REGNO
));
15488 /* Low 5 bits of 32 - value */
15490 output_operand_lossage ("invalid %%s value");
15492 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, (32 - INT_LOWPART (x
)) & 31);
15496 /* PowerPC64 mask position. All 0's is excluded.
15497 CONST_INT 32-bit mask is considered sign-extended so any
15498 transition must occur within the CONST_INT, not on the boundary. */
15499 if (! mask64_operand (x
, DImode
))
15500 output_operand_lossage ("invalid %%S value");
15502 uval
= INT_LOWPART (x
);
15504 if (uval
& 1) /* Clear Left */
15506 #if HOST_BITS_PER_WIDE_INT > 64
15507 uval
&= ((unsigned HOST_WIDE_INT
) 1 << 64) - 1;
15511 else /* Clear Right */
15514 #if HOST_BITS_PER_WIDE_INT > 64
15515 uval
&= ((unsigned HOST_WIDE_INT
) 1 << 64) - 1;
15521 gcc_assert (i
>= 0);
15522 fprintf (file
, "%d", i
);
15526 /* Like 'J' but get to the OVERFLOW/UNORDERED bit. */
15527 gcc_assert (GET_CODE (x
) == REG
&& GET_MODE (x
) == CCmode
);
15529 /* Bit 3 is OV bit. */
15530 i
= 4 * (REGNO (x
) - CR0_REGNO
) + 3;
15532 /* If we want bit 31, write a shift count of zero, not 32. */
15533 fprintf (file
, "%d", i
== 31 ? 0 : i
+ 1);
15537 /* Print the symbolic name of a branch target register. */
15538 if (GET_CODE (x
) != REG
|| (REGNO (x
) != LR_REGNO
15539 && REGNO (x
) != CTR_REGNO
))
15540 output_operand_lossage ("invalid %%T value");
15541 else if (REGNO (x
) == LR_REGNO
)
15542 fputs (TARGET_NEW_MNEMONICS
? "lr" : "r", file
);
15544 fputs ("ctr", file
);
15548 /* High-order 16 bits of constant for use in unsigned operand. */
15550 output_operand_lossage ("invalid %%u value");
15552 fprintf (file
, HOST_WIDE_INT_PRINT_HEX
,
15553 (INT_LOWPART (x
) >> 16) & 0xffff);
15557 /* High-order 16 bits of constant for use in signed operand. */
15559 output_operand_lossage ("invalid %%v value");
15561 fprintf (file
, HOST_WIDE_INT_PRINT_HEX
,
15562 (INT_LOWPART (x
) >> 16) & 0xffff);
15566 /* Print `u' if this has an auto-increment or auto-decrement. */
15567 if (GET_CODE (x
) == MEM
15568 && (GET_CODE (XEXP (x
, 0)) == PRE_INC
15569 || GET_CODE (XEXP (x
, 0)) == PRE_DEC
15570 || GET_CODE (XEXP (x
, 0)) == PRE_MODIFY
))
15575 /* Print the trap code for this operand. */
15576 switch (GET_CODE (x
))
15579 fputs ("eq", file
); /* 4 */
15582 fputs ("ne", file
); /* 24 */
15585 fputs ("lt", file
); /* 16 */
15588 fputs ("le", file
); /* 20 */
15591 fputs ("gt", file
); /* 8 */
15594 fputs ("ge", file
); /* 12 */
15597 fputs ("llt", file
); /* 2 */
15600 fputs ("lle", file
); /* 6 */
15603 fputs ("lgt", file
); /* 1 */
15606 fputs ("lge", file
); /* 5 */
15609 gcc_unreachable ();
15614 /* If constant, low-order 16 bits of constant, signed. Otherwise, write
15617 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
,
15618 ((INT_LOWPART (x
) & 0xffff) ^ 0x8000) - 0x8000);
15620 print_operand (file
, x
, 0);
15624 /* MB value for a PowerPC64 rldic operand. */
15625 val
= (GET_CODE (x
) == CONST_INT
15626 ? INTVAL (x
) : CONST_DOUBLE_HIGH (x
));
15631 for (i
= 0; i
< HOST_BITS_PER_WIDE_INT
; i
++)
15632 if ((val
<<= 1) < 0)
15635 #if HOST_BITS_PER_WIDE_INT == 32
15636 if (GET_CODE (x
) == CONST_INT
&& i
>= 0)
15637 i
+= 32; /* zero-extend high-part was all 0's */
15638 else if (GET_CODE (x
) == CONST_DOUBLE
&& i
== 32)
15640 val
= CONST_DOUBLE_LOW (x
);
15646 for ( ; i
< 64; i
++)
15647 if ((val
<<= 1) < 0)
15652 fprintf (file
, "%d", i
+ 1);
15656 /* X is a FPR or Altivec register used in a VSX context. */
15657 if (GET_CODE (x
) != REG
|| !VSX_REGNO_P (REGNO (x
)))
15658 output_operand_lossage ("invalid %%x value");
15661 int reg
= REGNO (x
);
15662 int vsx_reg
= (FP_REGNO_P (reg
)
15664 : reg
- FIRST_ALTIVEC_REGNO
+ 32);
15666 #ifdef TARGET_REGNAMES
15667 if (TARGET_REGNAMES
)
15668 fprintf (file
, "%%vs%d", vsx_reg
);
15671 fprintf (file
, "%d", vsx_reg
);
15676 if (GET_CODE (x
) == MEM
15677 && (legitimate_indexed_address_p (XEXP (x
, 0), 0)
15678 || (GET_CODE (XEXP (x
, 0)) == PRE_MODIFY
15679 && legitimate_indexed_address_p (XEXP (XEXP (x
, 0), 1), 0))))
15684 /* Like 'L', for third word of TImode */
15685 if (GET_CODE (x
) == REG
)
15686 fputs (reg_names
[REGNO (x
) + 2], file
);
15687 else if (GET_CODE (x
) == MEM
)
15689 if (GET_CODE (XEXP (x
, 0)) == PRE_INC
15690 || GET_CODE (XEXP (x
, 0)) == PRE_DEC
)
15691 output_address (plus_constant (XEXP (XEXP (x
, 0), 0), 8));
15692 else if (GET_CODE (XEXP (x
, 0)) == PRE_MODIFY
)
15693 output_address (plus_constant (XEXP (XEXP (x
, 0), 0), 8));
15695 output_address (XEXP (adjust_address_nv (x
, SImode
, 8), 0));
15696 if (small_data_operand (x
, GET_MODE (x
)))
15697 fprintf (file
, "@%s(%s)", SMALL_DATA_RELOC
,
15698 reg_names
[SMALL_DATA_REG
]);
15703 /* X is a SYMBOL_REF. Write out the name preceded by a
15704 period and without any trailing data in brackets. Used for function
15705 names. If we are configured for System V (or the embedded ABI) on
15706 the PowerPC, do not emit the period, since those systems do not use
15707 TOCs and the like. */
15708 gcc_assert (GET_CODE (x
) == SYMBOL_REF
);
15710 /* Mark the decl as referenced so that cgraph will output the
15712 if (SYMBOL_REF_DECL (x
))
15713 mark_decl_referenced (SYMBOL_REF_DECL (x
));
15715 /* For macho, check to see if we need a stub. */
15718 const char *name
= XSTR (x
, 0);
15720 if (darwin_emit_branch_islands
15721 && MACHOPIC_INDIRECT
15722 && machopic_classify_symbol (x
) == MACHOPIC_UNDEFINED_FUNCTION
)
15723 name
= machopic_indirection_name (x
, /*stub_p=*/true);
15725 assemble_name (file
, name
);
15727 else if (!DOT_SYMBOLS
)
15728 assemble_name (file
, XSTR (x
, 0));
15730 rs6000_output_function_entry (file
, XSTR (x
, 0));
15734 /* Like 'L', for last word of TImode. */
15735 if (GET_CODE (x
) == REG
)
15736 fputs (reg_names
[REGNO (x
) + 3], file
);
15737 else if (GET_CODE (x
) == MEM
)
15739 if (GET_CODE (XEXP (x
, 0)) == PRE_INC
15740 || GET_CODE (XEXP (x
, 0)) == PRE_DEC
)
15741 output_address (plus_constant (XEXP (XEXP (x
, 0), 0), 12));
15742 else if (GET_CODE (XEXP (x
, 0)) == PRE_MODIFY
)
15743 output_address (plus_constant (XEXP (XEXP (x
, 0), 0), 12));
15745 output_address (XEXP (adjust_address_nv (x
, SImode
, 12), 0));
15746 if (small_data_operand (x
, GET_MODE (x
)))
15747 fprintf (file
, "@%s(%s)", SMALL_DATA_RELOC
,
15748 reg_names
[SMALL_DATA_REG
]);
15752 /* Print AltiVec or SPE memory operand. */
15757 gcc_assert (GET_CODE (x
) == MEM
);
15761 /* Ugly hack because %y is overloaded. */
15762 if ((TARGET_SPE
|| TARGET_E500_DOUBLE
)
15763 && (GET_MODE_SIZE (GET_MODE (x
)) == 8
15764 || GET_MODE (x
) == TFmode
15765 || GET_MODE (x
) == TImode
))
15767 /* Handle [reg]. */
15768 if (GET_CODE (tmp
) == REG
)
15770 fprintf (file
, "0(%s)", reg_names
[REGNO (tmp
)]);
15773 /* Handle [reg+UIMM]. */
15774 else if (GET_CODE (tmp
) == PLUS
&&
15775 GET_CODE (XEXP (tmp
, 1)) == CONST_INT
)
15779 gcc_assert (GET_CODE (XEXP (tmp
, 0)) == REG
);
15781 x
= INTVAL (XEXP (tmp
, 1));
15782 fprintf (file
, "%d(%s)", x
, reg_names
[REGNO (XEXP (tmp
, 0))]);
15786 /* Fall through. Must be [reg+reg]. */
15788 if (VECTOR_MEM_ALTIVEC_P (GET_MODE (x
))
15789 && GET_CODE (tmp
) == AND
15790 && GET_CODE (XEXP (tmp
, 1)) == CONST_INT
15791 && INTVAL (XEXP (tmp
, 1)) == -16)
15792 tmp
= XEXP (tmp
, 0);
15793 else if (VECTOR_MEM_VSX_P (GET_MODE (x
))
15794 && GET_CODE (tmp
) == PRE_MODIFY
)
15795 tmp
= XEXP (tmp
, 1);
15796 if (GET_CODE (tmp
) == REG
)
15797 fprintf (file
, "0,%s", reg_names
[REGNO (tmp
)]);
15800 if (!GET_CODE (tmp
) == PLUS
15801 || !REG_P (XEXP (tmp
, 0))
15802 || !REG_P (XEXP (tmp
, 1)))
15804 output_operand_lossage ("invalid %%y value, try using the 'Z' constraint");
15808 if (REGNO (XEXP (tmp
, 0)) == 0)
15809 fprintf (file
, "%s,%s", reg_names
[ REGNO (XEXP (tmp
, 1)) ],
15810 reg_names
[ REGNO (XEXP (tmp
, 0)) ]);
15812 fprintf (file
, "%s,%s", reg_names
[ REGNO (XEXP (tmp
, 0)) ],
15813 reg_names
[ REGNO (XEXP (tmp
, 1)) ]);
15819 if (GET_CODE (x
) == REG
)
15820 fprintf (file
, "%s", reg_names
[REGNO (x
)]);
15821 else if (GET_CODE (x
) == MEM
)
15823 /* We need to handle PRE_INC and PRE_DEC here, since we need to
15824 know the width from the mode. */
15825 if (GET_CODE (XEXP (x
, 0)) == PRE_INC
)
15826 fprintf (file
, "%d(%s)", GET_MODE_SIZE (GET_MODE (x
)),
15827 reg_names
[REGNO (XEXP (XEXP (x
, 0), 0))]);
15828 else if (GET_CODE (XEXP (x
, 0)) == PRE_DEC
)
15829 fprintf (file
, "%d(%s)", - GET_MODE_SIZE (GET_MODE (x
)),
15830 reg_names
[REGNO (XEXP (XEXP (x
, 0), 0))]);
15831 else if (GET_CODE (XEXP (x
, 0)) == PRE_MODIFY
)
15832 output_address (XEXP (XEXP (x
, 0), 1));
15834 output_address (XEXP (x
, 0));
15837 output_addr_const (file
, x
);
15841 assemble_name (file
, rs6000_get_some_local_dynamic_name ());
15845 output_operand_lossage ("invalid %%xn code");
15849 /* Print the address of an operand. */
15852 print_operand_address (FILE *file
, rtx x
)
15854 if (GET_CODE (x
) == REG
)
15855 fprintf (file
, "0(%s)", reg_names
[ REGNO (x
) ]);
15856 else if (GET_CODE (x
) == SYMBOL_REF
|| GET_CODE (x
) == CONST
15857 || GET_CODE (x
) == LABEL_REF
)
15859 output_addr_const (file
, x
);
15860 if (small_data_operand (x
, GET_MODE (x
)))
15861 fprintf (file
, "@%s(%s)", SMALL_DATA_RELOC
,
15862 reg_names
[SMALL_DATA_REG
]);
15864 gcc_assert (!TARGET_TOC
);
15866 else if (GET_CODE (x
) == PLUS
&& GET_CODE (XEXP (x
, 1)) == REG
)
15868 gcc_assert (REG_P (XEXP (x
, 0)));
15869 if (REGNO (XEXP (x
, 0)) == 0)
15870 fprintf (file
, "%s,%s", reg_names
[ REGNO (XEXP (x
, 1)) ],
15871 reg_names
[ REGNO (XEXP (x
, 0)) ]);
15873 fprintf (file
, "%s,%s", reg_names
[ REGNO (XEXP (x
, 0)) ],
15874 reg_names
[ REGNO (XEXP (x
, 1)) ]);
15876 else if (GET_CODE (x
) == PLUS
&& GET_CODE (XEXP (x
, 1)) == CONST_INT
)
15877 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
"(%s)",
15878 INTVAL (XEXP (x
, 1)), reg_names
[ REGNO (XEXP (x
, 0)) ]);
15880 else if (GET_CODE (x
) == LO_SUM
&& GET_CODE (XEXP (x
, 0)) == REG
15881 && CONSTANT_P (XEXP (x
, 1)))
15883 fprintf (file
, "lo16(");
15884 output_addr_const (file
, XEXP (x
, 1));
15885 fprintf (file
, ")(%s)", reg_names
[ REGNO (XEXP (x
, 0)) ]);
15888 else if (legitimate_constant_pool_address_p (x
, true))
15890 /* This hack along with a corresponding hack in
15891 rs6000_output_addr_const_extra arranges to output addends
15892 where the assembler expects to find them. eg.
15894 . (const (plus (unspec [symbol_ref ("x") tocrel]) 8)))
15895 without this hack would be output as "x@toc+8@l(9)". We
15896 want "x+8@toc@l(9)". */
15897 output_addr_const (file
, tocrel_base
);
15898 if (GET_CODE (x
) == LO_SUM
)
15899 fprintf (file
, "@l(%s)", reg_names
[ REGNO (XEXP (x
, 0)) ]);
15901 fprintf (file
, "(%s)", reg_names
[REGNO (XEXP (x
, 0))]);
15904 else if (GET_CODE (x
) == LO_SUM
&& GET_CODE (XEXP (x
, 0)) == REG
15905 && CONSTANT_P (XEXP (x
, 1)))
15907 output_addr_const (file
, XEXP (x
, 1));
15908 fprintf (file
, "@l(%s)", reg_names
[ REGNO (XEXP (x
, 0)) ]);
15912 gcc_unreachable ();
15915 /* Implement OUTPUT_ADDR_CONST_EXTRA for address X. */
15918 rs6000_output_addr_const_extra (FILE *file
, rtx x
)
15920 if (GET_CODE (x
) == UNSPEC
)
15921 switch (XINT (x
, 1))
15923 case UNSPEC_TOCREL
:
15924 gcc_assert (GET_CODE (XVECEXP (x
, 0, 0)) == SYMBOL_REF
);
15925 output_addr_const (file
, XVECEXP (x
, 0, 0));
15926 if (x
== tocrel_base
&& tocrel_offset
!= const0_rtx
)
15928 if (INTVAL (tocrel_offset
) >= 0)
15929 fprintf (file
, "+");
15930 output_addr_const (file
, tocrel_offset
);
15932 if (!TARGET_AIX
|| (TARGET_ELF
&& TARGET_MINIMAL_TOC
))
15935 assemble_name (file
, toc_label_name
);
15937 else if (TARGET_ELF
)
15938 fputs ("@toc", file
);
15942 case UNSPEC_MACHOPIC_OFFSET
:
15943 output_addr_const (file
, XVECEXP (x
, 0, 0));
15945 machopic_output_function_base_name (file
);
15952 /* Target hook for assembling integer objects. The PowerPC version has
15953 to handle fixup entries for relocatable code if RELOCATABLE_NEEDS_FIXUP
15954 is defined. It also needs to handle DI-mode objects on 64-bit
15958 rs6000_assemble_integer (rtx x
, unsigned int size
, int aligned_p
)
15960 #ifdef RELOCATABLE_NEEDS_FIXUP
15961 /* Special handling for SI values. */
15962 if (RELOCATABLE_NEEDS_FIXUP
&& size
== 4 && aligned_p
)
15964 static int recurse
= 0;
15966 /* For -mrelocatable, we mark all addresses that need to be fixed up
15967 in the .fixup section. */
15968 if (TARGET_RELOCATABLE
15969 && in_section
!= toc_section
15970 && in_section
!= text_section
15971 && !unlikely_text_section_p (in_section
)
15973 && GET_CODE (x
) != CONST_INT
15974 && GET_CODE (x
) != CONST_DOUBLE
15980 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCP", fixuplabelno
);
15982 ASM_OUTPUT_LABEL (asm_out_file
, buf
);
15983 fprintf (asm_out_file
, "\t.long\t(");
15984 output_addr_const (asm_out_file
, x
);
15985 fprintf (asm_out_file
, ")@fixup\n");
15986 fprintf (asm_out_file
, "\t.section\t\".fixup\",\"aw\"\n");
15987 ASM_OUTPUT_ALIGN (asm_out_file
, 2);
15988 fprintf (asm_out_file
, "\t.long\t");
15989 assemble_name (asm_out_file
, buf
);
15990 fprintf (asm_out_file
, "\n\t.previous\n");
15994 /* Remove initial .'s to turn a -mcall-aixdesc function
15995 address into the address of the descriptor, not the function
15997 else if (GET_CODE (x
) == SYMBOL_REF
15998 && XSTR (x
, 0)[0] == '.'
15999 && DEFAULT_ABI
== ABI_AIX
)
16001 const char *name
= XSTR (x
, 0);
16002 while (*name
== '.')
16005 fprintf (asm_out_file
, "\t.long\t%s\n", name
);
16009 #endif /* RELOCATABLE_NEEDS_FIXUP */
16010 return default_assemble_integer (x
, size
, aligned_p
);
16013 #ifdef HAVE_GAS_HIDDEN
16014 /* Emit an assembler directive to set symbol visibility for DECL to
16015 VISIBILITY_TYPE. */
16018 rs6000_assemble_visibility (tree decl
, int vis
)
16020 /* Functions need to have their entry point symbol visibility set as
16021 well as their descriptor symbol visibility. */
16022 if (DEFAULT_ABI
== ABI_AIX
16024 && TREE_CODE (decl
) == FUNCTION_DECL
)
16026 static const char * const visibility_types
[] = {
16027 NULL
, "internal", "hidden", "protected"
16030 const char *name
, *type
;
16032 name
= ((* targetm
.strip_name_encoding
)
16033 (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl
))));
16034 type
= visibility_types
[vis
];
16036 fprintf (asm_out_file
, "\t.%s\t%s\n", type
, name
);
16037 fprintf (asm_out_file
, "\t.%s\t.%s\n", type
, name
);
16040 default_assemble_visibility (decl
, vis
);
16045 rs6000_reverse_condition (enum machine_mode mode
, enum rtx_code code
)
16047 /* Reversal of FP compares takes care -- an ordered compare
16048 becomes an unordered compare and vice versa. */
16049 if (mode
== CCFPmode
16050 && (!flag_finite_math_only
16051 || code
== UNLT
|| code
== UNLE
|| code
== UNGT
|| code
== UNGE
16052 || code
== UNEQ
|| code
== LTGT
))
16053 return reverse_condition_maybe_unordered (code
);
16055 return reverse_condition (code
);
16058 /* Generate a compare for CODE. Return a brand-new rtx that
16059 represents the result of the compare. */
16062 rs6000_generate_compare (rtx cmp
, enum machine_mode mode
)
16064 enum machine_mode comp_mode
;
16065 rtx compare_result
;
16066 enum rtx_code code
= GET_CODE (cmp
);
16067 rtx op0
= XEXP (cmp
, 0);
16068 rtx op1
= XEXP (cmp
, 1);
16070 if (FLOAT_MODE_P (mode
))
16071 comp_mode
= CCFPmode
;
16072 else if (code
== GTU
|| code
== LTU
16073 || code
== GEU
|| code
== LEU
)
16074 comp_mode
= CCUNSmode
;
16075 else if ((code
== EQ
|| code
== NE
)
16076 && GET_CODE (op0
) == SUBREG
16077 && GET_CODE (op1
) == SUBREG
16078 && SUBREG_PROMOTED_UNSIGNED_P (op0
)
16079 && SUBREG_PROMOTED_UNSIGNED_P (op1
))
16080 /* These are unsigned values, perhaps there will be a later
16081 ordering compare that can be shared with this one.
16082 Unfortunately we cannot detect the signedness of the operands
16083 for non-subregs. */
16084 comp_mode
= CCUNSmode
;
16086 comp_mode
= CCmode
;
16088 /* First, the compare. */
16089 compare_result
= gen_reg_rtx (comp_mode
);
16091 /* E500 FP compare instructions on the GPRs. Yuck! */
16092 if ((!TARGET_FPRS
&& TARGET_HARD_FLOAT
)
16093 && FLOAT_MODE_P (mode
))
16095 rtx cmp
, or_result
, compare_result2
;
16096 enum machine_mode op_mode
= GET_MODE (op0
);
16098 if (op_mode
== VOIDmode
)
16099 op_mode
= GET_MODE (op1
);
16101 /* The E500 FP compare instructions toggle the GT bit (CR bit 1) only.
16102 This explains the following mess. */
16106 case EQ
: case UNEQ
: case NE
: case LTGT
:
16110 cmp
= (flag_finite_math_only
&& !flag_trapping_math
)
16111 ? gen_tstsfeq_gpr (compare_result
, op0
, op1
)
16112 : gen_cmpsfeq_gpr (compare_result
, op0
, op1
);
16116 cmp
= (flag_finite_math_only
&& !flag_trapping_math
)
16117 ? gen_tstdfeq_gpr (compare_result
, op0
, op1
)
16118 : gen_cmpdfeq_gpr (compare_result
, op0
, op1
);
16122 cmp
= (flag_finite_math_only
&& !flag_trapping_math
)
16123 ? gen_tsttfeq_gpr (compare_result
, op0
, op1
)
16124 : gen_cmptfeq_gpr (compare_result
, op0
, op1
);
16128 gcc_unreachable ();
16132 case GT
: case GTU
: case UNGT
: case UNGE
: case GE
: case GEU
:
16136 cmp
= (flag_finite_math_only
&& !flag_trapping_math
)
16137 ? gen_tstsfgt_gpr (compare_result
, op0
, op1
)
16138 : gen_cmpsfgt_gpr (compare_result
, op0
, op1
);
16142 cmp
= (flag_finite_math_only
&& !flag_trapping_math
)
16143 ? gen_tstdfgt_gpr (compare_result
, op0
, op1
)
16144 : gen_cmpdfgt_gpr (compare_result
, op0
, op1
);
16148 cmp
= (flag_finite_math_only
&& !flag_trapping_math
)
16149 ? gen_tsttfgt_gpr (compare_result
, op0
, op1
)
16150 : gen_cmptfgt_gpr (compare_result
, op0
, op1
);
16154 gcc_unreachable ();
16158 case LT
: case LTU
: case UNLT
: case UNLE
: case LE
: case LEU
:
16162 cmp
= (flag_finite_math_only
&& !flag_trapping_math
)
16163 ? gen_tstsflt_gpr (compare_result
, op0
, op1
)
16164 : gen_cmpsflt_gpr (compare_result
, op0
, op1
);
16168 cmp
= (flag_finite_math_only
&& !flag_trapping_math
)
16169 ? gen_tstdflt_gpr (compare_result
, op0
, op1
)
16170 : gen_cmpdflt_gpr (compare_result
, op0
, op1
);
16174 cmp
= (flag_finite_math_only
&& !flag_trapping_math
)
16175 ? gen_tsttflt_gpr (compare_result
, op0
, op1
)
16176 : gen_cmptflt_gpr (compare_result
, op0
, op1
);
16180 gcc_unreachable ();
16184 gcc_unreachable ();
16187 /* Synthesize LE and GE from LT/GT || EQ. */
16188 if (code
== LE
|| code
== GE
|| code
== LEU
|| code
== GEU
)
16194 case LE
: code
= LT
; break;
16195 case GE
: code
= GT
; break;
16196 case LEU
: code
= LT
; break;
16197 case GEU
: code
= GT
; break;
16198 default: gcc_unreachable ();
16201 compare_result2
= gen_reg_rtx (CCFPmode
);
16207 cmp
= (flag_finite_math_only
&& !flag_trapping_math
)
16208 ? gen_tstsfeq_gpr (compare_result2
, op0
, op1
)
16209 : gen_cmpsfeq_gpr (compare_result2
, op0
, op1
);
16213 cmp
= (flag_finite_math_only
&& !flag_trapping_math
)
16214 ? gen_tstdfeq_gpr (compare_result2
, op0
, op1
)
16215 : gen_cmpdfeq_gpr (compare_result2
, op0
, op1
);
16219 cmp
= (flag_finite_math_only
&& !flag_trapping_math
)
16220 ? gen_tsttfeq_gpr (compare_result2
, op0
, op1
)
16221 : gen_cmptfeq_gpr (compare_result2
, op0
, op1
);
16225 gcc_unreachable ();
16229 /* OR them together. */
16230 or_result
= gen_reg_rtx (CCFPmode
);
16231 cmp
= gen_e500_cr_ior_compare (or_result
, compare_result
,
16233 compare_result
= or_result
;
16238 if (code
== NE
|| code
== LTGT
)
16248 /* Generate XLC-compatible TFmode compare as PARALLEL with extra
16249 CLOBBERs to match cmptf_internal2 pattern. */
16250 if (comp_mode
== CCFPmode
&& TARGET_XL_COMPAT
16251 && GET_MODE (op0
) == TFmode
16252 && !TARGET_IEEEQUAD
16253 && TARGET_HARD_FLOAT
&& TARGET_FPRS
&& TARGET_LONG_DOUBLE_128
)
16254 emit_insn (gen_rtx_PARALLEL (VOIDmode
,
16256 gen_rtx_SET (VOIDmode
,
16258 gen_rtx_COMPARE (comp_mode
, op0
, op1
)),
16259 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
16260 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
16261 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
16262 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
16263 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
16264 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
16265 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
16266 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
16267 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (Pmode
)))));
16268 else if (GET_CODE (op1
) == UNSPEC
16269 && XINT (op1
, 1) == UNSPEC_SP_TEST
)
16271 rtx op1b
= XVECEXP (op1
, 0, 0);
16272 comp_mode
= CCEQmode
;
16273 compare_result
= gen_reg_rtx (CCEQmode
);
16275 emit_insn (gen_stack_protect_testdi (compare_result
, op0
, op1b
));
16277 emit_insn (gen_stack_protect_testsi (compare_result
, op0
, op1b
));
16280 emit_insn (gen_rtx_SET (VOIDmode
, compare_result
,
16281 gen_rtx_COMPARE (comp_mode
, op0
, op1
)));
16284 /* Some kinds of FP comparisons need an OR operation;
16285 under flag_finite_math_only we don't bother. */
16286 if (FLOAT_MODE_P (mode
)
16287 && !flag_finite_math_only
16288 && !(TARGET_HARD_FLOAT
&& !TARGET_FPRS
)
16289 && (code
== LE
|| code
== GE
16290 || code
== UNEQ
|| code
== LTGT
16291 || code
== UNGT
|| code
== UNLT
))
16293 enum rtx_code or1
, or2
;
16294 rtx or1_rtx
, or2_rtx
, compare2_rtx
;
16295 rtx or_result
= gen_reg_rtx (CCEQmode
);
16299 case LE
: or1
= LT
; or2
= EQ
; break;
16300 case GE
: or1
= GT
; or2
= EQ
; break;
16301 case UNEQ
: or1
= UNORDERED
; or2
= EQ
; break;
16302 case LTGT
: or1
= LT
; or2
= GT
; break;
16303 case UNGT
: or1
= UNORDERED
; or2
= GT
; break;
16304 case UNLT
: or1
= UNORDERED
; or2
= LT
; break;
16305 default: gcc_unreachable ();
16307 validate_condition_mode (or1
, comp_mode
);
16308 validate_condition_mode (or2
, comp_mode
);
16309 or1_rtx
= gen_rtx_fmt_ee (or1
, SImode
, compare_result
, const0_rtx
);
16310 or2_rtx
= gen_rtx_fmt_ee (or2
, SImode
, compare_result
, const0_rtx
);
16311 compare2_rtx
= gen_rtx_COMPARE (CCEQmode
,
16312 gen_rtx_IOR (SImode
, or1_rtx
, or2_rtx
),
16314 emit_insn (gen_rtx_SET (VOIDmode
, or_result
, compare2_rtx
));
16316 compare_result
= or_result
;
16320 validate_condition_mode (code
, GET_MODE (compare_result
));
16322 return gen_rtx_fmt_ee (code
, VOIDmode
, compare_result
, const0_rtx
);
16326 /* Emit the RTL for an sISEL pattern. */
16329 rs6000_emit_sISEL (enum machine_mode mode ATTRIBUTE_UNUSED
, rtx operands
[])
16331 rs6000_emit_int_cmove (operands
[0], operands
[1], const1_rtx
, const0_rtx
);
16335 rs6000_emit_sCOND (enum machine_mode mode
, rtx operands
[])
16338 enum machine_mode op_mode
;
16339 enum rtx_code cond_code
;
16340 rtx result
= operands
[0];
16342 if (TARGET_ISEL
&& (mode
== SImode
|| mode
== DImode
))
16344 rs6000_emit_sISEL (mode
, operands
);
16348 condition_rtx
= rs6000_generate_compare (operands
[1], mode
);
16349 cond_code
= GET_CODE (condition_rtx
);
16351 if (FLOAT_MODE_P (mode
)
16352 && !TARGET_FPRS
&& TARGET_HARD_FLOAT
)
16356 PUT_MODE (condition_rtx
, SImode
);
16357 t
= XEXP (condition_rtx
, 0);
16359 gcc_assert (cond_code
== NE
|| cond_code
== EQ
);
16361 if (cond_code
== NE
)
16362 emit_insn (gen_e500_flip_gt_bit (t
, t
));
16364 emit_insn (gen_move_from_CR_gt_bit (result
, t
));
16368 if (cond_code
== NE
16369 || cond_code
== GE
|| cond_code
== LE
16370 || cond_code
== GEU
|| cond_code
== LEU
16371 || cond_code
== ORDERED
|| cond_code
== UNGE
|| cond_code
== UNLE
)
16373 rtx not_result
= gen_reg_rtx (CCEQmode
);
16374 rtx not_op
, rev_cond_rtx
;
16375 enum machine_mode cc_mode
;
16377 cc_mode
= GET_MODE (XEXP (condition_rtx
, 0));
16379 rev_cond_rtx
= gen_rtx_fmt_ee (rs6000_reverse_condition (cc_mode
, cond_code
),
16380 SImode
, XEXP (condition_rtx
, 0), const0_rtx
);
16381 not_op
= gen_rtx_COMPARE (CCEQmode
, rev_cond_rtx
, const0_rtx
);
16382 emit_insn (gen_rtx_SET (VOIDmode
, not_result
, not_op
));
16383 condition_rtx
= gen_rtx_EQ (VOIDmode
, not_result
, const0_rtx
);
16386 op_mode
= GET_MODE (XEXP (operands
[1], 0));
16387 if (op_mode
== VOIDmode
)
16388 op_mode
= GET_MODE (XEXP (operands
[1], 1));
16390 if (TARGET_POWERPC64
&& (op_mode
== DImode
|| FLOAT_MODE_P (mode
)))
16392 PUT_MODE (condition_rtx
, DImode
);
16393 convert_move (result
, condition_rtx
, 0);
16397 PUT_MODE (condition_rtx
, SImode
);
16398 emit_insn (gen_rtx_SET (VOIDmode
, result
, condition_rtx
));
16402 /* Emit a branch of kind CODE to location LOC. */
16405 rs6000_emit_cbranch (enum machine_mode mode
, rtx operands
[])
16407 rtx condition_rtx
, loc_ref
;
16409 condition_rtx
= rs6000_generate_compare (operands
[0], mode
);
16410 loc_ref
= gen_rtx_LABEL_REF (VOIDmode
, operands
[3]);
16411 emit_jump_insn (gen_rtx_SET (VOIDmode
, pc_rtx
,
16412 gen_rtx_IF_THEN_ELSE (VOIDmode
, condition_rtx
,
16413 loc_ref
, pc_rtx
)));
16416 /* Return the string to output a conditional branch to LABEL, which is
16417 the operand number of the label, or -1 if the branch is really a
16418 conditional return.
16420 OP is the conditional expression. XEXP (OP, 0) is assumed to be a
16421 condition code register and its mode specifies what kind of
16422 comparison we made.
16424 REVERSED is nonzero if we should reverse the sense of the comparison.
16426 INSN is the insn. */
16429 output_cbranch (rtx op
, const char *label
, int reversed
, rtx insn
)
16431 static char string
[64];
16432 enum rtx_code code
= GET_CODE (op
);
16433 rtx cc_reg
= XEXP (op
, 0);
16434 enum machine_mode mode
= GET_MODE (cc_reg
);
16435 int cc_regno
= REGNO (cc_reg
) - CR0_REGNO
;
16436 int need_longbranch
= label
!= NULL
&& get_attr_length (insn
) == 8;
16437 int really_reversed
= reversed
^ need_longbranch
;
16443 validate_condition_mode (code
, mode
);
16445 /* Work out which way this really branches. We could use
16446 reverse_condition_maybe_unordered here always but this
16447 makes the resulting assembler clearer. */
16448 if (really_reversed
)
16450 /* Reversal of FP compares takes care -- an ordered compare
16451 becomes an unordered compare and vice versa. */
16452 if (mode
== CCFPmode
)
16453 code
= reverse_condition_maybe_unordered (code
);
16455 code
= reverse_condition (code
);
16458 if ((!TARGET_FPRS
&& TARGET_HARD_FLOAT
) && mode
== CCFPmode
)
16460 /* The efscmp/tst* instructions twiddle bit 2, which maps nicely
16465 /* Opposite of GT. */
16474 gcc_unreachable ();
16480 /* Not all of these are actually distinct opcodes, but
16481 we distinguish them for clarity of the resulting assembler. */
16482 case NE
: case LTGT
:
16483 ccode
= "ne"; break;
16484 case EQ
: case UNEQ
:
16485 ccode
= "eq"; break;
16487 ccode
= "ge"; break;
16488 case GT
: case GTU
: case UNGT
:
16489 ccode
= "gt"; break;
16491 ccode
= "le"; break;
16492 case LT
: case LTU
: case UNLT
:
16493 ccode
= "lt"; break;
16494 case UNORDERED
: ccode
= "un"; break;
16495 case ORDERED
: ccode
= "nu"; break;
16496 case UNGE
: ccode
= "nl"; break;
16497 case UNLE
: ccode
= "ng"; break;
16499 gcc_unreachable ();
16502 /* Maybe we have a guess as to how likely the branch is.
16503 The old mnemonics don't have a way to specify this information. */
16505 note
= find_reg_note (insn
, REG_BR_PROB
, NULL_RTX
);
16506 if (note
!= NULL_RTX
)
16508 /* PROB is the difference from 50%. */
16509 int prob
= INTVAL (XEXP (note
, 0)) - REG_BR_PROB_BASE
/ 2;
16511 /* Only hint for highly probable/improbable branches on newer
16512 cpus as static prediction overrides processor dynamic
16513 prediction. For older cpus we may as well always hint, but
16514 assume not taken for branches that are very close to 50% as a
16515 mispredicted taken branch is more expensive than a
16516 mispredicted not-taken branch. */
16517 if (rs6000_always_hint
16518 || (abs (prob
) > REG_BR_PROB_BASE
/ 100 * 48
16519 && br_prob_note_reliable_p (note
)))
16521 if (abs (prob
) > REG_BR_PROB_BASE
/ 20
16522 && ((prob
> 0) ^ need_longbranch
))
16530 s
+= sprintf (s
, "{b%sr|b%slr%s} ", ccode
, ccode
, pred
);
16532 s
+= sprintf (s
, "{b%s|b%s%s} ", ccode
, ccode
, pred
);
16534 /* We need to escape any '%' characters in the reg_names string.
16535 Assume they'd only be the first character.... */
16536 if (reg_names
[cc_regno
+ CR0_REGNO
][0] == '%')
16538 s
+= sprintf (s
, "%s", reg_names
[cc_regno
+ CR0_REGNO
]);
16542 /* If the branch distance was too far, we may have to use an
16543 unconditional branch to go the distance. */
16544 if (need_longbranch
)
16545 s
+= sprintf (s
, ",$+8\n\tb %s", label
);
16547 s
+= sprintf (s
, ",%s", label
);
16553 /* Return the string to flip the GT bit on a CR. */
16555 output_e500_flip_gt_bit (rtx dst
, rtx src
)
16557 static char string
[64];
16560 gcc_assert (GET_CODE (dst
) == REG
&& CR_REGNO_P (REGNO (dst
))
16561 && GET_CODE (src
) == REG
&& CR_REGNO_P (REGNO (src
)));
16564 a
= 4 * (REGNO (dst
) - CR0_REGNO
) + 1;
16565 b
= 4 * (REGNO (src
) - CR0_REGNO
) + 1;
16567 sprintf (string
, "crnot %d,%d", a
, b
);
16571 /* Return insn for VSX or Altivec comparisons. */
16574 rs6000_emit_vector_compare_inner (enum rtx_code code
, rtx op0
, rtx op1
)
16577 enum machine_mode mode
= GET_MODE (op0
);
16585 if (GET_MODE_CLASS (mode
) == MODE_VECTOR_INT
)
16591 mask
= gen_reg_rtx (mode
);
16592 emit_insn (gen_rtx_SET (VOIDmode
,
16594 gen_rtx_fmt_ee (code
, mode
, op0
, op1
)));
16601 /* Emit vector compare for operands OP0 and OP1 using code RCODE.
16602 DMODE is expected destination mode. This is a recursive function. */
16605 rs6000_emit_vector_compare (enum rtx_code rcode
,
16607 enum machine_mode dmode
)
16610 bool swap_operands
= false;
16611 bool try_again
= false;
16613 gcc_assert (VECTOR_UNIT_ALTIVEC_OR_VSX_P (dmode
));
16614 gcc_assert (GET_MODE (op0
) == GET_MODE (op1
));
16616 /* See if the comparison works as is. */
16617 mask
= rs6000_emit_vector_compare_inner (rcode
, op0
, op1
);
16625 swap_operands
= true;
16630 swap_operands
= true;
16638 /* Invert condition and try again.
16639 e.g., A != B becomes ~(A==B). */
16641 enum rtx_code rev_code
;
16642 enum insn_code nor_code
;
16645 rev_code
= reverse_condition_maybe_unordered (rcode
);
16646 if (rev_code
== UNKNOWN
)
16649 nor_code
= optab_handler (one_cmpl_optab
, dmode
);
16650 if (nor_code
== CODE_FOR_nothing
)
16653 mask2
= rs6000_emit_vector_compare (rev_code
, op0
, op1
, dmode
);
16657 mask
= gen_reg_rtx (dmode
);
16658 emit_insn (GEN_FCN (nor_code
) (mask
, mask2
));
16666 /* Try GT/GTU/LT/LTU OR EQ */
16669 enum insn_code ior_code
;
16670 enum rtx_code new_code
;
16691 gcc_unreachable ();
16694 ior_code
= optab_handler (ior_optab
, dmode
);
16695 if (ior_code
== CODE_FOR_nothing
)
16698 c_rtx
= rs6000_emit_vector_compare (new_code
, op0
, op1
, dmode
);
16702 eq_rtx
= rs6000_emit_vector_compare (EQ
, op0
, op1
, dmode
);
16706 mask
= gen_reg_rtx (dmode
);
16707 emit_insn (GEN_FCN (ior_code
) (mask
, c_rtx
, eq_rtx
));
16725 mask
= rs6000_emit_vector_compare_inner (rcode
, op0
, op1
);
16730 /* You only get two chances. */
16734 /* Emit vector conditional expression. DEST is destination. OP_TRUE and
16735 OP_FALSE are two VEC_COND_EXPR operands. CC_OP0 and CC_OP1 are the two
16736 operands for the relation operation COND. */
16739 rs6000_emit_vector_cond_expr (rtx dest
, rtx op_true
, rtx op_false
,
16740 rtx cond
, rtx cc_op0
, rtx cc_op1
)
16742 enum machine_mode dest_mode
= GET_MODE (dest
);
16743 enum rtx_code rcode
= GET_CODE (cond
);
16744 enum machine_mode cc_mode
= CCmode
;
16748 bool invert_move
= false;
16750 if (VECTOR_UNIT_NONE_P (dest_mode
))
16755 /* Swap operands if we can, and fall back to doing the operation as
16756 specified, and doing a NOR to invert the test. */
16762 /* Invert condition and try again.
16763 e.g., A = (B != C) ? D : E becomes A = (B == C) ? E : D. */
16764 invert_move
= true;
16765 rcode
= reverse_condition_maybe_unordered (rcode
);
16766 if (rcode
== UNKNOWN
)
16770 /* Mark unsigned tests with CCUNSmode. */
16775 cc_mode
= CCUNSmode
;
16782 /* Get the vector mask for the given relational operations. */
16783 mask
= rs6000_emit_vector_compare (rcode
, cc_op0
, cc_op1
, dest_mode
);
16791 op_true
= op_false
;
16795 cond2
= gen_rtx_fmt_ee (NE
, cc_mode
, mask
, const0_rtx
);
16796 emit_insn (gen_rtx_SET (VOIDmode
,
16798 gen_rtx_IF_THEN_ELSE (dest_mode
,
16805 /* Emit a conditional move: move TRUE_COND to DEST if OP of the
16806 operands of the last comparison is nonzero/true, FALSE_COND if it
16807 is zero/false. Return 0 if the hardware has no such operation. */
16810 rs6000_emit_cmove (rtx dest
, rtx op
, rtx true_cond
, rtx false_cond
)
16812 enum rtx_code code
= GET_CODE (op
);
16813 rtx op0
= XEXP (op
, 0);
16814 rtx op1
= XEXP (op
, 1);
16815 REAL_VALUE_TYPE c1
;
16816 enum machine_mode compare_mode
= GET_MODE (op0
);
16817 enum machine_mode result_mode
= GET_MODE (dest
);
16819 bool is_against_zero
;
16821 /* These modes should always match. */
16822 if (GET_MODE (op1
) != compare_mode
16823 /* In the isel case however, we can use a compare immediate, so
16824 op1 may be a small constant. */
16825 && (!TARGET_ISEL
|| !short_cint_operand (op1
, VOIDmode
)))
16827 if (GET_MODE (true_cond
) != result_mode
)
16829 if (GET_MODE (false_cond
) != result_mode
)
16832 /* First, work out if the hardware can do this at all, or
16833 if it's too slow.... */
16834 if (!FLOAT_MODE_P (compare_mode
))
16837 return rs6000_emit_int_cmove (dest
, op
, true_cond
, false_cond
);
16840 else if (TARGET_HARD_FLOAT
&& !TARGET_FPRS
16841 && SCALAR_FLOAT_MODE_P (compare_mode
))
16844 is_against_zero
= op1
== CONST0_RTX (compare_mode
);
16846 /* A floating-point subtract might overflow, underflow, or produce
16847 an inexact result, thus changing the floating-point flags, so it
16848 can't be generated if we care about that. It's safe if one side
16849 of the construct is zero, since then no subtract will be
16851 if (SCALAR_FLOAT_MODE_P (compare_mode
)
16852 && flag_trapping_math
&& ! is_against_zero
)
16855 /* Eliminate half of the comparisons by switching operands, this
16856 makes the remaining code simpler. */
16857 if (code
== UNLT
|| code
== UNGT
|| code
== UNORDERED
|| code
== NE
16858 || code
== LTGT
|| code
== LT
|| code
== UNLE
)
16860 code
= reverse_condition_maybe_unordered (code
);
16862 true_cond
= false_cond
;
16866 /* UNEQ and LTGT take four instructions for a comparison with zero,
16867 it'll probably be faster to use a branch here too. */
16868 if (code
== UNEQ
&& HONOR_NANS (compare_mode
))
16871 if (GET_CODE (op1
) == CONST_DOUBLE
)
16872 REAL_VALUE_FROM_CONST_DOUBLE (c1
, op1
);
16874 /* We're going to try to implement comparisons by performing
16875 a subtract, then comparing against zero. Unfortunately,
16876 Inf - Inf is NaN which is not zero, and so if we don't
16877 know that the operand is finite and the comparison
16878 would treat EQ different to UNORDERED, we can't do it. */
16879 if (HONOR_INFINITIES (compare_mode
)
16880 && code
!= GT
&& code
!= UNGE
16881 && (GET_CODE (op1
) != CONST_DOUBLE
|| real_isinf (&c1
))
16882 /* Constructs of the form (a OP b ? a : b) are safe. */
16883 && ((! rtx_equal_p (op0
, false_cond
) && ! rtx_equal_p (op1
, false_cond
))
16884 || (! rtx_equal_p (op0
, true_cond
)
16885 && ! rtx_equal_p (op1
, true_cond
))))
16888 /* At this point we know we can use fsel. */
16890 /* Reduce the comparison to a comparison against zero. */
16891 if (! is_against_zero
)
16893 temp
= gen_reg_rtx (compare_mode
);
16894 emit_insn (gen_rtx_SET (VOIDmode
, temp
,
16895 gen_rtx_MINUS (compare_mode
, op0
, op1
)));
16897 op1
= CONST0_RTX (compare_mode
);
16900 /* If we don't care about NaNs we can reduce some of the comparisons
16901 down to faster ones. */
16902 if (! HONOR_NANS (compare_mode
))
16908 true_cond
= false_cond
;
16921 /* Now, reduce everything down to a GE. */
16928 temp
= gen_reg_rtx (compare_mode
);
16929 emit_insn (gen_rtx_SET (VOIDmode
, temp
, gen_rtx_NEG (compare_mode
, op0
)));
16934 temp
= gen_reg_rtx (compare_mode
);
16935 emit_insn (gen_rtx_SET (VOIDmode
, temp
, gen_rtx_ABS (compare_mode
, op0
)));
16940 temp
= gen_reg_rtx (compare_mode
);
16941 emit_insn (gen_rtx_SET (VOIDmode
, temp
,
16942 gen_rtx_NEG (compare_mode
,
16943 gen_rtx_ABS (compare_mode
, op0
))));
16948 /* a UNGE 0 <-> (a GE 0 || -a UNLT 0) */
16949 temp
= gen_reg_rtx (result_mode
);
16950 emit_insn (gen_rtx_SET (VOIDmode
, temp
,
16951 gen_rtx_IF_THEN_ELSE (result_mode
,
16952 gen_rtx_GE (VOIDmode
,
16954 true_cond
, false_cond
)));
16955 false_cond
= true_cond
;
16958 temp
= gen_reg_rtx (compare_mode
);
16959 emit_insn (gen_rtx_SET (VOIDmode
, temp
, gen_rtx_NEG (compare_mode
, op0
)));
16964 /* a GT 0 <-> (a GE 0 && -a UNLT 0) */
16965 temp
= gen_reg_rtx (result_mode
);
16966 emit_insn (gen_rtx_SET (VOIDmode
, temp
,
16967 gen_rtx_IF_THEN_ELSE (result_mode
,
16968 gen_rtx_GE (VOIDmode
,
16970 true_cond
, false_cond
)));
16971 true_cond
= false_cond
;
16974 temp
= gen_reg_rtx (compare_mode
);
16975 emit_insn (gen_rtx_SET (VOIDmode
, temp
, gen_rtx_NEG (compare_mode
, op0
)));
16980 gcc_unreachable ();
16983 emit_insn (gen_rtx_SET (VOIDmode
, dest
,
16984 gen_rtx_IF_THEN_ELSE (result_mode
,
16985 gen_rtx_GE (VOIDmode
,
16987 true_cond
, false_cond
)));
16991 /* Same as above, but for ints (isel). */
16994 rs6000_emit_int_cmove (rtx dest
, rtx op
, rtx true_cond
, rtx false_cond
)
16996 rtx condition_rtx
, cr
;
16997 enum machine_mode mode
= GET_MODE (dest
);
16998 enum rtx_code cond_code
;
16999 rtx (*isel_func
) (rtx
, rtx
, rtx
, rtx
, rtx
);
17002 if (mode
!= SImode
&& (!TARGET_POWERPC64
|| mode
!= DImode
))
17005 /* We still have to do the compare, because isel doesn't do a
17006 compare, it just looks at the CRx bits set by a previous compare
17008 condition_rtx
= rs6000_generate_compare (op
, mode
);
17009 cond_code
= GET_CODE (condition_rtx
);
17010 cr
= XEXP (condition_rtx
, 0);
17011 signedp
= GET_MODE (cr
) == CCmode
;
17013 isel_func
= (mode
== SImode
17014 ? (signedp
? gen_isel_signed_si
: gen_isel_unsigned_si
)
17015 : (signedp
? gen_isel_signed_di
: gen_isel_unsigned_di
));
17019 case LT
: case GT
: case LTU
: case GTU
: case EQ
:
17020 /* isel handles these directly. */
17024 /* We need to swap the sense of the comparison. */
17027 true_cond
= false_cond
;
17029 PUT_CODE (condition_rtx
, reverse_condition (cond_code
));
17034 false_cond
= force_reg (mode
, false_cond
);
17035 if (true_cond
!= const0_rtx
)
17036 true_cond
= force_reg (mode
, true_cond
);
17038 emit_insn (isel_func (dest
, condition_rtx
, true_cond
, false_cond
, cr
));
17044 output_isel (rtx
*operands
)
17046 enum rtx_code code
;
17048 code
= GET_CODE (operands
[1]);
17050 gcc_assert (!(code
== GE
|| code
== GEU
|| code
== LE
|| code
== LEU
|| code
== NE
));
17052 return "isel %0,%2,%3,%j1";
17056 rs6000_emit_minmax (rtx dest
, enum rtx_code code
, rtx op0
, rtx op1
)
17058 enum machine_mode mode
= GET_MODE (op0
);
17062 /* VSX/altivec have direct min/max insns. */
17063 if ((code
== SMAX
|| code
== SMIN
) && VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode
))
17065 emit_insn (gen_rtx_SET (VOIDmode
,
17067 gen_rtx_fmt_ee (code
, mode
, op0
, op1
)));
17071 if (code
== SMAX
|| code
== SMIN
)
17076 if (code
== SMAX
|| code
== UMAX
)
17077 target
= emit_conditional_move (dest
, c
, op0
, op1
, mode
,
17078 op0
, op1
, mode
, 0);
17080 target
= emit_conditional_move (dest
, c
, op0
, op1
, mode
,
17081 op1
, op0
, mode
, 0);
17082 gcc_assert (target
);
17083 if (target
!= dest
)
17084 emit_move_insn (dest
, target
);
17087 /* Emit instructions to perform a load-reserved/store-conditional operation.
17088 The operation performed is an atomic
17089 (set M (CODE:MODE M OP))
17090 If not NULL, BEFORE is atomically set to M before the operation, and
17091 AFTER is set to M after the operation (that is, (CODE:MODE M OP)).
17092 If SYNC_P then a memory barrier is emitted before the operation.
17093 Either OP or M may be wrapped in a NOT operation. */
17096 rs6000_emit_sync (enum rtx_code code
, enum machine_mode mode
,
17097 rtx m
, rtx op
, rtx before_param
, rtx after_param
,
17100 enum machine_mode used_mode
;
17101 rtx the_op
, set_before
, set_after
, set_atomic
, cc_scratch
, before
, after
;
17104 HOST_WIDE_INT imask
= GET_MODE_MASK (mode
);
17105 rtx shift
= NULL_RTX
;
17108 emit_insn (gen_lwsync ());
17112 /* If this is smaller than SImode, we'll have to use SImode with
17114 if (mode
== QImode
|| mode
== HImode
)
17118 if (MEM_ALIGN (used_m
) >= 32)
17121 if (BYTES_BIG_ENDIAN
)
17122 ishift
= GET_MODE_BITSIZE (SImode
) - GET_MODE_BITSIZE (mode
);
17124 shift
= GEN_INT (ishift
);
17125 used_m
= change_address (used_m
, SImode
, 0);
17129 rtx addrSI
, aligned_addr
;
17130 int shift_mask
= mode
== QImode
? 0x18 : 0x10;
17132 addrSI
= gen_lowpart_common (SImode
,
17133 force_reg (Pmode
, XEXP (used_m
, 0)));
17134 addrSI
= force_reg (SImode
, addrSI
);
17135 shift
= gen_reg_rtx (SImode
);
17137 emit_insn (gen_rlwinm (shift
, addrSI
, GEN_INT (3),
17138 GEN_INT (shift_mask
)));
17139 emit_insn (gen_xorsi3 (shift
, shift
, GEN_INT (shift_mask
)));
17141 aligned_addr
= expand_binop (Pmode
, and_optab
,
17143 GEN_INT (-4), NULL_RTX
,
17144 1, OPTAB_LIB_WIDEN
);
17145 used_m
= change_address (used_m
, SImode
, aligned_addr
);
17146 set_mem_align (used_m
, 32);
17148 /* It's safe to keep the old alias set of USED_M, because
17149 the operation is atomic and only affects the original
17153 if (GET_CODE (op
) == NOT
)
17155 oldop
= lowpart_subreg (SImode
, XEXP (op
, 0), mode
);
17156 oldop
= gen_rtx_NOT (SImode
, oldop
);
17159 oldop
= lowpart_subreg (SImode
, op
, mode
);
17165 newop
= expand_binop (SImode
, and_optab
,
17166 oldop
, GEN_INT (imask
), NULL_RTX
,
17167 1, OPTAB_LIB_WIDEN
);
17168 emit_insn (gen_ashlsi3 (newop
, newop
, shift
));
17171 case NOT
: /* NAND */
17172 newop
= expand_binop (SImode
, ior_optab
,
17173 oldop
, GEN_INT (~imask
), NULL_RTX
,
17174 1, OPTAB_LIB_WIDEN
);
17175 emit_insn (gen_rotlsi3 (newop
, newop
, shift
));
17179 newop
= expand_binop (SImode
, ior_optab
,
17180 oldop
, GEN_INT (~imask
), NULL_RTX
,
17181 1, OPTAB_LIB_WIDEN
);
17182 emit_insn (gen_rotlsi3 (newop
, newop
, shift
));
17190 newop
= expand_binop (SImode
, and_optab
,
17191 oldop
, GEN_INT (imask
), NULL_RTX
,
17192 1, OPTAB_LIB_WIDEN
);
17193 emit_insn (gen_ashlsi3 (newop
, newop
, shift
));
17195 mask
= gen_reg_rtx (SImode
);
17196 emit_move_insn (mask
, GEN_INT (imask
));
17197 emit_insn (gen_ashlsi3 (mask
, mask
, shift
));
17200 newop
= gen_rtx_PLUS (SImode
, m
, newop
);
17202 newop
= gen_rtx_MINUS (SImode
, m
, newop
);
17203 newop
= gen_rtx_AND (SImode
, newop
, mask
);
17204 newop
= gen_rtx_IOR (SImode
, newop
,
17205 gen_rtx_AND (SImode
,
17206 gen_rtx_NOT (SImode
, mask
),
17212 gcc_unreachable ();
17216 used_mode
= SImode
;
17217 before
= gen_reg_rtx (used_mode
);
17218 after
= gen_reg_rtx (used_mode
);
17223 before
= before_param
;
17224 after
= after_param
;
17226 if (before
== NULL_RTX
)
17227 before
= gen_reg_rtx (used_mode
);
17228 if (after
== NULL_RTX
)
17229 after
= gen_reg_rtx (used_mode
);
17232 if ((code
== PLUS
|| code
== MINUS
)
17233 && used_mode
!= mode
)
17234 the_op
= op
; /* Computed above. */
17235 else if (GET_CODE (op
) == NOT
&& GET_CODE (m
) != NOT
)
17236 the_op
= gen_rtx_fmt_ee (code
, used_mode
, op
, m
);
17237 else if (code
== NOT
)
17238 the_op
= gen_rtx_fmt_ee (IOR
, used_mode
,
17239 gen_rtx_NOT (used_mode
, m
),
17240 gen_rtx_NOT (used_mode
, op
));
17242 the_op
= gen_rtx_fmt_ee (code
, used_mode
, m
, op
);
17244 set_after
= gen_rtx_SET (VOIDmode
, after
, the_op
);
17245 set_before
= gen_rtx_SET (VOIDmode
, before
, used_m
);
17246 set_atomic
= gen_rtx_SET (VOIDmode
, used_m
,
17247 gen_rtx_UNSPEC (used_mode
,
17248 gen_rtvec (1, the_op
),
17250 cc_scratch
= gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (CCmode
));
17252 if ((code
== PLUS
|| code
== MINUS
) && used_mode
!= mode
)
17253 vec
= gen_rtvec (5, set_after
, set_before
, set_atomic
, cc_scratch
,
17254 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (SImode
)));
17256 vec
= gen_rtvec (4, set_after
, set_before
, set_atomic
, cc_scratch
);
17257 emit_insn (gen_rtx_PARALLEL (VOIDmode
, vec
));
17259 /* Shift and mask the return values properly. */
17260 if (used_mode
!= mode
&& before_param
)
17262 emit_insn (gen_lshrsi3 (before
, before
, shift
));
17263 convert_move (before_param
, before
, 1);
17266 if (used_mode
!= mode
&& after_param
)
17268 emit_insn (gen_lshrsi3 (after
, after
, shift
));
17269 convert_move (after_param
, after
, 1);
17272 /* The previous sequence will end with a branch that's dependent on
17273 the conditional store, so placing an isync will ensure that no
17274 other instructions (especially, no load or store instructions)
17275 can start before the atomic operation completes. */
17277 emit_insn (gen_isync ());
17280 /* A subroutine of the atomic operation splitters. Jump to LABEL if
17281 COND is true. Mark the jump as unlikely to be taken. */
17284 emit_unlikely_jump (rtx cond
, rtx label
)
17286 rtx very_unlikely
= GEN_INT (REG_BR_PROB_BASE
/ 100 - 1);
17289 x
= gen_rtx_IF_THEN_ELSE (VOIDmode
, cond
, label
, pc_rtx
);
17290 x
= emit_jump_insn (gen_rtx_SET (VOIDmode
, pc_rtx
, x
));
17291 add_reg_note (x
, REG_BR_PROB
, very_unlikely
);
17294 /* A subroutine of the atomic operation splitters. Emit a load-locked
17295 instruction in MODE. */
17298 emit_load_locked (enum machine_mode mode
, rtx reg
, rtx mem
)
17300 rtx (*fn
) (rtx
, rtx
) = NULL
;
17301 if (mode
== SImode
)
17302 fn
= gen_load_locked_si
;
17303 else if (mode
== DImode
)
17304 fn
= gen_load_locked_di
;
17305 emit_insn (fn (reg
, mem
));
17308 /* A subroutine of the atomic operation splitters. Emit a store-conditional
17309 instruction in MODE. */
17312 emit_store_conditional (enum machine_mode mode
, rtx res
, rtx mem
, rtx val
)
17314 rtx (*fn
) (rtx
, rtx
, rtx
) = NULL
;
17315 if (mode
== SImode
)
17316 fn
= gen_store_conditional_si
;
17317 else if (mode
== DImode
)
17318 fn
= gen_store_conditional_di
;
17320 /* Emit sync before stwcx. to address PPC405 Erratum. */
17321 if (PPC405_ERRATUM77
)
17322 emit_insn (gen_memory_barrier ());
17324 emit_insn (fn (res
, mem
, val
));
17327 /* Expand an atomic fetch-and-operate pattern. CODE is the binary operation
17328 to perform. MEM is the memory on which to operate. VAL is the second
17329 operand of the binary operator. BEFORE and AFTER are optional locations to
17330 return the value of MEM either before of after the operation. SCRATCH is
17331 a scratch register. */
17334 rs6000_split_atomic_op (enum rtx_code code
, rtx mem
, rtx val
,
17335 rtx before
, rtx after
, rtx scratch
)
17337 enum machine_mode mode
= GET_MODE (mem
);
17338 rtx label
, x
, cond
= gen_rtx_REG (CCmode
, CR0_REGNO
);
17340 emit_insn (gen_lwsync ());
17342 label
= gen_label_rtx ();
17343 emit_label (label
);
17344 label
= gen_rtx_LABEL_REF (VOIDmode
, label
);
17346 if (before
== NULL_RTX
)
17348 emit_load_locked (mode
, before
, mem
);
17351 x
= gen_rtx_IOR (mode
,
17352 gen_rtx_NOT (mode
, before
),
17353 gen_rtx_NOT (mode
, val
));
17354 else if (code
== AND
)
17355 x
= gen_rtx_UNSPEC (mode
, gen_rtvec (2, before
, val
), UNSPEC_AND
);
17357 x
= gen_rtx_fmt_ee (code
, mode
, before
, val
);
17359 if (after
!= NULL_RTX
)
17360 emit_insn (gen_rtx_SET (VOIDmode
, after
, copy_rtx (x
)));
17361 emit_insn (gen_rtx_SET (VOIDmode
, scratch
, x
));
17363 emit_store_conditional (mode
, cond
, mem
, scratch
);
17365 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
17366 emit_unlikely_jump (x
, label
);
17368 emit_insn (gen_isync ());
17371 /* Expand an atomic compare and swap operation. MEM is the memory on which
17372 to operate. OLDVAL is the old value to be compared. NEWVAL is the new
17373 value to be stored. SCRATCH is a scratch GPR. */
17376 rs6000_split_compare_and_swap (rtx retval
, rtx mem
, rtx oldval
, rtx newval
,
17379 enum machine_mode mode
= GET_MODE (mem
);
17380 rtx label1
, label2
, x
, cond
= gen_rtx_REG (CCmode
, CR0_REGNO
);
17382 emit_insn (gen_lwsync ());
17384 label1
= gen_rtx_LABEL_REF (VOIDmode
, gen_label_rtx ());
17385 label2
= gen_rtx_LABEL_REF (VOIDmode
, gen_label_rtx ());
17386 emit_label (XEXP (label1
, 0));
17388 emit_load_locked (mode
, retval
, mem
);
17390 x
= gen_rtx_COMPARE (CCmode
, retval
, oldval
);
17391 emit_insn (gen_rtx_SET (VOIDmode
, cond
, x
));
17393 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
17394 emit_unlikely_jump (x
, label2
);
17396 emit_move_insn (scratch
, newval
);
17397 emit_store_conditional (mode
, cond
, mem
, scratch
);
17399 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
17400 emit_unlikely_jump (x
, label1
);
17402 emit_insn (gen_isync ());
17403 emit_label (XEXP (label2
, 0));
17406 /* Expand an atomic test and set operation. MEM is the memory on which
17407 to operate. VAL is the value set. SCRATCH is a scratch GPR. */
17410 rs6000_split_lock_test_and_set (rtx retval
, rtx mem
, rtx val
, rtx scratch
)
17412 enum machine_mode mode
= GET_MODE (mem
);
17413 rtx label
, x
, cond
= gen_rtx_REG (CCmode
, CR0_REGNO
);
17415 label
= gen_rtx_LABEL_REF (VOIDmode
, gen_label_rtx ());
17416 emit_label (XEXP (label
, 0));
17418 emit_load_locked (mode
, retval
, mem
);
17419 emit_move_insn (scratch
, val
);
17420 emit_store_conditional (mode
, cond
, mem
, scratch
);
17422 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
17423 emit_unlikely_jump (x
, label
);
17425 emit_insn (gen_isync ());
17429 rs6000_expand_compare_and_swapqhi (rtx dst
, rtx mem
, rtx oldval
, rtx newval
)
17431 enum machine_mode mode
= GET_MODE (mem
);
17432 rtx addrSI
, align
, wdst
, shift
, mask
;
17433 HOST_WIDE_INT shift_mask
= mode
== QImode
? 0x18 : 0x10;
17434 HOST_WIDE_INT imask
= GET_MODE_MASK (mode
);
17436 /* Shift amount for subword relative to aligned word. */
17437 addrSI
= force_reg (GET_MODE (XEXP (mem
, 0)), XEXP (mem
, 0));
17438 addrSI
= force_reg (SImode
, gen_lowpart_common (SImode
, addrSI
));
17439 shift
= gen_reg_rtx (SImode
);
17440 emit_insn (gen_rlwinm (shift
, addrSI
, GEN_INT (3),
17441 GEN_INT (shift_mask
)));
17442 emit_insn (gen_xorsi3 (shift
, shift
, GEN_INT (shift_mask
)));
17444 /* Shift and mask old value into position within word. */
17445 oldval
= convert_modes (SImode
, mode
, oldval
, 1);
17446 oldval
= expand_binop (SImode
, and_optab
,
17447 oldval
, GEN_INT (imask
), NULL_RTX
,
17448 1, OPTAB_LIB_WIDEN
);
17449 emit_insn (gen_ashlsi3 (oldval
, oldval
, shift
));
17451 /* Shift and mask new value into position within word. */
17452 newval
= convert_modes (SImode
, mode
, newval
, 1);
17453 newval
= expand_binop (SImode
, and_optab
,
17454 newval
, GEN_INT (imask
), NULL_RTX
,
17455 1, OPTAB_LIB_WIDEN
);
17456 emit_insn (gen_ashlsi3 (newval
, newval
, shift
));
17458 /* Mask for insertion. */
17459 mask
= gen_reg_rtx (SImode
);
17460 emit_move_insn (mask
, GEN_INT (imask
));
17461 emit_insn (gen_ashlsi3 (mask
, mask
, shift
));
17463 /* Address of aligned word containing subword. */
17464 align
= expand_binop (Pmode
, and_optab
, XEXP (mem
, 0), GEN_INT (-4),
17465 NULL_RTX
, 1, OPTAB_LIB_WIDEN
);
17466 mem
= change_address (mem
, SImode
, align
);
17467 set_mem_align (mem
, 32);
17468 MEM_VOLATILE_P (mem
) = 1;
17470 wdst
= gen_reg_rtx (SImode
);
17471 emit_insn (gen_sync_compare_and_swapqhi_internal (wdst
, mask
,
17472 oldval
, newval
, mem
));
17474 /* Shift the result back. */
17475 emit_insn (gen_lshrsi3 (wdst
, wdst
, shift
));
17477 emit_move_insn (dst
, gen_lowpart (mode
, wdst
));
17481 rs6000_split_compare_and_swapqhi (rtx dest
, rtx mask
,
17482 rtx oldval
, rtx newval
, rtx mem
,
17485 rtx label1
, label2
, x
, cond
= gen_rtx_REG (CCmode
, CR0_REGNO
);
17487 emit_insn (gen_lwsync ());
17488 label1
= gen_rtx_LABEL_REF (VOIDmode
, gen_label_rtx ());
17489 label2
= gen_rtx_LABEL_REF (VOIDmode
, gen_label_rtx ());
17490 emit_label (XEXP (label1
, 0));
17492 emit_load_locked (SImode
, scratch
, mem
);
17494 /* Mask subword within loaded value for comparison with oldval.
17495 Use UNSPEC_AND to avoid clobber.*/
17496 emit_insn (gen_rtx_SET (SImode
, dest
,
17497 gen_rtx_UNSPEC (SImode
,
17498 gen_rtvec (2, scratch
, mask
),
17501 x
= gen_rtx_COMPARE (CCmode
, dest
, oldval
);
17502 emit_insn (gen_rtx_SET (VOIDmode
, cond
, x
));
17504 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
17505 emit_unlikely_jump (x
, label2
);
17507 /* Clear subword within loaded value for insertion of new value. */
17508 emit_insn (gen_rtx_SET (SImode
, scratch
,
17509 gen_rtx_AND (SImode
,
17510 gen_rtx_NOT (SImode
, mask
), scratch
)));
17511 emit_insn (gen_iorsi3 (scratch
, scratch
, newval
));
17512 emit_store_conditional (SImode
, cond
, mem
, scratch
);
17514 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
17515 emit_unlikely_jump (x
, label1
);
17517 emit_insn (gen_isync ());
17518 emit_label (XEXP (label2
, 0));
17522 /* Emit instructions to move SRC to DST. Called by splitters for
17523 multi-register moves. It will emit at most one instruction for
17524 each register that is accessed; that is, it won't emit li/lis pairs
17525 (or equivalent for 64-bit code). One of SRC or DST must be a hard
17529 rs6000_split_multireg_move (rtx dst
, rtx src
)
17531 /* The register number of the first register being moved. */
17533 /* The mode that is to be moved. */
17534 enum machine_mode mode
;
17535 /* The mode that the move is being done in, and its size. */
17536 enum machine_mode reg_mode
;
17538 /* The number of registers that will be moved. */
17541 reg
= REG_P (dst
) ? REGNO (dst
) : REGNO (src
);
17542 mode
= GET_MODE (dst
);
17543 nregs
= hard_regno_nregs
[reg
][mode
];
17544 if (FP_REGNO_P (reg
))
17545 reg_mode
= DECIMAL_FLOAT_MODE_P (mode
) ? DDmode
:
17546 ((TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
) ? DFmode
: SFmode
);
17547 else if (ALTIVEC_REGNO_P (reg
))
17548 reg_mode
= V16QImode
;
17549 else if (TARGET_E500_DOUBLE
&& mode
== TFmode
)
17552 reg_mode
= word_mode
;
17553 reg_mode_size
= GET_MODE_SIZE (reg_mode
);
17555 gcc_assert (reg_mode_size
* nregs
== GET_MODE_SIZE (mode
));
17557 if (REG_P (src
) && REG_P (dst
) && (REGNO (src
) < REGNO (dst
)))
17559 /* Move register range backwards, if we might have destructive
17562 for (i
= nregs
- 1; i
>= 0; i
--)
17563 emit_insn (gen_rtx_SET (VOIDmode
,
17564 simplify_gen_subreg (reg_mode
, dst
, mode
,
17565 i
* reg_mode_size
),
17566 simplify_gen_subreg (reg_mode
, src
, mode
,
17567 i
* reg_mode_size
)));
17573 bool used_update
= false;
17574 rtx restore_basereg
= NULL_RTX
;
17576 if (MEM_P (src
) && INT_REGNO_P (reg
))
17580 if (GET_CODE (XEXP (src
, 0)) == PRE_INC
17581 || GET_CODE (XEXP (src
, 0)) == PRE_DEC
)
17584 breg
= XEXP (XEXP (src
, 0), 0);
17585 delta_rtx
= (GET_CODE (XEXP (src
, 0)) == PRE_INC
17586 ? GEN_INT (GET_MODE_SIZE (GET_MODE (src
)))
17587 : GEN_INT (-GET_MODE_SIZE (GET_MODE (src
))));
17588 emit_insn (gen_add3_insn (breg
, breg
, delta_rtx
));
17589 src
= replace_equiv_address (src
, breg
);
17591 else if (! rs6000_offsettable_memref_p (src
))
17593 if (GET_CODE (XEXP (src
, 0)) == PRE_MODIFY
)
17595 rtx basereg
= XEXP (XEXP (src
, 0), 0);
17598 rtx ndst
= simplify_gen_subreg (reg_mode
, dst
, mode
, 0);
17599 emit_insn (gen_rtx_SET (VOIDmode
, ndst
,
17600 gen_rtx_MEM (reg_mode
, XEXP (src
, 0))));
17601 used_update
= true;
17604 emit_insn (gen_rtx_SET (VOIDmode
, basereg
,
17605 XEXP (XEXP (src
, 0), 1)));
17606 src
= replace_equiv_address (src
, basereg
);
17610 rtx basereg
= gen_rtx_REG (Pmode
, reg
);
17611 emit_insn (gen_rtx_SET (VOIDmode
, basereg
, XEXP (src
, 0)));
17612 src
= replace_equiv_address (src
, basereg
);
17616 breg
= XEXP (src
, 0);
17617 if (GET_CODE (breg
) == PLUS
|| GET_CODE (breg
) == LO_SUM
)
17618 breg
= XEXP (breg
, 0);
17620 /* If the base register we are using to address memory is
17621 also a destination reg, then change that register last. */
17623 && REGNO (breg
) >= REGNO (dst
)
17624 && REGNO (breg
) < REGNO (dst
) + nregs
)
17625 j
= REGNO (breg
) - REGNO (dst
);
17627 else if (MEM_P (dst
) && INT_REGNO_P (reg
))
17631 if (GET_CODE (XEXP (dst
, 0)) == PRE_INC
17632 || GET_CODE (XEXP (dst
, 0)) == PRE_DEC
)
17635 breg
= XEXP (XEXP (dst
, 0), 0);
17636 delta_rtx
= (GET_CODE (XEXP (dst
, 0)) == PRE_INC
17637 ? GEN_INT (GET_MODE_SIZE (GET_MODE (dst
)))
17638 : GEN_INT (-GET_MODE_SIZE (GET_MODE (dst
))));
17640 /* We have to update the breg before doing the store.
17641 Use store with update, if available. */
17645 rtx nsrc
= simplify_gen_subreg (reg_mode
, src
, mode
, 0);
17646 emit_insn (TARGET_32BIT
17647 ? (TARGET_POWERPC64
17648 ? gen_movdi_si_update (breg
, breg
, delta_rtx
, nsrc
)
17649 : gen_movsi_update (breg
, breg
, delta_rtx
, nsrc
))
17650 : gen_movdi_di_update (breg
, breg
, delta_rtx
, nsrc
));
17651 used_update
= true;
17654 emit_insn (gen_add3_insn (breg
, breg
, delta_rtx
));
17655 dst
= replace_equiv_address (dst
, breg
);
17657 else if (!rs6000_offsettable_memref_p (dst
)
17658 && GET_CODE (XEXP (dst
, 0)) != LO_SUM
)
17660 if (GET_CODE (XEXP (dst
, 0)) == PRE_MODIFY
)
17662 rtx basereg
= XEXP (XEXP (dst
, 0), 0);
17665 rtx nsrc
= simplify_gen_subreg (reg_mode
, src
, mode
, 0);
17666 emit_insn (gen_rtx_SET (VOIDmode
,
17667 gen_rtx_MEM (reg_mode
, XEXP (dst
, 0)), nsrc
));
17668 used_update
= true;
17671 emit_insn (gen_rtx_SET (VOIDmode
, basereg
,
17672 XEXP (XEXP (dst
, 0), 1)));
17673 dst
= replace_equiv_address (dst
, basereg
);
17677 rtx basereg
= XEXP (XEXP (dst
, 0), 0);
17678 rtx offsetreg
= XEXP (XEXP (dst
, 0), 1);
17679 gcc_assert (GET_CODE (XEXP (dst
, 0)) == PLUS
17681 && REG_P (offsetreg
)
17682 && REGNO (basereg
) != REGNO (offsetreg
));
17683 if (REGNO (basereg
) == 0)
17685 rtx tmp
= offsetreg
;
17686 offsetreg
= basereg
;
17689 emit_insn (gen_add3_insn (basereg
, basereg
, offsetreg
));
17690 restore_basereg
= gen_sub3_insn (basereg
, basereg
, offsetreg
);
17691 dst
= replace_equiv_address (dst
, basereg
);
17694 else if (GET_CODE (XEXP (dst
, 0)) != LO_SUM
)
17695 gcc_assert (rs6000_offsettable_memref_p (dst
));
17698 for (i
= 0; i
< nregs
; i
++)
17700 /* Calculate index to next subword. */
17705 /* If compiler already emitted move of first word by
17706 store with update, no need to do anything. */
17707 if (j
== 0 && used_update
)
17710 emit_insn (gen_rtx_SET (VOIDmode
,
17711 simplify_gen_subreg (reg_mode
, dst
, mode
,
17712 j
* reg_mode_size
),
17713 simplify_gen_subreg (reg_mode
, src
, mode
,
17714 j
* reg_mode_size
)));
17716 if (restore_basereg
!= NULL_RTX
)
17717 emit_insn (restore_basereg
);
17722 /* This page contains routines that are used to determine what the
17723 function prologue and epilogue code will do and write them out. */
17725 /* Return the first fixed-point register that is required to be
17726 saved. 32 if none. */
17729 first_reg_to_save (void)
17733 /* Find lowest numbered live register. */
17734 for (first_reg
= 13; first_reg
<= 31; first_reg
++)
17735 if (df_regs_ever_live_p (first_reg
)
17736 && (! call_used_regs
[first_reg
]
17737 || (first_reg
== RS6000_PIC_OFFSET_TABLE_REGNUM
17738 && ((DEFAULT_ABI
== ABI_V4
&& flag_pic
!= 0)
17739 || (DEFAULT_ABI
== ABI_DARWIN
&& flag_pic
)
17740 || (TARGET_TOC
&& TARGET_MINIMAL_TOC
)))))
17745 && crtl
->uses_pic_offset_table
17746 && first_reg
> RS6000_PIC_OFFSET_TABLE_REGNUM
)
17747 return RS6000_PIC_OFFSET_TABLE_REGNUM
;
17753 /* Similar, for FP regs. */
17756 first_fp_reg_to_save (void)
17760 /* Find lowest numbered live register. */
17761 for (first_reg
= 14 + 32; first_reg
<= 63; first_reg
++)
17762 if (df_regs_ever_live_p (first_reg
))
17768 /* Similar, for AltiVec regs. */
17771 first_altivec_reg_to_save (void)
17775 /* Stack frame remains as is unless we are in AltiVec ABI. */
17776 if (! TARGET_ALTIVEC_ABI
)
17777 return LAST_ALTIVEC_REGNO
+ 1;
17779 /* On Darwin, the unwind routines are compiled without
17780 TARGET_ALTIVEC, and use save_world to save/restore the
17781 altivec registers when necessary. */
17782 if (DEFAULT_ABI
== ABI_DARWIN
&& crtl
->calls_eh_return
17783 && ! TARGET_ALTIVEC
)
17784 return FIRST_ALTIVEC_REGNO
+ 20;
17786 /* Find lowest numbered live register. */
17787 for (i
= FIRST_ALTIVEC_REGNO
+ 20; i
<= LAST_ALTIVEC_REGNO
; ++i
)
17788 if (df_regs_ever_live_p (i
))
17794 /* Return a 32-bit mask of the AltiVec registers we need to set in
17795 VRSAVE. Bit n of the return value is 1 if Vn is live. The MSB in
17796 the 32-bit word is 0. */
17798 static unsigned int
17799 compute_vrsave_mask (void)
17801 unsigned int i
, mask
= 0;
17803 /* On Darwin, the unwind routines are compiled without
17804 TARGET_ALTIVEC, and use save_world to save/restore the
17805 call-saved altivec registers when necessary. */
17806 if (DEFAULT_ABI
== ABI_DARWIN
&& crtl
->calls_eh_return
17807 && ! TARGET_ALTIVEC
)
17810 /* First, find out if we use _any_ altivec registers. */
17811 for (i
= FIRST_ALTIVEC_REGNO
; i
<= LAST_ALTIVEC_REGNO
; ++i
)
17812 if (df_regs_ever_live_p (i
))
17813 mask
|= ALTIVEC_REG_BIT (i
);
17818 /* Next, remove the argument registers from the set. These must
17819 be in the VRSAVE mask set by the caller, so we don't need to add
17820 them in again. More importantly, the mask we compute here is
17821 used to generate CLOBBERs in the set_vrsave insn, and we do not
17822 wish the argument registers to die. */
17823 for (i
= crtl
->args
.info
.vregno
- 1; i
>= ALTIVEC_ARG_MIN_REG
; --i
)
17824 mask
&= ~ALTIVEC_REG_BIT (i
);
17826 /* Similarly, remove the return value from the set. */
17829 diddle_return_value (is_altivec_return_reg
, &yes
);
17831 mask
&= ~ALTIVEC_REG_BIT (ALTIVEC_ARG_RETURN
);
17837 /* For a very restricted set of circumstances, we can cut down the
17838 size of prologues/epilogues by calling our own save/restore-the-world
17842 compute_save_world_info (rs6000_stack_t
*info_ptr
)
17844 info_ptr
->world_save_p
= 1;
17845 info_ptr
->world_save_p
17846 = (WORLD_SAVE_P (info_ptr
)
17847 && DEFAULT_ABI
== ABI_DARWIN
17848 && ! (cfun
->calls_setjmp
&& flag_exceptions
)
17849 && info_ptr
->first_fp_reg_save
== FIRST_SAVED_FP_REGNO
17850 && info_ptr
->first_gp_reg_save
== FIRST_SAVED_GP_REGNO
17851 && info_ptr
->first_altivec_reg_save
== FIRST_SAVED_ALTIVEC_REGNO
17852 && info_ptr
->cr_save_p
);
17854 /* This will not work in conjunction with sibcalls. Make sure there
17855 are none. (This check is expensive, but seldom executed.) */
17856 if (WORLD_SAVE_P (info_ptr
))
17859 for ( insn
= get_last_insn_anywhere (); insn
; insn
= PREV_INSN (insn
))
17860 if ( GET_CODE (insn
) == CALL_INSN
17861 && SIBLING_CALL_P (insn
))
17863 info_ptr
->world_save_p
= 0;
17868 if (WORLD_SAVE_P (info_ptr
))
17870 /* Even if we're not touching VRsave, make sure there's room on the
17871 stack for it, if it looks like we're calling SAVE_WORLD, which
17872 will attempt to save it. */
17873 info_ptr
->vrsave_size
= 4;
17875 /* If we are going to save the world, we need to save the link register too. */
17876 info_ptr
->lr_save_p
= 1;
17878 /* "Save" the VRsave register too if we're saving the world. */
17879 if (info_ptr
->vrsave_mask
== 0)
17880 info_ptr
->vrsave_mask
= compute_vrsave_mask ();
17882 /* Because the Darwin register save/restore routines only handle
17883 F14 .. F31 and V20 .. V31 as per the ABI, perform a consistency
17885 gcc_assert (info_ptr
->first_fp_reg_save
>= FIRST_SAVED_FP_REGNO
17886 && (info_ptr
->first_altivec_reg_save
17887 >= FIRST_SAVED_ALTIVEC_REGNO
));
17894 is_altivec_return_reg (rtx reg
, void *xyes
)
17896 bool *yes
= (bool *) xyes
;
17897 if (REGNO (reg
) == ALTIVEC_ARG_RETURN
)
17902 /* Calculate the stack information for the current function. This is
17903 complicated by having two separate calling sequences, the AIX calling
17904 sequence and the V.4 calling sequence.
17906 AIX (and Darwin/Mac OS X) stack frames look like:
17908 SP----> +---------------------------------------+
17909 | back chain to caller | 0 0
17910 +---------------------------------------+
17911 | saved CR | 4 8 (8-11)
17912 +---------------------------------------+
17914 +---------------------------------------+
17915 | reserved for compilers | 12 24
17916 +---------------------------------------+
17917 | reserved for binders | 16 32
17918 +---------------------------------------+
17919 | saved TOC pointer | 20 40
17920 +---------------------------------------+
17921 | Parameter save area (P) | 24 48
17922 +---------------------------------------+
17923 | Alloca space (A) | 24+P etc.
17924 +---------------------------------------+
17925 | Local variable space (L) | 24+P+A
17926 +---------------------------------------+
17927 | Float/int conversion temporary (X) | 24+P+A+L
17928 +---------------------------------------+
17929 | Save area for AltiVec registers (W) | 24+P+A+L+X
17930 +---------------------------------------+
17931 | AltiVec alignment padding (Y) | 24+P+A+L+X+W
17932 +---------------------------------------+
17933 | Save area for VRSAVE register (Z) | 24+P+A+L+X+W+Y
17934 +---------------------------------------+
17935 | Save area for GP registers (G) | 24+P+A+X+L+X+W+Y+Z
17936 +---------------------------------------+
17937 | Save area for FP registers (F) | 24+P+A+X+L+X+W+Y+Z+G
17938 +---------------------------------------+
17939 old SP->| back chain to caller's caller |
17940 +---------------------------------------+
17942 The required alignment for AIX configurations is two words (i.e., 8
17946 V.4 stack frames look like:
17948 SP----> +---------------------------------------+
17949 | back chain to caller | 0
17950 +---------------------------------------+
17951 | caller's saved LR | 4
17952 +---------------------------------------+
17953 | Parameter save area (P) | 8
17954 +---------------------------------------+
17955 | Alloca space (A) | 8+P
17956 +---------------------------------------+
17957 | Varargs save area (V) | 8+P+A
17958 +---------------------------------------+
17959 | Local variable space (L) | 8+P+A+V
17960 +---------------------------------------+
17961 | Float/int conversion temporary (X) | 8+P+A+V+L
17962 +---------------------------------------+
17963 | Save area for AltiVec registers (W) | 8+P+A+V+L+X
17964 +---------------------------------------+
17965 | AltiVec alignment padding (Y) | 8+P+A+V+L+X+W
17966 +---------------------------------------+
17967 | Save area for VRSAVE register (Z) | 8+P+A+V+L+X+W+Y
17968 +---------------------------------------+
17969 | SPE: area for 64-bit GP registers |
17970 +---------------------------------------+
17971 | SPE alignment padding |
17972 +---------------------------------------+
17973 | saved CR (C) | 8+P+A+V+L+X+W+Y+Z
17974 +---------------------------------------+
17975 | Save area for GP registers (G) | 8+P+A+V+L+X+W+Y+Z+C
17976 +---------------------------------------+
17977 | Save area for FP registers (F) | 8+P+A+V+L+X+W+Y+Z+C+G
17978 +---------------------------------------+
17979 old SP->| back chain to caller's caller |
17980 +---------------------------------------+
17982 The required alignment for V.4 is 16 bytes, or 8 bytes if -meabi is
17983 given. (But note below and in sysv4.h that we require only 8 and
17984 may round up the size of our stack frame anyways. The historical
17985 reason is early versions of powerpc-linux which didn't properly
17986 align the stack at program startup. A happy side-effect is that
17987 -mno-eabi libraries can be used with -meabi programs.)
17989 The EABI configuration defaults to the V.4 layout. However,
17990 the stack alignment requirements may differ. If -mno-eabi is not
17991 given, the required stack alignment is 8 bytes; if -mno-eabi is
17992 given, the required alignment is 16 bytes. (But see V.4 comment
17995 #ifndef ABI_STACK_BOUNDARY
17996 #define ABI_STACK_BOUNDARY STACK_BOUNDARY
17999 static rs6000_stack_t
*
18000 rs6000_stack_info (void)
18002 static rs6000_stack_t info
;
18003 rs6000_stack_t
*info_ptr
= &info
;
18004 int reg_size
= TARGET_32BIT
? 4 : 8;
18008 HOST_WIDE_INT non_fixed_size
;
18010 memset (&info
, 0, sizeof (info
));
18014 /* Cache value so we don't rescan instruction chain over and over. */
18015 if (cfun
->machine
->insn_chain_scanned_p
== 0)
18016 cfun
->machine
->insn_chain_scanned_p
18017 = spe_func_has_64bit_regs_p () + 1;
18018 info_ptr
->spe_64bit_regs_used
= cfun
->machine
->insn_chain_scanned_p
- 1;
18021 /* Select which calling sequence. */
18022 info_ptr
->abi
= DEFAULT_ABI
;
18024 /* Calculate which registers need to be saved & save area size. */
18025 info_ptr
->first_gp_reg_save
= first_reg_to_save ();
18026 /* Assume that we will have to save RS6000_PIC_OFFSET_TABLE_REGNUM,
18027 even if it currently looks like we won't. Reload may need it to
18028 get at a constant; if so, it will have already created a constant
18029 pool entry for it. */
18030 if (((TARGET_TOC
&& TARGET_MINIMAL_TOC
)
18031 || (flag_pic
== 1 && DEFAULT_ABI
== ABI_V4
)
18032 || (flag_pic
&& DEFAULT_ABI
== ABI_DARWIN
))
18033 && crtl
->uses_const_pool
18034 && info_ptr
->first_gp_reg_save
> RS6000_PIC_OFFSET_TABLE_REGNUM
)
18035 first_gp
= RS6000_PIC_OFFSET_TABLE_REGNUM
;
18037 first_gp
= info_ptr
->first_gp_reg_save
;
18039 info_ptr
->gp_size
= reg_size
* (32 - first_gp
);
18041 /* For the SPE, we have an additional upper 32-bits on each GPR.
18042 Ideally we should save the entire 64-bits only when the upper
18043 half is used in SIMD instructions. Since we only record
18044 registers live (not the size they are used in), this proves
18045 difficult because we'd have to traverse the instruction chain at
18046 the right time, taking reload into account. This is a real pain,
18047 so we opt to save the GPRs in 64-bits always if but one register
18048 gets used in 64-bits. Otherwise, all the registers in the frame
18049 get saved in 32-bits.
18051 So... since when we save all GPRs (except the SP) in 64-bits, the
18052 traditional GP save area will be empty. */
18053 if (TARGET_SPE_ABI
&& info_ptr
->spe_64bit_regs_used
!= 0)
18054 info_ptr
->gp_size
= 0;
18056 info_ptr
->first_fp_reg_save
= first_fp_reg_to_save ();
18057 info_ptr
->fp_size
= 8 * (64 - info_ptr
->first_fp_reg_save
);
18059 info_ptr
->first_altivec_reg_save
= first_altivec_reg_to_save ();
18060 info_ptr
->altivec_size
= 16 * (LAST_ALTIVEC_REGNO
+ 1
18061 - info_ptr
->first_altivec_reg_save
);
18063 /* Does this function call anything? */
18064 info_ptr
->calls_p
= (! current_function_is_leaf
18065 || cfun
->machine
->ra_needs_full_frame
);
18067 /* Determine if we need to save the link register. */
18068 if ((DEFAULT_ABI
== ABI_AIX
18070 && !TARGET_PROFILE_KERNEL
)
18071 #ifdef TARGET_RELOCATABLE
18072 || (TARGET_RELOCATABLE
&& (get_pool_size () != 0))
18074 || (info_ptr
->first_fp_reg_save
!= 64
18075 && !FP_SAVE_INLINE (info_ptr
->first_fp_reg_save
))
18076 || (DEFAULT_ABI
== ABI_V4
&& cfun
->calls_alloca
)
18077 || info_ptr
->calls_p
18078 || rs6000_ra_ever_killed ())
18080 info_ptr
->lr_save_p
= 1;
18081 df_set_regs_ever_live (LR_REGNO
, true);
18084 /* Determine if we need to save the condition code registers. */
18085 if (df_regs_ever_live_p (CR2_REGNO
)
18086 || df_regs_ever_live_p (CR3_REGNO
)
18087 || df_regs_ever_live_p (CR4_REGNO
))
18089 info_ptr
->cr_save_p
= 1;
18090 if (DEFAULT_ABI
== ABI_V4
)
18091 info_ptr
->cr_size
= reg_size
;
18094 /* If the current function calls __builtin_eh_return, then we need
18095 to allocate stack space for registers that will hold data for
18096 the exception handler. */
18097 if (crtl
->calls_eh_return
)
18100 for (i
= 0; EH_RETURN_DATA_REGNO (i
) != INVALID_REGNUM
; ++i
)
18103 /* SPE saves EH registers in 64-bits. */
18104 ehrd_size
= i
* (TARGET_SPE_ABI
18105 && info_ptr
->spe_64bit_regs_used
!= 0
18106 ? UNITS_PER_SPE_WORD
: UNITS_PER_WORD
);
18111 /* Determine various sizes. */
18112 info_ptr
->reg_size
= reg_size
;
18113 info_ptr
->fixed_size
= RS6000_SAVE_AREA
;
18114 info_ptr
->vars_size
= RS6000_ALIGN (get_frame_size (), 8);
18115 info_ptr
->parm_size
= RS6000_ALIGN (crtl
->outgoing_args_size
,
18116 TARGET_ALTIVEC
? 16 : 8);
18117 if (FRAME_GROWS_DOWNWARD
)
18118 info_ptr
->vars_size
18119 += RS6000_ALIGN (info_ptr
->fixed_size
+ info_ptr
->vars_size
18120 + info_ptr
->parm_size
,
18121 ABI_STACK_BOUNDARY
/ BITS_PER_UNIT
)
18122 - (info_ptr
->fixed_size
+ info_ptr
->vars_size
18123 + info_ptr
->parm_size
);
18125 if (TARGET_SPE_ABI
&& info_ptr
->spe_64bit_regs_used
!= 0)
18126 info_ptr
->spe_gp_size
= 8 * (32 - first_gp
);
18128 info_ptr
->spe_gp_size
= 0;
18130 if (TARGET_ALTIVEC_ABI
)
18131 info_ptr
->vrsave_mask
= compute_vrsave_mask ();
18133 info_ptr
->vrsave_mask
= 0;
18135 if (TARGET_ALTIVEC_VRSAVE
&& info_ptr
->vrsave_mask
)
18136 info_ptr
->vrsave_size
= 4;
18138 info_ptr
->vrsave_size
= 0;
18140 compute_save_world_info (info_ptr
);
18142 /* Calculate the offsets. */
18143 switch (DEFAULT_ABI
)
18147 gcc_unreachable ();
18151 info_ptr
->fp_save_offset
= - info_ptr
->fp_size
;
18152 info_ptr
->gp_save_offset
= info_ptr
->fp_save_offset
- info_ptr
->gp_size
;
18154 if (TARGET_ALTIVEC_ABI
)
18156 info_ptr
->vrsave_save_offset
18157 = info_ptr
->gp_save_offset
- info_ptr
->vrsave_size
;
18159 /* Align stack so vector save area is on a quadword boundary.
18160 The padding goes above the vectors. */
18161 if (info_ptr
->altivec_size
!= 0)
18162 info_ptr
->altivec_padding_size
18163 = info_ptr
->vrsave_save_offset
& 0xF;
18165 info_ptr
->altivec_padding_size
= 0;
18167 info_ptr
->altivec_save_offset
18168 = info_ptr
->vrsave_save_offset
18169 - info_ptr
->altivec_padding_size
18170 - info_ptr
->altivec_size
;
18171 gcc_assert (info_ptr
->altivec_size
== 0
18172 || info_ptr
->altivec_save_offset
% 16 == 0);
18174 /* Adjust for AltiVec case. */
18175 info_ptr
->ehrd_offset
= info_ptr
->altivec_save_offset
- ehrd_size
;
18178 info_ptr
->ehrd_offset
= info_ptr
->gp_save_offset
- ehrd_size
;
18179 info_ptr
->cr_save_offset
= reg_size
; /* first word when 64-bit. */
18180 info_ptr
->lr_save_offset
= 2*reg_size
;
18184 info_ptr
->fp_save_offset
= - info_ptr
->fp_size
;
18185 info_ptr
->gp_save_offset
= info_ptr
->fp_save_offset
- info_ptr
->gp_size
;
18186 info_ptr
->cr_save_offset
= info_ptr
->gp_save_offset
- info_ptr
->cr_size
;
18188 if (TARGET_SPE_ABI
&& info_ptr
->spe_64bit_regs_used
!= 0)
18190 /* Align stack so SPE GPR save area is aligned on a
18191 double-word boundary. */
18192 if (info_ptr
->spe_gp_size
!= 0 && info_ptr
->cr_save_offset
!= 0)
18193 info_ptr
->spe_padding_size
18194 = 8 - (-info_ptr
->cr_save_offset
% 8);
18196 info_ptr
->spe_padding_size
= 0;
18198 info_ptr
->spe_gp_save_offset
18199 = info_ptr
->cr_save_offset
18200 - info_ptr
->spe_padding_size
18201 - info_ptr
->spe_gp_size
;
18203 /* Adjust for SPE case. */
18204 info_ptr
->ehrd_offset
= info_ptr
->spe_gp_save_offset
;
18206 else if (TARGET_ALTIVEC_ABI
)
18208 info_ptr
->vrsave_save_offset
18209 = info_ptr
->cr_save_offset
- info_ptr
->vrsave_size
;
18211 /* Align stack so vector save area is on a quadword boundary. */
18212 if (info_ptr
->altivec_size
!= 0)
18213 info_ptr
->altivec_padding_size
18214 = 16 - (-info_ptr
->vrsave_save_offset
% 16);
18216 info_ptr
->altivec_padding_size
= 0;
18218 info_ptr
->altivec_save_offset
18219 = info_ptr
->vrsave_save_offset
18220 - info_ptr
->altivec_padding_size
18221 - info_ptr
->altivec_size
;
18223 /* Adjust for AltiVec case. */
18224 info_ptr
->ehrd_offset
= info_ptr
->altivec_save_offset
;
18227 info_ptr
->ehrd_offset
= info_ptr
->cr_save_offset
;
18228 info_ptr
->ehrd_offset
-= ehrd_size
;
18229 info_ptr
->lr_save_offset
= reg_size
;
18233 save_align
= (TARGET_ALTIVEC_ABI
|| DEFAULT_ABI
== ABI_DARWIN
) ? 16 : 8;
18234 info_ptr
->save_size
= RS6000_ALIGN (info_ptr
->fp_size
18235 + info_ptr
->gp_size
18236 + info_ptr
->altivec_size
18237 + info_ptr
->altivec_padding_size
18238 + info_ptr
->spe_gp_size
18239 + info_ptr
->spe_padding_size
18241 + info_ptr
->cr_size
18242 + info_ptr
->vrsave_size
,
18245 non_fixed_size
= (info_ptr
->vars_size
18246 + info_ptr
->parm_size
18247 + info_ptr
->save_size
);
18249 info_ptr
->total_size
= RS6000_ALIGN (non_fixed_size
+ info_ptr
->fixed_size
,
18250 ABI_STACK_BOUNDARY
/ BITS_PER_UNIT
);
18252 /* Determine if we need to allocate any stack frame:
18254 For AIX we need to push the stack if a frame pointer is needed
18255 (because the stack might be dynamically adjusted), if we are
18256 debugging, if we make calls, or if the sum of fp_save, gp_save,
18257 and local variables are more than the space needed to save all
18258 non-volatile registers: 32-bit: 18*8 + 19*4 = 220 or 64-bit: 18*8
18259 + 18*8 = 288 (GPR13 reserved).
18261 For V.4 we don't have the stack cushion that AIX uses, but assume
18262 that the debugger can handle stackless frames. */
18264 if (info_ptr
->calls_p
)
18265 info_ptr
->push_p
= 1;
18267 else if (DEFAULT_ABI
== ABI_V4
)
18268 info_ptr
->push_p
= non_fixed_size
!= 0;
18270 else if (frame_pointer_needed
)
18271 info_ptr
->push_p
= 1;
18273 else if (TARGET_XCOFF
&& write_symbols
!= NO_DEBUG
)
18274 info_ptr
->push_p
= 1;
18277 info_ptr
->push_p
= non_fixed_size
> (TARGET_32BIT
? 220 : 288);
18279 /* Zero offsets if we're not saving those registers. */
18280 if (info_ptr
->fp_size
== 0)
18281 info_ptr
->fp_save_offset
= 0;
18283 if (info_ptr
->gp_size
== 0)
18284 info_ptr
->gp_save_offset
= 0;
18286 if (! TARGET_ALTIVEC_ABI
|| info_ptr
->altivec_size
== 0)
18287 info_ptr
->altivec_save_offset
= 0;
18289 if (! TARGET_ALTIVEC_ABI
|| info_ptr
->vrsave_mask
== 0)
18290 info_ptr
->vrsave_save_offset
= 0;
18292 if (! TARGET_SPE_ABI
18293 || info_ptr
->spe_64bit_regs_used
== 0
18294 || info_ptr
->spe_gp_size
== 0)
18295 info_ptr
->spe_gp_save_offset
= 0;
18297 if (! info_ptr
->lr_save_p
)
18298 info_ptr
->lr_save_offset
= 0;
18300 if (! info_ptr
->cr_save_p
)
18301 info_ptr
->cr_save_offset
= 0;
18306 /* Return true if the current function uses any GPRs in 64-bit SIMD
18310 spe_func_has_64bit_regs_p (void)
18314 /* Functions that save and restore all the call-saved registers will
18315 need to save/restore the registers in 64-bits. */
18316 if (crtl
->calls_eh_return
18317 || cfun
->calls_setjmp
18318 || crtl
->has_nonlocal_goto
)
18321 insns
= get_insns ();
18323 for (insn
= NEXT_INSN (insns
); insn
!= NULL_RTX
; insn
= NEXT_INSN (insn
))
18329 /* FIXME: This should be implemented with attributes...
18331 (set_attr "spe64" "true")....then,
18332 if (get_spe64(insn)) return true;
18334 It's the only reliable way to do the stuff below. */
18336 i
= PATTERN (insn
);
18337 if (GET_CODE (i
) == SET
)
18339 enum machine_mode mode
= GET_MODE (SET_SRC (i
));
18341 if (SPE_VECTOR_MODE (mode
))
18343 if (TARGET_E500_DOUBLE
&& (mode
== DFmode
|| mode
== TFmode
))
18353 debug_stack_info (rs6000_stack_t
*info
)
18355 const char *abi_string
;
18358 info
= rs6000_stack_info ();
18360 fprintf (stderr
, "\nStack information for function %s:\n",
18361 ((current_function_decl
&& DECL_NAME (current_function_decl
))
18362 ? IDENTIFIER_POINTER (DECL_NAME (current_function_decl
))
18367 default: abi_string
= "Unknown"; break;
18368 case ABI_NONE
: abi_string
= "NONE"; break;
18369 case ABI_AIX
: abi_string
= "AIX"; break;
18370 case ABI_DARWIN
: abi_string
= "Darwin"; break;
18371 case ABI_V4
: abi_string
= "V.4"; break;
18374 fprintf (stderr
, "\tABI = %5s\n", abi_string
);
18376 if (TARGET_ALTIVEC_ABI
)
18377 fprintf (stderr
, "\tALTIVEC ABI extensions enabled.\n");
18379 if (TARGET_SPE_ABI
)
18380 fprintf (stderr
, "\tSPE ABI extensions enabled.\n");
18382 if (info
->first_gp_reg_save
!= 32)
18383 fprintf (stderr
, "\tfirst_gp_reg_save = %5d\n", info
->first_gp_reg_save
);
18385 if (info
->first_fp_reg_save
!= 64)
18386 fprintf (stderr
, "\tfirst_fp_reg_save = %5d\n", info
->first_fp_reg_save
);
18388 if (info
->first_altivec_reg_save
<= LAST_ALTIVEC_REGNO
)
18389 fprintf (stderr
, "\tfirst_altivec_reg_save = %5d\n",
18390 info
->first_altivec_reg_save
);
18392 if (info
->lr_save_p
)
18393 fprintf (stderr
, "\tlr_save_p = %5d\n", info
->lr_save_p
);
18395 if (info
->cr_save_p
)
18396 fprintf (stderr
, "\tcr_save_p = %5d\n", info
->cr_save_p
);
18398 if (info
->vrsave_mask
)
18399 fprintf (stderr
, "\tvrsave_mask = 0x%x\n", info
->vrsave_mask
);
18402 fprintf (stderr
, "\tpush_p = %5d\n", info
->push_p
);
18405 fprintf (stderr
, "\tcalls_p = %5d\n", info
->calls_p
);
18407 if (info
->gp_save_offset
)
18408 fprintf (stderr
, "\tgp_save_offset = %5d\n", info
->gp_save_offset
);
18410 if (info
->fp_save_offset
)
18411 fprintf (stderr
, "\tfp_save_offset = %5d\n", info
->fp_save_offset
);
18413 if (info
->altivec_save_offset
)
18414 fprintf (stderr
, "\taltivec_save_offset = %5d\n",
18415 info
->altivec_save_offset
);
18417 if (info
->spe_gp_save_offset
)
18418 fprintf (stderr
, "\tspe_gp_save_offset = %5d\n",
18419 info
->spe_gp_save_offset
);
18421 if (info
->vrsave_save_offset
)
18422 fprintf (stderr
, "\tvrsave_save_offset = %5d\n",
18423 info
->vrsave_save_offset
);
18425 if (info
->lr_save_offset
)
18426 fprintf (stderr
, "\tlr_save_offset = %5d\n", info
->lr_save_offset
);
18428 if (info
->cr_save_offset
)
18429 fprintf (stderr
, "\tcr_save_offset = %5d\n", info
->cr_save_offset
);
18431 if (info
->varargs_save_offset
)
18432 fprintf (stderr
, "\tvarargs_save_offset = %5d\n", info
->varargs_save_offset
);
18434 if (info
->total_size
)
18435 fprintf (stderr
, "\ttotal_size = "HOST_WIDE_INT_PRINT_DEC
"\n",
18438 if (info
->vars_size
)
18439 fprintf (stderr
, "\tvars_size = "HOST_WIDE_INT_PRINT_DEC
"\n",
18442 if (info
->parm_size
)
18443 fprintf (stderr
, "\tparm_size = %5d\n", info
->parm_size
);
18445 if (info
->fixed_size
)
18446 fprintf (stderr
, "\tfixed_size = %5d\n", info
->fixed_size
);
18449 fprintf (stderr
, "\tgp_size = %5d\n", info
->gp_size
);
18451 if (info
->spe_gp_size
)
18452 fprintf (stderr
, "\tspe_gp_size = %5d\n", info
->spe_gp_size
);
18455 fprintf (stderr
, "\tfp_size = %5d\n", info
->fp_size
);
18457 if (info
->altivec_size
)
18458 fprintf (stderr
, "\taltivec_size = %5d\n", info
->altivec_size
);
18460 if (info
->vrsave_size
)
18461 fprintf (stderr
, "\tvrsave_size = %5d\n", info
->vrsave_size
);
18463 if (info
->altivec_padding_size
)
18464 fprintf (stderr
, "\taltivec_padding_size= %5d\n",
18465 info
->altivec_padding_size
);
18467 if (info
->spe_padding_size
)
18468 fprintf (stderr
, "\tspe_padding_size = %5d\n",
18469 info
->spe_padding_size
);
18472 fprintf (stderr
, "\tcr_size = %5d\n", info
->cr_size
);
18474 if (info
->save_size
)
18475 fprintf (stderr
, "\tsave_size = %5d\n", info
->save_size
);
18477 if (info
->reg_size
!= 4)
18478 fprintf (stderr
, "\treg_size = %5d\n", info
->reg_size
);
18480 fprintf (stderr
, "\n");
18484 rs6000_return_addr (int count
, rtx frame
)
18486 /* Currently we don't optimize very well between prolog and body
18487 code and for PIC code the code can be actually quite bad, so
18488 don't try to be too clever here. */
18489 if (count
!= 0 || (DEFAULT_ABI
!= ABI_AIX
&& flag_pic
))
18491 cfun
->machine
->ra_needs_full_frame
= 1;
18498 plus_constant (copy_to_reg
18499 (gen_rtx_MEM (Pmode
,
18500 memory_address (Pmode
, frame
))),
18501 RETURN_ADDRESS_OFFSET
)));
18504 cfun
->machine
->ra_need_lr
= 1;
18505 return get_hard_reg_initial_val (Pmode
, LR_REGNO
);
18508 /* Say whether a function is a candidate for sibcall handling or not.
18509 We do not allow indirect calls to be optimized into sibling calls.
18510 Also, we can't do it if there are any vector parameters; there's
18511 nowhere to put the VRsave code so it works; note that functions with
18512 vector parameters are required to have a prototype, so the argument
18513 type info must be available here. (The tail recursion case can work
18514 with vector parameters, but there's no way to distinguish here.) */
18516 rs6000_function_ok_for_sibcall (tree decl
, tree exp ATTRIBUTE_UNUSED
)
18521 if (TARGET_ALTIVEC_VRSAVE
)
18523 for (type
= TYPE_ARG_TYPES (TREE_TYPE (decl
));
18524 type
; type
= TREE_CHAIN (type
))
18526 if (TREE_CODE (TREE_VALUE (type
)) == VECTOR_TYPE
)
18530 if (DEFAULT_ABI
== ABI_DARWIN
18531 || ((*targetm
.binds_local_p
) (decl
)
18532 && (DEFAULT_ABI
!= ABI_AIX
|| !DECL_EXTERNAL (decl
))))
18534 tree attr_list
= TYPE_ATTRIBUTES (TREE_TYPE (decl
));
18536 if (!lookup_attribute ("longcall", attr_list
)
18537 || lookup_attribute ("shortcall", attr_list
))
18544 /* NULL if INSN insn is valid within a low-overhead loop.
18545 Otherwise return why doloop cannot be applied.
18546 PowerPC uses the COUNT register for branch on table instructions. */
18548 static const char *
18549 rs6000_invalid_within_doloop (const_rtx insn
)
18552 return "Function call in the loop.";
18555 && (GET_CODE (PATTERN (insn
)) == ADDR_DIFF_VEC
18556 || GET_CODE (PATTERN (insn
)) == ADDR_VEC
))
18557 return "Computed branch in the loop.";
18563 rs6000_ra_ever_killed (void)
18569 if (cfun
->is_thunk
)
18572 if (cfun
->machine
->lr_save_state
)
18573 return cfun
->machine
->lr_save_state
- 1;
18575 /* regs_ever_live has LR marked as used if any sibcalls are present,
18576 but this should not force saving and restoring in the
18577 pro/epilogue. Likewise, reg_set_between_p thinks a sibcall
18578 clobbers LR, so that is inappropriate. */
18580 /* Also, the prologue can generate a store into LR that
18581 doesn't really count, like this:
18584 bcl to set PIC register
18588 When we're called from the epilogue, we need to avoid counting
18589 this as a store. */
18591 push_topmost_sequence ();
18592 top
= get_insns ();
18593 pop_topmost_sequence ();
18594 reg
= gen_rtx_REG (Pmode
, LR_REGNO
);
18596 for (insn
= NEXT_INSN (top
); insn
!= NULL_RTX
; insn
= NEXT_INSN (insn
))
18602 if (!SIBLING_CALL_P (insn
))
18605 else if (find_regno_note (insn
, REG_INC
, LR_REGNO
))
18607 else if (set_of (reg
, insn
) != NULL_RTX
18608 && !prologue_epilogue_contains (insn
))
18615 /* Emit instructions needed to load the TOC register.
18616 This is only needed when TARGET_TOC, TARGET_MINIMAL_TOC, and there is
18617 a constant pool; or for SVR4 -fpic. */
18620 rs6000_emit_load_toc_table (int fromprolog
)
18623 dest
= gen_rtx_REG (Pmode
, RS6000_PIC_OFFSET_TABLE_REGNUM
);
18625 if (TARGET_ELF
&& TARGET_SECURE_PLT
&& DEFAULT_ABI
!= ABI_AIX
&& flag_pic
)
18628 rtx lab
, tmp1
, tmp2
, got
;
18630 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCF", rs6000_pic_labelno
);
18631 lab
= gen_rtx_SYMBOL_REF (Pmode
, ggc_strdup (buf
));
18633 got
= gen_rtx_SYMBOL_REF (Pmode
, toc_label_name
);
18635 got
= rs6000_got_sym ();
18636 tmp1
= tmp2
= dest
;
18639 tmp1
= gen_reg_rtx (Pmode
);
18640 tmp2
= gen_reg_rtx (Pmode
);
18642 emit_insn (gen_load_toc_v4_PIC_1 (lab
));
18643 emit_move_insn (tmp1
,
18644 gen_rtx_REG (Pmode
, LR_REGNO
));
18645 emit_insn (gen_load_toc_v4_PIC_3b (tmp2
, tmp1
, got
, lab
));
18646 emit_insn (gen_load_toc_v4_PIC_3c (dest
, tmp2
, got
, lab
));
18648 else if (TARGET_ELF
&& DEFAULT_ABI
== ABI_V4
&& flag_pic
== 1)
18650 emit_insn (gen_load_toc_v4_pic_si ());
18651 emit_move_insn (dest
, gen_rtx_REG (Pmode
, LR_REGNO
));
18653 else if (TARGET_ELF
&& DEFAULT_ABI
!= ABI_AIX
&& flag_pic
== 2)
18656 rtx temp0
= (fromprolog
18657 ? gen_rtx_REG (Pmode
, 0)
18658 : gen_reg_rtx (Pmode
));
18664 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCF", rs6000_pic_labelno
);
18665 symF
= gen_rtx_SYMBOL_REF (Pmode
, ggc_strdup (buf
));
18667 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCL", rs6000_pic_labelno
);
18668 symL
= gen_rtx_SYMBOL_REF (Pmode
, ggc_strdup (buf
));
18670 emit_insn (gen_load_toc_v4_PIC_1 (symF
));
18671 emit_move_insn (dest
,
18672 gen_rtx_REG (Pmode
, LR_REGNO
));
18673 emit_insn (gen_load_toc_v4_PIC_2 (temp0
, dest
, symL
, symF
));
18679 tocsym
= gen_rtx_SYMBOL_REF (Pmode
, toc_label_name
);
18680 lab
= gen_label_rtx ();
18681 emit_insn (gen_load_toc_v4_PIC_1b (tocsym
, lab
));
18682 emit_move_insn (dest
, gen_rtx_REG (Pmode
, LR_REGNO
));
18683 emit_move_insn (temp0
, gen_rtx_MEM (Pmode
, dest
));
18685 emit_insn (gen_addsi3 (dest
, temp0
, dest
));
18687 else if (TARGET_ELF
&& !TARGET_AIX
&& flag_pic
== 0 && TARGET_MINIMAL_TOC
)
18689 /* This is for AIX code running in non-PIC ELF32. */
18692 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCTOC", 1);
18693 realsym
= gen_rtx_SYMBOL_REF (Pmode
, ggc_strdup (buf
));
18695 emit_insn (gen_elf_high (dest
, realsym
));
18696 emit_insn (gen_elf_low (dest
, dest
, realsym
));
18700 gcc_assert (DEFAULT_ABI
== ABI_AIX
);
18703 emit_insn (gen_load_toc_aix_si (dest
));
18705 emit_insn (gen_load_toc_aix_di (dest
));
18709 /* Emit instructions to restore the link register after determining where
18710 its value has been stored. */
18713 rs6000_emit_eh_reg_restore (rtx source
, rtx scratch
)
18715 rs6000_stack_t
*info
= rs6000_stack_info ();
18718 operands
[0] = source
;
18719 operands
[1] = scratch
;
18721 if (info
->lr_save_p
)
18723 rtx frame_rtx
= stack_pointer_rtx
;
18724 HOST_WIDE_INT sp_offset
= 0;
18727 if (frame_pointer_needed
18728 || cfun
->calls_alloca
18729 || info
->total_size
> 32767)
18731 tmp
= gen_frame_mem (Pmode
, frame_rtx
);
18732 emit_move_insn (operands
[1], tmp
);
18733 frame_rtx
= operands
[1];
18735 else if (info
->push_p
)
18736 sp_offset
= info
->total_size
;
18738 tmp
= plus_constant (frame_rtx
, info
->lr_save_offset
+ sp_offset
);
18739 tmp
= gen_frame_mem (Pmode
, tmp
);
18740 emit_move_insn (tmp
, operands
[0]);
18743 emit_move_insn (gen_rtx_REG (Pmode
, LR_REGNO
), operands
[0]);
18745 /* Freeze lr_save_p. We've just emitted rtl that depends on the
18746 state of lr_save_p so any change from here on would be a bug. In
18747 particular, stop rs6000_ra_ever_killed from considering the SET
18748 of lr we may have added just above. */
18749 cfun
->machine
->lr_save_state
= info
->lr_save_p
+ 1;
18752 static GTY(()) alias_set_type set
= -1;
18755 get_TOC_alias_set (void)
18758 set
= new_alias_set ();
18762 /* This returns nonzero if the current function uses the TOC. This is
18763 determined by the presence of (use (unspec ... UNSPEC_TOC)), which
18764 is generated by the ABI_V4 load_toc_* patterns. */
18771 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
18774 rtx pat
= PATTERN (insn
);
18777 if (GET_CODE (pat
) == PARALLEL
)
18778 for (i
= 0; i
< XVECLEN (pat
, 0); i
++)
18780 rtx sub
= XVECEXP (pat
, 0, i
);
18781 if (GET_CODE (sub
) == USE
)
18783 sub
= XEXP (sub
, 0);
18784 if (GET_CODE (sub
) == UNSPEC
18785 && XINT (sub
, 1) == UNSPEC_TOC
)
18795 create_TOC_reference (rtx symbol
, rtx largetoc_reg
)
18797 rtx tocrel
, tocreg
;
18799 if (TARGET_DEBUG_ADDR
)
18801 if (GET_CODE (symbol
) == SYMBOL_REF
)
18802 fprintf (stderr
, "\ncreate_TOC_reference, (symbol_ref %s)\n",
18806 fprintf (stderr
, "\ncreate_TOC_reference, code %s:\n",
18807 GET_RTX_NAME (GET_CODE (symbol
)));
18808 debug_rtx (symbol
);
18812 if (!can_create_pseudo_p ())
18813 df_set_regs_ever_live (TOC_REGISTER
, true);
18815 tocrel
= gen_rtx_CONST (Pmode
,
18816 gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, symbol
),
18818 tocreg
= gen_rtx_REG (Pmode
, TOC_REGISTER
);
18819 if (TARGET_CMODEL
!= CMODEL_SMALL
)
18821 rtx hi
= gen_rtx_PLUS (Pmode
, tocreg
, gen_rtx_HIGH (Pmode
, tocrel
));
18822 if (largetoc_reg
!= NULL
)
18824 emit_move_insn (largetoc_reg
, hi
);
18827 return gen_rtx_LO_SUM (Pmode
, hi
, copy_rtx (tocrel
));
18830 return gen_rtx_PLUS (Pmode
, tocreg
, tocrel
);
18833 /* Issue assembly directives that create a reference to the given DWARF
18834 FRAME_TABLE_LABEL from the current function section. */
18836 rs6000_aix_asm_output_dwarf_table_ref (char * frame_table_label
)
18838 fprintf (asm_out_file
, "\t.ref %s\n",
18839 TARGET_STRIP_NAME_ENCODING (frame_table_label
));
18842 /* If _Unwind_* has been called from within the same module,
18843 toc register is not guaranteed to be saved to 40(1) on function
18844 entry. Save it there in that case. */
18847 rs6000_aix_emit_builtin_unwind_init (void)
18850 rtx stack_top
= gen_reg_rtx (Pmode
);
18851 rtx opcode_addr
= gen_reg_rtx (Pmode
);
18852 rtx opcode
= gen_reg_rtx (SImode
);
18853 rtx tocompare
= gen_reg_rtx (SImode
);
18854 rtx no_toc_save_needed
= gen_label_rtx ();
18856 mem
= gen_frame_mem (Pmode
, hard_frame_pointer_rtx
);
18857 emit_move_insn (stack_top
, mem
);
18859 mem
= gen_frame_mem (Pmode
,
18860 gen_rtx_PLUS (Pmode
, stack_top
,
18861 GEN_INT (2 * GET_MODE_SIZE (Pmode
))));
18862 emit_move_insn (opcode_addr
, mem
);
18863 emit_move_insn (opcode
, gen_rtx_MEM (SImode
, opcode_addr
));
18864 emit_move_insn (tocompare
, gen_int_mode (TARGET_32BIT
? 0x80410014
18865 : 0xE8410028, SImode
));
18867 do_compare_rtx_and_jump (opcode
, tocompare
, EQ
, 1,
18868 SImode
, NULL_RTX
, NULL_RTX
,
18869 no_toc_save_needed
, -1);
18871 mem
= gen_frame_mem (Pmode
,
18872 gen_rtx_PLUS (Pmode
, stack_top
,
18873 GEN_INT (5 * GET_MODE_SIZE (Pmode
))));
18874 emit_move_insn (mem
, gen_rtx_REG (Pmode
, 2));
18875 emit_label (no_toc_save_needed
);
18878 /* This ties together stack memory (MEM with an alias set of frame_alias_set)
18879 and the change to the stack pointer. */
18882 rs6000_emit_stack_tie (void)
18884 rtx mem
= gen_frame_mem (BLKmode
,
18885 gen_rtx_REG (Pmode
, STACK_POINTER_REGNUM
));
18887 emit_insn (gen_stack_tie (mem
));
18890 /* Emit the correct code for allocating stack space, as insns.
18891 If COPY_REG, make sure a copy of the old frame is left there.
18892 The generated code may use hard register 0 as a temporary. */
18895 rs6000_emit_allocate_stack (HOST_WIDE_INT size
, rtx copy_reg
)
18898 rtx stack_reg
= gen_rtx_REG (Pmode
, STACK_POINTER_REGNUM
);
18899 rtx tmp_reg
= gen_rtx_REG (Pmode
, 0);
18900 rtx todec
= gen_int_mode (-size
, Pmode
);
18903 if (INTVAL (todec
) != -size
)
18905 warning (0, "stack frame too large");
18906 emit_insn (gen_trap ());
18910 if (crtl
->limit_stack
)
18912 if (REG_P (stack_limit_rtx
)
18913 && REGNO (stack_limit_rtx
) > 1
18914 && REGNO (stack_limit_rtx
) <= 31)
18916 emit_insn (gen_add3_insn (tmp_reg
, stack_limit_rtx
, GEN_INT (size
)));
18917 emit_insn (gen_cond_trap (LTU
, stack_reg
, tmp_reg
,
18920 else if (GET_CODE (stack_limit_rtx
) == SYMBOL_REF
18922 && DEFAULT_ABI
== ABI_V4
)
18924 rtx toload
= gen_rtx_CONST (VOIDmode
,
18925 gen_rtx_PLUS (Pmode
,
18929 emit_insn (gen_elf_high (tmp_reg
, toload
));
18930 emit_insn (gen_elf_low (tmp_reg
, tmp_reg
, toload
));
18931 emit_insn (gen_cond_trap (LTU
, stack_reg
, tmp_reg
,
18935 warning (0, "stack limit expression is not supported");
18939 emit_move_insn (copy_reg
, stack_reg
);
18943 /* Need a note here so that try_split doesn't get confused. */
18944 if (get_last_insn () == NULL_RTX
)
18945 emit_note (NOTE_INSN_DELETED
);
18946 insn
= emit_move_insn (tmp_reg
, todec
);
18947 try_split (PATTERN (insn
), insn
, 0);
18951 insn
= emit_insn (TARGET_32BIT
18952 ? gen_movsi_update_stack (stack_reg
, stack_reg
,
18954 : gen_movdi_di_update_stack (stack_reg
, stack_reg
,
18955 todec
, stack_reg
));
18956 /* Since we didn't use gen_frame_mem to generate the MEM, grab
18957 it now and set the alias set/attributes. The above gen_*_update
18958 calls will generate a PARALLEL with the MEM set being the first
18960 par
= PATTERN (insn
);
18961 gcc_assert (GET_CODE (par
) == PARALLEL
);
18962 set
= XVECEXP (par
, 0, 0);
18963 gcc_assert (GET_CODE (set
) == SET
);
18964 mem
= SET_DEST (set
);
18965 gcc_assert (MEM_P (mem
));
18966 MEM_NOTRAP_P (mem
) = 1;
18967 set_mem_alias_set (mem
, get_frame_alias_set ());
18969 RTX_FRAME_RELATED_P (insn
) = 1;
18970 add_reg_note (insn
, REG_FRAME_RELATED_EXPR
,
18971 gen_rtx_SET (VOIDmode
, stack_reg
,
18972 gen_rtx_PLUS (Pmode
, stack_reg
,
18973 GEN_INT (-size
))));
18976 #define PROBE_INTERVAL (1 << STACK_CHECK_PROBE_INTERVAL_EXP)
18978 #if PROBE_INTERVAL > 32768
18979 #error Cannot use indexed addressing mode for stack probing
18982 /* Emit code to probe a range of stack addresses from FIRST to FIRST+SIZE,
18983 inclusive. These are offsets from the current stack pointer. */
18986 rs6000_emit_probe_stack_range (HOST_WIDE_INT first
, HOST_WIDE_INT size
)
18988 /* See if we have a constant small number of probes to generate. If so,
18989 that's the easy case. */
18990 if (first
+ size
<= 32768)
18994 /* Probe at FIRST + N * PROBE_INTERVAL for values of N from 1 until
18995 it exceeds SIZE. If only one probe is needed, this will not
18996 generate any code. Then probe at FIRST + SIZE. */
18997 for (i
= PROBE_INTERVAL
; i
< size
; i
+= PROBE_INTERVAL
)
18998 emit_stack_probe (plus_constant (stack_pointer_rtx
, -(first
+ i
)));
19000 emit_stack_probe (plus_constant (stack_pointer_rtx
, -(first
+ size
)));
19003 /* Otherwise, do the same as above, but in a loop. Note that we must be
19004 extra careful with variables wrapping around because we might be at
19005 the very top (or the very bottom) of the address space and we have
19006 to be able to handle this case properly; in particular, we use an
19007 equality test for the loop condition. */
19010 HOST_WIDE_INT rounded_size
;
19011 rtx r12
= gen_rtx_REG (Pmode
, 12);
19012 rtx r0
= gen_rtx_REG (Pmode
, 0);
19014 /* Sanity check for the addressing mode we're going to use. */
19015 gcc_assert (first
<= 32768);
19017 /* Step 1: round SIZE to the previous multiple of the interval. */
19019 rounded_size
= size
& -PROBE_INTERVAL
;
19022 /* Step 2: compute initial and final value of the loop counter. */
19024 /* TEST_ADDR = SP + FIRST. */
19025 emit_insn (gen_rtx_SET (VOIDmode
, r12
,
19026 plus_constant (stack_pointer_rtx
, -first
)));
19028 /* LAST_ADDR = SP + FIRST + ROUNDED_SIZE. */
19029 if (rounded_size
> 32768)
19031 emit_move_insn (r0
, GEN_INT (-rounded_size
));
19032 emit_insn (gen_rtx_SET (VOIDmode
, r0
,
19033 gen_rtx_PLUS (Pmode
, r12
, r0
)));
19036 emit_insn (gen_rtx_SET (VOIDmode
, r0
,
19037 plus_constant (r12
, -rounded_size
)));
19040 /* Step 3: the loop
19042 while (TEST_ADDR != LAST_ADDR)
19044 TEST_ADDR = TEST_ADDR + PROBE_INTERVAL
19048 probes at FIRST + N * PROBE_INTERVAL for values of N from 1
19049 until it is equal to ROUNDED_SIZE. */
19052 emit_insn (gen_probe_stack_rangedi (r12
, r12
, r0
));
19054 emit_insn (gen_probe_stack_rangesi (r12
, r12
, r0
));
19057 /* Step 4: probe at FIRST + SIZE if we cannot assert at compile-time
19058 that SIZE is equal to ROUNDED_SIZE. */
19060 if (size
!= rounded_size
)
19061 emit_stack_probe (plus_constant (r12
, rounded_size
- size
));
19065 /* Probe a range of stack addresses from REG1 to REG2 inclusive. These are
19066 absolute addresses. */
19069 output_probe_stack_range (rtx reg1
, rtx reg2
)
19071 static int labelno
= 0;
19072 char loop_lab
[32], end_lab
[32];
19075 ASM_GENERATE_INTERNAL_LABEL (loop_lab
, "LPSRL", labelno
);
19076 ASM_GENERATE_INTERNAL_LABEL (end_lab
, "LPSRE", labelno
++);
19078 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file
, loop_lab
);
19080 /* Jump to END_LAB if TEST_ADDR == LAST_ADDR. */
19084 output_asm_insn ("{cmp|cmpd} 0,%0,%1", xops
);
19086 output_asm_insn ("{cmp|cmpw} 0,%0,%1", xops
);
19088 fputs ("\tbeq 0,", asm_out_file
);
19089 assemble_name_raw (asm_out_file
, end_lab
);
19090 fputc ('\n', asm_out_file
);
19092 /* TEST_ADDR = TEST_ADDR + PROBE_INTERVAL. */
19093 xops
[1] = GEN_INT (-PROBE_INTERVAL
);
19094 output_asm_insn ("{cal %0,%1(%0)|addi %0,%0,%1}", xops
);
19096 /* Probe at TEST_ADDR and branch. */
19097 output_asm_insn ("{st|stw} 0,0(%0)", xops
);
19098 fprintf (asm_out_file
, "\tb ");
19099 assemble_name_raw (asm_out_file
, loop_lab
);
19100 fputc ('\n', asm_out_file
);
19102 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file
, end_lab
);
19107 /* Add to 'insn' a note which is PATTERN (INSN) but with REG replaced
19108 with (plus:P (reg 1) VAL), and with REG2 replaced with RREG if REG2
19109 is not NULL. It would be nice if dwarf2out_frame_debug_expr could
19110 deduce these equivalences by itself so it wasn't necessary to hold
19111 its hand so much. */
19114 rs6000_frame_related (rtx insn
, rtx reg
, HOST_WIDE_INT val
,
19115 rtx reg2
, rtx rreg
)
19119 /* copy_rtx will not make unique copies of registers, so we need to
19120 ensure we don't have unwanted sharing here. */
19122 reg
= gen_raw_REG (GET_MODE (reg
), REGNO (reg
));
19125 reg
= gen_raw_REG (GET_MODE (reg
), REGNO (reg
));
19127 real
= copy_rtx (PATTERN (insn
));
19129 if (reg2
!= NULL_RTX
)
19130 real
= replace_rtx (real
, reg2
, rreg
);
19132 real
= replace_rtx (real
, reg
,
19133 gen_rtx_PLUS (Pmode
, gen_rtx_REG (Pmode
,
19134 STACK_POINTER_REGNUM
),
19137 /* We expect that 'real' is either a SET or a PARALLEL containing
19138 SETs (and possibly other stuff). In a PARALLEL, all the SETs
19139 are important so they all have to be marked RTX_FRAME_RELATED_P. */
19141 if (GET_CODE (real
) == SET
)
19145 temp
= simplify_rtx (SET_SRC (set
));
19147 SET_SRC (set
) = temp
;
19148 temp
= simplify_rtx (SET_DEST (set
));
19150 SET_DEST (set
) = temp
;
19151 if (GET_CODE (SET_DEST (set
)) == MEM
)
19153 temp
= simplify_rtx (XEXP (SET_DEST (set
), 0));
19155 XEXP (SET_DEST (set
), 0) = temp
;
19162 gcc_assert (GET_CODE (real
) == PARALLEL
);
19163 for (i
= 0; i
< XVECLEN (real
, 0); i
++)
19164 if (GET_CODE (XVECEXP (real
, 0, i
)) == SET
)
19166 rtx set
= XVECEXP (real
, 0, i
);
19168 temp
= simplify_rtx (SET_SRC (set
));
19170 SET_SRC (set
) = temp
;
19171 temp
= simplify_rtx (SET_DEST (set
));
19173 SET_DEST (set
) = temp
;
19174 if (GET_CODE (SET_DEST (set
)) == MEM
)
19176 temp
= simplify_rtx (XEXP (SET_DEST (set
), 0));
19178 XEXP (SET_DEST (set
), 0) = temp
;
19180 RTX_FRAME_RELATED_P (set
) = 1;
19184 RTX_FRAME_RELATED_P (insn
) = 1;
19185 add_reg_note (insn
, REG_FRAME_RELATED_EXPR
, real
);
19188 /* Returns an insn that has a vrsave set operation with the
19189 appropriate CLOBBERs. */
19192 generate_set_vrsave (rtx reg
, rs6000_stack_t
*info
, int epiloguep
)
19195 rtx insn
, clobs
[TOTAL_ALTIVEC_REGS
+ 1];
19196 rtx vrsave
= gen_rtx_REG (SImode
, VRSAVE_REGNO
);
19199 = gen_rtx_SET (VOIDmode
,
19201 gen_rtx_UNSPEC_VOLATILE (SImode
,
19202 gen_rtvec (2, reg
, vrsave
),
19203 UNSPECV_SET_VRSAVE
));
19207 /* We need to clobber the registers in the mask so the scheduler
19208 does not move sets to VRSAVE before sets of AltiVec registers.
19210 However, if the function receives nonlocal gotos, reload will set
19211 all call saved registers live. We will end up with:
19213 (set (reg 999) (mem))
19214 (parallel [ (set (reg vrsave) (unspec blah))
19215 (clobber (reg 999))])
19217 The clobber will cause the store into reg 999 to be dead, and
19218 flow will attempt to delete an epilogue insn. In this case, we
19219 need an unspec use/set of the register. */
19221 for (i
= FIRST_ALTIVEC_REGNO
; i
<= LAST_ALTIVEC_REGNO
; ++i
)
19222 if (info
->vrsave_mask
& ALTIVEC_REG_BIT (i
))
19224 if (!epiloguep
|| call_used_regs
[i
])
19225 clobs
[nclobs
++] = gen_rtx_CLOBBER (VOIDmode
,
19226 gen_rtx_REG (V4SImode
, i
));
19229 rtx reg
= gen_rtx_REG (V4SImode
, i
);
19232 = gen_rtx_SET (VOIDmode
,
19234 gen_rtx_UNSPEC (V4SImode
,
19235 gen_rtvec (1, reg
), 27));
19239 insn
= gen_rtx_PARALLEL (VOIDmode
, rtvec_alloc (nclobs
));
19241 for (i
= 0; i
< nclobs
; ++i
)
19242 XVECEXP (insn
, 0, i
) = clobs
[i
];
19247 /* Save a register into the frame, and emit RTX_FRAME_RELATED_P notes.
19248 Save REGNO into [FRAME_REG + OFFSET] in mode MODE. */
19251 emit_frame_save (rtx frame_reg
, rtx frame_ptr
, enum machine_mode mode
,
19252 unsigned int regno
, int offset
, HOST_WIDE_INT total_size
)
19254 rtx reg
, offset_rtx
, insn
, mem
, addr
, int_rtx
;
19255 rtx replacea
, replaceb
;
19257 int_rtx
= GEN_INT (offset
);
19259 /* Some cases that need register indexed addressing. */
19260 if ((TARGET_ALTIVEC_ABI
&& ALTIVEC_VECTOR_MODE (mode
))
19261 || (TARGET_VSX
&& VSX_VECTOR_MODE (mode
))
19262 || (TARGET_E500_DOUBLE
&& mode
== DFmode
)
19264 && SPE_VECTOR_MODE (mode
)
19265 && !SPE_CONST_OFFSET_OK (offset
)))
19267 /* Whomever calls us must make sure r11 is available in the
19268 flow path of instructions in the prologue. */
19269 offset_rtx
= gen_rtx_REG (Pmode
, 11);
19270 emit_move_insn (offset_rtx
, int_rtx
);
19272 replacea
= offset_rtx
;
19273 replaceb
= int_rtx
;
19277 offset_rtx
= int_rtx
;
19278 replacea
= NULL_RTX
;
19279 replaceb
= NULL_RTX
;
19282 reg
= gen_rtx_REG (mode
, regno
);
19283 addr
= gen_rtx_PLUS (Pmode
, frame_reg
, offset_rtx
);
19284 mem
= gen_frame_mem (mode
, addr
);
19286 insn
= emit_move_insn (mem
, reg
);
19288 rs6000_frame_related (insn
, frame_ptr
, total_size
, replacea
, replaceb
);
19291 /* Emit an offset memory reference suitable for a frame store, while
19292 converting to a valid addressing mode. */
19295 gen_frame_mem_offset (enum machine_mode mode
, rtx reg
, int offset
)
19297 rtx int_rtx
, offset_rtx
;
19299 int_rtx
= GEN_INT (offset
);
19301 if ((TARGET_SPE_ABI
&& SPE_VECTOR_MODE (mode
))
19302 || (TARGET_E500_DOUBLE
&& mode
== DFmode
))
19304 offset_rtx
= gen_rtx_REG (Pmode
, FIXED_SCRATCH
);
19305 emit_move_insn (offset_rtx
, int_rtx
);
19308 offset_rtx
= int_rtx
;
19310 return gen_frame_mem (mode
, gen_rtx_PLUS (Pmode
, reg
, offset_rtx
));
19313 /* Look for user-defined global regs. We should not save and restore these,
19314 and cannot use stmw/lmw if there are any in its range. */
19317 no_global_regs_above (int first
, bool gpr
)
19320 int last
= gpr
? 32 : 64;
19321 for (i
= first
; i
< last
; i
++)
19322 if (global_regs
[i
])
19327 #ifndef TARGET_FIX_AND_CONTINUE
19328 #define TARGET_FIX_AND_CONTINUE 0
19331 /* It's really GPR 13 and FPR 14, but we need the smaller of the two. */
19332 #define FIRST_SAVRES_REGISTER FIRST_SAVED_GP_REGNO
19333 #define LAST_SAVRES_REGISTER 31
19334 #define N_SAVRES_REGISTERS (LAST_SAVRES_REGISTER - FIRST_SAVRES_REGISTER + 1)
19336 static GTY(()) rtx savres_routine_syms
[N_SAVRES_REGISTERS
][8];
19338 /* Temporary holding space for an out-of-line register save/restore
19340 static char savres_routine_name
[30];
19342 /* Return the name for an out-of-line register save/restore routine.
19343 We are saving/restoring GPRs if GPR is true. */
19346 rs6000_savres_routine_name (rs6000_stack_t
*info
, int regno
,
19347 bool savep
, bool gpr
, bool lr
)
19349 const char *prefix
= "";
19350 const char *suffix
= "";
19352 /* Different targets are supposed to define
19353 {SAVE,RESTORE}_FP_{PREFIX,SUFFIX} with the idea that the needed
19354 routine name could be defined with:
19356 sprintf (name, "%s%d%s", SAVE_FP_PREFIX, regno, SAVE_FP_SUFFIX)
19358 This is a nice idea in practice, but in reality, things are
19359 complicated in several ways:
19361 - ELF targets have save/restore routines for GPRs.
19363 - SPE targets use different prefixes for 32/64-bit registers, and
19364 neither of them fit neatly in the FOO_{PREFIX,SUFFIX} regimen.
19366 - PPC64 ELF targets have routines for save/restore of GPRs that
19367 differ in what they do with the link register, so having a set
19368 prefix doesn't work. (We only use one of the save routines at
19369 the moment, though.)
19371 - PPC32 elf targets have "exit" versions of the restore routines
19372 that restore the link register and can save some extra space.
19373 These require an extra suffix. (There are also "tail" versions
19374 of the restore routines and "GOT" versions of the save routines,
19375 but we don't generate those at present. Same problems apply,
19378 We deal with all this by synthesizing our own prefix/suffix and
19379 using that for the simple sprintf call shown above. */
19382 /* No floating point saves on the SPE. */
19386 prefix
= info
->spe_64bit_regs_used
? "_save64gpr_" : "_save32gpr_";
19388 prefix
= info
->spe_64bit_regs_used
? "_rest64gpr_" : "_rest32gpr_";
19393 else if (DEFAULT_ABI
== ABI_V4
)
19399 prefix
= savep
? "_savegpr_" : "_restgpr_";
19401 prefix
= savep
? "_savefpr_" : "_restfpr_";
19406 else if (DEFAULT_ABI
== ABI_AIX
)
19408 #ifndef POWERPC_LINUX
19409 /* No out-of-line save/restore routines for GPRs on AIX. */
19410 gcc_assert (!TARGET_AIX
|| !gpr
);
19416 ? (lr
? "_savegpr0_" : "_savegpr1_")
19417 : (lr
? "_restgpr0_" : "_restgpr1_"));
19418 #ifdef POWERPC_LINUX
19420 prefix
= (savep
? "_savefpr_" : "_restfpr_");
19424 prefix
= savep
? SAVE_FP_PREFIX
: RESTORE_FP_PREFIX
;
19425 suffix
= savep
? SAVE_FP_SUFFIX
: RESTORE_FP_SUFFIX
;
19428 else if (DEFAULT_ABI
== ABI_DARWIN
)
19429 sorry ("Out-of-line save/restore routines not supported on Darwin");
19431 sprintf (savres_routine_name
, "%s%d%s", prefix
, regno
, suffix
);
19433 return savres_routine_name
;
19436 /* Return an RTL SYMBOL_REF for an out-of-line register save/restore routine.
19437 We are saving/restoring GPRs if GPR is true. */
19440 rs6000_savres_routine_sym (rs6000_stack_t
*info
, bool savep
,
19443 int regno
= gpr
? info
->first_gp_reg_save
: (info
->first_fp_reg_save
- 32);
19445 int select
= ((savep
? 1 : 0) << 2
19447 /* On the SPE, we never have any FPRs, but we do have
19448 32/64-bit versions of the routines. */
19449 ? (info
->spe_64bit_regs_used
? 1 : 0)
19450 : (gpr
? 1 : 0)) << 1)
19453 /* Don't generate bogus routine names. */
19454 gcc_assert (FIRST_SAVRES_REGISTER
<= regno
19455 && regno
<= LAST_SAVRES_REGISTER
);
19457 sym
= savres_routine_syms
[regno
-FIRST_SAVRES_REGISTER
][select
];
19463 name
= rs6000_savres_routine_name (info
, regno
, savep
, gpr
, lr
);
19465 sym
= savres_routine_syms
[regno
-FIRST_SAVRES_REGISTER
][select
]
19466 = gen_rtx_SYMBOL_REF (Pmode
, ggc_strdup (name
));
19467 SYMBOL_REF_FLAGS (sym
) |= SYMBOL_FLAG_FUNCTION
;
19473 /* Emit a sequence of insns, including a stack tie if needed, for
19474 resetting the stack pointer. If SAVRES is true, then don't reset the
19475 stack pointer, but move the base of the frame into r11 for use by
19476 out-of-line register restore routines. */
19479 rs6000_emit_stack_reset (rs6000_stack_t
*info
,
19480 rtx sp_reg_rtx
, rtx frame_reg_rtx
,
19481 int sp_offset
, bool savres
)
19483 /* This blockage is needed so that sched doesn't decide to move
19484 the sp change before the register restores. */
19485 if (frame_reg_rtx
!= sp_reg_rtx
19487 && info
->spe_64bit_regs_used
!= 0
19488 && info
->first_gp_reg_save
!= 32))
19489 rs6000_emit_stack_tie ();
19491 if (frame_reg_rtx
!= sp_reg_rtx
)
19493 if (sp_offset
!= 0)
19495 rtx dest_reg
= savres
? gen_rtx_REG (Pmode
, 11) : sp_reg_rtx
;
19496 return emit_insn (gen_add3_insn (dest_reg
, frame_reg_rtx
,
19497 GEN_INT (sp_offset
)));
19500 return emit_move_insn (sp_reg_rtx
, frame_reg_rtx
);
19502 else if (sp_offset
!= 0)
19504 /* If we are restoring registers out-of-line, we will be using the
19505 "exit" variants of the restore routines, which will reset the
19506 stack for us. But we do need to point r11 into the right place
19507 for those routines. */
19508 rtx dest_reg
= (savres
19509 ? gen_rtx_REG (Pmode
, 11)
19512 rtx insn
= emit_insn (gen_add3_insn (dest_reg
, sp_reg_rtx
,
19513 GEN_INT (sp_offset
)));
19520 /* Construct a parallel rtx describing the effect of a call to an
19521 out-of-line register save/restore routine. */
19524 rs6000_make_savres_rtx (rs6000_stack_t
*info
,
19525 rtx frame_reg_rtx
, int save_area_offset
,
19526 enum machine_mode reg_mode
,
19527 bool savep
, bool gpr
, bool lr
)
19530 int offset
, start_reg
, end_reg
, n_regs
;
19531 int reg_size
= GET_MODE_SIZE (reg_mode
);
19537 ? info
->first_gp_reg_save
19538 : info
->first_fp_reg_save
);
19539 end_reg
= gpr
? 32 : 64;
19540 n_regs
= end_reg
- start_reg
;
19541 p
= rtvec_alloc ((lr
? 4 : 3) + n_regs
);
19544 RTVEC_ELT (p
, offset
++) = gen_rtx_RETURN (VOIDmode
);
19546 RTVEC_ELT (p
, offset
++)
19547 = gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (Pmode
, 65));
19549 sym
= rs6000_savres_routine_sym (info
, savep
, gpr
, lr
);
19550 RTVEC_ELT (p
, offset
++) = gen_rtx_USE (VOIDmode
, sym
);
19551 RTVEC_ELT (p
, offset
++)
19552 = gen_rtx_USE (VOIDmode
,
19553 gen_rtx_REG (Pmode
, DEFAULT_ABI
!= ABI_AIX
? 11
19557 for (i
= 0; i
< end_reg
- start_reg
; i
++)
19559 rtx addr
, reg
, mem
;
19560 reg
= gen_rtx_REG (reg_mode
, start_reg
+ i
);
19561 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
19562 GEN_INT (save_area_offset
+ reg_size
*i
));
19563 mem
= gen_frame_mem (reg_mode
, addr
);
19565 RTVEC_ELT (p
, i
+ offset
) = gen_rtx_SET (VOIDmode
,
19567 savep
? reg
: mem
);
19572 rtx addr
, reg
, mem
;
19573 reg
= gen_rtx_REG (Pmode
, 0);
19574 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
19575 GEN_INT (info
->lr_save_offset
));
19576 mem
= gen_frame_mem (Pmode
, addr
);
19577 RTVEC_ELT (p
, i
+ offset
) = gen_rtx_SET (VOIDmode
, mem
, reg
);
19580 return gen_rtx_PARALLEL (VOIDmode
, p
);
19583 /* Determine whether the gp REG is really used. */
19586 rs6000_reg_live_or_pic_offset_p (int reg
)
19588 return ((df_regs_ever_live_p (reg
)
19589 && (!call_used_regs
[reg
]
19590 || (reg
== RS6000_PIC_OFFSET_TABLE_REGNUM
19591 && TARGET_TOC
&& TARGET_MINIMAL_TOC
)))
19592 || (reg
== RS6000_PIC_OFFSET_TABLE_REGNUM
19593 && ((DEFAULT_ABI
== ABI_V4
&& flag_pic
!= 0)
19594 || (DEFAULT_ABI
== ABI_DARWIN
&& flag_pic
))));
19598 SAVRES_MULTIPLE
= 0x1,
19599 SAVRES_INLINE_FPRS
= 0x2,
19600 SAVRES_INLINE_GPRS
= 0x4,
19601 SAVRES_NOINLINE_GPRS_SAVES_LR
= 0x8,
19602 SAVRES_NOINLINE_FPRS_SAVES_LR
= 0x10,
19603 SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR
= 0x20
19606 /* Determine the strategy for savings/restoring registers. */
19609 rs6000_savres_strategy (rs6000_stack_t
*info
, bool savep
,
19610 int using_static_chain_p
, int sibcall
)
19612 bool using_multiple_p
;
19614 bool savres_fprs_inline
;
19615 bool savres_gprs_inline
;
19616 bool noclobber_global_gprs
19617 = no_global_regs_above (info
->first_gp_reg_save
, /*gpr=*/true);
19620 using_multiple_p
= (TARGET_MULTIPLE
&& ! TARGET_POWERPC64
19621 && (!TARGET_SPE_ABI
19622 || info
->spe_64bit_regs_used
== 0)
19623 && info
->first_gp_reg_save
< 31
19624 && noclobber_global_gprs
);
19625 /* Don't bother to try to save things out-of-line if r11 is occupied
19626 by the static chain. It would require too much fiddling and the
19627 static chain is rarely used anyway. */
19628 common
= (using_static_chain_p
19630 || crtl
->calls_eh_return
19631 || !info
->lr_save_p
19632 || cfun
->machine
->ra_need_lr
19633 || info
->total_size
> 32767);
19634 savres_fprs_inline
= (common
19635 || info
->first_fp_reg_save
== 64
19636 || !no_global_regs_above (info
->first_fp_reg_save
,
19638 /* The out-of-line FP routines use
19639 double-precision stores; we can't use those
19640 routines if we don't have such stores. */
19641 || (TARGET_HARD_FLOAT
&& !TARGET_DOUBLE_FLOAT
)
19642 || FP_SAVE_INLINE (info
->first_fp_reg_save
));
19643 savres_gprs_inline
= (common
19644 /* Saving CR interferes with the exit routines
19645 used on the SPE, so just punt here. */
19648 && info
->spe_64bit_regs_used
!= 0
19649 && info
->cr_save_p
!= 0)
19650 || info
->first_gp_reg_save
== 32
19651 || !noclobber_global_gprs
19652 || GP_SAVE_INLINE (info
->first_gp_reg_save
));
19655 /* If we are going to use store multiple, then don't even bother
19656 with the out-of-line routines, since the store-multiple instruction
19657 will always be smaller. */
19658 savres_gprs_inline
= savres_gprs_inline
|| using_multiple_p
;
19661 /* The situation is more complicated with load multiple. We'd
19662 prefer to use the out-of-line routines for restores, since the
19663 "exit" out-of-line routines can handle the restore of LR and
19664 the frame teardown. But we can only use the out-of-line
19665 routines if we know that we've used store multiple or
19666 out-of-line routines in the prologue, i.e. if we've saved all
19667 the registers from first_gp_reg_save. Otherwise, we risk
19668 loading garbage from the stack. Furthermore, we can only use
19669 the "exit" out-of-line gpr restore if we haven't saved any
19671 bool saved_all
= !savres_gprs_inline
|| using_multiple_p
;
19673 if (saved_all
&& info
->first_fp_reg_save
!= 64)
19674 /* We can't use the exit routine; use load multiple if it's
19676 savres_gprs_inline
= savres_gprs_inline
|| using_multiple_p
;
19679 strategy
= (using_multiple_p
19680 | (savres_fprs_inline
<< 1)
19681 | (savres_gprs_inline
<< 2));
19682 #ifdef POWERPC_LINUX
19685 if (!savres_fprs_inline
)
19686 strategy
|= SAVRES_NOINLINE_FPRS_SAVES_LR
;
19687 else if (!savres_gprs_inline
&& info
->first_fp_reg_save
== 64)
19688 strategy
|= SAVRES_NOINLINE_GPRS_SAVES_LR
;
19691 if (TARGET_AIX
&& !savres_fprs_inline
)
19692 strategy
|= SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR
;
19697 /* Emit function prologue as insns. */
19700 rs6000_emit_prologue (void)
19702 rs6000_stack_t
*info
= rs6000_stack_info ();
19703 enum machine_mode reg_mode
= Pmode
;
19704 int reg_size
= TARGET_32BIT
? 4 : 8;
19705 rtx sp_reg_rtx
= gen_rtx_REG (Pmode
, STACK_POINTER_REGNUM
);
19706 rtx frame_ptr_rtx
= gen_rtx_REG (Pmode
, 12);
19707 rtx frame_reg_rtx
= sp_reg_rtx
;
19708 rtx cr_save_rtx
= NULL_RTX
;
19711 int saving_FPRs_inline
;
19712 int saving_GPRs_inline
;
19713 int using_store_multiple
;
19714 int using_static_chain_p
= (cfun
->static_chain_decl
!= NULL_TREE
19715 && df_regs_ever_live_p (STATIC_CHAIN_REGNUM
)
19716 && call_used_regs
[STATIC_CHAIN_REGNUM
]);
19717 HOST_WIDE_INT sp_offset
= 0;
19719 if (flag_stack_usage
)
19720 current_function_static_stack_size
= info
->total_size
;
19722 if (flag_stack_check
== STATIC_BUILTIN_STACK_CHECK
&& info
->total_size
)
19723 rs6000_emit_probe_stack_range (STACK_CHECK_PROTECT
, info
->total_size
);
19725 if (TARGET_FIX_AND_CONTINUE
)
19727 /* gdb on darwin arranges to forward a function from the old
19728 address by modifying the first 5 instructions of the function
19729 to branch to the overriding function. This is necessary to
19730 permit function pointers that point to the old function to
19731 actually forward to the new function. */
19732 emit_insn (gen_nop ());
19733 emit_insn (gen_nop ());
19734 emit_insn (gen_nop ());
19735 emit_insn (gen_nop ());
19736 emit_insn (gen_nop ());
19739 if (TARGET_SPE_ABI
&& info
->spe_64bit_regs_used
!= 0)
19741 reg_mode
= V2SImode
;
19745 strategy
= rs6000_savres_strategy (info
, /*savep=*/true,
19746 /*static_chain_p=*/using_static_chain_p
,
19748 using_store_multiple
= strategy
& SAVRES_MULTIPLE
;
19749 saving_FPRs_inline
= strategy
& SAVRES_INLINE_FPRS
;
19750 saving_GPRs_inline
= strategy
& SAVRES_INLINE_GPRS
;
19752 /* For V.4, update stack before we do any saving and set back pointer. */
19753 if (! WORLD_SAVE_P (info
)
19755 && (DEFAULT_ABI
== ABI_V4
19756 || crtl
->calls_eh_return
))
19758 bool need_r11
= (TARGET_SPE
19759 ? (!saving_GPRs_inline
19760 && info
->spe_64bit_regs_used
== 0)
19761 : (!saving_FPRs_inline
|| !saving_GPRs_inline
));
19762 rtx copy_reg
= need_r11
? gen_rtx_REG (Pmode
, 11) : NULL
;
19764 if (info
->total_size
< 32767)
19765 sp_offset
= info
->total_size
;
19767 frame_reg_rtx
= copy_reg
;
19768 else if (info
->cr_save_p
19770 || info
->first_fp_reg_save
< 64
19771 || info
->first_gp_reg_save
< 32
19772 || info
->altivec_size
!= 0
19773 || info
->vrsave_mask
!= 0
19774 || crtl
->calls_eh_return
)
19776 copy_reg
= frame_ptr_rtx
;
19777 frame_reg_rtx
= copy_reg
;
19781 /* The prologue won't be saving any regs so there is no need
19782 to set up a frame register to access any frame save area.
19783 We also won't be using sp_offset anywhere below, but set
19784 the correct value anyway to protect against future
19785 changes to this function. */
19786 sp_offset
= info
->total_size
;
19788 rs6000_emit_allocate_stack (info
->total_size
, copy_reg
);
19789 if (frame_reg_rtx
!= sp_reg_rtx
)
19790 rs6000_emit_stack_tie ();
19793 /* Handle world saves specially here. */
19794 if (WORLD_SAVE_P (info
))
19801 /* save_world expects lr in r0. */
19802 reg0
= gen_rtx_REG (Pmode
, 0);
19803 if (info
->lr_save_p
)
19805 insn
= emit_move_insn (reg0
,
19806 gen_rtx_REG (Pmode
, LR_REGNO
));
19807 RTX_FRAME_RELATED_P (insn
) = 1;
19810 /* The SAVE_WORLD and RESTORE_WORLD routines make a number of
19811 assumptions about the offsets of various bits of the stack
19813 gcc_assert (info
->gp_save_offset
== -220
19814 && info
->fp_save_offset
== -144
19815 && info
->lr_save_offset
== 8
19816 && info
->cr_save_offset
== 4
19819 && (!crtl
->calls_eh_return
19820 || info
->ehrd_offset
== -432)
19821 && info
->vrsave_save_offset
== -224
19822 && info
->altivec_save_offset
== -416);
19824 treg
= gen_rtx_REG (SImode
, 11);
19825 emit_move_insn (treg
, GEN_INT (-info
->total_size
));
19827 /* SAVE_WORLD takes the caller's LR in R0 and the frame size
19828 in R11. It also clobbers R12, so beware! */
19830 /* Preserve CR2 for save_world prologues */
19832 sz
+= 32 - info
->first_gp_reg_save
;
19833 sz
+= 64 - info
->first_fp_reg_save
;
19834 sz
+= LAST_ALTIVEC_REGNO
- info
->first_altivec_reg_save
+ 1;
19835 p
= rtvec_alloc (sz
);
19837 RTVEC_ELT (p
, j
++) = gen_rtx_CLOBBER (VOIDmode
,
19838 gen_rtx_REG (SImode
,
19840 RTVEC_ELT (p
, j
++) = gen_rtx_USE (VOIDmode
,
19841 gen_rtx_SYMBOL_REF (Pmode
,
19843 /* We do floats first so that the instruction pattern matches
19845 for (i
= 0; i
< 64 - info
->first_fp_reg_save
; i
++)
19847 rtx reg
= gen_rtx_REG (((TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
)
19848 ? DFmode
: SFmode
),
19849 info
->first_fp_reg_save
+ i
);
19850 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
19851 GEN_INT (info
->fp_save_offset
19852 + sp_offset
+ 8 * i
));
19853 rtx mem
= gen_frame_mem (((TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
)
19854 ? DFmode
: SFmode
), addr
);
19856 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, mem
, reg
);
19858 for (i
= 0; info
->first_altivec_reg_save
+ i
<= LAST_ALTIVEC_REGNO
; i
++)
19860 rtx reg
= gen_rtx_REG (V4SImode
, info
->first_altivec_reg_save
+ i
);
19861 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
19862 GEN_INT (info
->altivec_save_offset
19863 + sp_offset
+ 16 * i
));
19864 rtx mem
= gen_frame_mem (V4SImode
, addr
);
19866 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, mem
, reg
);
19868 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
19870 rtx reg
= gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
);
19871 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
19872 GEN_INT (info
->gp_save_offset
19873 + sp_offset
+ reg_size
* i
));
19874 rtx mem
= gen_frame_mem (reg_mode
, addr
);
19876 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, mem
, reg
);
19880 /* CR register traditionally saved as CR2. */
19881 rtx reg
= gen_rtx_REG (reg_mode
, CR2_REGNO
);
19882 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
19883 GEN_INT (info
->cr_save_offset
19885 rtx mem
= gen_frame_mem (reg_mode
, addr
);
19887 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, mem
, reg
);
19889 /* Explain about use of R0. */
19890 if (info
->lr_save_p
)
19892 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
19893 GEN_INT (info
->lr_save_offset
19895 rtx mem
= gen_frame_mem (reg_mode
, addr
);
19897 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, mem
, reg0
);
19899 /* Explain what happens to the stack pointer. */
19901 rtx newval
= gen_rtx_PLUS (Pmode
, sp_reg_rtx
, treg
);
19902 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, sp_reg_rtx
, newval
);
19905 insn
= emit_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
19906 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
19907 treg
, GEN_INT (-info
->total_size
));
19908 sp_offset
= info
->total_size
;
19911 /* If we use the link register, get it into r0. */
19912 if (!WORLD_SAVE_P (info
) && info
->lr_save_p
)
19914 rtx addr
, reg
, mem
;
19916 insn
= emit_move_insn (gen_rtx_REG (Pmode
, 0),
19917 gen_rtx_REG (Pmode
, LR_REGNO
));
19918 RTX_FRAME_RELATED_P (insn
) = 1;
19920 if (!(strategy
& (SAVRES_NOINLINE_GPRS_SAVES_LR
19921 | SAVRES_NOINLINE_FPRS_SAVES_LR
)))
19923 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
19924 GEN_INT (info
->lr_save_offset
+ sp_offset
));
19925 reg
= gen_rtx_REG (Pmode
, 0);
19926 mem
= gen_rtx_MEM (Pmode
, addr
);
19927 /* This should not be of rs6000_sr_alias_set, because of
19928 __builtin_return_address. */
19930 insn
= emit_move_insn (mem
, reg
);
19931 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
19932 NULL_RTX
, NULL_RTX
);
19936 /* If we need to save CR, put it into r12 or r11. */
19937 if (!WORLD_SAVE_P (info
) && info
->cr_save_p
&& frame_reg_rtx
!= frame_ptr_rtx
)
19942 = gen_rtx_REG (SImode
, DEFAULT_ABI
== ABI_AIX
&& !saving_GPRs_inline
19944 insn
= emit_insn (gen_movesi_from_cr (cr_save_rtx
));
19945 RTX_FRAME_RELATED_P (insn
) = 1;
19946 /* Now, there's no way that dwarf2out_frame_debug_expr is going
19947 to understand '(unspec:SI [(reg:CC 68) ...] UNSPEC_MOVESI_FROM_CR)'.
19948 But that's OK. All we have to do is specify that _one_ condition
19949 code register is saved in this stack slot. The thrower's epilogue
19950 will then restore all the call-saved registers.
19951 We use CR2_REGNO (70) to be compatible with gcc-2.95 on Linux. */
19952 set
= gen_rtx_SET (VOIDmode
, cr_save_rtx
,
19953 gen_rtx_REG (SImode
, CR2_REGNO
));
19954 add_reg_note (insn
, REG_FRAME_RELATED_EXPR
, set
);
19957 /* Do any required saving of fpr's. If only one or two to save, do
19958 it ourselves. Otherwise, call function. */
19959 if (!WORLD_SAVE_P (info
) && saving_FPRs_inline
)
19962 for (i
= 0; i
< 64 - info
->first_fp_reg_save
; i
++)
19963 if ((df_regs_ever_live_p (info
->first_fp_reg_save
+i
)
19964 && ! call_used_regs
[info
->first_fp_reg_save
+i
]))
19965 emit_frame_save (frame_reg_rtx
, frame_ptr_rtx
,
19966 (TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
)
19968 info
->first_fp_reg_save
+ i
,
19969 info
->fp_save_offset
+ sp_offset
+ 8 * i
,
19972 else if (!WORLD_SAVE_P (info
) && info
->first_fp_reg_save
!= 64)
19976 par
= rs6000_make_savres_rtx (info
, frame_reg_rtx
,
19977 info
->fp_save_offset
+ sp_offset
,
19979 /*savep=*/true, /*gpr=*/false,
19981 & SAVRES_NOINLINE_FPRS_SAVES_LR
)
19983 insn
= emit_insn (par
);
19984 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
19985 NULL_RTX
, NULL_RTX
);
19988 /* Save GPRs. This is done as a PARALLEL if we are using
19989 the store-multiple instructions. */
19990 if (!WORLD_SAVE_P (info
)
19992 && info
->spe_64bit_regs_used
!= 0
19993 && info
->first_gp_reg_save
!= 32)
19996 rtx spe_save_area_ptr
;
19998 /* Determine whether we can address all of the registers that need
19999 to be saved with an offset from the stack pointer that fits in
20000 the small const field for SPE memory instructions. */
20001 int spe_regs_addressable_via_sp
20002 = (SPE_CONST_OFFSET_OK(info
->spe_gp_save_offset
+ sp_offset
20003 + (32 - info
->first_gp_reg_save
- 1) * reg_size
)
20004 && saving_GPRs_inline
);
20007 if (spe_regs_addressable_via_sp
)
20009 spe_save_area_ptr
= frame_reg_rtx
;
20010 spe_offset
= info
->spe_gp_save_offset
+ sp_offset
;
20014 /* Make r11 point to the start of the SPE save area. We need
20015 to be careful here if r11 is holding the static chain. If
20016 it is, then temporarily save it in r0. We would use r0 as
20017 our base register here, but using r0 as a base register in
20018 loads and stores means something different from what we
20020 int ool_adjust
= (saving_GPRs_inline
20022 : (info
->first_gp_reg_save
20023 - (FIRST_SAVRES_REGISTER
+1))*8);
20024 HOST_WIDE_INT offset
= (info
->spe_gp_save_offset
20025 + sp_offset
- ool_adjust
);
20027 if (using_static_chain_p
)
20029 rtx r0
= gen_rtx_REG (Pmode
, 0);
20030 gcc_assert (info
->first_gp_reg_save
> 11);
20032 emit_move_insn (r0
, gen_rtx_REG (Pmode
, 11));
20035 spe_save_area_ptr
= gen_rtx_REG (Pmode
, 11);
20036 insn
= emit_insn (gen_addsi3 (spe_save_area_ptr
,
20038 GEN_INT (offset
)));
20039 /* We need to make sure the move to r11 gets noted for
20040 properly outputting unwind information. */
20041 if (!saving_GPRs_inline
)
20042 rs6000_frame_related (insn
, frame_reg_rtx
, offset
,
20043 NULL_RTX
, NULL_RTX
);
20047 if (saving_GPRs_inline
)
20049 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
20050 if (rs6000_reg_live_or_pic_offset_p (info
->first_gp_reg_save
+ i
))
20052 rtx reg
= gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
);
20053 rtx offset
, addr
, mem
;
20055 /* We're doing all this to ensure that the offset fits into
20056 the immediate offset of 'evstdd'. */
20057 gcc_assert (SPE_CONST_OFFSET_OK (reg_size
* i
+ spe_offset
));
20059 offset
= GEN_INT (reg_size
* i
+ spe_offset
);
20060 addr
= gen_rtx_PLUS (Pmode
, spe_save_area_ptr
, offset
);
20061 mem
= gen_rtx_MEM (V2SImode
, addr
);
20063 insn
= emit_move_insn (mem
, reg
);
20065 rs6000_frame_related (insn
, spe_save_area_ptr
,
20066 info
->spe_gp_save_offset
20067 + sp_offset
+ reg_size
* i
,
20068 offset
, const0_rtx
);
20075 par
= rs6000_make_savres_rtx (info
, gen_rtx_REG (Pmode
, 11),
20077 /*savep=*/true, /*gpr=*/true,
20079 insn
= emit_insn (par
);
20080 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
20081 NULL_RTX
, NULL_RTX
);
20085 /* Move the static chain pointer back. */
20086 if (using_static_chain_p
&& !spe_regs_addressable_via_sp
)
20087 emit_move_insn (gen_rtx_REG (Pmode
, 11), gen_rtx_REG (Pmode
, 0));
20089 else if (!WORLD_SAVE_P (info
) && !saving_GPRs_inline
)
20093 /* Need to adjust r11 (r12) if we saved any FPRs. */
20094 if (info
->first_fp_reg_save
!= 64)
20096 rtx dest_reg
= gen_rtx_REG (reg_mode
, DEFAULT_ABI
== ABI_AIX
20098 rtx offset
= GEN_INT (sp_offset
20099 + (-8 * (64-info
->first_fp_reg_save
)));
20100 emit_insn (gen_add3_insn (dest_reg
, frame_reg_rtx
, offset
));
20103 par
= rs6000_make_savres_rtx (info
, frame_reg_rtx
,
20104 info
->gp_save_offset
+ sp_offset
,
20106 /*savep=*/true, /*gpr=*/true,
20108 & SAVRES_NOINLINE_GPRS_SAVES_LR
)
20110 insn
= emit_insn (par
);
20111 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
20112 NULL_RTX
, NULL_RTX
);
20114 else if (!WORLD_SAVE_P (info
) && using_store_multiple
)
20118 p
= rtvec_alloc (32 - info
->first_gp_reg_save
);
20119 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
20121 rtx addr
, reg
, mem
;
20122 reg
= gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
);
20123 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
20124 GEN_INT (info
->gp_save_offset
20127 mem
= gen_frame_mem (reg_mode
, addr
);
20129 RTVEC_ELT (p
, i
) = gen_rtx_SET (VOIDmode
, mem
, reg
);
20131 insn
= emit_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
20132 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
20133 NULL_RTX
, NULL_RTX
);
20135 else if (!WORLD_SAVE_P (info
))
20138 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
20139 if (rs6000_reg_live_or_pic_offset_p (info
->first_gp_reg_save
+ i
))
20141 rtx addr
, reg
, mem
;
20142 reg
= gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
);
20144 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
20145 GEN_INT (info
->gp_save_offset
20148 mem
= gen_frame_mem (reg_mode
, addr
);
20150 insn
= emit_move_insn (mem
, reg
);
20151 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
20152 NULL_RTX
, NULL_RTX
);
20156 /* ??? There's no need to emit actual instructions here, but it's the
20157 easiest way to get the frame unwind information emitted. */
20158 if (crtl
->calls_eh_return
)
20160 unsigned int i
, regno
;
20162 /* In AIX ABI we need to pretend we save r2 here. */
20165 rtx addr
, reg
, mem
;
20167 reg
= gen_rtx_REG (reg_mode
, 2);
20168 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
20169 GEN_INT (sp_offset
+ 5 * reg_size
));
20170 mem
= gen_frame_mem (reg_mode
, addr
);
20172 insn
= emit_move_insn (mem
, reg
);
20173 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
20174 NULL_RTX
, NULL_RTX
);
20175 PATTERN (insn
) = gen_blockage ();
20180 regno
= EH_RETURN_DATA_REGNO (i
);
20181 if (regno
== INVALID_REGNUM
)
20184 emit_frame_save (frame_reg_rtx
, frame_ptr_rtx
, reg_mode
, regno
,
20185 info
->ehrd_offset
+ sp_offset
20186 + reg_size
* (int) i
,
20191 /* Save CR if we use any that must be preserved. */
20192 if (!WORLD_SAVE_P (info
) && info
->cr_save_p
)
20194 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
20195 GEN_INT (info
->cr_save_offset
+ sp_offset
));
20196 rtx mem
= gen_frame_mem (SImode
, addr
);
20197 /* See the large comment above about why CR2_REGNO is used. */
20198 rtx magic_eh_cr_reg
= gen_rtx_REG (SImode
, CR2_REGNO
);
20200 /* If r12 was used to hold the original sp, copy cr into r0 now
20202 if (REGNO (frame_reg_rtx
) == 12)
20206 cr_save_rtx
= gen_rtx_REG (SImode
, 0);
20207 insn
= emit_insn (gen_movesi_from_cr (cr_save_rtx
));
20208 RTX_FRAME_RELATED_P (insn
) = 1;
20209 set
= gen_rtx_SET (VOIDmode
, cr_save_rtx
, magic_eh_cr_reg
);
20210 add_reg_note (insn
, REG_FRAME_RELATED_EXPR
, set
);
20212 insn
= emit_move_insn (mem
, cr_save_rtx
);
20214 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
20215 NULL_RTX
, NULL_RTX
);
20218 /* Update stack and set back pointer unless this is V.4,
20219 for which it was done previously. */
20220 if (!WORLD_SAVE_P (info
) && info
->push_p
20221 && !(DEFAULT_ABI
== ABI_V4
|| crtl
->calls_eh_return
))
20223 rtx copy_reg
= NULL
;
20225 if (info
->total_size
< 32767)
20226 sp_offset
= info
->total_size
;
20227 else if (info
->altivec_size
!= 0
20228 || info
->vrsave_mask
!= 0)
20230 copy_reg
= frame_ptr_rtx
;
20231 frame_reg_rtx
= copy_reg
;
20234 sp_offset
= info
->total_size
;
20235 rs6000_emit_allocate_stack (info
->total_size
, copy_reg
);
20236 if (frame_reg_rtx
!= sp_reg_rtx
)
20237 rs6000_emit_stack_tie ();
20240 /* Set frame pointer, if needed. */
20241 if (frame_pointer_needed
)
20243 insn
= emit_move_insn (gen_rtx_REG (Pmode
, HARD_FRAME_POINTER_REGNUM
),
20245 RTX_FRAME_RELATED_P (insn
) = 1;
20248 /* Save AltiVec registers if needed. Save here because the red zone does
20249 not include AltiVec registers. */
20250 if (!WORLD_SAVE_P (info
) && TARGET_ALTIVEC_ABI
&& info
->altivec_size
!= 0)
20254 /* There should be a non inline version of this, for when we
20255 are saving lots of vector registers. */
20256 for (i
= info
->first_altivec_reg_save
; i
<= LAST_ALTIVEC_REGNO
; ++i
)
20257 if (info
->vrsave_mask
& ALTIVEC_REG_BIT (i
))
20259 rtx areg
, savereg
, mem
;
20262 offset
= info
->altivec_save_offset
+ sp_offset
20263 + 16 * (i
- info
->first_altivec_reg_save
);
20265 savereg
= gen_rtx_REG (V4SImode
, i
);
20267 areg
= gen_rtx_REG (Pmode
, 0);
20268 emit_move_insn (areg
, GEN_INT (offset
));
20270 /* AltiVec addressing mode is [reg+reg]. */
20271 mem
= gen_frame_mem (V4SImode
,
20272 gen_rtx_PLUS (Pmode
, frame_reg_rtx
, areg
));
20274 insn
= emit_move_insn (mem
, savereg
);
20276 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
20277 areg
, GEN_INT (offset
));
20281 /* VRSAVE is a bit vector representing which AltiVec registers
20282 are used. The OS uses this to determine which vector
20283 registers to save on a context switch. We need to save
20284 VRSAVE on the stack frame, add whatever AltiVec registers we
20285 used in this function, and do the corresponding magic in the
20288 if (TARGET_ALTIVEC
&& TARGET_ALTIVEC_VRSAVE
20289 && info
->vrsave_mask
!= 0)
20291 rtx reg
, mem
, vrsave
;
20294 /* Get VRSAVE onto a GPR. Note that ABI_V4 might be using r12
20295 as frame_reg_rtx and r11 as the static chain pointer for
20296 nested functions. */
20297 reg
= gen_rtx_REG (SImode
, 0);
20298 vrsave
= gen_rtx_REG (SImode
, VRSAVE_REGNO
);
20300 emit_insn (gen_get_vrsave_internal (reg
));
20302 emit_insn (gen_rtx_SET (VOIDmode
, reg
, vrsave
));
20304 if (!WORLD_SAVE_P (info
))
20307 offset
= info
->vrsave_save_offset
+ sp_offset
;
20308 mem
= gen_frame_mem (SImode
,
20309 gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
20310 GEN_INT (offset
)));
20311 insn
= emit_move_insn (mem
, reg
);
20314 /* Include the registers in the mask. */
20315 emit_insn (gen_iorsi3 (reg
, reg
, GEN_INT ((int) info
->vrsave_mask
)));
20317 insn
= emit_insn (generate_set_vrsave (reg
, info
, 0));
20320 /* If we are using RS6000_PIC_OFFSET_TABLE_REGNUM, we need to set it up. */
20321 if ((TARGET_TOC
&& TARGET_MINIMAL_TOC
&& get_pool_size () != 0)
20322 || (DEFAULT_ABI
== ABI_V4
20323 && (flag_pic
== 1 || (flag_pic
&& TARGET_SECURE_PLT
))
20324 && df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM
)))
20326 /* If emit_load_toc_table will use the link register, we need to save
20327 it. We use R12 for this purpose because emit_load_toc_table
20328 can use register 0. This allows us to use a plain 'blr' to return
20329 from the procedure more often. */
20330 int save_LR_around_toc_setup
= (TARGET_ELF
20331 && DEFAULT_ABI
!= ABI_AIX
20333 && ! info
->lr_save_p
20334 && EDGE_COUNT (EXIT_BLOCK_PTR
->preds
) > 0);
20335 if (save_LR_around_toc_setup
)
20337 rtx lr
= gen_rtx_REG (Pmode
, LR_REGNO
);
20339 insn
= emit_move_insn (frame_ptr_rtx
, lr
);
20340 RTX_FRAME_RELATED_P (insn
) = 1;
20342 rs6000_emit_load_toc_table (TRUE
);
20344 insn
= emit_move_insn (lr
, frame_ptr_rtx
);
20345 RTX_FRAME_RELATED_P (insn
) = 1;
20348 rs6000_emit_load_toc_table (TRUE
);
20352 if (DEFAULT_ABI
== ABI_DARWIN
20353 && flag_pic
&& crtl
->uses_pic_offset_table
)
20355 rtx lr
= gen_rtx_REG (Pmode
, LR_REGNO
);
20356 rtx src
= gen_rtx_SYMBOL_REF (Pmode
, MACHOPIC_FUNCTION_BASE_NAME
);
20358 /* Save and restore LR locally around this call (in R0). */
20359 if (!info
->lr_save_p
)
20360 emit_move_insn (gen_rtx_REG (Pmode
, 0), lr
);
20362 emit_insn (gen_load_macho_picbase (src
));
20364 emit_move_insn (gen_rtx_REG (Pmode
,
20365 RS6000_PIC_OFFSET_TABLE_REGNUM
),
20368 if (!info
->lr_save_p
)
20369 emit_move_insn (lr
, gen_rtx_REG (Pmode
, 0));
20374 /* Write function prologue. */
20377 rs6000_output_function_prologue (FILE *file
,
20378 HOST_WIDE_INT size ATTRIBUTE_UNUSED
)
20380 rs6000_stack_t
*info
= rs6000_stack_info ();
20382 if (TARGET_DEBUG_STACK
)
20383 debug_stack_info (info
);
20385 /* Write .extern for any function we will call to save and restore
20387 if (info
->first_fp_reg_save
< 64
20388 && !FP_SAVE_INLINE (info
->first_fp_reg_save
))
20391 int regno
= info
->first_fp_reg_save
- 32;
20393 name
= rs6000_savres_routine_name (info
, regno
, /*savep=*/true,
20394 /*gpr=*/false, /*lr=*/false);
20395 fprintf (file
, "\t.extern %s\n", name
);
20397 name
= rs6000_savres_routine_name (info
, regno
, /*savep=*/false,
20398 /*gpr=*/false, /*lr=*/true);
20399 fprintf (file
, "\t.extern %s\n", name
);
20402 /* Write .extern for AIX common mode routines, if needed. */
20403 if (! TARGET_POWER
&& ! TARGET_POWERPC
&& ! common_mode_defined
)
20405 fputs ("\t.extern __mulh\n", file
);
20406 fputs ("\t.extern __mull\n", file
);
20407 fputs ("\t.extern __divss\n", file
);
20408 fputs ("\t.extern __divus\n", file
);
20409 fputs ("\t.extern __quoss\n", file
);
20410 fputs ("\t.extern __quous\n", file
);
20411 common_mode_defined
= 1;
20414 if (! HAVE_prologue
)
20420 /* A NOTE_INSN_DELETED is supposed to be at the start and end of
20421 the "toplevel" insn chain. */
20422 emit_note (NOTE_INSN_DELETED
);
20423 rs6000_emit_prologue ();
20424 emit_note (NOTE_INSN_DELETED
);
20426 /* Expand INSN_ADDRESSES so final() doesn't crash. */
20430 for (insn
= get_insns (); insn
!= 0; insn
= NEXT_INSN (insn
))
20432 INSN_ADDRESSES_NEW (insn
, addr
);
20437 prologue
= get_insns ();
20440 if (TARGET_DEBUG_STACK
)
20441 debug_rtx_list (prologue
, 100);
20443 emit_insn_before_noloc (prologue
, BB_HEAD (ENTRY_BLOCK_PTR
->next_bb
),
20447 rs6000_pic_labelno
++;
20450 /* Non-zero if vmx regs are restored before the frame pop, zero if
20451 we restore after the pop when possible. */
20452 #define ALWAYS_RESTORE_ALTIVEC_BEFORE_POP 0
20454 /* Reload CR from REG. */
20457 rs6000_restore_saved_cr (rtx reg
, int using_mfcr_multiple
)
20462 if (using_mfcr_multiple
)
20464 for (i
= 0; i
< 8; i
++)
20465 if (df_regs_ever_live_p (CR0_REGNO
+i
) && ! call_used_regs
[CR0_REGNO
+i
])
20467 gcc_assert (count
);
20470 if (using_mfcr_multiple
&& count
> 1)
20475 p
= rtvec_alloc (count
);
20478 for (i
= 0; i
< 8; i
++)
20479 if (df_regs_ever_live_p (CR0_REGNO
+i
) && ! call_used_regs
[CR0_REGNO
+i
])
20481 rtvec r
= rtvec_alloc (2);
20482 RTVEC_ELT (r
, 0) = reg
;
20483 RTVEC_ELT (r
, 1) = GEN_INT (1 << (7-i
));
20484 RTVEC_ELT (p
, ndx
) =
20485 gen_rtx_SET (VOIDmode
, gen_rtx_REG (CCmode
, CR0_REGNO
+i
),
20486 gen_rtx_UNSPEC (CCmode
, r
, UNSPEC_MOVESI_TO_CR
));
20489 emit_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
20490 gcc_assert (ndx
== count
);
20493 for (i
= 0; i
< 8; i
++)
20494 if (df_regs_ever_live_p (CR0_REGNO
+i
) && ! call_used_regs
[CR0_REGNO
+i
])
20496 emit_insn (gen_movsi_to_cr_one (gen_rtx_REG (CCmode
,
20502 /* Return true if OFFSET from stack pointer can be clobbered by signals.
20503 V.4 doesn't have any stack cushion, AIX ABIs have 220 or 288 bytes
20504 below stack pointer not cloberred by signals. */
20507 offset_below_red_zone_p (HOST_WIDE_INT offset
)
20509 return offset
< (DEFAULT_ABI
== ABI_V4
20511 : TARGET_32BIT
? -220 : -288);
20514 /* Emit function epilogue as insns. */
20517 rs6000_emit_epilogue (int sibcall
)
20519 rs6000_stack_t
*info
;
20520 int restoring_GPRs_inline
;
20521 int restoring_FPRs_inline
;
20522 int using_load_multiple
;
20523 int using_mtcr_multiple
;
20524 int use_backchain_to_restore_sp
;
20528 rtx sp_reg_rtx
= gen_rtx_REG (Pmode
, 1);
20529 rtx frame_reg_rtx
= sp_reg_rtx
;
20530 rtx cfa_restores
= NULL_RTX
;
20532 rtx cr_save_reg
= NULL_RTX
;
20533 enum machine_mode reg_mode
= Pmode
;
20534 int reg_size
= TARGET_32BIT
? 4 : 8;
20537 info
= rs6000_stack_info ();
20539 if (TARGET_SPE_ABI
&& info
->spe_64bit_regs_used
!= 0)
20541 reg_mode
= V2SImode
;
20545 strategy
= rs6000_savres_strategy (info
, /*savep=*/false,
20546 /*static_chain_p=*/0, sibcall
);
20547 using_load_multiple
= strategy
& SAVRES_MULTIPLE
;
20548 restoring_FPRs_inline
= strategy
& SAVRES_INLINE_FPRS
;
20549 restoring_GPRs_inline
= strategy
& SAVRES_INLINE_GPRS
;
20550 using_mtcr_multiple
= (rs6000_cpu
== PROCESSOR_PPC601
20551 || rs6000_cpu
== PROCESSOR_PPC603
20552 || rs6000_cpu
== PROCESSOR_PPC750
20554 /* Restore via the backchain when we have a large frame, since this
20555 is more efficient than an addis, addi pair. The second condition
20556 here will not trigger at the moment; We don't actually need a
20557 frame pointer for alloca, but the generic parts of the compiler
20558 give us one anyway. */
20559 use_backchain_to_restore_sp
= (info
->total_size
> 32767
20560 || info
->total_size
20561 + (info
->lr_save_p
? info
->lr_save_offset
: 0)
20563 || (cfun
->calls_alloca
20564 && !frame_pointer_needed
));
20565 restore_lr
= (info
->lr_save_p
20566 && (restoring_FPRs_inline
20567 || (strategy
& SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR
))
20568 && (restoring_GPRs_inline
20569 || info
->first_fp_reg_save
< 64));
20571 if (WORLD_SAVE_P (info
))
20575 const char *alloc_rname
;
20578 /* eh_rest_world_r10 will return to the location saved in the LR
20579 stack slot (which is not likely to be our caller.)
20580 Input: R10 -- stack adjustment. Clobbers R0, R11, R12, R7, R8.
20581 rest_world is similar, except any R10 parameter is ignored.
20582 The exception-handling stuff that was here in 2.95 is no
20583 longer necessary. */
20587 + 32 - info
->first_gp_reg_save
20588 + LAST_ALTIVEC_REGNO
+ 1 - info
->first_altivec_reg_save
20589 + 63 + 1 - info
->first_fp_reg_save
);
20591 strcpy (rname
, ((crtl
->calls_eh_return
) ?
20592 "*eh_rest_world_r10" : "*rest_world"));
20593 alloc_rname
= ggc_strdup (rname
);
20596 RTVEC_ELT (p
, j
++) = gen_rtx_RETURN (VOIDmode
);
20597 RTVEC_ELT (p
, j
++) = gen_rtx_USE (VOIDmode
,
20598 gen_rtx_REG (Pmode
,
20601 = gen_rtx_USE (VOIDmode
, gen_rtx_SYMBOL_REF (Pmode
, alloc_rname
));
20602 /* The instruction pattern requires a clobber here;
20603 it is shared with the restVEC helper. */
20605 = gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (Pmode
, 11));
20608 /* CR register traditionally saved as CR2. */
20609 rtx reg
= gen_rtx_REG (reg_mode
, CR2_REGNO
);
20610 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
20611 GEN_INT (info
->cr_save_offset
));
20612 rtx mem
= gen_frame_mem (reg_mode
, addr
);
20614 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, reg
, mem
);
20617 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
20619 rtx reg
= gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
);
20620 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
20621 GEN_INT (info
->gp_save_offset
20623 rtx mem
= gen_frame_mem (reg_mode
, addr
);
20625 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, reg
, mem
);
20627 for (i
= 0; info
->first_altivec_reg_save
+ i
<= LAST_ALTIVEC_REGNO
; i
++)
20629 rtx reg
= gen_rtx_REG (V4SImode
, info
->first_altivec_reg_save
+ i
);
20630 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
20631 GEN_INT (info
->altivec_save_offset
20633 rtx mem
= gen_frame_mem (V4SImode
, addr
);
20635 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, reg
, mem
);
20637 for (i
= 0; info
->first_fp_reg_save
+ i
<= 63; i
++)
20639 rtx reg
= gen_rtx_REG (((TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
)
20640 ? DFmode
: SFmode
),
20641 info
->first_fp_reg_save
+ i
);
20642 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
20643 GEN_INT (info
->fp_save_offset
20645 rtx mem
= gen_frame_mem (((TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
)
20646 ? DFmode
: SFmode
), addr
);
20648 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, reg
, mem
);
20651 = gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (Pmode
, 0));
20653 = gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (SImode
, 12));
20655 = gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (SImode
, 7));
20657 = gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (SImode
, 8));
20659 = gen_rtx_USE (VOIDmode
, gen_rtx_REG (SImode
, 10));
20660 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
20665 /* frame_reg_rtx + sp_offset points to the top of this stack frame. */
20667 sp_offset
= info
->total_size
;
20669 /* Restore AltiVec registers if we must do so before adjusting the
20671 if (TARGET_ALTIVEC_ABI
20672 && info
->altivec_size
!= 0
20673 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
20674 || (DEFAULT_ABI
!= ABI_V4
20675 && offset_below_red_zone_p (info
->altivec_save_offset
))))
20679 if (use_backchain_to_restore_sp
)
20681 frame_reg_rtx
= gen_rtx_REG (Pmode
, 11);
20682 emit_move_insn (frame_reg_rtx
,
20683 gen_rtx_MEM (Pmode
, sp_reg_rtx
));
20686 else if (frame_pointer_needed
)
20687 frame_reg_rtx
= hard_frame_pointer_rtx
;
20689 for (i
= info
->first_altivec_reg_save
; i
<= LAST_ALTIVEC_REGNO
; ++i
)
20690 if (info
->vrsave_mask
& ALTIVEC_REG_BIT (i
))
20692 rtx addr
, areg
, mem
, reg
;
20694 areg
= gen_rtx_REG (Pmode
, 0);
20696 (areg
, GEN_INT (info
->altivec_save_offset
20698 + 16 * (i
- info
->first_altivec_reg_save
)));
20700 /* AltiVec addressing mode is [reg+reg]. */
20701 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
, areg
);
20702 mem
= gen_frame_mem (V4SImode
, addr
);
20704 reg
= gen_rtx_REG (V4SImode
, i
);
20705 emit_move_insn (reg
, mem
);
20706 if (offset_below_red_zone_p (info
->altivec_save_offset
20707 + (i
- info
->first_altivec_reg_save
)
20709 cfa_restores
= alloc_reg_note (REG_CFA_RESTORE
, reg
,
20714 /* Restore VRSAVE if we must do so before adjusting the stack. */
20716 && TARGET_ALTIVEC_VRSAVE
20717 && info
->vrsave_mask
!= 0
20718 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
20719 || (DEFAULT_ABI
!= ABI_V4
20720 && offset_below_red_zone_p (info
->vrsave_save_offset
))))
20722 rtx addr
, mem
, reg
;
20724 if (frame_reg_rtx
== sp_reg_rtx
)
20726 if (use_backchain_to_restore_sp
)
20728 frame_reg_rtx
= gen_rtx_REG (Pmode
, 11);
20729 emit_move_insn (frame_reg_rtx
,
20730 gen_rtx_MEM (Pmode
, sp_reg_rtx
));
20733 else if (frame_pointer_needed
)
20734 frame_reg_rtx
= hard_frame_pointer_rtx
;
20737 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
20738 GEN_INT (info
->vrsave_save_offset
+ sp_offset
));
20739 mem
= gen_frame_mem (SImode
, addr
);
20740 reg
= gen_rtx_REG (SImode
, 12);
20741 emit_move_insn (reg
, mem
);
20743 emit_insn (generate_set_vrsave (reg
, info
, 1));
20747 /* If we have a large stack frame, restore the old stack pointer
20748 using the backchain. */
20749 if (use_backchain_to_restore_sp
)
20751 if (frame_reg_rtx
== sp_reg_rtx
)
20753 /* Under V.4, don't reset the stack pointer until after we're done
20754 loading the saved registers. */
20755 if (DEFAULT_ABI
== ABI_V4
)
20756 frame_reg_rtx
= gen_rtx_REG (Pmode
, 11);
20758 insn
= emit_move_insn (frame_reg_rtx
,
20759 gen_rtx_MEM (Pmode
, sp_reg_rtx
));
20762 else if (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
20763 && DEFAULT_ABI
== ABI_V4
)
20764 /* frame_reg_rtx has been set up by the altivec restore. */
20768 insn
= emit_move_insn (sp_reg_rtx
, frame_reg_rtx
);
20769 frame_reg_rtx
= sp_reg_rtx
;
20772 /* If we have a frame pointer, we can restore the old stack pointer
20774 else if (frame_pointer_needed
)
20776 frame_reg_rtx
= sp_reg_rtx
;
20777 if (DEFAULT_ABI
== ABI_V4
)
20778 frame_reg_rtx
= gen_rtx_REG (Pmode
, 11);
20779 /* Prevent reordering memory accesses against stack pointer restore. */
20780 else if (cfun
->calls_alloca
20781 || offset_below_red_zone_p (-info
->total_size
))
20783 rtx mem1
= gen_rtx_MEM (BLKmode
, hard_frame_pointer_rtx
);
20784 rtx mem2
= gen_rtx_MEM (BLKmode
, sp_reg_rtx
);
20785 MEM_NOTRAP_P (mem1
) = 1;
20786 MEM_NOTRAP_P (mem2
) = 1;
20787 emit_insn (gen_frame_tie (mem1
, mem2
));
20790 insn
= emit_insn (gen_add3_insn (frame_reg_rtx
, hard_frame_pointer_rtx
,
20791 GEN_INT (info
->total_size
)));
20794 else if (info
->push_p
20795 && DEFAULT_ABI
!= ABI_V4
20796 && !crtl
->calls_eh_return
)
20798 /* Prevent reordering memory accesses against stack pointer restore. */
20799 if (cfun
->calls_alloca
20800 || offset_below_red_zone_p (-info
->total_size
))
20802 rtx mem
= gen_rtx_MEM (BLKmode
, sp_reg_rtx
);
20803 MEM_NOTRAP_P (mem
) = 1;
20804 emit_insn (gen_stack_tie (mem
));
20806 insn
= emit_insn (gen_add3_insn (sp_reg_rtx
, sp_reg_rtx
,
20807 GEN_INT (info
->total_size
)));
20810 if (insn
&& frame_reg_rtx
== sp_reg_rtx
)
20814 REG_NOTES (insn
) = cfa_restores
;
20815 cfa_restores
= NULL_RTX
;
20817 add_reg_note (insn
, REG_CFA_DEF_CFA
, sp_reg_rtx
);
20818 RTX_FRAME_RELATED_P (insn
) = 1;
20821 /* Restore AltiVec registers if we have not done so already. */
20822 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
20823 && TARGET_ALTIVEC_ABI
20824 && info
->altivec_size
!= 0
20825 && (DEFAULT_ABI
== ABI_V4
20826 || !offset_below_red_zone_p (info
->altivec_save_offset
)))
20830 for (i
= info
->first_altivec_reg_save
; i
<= LAST_ALTIVEC_REGNO
; ++i
)
20831 if (info
->vrsave_mask
& ALTIVEC_REG_BIT (i
))
20833 rtx addr
, areg
, mem
, reg
;
20835 areg
= gen_rtx_REG (Pmode
, 0);
20837 (areg
, GEN_INT (info
->altivec_save_offset
20839 + 16 * (i
- info
->first_altivec_reg_save
)));
20841 /* AltiVec addressing mode is [reg+reg]. */
20842 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
, areg
);
20843 mem
= gen_frame_mem (V4SImode
, addr
);
20845 reg
= gen_rtx_REG (V4SImode
, i
);
20846 emit_move_insn (reg
, mem
);
20847 if (DEFAULT_ABI
== ABI_V4
)
20848 cfa_restores
= alloc_reg_note (REG_CFA_RESTORE
, reg
,
20853 /* Restore VRSAVE if we have not done so already. */
20854 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
20856 && TARGET_ALTIVEC_VRSAVE
20857 && info
->vrsave_mask
!= 0
20858 && (DEFAULT_ABI
== ABI_V4
20859 || !offset_below_red_zone_p (info
->vrsave_save_offset
)))
20861 rtx addr
, mem
, reg
;
20863 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
20864 GEN_INT (info
->vrsave_save_offset
+ sp_offset
));
20865 mem
= gen_frame_mem (SImode
, addr
);
20866 reg
= gen_rtx_REG (SImode
, 12);
20867 emit_move_insn (reg
, mem
);
20869 emit_insn (generate_set_vrsave (reg
, info
, 1));
20872 /* Get the old lr if we saved it. If we are restoring registers
20873 out-of-line, then the out-of-line routines can do this for us. */
20874 if (restore_lr
&& restoring_GPRs_inline
)
20876 rtx mem
= gen_frame_mem_offset (Pmode
, frame_reg_rtx
,
20877 info
->lr_save_offset
+ sp_offset
);
20879 emit_move_insn (gen_rtx_REG (Pmode
, 0), mem
);
20882 /* Get the old cr if we saved it. */
20883 if (info
->cr_save_p
)
20885 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
20886 GEN_INT (info
->cr_save_offset
+ sp_offset
));
20887 rtx mem
= gen_frame_mem (SImode
, addr
);
20889 cr_save_reg
= gen_rtx_REG (SImode
,
20890 DEFAULT_ABI
== ABI_AIX
20891 && !restoring_GPRs_inline
20892 && info
->first_fp_reg_save
< 64
20894 emit_move_insn (cr_save_reg
, mem
);
20897 /* Set LR here to try to overlap restores below. LR is always saved
20898 above incoming stack, so it never needs REG_CFA_RESTORE. */
20899 if (restore_lr
&& restoring_GPRs_inline
)
20900 emit_move_insn (gen_rtx_REG (Pmode
, LR_REGNO
),
20901 gen_rtx_REG (Pmode
, 0));
20903 /* Load exception handler data registers, if needed. */
20904 if (crtl
->calls_eh_return
)
20906 unsigned int i
, regno
;
20910 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
20911 GEN_INT (sp_offset
+ 5 * reg_size
));
20912 rtx mem
= gen_frame_mem (reg_mode
, addr
);
20914 emit_move_insn (gen_rtx_REG (reg_mode
, 2), mem
);
20921 regno
= EH_RETURN_DATA_REGNO (i
);
20922 if (regno
== INVALID_REGNUM
)
20925 mem
= gen_frame_mem_offset (reg_mode
, frame_reg_rtx
,
20926 info
->ehrd_offset
+ sp_offset
20927 + reg_size
* (int) i
);
20929 emit_move_insn (gen_rtx_REG (reg_mode
, regno
), mem
);
20933 /* Restore GPRs. This is done as a PARALLEL if we are using
20934 the load-multiple instructions. */
20936 && info
->spe_64bit_regs_used
!= 0
20937 && info
->first_gp_reg_save
!= 32)
20939 /* Determine whether we can address all of the registers that need
20940 to be saved with an offset from the stack pointer that fits in
20941 the small const field for SPE memory instructions. */
20942 int spe_regs_addressable_via_sp
20943 = (SPE_CONST_OFFSET_OK(info
->spe_gp_save_offset
+ sp_offset
20944 + (32 - info
->first_gp_reg_save
- 1) * reg_size
)
20945 && restoring_GPRs_inline
);
20948 if (spe_regs_addressable_via_sp
)
20949 spe_offset
= info
->spe_gp_save_offset
+ sp_offset
;
20952 rtx old_frame_reg_rtx
= frame_reg_rtx
;
20953 /* Make r11 point to the start of the SPE save area. We worried about
20954 not clobbering it when we were saving registers in the prologue.
20955 There's no need to worry here because the static chain is passed
20956 anew to every function. */
20957 int ool_adjust
= (restoring_GPRs_inline
20959 : (info
->first_gp_reg_save
20960 - (FIRST_SAVRES_REGISTER
+1))*8);
20962 if (frame_reg_rtx
== sp_reg_rtx
)
20963 frame_reg_rtx
= gen_rtx_REG (Pmode
, 11);
20964 emit_insn (gen_addsi3 (frame_reg_rtx
, old_frame_reg_rtx
,
20965 GEN_INT (info
->spe_gp_save_offset
20968 /* Keep the invariant that frame_reg_rtx + sp_offset points
20969 at the top of the stack frame. */
20970 sp_offset
= -info
->spe_gp_save_offset
;
20975 if (restoring_GPRs_inline
)
20977 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
20978 if (rs6000_reg_live_or_pic_offset_p (info
->first_gp_reg_save
+ i
))
20980 rtx offset
, addr
, mem
, reg
;
20982 /* We're doing all this to ensure that the immediate offset
20983 fits into the immediate field of 'evldd'. */
20984 gcc_assert (SPE_CONST_OFFSET_OK (spe_offset
+ reg_size
* i
));
20986 offset
= GEN_INT (spe_offset
+ reg_size
* i
);
20987 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
, offset
);
20988 mem
= gen_rtx_MEM (V2SImode
, addr
);
20989 reg
= gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
);
20991 insn
= emit_move_insn (reg
, mem
);
20992 if (DEFAULT_ABI
== ABI_V4
)
20994 if (frame_pointer_needed
20995 && info
->first_gp_reg_save
+ i
20996 == HARD_FRAME_POINTER_REGNUM
)
20998 add_reg_note (insn
, REG_CFA_DEF_CFA
,
20999 plus_constant (frame_reg_rtx
,
21001 RTX_FRAME_RELATED_P (insn
) = 1;
21004 cfa_restores
= alloc_reg_note (REG_CFA_RESTORE
, reg
,
21013 par
= rs6000_make_savres_rtx (info
, gen_rtx_REG (Pmode
, 11),
21015 /*savep=*/false, /*gpr=*/true,
21017 emit_jump_insn (par
);
21018 /* We don't want anybody else emitting things after we jumped
21023 else if (!restoring_GPRs_inline
)
21025 /* We are jumping to an out-of-line function. */
21026 bool can_use_exit
= info
->first_fp_reg_save
== 64;
21029 /* Emit stack reset code if we need it. */
21031 rs6000_emit_stack_reset (info
, sp_reg_rtx
, frame_reg_rtx
,
21032 sp_offset
, can_use_exit
);
21035 emit_insn (gen_add3_insn (gen_rtx_REG (Pmode
, DEFAULT_ABI
== ABI_AIX
21038 GEN_INT (sp_offset
- info
->fp_size
)));
21039 if (REGNO (frame_reg_rtx
) == 11)
21040 sp_offset
+= info
->fp_size
;
21043 par
= rs6000_make_savres_rtx (info
, frame_reg_rtx
,
21044 info
->gp_save_offset
, reg_mode
,
21045 /*savep=*/false, /*gpr=*/true,
21046 /*lr=*/can_use_exit
);
21050 if (info
->cr_save_p
)
21052 rs6000_restore_saved_cr (cr_save_reg
, using_mtcr_multiple
);
21053 if (DEFAULT_ABI
== ABI_V4
)
21055 = alloc_reg_note (REG_CFA_RESTORE
,
21056 gen_rtx_REG (SImode
, CR2_REGNO
),
21060 emit_jump_insn (par
);
21062 /* We don't want anybody else emitting things after we jumped
21067 insn
= emit_insn (par
);
21068 if (DEFAULT_ABI
== ABI_V4
)
21070 if (frame_pointer_needed
)
21072 add_reg_note (insn
, REG_CFA_DEF_CFA
,
21073 plus_constant (frame_reg_rtx
, sp_offset
));
21074 RTX_FRAME_RELATED_P (insn
) = 1;
21077 for (i
= info
->first_gp_reg_save
; i
< 32; i
++)
21079 = alloc_reg_note (REG_CFA_RESTORE
,
21080 gen_rtx_REG (reg_mode
, i
), cfa_restores
);
21083 else if (using_load_multiple
)
21086 p
= rtvec_alloc (32 - info
->first_gp_reg_save
);
21087 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
21089 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
21090 GEN_INT (info
->gp_save_offset
21093 rtx mem
= gen_frame_mem (reg_mode
, addr
);
21094 rtx reg
= gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
);
21096 RTVEC_ELT (p
, i
) = gen_rtx_SET (VOIDmode
, reg
, mem
);
21097 if (DEFAULT_ABI
== ABI_V4
)
21098 cfa_restores
= alloc_reg_note (REG_CFA_RESTORE
, reg
,
21101 insn
= emit_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
21102 if (DEFAULT_ABI
== ABI_V4
&& frame_pointer_needed
)
21104 add_reg_note (insn
, REG_CFA_DEF_CFA
,
21105 plus_constant (frame_reg_rtx
, sp_offset
));
21106 RTX_FRAME_RELATED_P (insn
) = 1;
21111 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
21112 if (rs6000_reg_live_or_pic_offset_p (info
->first_gp_reg_save
+ i
))
21114 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
21115 GEN_INT (info
->gp_save_offset
21118 rtx mem
= gen_frame_mem (reg_mode
, addr
);
21119 rtx reg
= gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
);
21121 insn
= emit_move_insn (reg
, mem
);
21122 if (DEFAULT_ABI
== ABI_V4
)
21124 if (frame_pointer_needed
21125 && info
->first_gp_reg_save
+ i
21126 == HARD_FRAME_POINTER_REGNUM
)
21128 add_reg_note (insn
, REG_CFA_DEF_CFA
,
21129 plus_constant (frame_reg_rtx
, sp_offset
));
21130 RTX_FRAME_RELATED_P (insn
) = 1;
21133 cfa_restores
= alloc_reg_note (REG_CFA_RESTORE
, reg
,
21139 if (restore_lr
&& !restoring_GPRs_inline
)
21141 rtx mem
= gen_frame_mem_offset (Pmode
, frame_reg_rtx
,
21142 info
->lr_save_offset
+ sp_offset
);
21144 emit_move_insn (gen_rtx_REG (Pmode
, 0), mem
);
21145 emit_move_insn (gen_rtx_REG (Pmode
, LR_REGNO
),
21146 gen_rtx_REG (Pmode
, 0));
21149 /* Restore fpr's if we need to do it without calling a function. */
21150 if (restoring_FPRs_inline
)
21151 for (i
= 0; i
< 64 - info
->first_fp_reg_save
; i
++)
21152 if ((df_regs_ever_live_p (info
->first_fp_reg_save
+i
)
21153 && ! call_used_regs
[info
->first_fp_reg_save
+i
]))
21155 rtx addr
, mem
, reg
;
21156 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
21157 GEN_INT (info
->fp_save_offset
21160 mem
= gen_frame_mem (((TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
)
21161 ? DFmode
: SFmode
), addr
);
21162 reg
= gen_rtx_REG (((TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
)
21163 ? DFmode
: SFmode
),
21164 info
->first_fp_reg_save
+ i
);
21166 emit_move_insn (reg
, mem
);
21167 if (DEFAULT_ABI
== ABI_V4
)
21168 cfa_restores
= alloc_reg_note (REG_CFA_RESTORE
, reg
,
21172 /* If we saved cr, restore it here. Just those that were used. */
21173 if (info
->cr_save_p
)
21175 rs6000_restore_saved_cr (cr_save_reg
, using_mtcr_multiple
);
21176 if (DEFAULT_ABI
== ABI_V4
)
21178 = alloc_reg_note (REG_CFA_RESTORE
, gen_rtx_REG (SImode
, CR2_REGNO
),
21182 /* If this is V.4, unwind the stack pointer after all of the loads
21184 insn
= rs6000_emit_stack_reset (info
, sp_reg_rtx
, frame_reg_rtx
,
21185 sp_offset
, !restoring_FPRs_inline
);
21190 REG_NOTES (insn
) = cfa_restores
;
21191 cfa_restores
= NULL_RTX
;
21193 add_reg_note (insn
, REG_CFA_DEF_CFA
, sp_reg_rtx
);
21194 RTX_FRAME_RELATED_P (insn
) = 1;
21197 if (crtl
->calls_eh_return
)
21199 rtx sa
= EH_RETURN_STACKADJ_RTX
;
21200 emit_insn (gen_add3_insn (sp_reg_rtx
, sp_reg_rtx
, sa
));
21206 bool lr
= (strategy
& SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR
) == 0;
21207 if (! restoring_FPRs_inline
)
21208 p
= rtvec_alloc (4 + 64 - info
->first_fp_reg_save
);
21210 p
= rtvec_alloc (2);
21212 RTVEC_ELT (p
, 0) = gen_rtx_RETURN (VOIDmode
);
21213 RTVEC_ELT (p
, 1) = ((restoring_FPRs_inline
|| !lr
)
21214 ? gen_rtx_USE (VOIDmode
, gen_rtx_REG (Pmode
, 65))
21215 : gen_rtx_CLOBBER (VOIDmode
,
21216 gen_rtx_REG (Pmode
, 65)));
21218 /* If we have to restore more than two FP registers, branch to the
21219 restore function. It will return to our caller. */
21220 if (! restoring_FPRs_inline
)
21225 sym
= rs6000_savres_routine_sym (info
,
21229 RTVEC_ELT (p
, 2) = gen_rtx_USE (VOIDmode
, sym
);
21230 RTVEC_ELT (p
, 3) = gen_rtx_USE (VOIDmode
,
21231 gen_rtx_REG (Pmode
,
21232 DEFAULT_ABI
== ABI_AIX
21234 for (i
= 0; i
< 64 - info
->first_fp_reg_save
; i
++)
21237 addr
= gen_rtx_PLUS (Pmode
, sp_reg_rtx
,
21238 GEN_INT (info
->fp_save_offset
+ 8*i
));
21239 mem
= gen_frame_mem (DFmode
, addr
);
21241 RTVEC_ELT (p
, i
+4) =
21242 gen_rtx_SET (VOIDmode
,
21243 gen_rtx_REG (DFmode
, info
->first_fp_reg_save
+ i
),
21248 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
21252 /* Write function epilogue. */
21255 rs6000_output_function_epilogue (FILE *file
,
21256 HOST_WIDE_INT size ATTRIBUTE_UNUSED
)
21258 if (! HAVE_epilogue
)
21260 rtx insn
= get_last_insn ();
21261 /* If the last insn was a BARRIER, we don't have to write anything except
21262 the trace table. */
21263 if (GET_CODE (insn
) == NOTE
)
21264 insn
= prev_nonnote_insn (insn
);
21265 if (insn
== 0 || GET_CODE (insn
) != BARRIER
)
21267 /* This is slightly ugly, but at least we don't have two
21268 copies of the epilogue-emitting code. */
21271 /* A NOTE_INSN_DELETED is supposed to be at the start
21272 and end of the "toplevel" insn chain. */
21273 emit_note (NOTE_INSN_DELETED
);
21274 rs6000_emit_epilogue (FALSE
);
21275 emit_note (NOTE_INSN_DELETED
);
21277 /* Expand INSN_ADDRESSES so final() doesn't crash. */
21281 for (insn
= get_insns (); insn
!= 0; insn
= NEXT_INSN (insn
))
21283 INSN_ADDRESSES_NEW (insn
, addr
);
21288 if (TARGET_DEBUG_STACK
)
21289 debug_rtx_list (get_insns (), 100);
21290 final (get_insns (), file
, FALSE
);
21296 macho_branch_islands ();
21297 /* Mach-O doesn't support labels at the end of objects, so if
21298 it looks like we might want one, insert a NOP. */
21300 rtx insn
= get_last_insn ();
21303 && NOTE_KIND (insn
) != NOTE_INSN_DELETED_LABEL
)
21304 insn
= PREV_INSN (insn
);
21308 && NOTE_KIND (insn
) == NOTE_INSN_DELETED_LABEL
)))
21309 fputs ("\tnop\n", file
);
21313 /* Output a traceback table here. See /usr/include/sys/debug.h for info
21316 We don't output a traceback table if -finhibit-size-directive was
21317 used. The documentation for -finhibit-size-directive reads
21318 ``don't output a @code{.size} assembler directive, or anything
21319 else that would cause trouble if the function is split in the
21320 middle, and the two halves are placed at locations far apart in
21321 memory.'' The traceback table has this property, since it
21322 includes the offset from the start of the function to the
21323 traceback table itself.
21325 System V.4 Powerpc's (and the embedded ABI derived from it) use a
21326 different traceback table. */
21327 if (DEFAULT_ABI
== ABI_AIX
&& ! flag_inhibit_size_directive
21328 && rs6000_traceback
!= traceback_none
&& !cfun
->is_thunk
)
21330 const char *fname
= NULL
;
21331 const char *language_string
= lang_hooks
.name
;
21332 int fixed_parms
= 0, float_parms
= 0, parm_info
= 0;
21334 int optional_tbtab
;
21335 rs6000_stack_t
*info
= rs6000_stack_info ();
21337 if (rs6000_traceback
== traceback_full
)
21338 optional_tbtab
= 1;
21339 else if (rs6000_traceback
== traceback_part
)
21340 optional_tbtab
= 0;
21342 optional_tbtab
= !optimize_size
&& !TARGET_ELF
;
21344 if (optional_tbtab
)
21346 fname
= XSTR (XEXP (DECL_RTL (current_function_decl
), 0), 0);
21347 while (*fname
== '.') /* V.4 encodes . in the name */
21350 /* Need label immediately before tbtab, so we can compute
21351 its offset from the function start. */
21352 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file
, "LT");
21353 ASM_OUTPUT_LABEL (file
, fname
);
21356 /* The .tbtab pseudo-op can only be used for the first eight
21357 expressions, since it can't handle the possibly variable
21358 length fields that follow. However, if you omit the optional
21359 fields, the assembler outputs zeros for all optional fields
21360 anyways, giving each variable length field is minimum length
21361 (as defined in sys/debug.h). Thus we can not use the .tbtab
21362 pseudo-op at all. */
21364 /* An all-zero word flags the start of the tbtab, for debuggers
21365 that have to find it by searching forward from the entry
21366 point or from the current pc. */
21367 fputs ("\t.long 0\n", file
);
21369 /* Tbtab format type. Use format type 0. */
21370 fputs ("\t.byte 0,", file
);
21372 /* Language type. Unfortunately, there does not seem to be any
21373 official way to discover the language being compiled, so we
21374 use language_string.
21375 C is 0. Fortran is 1. Pascal is 2. Ada is 3. C++ is 9.
21376 Java is 13. Objective-C is 14. Objective-C++ isn't assigned
21377 a number, so for now use 9. LTO isn't assigned a number either,
21378 so for now use 0. */
21379 if (! strcmp (language_string
, "GNU C")
21380 || ! strcmp (language_string
, "GNU GIMPLE"))
21382 else if (! strcmp (language_string
, "GNU F77")
21383 || ! strcmp (language_string
, "GNU Fortran"))
21385 else if (! strcmp (language_string
, "GNU Pascal"))
21387 else if (! strcmp (language_string
, "GNU Ada"))
21389 else if (! strcmp (language_string
, "GNU C++")
21390 || ! strcmp (language_string
, "GNU Objective-C++"))
21392 else if (! strcmp (language_string
, "GNU Java"))
21394 else if (! strcmp (language_string
, "GNU Objective-C"))
21397 gcc_unreachable ();
21398 fprintf (file
, "%d,", i
);
21400 /* 8 single bit fields: global linkage (not set for C extern linkage,
21401 apparently a PL/I convention?), out-of-line epilogue/prologue, offset
21402 from start of procedure stored in tbtab, internal function, function
21403 has controlled storage, function has no toc, function uses fp,
21404 function logs/aborts fp operations. */
21405 /* Assume that fp operations are used if any fp reg must be saved. */
21406 fprintf (file
, "%d,",
21407 (optional_tbtab
<< 5) | ((info
->first_fp_reg_save
!= 64) << 1));
21409 /* 6 bitfields: function is interrupt handler, name present in
21410 proc table, function calls alloca, on condition directives
21411 (controls stack walks, 3 bits), saves condition reg, saves
21413 /* The `function calls alloca' bit seems to be set whenever reg 31 is
21414 set up as a frame pointer, even when there is no alloca call. */
21415 fprintf (file
, "%d,",
21416 ((optional_tbtab
<< 6)
21417 | ((optional_tbtab
& frame_pointer_needed
) << 5)
21418 | (info
->cr_save_p
<< 1)
21419 | (info
->lr_save_p
)));
21421 /* 3 bitfields: saves backchain, fixup code, number of fpr saved
21423 fprintf (file
, "%d,",
21424 (info
->push_p
<< 7) | (64 - info
->first_fp_reg_save
));
21426 /* 2 bitfields: spare bits (2 bits), number of gpr saved (6 bits). */
21427 fprintf (file
, "%d,", (32 - first_reg_to_save ()));
21429 if (optional_tbtab
)
21431 /* Compute the parameter info from the function decl argument
21434 int next_parm_info_bit
= 31;
21436 for (decl
= DECL_ARGUMENTS (current_function_decl
);
21437 decl
; decl
= DECL_CHAIN (decl
))
21439 rtx parameter
= DECL_INCOMING_RTL (decl
);
21440 enum machine_mode mode
= GET_MODE (parameter
);
21442 if (GET_CODE (parameter
) == REG
)
21444 if (SCALAR_FLOAT_MODE_P (mode
))
21465 gcc_unreachable ();
21468 /* If only one bit will fit, don't or in this entry. */
21469 if (next_parm_info_bit
> 0)
21470 parm_info
|= (bits
<< (next_parm_info_bit
- 1));
21471 next_parm_info_bit
-= 2;
21475 fixed_parms
+= ((GET_MODE_SIZE (mode
)
21476 + (UNITS_PER_WORD
- 1))
21478 next_parm_info_bit
-= 1;
21484 /* Number of fixed point parameters. */
21485 /* This is actually the number of words of fixed point parameters; thus
21486 an 8 byte struct counts as 2; and thus the maximum value is 8. */
21487 fprintf (file
, "%d,", fixed_parms
);
21489 /* 2 bitfields: number of floating point parameters (7 bits), parameters
21491 /* This is actually the number of fp registers that hold parameters;
21492 and thus the maximum value is 13. */
21493 /* Set parameters on stack bit if parameters are not in their original
21494 registers, regardless of whether they are on the stack? Xlc
21495 seems to set the bit when not optimizing. */
21496 fprintf (file
, "%d\n", ((float_parms
<< 1) | (! optimize
)));
21498 if (! optional_tbtab
)
21501 /* Optional fields follow. Some are variable length. */
21503 /* Parameter types, left adjusted bit fields: 0 fixed, 10 single float,
21504 11 double float. */
21505 /* There is an entry for each parameter in a register, in the order that
21506 they occur in the parameter list. Any intervening arguments on the
21507 stack are ignored. If the list overflows a long (max possible length
21508 34 bits) then completely leave off all elements that don't fit. */
21509 /* Only emit this long if there was at least one parameter. */
21510 if (fixed_parms
|| float_parms
)
21511 fprintf (file
, "\t.long %d\n", parm_info
);
21513 /* Offset from start of code to tb table. */
21514 fputs ("\t.long ", file
);
21515 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file
, "LT");
21516 RS6000_OUTPUT_BASENAME (file
, fname
);
21518 rs6000_output_function_entry (file
, fname
);
21521 /* Interrupt handler mask. */
21522 /* Omit this long, since we never set the interrupt handler bit
21525 /* Number of CTL (controlled storage) anchors. */
21526 /* Omit this long, since the has_ctl bit is never set above. */
21528 /* Displacement into stack of each CTL anchor. */
21529 /* Omit this list of longs, because there are no CTL anchors. */
21531 /* Length of function name. */
21534 fprintf (file
, "\t.short %d\n", (int) strlen (fname
));
21536 /* Function name. */
21537 assemble_string (fname
, strlen (fname
));
21539 /* Register for alloca automatic storage; this is always reg 31.
21540 Only emit this if the alloca bit was set above. */
21541 if (frame_pointer_needed
)
21542 fputs ("\t.byte 31\n", file
);
21544 fputs ("\t.align 2\n", file
);
21548 /* A C compound statement that outputs the assembler code for a thunk
21549 function, used to implement C++ virtual function calls with
21550 multiple inheritance. The thunk acts as a wrapper around a virtual
21551 function, adjusting the implicit object parameter before handing
21552 control off to the real function.
21554 First, emit code to add the integer DELTA to the location that
21555 contains the incoming first argument. Assume that this argument
21556 contains a pointer, and is the one used to pass the `this' pointer
21557 in C++. This is the incoming argument *before* the function
21558 prologue, e.g. `%o0' on a sparc. The addition must preserve the
21559 values of all other incoming arguments.
21561 After the addition, emit code to jump to FUNCTION, which is a
21562 `FUNCTION_DECL'. This is a direct pure jump, not a call, and does
21563 not touch the return address. Hence returning from FUNCTION will
21564 return to whoever called the current `thunk'.
21566 The effect must be as if FUNCTION had been called directly with the
21567 adjusted first argument. This macro is responsible for emitting
21568 all of the code for a thunk function; output_function_prologue()
21569 and output_function_epilogue() are not invoked.
21571 The THUNK_FNDECL is redundant. (DELTA and FUNCTION have already
21572 been extracted from it.) It might possibly be useful on some
21573 targets, but probably not.
21575 If you do not define this macro, the target-independent code in the
21576 C++ frontend will generate a less efficient heavyweight thunk that
21577 calls FUNCTION instead of jumping to it. The generic approach does
21578 not support varargs. */
21581 rs6000_output_mi_thunk (FILE *file
, tree thunk_fndecl ATTRIBUTE_UNUSED
,
21582 HOST_WIDE_INT delta
, HOST_WIDE_INT vcall_offset
,
21585 rtx this_rtx
, insn
, funexp
;
21587 reload_completed
= 1;
21588 epilogue_completed
= 1;
21590 /* Mark the end of the (empty) prologue. */
21591 emit_note (NOTE_INSN_PROLOGUE_END
);
21593 /* Find the "this" pointer. If the function returns a structure,
21594 the structure return pointer is in r3. */
21595 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function
)), function
))
21596 this_rtx
= gen_rtx_REG (Pmode
, 4);
21598 this_rtx
= gen_rtx_REG (Pmode
, 3);
21600 /* Apply the constant offset, if required. */
21602 emit_insn (gen_add3_insn (this_rtx
, this_rtx
, GEN_INT (delta
)));
21604 /* Apply the offset from the vtable, if required. */
21607 rtx vcall_offset_rtx
= GEN_INT (vcall_offset
);
21608 rtx tmp
= gen_rtx_REG (Pmode
, 12);
21610 emit_move_insn (tmp
, gen_rtx_MEM (Pmode
, this_rtx
));
21611 if (((unsigned HOST_WIDE_INT
) vcall_offset
) + 0x8000 >= 0x10000)
21613 emit_insn (gen_add3_insn (tmp
, tmp
, vcall_offset_rtx
));
21614 emit_move_insn (tmp
, gen_rtx_MEM (Pmode
, tmp
));
21618 rtx loc
= gen_rtx_PLUS (Pmode
, tmp
, vcall_offset_rtx
);
21620 emit_move_insn (tmp
, gen_rtx_MEM (Pmode
, loc
));
21622 emit_insn (gen_add3_insn (this_rtx
, this_rtx
, tmp
));
21625 /* Generate a tail call to the target function. */
21626 if (!TREE_USED (function
))
21628 assemble_external (function
);
21629 TREE_USED (function
) = 1;
21631 funexp
= XEXP (DECL_RTL (function
), 0);
21632 funexp
= gen_rtx_MEM (FUNCTION_MODE
, funexp
);
21635 if (MACHOPIC_INDIRECT
)
21636 funexp
= machopic_indirect_call_target (funexp
);
21639 /* gen_sibcall expects reload to convert scratch pseudo to LR so we must
21640 generate sibcall RTL explicitly. */
21641 insn
= emit_call_insn (
21642 gen_rtx_PARALLEL (VOIDmode
,
21644 gen_rtx_CALL (VOIDmode
,
21645 funexp
, const0_rtx
),
21646 gen_rtx_USE (VOIDmode
, const0_rtx
),
21647 gen_rtx_USE (VOIDmode
,
21648 gen_rtx_REG (SImode
,
21650 gen_rtx_RETURN (VOIDmode
))));
21651 SIBLING_CALL_P (insn
) = 1;
21654 /* Run just enough of rest_of_compilation to get the insns emitted.
21655 There's not really enough bulk here to make other passes such as
21656 instruction scheduling worth while. Note that use_thunk calls
21657 assemble_start_function and assemble_end_function. */
21658 insn
= get_insns ();
21659 insn_locators_alloc ();
21660 shorten_branches (insn
);
21661 final_start_function (insn
, file
, 1);
21662 final (insn
, file
, 1);
21663 final_end_function ();
21665 reload_completed
= 0;
21666 epilogue_completed
= 0;
21669 /* A quick summary of the various types of 'constant-pool tables'
21672 Target Flags Name One table per
21673 AIX (none) AIX TOC object file
21674 AIX -mfull-toc AIX TOC object file
21675 AIX -mminimal-toc AIX minimal TOC translation unit
21676 SVR4/EABI (none) SVR4 SDATA object file
21677 SVR4/EABI -fpic SVR4 pic object file
21678 SVR4/EABI -fPIC SVR4 PIC translation unit
21679 SVR4/EABI -mrelocatable EABI TOC function
21680 SVR4/EABI -maix AIX TOC object file
21681 SVR4/EABI -maix -mminimal-toc
21682 AIX minimal TOC translation unit
21684 Name Reg. Set by entries contains:
21685 made by addrs? fp? sum?
21687 AIX TOC 2 crt0 as Y option option
21688 AIX minimal TOC 30 prolog gcc Y Y option
21689 SVR4 SDATA 13 crt0 gcc N Y N
21690 SVR4 pic 30 prolog ld Y not yet N
21691 SVR4 PIC 30 prolog gcc Y option option
21692 EABI TOC 30 prolog gcc Y option option
21696 /* Hash functions for the hash table. */
21699 rs6000_hash_constant (rtx k
)
21701 enum rtx_code code
= GET_CODE (k
);
21702 enum machine_mode mode
= GET_MODE (k
);
21703 unsigned result
= (code
<< 3) ^ mode
;
21704 const char *format
;
21707 format
= GET_RTX_FORMAT (code
);
21708 flen
= strlen (format
);
21714 return result
* 1231 + (unsigned) INSN_UID (XEXP (k
, 0));
21717 if (mode
!= VOIDmode
)
21718 return real_hash (CONST_DOUBLE_REAL_VALUE (k
)) * result
;
21730 for (; fidx
< flen
; fidx
++)
21731 switch (format
[fidx
])
21736 const char *str
= XSTR (k
, fidx
);
21737 len
= strlen (str
);
21738 result
= result
* 613 + len
;
21739 for (i
= 0; i
< len
; i
++)
21740 result
= result
* 613 + (unsigned) str
[i
];
21745 result
= result
* 1231 + rs6000_hash_constant (XEXP (k
, fidx
));
21749 result
= result
* 613 + (unsigned) XINT (k
, fidx
);
21752 if (sizeof (unsigned) >= sizeof (HOST_WIDE_INT
))
21753 result
= result
* 613 + (unsigned) XWINT (k
, fidx
);
21757 for (i
= 0; i
< sizeof (HOST_WIDE_INT
) / sizeof (unsigned); i
++)
21758 result
= result
* 613 + (unsigned) (XWINT (k
, fidx
)
21765 gcc_unreachable ();
21772 toc_hash_function (const void *hash_entry
)
21774 const struct toc_hash_struct
*thc
=
21775 (const struct toc_hash_struct
*) hash_entry
;
21776 return rs6000_hash_constant (thc
->key
) ^ thc
->key_mode
;
21779 /* Compare H1 and H2 for equivalence. */
21782 toc_hash_eq (const void *h1
, const void *h2
)
21784 rtx r1
= ((const struct toc_hash_struct
*) h1
)->key
;
21785 rtx r2
= ((const struct toc_hash_struct
*) h2
)->key
;
21787 if (((const struct toc_hash_struct
*) h1
)->key_mode
21788 != ((const struct toc_hash_struct
*) h2
)->key_mode
)
21791 return rtx_equal_p (r1
, r2
);
21794 /* These are the names given by the C++ front-end to vtables, and
21795 vtable-like objects. Ideally, this logic should not be here;
21796 instead, there should be some programmatic way of inquiring as
21797 to whether or not an object is a vtable. */
21799 #define VTABLE_NAME_P(NAME) \
21800 (strncmp ("_vt.", name, strlen ("_vt.")) == 0 \
21801 || strncmp ("_ZTV", name, strlen ("_ZTV")) == 0 \
21802 || strncmp ("_ZTT", name, strlen ("_ZTT")) == 0 \
21803 || strncmp ("_ZTI", name, strlen ("_ZTI")) == 0 \
21804 || strncmp ("_ZTC", name, strlen ("_ZTC")) == 0)
21806 #ifdef NO_DOLLAR_IN_LABEL
21807 /* Return a GGC-allocated character string translating dollar signs in
21808 input NAME to underscores. Used by XCOFF ASM_OUTPUT_LABELREF. */
21811 rs6000_xcoff_strip_dollar (const char *name
)
21816 p
= strchr (name
, '$');
21818 if (p
== 0 || p
== name
)
21821 len
= strlen (name
);
21822 strip
= (char *) alloca (len
+ 1);
21823 strcpy (strip
, name
);
21824 p
= strchr (strip
, '$');
21828 p
= strchr (p
+ 1, '$');
21831 return ggc_alloc_string (strip
, len
);
21836 rs6000_output_symbol_ref (FILE *file
, rtx x
)
21838 /* Currently C++ toc references to vtables can be emitted before it
21839 is decided whether the vtable is public or private. If this is
21840 the case, then the linker will eventually complain that there is
21841 a reference to an unknown section. Thus, for vtables only,
21842 we emit the TOC reference to reference the symbol and not the
21844 const char *name
= XSTR (x
, 0);
21846 if (VTABLE_NAME_P (name
))
21848 RS6000_OUTPUT_BASENAME (file
, name
);
21851 assemble_name (file
, name
);
21854 /* Output a TOC entry. We derive the entry name from what is being
21858 output_toc (FILE *file
, rtx x
, int labelno
, enum machine_mode mode
)
21861 const char *name
= buf
;
21863 HOST_WIDE_INT offset
= 0;
21865 gcc_assert (!TARGET_NO_TOC
);
21867 /* When the linker won't eliminate them, don't output duplicate
21868 TOC entries (this happens on AIX if there is any kind of TOC,
21869 and on SVR4 under -fPIC or -mrelocatable). Don't do this for
21871 if (TARGET_TOC
&& GET_CODE (x
) != LABEL_REF
)
21873 struct toc_hash_struct
*h
;
21876 /* Create toc_hash_table. This can't be done at OVERRIDE_OPTIONS
21877 time because GGC is not initialized at that point. */
21878 if (toc_hash_table
== NULL
)
21879 toc_hash_table
= htab_create_ggc (1021, toc_hash_function
,
21880 toc_hash_eq
, NULL
);
21882 h
= ggc_alloc_toc_hash_struct ();
21884 h
->key_mode
= mode
;
21885 h
->labelno
= labelno
;
21887 found
= htab_find_slot (toc_hash_table
, h
, INSERT
);
21888 if (*found
== NULL
)
21890 else /* This is indeed a duplicate.
21891 Set this label equal to that label. */
21893 fputs ("\t.set ", file
);
21894 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file
, "LC");
21895 fprintf (file
, "%d,", labelno
);
21896 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file
, "LC");
21897 fprintf (file
, "%d\n", ((*(const struct toc_hash_struct
**)
21903 /* If we're going to put a double constant in the TOC, make sure it's
21904 aligned properly when strict alignment is on. */
21905 if (GET_CODE (x
) == CONST_DOUBLE
21906 && STRICT_ALIGNMENT
21907 && GET_MODE_BITSIZE (mode
) >= 64
21908 && ! (TARGET_NO_FP_IN_TOC
&& ! TARGET_MINIMAL_TOC
)) {
21909 ASM_OUTPUT_ALIGN (file
, 3);
21912 (*targetm
.asm_out
.internal_label
) (file
, "LC", labelno
);
21914 /* Handle FP constants specially. Note that if we have a minimal
21915 TOC, things we put here aren't actually in the TOC, so we can allow
21917 if (GET_CODE (x
) == CONST_DOUBLE
&&
21918 (GET_MODE (x
) == TFmode
|| GET_MODE (x
) == TDmode
))
21920 REAL_VALUE_TYPE rv
;
21923 REAL_VALUE_FROM_CONST_DOUBLE (rv
, x
);
21924 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x
)))
21925 REAL_VALUE_TO_TARGET_DECIMAL128 (rv
, k
);
21927 REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv
, k
);
21931 if (TARGET_MINIMAL_TOC
)
21932 fputs (DOUBLE_INT_ASM_OP
, file
);
21934 fprintf (file
, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
21935 k
[0] & 0xffffffff, k
[1] & 0xffffffff,
21936 k
[2] & 0xffffffff, k
[3] & 0xffffffff);
21937 fprintf (file
, "0x%lx%08lx,0x%lx%08lx\n",
21938 k
[0] & 0xffffffff, k
[1] & 0xffffffff,
21939 k
[2] & 0xffffffff, k
[3] & 0xffffffff);
21944 if (TARGET_MINIMAL_TOC
)
21945 fputs ("\t.long ", file
);
21947 fprintf (file
, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
21948 k
[0] & 0xffffffff, k
[1] & 0xffffffff,
21949 k
[2] & 0xffffffff, k
[3] & 0xffffffff);
21950 fprintf (file
, "0x%lx,0x%lx,0x%lx,0x%lx\n",
21951 k
[0] & 0xffffffff, k
[1] & 0xffffffff,
21952 k
[2] & 0xffffffff, k
[3] & 0xffffffff);
21956 else if (GET_CODE (x
) == CONST_DOUBLE
&&
21957 (GET_MODE (x
) == DFmode
|| GET_MODE (x
) == DDmode
))
21959 REAL_VALUE_TYPE rv
;
21962 REAL_VALUE_FROM_CONST_DOUBLE (rv
, x
);
21964 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x
)))
21965 REAL_VALUE_TO_TARGET_DECIMAL64 (rv
, k
);
21967 REAL_VALUE_TO_TARGET_DOUBLE (rv
, k
);
21971 if (TARGET_MINIMAL_TOC
)
21972 fputs (DOUBLE_INT_ASM_OP
, file
);
21974 fprintf (file
, "\t.tc FD_%lx_%lx[TC],",
21975 k
[0] & 0xffffffff, k
[1] & 0xffffffff);
21976 fprintf (file
, "0x%lx%08lx\n",
21977 k
[0] & 0xffffffff, k
[1] & 0xffffffff);
21982 if (TARGET_MINIMAL_TOC
)
21983 fputs ("\t.long ", file
);
21985 fprintf (file
, "\t.tc FD_%lx_%lx[TC],",
21986 k
[0] & 0xffffffff, k
[1] & 0xffffffff);
21987 fprintf (file
, "0x%lx,0x%lx\n",
21988 k
[0] & 0xffffffff, k
[1] & 0xffffffff);
21992 else if (GET_CODE (x
) == CONST_DOUBLE
&&
21993 (GET_MODE (x
) == SFmode
|| GET_MODE (x
) == SDmode
))
21995 REAL_VALUE_TYPE rv
;
21998 REAL_VALUE_FROM_CONST_DOUBLE (rv
, x
);
21999 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x
)))
22000 REAL_VALUE_TO_TARGET_DECIMAL32 (rv
, l
);
22002 REAL_VALUE_TO_TARGET_SINGLE (rv
, l
);
22006 if (TARGET_MINIMAL_TOC
)
22007 fputs (DOUBLE_INT_ASM_OP
, file
);
22009 fprintf (file
, "\t.tc FS_%lx[TC],", l
& 0xffffffff);
22010 fprintf (file
, "0x%lx00000000\n", l
& 0xffffffff);
22015 if (TARGET_MINIMAL_TOC
)
22016 fputs ("\t.long ", file
);
22018 fprintf (file
, "\t.tc FS_%lx[TC],", l
& 0xffffffff);
22019 fprintf (file
, "0x%lx\n", l
& 0xffffffff);
22023 else if (GET_MODE (x
) == VOIDmode
22024 && (GET_CODE (x
) == CONST_INT
|| GET_CODE (x
) == CONST_DOUBLE
))
22026 unsigned HOST_WIDE_INT low
;
22027 HOST_WIDE_INT high
;
22029 if (GET_CODE (x
) == CONST_DOUBLE
)
22031 low
= CONST_DOUBLE_LOW (x
);
22032 high
= CONST_DOUBLE_HIGH (x
);
22035 #if HOST_BITS_PER_WIDE_INT == 32
22038 high
= (low
& 0x80000000) ? ~0 : 0;
22042 low
= INTVAL (x
) & 0xffffffff;
22043 high
= (HOST_WIDE_INT
) INTVAL (x
) >> 32;
22047 /* TOC entries are always Pmode-sized, but since this
22048 is a bigendian machine then if we're putting smaller
22049 integer constants in the TOC we have to pad them.
22050 (This is still a win over putting the constants in
22051 a separate constant pool, because then we'd have
22052 to have both a TOC entry _and_ the actual constant.)
22054 For a 32-bit target, CONST_INT values are loaded and shifted
22055 entirely within `low' and can be stored in one TOC entry. */
22057 /* It would be easy to make this work, but it doesn't now. */
22058 gcc_assert (!TARGET_64BIT
|| POINTER_SIZE
>= GET_MODE_BITSIZE (mode
));
22060 if (POINTER_SIZE
> GET_MODE_BITSIZE (mode
))
22062 #if HOST_BITS_PER_WIDE_INT == 32
22063 lshift_double (low
, high
, POINTER_SIZE
- GET_MODE_BITSIZE (mode
),
22064 POINTER_SIZE
, &low
, &high
, 0);
22067 low
<<= POINTER_SIZE
- GET_MODE_BITSIZE (mode
);
22068 high
= (HOST_WIDE_INT
) low
>> 32;
22075 if (TARGET_MINIMAL_TOC
)
22076 fputs (DOUBLE_INT_ASM_OP
, file
);
22078 fprintf (file
, "\t.tc ID_%lx_%lx[TC],",
22079 (long) high
& 0xffffffff, (long) low
& 0xffffffff);
22080 fprintf (file
, "0x%lx%08lx\n",
22081 (long) high
& 0xffffffff, (long) low
& 0xffffffff);
22086 if (POINTER_SIZE
< GET_MODE_BITSIZE (mode
))
22088 if (TARGET_MINIMAL_TOC
)
22089 fputs ("\t.long ", file
);
22091 fprintf (file
, "\t.tc ID_%lx_%lx[TC],",
22092 (long) high
& 0xffffffff, (long) low
& 0xffffffff);
22093 fprintf (file
, "0x%lx,0x%lx\n",
22094 (long) high
& 0xffffffff, (long) low
& 0xffffffff);
22098 if (TARGET_MINIMAL_TOC
)
22099 fputs ("\t.long ", file
);
22101 fprintf (file
, "\t.tc IS_%lx[TC],", (long) low
& 0xffffffff);
22102 fprintf (file
, "0x%lx\n", (long) low
& 0xffffffff);
22108 if (GET_CODE (x
) == CONST
)
22110 gcc_assert (GET_CODE (XEXP (x
, 0)) == PLUS
22111 && GET_CODE (XEXP (XEXP (x
, 0), 1)) == CONST_INT
);
22113 base
= XEXP (XEXP (x
, 0), 0);
22114 offset
= INTVAL (XEXP (XEXP (x
, 0), 1));
22117 switch (GET_CODE (base
))
22120 name
= XSTR (base
, 0);
22124 ASM_GENERATE_INTERNAL_LABEL (buf
, "L",
22125 CODE_LABEL_NUMBER (XEXP (base
, 0)));
22129 ASM_GENERATE_INTERNAL_LABEL (buf
, "L", CODE_LABEL_NUMBER (base
));
22133 gcc_unreachable ();
22136 if (TARGET_MINIMAL_TOC
)
22137 fputs (TARGET_32BIT
? "\t.long " : DOUBLE_INT_ASM_OP
, file
);
22140 fputs ("\t.tc ", file
);
22141 RS6000_OUTPUT_BASENAME (file
, name
);
22144 fprintf (file
, ".N" HOST_WIDE_INT_PRINT_UNSIGNED
, - offset
);
22146 fprintf (file
, ".P" HOST_WIDE_INT_PRINT_UNSIGNED
, offset
);
22148 fputs ("[TC],", file
);
22151 /* Currently C++ toc references to vtables can be emitted before it
22152 is decided whether the vtable is public or private. If this is
22153 the case, then the linker will eventually complain that there is
22154 a TOC reference to an unknown section. Thus, for vtables only,
22155 we emit the TOC reference to reference the symbol and not the
22157 if (VTABLE_NAME_P (name
))
22159 RS6000_OUTPUT_BASENAME (file
, name
);
22161 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, offset
);
22162 else if (offset
> 0)
22163 fprintf (file
, "+" HOST_WIDE_INT_PRINT_DEC
, offset
);
22166 output_addr_const (file
, x
);
22170 /* Output an assembler pseudo-op to write an ASCII string of N characters
22171 starting at P to FILE.
22173 On the RS/6000, we have to do this using the .byte operation and
22174 write out special characters outside the quoted string.
22175 Also, the assembler is broken; very long strings are truncated,
22176 so we must artificially break them up early. */
22179 output_ascii (FILE *file
, const char *p
, int n
)
22182 int i
, count_string
;
22183 const char *for_string
= "\t.byte \"";
22184 const char *for_decimal
= "\t.byte ";
22185 const char *to_close
= NULL
;
22188 for (i
= 0; i
< n
; i
++)
22191 if (c
>= ' ' && c
< 0177)
22194 fputs (for_string
, file
);
22197 /* Write two quotes to get one. */
22205 for_decimal
= "\"\n\t.byte ";
22209 if (count_string
>= 512)
22211 fputs (to_close
, file
);
22213 for_string
= "\t.byte \"";
22214 for_decimal
= "\t.byte ";
22222 fputs (for_decimal
, file
);
22223 fprintf (file
, "%d", c
);
22225 for_string
= "\n\t.byte \"";
22226 for_decimal
= ", ";
22232 /* Now close the string if we have written one. Then end the line. */
22234 fputs (to_close
, file
);
22237 /* Generate a unique section name for FILENAME for a section type
22238 represented by SECTION_DESC. Output goes into BUF.
22240 SECTION_DESC can be any string, as long as it is different for each
22241 possible section type.
22243 We name the section in the same manner as xlc. The name begins with an
22244 underscore followed by the filename (after stripping any leading directory
22245 names) with the last period replaced by the string SECTION_DESC. If
22246 FILENAME does not contain a period, SECTION_DESC is appended to the end of
22250 rs6000_gen_section_name (char **buf
, const char *filename
,
22251 const char *section_desc
)
22253 const char *q
, *after_last_slash
, *last_period
= 0;
22257 after_last_slash
= filename
;
22258 for (q
= filename
; *q
; q
++)
22261 after_last_slash
= q
+ 1;
22262 else if (*q
== '.')
22266 len
= strlen (after_last_slash
) + strlen (section_desc
) + 2;
22267 *buf
= (char *) xmalloc (len
);
22272 for (q
= after_last_slash
; *q
; q
++)
22274 if (q
== last_period
)
22276 strcpy (p
, section_desc
);
22277 p
+= strlen (section_desc
);
22281 else if (ISALNUM (*q
))
22285 if (last_period
== 0)
22286 strcpy (p
, section_desc
);
22291 /* Emit profile function. */
22294 output_profile_hook (int labelno ATTRIBUTE_UNUSED
)
22296 /* Non-standard profiling for kernels, which just saves LR then calls
22297 _mcount without worrying about arg saves. The idea is to change
22298 the function prologue as little as possible as it isn't easy to
22299 account for arg save/restore code added just for _mcount. */
22300 if (TARGET_PROFILE_KERNEL
)
22303 if (DEFAULT_ABI
== ABI_AIX
)
22305 #ifndef NO_PROFILE_COUNTERS
22306 # define NO_PROFILE_COUNTERS 0
22308 if (NO_PROFILE_COUNTERS
)
22309 emit_library_call (init_one_libfunc (RS6000_MCOUNT
),
22310 LCT_NORMAL
, VOIDmode
, 0);
22314 const char *label_name
;
22317 ASM_GENERATE_INTERNAL_LABEL (buf
, "LP", labelno
);
22318 label_name
= (*targetm
.strip_name_encoding
) (ggc_strdup (buf
));
22319 fun
= gen_rtx_SYMBOL_REF (Pmode
, label_name
);
22321 emit_library_call (init_one_libfunc (RS6000_MCOUNT
),
22322 LCT_NORMAL
, VOIDmode
, 1, fun
, Pmode
);
22325 else if (DEFAULT_ABI
== ABI_DARWIN
)
22327 const char *mcount_name
= RS6000_MCOUNT
;
22328 int caller_addr_regno
= LR_REGNO
;
22330 /* Be conservative and always set this, at least for now. */
22331 crtl
->uses_pic_offset_table
= 1;
22334 /* For PIC code, set up a stub and collect the caller's address
22335 from r0, which is where the prologue puts it. */
22336 if (MACHOPIC_INDIRECT
22337 && crtl
->uses_pic_offset_table
)
22338 caller_addr_regno
= 0;
22340 emit_library_call (gen_rtx_SYMBOL_REF (Pmode
, mcount_name
),
22341 LCT_NORMAL
, VOIDmode
, 1,
22342 gen_rtx_REG (Pmode
, caller_addr_regno
), Pmode
);
22346 /* Write function profiler code. */
22349 output_function_profiler (FILE *file
, int labelno
)
22353 switch (DEFAULT_ABI
)
22356 gcc_unreachable ();
22361 warning (0, "no profiling of 64-bit code for this ABI");
22364 ASM_GENERATE_INTERNAL_LABEL (buf
, "LP", labelno
);
22365 fprintf (file
, "\tmflr %s\n", reg_names
[0]);
22366 if (NO_PROFILE_COUNTERS
)
22368 asm_fprintf (file
, "\t{st|stw} %s,4(%s)\n",
22369 reg_names
[0], reg_names
[1]);
22371 else if (TARGET_SECURE_PLT
&& flag_pic
)
22373 asm_fprintf (file
, "\tbcl 20,31,1f\n1:\n\t{st|stw} %s,4(%s)\n",
22374 reg_names
[0], reg_names
[1]);
22375 asm_fprintf (file
, "\tmflr %s\n", reg_names
[12]);
22376 asm_fprintf (file
, "\t{cau|addis} %s,%s,",
22377 reg_names
[12], reg_names
[12]);
22378 assemble_name (file
, buf
);
22379 asm_fprintf (file
, "-1b@ha\n\t{cal|la} %s,", reg_names
[0]);
22380 assemble_name (file
, buf
);
22381 asm_fprintf (file
, "-1b@l(%s)\n", reg_names
[12]);
22383 else if (flag_pic
== 1)
22385 fputs ("\tbl _GLOBAL_OFFSET_TABLE_@local-4\n", file
);
22386 asm_fprintf (file
, "\t{st|stw} %s,4(%s)\n",
22387 reg_names
[0], reg_names
[1]);
22388 asm_fprintf (file
, "\tmflr %s\n", reg_names
[12]);
22389 asm_fprintf (file
, "\t{l|lwz} %s,", reg_names
[0]);
22390 assemble_name (file
, buf
);
22391 asm_fprintf (file
, "@got(%s)\n", reg_names
[12]);
22393 else if (flag_pic
> 1)
22395 asm_fprintf (file
, "\t{st|stw} %s,4(%s)\n",
22396 reg_names
[0], reg_names
[1]);
22397 /* Now, we need to get the address of the label. */
22398 fputs ("\tbcl 20,31,1f\n\t.long ", file
);
22399 assemble_name (file
, buf
);
22400 fputs ("-.\n1:", file
);
22401 asm_fprintf (file
, "\tmflr %s\n", reg_names
[11]);
22402 asm_fprintf (file
, "\t{l|lwz} %s,0(%s)\n",
22403 reg_names
[0], reg_names
[11]);
22404 asm_fprintf (file
, "\t{cax|add} %s,%s,%s\n",
22405 reg_names
[0], reg_names
[0], reg_names
[11]);
22409 asm_fprintf (file
, "\t{liu|lis} %s,", reg_names
[12]);
22410 assemble_name (file
, buf
);
22411 fputs ("@ha\n", file
);
22412 asm_fprintf (file
, "\t{st|stw} %s,4(%s)\n",
22413 reg_names
[0], reg_names
[1]);
22414 asm_fprintf (file
, "\t{cal|la} %s,", reg_names
[0]);
22415 assemble_name (file
, buf
);
22416 asm_fprintf (file
, "@l(%s)\n", reg_names
[12]);
22419 /* ABI_V4 saves the static chain reg with ASM_OUTPUT_REG_PUSH. */
22420 fprintf (file
, "\tbl %s%s\n",
22421 RS6000_MCOUNT
, flag_pic
? "@plt" : "");
22426 if (!TARGET_PROFILE_KERNEL
)
22428 /* Don't do anything, done in output_profile_hook (). */
22432 gcc_assert (!TARGET_32BIT
);
22434 asm_fprintf (file
, "\tmflr %s\n", reg_names
[0]);
22435 asm_fprintf (file
, "\tstd %s,16(%s)\n", reg_names
[0], reg_names
[1]);
22437 if (cfun
->static_chain_decl
!= NULL
)
22439 asm_fprintf (file
, "\tstd %s,24(%s)\n",
22440 reg_names
[STATIC_CHAIN_REGNUM
], reg_names
[1]);
22441 fprintf (file
, "\tbl %s\n", RS6000_MCOUNT
);
22442 asm_fprintf (file
, "\tld %s,24(%s)\n",
22443 reg_names
[STATIC_CHAIN_REGNUM
], reg_names
[1]);
22446 fprintf (file
, "\tbl %s\n", RS6000_MCOUNT
);
22454 /* The following variable value is the last issued insn. */
22456 static rtx last_scheduled_insn
;
22458 /* The following variable helps to balance issuing of load and
22459 store instructions */
22461 static int load_store_pendulum
;
22463 /* Power4 load update and store update instructions are cracked into a
22464 load or store and an integer insn which are executed in the same cycle.
22465 Branches have their own dispatch slot which does not count against the
22466 GCC issue rate, but it changes the program flow so there are no other
22467 instructions to issue in this cycle. */
22470 rs6000_variable_issue_1 (rtx insn
, int more
)
22472 last_scheduled_insn
= insn
;
22473 if (GET_CODE (PATTERN (insn
)) == USE
22474 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
22476 cached_can_issue_more
= more
;
22477 return cached_can_issue_more
;
22480 if (insn_terminates_group_p (insn
, current_group
))
22482 cached_can_issue_more
= 0;
22483 return cached_can_issue_more
;
22486 /* If no reservation, but reach here */
22487 if (recog_memoized (insn
) < 0)
22490 if (rs6000_sched_groups
)
22492 if (is_microcoded_insn (insn
))
22493 cached_can_issue_more
= 0;
22494 else if (is_cracked_insn (insn
))
22495 cached_can_issue_more
= more
> 2 ? more
- 2 : 0;
22497 cached_can_issue_more
= more
- 1;
22499 return cached_can_issue_more
;
22502 if (rs6000_cpu_attr
== CPU_CELL
&& is_nonpipeline_insn (insn
))
22505 cached_can_issue_more
= more
- 1;
22506 return cached_can_issue_more
;
22510 rs6000_variable_issue (FILE *stream
, int verbose
, rtx insn
, int more
)
22512 int r
= rs6000_variable_issue_1 (insn
, more
);
22514 fprintf (stream
, "// rs6000_variable_issue (more = %d) = %d\n", more
, r
);
22518 /* Adjust the cost of a scheduling dependency. Return the new cost of
22519 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
22522 rs6000_adjust_cost (rtx insn
, rtx link
, rtx dep_insn
, int cost
)
22524 enum attr_type attr_type
;
22526 if (! recog_memoized (insn
))
22529 switch (REG_NOTE_KIND (link
))
22533 /* Data dependency; DEP_INSN writes a register that INSN reads
22534 some cycles later. */
22536 /* Separate a load from a narrower, dependent store. */
22537 if (rs6000_sched_groups
22538 && GET_CODE (PATTERN (insn
)) == SET
22539 && GET_CODE (PATTERN (dep_insn
)) == SET
22540 && GET_CODE (XEXP (PATTERN (insn
), 1)) == MEM
22541 && GET_CODE (XEXP (PATTERN (dep_insn
), 0)) == MEM
22542 && (GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (insn
), 1)))
22543 > GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (dep_insn
), 0)))))
22546 attr_type
= get_attr_type (insn
);
22551 /* Tell the first scheduling pass about the latency between
22552 a mtctr and bctr (and mtlr and br/blr). The first
22553 scheduling pass will not know about this latency since
22554 the mtctr instruction, which has the latency associated
22555 to it, will be generated by reload. */
22556 return TARGET_POWER
? 5 : 4;
22558 /* Leave some extra cycles between a compare and its
22559 dependent branch, to inhibit expensive mispredicts. */
22560 if ((rs6000_cpu_attr
== CPU_PPC603
22561 || rs6000_cpu_attr
== CPU_PPC604
22562 || rs6000_cpu_attr
== CPU_PPC604E
22563 || rs6000_cpu_attr
== CPU_PPC620
22564 || rs6000_cpu_attr
== CPU_PPC630
22565 || rs6000_cpu_attr
== CPU_PPC750
22566 || rs6000_cpu_attr
== CPU_PPC7400
22567 || rs6000_cpu_attr
== CPU_PPC7450
22568 || rs6000_cpu_attr
== CPU_POWER4
22569 || rs6000_cpu_attr
== CPU_POWER5
22570 || rs6000_cpu_attr
== CPU_POWER7
22571 || rs6000_cpu_attr
== CPU_CELL
)
22572 && recog_memoized (dep_insn
)
22573 && (INSN_CODE (dep_insn
) >= 0))
22575 switch (get_attr_type (dep_insn
))
22579 case TYPE_DELAYED_COMPARE
:
22580 case TYPE_IMUL_COMPARE
:
22581 case TYPE_LMUL_COMPARE
:
22582 case TYPE_FPCOMPARE
:
22583 case TYPE_CR_LOGICAL
:
22584 case TYPE_DELAYED_CR
:
22593 case TYPE_STORE_UX
:
22595 case TYPE_FPSTORE_U
:
22596 case TYPE_FPSTORE_UX
:
22597 if ((rs6000_cpu
== PROCESSOR_POWER6
)
22598 && recog_memoized (dep_insn
)
22599 && (INSN_CODE (dep_insn
) >= 0))
22602 if (GET_CODE (PATTERN (insn
)) != SET
)
22603 /* If this happens, we have to extend this to schedule
22604 optimally. Return default for now. */
22607 /* Adjust the cost for the case where the value written
22608 by a fixed point operation is used as the address
22609 gen value on a store. */
22610 switch (get_attr_type (dep_insn
))
22617 if (! store_data_bypass_p (dep_insn
, insn
))
22621 case TYPE_LOAD_EXT
:
22622 case TYPE_LOAD_EXT_U
:
22623 case TYPE_LOAD_EXT_UX
:
22624 case TYPE_VAR_SHIFT_ROTATE
:
22625 case TYPE_VAR_DELAYED_COMPARE
:
22627 if (! store_data_bypass_p (dep_insn
, insn
))
22633 case TYPE_FAST_COMPARE
:
22636 case TYPE_INSERT_WORD
:
22637 case TYPE_INSERT_DWORD
:
22638 case TYPE_FPLOAD_U
:
22639 case TYPE_FPLOAD_UX
:
22641 case TYPE_STORE_UX
:
22642 case TYPE_FPSTORE_U
:
22643 case TYPE_FPSTORE_UX
:
22645 if (! store_data_bypass_p (dep_insn
, insn
))
22653 case TYPE_IMUL_COMPARE
:
22654 case TYPE_LMUL_COMPARE
:
22656 if (! store_data_bypass_p (dep_insn
, insn
))
22662 if (! store_data_bypass_p (dep_insn
, insn
))
22668 if (! store_data_bypass_p (dep_insn
, insn
))
22681 case TYPE_LOAD_EXT
:
22682 case TYPE_LOAD_EXT_U
:
22683 case TYPE_LOAD_EXT_UX
:
22684 if ((rs6000_cpu
== PROCESSOR_POWER6
)
22685 && recog_memoized (dep_insn
)
22686 && (INSN_CODE (dep_insn
) >= 0))
22689 /* Adjust the cost for the case where the value written
22690 by a fixed point instruction is used within the address
22691 gen portion of a subsequent load(u)(x) */
22692 switch (get_attr_type (dep_insn
))
22699 if (set_to_load_agen (dep_insn
, insn
))
22703 case TYPE_LOAD_EXT
:
22704 case TYPE_LOAD_EXT_U
:
22705 case TYPE_LOAD_EXT_UX
:
22706 case TYPE_VAR_SHIFT_ROTATE
:
22707 case TYPE_VAR_DELAYED_COMPARE
:
22709 if (set_to_load_agen (dep_insn
, insn
))
22715 case TYPE_FAST_COMPARE
:
22718 case TYPE_INSERT_WORD
:
22719 case TYPE_INSERT_DWORD
:
22720 case TYPE_FPLOAD_U
:
22721 case TYPE_FPLOAD_UX
:
22723 case TYPE_STORE_UX
:
22724 case TYPE_FPSTORE_U
:
22725 case TYPE_FPSTORE_UX
:
22727 if (set_to_load_agen (dep_insn
, insn
))
22735 case TYPE_IMUL_COMPARE
:
22736 case TYPE_LMUL_COMPARE
:
22738 if (set_to_load_agen (dep_insn
, insn
))
22744 if (set_to_load_agen (dep_insn
, insn
))
22750 if (set_to_load_agen (dep_insn
, insn
))
22761 if ((rs6000_cpu
== PROCESSOR_POWER6
)
22762 && recog_memoized (dep_insn
)
22763 && (INSN_CODE (dep_insn
) >= 0)
22764 && (get_attr_type (dep_insn
) == TYPE_MFFGPR
))
22771 /* Fall out to return default cost. */
22775 case REG_DEP_OUTPUT
:
22776 /* Output dependency; DEP_INSN writes a register that INSN writes some
22778 if ((rs6000_cpu
== PROCESSOR_POWER6
)
22779 && recog_memoized (dep_insn
)
22780 && (INSN_CODE (dep_insn
) >= 0))
22782 attr_type
= get_attr_type (insn
);
22787 if (get_attr_type (dep_insn
) == TYPE_FP
)
22791 if (get_attr_type (dep_insn
) == TYPE_MFFGPR
)
22799 /* Anti dependency; DEP_INSN reads a register that INSN writes some
22804 gcc_unreachable ();
22810 /* Debug version of rs6000_adjust_cost. */
22813 rs6000_debug_adjust_cost (rtx insn
, rtx link
, rtx dep_insn
, int cost
)
22815 int ret
= rs6000_adjust_cost (insn
, link
, dep_insn
, cost
);
22821 switch (REG_NOTE_KIND (link
))
22823 default: dep
= "unknown depencency"; break;
22824 case REG_DEP_TRUE
: dep
= "data dependency"; break;
22825 case REG_DEP_OUTPUT
: dep
= "output dependency"; break;
22826 case REG_DEP_ANTI
: dep
= "anti depencency"; break;
22830 "\nrs6000_adjust_cost, final cost = %d, orig cost = %d, "
22831 "%s, insn:\n", ret
, cost
, dep
);
22839 /* The function returns a true if INSN is microcoded.
22840 Return false otherwise. */
22843 is_microcoded_insn (rtx insn
)
22845 if (!insn
|| !NONDEBUG_INSN_P (insn
)
22846 || GET_CODE (PATTERN (insn
)) == USE
22847 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
22850 if (rs6000_cpu_attr
== CPU_CELL
)
22851 return get_attr_cell_micro (insn
) == CELL_MICRO_ALWAYS
;
22853 if (rs6000_sched_groups
)
22855 enum attr_type type
= get_attr_type (insn
);
22856 if (type
== TYPE_LOAD_EXT_U
22857 || type
== TYPE_LOAD_EXT_UX
22858 || type
== TYPE_LOAD_UX
22859 || type
== TYPE_STORE_UX
22860 || type
== TYPE_MFCR
)
22867 /* The function returns true if INSN is cracked into 2 instructions
22868 by the processor (and therefore occupies 2 issue slots). */
22871 is_cracked_insn (rtx insn
)
22873 if (!insn
|| !NONDEBUG_INSN_P (insn
)
22874 || GET_CODE (PATTERN (insn
)) == USE
22875 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
22878 if (rs6000_sched_groups
)
22880 enum attr_type type
= get_attr_type (insn
);
22881 if (type
== TYPE_LOAD_U
|| type
== TYPE_STORE_U
22882 || type
== TYPE_FPLOAD_U
|| type
== TYPE_FPSTORE_U
22883 || type
== TYPE_FPLOAD_UX
|| type
== TYPE_FPSTORE_UX
22884 || type
== TYPE_LOAD_EXT
|| type
== TYPE_DELAYED_CR
22885 || type
== TYPE_COMPARE
|| type
== TYPE_DELAYED_COMPARE
22886 || type
== TYPE_IMUL_COMPARE
|| type
== TYPE_LMUL_COMPARE
22887 || type
== TYPE_IDIV
|| type
== TYPE_LDIV
22888 || type
== TYPE_INSERT_WORD
)
22895 /* The function returns true if INSN can be issued only from
22896 the branch slot. */
22899 is_branch_slot_insn (rtx insn
)
22901 if (!insn
|| !NONDEBUG_INSN_P (insn
)
22902 || GET_CODE (PATTERN (insn
)) == USE
22903 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
22906 if (rs6000_sched_groups
)
22908 enum attr_type type
= get_attr_type (insn
);
22909 if (type
== TYPE_BRANCH
|| type
== TYPE_JMPREG
)
22917 /* The function returns true if out_inst sets a value that is
22918 used in the address generation computation of in_insn */
22920 set_to_load_agen (rtx out_insn
, rtx in_insn
)
22922 rtx out_set
, in_set
;
22924 /* For performance reasons, only handle the simple case where
22925 both loads are a single_set. */
22926 out_set
= single_set (out_insn
);
22929 in_set
= single_set (in_insn
);
22931 return reg_mentioned_p (SET_DEST (out_set
), SET_SRC (in_set
));
22937 /* The function returns true if the target storage location of
22938 out_insn is adjacent to the target storage location of in_insn */
22939 /* Return 1 if memory locations are adjacent. */
22942 adjacent_mem_locations (rtx insn1
, rtx insn2
)
22945 rtx a
= get_store_dest (PATTERN (insn1
));
22946 rtx b
= get_store_dest (PATTERN (insn2
));
22948 if ((GET_CODE (XEXP (a
, 0)) == REG
22949 || (GET_CODE (XEXP (a
, 0)) == PLUS
22950 && GET_CODE (XEXP (XEXP (a
, 0), 1)) == CONST_INT
))
22951 && (GET_CODE (XEXP (b
, 0)) == REG
22952 || (GET_CODE (XEXP (b
, 0)) == PLUS
22953 && GET_CODE (XEXP (XEXP (b
, 0), 1)) == CONST_INT
)))
22955 HOST_WIDE_INT val0
= 0, val1
= 0, val_diff
;
22958 if (GET_CODE (XEXP (a
, 0)) == PLUS
)
22960 reg0
= XEXP (XEXP (a
, 0), 0);
22961 val0
= INTVAL (XEXP (XEXP (a
, 0), 1));
22964 reg0
= XEXP (a
, 0);
22966 if (GET_CODE (XEXP (b
, 0)) == PLUS
)
22968 reg1
= XEXP (XEXP (b
, 0), 0);
22969 val1
= INTVAL (XEXP (XEXP (b
, 0), 1));
22972 reg1
= XEXP (b
, 0);
22974 val_diff
= val1
- val0
;
22976 return ((REGNO (reg0
) == REGNO (reg1
))
22977 && ((MEM_SIZE (a
) && val_diff
== INTVAL (MEM_SIZE (a
)))
22978 || (MEM_SIZE (b
) && val_diff
== -INTVAL (MEM_SIZE (b
)))));
22984 /* A C statement (sans semicolon) to update the integer scheduling
22985 priority INSN_PRIORITY (INSN). Increase the priority to execute the
22986 INSN earlier, reduce the priority to execute INSN later. Do not
22987 define this macro if you do not need to adjust the scheduling
22988 priorities of insns. */
22991 rs6000_adjust_priority (rtx insn ATTRIBUTE_UNUSED
, int priority
)
22993 /* On machines (like the 750) which have asymmetric integer units,
22994 where one integer unit can do multiply and divides and the other
22995 can't, reduce the priority of multiply/divide so it is scheduled
22996 before other integer operations. */
22999 if (! INSN_P (insn
))
23002 if (GET_CODE (PATTERN (insn
)) == USE
)
23005 switch (rs6000_cpu_attr
) {
23007 switch (get_attr_type (insn
))
23014 fprintf (stderr
, "priority was %#x (%d) before adjustment\n",
23015 priority
, priority
);
23016 if (priority
>= 0 && priority
< 0x01000000)
23023 if (insn_must_be_first_in_group (insn
)
23024 && reload_completed
23025 && current_sched_info
->sched_max_insns_priority
23026 && rs6000_sched_restricted_insns_priority
)
23029 /* Prioritize insns that can be dispatched only in the first
23031 if (rs6000_sched_restricted_insns_priority
== 1)
23032 /* Attach highest priority to insn. This means that in
23033 haifa-sched.c:ready_sort(), dispatch-slot restriction considerations
23034 precede 'priority' (critical path) considerations. */
23035 return current_sched_info
->sched_max_insns_priority
;
23036 else if (rs6000_sched_restricted_insns_priority
== 2)
23037 /* Increase priority of insn by a minimal amount. This means that in
23038 haifa-sched.c:ready_sort(), only 'priority' (critical path)
23039 considerations precede dispatch-slot restriction considerations. */
23040 return (priority
+ 1);
23043 if (rs6000_cpu
== PROCESSOR_POWER6
23044 && ((load_store_pendulum
== -2 && is_load_insn (insn
))
23045 || (load_store_pendulum
== 2 && is_store_insn (insn
))))
23046 /* Attach highest priority to insn if the scheduler has just issued two
23047 stores and this instruction is a load, or two loads and this instruction
23048 is a store. Power6 wants loads and stores scheduled alternately
23050 return current_sched_info
->sched_max_insns_priority
;
23055 /* Return true if the instruction is nonpipelined on the Cell. */
23057 is_nonpipeline_insn (rtx insn
)
23059 enum attr_type type
;
23060 if (!insn
|| !NONDEBUG_INSN_P (insn
)
23061 || GET_CODE (PATTERN (insn
)) == USE
23062 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
23065 type
= get_attr_type (insn
);
23066 if (type
== TYPE_IMUL
23067 || type
== TYPE_IMUL2
23068 || type
== TYPE_IMUL3
23069 || type
== TYPE_LMUL
23070 || type
== TYPE_IDIV
23071 || type
== TYPE_LDIV
23072 || type
== TYPE_SDIV
23073 || type
== TYPE_DDIV
23074 || type
== TYPE_SSQRT
23075 || type
== TYPE_DSQRT
23076 || type
== TYPE_MFCR
23077 || type
== TYPE_MFCRF
23078 || type
== TYPE_MFJMPR
)
23086 /* Return how many instructions the machine can issue per cycle. */
23089 rs6000_issue_rate (void)
23091 /* Unless scheduling for register pressure, use issue rate of 1 for
23092 first scheduling pass to decrease degradation. */
23093 if (!reload_completed
&& !flag_sched_pressure
)
23096 switch (rs6000_cpu_attr
) {
23097 case CPU_RIOS1
: /* ? */
23099 case CPU_PPC601
: /* ? */
23108 case CPU_PPCE300C2
:
23109 case CPU_PPCE300C3
:
23110 case CPU_PPCE500MC
:
23111 case CPU_PPCE500MC64
:
23131 /* Return how many instructions to look ahead for better insn
23135 rs6000_use_sched_lookahead (void)
23137 if (rs6000_cpu_attr
== CPU_PPC8540
)
23139 if (rs6000_cpu_attr
== CPU_CELL
)
23140 return (reload_completed
? 8 : 0);
23144 /* We are choosing insn from the ready queue. Return nonzero if INSN can be chosen. */
23146 rs6000_use_sched_lookahead_guard (rtx insn
)
23148 if (rs6000_cpu_attr
!= CPU_CELL
)
23151 if (insn
== NULL_RTX
|| !INSN_P (insn
))
23154 if (!reload_completed
23155 || is_nonpipeline_insn (insn
)
23156 || is_microcoded_insn (insn
))
23162 /* Determine is PAT refers to memory. */
23165 is_mem_ref (rtx pat
)
23171 /* stack_tie does not produce any real memory traffic. */
23172 if (GET_CODE (pat
) == UNSPEC
23173 && XINT (pat
, 1) == UNSPEC_TIE
)
23176 if (GET_CODE (pat
) == MEM
)
23179 /* Recursively process the pattern. */
23180 fmt
= GET_RTX_FORMAT (GET_CODE (pat
));
23182 for (i
= GET_RTX_LENGTH (GET_CODE (pat
)) - 1; i
>= 0 && !ret
; i
--)
23185 ret
|= is_mem_ref (XEXP (pat
, i
));
23186 else if (fmt
[i
] == 'E')
23187 for (j
= XVECLEN (pat
, i
) - 1; j
>= 0; j
--)
23188 ret
|= is_mem_ref (XVECEXP (pat
, i
, j
));
23194 /* Determine if PAT is a PATTERN of a load insn. */
23197 is_load_insn1 (rtx pat
)
23199 if (!pat
|| pat
== NULL_RTX
)
23202 if (GET_CODE (pat
) == SET
)
23203 return is_mem_ref (SET_SRC (pat
));
23205 if (GET_CODE (pat
) == PARALLEL
)
23209 for (i
= 0; i
< XVECLEN (pat
, 0); i
++)
23210 if (is_load_insn1 (XVECEXP (pat
, 0, i
)))
23217 /* Determine if INSN loads from memory. */
23220 is_load_insn (rtx insn
)
23222 if (!insn
|| !INSN_P (insn
))
23225 if (GET_CODE (insn
) == CALL_INSN
)
23228 return is_load_insn1 (PATTERN (insn
));
23231 /* Determine if PAT is a PATTERN of a store insn. */
23234 is_store_insn1 (rtx pat
)
23236 if (!pat
|| pat
== NULL_RTX
)
23239 if (GET_CODE (pat
) == SET
)
23240 return is_mem_ref (SET_DEST (pat
));
23242 if (GET_CODE (pat
) == PARALLEL
)
23246 for (i
= 0; i
< XVECLEN (pat
, 0); i
++)
23247 if (is_store_insn1 (XVECEXP (pat
, 0, i
)))
23254 /* Determine if INSN stores to memory. */
23257 is_store_insn (rtx insn
)
23259 if (!insn
|| !INSN_P (insn
))
23262 return is_store_insn1 (PATTERN (insn
));
23265 /* Return the dest of a store insn. */
23268 get_store_dest (rtx pat
)
23270 gcc_assert (is_store_insn1 (pat
));
23272 if (GET_CODE (pat
) == SET
)
23273 return SET_DEST (pat
);
23274 else if (GET_CODE (pat
) == PARALLEL
)
23278 for (i
= 0; i
< XVECLEN (pat
, 0); i
++)
23280 rtx inner_pat
= XVECEXP (pat
, 0, i
);
23281 if (GET_CODE (inner_pat
) == SET
23282 && is_mem_ref (SET_DEST (inner_pat
)))
23286 /* We shouldn't get here, because we should have either a simple
23287 store insn or a store with update which are covered above. */
23291 /* Returns whether the dependence between INSN and NEXT is considered
23292 costly by the given target. */
23295 rs6000_is_costly_dependence (dep_t dep
, int cost
, int distance
)
23300 /* If the flag is not enabled - no dependence is considered costly;
23301 allow all dependent insns in the same group.
23302 This is the most aggressive option. */
23303 if (rs6000_sched_costly_dep
== no_dep_costly
)
23306 /* If the flag is set to 1 - a dependence is always considered costly;
23307 do not allow dependent instructions in the same group.
23308 This is the most conservative option. */
23309 if (rs6000_sched_costly_dep
== all_deps_costly
)
23312 insn
= DEP_PRO (dep
);
23313 next
= DEP_CON (dep
);
23315 if (rs6000_sched_costly_dep
== store_to_load_dep_costly
23316 && is_load_insn (next
)
23317 && is_store_insn (insn
))
23318 /* Prevent load after store in the same group. */
23321 if (rs6000_sched_costly_dep
== true_store_to_load_dep_costly
23322 && is_load_insn (next
)
23323 && is_store_insn (insn
)
23324 && DEP_TYPE (dep
) == REG_DEP_TRUE
)
23325 /* Prevent load after store in the same group if it is a true
23329 /* The flag is set to X; dependences with latency >= X are considered costly,
23330 and will not be scheduled in the same group. */
23331 if (rs6000_sched_costly_dep
<= max_dep_latency
23332 && ((cost
- distance
) >= (int)rs6000_sched_costly_dep
))
23338 /* Return the next insn after INSN that is found before TAIL is reached,
23339 skipping any "non-active" insns - insns that will not actually occupy
23340 an issue slot. Return NULL_RTX if such an insn is not found. */
23343 get_next_active_insn (rtx insn
, rtx tail
)
23345 if (insn
== NULL_RTX
|| insn
== tail
)
23350 insn
= NEXT_INSN (insn
);
23351 if (insn
== NULL_RTX
|| insn
== tail
)
23356 || (NONJUMP_INSN_P (insn
)
23357 && GET_CODE (PATTERN (insn
)) != USE
23358 && GET_CODE (PATTERN (insn
)) != CLOBBER
23359 && INSN_CODE (insn
) != CODE_FOR_stack_tie
))
23365 /* We are about to begin issuing insns for this clock cycle. */
23368 rs6000_sched_reorder (FILE *dump ATTRIBUTE_UNUSED
, int sched_verbose
,
23369 rtx
*ready ATTRIBUTE_UNUSED
,
23370 int *pn_ready ATTRIBUTE_UNUSED
,
23371 int clock_var ATTRIBUTE_UNUSED
)
23373 int n_ready
= *pn_ready
;
23376 fprintf (dump
, "// rs6000_sched_reorder :\n");
23378 /* Reorder the ready list, if the second to last ready insn
23379 is a nonepipeline insn. */
23380 if (rs6000_cpu_attr
== CPU_CELL
&& n_ready
> 1)
23382 if (is_nonpipeline_insn (ready
[n_ready
- 1])
23383 && (recog_memoized (ready
[n_ready
- 2]) > 0))
23384 /* Simply swap first two insns. */
23386 rtx tmp
= ready
[n_ready
- 1];
23387 ready
[n_ready
- 1] = ready
[n_ready
- 2];
23388 ready
[n_ready
- 2] = tmp
;
23392 if (rs6000_cpu
== PROCESSOR_POWER6
)
23393 load_store_pendulum
= 0;
23395 return rs6000_issue_rate ();
23398 /* Like rs6000_sched_reorder, but called after issuing each insn. */
23401 rs6000_sched_reorder2 (FILE *dump
, int sched_verbose
, rtx
*ready
,
23402 int *pn_ready
, int clock_var ATTRIBUTE_UNUSED
)
23405 fprintf (dump
, "// rs6000_sched_reorder2 :\n");
23407 /* For Power6, we need to handle some special cases to try and keep the
23408 store queue from overflowing and triggering expensive flushes.
23410 This code monitors how load and store instructions are being issued
23411 and skews the ready list one way or the other to increase the likelihood
23412 that a desired instruction is issued at the proper time.
23414 A couple of things are done. First, we maintain a "load_store_pendulum"
23415 to track the current state of load/store issue.
23417 - If the pendulum is at zero, then no loads or stores have been
23418 issued in the current cycle so we do nothing.
23420 - If the pendulum is 1, then a single load has been issued in this
23421 cycle and we attempt to locate another load in the ready list to
23424 - If the pendulum is -2, then two stores have already been
23425 issued in this cycle, so we increase the priority of the first load
23426 in the ready list to increase it's likelihood of being chosen first
23429 - If the pendulum is -1, then a single store has been issued in this
23430 cycle and we attempt to locate another store in the ready list to
23431 issue with it, preferring a store to an adjacent memory location to
23432 facilitate store pairing in the store queue.
23434 - If the pendulum is 2, then two loads have already been
23435 issued in this cycle, so we increase the priority of the first store
23436 in the ready list to increase it's likelihood of being chosen first
23439 - If the pendulum < -2 or > 2, then do nothing.
23441 Note: This code covers the most common scenarios. There exist non
23442 load/store instructions which make use of the LSU and which
23443 would need to be accounted for to strictly model the behavior
23444 of the machine. Those instructions are currently unaccounted
23445 for to help minimize compile time overhead of this code.
23447 if (rs6000_cpu
== PROCESSOR_POWER6
&& last_scheduled_insn
)
23453 if (is_store_insn (last_scheduled_insn
))
23454 /* Issuing a store, swing the load_store_pendulum to the left */
23455 load_store_pendulum
--;
23456 else if (is_load_insn (last_scheduled_insn
))
23457 /* Issuing a load, swing the load_store_pendulum to the right */
23458 load_store_pendulum
++;
23460 return cached_can_issue_more
;
23462 /* If the pendulum is balanced, or there is only one instruction on
23463 the ready list, then all is well, so return. */
23464 if ((load_store_pendulum
== 0) || (*pn_ready
<= 1))
23465 return cached_can_issue_more
;
23467 if (load_store_pendulum
== 1)
23469 /* A load has been issued in this cycle. Scan the ready list
23470 for another load to issue with it */
23475 if (is_load_insn (ready
[pos
]))
23477 /* Found a load. Move it to the head of the ready list,
23478 and adjust it's priority so that it is more likely to
23481 for (i
=pos
; i
<*pn_ready
-1; i
++)
23482 ready
[i
] = ready
[i
+ 1];
23483 ready
[*pn_ready
-1] = tmp
;
23485 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp
))
23486 INSN_PRIORITY (tmp
)++;
23492 else if (load_store_pendulum
== -2)
23494 /* Two stores have been issued in this cycle. Increase the
23495 priority of the first load in the ready list to favor it for
23496 issuing in the next cycle. */
23501 if (is_load_insn (ready
[pos
])
23503 && INSN_PRIORITY_KNOWN (ready
[pos
]))
23505 INSN_PRIORITY (ready
[pos
])++;
23507 /* Adjust the pendulum to account for the fact that a load
23508 was found and increased in priority. This is to prevent
23509 increasing the priority of multiple loads */
23510 load_store_pendulum
--;
23517 else if (load_store_pendulum
== -1)
23519 /* A store has been issued in this cycle. Scan the ready list for
23520 another store to issue with it, preferring a store to an adjacent
23522 int first_store_pos
= -1;
23528 if (is_store_insn (ready
[pos
]))
23530 /* Maintain the index of the first store found on the
23532 if (first_store_pos
== -1)
23533 first_store_pos
= pos
;
23535 if (is_store_insn (last_scheduled_insn
)
23536 && adjacent_mem_locations (last_scheduled_insn
,ready
[pos
]))
23538 /* Found an adjacent store. Move it to the head of the
23539 ready list, and adjust it's priority so that it is
23540 more likely to stay there */
23542 for (i
=pos
; i
<*pn_ready
-1; i
++)
23543 ready
[i
] = ready
[i
+ 1];
23544 ready
[*pn_ready
-1] = tmp
;
23546 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp
))
23547 INSN_PRIORITY (tmp
)++;
23549 first_store_pos
= -1;
23557 if (first_store_pos
>= 0)
23559 /* An adjacent store wasn't found, but a non-adjacent store was,
23560 so move the non-adjacent store to the front of the ready
23561 list, and adjust its priority so that it is more likely to
23563 tmp
= ready
[first_store_pos
];
23564 for (i
=first_store_pos
; i
<*pn_ready
-1; i
++)
23565 ready
[i
] = ready
[i
+ 1];
23566 ready
[*pn_ready
-1] = tmp
;
23567 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp
))
23568 INSN_PRIORITY (tmp
)++;
23571 else if (load_store_pendulum
== 2)
23573 /* Two loads have been issued in this cycle. Increase the priority
23574 of the first store in the ready list to favor it for issuing in
23580 if (is_store_insn (ready
[pos
])
23582 && INSN_PRIORITY_KNOWN (ready
[pos
]))
23584 INSN_PRIORITY (ready
[pos
])++;
23586 /* Adjust the pendulum to account for the fact that a store
23587 was found and increased in priority. This is to prevent
23588 increasing the priority of multiple stores */
23589 load_store_pendulum
++;
23598 return cached_can_issue_more
;
23601 /* Return whether the presence of INSN causes a dispatch group termination
23602 of group WHICH_GROUP.
23604 If WHICH_GROUP == current_group, this function will return true if INSN
23605 causes the termination of the current group (i.e, the dispatch group to
23606 which INSN belongs). This means that INSN will be the last insn in the
23607 group it belongs to.
23609 If WHICH_GROUP == previous_group, this function will return true if INSN
23610 causes the termination of the previous group (i.e, the dispatch group that
23611 precedes the group to which INSN belongs). This means that INSN will be
23612 the first insn in the group it belongs to). */
23615 insn_terminates_group_p (rtx insn
, enum group_termination which_group
)
23622 first
= insn_must_be_first_in_group (insn
);
23623 last
= insn_must_be_last_in_group (insn
);
23628 if (which_group
== current_group
)
23630 else if (which_group
== previous_group
)
23638 insn_must_be_first_in_group (rtx insn
)
23640 enum attr_type type
;
23643 || GET_CODE (insn
) == NOTE
23644 || DEBUG_INSN_P (insn
)
23645 || GET_CODE (PATTERN (insn
)) == USE
23646 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
23649 switch (rs6000_cpu
)
23651 case PROCESSOR_POWER5
:
23652 if (is_cracked_insn (insn
))
23654 case PROCESSOR_POWER4
:
23655 if (is_microcoded_insn (insn
))
23658 if (!rs6000_sched_groups
)
23661 type
= get_attr_type (insn
);
23668 case TYPE_DELAYED_CR
:
23669 case TYPE_CR_LOGICAL
:
23683 case PROCESSOR_POWER6
:
23684 type
= get_attr_type (insn
);
23688 case TYPE_INSERT_DWORD
:
23692 case TYPE_VAR_SHIFT_ROTATE
:
23699 case TYPE_INSERT_WORD
:
23700 case TYPE_DELAYED_COMPARE
:
23701 case TYPE_IMUL_COMPARE
:
23702 case TYPE_LMUL_COMPARE
:
23703 case TYPE_FPCOMPARE
:
23714 case TYPE_LOAD_EXT_UX
:
23716 case TYPE_STORE_UX
:
23717 case TYPE_FPLOAD_U
:
23718 case TYPE_FPLOAD_UX
:
23719 case TYPE_FPSTORE_U
:
23720 case TYPE_FPSTORE_UX
:
23726 case PROCESSOR_POWER7
:
23727 type
= get_attr_type (insn
);
23731 case TYPE_CR_LOGICAL
:
23738 case TYPE_DELAYED_COMPARE
:
23739 case TYPE_VAR_DELAYED_COMPARE
:
23745 case TYPE_LOAD_EXT
:
23746 case TYPE_LOAD_EXT_U
:
23747 case TYPE_LOAD_EXT_UX
:
23749 case TYPE_STORE_UX
:
23750 case TYPE_FPLOAD_U
:
23751 case TYPE_FPLOAD_UX
:
23752 case TYPE_FPSTORE_U
:
23753 case TYPE_FPSTORE_UX
:
23769 insn_must_be_last_in_group (rtx insn
)
23771 enum attr_type type
;
23774 || GET_CODE (insn
) == NOTE
23775 || DEBUG_INSN_P (insn
)
23776 || GET_CODE (PATTERN (insn
)) == USE
23777 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
23780 switch (rs6000_cpu
) {
23781 case PROCESSOR_POWER4
:
23782 case PROCESSOR_POWER5
:
23783 if (is_microcoded_insn (insn
))
23786 if (is_branch_slot_insn (insn
))
23790 case PROCESSOR_POWER6
:
23791 type
= get_attr_type (insn
);
23798 case TYPE_VAR_SHIFT_ROTATE
:
23805 case TYPE_DELAYED_COMPARE
:
23806 case TYPE_IMUL_COMPARE
:
23807 case TYPE_LMUL_COMPARE
:
23808 case TYPE_FPCOMPARE
:
23822 case PROCESSOR_POWER7
:
23823 type
= get_attr_type (insn
);
23831 case TYPE_LOAD_EXT_U
:
23832 case TYPE_LOAD_EXT_UX
:
23833 case TYPE_STORE_UX
:
23846 /* Return true if it is recommended to keep NEXT_INSN "far" (in a separate
23847 dispatch group) from the insns in GROUP_INSNS. Return false otherwise. */
23850 is_costly_group (rtx
*group_insns
, rtx next_insn
)
23853 int issue_rate
= rs6000_issue_rate ();
23855 for (i
= 0; i
< issue_rate
; i
++)
23857 sd_iterator_def sd_it
;
23859 rtx insn
= group_insns
[i
];
23864 FOR_EACH_DEP (insn
, SD_LIST_FORW
, sd_it
, dep
)
23866 rtx next
= DEP_CON (dep
);
23868 if (next
== next_insn
23869 && rs6000_is_costly_dependence (dep
, dep_cost (dep
), 0))
23877 /* Utility of the function redefine_groups.
23878 Check if it is too costly to schedule NEXT_INSN together with GROUP_INSNS
23879 in the same dispatch group. If so, insert nops before NEXT_INSN, in order
23880 to keep it "far" (in a separate group) from GROUP_INSNS, following
23881 one of the following schemes, depending on the value of the flag
23882 -minsert_sched_nops = X:
23883 (1) X == sched_finish_regroup_exact: insert exactly as many nops as needed
23884 in order to force NEXT_INSN into a separate group.
23885 (2) X < sched_finish_regroup_exact: insert exactly X nops.
23886 GROUP_END, CAN_ISSUE_MORE and GROUP_COUNT record the state after nop
23887 insertion (has a group just ended, how many vacant issue slots remain in the
23888 last group, and how many dispatch groups were encountered so far). */
23891 force_new_group (int sched_verbose
, FILE *dump
, rtx
*group_insns
,
23892 rtx next_insn
, bool *group_end
, int can_issue_more
,
23897 int issue_rate
= rs6000_issue_rate ();
23898 bool end
= *group_end
;
23901 if (next_insn
== NULL_RTX
|| DEBUG_INSN_P (next_insn
))
23902 return can_issue_more
;
23904 if (rs6000_sched_insert_nops
> sched_finish_regroup_exact
)
23905 return can_issue_more
;
23907 force
= is_costly_group (group_insns
, next_insn
);
23909 return can_issue_more
;
23911 if (sched_verbose
> 6)
23912 fprintf (dump
,"force: group count = %d, can_issue_more = %d\n",
23913 *group_count
,can_issue_more
);
23915 if (rs6000_sched_insert_nops
== sched_finish_regroup_exact
)
23918 can_issue_more
= 0;
23920 /* Since only a branch can be issued in the last issue_slot, it is
23921 sufficient to insert 'can_issue_more - 1' nops if next_insn is not
23922 a branch. If next_insn is a branch, we insert 'can_issue_more' nops;
23923 in this case the last nop will start a new group and the branch
23924 will be forced to the new group. */
23925 if (can_issue_more
&& !is_branch_slot_insn (next_insn
))
23928 while (can_issue_more
> 0)
23931 emit_insn_before (nop
, next_insn
);
23939 if (rs6000_sched_insert_nops
< sched_finish_regroup_exact
)
23941 int n_nops
= rs6000_sched_insert_nops
;
23943 /* Nops can't be issued from the branch slot, so the effective
23944 issue_rate for nops is 'issue_rate - 1'. */
23945 if (can_issue_more
== 0)
23946 can_issue_more
= issue_rate
;
23948 if (can_issue_more
== 0)
23950 can_issue_more
= issue_rate
- 1;
23953 for (i
= 0; i
< issue_rate
; i
++)
23955 group_insns
[i
] = 0;
23962 emit_insn_before (nop
, next_insn
);
23963 if (can_issue_more
== issue_rate
- 1) /* new group begins */
23966 if (can_issue_more
== 0)
23968 can_issue_more
= issue_rate
- 1;
23971 for (i
= 0; i
< issue_rate
; i
++)
23973 group_insns
[i
] = 0;
23979 /* Scale back relative to 'issue_rate' (instead of 'issue_rate - 1'). */
23982 /* Is next_insn going to start a new group? */
23985 || (can_issue_more
== 1 && !is_branch_slot_insn (next_insn
))
23986 || (can_issue_more
<= 2 && is_cracked_insn (next_insn
))
23987 || (can_issue_more
< issue_rate
&&
23988 insn_terminates_group_p (next_insn
, previous_group
)));
23989 if (*group_end
&& end
)
23992 if (sched_verbose
> 6)
23993 fprintf (dump
, "done force: group count = %d, can_issue_more = %d\n",
23994 *group_count
, can_issue_more
);
23995 return can_issue_more
;
23998 return can_issue_more
;
24001 /* This function tries to synch the dispatch groups that the compiler "sees"
24002 with the dispatch groups that the processor dispatcher is expected to
24003 form in practice. It tries to achieve this synchronization by forcing the
24004 estimated processor grouping on the compiler (as opposed to the function
24005 'pad_goups' which tries to force the scheduler's grouping on the processor).
24007 The function scans the insn sequence between PREV_HEAD_INSN and TAIL and
24008 examines the (estimated) dispatch groups that will be formed by the processor
24009 dispatcher. It marks these group boundaries to reflect the estimated
24010 processor grouping, overriding the grouping that the scheduler had marked.
24011 Depending on the value of the flag '-minsert-sched-nops' this function can
24012 force certain insns into separate groups or force a certain distance between
24013 them by inserting nops, for example, if there exists a "costly dependence"
24016 The function estimates the group boundaries that the processor will form as
24017 follows: It keeps track of how many vacant issue slots are available after
24018 each insn. A subsequent insn will start a new group if one of the following
24020 - no more vacant issue slots remain in the current dispatch group.
24021 - only the last issue slot, which is the branch slot, is vacant, but the next
24022 insn is not a branch.
24023 - only the last 2 or less issue slots, including the branch slot, are vacant,
24024 which means that a cracked insn (which occupies two issue slots) can't be
24025 issued in this group.
24026 - less than 'issue_rate' slots are vacant, and the next insn always needs to
24027 start a new group. */
24030 redefine_groups (FILE *dump
, int sched_verbose
, rtx prev_head_insn
, rtx tail
)
24032 rtx insn
, next_insn
;
24034 int can_issue_more
;
24037 int group_count
= 0;
24041 issue_rate
= rs6000_issue_rate ();
24042 group_insns
= XALLOCAVEC (rtx
, issue_rate
);
24043 for (i
= 0; i
< issue_rate
; i
++)
24045 group_insns
[i
] = 0;
24047 can_issue_more
= issue_rate
;
24049 insn
= get_next_active_insn (prev_head_insn
, tail
);
24052 while (insn
!= NULL_RTX
)
24054 slot
= (issue_rate
- can_issue_more
);
24055 group_insns
[slot
] = insn
;
24057 rs6000_variable_issue (dump
, sched_verbose
, insn
, can_issue_more
);
24058 if (insn_terminates_group_p (insn
, current_group
))
24059 can_issue_more
= 0;
24061 next_insn
= get_next_active_insn (insn
, tail
);
24062 if (next_insn
== NULL_RTX
)
24063 return group_count
+ 1;
24065 /* Is next_insn going to start a new group? */
24067 = (can_issue_more
== 0
24068 || (can_issue_more
== 1 && !is_branch_slot_insn (next_insn
))
24069 || (can_issue_more
<= 2 && is_cracked_insn (next_insn
))
24070 || (can_issue_more
< issue_rate
&&
24071 insn_terminates_group_p (next_insn
, previous_group
)));
24073 can_issue_more
= force_new_group (sched_verbose
, dump
, group_insns
,
24074 next_insn
, &group_end
, can_issue_more
,
24080 can_issue_more
= 0;
24081 for (i
= 0; i
< issue_rate
; i
++)
24083 group_insns
[i
] = 0;
24087 if (GET_MODE (next_insn
) == TImode
&& can_issue_more
)
24088 PUT_MODE (next_insn
, VOIDmode
);
24089 else if (!can_issue_more
&& GET_MODE (next_insn
) != TImode
)
24090 PUT_MODE (next_insn
, TImode
);
24093 if (can_issue_more
== 0)
24094 can_issue_more
= issue_rate
;
24097 return group_count
;
24100 /* Scan the insn sequence between PREV_HEAD_INSN and TAIL and examine the
24101 dispatch group boundaries that the scheduler had marked. Pad with nops
24102 any dispatch groups which have vacant issue slots, in order to force the
24103 scheduler's grouping on the processor dispatcher. The function
24104 returns the number of dispatch groups found. */
24107 pad_groups (FILE *dump
, int sched_verbose
, rtx prev_head_insn
, rtx tail
)
24109 rtx insn
, next_insn
;
24112 int can_issue_more
;
24114 int group_count
= 0;
24116 /* Initialize issue_rate. */
24117 issue_rate
= rs6000_issue_rate ();
24118 can_issue_more
= issue_rate
;
24120 insn
= get_next_active_insn (prev_head_insn
, tail
);
24121 next_insn
= get_next_active_insn (insn
, tail
);
24123 while (insn
!= NULL_RTX
)
24126 rs6000_variable_issue (dump
, sched_verbose
, insn
, can_issue_more
);
24128 group_end
= (next_insn
== NULL_RTX
|| GET_MODE (next_insn
) == TImode
);
24130 if (next_insn
== NULL_RTX
)
24135 /* If the scheduler had marked group termination at this location
24136 (between insn and next_insn), and neither insn nor next_insn will
24137 force group termination, pad the group with nops to force group
24140 && (rs6000_sched_insert_nops
== sched_finish_pad_groups
)
24141 && !insn_terminates_group_p (insn
, current_group
)
24142 && !insn_terminates_group_p (next_insn
, previous_group
))
24144 if (!is_branch_slot_insn (next_insn
))
24147 while (can_issue_more
)
24150 emit_insn_before (nop
, next_insn
);
24155 can_issue_more
= issue_rate
;
24160 next_insn
= get_next_active_insn (insn
, tail
);
24163 return group_count
;
24166 /* We're beginning a new block. Initialize data structures as necessary. */
24169 rs6000_sched_init (FILE *dump ATTRIBUTE_UNUSED
,
24170 int sched_verbose ATTRIBUTE_UNUSED
,
24171 int max_ready ATTRIBUTE_UNUSED
)
24173 last_scheduled_insn
= NULL_RTX
;
24174 load_store_pendulum
= 0;
24177 /* The following function is called at the end of scheduling BB.
24178 After reload, it inserts nops at insn group bundling. */
24181 rs6000_sched_finish (FILE *dump
, int sched_verbose
)
24186 fprintf (dump
, "=== Finishing schedule.\n");
24188 if (reload_completed
&& rs6000_sched_groups
)
24190 /* Do not run sched_finish hook when selective scheduling enabled. */
24191 if (sel_sched_p ())
24194 if (rs6000_sched_insert_nops
== sched_finish_none
)
24197 if (rs6000_sched_insert_nops
== sched_finish_pad_groups
)
24198 n_groups
= pad_groups (dump
, sched_verbose
,
24199 current_sched_info
->prev_head
,
24200 current_sched_info
->next_tail
);
24202 n_groups
= redefine_groups (dump
, sched_verbose
,
24203 current_sched_info
->prev_head
,
24204 current_sched_info
->next_tail
);
24206 if (sched_verbose
>= 6)
24208 fprintf (dump
, "ngroups = %d\n", n_groups
);
24209 print_rtl (dump
, current_sched_info
->prev_head
);
24210 fprintf (dump
, "Done finish_sched\n");
24215 struct _rs6000_sched_context
24217 short cached_can_issue_more
;
24218 rtx last_scheduled_insn
;
24219 int load_store_pendulum
;
24222 typedef struct _rs6000_sched_context rs6000_sched_context_def
;
24223 typedef rs6000_sched_context_def
*rs6000_sched_context_t
;
24225 /* Allocate store for new scheduling context. */
24227 rs6000_alloc_sched_context (void)
24229 return xmalloc (sizeof (rs6000_sched_context_def
));
24232 /* If CLEAN_P is true then initializes _SC with clean data,
24233 and from the global context otherwise. */
24235 rs6000_init_sched_context (void *_sc
, bool clean_p
)
24237 rs6000_sched_context_t sc
= (rs6000_sched_context_t
) _sc
;
24241 sc
->cached_can_issue_more
= 0;
24242 sc
->last_scheduled_insn
= NULL_RTX
;
24243 sc
->load_store_pendulum
= 0;
24247 sc
->cached_can_issue_more
= cached_can_issue_more
;
24248 sc
->last_scheduled_insn
= last_scheduled_insn
;
24249 sc
->load_store_pendulum
= load_store_pendulum
;
24253 /* Sets the global scheduling context to the one pointed to by _SC. */
24255 rs6000_set_sched_context (void *_sc
)
24257 rs6000_sched_context_t sc
= (rs6000_sched_context_t
) _sc
;
24259 gcc_assert (sc
!= NULL
);
24261 cached_can_issue_more
= sc
->cached_can_issue_more
;
24262 last_scheduled_insn
= sc
->last_scheduled_insn
;
24263 load_store_pendulum
= sc
->load_store_pendulum
;
24268 rs6000_free_sched_context (void *_sc
)
24270 gcc_assert (_sc
!= NULL
);
24276 /* Length in units of the trampoline for entering a nested function. */
24279 rs6000_trampoline_size (void)
24283 switch (DEFAULT_ABI
)
24286 gcc_unreachable ();
24289 ret
= (TARGET_32BIT
) ? 12 : 24;
24294 ret
= (TARGET_32BIT
) ? 40 : 48;
24301 /* Emit RTL insns to initialize the variable parts of a trampoline.
24302 FNADDR is an RTX for the address of the function's pure code.
24303 CXT is an RTX for the static chain value for the function. */
24306 rs6000_trampoline_init (rtx m_tramp
, tree fndecl
, rtx cxt
)
24308 int regsize
= (TARGET_32BIT
) ? 4 : 8;
24309 rtx fnaddr
= XEXP (DECL_RTL (fndecl
), 0);
24310 rtx ctx_reg
= force_reg (Pmode
, cxt
);
24311 rtx addr
= force_reg (Pmode
, XEXP (m_tramp
, 0));
24313 switch (DEFAULT_ABI
)
24316 gcc_unreachable ();
24318 /* Under AIX, just build the 3 word function descriptor */
24321 rtx fnmem
= gen_const_mem (Pmode
, force_reg (Pmode
, fnaddr
));
24322 rtx fn_reg
= gen_reg_rtx (Pmode
);
24323 rtx toc_reg
= gen_reg_rtx (Pmode
);
24325 /* Macro to shorten the code expansions below. */
24326 # define MEM_PLUS(MEM, OFFSET) adjust_address (MEM, Pmode, OFFSET)
24328 m_tramp
= replace_equiv_address (m_tramp
, addr
);
24330 emit_move_insn (fn_reg
, MEM_PLUS (fnmem
, 0));
24331 emit_move_insn (toc_reg
, MEM_PLUS (fnmem
, regsize
));
24332 emit_move_insn (MEM_PLUS (m_tramp
, 0), fn_reg
);
24333 emit_move_insn (MEM_PLUS (m_tramp
, regsize
), toc_reg
);
24334 emit_move_insn (MEM_PLUS (m_tramp
, 2*regsize
), ctx_reg
);
24340 /* Under V.4/eabi/darwin, __trampoline_setup does the real work. */
24343 emit_library_call (gen_rtx_SYMBOL_REF (Pmode
, "__trampoline_setup"),
24344 LCT_NORMAL
, VOIDmode
, 4,
24346 GEN_INT (rs6000_trampoline_size ()), SImode
,
24354 /* Returns TRUE iff the target attribute indicated by ATTR_ID takes a plain
24355 identifier as an argument, so the front end shouldn't look it up. */
24358 rs6000_attribute_takes_identifier_p (const_tree attr_id
)
24360 return is_attribute_p ("altivec", attr_id
);
24363 /* Handle the "altivec" attribute. The attribute may have
24364 arguments as follows:
24366 __attribute__((altivec(vector__)))
24367 __attribute__((altivec(pixel__))) (always followed by 'unsigned short')
24368 __attribute__((altivec(bool__))) (always followed by 'unsigned')
24370 and may appear more than once (e.g., 'vector bool char') in a
24371 given declaration. */
24374 rs6000_handle_altivec_attribute (tree
*node
,
24375 tree name ATTRIBUTE_UNUSED
,
24377 int flags ATTRIBUTE_UNUSED
,
24378 bool *no_add_attrs
)
24380 tree type
= *node
, result
= NULL_TREE
;
24381 enum machine_mode mode
;
24384 = ((args
&& TREE_CODE (args
) == TREE_LIST
&& TREE_VALUE (args
)
24385 && TREE_CODE (TREE_VALUE (args
)) == IDENTIFIER_NODE
)
24386 ? *IDENTIFIER_POINTER (TREE_VALUE (args
))
24389 while (POINTER_TYPE_P (type
)
24390 || TREE_CODE (type
) == FUNCTION_TYPE
24391 || TREE_CODE (type
) == METHOD_TYPE
24392 || TREE_CODE (type
) == ARRAY_TYPE
)
24393 type
= TREE_TYPE (type
);
24395 mode
= TYPE_MODE (type
);
24397 /* Check for invalid AltiVec type qualifiers. */
24398 if (type
== long_double_type_node
)
24399 error ("use of %<long double%> in AltiVec types is invalid");
24400 else if (type
== boolean_type_node
)
24401 error ("use of boolean types in AltiVec types is invalid");
24402 else if (TREE_CODE (type
) == COMPLEX_TYPE
)
24403 error ("use of %<complex%> in AltiVec types is invalid");
24404 else if (DECIMAL_FLOAT_MODE_P (mode
))
24405 error ("use of decimal floating point types in AltiVec types is invalid");
24406 else if (!TARGET_VSX
)
24408 if (type
== long_unsigned_type_node
|| type
== long_integer_type_node
)
24411 error ("use of %<long%> in AltiVec types is invalid for "
24412 "64-bit code without -mvsx");
24413 else if (rs6000_warn_altivec_long
)
24414 warning (0, "use of %<long%> in AltiVec types is deprecated; "
24417 else if (type
== long_long_unsigned_type_node
24418 || type
== long_long_integer_type_node
)
24419 error ("use of %<long long%> in AltiVec types is invalid without "
24421 else if (type
== double_type_node
)
24422 error ("use of %<double%> in AltiVec types is invalid without -mvsx");
24425 switch (altivec_type
)
24428 unsigned_p
= TYPE_UNSIGNED (type
);
24432 result
= (unsigned_p
? unsigned_V2DI_type_node
: V2DI_type_node
);
24435 result
= (unsigned_p
? unsigned_V4SI_type_node
: V4SI_type_node
);
24438 result
= (unsigned_p
? unsigned_V8HI_type_node
: V8HI_type_node
);
24441 result
= (unsigned_p
? unsigned_V16QI_type_node
: V16QI_type_node
);
24443 case SFmode
: result
= V4SF_type_node
; break;
24444 case DFmode
: result
= V2DF_type_node
; break;
24445 /* If the user says 'vector int bool', we may be handed the 'bool'
24446 attribute _before_ the 'vector' attribute, and so select the
24447 proper type in the 'b' case below. */
24448 case V4SImode
: case V8HImode
: case V16QImode
: case V4SFmode
:
24449 case V2DImode
: case V2DFmode
:
24457 case DImode
: case V2DImode
: result
= bool_V2DI_type_node
; break;
24458 case SImode
: case V4SImode
: result
= bool_V4SI_type_node
; break;
24459 case HImode
: case V8HImode
: result
= bool_V8HI_type_node
; break;
24460 case QImode
: case V16QImode
: result
= bool_V16QI_type_node
;
24467 case V8HImode
: result
= pixel_V8HI_type_node
;
24473 /* Propagate qualifiers attached to the element type
24474 onto the vector type. */
24475 if (result
&& result
!= type
&& TYPE_QUALS (type
))
24476 result
= build_qualified_type (result
, TYPE_QUALS (type
));
24478 *no_add_attrs
= true; /* No need to hang on to the attribute. */
24481 *node
= lang_hooks
.types
.reconstruct_complex_type (*node
, result
);
24486 /* AltiVec defines four built-in scalar types that serve as vector
24487 elements; we must teach the compiler how to mangle them. */
24489 static const char *
24490 rs6000_mangle_type (const_tree type
)
24492 type
= TYPE_MAIN_VARIANT (type
);
24494 if (TREE_CODE (type
) != VOID_TYPE
&& TREE_CODE (type
) != BOOLEAN_TYPE
24495 && TREE_CODE (type
) != INTEGER_TYPE
&& TREE_CODE (type
) != REAL_TYPE
)
24498 if (type
== bool_char_type_node
) return "U6__boolc";
24499 if (type
== bool_short_type_node
) return "U6__bools";
24500 if (type
== pixel_type_node
) return "u7__pixel";
24501 if (type
== bool_int_type_node
) return "U6__booli";
24502 if (type
== bool_long_type_node
) return "U6__booll";
24504 /* Mangle IBM extended float long double as `g' (__float128) on
24505 powerpc*-linux where long-double-64 previously was the default. */
24506 if (TYPE_MAIN_VARIANT (type
) == long_double_type_node
24508 && TARGET_LONG_DOUBLE_128
24509 && !TARGET_IEEEQUAD
)
24512 /* For all other types, use normal C++ mangling. */
24516 /* Handle a "longcall" or "shortcall" attribute; arguments as in
24517 struct attribute_spec.handler. */
24520 rs6000_handle_longcall_attribute (tree
*node
, tree name
,
24521 tree args ATTRIBUTE_UNUSED
,
24522 int flags ATTRIBUTE_UNUSED
,
24523 bool *no_add_attrs
)
24525 if (TREE_CODE (*node
) != FUNCTION_TYPE
24526 && TREE_CODE (*node
) != FIELD_DECL
24527 && TREE_CODE (*node
) != TYPE_DECL
)
24529 warning (OPT_Wattributes
, "%qE attribute only applies to functions",
24531 *no_add_attrs
= true;
24537 /* Set longcall attributes on all functions declared when
24538 rs6000_default_long_calls is true. */
24540 rs6000_set_default_type_attributes (tree type
)
24542 if (rs6000_default_long_calls
24543 && (TREE_CODE (type
) == FUNCTION_TYPE
24544 || TREE_CODE (type
) == METHOD_TYPE
))
24545 TYPE_ATTRIBUTES (type
) = tree_cons (get_identifier ("longcall"),
24547 TYPE_ATTRIBUTES (type
));
24550 darwin_set_default_type_attributes (type
);
24554 /* Return a reference suitable for calling a function with the
24555 longcall attribute. */
24558 rs6000_longcall_ref (rtx call_ref
)
24560 const char *call_name
;
24563 if (GET_CODE (call_ref
) != SYMBOL_REF
)
24566 /* System V adds '.' to the internal name, so skip them. */
24567 call_name
= XSTR (call_ref
, 0);
24568 if (*call_name
== '.')
24570 while (*call_name
== '.')
24573 node
= get_identifier (call_name
);
24574 call_ref
= gen_rtx_SYMBOL_REF (VOIDmode
, IDENTIFIER_POINTER (node
));
24577 return force_reg (Pmode
, call_ref
);
24580 #ifndef TARGET_USE_MS_BITFIELD_LAYOUT
24581 #define TARGET_USE_MS_BITFIELD_LAYOUT 0
24584 /* Handle a "ms_struct" or "gcc_struct" attribute; arguments as in
24585 struct attribute_spec.handler. */
24587 rs6000_handle_struct_attribute (tree
*node
, tree name
,
24588 tree args ATTRIBUTE_UNUSED
,
24589 int flags ATTRIBUTE_UNUSED
, bool *no_add_attrs
)
24592 if (DECL_P (*node
))
24594 if (TREE_CODE (*node
) == TYPE_DECL
)
24595 type
= &TREE_TYPE (*node
);
24600 if (!(type
&& (TREE_CODE (*type
) == RECORD_TYPE
24601 || TREE_CODE (*type
) == UNION_TYPE
)))
24603 warning (OPT_Wattributes
, "%qE attribute ignored", name
);
24604 *no_add_attrs
= true;
24607 else if ((is_attribute_p ("ms_struct", name
)
24608 && lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (*type
)))
24609 || ((is_attribute_p ("gcc_struct", name
)
24610 && lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (*type
)))))
24612 warning (OPT_Wattributes
, "%qE incompatible attribute ignored",
24614 *no_add_attrs
= true;
24621 rs6000_ms_bitfield_layout_p (const_tree record_type
)
24623 return (TARGET_USE_MS_BITFIELD_LAYOUT
&&
24624 !lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (record_type
)))
24625 || lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (record_type
));
24628 #ifdef USING_ELFOS_H
24630 /* A get_unnamed_section callback, used for switching to toc_section. */
24633 rs6000_elf_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED
)
24635 if (DEFAULT_ABI
== ABI_AIX
24636 && TARGET_MINIMAL_TOC
24637 && !TARGET_RELOCATABLE
)
24639 if (!toc_initialized
)
24641 toc_initialized
= 1;
24642 fprintf (asm_out_file
, "%s\n", TOC_SECTION_ASM_OP
);
24643 (*targetm
.asm_out
.internal_label
) (asm_out_file
, "LCTOC", 0);
24644 fprintf (asm_out_file
, "\t.tc ");
24645 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file
, "LCTOC1[TC],");
24646 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file
, "LCTOC1");
24647 fprintf (asm_out_file
, "\n");
24649 fprintf (asm_out_file
, "%s\n", MINIMAL_TOC_SECTION_ASM_OP
);
24650 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file
, "LCTOC1");
24651 fprintf (asm_out_file
, " = .+32768\n");
24654 fprintf (asm_out_file
, "%s\n", MINIMAL_TOC_SECTION_ASM_OP
);
24656 else if (DEFAULT_ABI
== ABI_AIX
&& !TARGET_RELOCATABLE
)
24657 fprintf (asm_out_file
, "%s\n", TOC_SECTION_ASM_OP
);
24660 fprintf (asm_out_file
, "%s\n", MINIMAL_TOC_SECTION_ASM_OP
);
24661 if (!toc_initialized
)
24663 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file
, "LCTOC1");
24664 fprintf (asm_out_file
, " = .+32768\n");
24665 toc_initialized
= 1;
24670 /* Implement TARGET_ASM_INIT_SECTIONS. */
24673 rs6000_elf_asm_init_sections (void)
24676 = get_unnamed_section (0, rs6000_elf_output_toc_section_asm_op
, NULL
);
24679 = get_unnamed_section (SECTION_WRITE
, output_section_asm_op
,
24680 SDATA2_SECTION_ASM_OP
);
24683 /* Implement TARGET_SELECT_RTX_SECTION. */
24686 rs6000_elf_select_rtx_section (enum machine_mode mode
, rtx x
,
24687 unsigned HOST_WIDE_INT align
)
24689 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x
, mode
))
24690 return toc_section
;
24692 return default_elf_select_rtx_section (mode
, x
, align
);
24695 /* For a SYMBOL_REF, set generic flags and then perform some
24696 target-specific processing.
24698 When the AIX ABI is requested on a non-AIX system, replace the
24699 function name with the real name (with a leading .) rather than the
24700 function descriptor name. This saves a lot of overriding code to
24701 read the prefixes. */
24704 rs6000_elf_encode_section_info (tree decl
, rtx rtl
, int first
)
24706 default_encode_section_info (decl
, rtl
, first
);
24709 && TREE_CODE (decl
) == FUNCTION_DECL
24711 && DEFAULT_ABI
== ABI_AIX
)
24713 rtx sym_ref
= XEXP (rtl
, 0);
24714 size_t len
= strlen (XSTR (sym_ref
, 0));
24715 char *str
= XALLOCAVEC (char, len
+ 2);
24717 memcpy (str
+ 1, XSTR (sym_ref
, 0), len
+ 1);
24718 XSTR (sym_ref
, 0) = ggc_alloc_string (str
, len
+ 1);
24723 compare_section_name (const char *section
, const char *templ
)
24727 len
= strlen (templ
);
24728 return (strncmp (section
, templ
, len
) == 0
24729 && (section
[len
] == 0 || section
[len
] == '.'));
24733 rs6000_elf_in_small_data_p (const_tree decl
)
24735 if (rs6000_sdata
== SDATA_NONE
)
24738 /* We want to merge strings, so we never consider them small data. */
24739 if (TREE_CODE (decl
) == STRING_CST
)
24742 /* Functions are never in the small data area. */
24743 if (TREE_CODE (decl
) == FUNCTION_DECL
)
24746 if (TREE_CODE (decl
) == VAR_DECL
&& DECL_SECTION_NAME (decl
))
24748 const char *section
= TREE_STRING_POINTER (DECL_SECTION_NAME (decl
));
24749 if (compare_section_name (section
, ".sdata")
24750 || compare_section_name (section
, ".sdata2")
24751 || compare_section_name (section
, ".gnu.linkonce.s")
24752 || compare_section_name (section
, ".sbss")
24753 || compare_section_name (section
, ".sbss2")
24754 || compare_section_name (section
, ".gnu.linkonce.sb")
24755 || strcmp (section
, ".PPC.EMB.sdata0") == 0
24756 || strcmp (section
, ".PPC.EMB.sbss0") == 0)
24761 HOST_WIDE_INT size
= int_size_in_bytes (TREE_TYPE (decl
));
24764 && (unsigned HOST_WIDE_INT
) size
<= g_switch_value
24765 /* If it's not public, and we're not going to reference it there,
24766 there's no need to put it in the small data section. */
24767 && (rs6000_sdata
!= SDATA_DATA
|| TREE_PUBLIC (decl
)))
24774 #endif /* USING_ELFOS_H */
24776 /* Implement TARGET_USE_BLOCKS_FOR_CONSTANT_P. */
24779 rs6000_use_blocks_for_constant_p (enum machine_mode mode
, const_rtx x
)
24781 return !ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x
, mode
);
24784 /* Return a REG that occurs in ADDR with coefficient 1.
24785 ADDR can be effectively incremented by incrementing REG.
24787 r0 is special and we must not select it as an address
24788 register by this routine since our caller will try to
24789 increment the returned register via an "la" instruction. */
24792 find_addr_reg (rtx addr
)
24794 while (GET_CODE (addr
) == PLUS
)
24796 if (GET_CODE (XEXP (addr
, 0)) == REG
24797 && REGNO (XEXP (addr
, 0)) != 0)
24798 addr
= XEXP (addr
, 0);
24799 else if (GET_CODE (XEXP (addr
, 1)) == REG
24800 && REGNO (XEXP (addr
, 1)) != 0)
24801 addr
= XEXP (addr
, 1);
24802 else if (CONSTANT_P (XEXP (addr
, 0)))
24803 addr
= XEXP (addr
, 1);
24804 else if (CONSTANT_P (XEXP (addr
, 1)))
24805 addr
= XEXP (addr
, 0);
24807 gcc_unreachable ();
24809 gcc_assert (GET_CODE (addr
) == REG
&& REGNO (addr
) != 0);
24814 rs6000_fatal_bad_address (rtx op
)
24816 fatal_insn ("bad address", op
);
24821 typedef struct branch_island_d
{
24822 tree function_name
;
24827 DEF_VEC_O(branch_island
);
24828 DEF_VEC_ALLOC_O(branch_island
,gc
);
24830 static VEC(branch_island
,gc
) *branch_islands
;
24832 /* Remember to generate a branch island for far calls to the given
24836 add_compiler_branch_island (tree label_name
, tree function_name
,
24839 branch_island
*bi
= VEC_safe_push (branch_island
, gc
, branch_islands
, NULL
);
24841 bi
->function_name
= function_name
;
24842 bi
->label_name
= label_name
;
24843 bi
->line_number
= line_number
;
24846 /* Generate far-jump branch islands for everything recorded in
24847 branch_islands. Invoked immediately after the last instruction of
24848 the epilogue has been emitted; the branch islands must be appended
24849 to, and contiguous with, the function body. Mach-O stubs are
24850 generated in machopic_output_stub(). */
24853 macho_branch_islands (void)
24857 while (!VEC_empty (branch_island
, branch_islands
))
24859 branch_island
*bi
= VEC_last (branch_island
, branch_islands
);
24860 const char *label
= IDENTIFIER_POINTER (bi
->label_name
);
24861 const char *name
= IDENTIFIER_POINTER (bi
->function_name
);
24862 char name_buf
[512];
24863 /* Cheap copy of the details from the Darwin ASM_OUTPUT_LABELREF(). */
24864 if (name
[0] == '*' || name
[0] == '&')
24865 strcpy (name_buf
, name
+1);
24869 strcpy (name_buf
+1, name
);
24871 strcpy (tmp_buf
, "\n");
24872 strcat (tmp_buf
, label
);
24873 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
24874 if (write_symbols
== DBX_DEBUG
|| write_symbols
== XCOFF_DEBUG
)
24875 dbxout_stabd (N_SLINE
, bi
->line_number
);
24876 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
24879 strcat (tmp_buf
, ":\n\tmflr r0\n\tbcl 20,31,");
24880 strcat (tmp_buf
, label
);
24881 strcat (tmp_buf
, "_pic\n");
24882 strcat (tmp_buf
, label
);
24883 strcat (tmp_buf
, "_pic:\n\tmflr r11\n");
24885 strcat (tmp_buf
, "\taddis r11,r11,ha16(");
24886 strcat (tmp_buf
, name_buf
);
24887 strcat (tmp_buf
, " - ");
24888 strcat (tmp_buf
, label
);
24889 strcat (tmp_buf
, "_pic)\n");
24891 strcat (tmp_buf
, "\tmtlr r0\n");
24893 strcat (tmp_buf
, "\taddi r12,r11,lo16(");
24894 strcat (tmp_buf
, name_buf
);
24895 strcat (tmp_buf
, " - ");
24896 strcat (tmp_buf
, label
);
24897 strcat (tmp_buf
, "_pic)\n");
24899 strcat (tmp_buf
, "\tmtctr r12\n\tbctr\n");
24903 strcat (tmp_buf
, ":\nlis r12,hi16(");
24904 strcat (tmp_buf
, name_buf
);
24905 strcat (tmp_buf
, ")\n\tori r12,r12,lo16(");
24906 strcat (tmp_buf
, name_buf
);
24907 strcat (tmp_buf
, ")\n\tmtctr r12\n\tbctr");
24909 output_asm_insn (tmp_buf
, 0);
24910 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
24911 if (write_symbols
== DBX_DEBUG
|| write_symbols
== XCOFF_DEBUG
)
24912 dbxout_stabd (N_SLINE
, bi
->line_number
);
24913 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
24914 VEC_pop (branch_island
, branch_islands
);
24918 /* NO_PREVIOUS_DEF checks in the link list whether the function name is
24919 already there or not. */
24922 no_previous_def (tree function_name
)
24927 FOR_EACH_VEC_ELT (branch_island
, branch_islands
, ix
, bi
)
24928 if (function_name
== bi
->function_name
)
24933 /* GET_PREV_LABEL gets the label name from the previous definition of
24937 get_prev_label (tree function_name
)
24942 FOR_EACH_VEC_ELT (branch_island
, branch_islands
, ix
, bi
)
24943 if (function_name
== bi
->function_name
)
24944 return bi
->label_name
;
24948 /* INSN is either a function call or a millicode call. It may have an
24949 unconditional jump in its delay slot.
24951 CALL_DEST is the routine we are calling. */
24954 output_call (rtx insn
, rtx
*operands
, int dest_operand_number
,
24955 int cookie_operand_number
)
24957 static char buf
[256];
24958 if (darwin_emit_branch_islands
24959 && GET_CODE (operands
[dest_operand_number
]) == SYMBOL_REF
24960 && (INTVAL (operands
[cookie_operand_number
]) & CALL_LONG
))
24963 tree funname
= get_identifier (XSTR (operands
[dest_operand_number
], 0));
24965 if (no_previous_def (funname
))
24967 rtx label_rtx
= gen_label_rtx ();
24968 char *label_buf
, temp_buf
[256];
24969 ASM_GENERATE_INTERNAL_LABEL (temp_buf
, "L",
24970 CODE_LABEL_NUMBER (label_rtx
));
24971 label_buf
= temp_buf
[0] == '*' ? temp_buf
+ 1 : temp_buf
;
24972 labelname
= get_identifier (label_buf
);
24973 add_compiler_branch_island (labelname
, funname
, insn_line (insn
));
24976 labelname
= get_prev_label (funname
);
24978 /* "jbsr foo, L42" is Mach-O for "Link as 'bl foo' if a 'bl'
24979 instruction will reach 'foo', otherwise link as 'bl L42'".
24980 "L42" should be a 'branch island', that will do a far jump to
24981 'foo'. Branch islands are generated in
24982 macho_branch_islands(). */
24983 sprintf (buf
, "jbsr %%z%d,%.246s",
24984 dest_operand_number
, IDENTIFIER_POINTER (labelname
));
24987 sprintf (buf
, "bl %%z%d", dest_operand_number
);
24991 /* Generate PIC and indirect symbol stubs. */
24994 machopic_output_stub (FILE *file
, const char *symb
, const char *stub
)
24996 unsigned int length
;
24997 char *symbol_name
, *lazy_ptr_name
;
24998 char *local_label_0
;
24999 static int label
= 0;
25001 /* Lose our funky encoding stuff so it doesn't contaminate the stub. */
25002 symb
= (*targetm
.strip_name_encoding
) (symb
);
25005 length
= strlen (symb
);
25006 symbol_name
= XALLOCAVEC (char, length
+ 32);
25007 GEN_SYMBOL_NAME_FOR_SYMBOL (symbol_name
, symb
, length
);
25009 lazy_ptr_name
= XALLOCAVEC (char, length
+ 32);
25010 GEN_LAZY_PTR_NAME_FOR_SYMBOL (lazy_ptr_name
, symb
, length
);
25013 switch_to_section (darwin_sections
[machopic_picsymbol_stub1_section
]);
25015 switch_to_section (darwin_sections
[machopic_symbol_stub1_section
]);
25019 fprintf (file
, "\t.align 5\n");
25021 fprintf (file
, "%s:\n", stub
);
25022 fprintf (file
, "\t.indirect_symbol %s\n", symbol_name
);
25025 local_label_0
= XALLOCAVEC (char, sizeof ("\"L00000000000$spb\""));
25026 sprintf (local_label_0
, "\"L%011d$spb\"", label
);
25028 fprintf (file
, "\tmflr r0\n");
25029 fprintf (file
, "\tbcl 20,31,%s\n", local_label_0
);
25030 fprintf (file
, "%s:\n\tmflr r11\n", local_label_0
);
25031 fprintf (file
, "\taddis r11,r11,ha16(%s-%s)\n",
25032 lazy_ptr_name
, local_label_0
);
25033 fprintf (file
, "\tmtlr r0\n");
25034 fprintf (file
, "\t%s r12,lo16(%s-%s)(r11)\n",
25035 (TARGET_64BIT
? "ldu" : "lwzu"),
25036 lazy_ptr_name
, local_label_0
);
25037 fprintf (file
, "\tmtctr r12\n");
25038 fprintf (file
, "\tbctr\n");
25042 fprintf (file
, "\t.align 4\n");
25044 fprintf (file
, "%s:\n", stub
);
25045 fprintf (file
, "\t.indirect_symbol %s\n", symbol_name
);
25047 fprintf (file
, "\tlis r11,ha16(%s)\n", lazy_ptr_name
);
25048 fprintf (file
, "\t%s r12,lo16(%s)(r11)\n",
25049 (TARGET_64BIT
? "ldu" : "lwzu"),
25051 fprintf (file
, "\tmtctr r12\n");
25052 fprintf (file
, "\tbctr\n");
25055 switch_to_section (darwin_sections
[machopic_lazy_symbol_ptr_section
]);
25056 fprintf (file
, "%s:\n", lazy_ptr_name
);
25057 fprintf (file
, "\t.indirect_symbol %s\n", symbol_name
);
25058 fprintf (file
, "%sdyld_stub_binding_helper\n",
25059 (TARGET_64BIT
? DOUBLE_INT_ASM_OP
: "\t.long\t"));
25062 /* Legitimize PIC addresses. If the address is already
25063 position-independent, we return ORIG. Newly generated
25064 position-independent addresses go into a reg. This is REG if non
25065 zero, otherwise we allocate register(s) as necessary. */
25067 #define SMALL_INT(X) ((UINTVAL (X) + 0x8000) < 0x10000)
25070 rs6000_machopic_legitimize_pic_address (rtx orig
, enum machine_mode mode
,
25075 if (reg
== NULL
&& ! reload_in_progress
&& ! reload_completed
)
25076 reg
= gen_reg_rtx (Pmode
);
25078 if (GET_CODE (orig
) == CONST
)
25082 if (GET_CODE (XEXP (orig
, 0)) == PLUS
25083 && XEXP (XEXP (orig
, 0), 0) == pic_offset_table_rtx
)
25086 gcc_assert (GET_CODE (XEXP (orig
, 0)) == PLUS
);
25088 /* Use a different reg for the intermediate value, as
25089 it will be marked UNCHANGING. */
25090 reg_temp
= !can_create_pseudo_p () ? reg
: gen_reg_rtx (Pmode
);
25091 base
= rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig
, 0), 0),
25094 rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig
, 0), 1),
25097 if (GET_CODE (offset
) == CONST_INT
)
25099 if (SMALL_INT (offset
))
25100 return plus_constant (base
, INTVAL (offset
));
25101 else if (! reload_in_progress
&& ! reload_completed
)
25102 offset
= force_reg (Pmode
, offset
);
25105 rtx mem
= force_const_mem (Pmode
, orig
);
25106 return machopic_legitimize_pic_address (mem
, Pmode
, reg
);
25109 return gen_rtx_PLUS (Pmode
, base
, offset
);
25112 /* Fall back on generic machopic code. */
25113 return machopic_legitimize_pic_address (orig
, mode
, reg
);
25116 /* Output a .machine directive for the Darwin assembler, and call
25117 the generic start_file routine. */
25120 rs6000_darwin_file_start (void)
25122 static const struct
25128 { "ppc64", "ppc64", MASK_64BIT
},
25129 { "970", "ppc970", MASK_PPC_GPOPT
| MASK_MFCRF
| MASK_POWERPC64
},
25130 { "power4", "ppc970", 0 },
25131 { "G5", "ppc970", 0 },
25132 { "7450", "ppc7450", 0 },
25133 { "7400", "ppc7400", MASK_ALTIVEC
},
25134 { "G4", "ppc7400", 0 },
25135 { "750", "ppc750", 0 },
25136 { "740", "ppc750", 0 },
25137 { "G3", "ppc750", 0 },
25138 { "604e", "ppc604e", 0 },
25139 { "604", "ppc604", 0 },
25140 { "603e", "ppc603", 0 },
25141 { "603", "ppc603", 0 },
25142 { "601", "ppc601", 0 },
25143 { NULL
, "ppc", 0 } };
25144 const char *cpu_id
= "";
25147 rs6000_file_start ();
25148 darwin_file_start ();
25150 /* Determine the argument to -mcpu=. Default to G3 if not specified. */
25151 for (i
= 0; i
< ARRAY_SIZE (rs6000_select
); i
++)
25152 if (rs6000_select
[i
].set_arch_p
&& rs6000_select
[i
].string
25153 && rs6000_select
[i
].string
[0] != '\0')
25154 cpu_id
= rs6000_select
[i
].string
;
25156 /* Look through the mapping array. Pick the first name that either
25157 matches the argument, has a bit set in IF_SET that is also set
25158 in the target flags, or has a NULL name. */
25161 while (mapping
[i
].arg
!= NULL
25162 && strcmp (mapping
[i
].arg
, cpu_id
) != 0
25163 && (mapping
[i
].if_set
& target_flags
) == 0)
25166 fprintf (asm_out_file
, "\t.machine %s\n", mapping
[i
].name
);
25169 #endif /* TARGET_MACHO */
25173 rs6000_elf_reloc_rw_mask (void)
25177 else if (DEFAULT_ABI
== ABI_AIX
)
25183 /* Record an element in the table of global constructors. SYMBOL is
25184 a SYMBOL_REF of the function to be called; PRIORITY is a number
25185 between 0 and MAX_INIT_PRIORITY.
25187 This differs from default_named_section_asm_out_constructor in
25188 that we have special handling for -mrelocatable. */
25191 rs6000_elf_asm_out_constructor (rtx symbol
, int priority
)
25193 const char *section
= ".ctors";
25196 if (priority
!= DEFAULT_INIT_PRIORITY
)
25198 sprintf (buf
, ".ctors.%.5u",
25199 /* Invert the numbering so the linker puts us in the proper
25200 order; constructors are run from right to left, and the
25201 linker sorts in increasing order. */
25202 MAX_INIT_PRIORITY
- priority
);
25206 switch_to_section (get_section (section
, SECTION_WRITE
, NULL
));
25207 assemble_align (POINTER_SIZE
);
25209 if (TARGET_RELOCATABLE
)
25211 fputs ("\t.long (", asm_out_file
);
25212 output_addr_const (asm_out_file
, symbol
);
25213 fputs (")@fixup\n", asm_out_file
);
25216 assemble_integer (symbol
, POINTER_SIZE
/ BITS_PER_UNIT
, POINTER_SIZE
, 1);
25220 rs6000_elf_asm_out_destructor (rtx symbol
, int priority
)
25222 const char *section
= ".dtors";
25225 if (priority
!= DEFAULT_INIT_PRIORITY
)
25227 sprintf (buf
, ".dtors.%.5u",
25228 /* Invert the numbering so the linker puts us in the proper
25229 order; constructors are run from right to left, and the
25230 linker sorts in increasing order. */
25231 MAX_INIT_PRIORITY
- priority
);
25235 switch_to_section (get_section (section
, SECTION_WRITE
, NULL
));
25236 assemble_align (POINTER_SIZE
);
25238 if (TARGET_RELOCATABLE
)
25240 fputs ("\t.long (", asm_out_file
);
25241 output_addr_const (asm_out_file
, symbol
);
25242 fputs (")@fixup\n", asm_out_file
);
25245 assemble_integer (symbol
, POINTER_SIZE
/ BITS_PER_UNIT
, POINTER_SIZE
, 1);
25249 rs6000_elf_declare_function_name (FILE *file
, const char *name
, tree decl
)
25253 fputs ("\t.section\t\".opd\",\"aw\"\n\t.align 3\n", file
);
25254 ASM_OUTPUT_LABEL (file
, name
);
25255 fputs (DOUBLE_INT_ASM_OP
, file
);
25256 rs6000_output_function_entry (file
, name
);
25257 fputs (",.TOC.@tocbase,0\n\t.previous\n", file
);
25260 fputs ("\t.size\t", file
);
25261 assemble_name (file
, name
);
25262 fputs (",24\n\t.type\t.", file
);
25263 assemble_name (file
, name
);
25264 fputs (",@function\n", file
);
25265 if (TREE_PUBLIC (decl
) && ! DECL_WEAK (decl
))
25267 fputs ("\t.globl\t.", file
);
25268 assemble_name (file
, name
);
25273 ASM_OUTPUT_TYPE_DIRECTIVE (file
, name
, "function");
25274 ASM_DECLARE_RESULT (file
, DECL_RESULT (decl
));
25275 rs6000_output_function_entry (file
, name
);
25276 fputs (":\n", file
);
25280 if (TARGET_RELOCATABLE
25281 && !TARGET_SECURE_PLT
25282 && (get_pool_size () != 0 || crtl
->profile
)
25287 (*targetm
.asm_out
.internal_label
) (file
, "LCL", rs6000_pic_labelno
);
25289 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCTOC", 1);
25290 fprintf (file
, "\t.long ");
25291 assemble_name (file
, buf
);
25293 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCF", rs6000_pic_labelno
);
25294 assemble_name (file
, buf
);
25298 ASM_OUTPUT_TYPE_DIRECTIVE (file
, name
, "function");
25299 ASM_DECLARE_RESULT (file
, DECL_RESULT (decl
));
25301 if (DEFAULT_ABI
== ABI_AIX
)
25303 const char *desc_name
, *orig_name
;
25305 orig_name
= (*targetm
.strip_name_encoding
) (name
);
25306 desc_name
= orig_name
;
25307 while (*desc_name
== '.')
25310 if (TREE_PUBLIC (decl
))
25311 fprintf (file
, "\t.globl %s\n", desc_name
);
25313 fprintf (file
, "%s\n", MINIMAL_TOC_SECTION_ASM_OP
);
25314 fprintf (file
, "%s:\n", desc_name
);
25315 fprintf (file
, "\t.long %s\n", orig_name
);
25316 fputs ("\t.long _GLOBAL_OFFSET_TABLE_\n", file
);
25317 if (DEFAULT_ABI
== ABI_AIX
)
25318 fputs ("\t.long 0\n", file
);
25319 fprintf (file
, "\t.previous\n");
25321 ASM_OUTPUT_LABEL (file
, name
);
25325 rs6000_elf_end_indicate_exec_stack (void)
25328 file_end_indicate_exec_stack ();
25334 rs6000_xcoff_asm_output_anchor (rtx symbol
)
25338 sprintf (buffer
, "$ + " HOST_WIDE_INT_PRINT_DEC
,
25339 SYMBOL_REF_BLOCK_OFFSET (symbol
));
25340 ASM_OUTPUT_DEF (asm_out_file
, XSTR (symbol
, 0), buffer
);
25344 rs6000_xcoff_asm_globalize_label (FILE *stream
, const char *name
)
25346 fputs (GLOBAL_ASM_OP
, stream
);
25347 RS6000_OUTPUT_BASENAME (stream
, name
);
25348 putc ('\n', stream
);
25351 /* A get_unnamed_decl callback, used for read-only sections. PTR
25352 points to the section string variable. */
25355 rs6000_xcoff_output_readonly_section_asm_op (const void *directive
)
25357 fprintf (asm_out_file
, "\t.csect %s[RO],%s\n",
25358 *(const char *const *) directive
,
25359 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR
);
25362 /* Likewise for read-write sections. */
25365 rs6000_xcoff_output_readwrite_section_asm_op (const void *directive
)
25367 fprintf (asm_out_file
, "\t.csect %s[RW],%s\n",
25368 *(const char *const *) directive
,
25369 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR
);
25372 /* A get_unnamed_section callback, used for switching to toc_section. */
25375 rs6000_xcoff_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED
)
25377 if (TARGET_MINIMAL_TOC
)
25379 /* toc_section is always selected at least once from
25380 rs6000_xcoff_file_start, so this is guaranteed to
25381 always be defined once and only once in each file. */
25382 if (!toc_initialized
)
25384 fputs ("\t.toc\nLCTOC..1:\n", asm_out_file
);
25385 fputs ("\t.tc toc_table[TC],toc_table[RW]\n", asm_out_file
);
25386 toc_initialized
= 1;
25388 fprintf (asm_out_file
, "\t.csect toc_table[RW]%s\n",
25389 (TARGET_32BIT
? "" : ",3"));
25392 fputs ("\t.toc\n", asm_out_file
);
25395 /* Implement TARGET_ASM_INIT_SECTIONS. */
25398 rs6000_xcoff_asm_init_sections (void)
25400 read_only_data_section
25401 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op
,
25402 &xcoff_read_only_section_name
);
25404 private_data_section
25405 = get_unnamed_section (SECTION_WRITE
,
25406 rs6000_xcoff_output_readwrite_section_asm_op
,
25407 &xcoff_private_data_section_name
);
25409 read_only_private_data_section
25410 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op
,
25411 &xcoff_private_data_section_name
);
25414 = get_unnamed_section (0, rs6000_xcoff_output_toc_section_asm_op
, NULL
);
25416 readonly_data_section
= read_only_data_section
;
25417 exception_section
= data_section
;
25421 rs6000_xcoff_reloc_rw_mask (void)
25427 rs6000_xcoff_asm_named_section (const char *name
, unsigned int flags
,
25428 tree decl ATTRIBUTE_UNUSED
)
25431 static const char * const suffix
[3] = { "PR", "RO", "RW" };
25433 if (flags
& SECTION_CODE
)
25435 else if (flags
& SECTION_WRITE
)
25440 fprintf (asm_out_file
, "\t.csect %s%s[%s],%u\n",
25441 (flags
& SECTION_CODE
) ? "." : "",
25442 name
, suffix
[smclass
], flags
& SECTION_ENTSIZE
);
25446 rs6000_xcoff_select_section (tree decl
, int reloc
,
25447 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED
)
25449 if (decl_readonly_section (decl
, reloc
))
25451 if (TREE_PUBLIC (decl
))
25452 return read_only_data_section
;
25454 return read_only_private_data_section
;
25458 if (TREE_PUBLIC (decl
))
25459 return data_section
;
25461 return private_data_section
;
25466 rs6000_xcoff_unique_section (tree decl
, int reloc ATTRIBUTE_UNUSED
)
25470 /* Use select_section for private and uninitialized data. */
25471 if (!TREE_PUBLIC (decl
)
25472 || DECL_COMMON (decl
)
25473 || DECL_INITIAL (decl
) == NULL_TREE
25474 || DECL_INITIAL (decl
) == error_mark_node
25475 || (flag_zero_initialized_in_bss
25476 && initializer_zerop (DECL_INITIAL (decl
))))
25479 name
= IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl
));
25480 name
= (*targetm
.strip_name_encoding
) (name
);
25481 DECL_SECTION_NAME (decl
) = build_string (strlen (name
), name
);
25484 /* Select section for constant in constant pool.
25486 On RS/6000, all constants are in the private read-only data area.
25487 However, if this is being placed in the TOC it must be output as a
25491 rs6000_xcoff_select_rtx_section (enum machine_mode mode
, rtx x
,
25492 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED
)
25494 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x
, mode
))
25495 return toc_section
;
25497 return read_only_private_data_section
;
25500 /* Remove any trailing [DS] or the like from the symbol name. */
25502 static const char *
25503 rs6000_xcoff_strip_name_encoding (const char *name
)
25508 len
= strlen (name
);
25509 if (name
[len
- 1] == ']')
25510 return ggc_alloc_string (name
, len
- 4);
25515 /* Section attributes. AIX is always PIC. */
25517 static unsigned int
25518 rs6000_xcoff_section_type_flags (tree decl
, const char *name
, int reloc
)
25520 unsigned int align
;
25521 unsigned int flags
= default_section_type_flags (decl
, name
, reloc
);
25523 /* Align to at least UNIT size. */
25524 if (flags
& SECTION_CODE
)
25525 align
= MIN_UNITS_PER_WORD
;
25527 /* Increase alignment of large objects if not already stricter. */
25528 align
= MAX ((DECL_ALIGN (decl
) / BITS_PER_UNIT
),
25529 int_size_in_bytes (TREE_TYPE (decl
)) > MIN_UNITS_PER_WORD
25530 ? UNITS_PER_FP_WORD
: MIN_UNITS_PER_WORD
);
25532 return flags
| (exact_log2 (align
) & SECTION_ENTSIZE
);
25535 /* Output at beginning of assembler file.
25537 Initialize the section names for the RS/6000 at this point.
25539 Specify filename, including full path, to assembler.
25541 We want to go into the TOC section so at least one .toc will be emitted.
25542 Also, in order to output proper .bs/.es pairs, we need at least one static
25543 [RW] section emitted.
25545 Finally, declare mcount when profiling to make the assembler happy. */
25548 rs6000_xcoff_file_start (void)
25550 rs6000_gen_section_name (&xcoff_bss_section_name
,
25551 main_input_filename
, ".bss_");
25552 rs6000_gen_section_name (&xcoff_private_data_section_name
,
25553 main_input_filename
, ".rw_");
25554 rs6000_gen_section_name (&xcoff_read_only_section_name
,
25555 main_input_filename
, ".ro_");
25557 fputs ("\t.file\t", asm_out_file
);
25558 output_quoted_string (asm_out_file
, main_input_filename
);
25559 fputc ('\n', asm_out_file
);
25560 if (write_symbols
!= NO_DEBUG
)
25561 switch_to_section (private_data_section
);
25562 switch_to_section (text_section
);
25564 fprintf (asm_out_file
, "\t.extern %s\n", RS6000_MCOUNT
);
25565 rs6000_file_start ();
25568 /* Output at end of assembler file.
25569 On the RS/6000, referencing data should automatically pull in text. */
25572 rs6000_xcoff_file_end (void)
25574 switch_to_section (text_section
);
25575 fputs ("_section_.text:\n", asm_out_file
);
25576 switch_to_section (data_section
);
25577 fputs (TARGET_32BIT
25578 ? "\t.long _section_.text\n" : "\t.llong _section_.text\n",
25581 #endif /* TARGET_XCOFF */
25583 /* Compute a (partial) cost for rtx X. Return true if the complete
25584 cost has been computed, and false if subexpressions should be
25585 scanned. In either case, *TOTAL contains the cost result. */
25588 rs6000_rtx_costs (rtx x
, int code
, int outer_code
, int *total
,
25591 enum machine_mode mode
= GET_MODE (x
);
25595 /* On the RS/6000, if it is valid in the insn, it is free. */
25597 if (((outer_code
== SET
25598 || outer_code
== PLUS
25599 || outer_code
== MINUS
)
25600 && (satisfies_constraint_I (x
)
25601 || satisfies_constraint_L (x
)))
25602 || (outer_code
== AND
25603 && (satisfies_constraint_K (x
)
25605 ? satisfies_constraint_L (x
)
25606 : satisfies_constraint_J (x
))
25607 || mask_operand (x
, mode
)
25609 && mask64_operand (x
, DImode
))))
25610 || ((outer_code
== IOR
|| outer_code
== XOR
)
25611 && (satisfies_constraint_K (x
)
25613 ? satisfies_constraint_L (x
)
25614 : satisfies_constraint_J (x
))))
25615 || outer_code
== ASHIFT
25616 || outer_code
== ASHIFTRT
25617 || outer_code
== LSHIFTRT
25618 || outer_code
== ROTATE
25619 || outer_code
== ROTATERT
25620 || outer_code
== ZERO_EXTRACT
25621 || (outer_code
== MULT
25622 && satisfies_constraint_I (x
))
25623 || ((outer_code
== DIV
|| outer_code
== UDIV
25624 || outer_code
== MOD
|| outer_code
== UMOD
)
25625 && exact_log2 (INTVAL (x
)) >= 0)
25626 || (outer_code
== COMPARE
25627 && (satisfies_constraint_I (x
)
25628 || satisfies_constraint_K (x
)))
25629 || (outer_code
== EQ
25630 && (satisfies_constraint_I (x
)
25631 || satisfies_constraint_K (x
)
25633 ? satisfies_constraint_L (x
)
25634 : satisfies_constraint_J (x
))))
25635 || (outer_code
== GTU
25636 && satisfies_constraint_I (x
))
25637 || (outer_code
== LTU
25638 && satisfies_constraint_P (x
)))
25643 else if ((outer_code
== PLUS
25644 && reg_or_add_cint_operand (x
, VOIDmode
))
25645 || (outer_code
== MINUS
25646 && reg_or_sub_cint_operand (x
, VOIDmode
))
25647 || ((outer_code
== SET
25648 || outer_code
== IOR
25649 || outer_code
== XOR
)
25651 & ~ (unsigned HOST_WIDE_INT
) 0xffffffff) == 0))
25653 *total
= COSTS_N_INSNS (1);
25659 if (mode
== DImode
&& code
== CONST_DOUBLE
)
25661 if ((outer_code
== IOR
|| outer_code
== XOR
)
25662 && CONST_DOUBLE_HIGH (x
) == 0
25663 && (CONST_DOUBLE_LOW (x
)
25664 & ~ (unsigned HOST_WIDE_INT
) 0xffff) == 0)
25669 else if ((outer_code
== AND
&& and64_2_operand (x
, DImode
))
25670 || ((outer_code
== SET
25671 || outer_code
== IOR
25672 || outer_code
== XOR
)
25673 && CONST_DOUBLE_HIGH (x
) == 0))
25675 *total
= COSTS_N_INSNS (1);
25685 /* When optimizing for size, MEM should be slightly more expensive
25686 than generating address, e.g., (plus (reg) (const)).
25687 L1 cache latency is about two instructions. */
25688 *total
= !speed
? COSTS_N_INSNS (1) + 1 : COSTS_N_INSNS (2);
25696 if (mode
== DFmode
)
25698 if (GET_CODE (XEXP (x
, 0)) == MULT
)
25700 /* FNMA accounted in outer NEG. */
25701 if (outer_code
== NEG
)
25702 *total
= rs6000_cost
->dmul
- rs6000_cost
->fp
;
25704 *total
= rs6000_cost
->dmul
;
25707 *total
= rs6000_cost
->fp
;
25709 else if (mode
== SFmode
)
25711 /* FNMA accounted in outer NEG. */
25712 if (outer_code
== NEG
&& GET_CODE (XEXP (x
, 0)) == MULT
)
25715 *total
= rs6000_cost
->fp
;
25718 *total
= COSTS_N_INSNS (1);
25722 if (mode
== DFmode
)
25724 if (GET_CODE (XEXP (x
, 0)) == MULT
25725 || GET_CODE (XEXP (x
, 1)) == MULT
)
25727 /* FNMA accounted in outer NEG. */
25728 if (outer_code
== NEG
)
25729 *total
= rs6000_cost
->dmul
- rs6000_cost
->fp
;
25731 *total
= rs6000_cost
->dmul
;
25734 *total
= rs6000_cost
->fp
;
25736 else if (mode
== SFmode
)
25738 /* FNMA accounted in outer NEG. */
25739 if (outer_code
== NEG
&& GET_CODE (XEXP (x
, 0)) == MULT
)
25742 *total
= rs6000_cost
->fp
;
25745 *total
= COSTS_N_INSNS (1);
25749 if (GET_CODE (XEXP (x
, 1)) == CONST_INT
25750 && satisfies_constraint_I (XEXP (x
, 1)))
25752 if (INTVAL (XEXP (x
, 1)) >= -256
25753 && INTVAL (XEXP (x
, 1)) <= 255)
25754 *total
= rs6000_cost
->mulsi_const9
;
25756 *total
= rs6000_cost
->mulsi_const
;
25758 /* FMA accounted in outer PLUS/MINUS. */
25759 else if ((mode
== DFmode
|| mode
== SFmode
)
25760 && (outer_code
== PLUS
|| outer_code
== MINUS
))
25762 else if (mode
== DFmode
)
25763 *total
= rs6000_cost
->dmul
;
25764 else if (mode
== SFmode
)
25765 *total
= rs6000_cost
->fp
;
25766 else if (mode
== DImode
)
25767 *total
= rs6000_cost
->muldi
;
25769 *total
= rs6000_cost
->mulsi
;
25774 if (FLOAT_MODE_P (mode
))
25776 *total
= mode
== DFmode
? rs6000_cost
->ddiv
25777 : rs6000_cost
->sdiv
;
25784 if (GET_CODE (XEXP (x
, 1)) == CONST_INT
25785 && exact_log2 (INTVAL (XEXP (x
, 1))) >= 0)
25787 if (code
== DIV
|| code
== MOD
)
25789 *total
= COSTS_N_INSNS (2);
25792 *total
= COSTS_N_INSNS (1);
25796 if (GET_MODE (XEXP (x
, 1)) == DImode
)
25797 *total
= rs6000_cost
->divdi
;
25799 *total
= rs6000_cost
->divsi
;
25801 /* Add in shift and subtract for MOD. */
25802 if (code
== MOD
|| code
== UMOD
)
25803 *total
+= COSTS_N_INSNS (2);
25808 *total
= COSTS_N_INSNS (4);
25812 *total
= COSTS_N_INSNS (TARGET_POPCNTD
? 1 : 6);
25816 *total
= COSTS_N_INSNS (TARGET_CMPB
? 2 : 6);
25820 if (outer_code
== AND
|| outer_code
== IOR
|| outer_code
== XOR
)
25832 *total
= COSTS_N_INSNS (1);
25840 /* Handle mul_highpart. */
25841 if (outer_code
== TRUNCATE
25842 && GET_CODE (XEXP (x
, 0)) == MULT
)
25844 if (mode
== DImode
)
25845 *total
= rs6000_cost
->muldi
;
25847 *total
= rs6000_cost
->mulsi
;
25850 else if (outer_code
== AND
)
25853 *total
= COSTS_N_INSNS (1);
25858 if (GET_CODE (XEXP (x
, 0)) == MEM
)
25861 *total
= COSTS_N_INSNS (1);
25867 if (!FLOAT_MODE_P (mode
))
25869 *total
= COSTS_N_INSNS (1);
25875 case UNSIGNED_FLOAT
:
25878 case FLOAT_TRUNCATE
:
25879 *total
= rs6000_cost
->fp
;
25883 if (mode
== DFmode
)
25886 *total
= rs6000_cost
->fp
;
25890 switch (XINT (x
, 1))
25893 *total
= rs6000_cost
->fp
;
25905 *total
= COSTS_N_INSNS (1);
25908 else if (FLOAT_MODE_P (mode
)
25909 && TARGET_PPC_GFXOPT
&& TARGET_HARD_FLOAT
&& TARGET_FPRS
)
25911 *total
= rs6000_cost
->fp
;
25919 /* Carry bit requires mode == Pmode.
25920 NEG or PLUS already counted so only add one. */
25922 && (outer_code
== NEG
|| outer_code
== PLUS
))
25924 *total
= COSTS_N_INSNS (1);
25927 if (outer_code
== SET
)
25929 if (XEXP (x
, 1) == const0_rtx
)
25931 if (TARGET_ISEL
&& !TARGET_MFCRF
)
25932 *total
= COSTS_N_INSNS (8);
25934 *total
= COSTS_N_INSNS (2);
25937 else if (mode
== Pmode
)
25939 *total
= COSTS_N_INSNS (3);
25948 if (outer_code
== SET
&& (XEXP (x
, 1) == const0_rtx
))
25950 if (TARGET_ISEL
&& !TARGET_MFCRF
)
25951 *total
= COSTS_N_INSNS (8);
25953 *total
= COSTS_N_INSNS (2);
25957 if (outer_code
== COMPARE
)
25971 /* Debug form of r6000_rtx_costs that is selected if -mdebug=cost. */
25974 rs6000_debug_rtx_costs (rtx x
, int code
, int outer_code
, int *total
,
25977 bool ret
= rs6000_rtx_costs (x
, code
, outer_code
, total
, speed
);
25980 "\nrs6000_rtx_costs, return = %s, code = %s, outer_code = %s, "
25981 "total = %d, speed = %s, x:\n",
25982 ret
? "complete" : "scan inner",
25983 GET_RTX_NAME (code
),
25984 GET_RTX_NAME (outer_code
),
25986 speed
? "true" : "false");
25993 /* Debug form of ADDRESS_COST that is selected if -mdebug=cost. */
25996 rs6000_debug_address_cost (rtx x
, bool speed
)
25998 int ret
= TARGET_ADDRESS_COST (x
, speed
);
26000 fprintf (stderr
, "\nrs6000_address_cost, return = %d, speed = %s, x:\n",
26001 ret
, speed
? "true" : "false");
26008 /* A C expression returning the cost of moving data from a register of class
26009 CLASS1 to one of CLASS2. */
26012 rs6000_register_move_cost (enum machine_mode mode
,
26013 reg_class_t from
, reg_class_t to
)
26017 /* Moves from/to GENERAL_REGS. */
26018 if (reg_classes_intersect_p (to
, GENERAL_REGS
)
26019 || reg_classes_intersect_p (from
, GENERAL_REGS
))
26021 if (! reg_classes_intersect_p (to
, GENERAL_REGS
))
26024 if (from
== FLOAT_REGS
|| from
== ALTIVEC_REGS
|| from
== VSX_REGS
)
26025 ret
= (rs6000_memory_move_cost (mode
, from
, false)
26026 + rs6000_memory_move_cost (mode
, GENERAL_REGS
, false));
26028 /* It's more expensive to move CR_REGS than CR0_REGS because of the
26030 else if (from
== CR_REGS
)
26033 /* Power6 has slower LR/CTR moves so make them more expensive than
26034 memory in order to bias spills to memory .*/
26035 else if (rs6000_cpu
== PROCESSOR_POWER6
26036 && reg_classes_intersect_p (from
, LINK_OR_CTR_REGS
))
26037 ret
= 6 * hard_regno_nregs
[0][mode
];
26040 /* A move will cost one instruction per GPR moved. */
26041 ret
= 2 * hard_regno_nregs
[0][mode
];
26044 /* If we have VSX, we can easily move between FPR or Altivec registers. */
26045 else if (VECTOR_UNIT_VSX_P (mode
)
26046 && reg_classes_intersect_p (to
, VSX_REGS
)
26047 && reg_classes_intersect_p (from
, VSX_REGS
))
26048 ret
= 2 * hard_regno_nregs
[32][mode
];
26050 /* Moving between two similar registers is just one instruction. */
26051 else if (reg_classes_intersect_p (to
, from
))
26052 ret
= (mode
== TFmode
|| mode
== TDmode
) ? 4 : 2;
26054 /* Everything else has to go through GENERAL_REGS. */
26056 ret
= (rs6000_register_move_cost (mode
, GENERAL_REGS
, to
)
26057 + rs6000_register_move_cost (mode
, from
, GENERAL_REGS
));
26059 if (TARGET_DEBUG_COST
)
26061 "rs6000_register_move_cost:, ret=%d, mode=%s, from=%s, to=%s\n",
26062 ret
, GET_MODE_NAME (mode
), reg_class_names
[from
],
26063 reg_class_names
[to
]);
26068 /* A C expressions returning the cost of moving data of MODE from a register to
26072 rs6000_memory_move_cost (enum machine_mode mode
, reg_class_t rclass
,
26073 bool in ATTRIBUTE_UNUSED
)
26077 if (reg_classes_intersect_p (rclass
, GENERAL_REGS
))
26078 ret
= 4 * hard_regno_nregs
[0][mode
];
26079 else if (reg_classes_intersect_p (rclass
, FLOAT_REGS
))
26080 ret
= 4 * hard_regno_nregs
[32][mode
];
26081 else if (reg_classes_intersect_p (rclass
, ALTIVEC_REGS
))
26082 ret
= 4 * hard_regno_nregs
[FIRST_ALTIVEC_REGNO
][mode
];
26084 ret
= 4 + rs6000_register_move_cost (mode
, rclass
, GENERAL_REGS
);
26086 if (TARGET_DEBUG_COST
)
26088 "rs6000_memory_move_cost: ret=%d, mode=%s, rclass=%s, in=%d\n",
26089 ret
, GET_MODE_NAME (mode
), reg_class_names
[rclass
], in
);
26094 /* Returns a code for a target-specific builtin that implements
26095 reciprocal of the function, or NULL_TREE if not available. */
26098 rs6000_builtin_reciprocal (unsigned int fn
, bool md_fn
,
26099 bool sqrt ATTRIBUTE_UNUSED
)
26101 if (optimize_insn_for_size_p ())
26107 case VSX_BUILTIN_XVSQRTDP
:
26108 if (!RS6000_RECIP_AUTO_RSQRTE_P (V2DFmode
))
26111 return rs6000_builtin_decls
[VSX_BUILTIN_VEC_RSQRT_V2DF
];
26113 case VSX_BUILTIN_XVSQRTSP
:
26114 if (!RS6000_RECIP_AUTO_RSQRTE_P (V4SFmode
))
26117 return rs6000_builtin_decls
[VSX_BUILTIN_VEC_RSQRT_V4SF
];
26126 case BUILT_IN_SQRT
:
26127 if (!RS6000_RECIP_AUTO_RSQRTE_P (DFmode
))
26130 return rs6000_builtin_decls
[RS6000_BUILTIN_RSQRT
];
26132 case BUILT_IN_SQRTF
:
26133 if (!RS6000_RECIP_AUTO_RSQRTE_P (SFmode
))
26136 return rs6000_builtin_decls
[RS6000_BUILTIN_RSQRTF
];
26143 /* Load up a constant. If the mode is a vector mode, splat the value across
26144 all of the vector elements. */
26147 rs6000_load_constant_and_splat (enum machine_mode mode
, REAL_VALUE_TYPE dconst
)
26151 if (mode
== SFmode
|| mode
== DFmode
)
26153 rtx d
= CONST_DOUBLE_FROM_REAL_VALUE (dconst
, mode
);
26154 reg
= force_reg (mode
, d
);
26156 else if (mode
== V4SFmode
)
26158 rtx d
= CONST_DOUBLE_FROM_REAL_VALUE (dconst
, SFmode
);
26159 rtvec v
= gen_rtvec (4, d
, d
, d
, d
);
26160 reg
= gen_reg_rtx (mode
);
26161 rs6000_expand_vector_init (reg
, gen_rtx_PARALLEL (mode
, v
));
26163 else if (mode
== V2DFmode
)
26165 rtx d
= CONST_DOUBLE_FROM_REAL_VALUE (dconst
, DFmode
);
26166 rtvec v
= gen_rtvec (2, d
, d
);
26167 reg
= gen_reg_rtx (mode
);
26168 rs6000_expand_vector_init (reg
, gen_rtx_PARALLEL (mode
, v
));
26171 gcc_unreachable ();
26176 /* Generate a FMADD instruction:
26177 dst = (m1 * m2) + a
26179 generating different RTL based on the fused multiply/add switch. */
26182 rs6000_emit_madd (rtx dst
, rtx m1
, rtx m2
, rtx a
)
26184 enum machine_mode mode
= GET_MODE (dst
);
26186 if (!TARGET_FUSED_MADD
)
26188 /* For the simple ops, use the generator function, rather than assuming
26189 that the RTL is standard. */
26190 enum insn_code mcode
= optab_handler (smul_optab
, mode
);
26191 enum insn_code acode
= optab_handler (add_optab
, mode
);
26192 gen_2arg_fn_t gen_mul
= (gen_2arg_fn_t
) GEN_FCN (mcode
);
26193 gen_2arg_fn_t gen_add
= (gen_2arg_fn_t
) GEN_FCN (acode
);
26194 rtx mreg
= gen_reg_rtx (mode
);
26196 gcc_assert (mcode
!= CODE_FOR_nothing
&& acode
!= CODE_FOR_nothing
);
26197 emit_insn (gen_mul (mreg
, m1
, m2
));
26198 emit_insn (gen_add (dst
, mreg
, a
));
26202 emit_insn (gen_rtx_SET (VOIDmode
, dst
,
26203 gen_rtx_PLUS (mode
,
26204 gen_rtx_MULT (mode
, m1
, m2
),
26208 /* Generate a FMSUB instruction:
26209 dst = (m1 * m2) - a
26211 generating different RTL based on the fused multiply/add switch. */
26214 rs6000_emit_msub (rtx dst
, rtx m1
, rtx m2
, rtx a
)
26216 enum machine_mode mode
= GET_MODE (dst
);
26218 if (!TARGET_FUSED_MADD
26219 || (mode
== V4SFmode
&& VECTOR_UNIT_ALTIVEC_P (V4SFmode
)))
26221 /* For the simple ops, use the generator function, rather than assuming
26222 that the RTL is standard. */
26223 enum insn_code mcode
= optab_handler (smul_optab
, mode
);
26224 enum insn_code scode
= optab_handler (add_optab
, mode
);
26225 gen_2arg_fn_t gen_mul
= (gen_2arg_fn_t
) GEN_FCN (mcode
);
26226 gen_2arg_fn_t gen_sub
= (gen_2arg_fn_t
) GEN_FCN (scode
);
26227 rtx mreg
= gen_reg_rtx (mode
);
26229 gcc_assert (mcode
!= CODE_FOR_nothing
&& scode
!= CODE_FOR_nothing
);
26230 emit_insn (gen_mul (mreg
, m1
, m2
));
26231 emit_insn (gen_sub (dst
, mreg
, a
));
26235 emit_insn (gen_rtx_SET (VOIDmode
, dst
,
26236 gen_rtx_MINUS (mode
,
26237 gen_rtx_MULT (mode
, m1
, m2
),
26241 /* Generate a FNMSUB instruction:
26242 dst = - ((m1 * m2) - a)
26244 Which is equivalent to (except in the prescence of -0.0):
26245 dst = a - (m1 * m2)
26247 generating different RTL based on the fast-math and fused multiply/add
26251 rs6000_emit_nmsub (rtx dst
, rtx m1
, rtx m2
, rtx a
)
26253 enum machine_mode mode
= GET_MODE (dst
);
26255 if (!TARGET_FUSED_MADD
)
26257 /* For the simple ops, use the generator function, rather than assuming
26258 that the RTL is standard. */
26259 enum insn_code mcode
= optab_handler (smul_optab
, mode
);
26260 enum insn_code scode
= optab_handler (sub_optab
, mode
);
26261 gen_2arg_fn_t gen_mul
= (gen_2arg_fn_t
) GEN_FCN (mcode
);
26262 gen_2arg_fn_t gen_sub
= (gen_2arg_fn_t
) GEN_FCN (scode
);
26263 rtx mreg
= gen_reg_rtx (mode
);
26265 gcc_assert (mcode
!= CODE_FOR_nothing
&& scode
!= CODE_FOR_nothing
);
26266 emit_insn (gen_mul (mreg
, m1
, m2
));
26267 emit_insn (gen_sub (dst
, a
, mreg
));
26272 rtx m
= gen_rtx_MULT (mode
, m1
, m2
);
26274 if (!HONOR_SIGNED_ZEROS (mode
))
26275 emit_insn (gen_rtx_SET (VOIDmode
, dst
, gen_rtx_MINUS (mode
, a
, m
)));
26278 emit_insn (gen_rtx_SET (VOIDmode
, dst
,
26280 gen_rtx_MINUS (mode
, m
, a
))));
26284 /* Newton-Raphson approximation of floating point divide with just 2 passes
26285 (either single precision floating point, or newer machines with higher
26286 accuracy estimates). Support both scalar and vector divide. Assumes no
26287 trapping math and finite arguments. */
26290 rs6000_emit_swdiv_high_precision (rtx dst
, rtx n
, rtx d
)
26292 enum machine_mode mode
= GET_MODE (dst
);
26293 rtx x0
, e0
, e1
, y1
, u0
, v0
;
26294 enum insn_code code
= optab_handler (smul_optab
, mode
);
26295 gen_2arg_fn_t gen_mul
= (gen_2arg_fn_t
) GEN_FCN (code
);
26296 rtx one
= rs6000_load_constant_and_splat (mode
, dconst1
);
26298 gcc_assert (code
!= CODE_FOR_nothing
);
26300 /* x0 = 1./d estimate */
26301 x0
= gen_reg_rtx (mode
);
26302 emit_insn (gen_rtx_SET (VOIDmode
, x0
,
26303 gen_rtx_UNSPEC (mode
, gen_rtvec (1, d
),
26306 e0
= gen_reg_rtx (mode
);
26307 rs6000_emit_nmsub (e0
, d
, x0
, one
); /* e0 = 1. - (d * x0) */
26309 e1
= gen_reg_rtx (mode
);
26310 rs6000_emit_madd (e1
, e0
, e0
, e0
); /* e1 = (e0 * e0) + e0 */
26312 y1
= gen_reg_rtx (mode
);
26313 rs6000_emit_madd (y1
, e1
, x0
, x0
); /* y1 = (e1 * x0) + x0 */
26315 u0
= gen_reg_rtx (mode
);
26316 emit_insn (gen_mul (u0
, n
, y1
)); /* u0 = n * y1 */
26318 v0
= gen_reg_rtx (mode
);
26319 rs6000_emit_nmsub (v0
, d
, u0
, n
); /* v0 = n - (d * u0) */
26321 rs6000_emit_madd (dst
, v0
, y1
, u0
); /* dst = (v0 * y1) + u0 */
26324 /* Newton-Raphson approximation of floating point divide that has a low
26325 precision estimate. Assumes no trapping math and finite arguments. */
26328 rs6000_emit_swdiv_low_precision (rtx dst
, rtx n
, rtx d
)
26330 enum machine_mode mode
= GET_MODE (dst
);
26331 rtx x0
, e0
, e1
, e2
, y1
, y2
, y3
, u0
, v0
, one
;
26332 enum insn_code code
= optab_handler (smul_optab
, mode
);
26333 gen_2arg_fn_t gen_mul
= (gen_2arg_fn_t
) GEN_FCN (code
);
26335 gcc_assert (code
!= CODE_FOR_nothing
);
26337 one
= rs6000_load_constant_and_splat (mode
, dconst1
);
26339 /* x0 = 1./d estimate */
26340 x0
= gen_reg_rtx (mode
);
26341 emit_insn (gen_rtx_SET (VOIDmode
, x0
,
26342 gen_rtx_UNSPEC (mode
, gen_rtvec (1, d
),
26345 e0
= gen_reg_rtx (mode
);
26346 rs6000_emit_nmsub (e0
, d
, x0
, one
); /* e0 = 1. - d * x0 */
26348 y1
= gen_reg_rtx (mode
);
26349 rs6000_emit_madd (y1
, e0
, x0
, x0
); /* y1 = x0 + e0 * x0 */
26351 e1
= gen_reg_rtx (mode
);
26352 emit_insn (gen_mul (e1
, e0
, e0
)); /* e1 = e0 * e0 */
26354 y2
= gen_reg_rtx (mode
);
26355 rs6000_emit_madd (y2
, e1
, y1
, y1
); /* y2 = y1 + e1 * y1 */
26357 e2
= gen_reg_rtx (mode
);
26358 emit_insn (gen_mul (e2
, e1
, e1
)); /* e2 = e1 * e1 */
26360 y3
= gen_reg_rtx (mode
);
26361 rs6000_emit_madd (y3
, e2
, y2
, y2
); /* y3 = y2 + e2 * y2 */
26363 u0
= gen_reg_rtx (mode
);
26364 emit_insn (gen_mul (u0
, n
, y3
)); /* u0 = n * y3 */
26366 v0
= gen_reg_rtx (mode
);
26367 rs6000_emit_nmsub (v0
, d
, u0
, n
); /* v0 = n - d * u0 */
26369 rs6000_emit_madd (dst
, v0
, y3
, u0
); /* dst = u0 + v0 * y3 */
26372 /* Newton-Raphson approximation of floating point divide DST = N/D. If NOTE_P,
26373 add a reg_note saying that this was a division. Support both scalar and
26374 vector divide. Assumes no trapping math and finite arguments. */
26377 rs6000_emit_swdiv (rtx dst
, rtx n
, rtx d
, bool note_p
)
26379 enum machine_mode mode
= GET_MODE (dst
);
26381 if (RS6000_RECIP_HIGH_PRECISION_P (mode
))
26382 rs6000_emit_swdiv_high_precision (dst
, n
, d
);
26384 rs6000_emit_swdiv_low_precision (dst
, n
, d
);
26387 add_reg_note (get_last_insn (), REG_EQUAL
, gen_rtx_DIV (mode
, n
, d
));
26390 /* Newton-Raphson approximation of single/double-precision floating point
26391 rsqrt. Assumes no trapping math and finite arguments. */
26394 rs6000_emit_swrsqrt (rtx dst
, rtx src
)
26396 enum machine_mode mode
= GET_MODE (src
);
26397 rtx x0
= gen_reg_rtx (mode
);
26398 rtx y
= gen_reg_rtx (mode
);
26399 int passes
= (TARGET_RECIP_PRECISION
) ? 2 : 3;
26400 REAL_VALUE_TYPE dconst3_2
;
26403 enum insn_code code
= optab_handler (smul_optab
, mode
);
26404 gen_2arg_fn_t gen_mul
= (gen_2arg_fn_t
) GEN_FCN (code
);
26406 gcc_assert (code
!= CODE_FOR_nothing
);
26408 /* Load up the constant 1.5 either as a scalar, or as a vector. */
26409 real_from_integer (&dconst3_2
, VOIDmode
, 3, 0, 0);
26410 SET_REAL_EXP (&dconst3_2
, REAL_EXP (&dconst3_2
) - 1);
26412 halfthree
= rs6000_load_constant_and_splat (mode
, dconst3_2
);
26414 /* x0 = rsqrt estimate */
26415 emit_insn (gen_rtx_SET (VOIDmode
, x0
,
26416 gen_rtx_UNSPEC (mode
, gen_rtvec (1, src
),
26419 /* y = 0.5 * src = 1.5 * src - src -> fewer constants */
26420 rs6000_emit_msub (y
, src
, halfthree
, src
);
26422 for (i
= 0; i
< passes
; i
++)
26424 rtx x1
= gen_reg_rtx (mode
);
26425 rtx u
= gen_reg_rtx (mode
);
26426 rtx v
= gen_reg_rtx (mode
);
26428 /* x1 = x0 * (1.5 - y * (x0 * x0)) */
26429 emit_insn (gen_mul (u
, x0
, x0
));
26430 rs6000_emit_nmsub (v
, y
, u
, halfthree
);
26431 emit_insn (gen_mul (x1
, x0
, v
));
26435 emit_move_insn (dst
, x0
);
26439 /* Emit popcount intrinsic on TARGET_POPCNTB (Power5) and TARGET_POPCNTD
26440 (Power7) targets. DST is the target, and SRC is the argument operand. */
26443 rs6000_emit_popcount (rtx dst
, rtx src
)
26445 enum machine_mode mode
= GET_MODE (dst
);
26448 /* Use the PPC ISA 2.06 popcnt{w,d} instruction if we can. */
26449 if (TARGET_POPCNTD
)
26451 if (mode
== SImode
)
26452 emit_insn (gen_popcntdsi2 (dst
, src
));
26454 emit_insn (gen_popcntddi2 (dst
, src
));
26458 tmp1
= gen_reg_rtx (mode
);
26460 if (mode
== SImode
)
26462 emit_insn (gen_popcntbsi2 (tmp1
, src
));
26463 tmp2
= expand_mult (SImode
, tmp1
, GEN_INT (0x01010101),
26465 tmp2
= force_reg (SImode
, tmp2
);
26466 emit_insn (gen_lshrsi3 (dst
, tmp2
, GEN_INT (24)));
26470 emit_insn (gen_popcntbdi2 (tmp1
, src
));
26471 tmp2
= expand_mult (DImode
, tmp1
,
26472 GEN_INT ((HOST_WIDE_INT
)
26473 0x01010101 << 32 | 0x01010101),
26475 tmp2
= force_reg (DImode
, tmp2
);
26476 emit_insn (gen_lshrdi3 (dst
, tmp2
, GEN_INT (56)));
26481 /* Emit parity intrinsic on TARGET_POPCNTB targets. DST is the
26482 target, and SRC is the argument operand. */
26485 rs6000_emit_parity (rtx dst
, rtx src
)
26487 enum machine_mode mode
= GET_MODE (dst
);
26490 tmp
= gen_reg_rtx (mode
);
26492 /* Use the PPC ISA 2.05 prtyw/prtyd instruction if we can. */
26495 if (mode
== SImode
)
26497 emit_insn (gen_popcntbsi2 (tmp
, src
));
26498 emit_insn (gen_paritysi2_cmpb (dst
, tmp
));
26502 emit_insn (gen_popcntbdi2 (tmp
, src
));
26503 emit_insn (gen_paritydi2_cmpb (dst
, tmp
));
26508 if (mode
== SImode
)
26510 /* Is mult+shift >= shift+xor+shift+xor? */
26511 if (rs6000_cost
->mulsi_const
>= COSTS_N_INSNS (3))
26513 rtx tmp1
, tmp2
, tmp3
, tmp4
;
26515 tmp1
= gen_reg_rtx (SImode
);
26516 emit_insn (gen_popcntbsi2 (tmp1
, src
));
26518 tmp2
= gen_reg_rtx (SImode
);
26519 emit_insn (gen_lshrsi3 (tmp2
, tmp1
, GEN_INT (16)));
26520 tmp3
= gen_reg_rtx (SImode
);
26521 emit_insn (gen_xorsi3 (tmp3
, tmp1
, tmp2
));
26523 tmp4
= gen_reg_rtx (SImode
);
26524 emit_insn (gen_lshrsi3 (tmp4
, tmp3
, GEN_INT (8)));
26525 emit_insn (gen_xorsi3 (tmp
, tmp3
, tmp4
));
26528 rs6000_emit_popcount (tmp
, src
);
26529 emit_insn (gen_andsi3 (dst
, tmp
, const1_rtx
));
26533 /* Is mult+shift >= shift+xor+shift+xor+shift+xor? */
26534 if (rs6000_cost
->muldi
>= COSTS_N_INSNS (5))
26536 rtx tmp1
, tmp2
, tmp3
, tmp4
, tmp5
, tmp6
;
26538 tmp1
= gen_reg_rtx (DImode
);
26539 emit_insn (gen_popcntbdi2 (tmp1
, src
));
26541 tmp2
= gen_reg_rtx (DImode
);
26542 emit_insn (gen_lshrdi3 (tmp2
, tmp1
, GEN_INT (32)));
26543 tmp3
= gen_reg_rtx (DImode
);
26544 emit_insn (gen_xordi3 (tmp3
, tmp1
, tmp2
));
26546 tmp4
= gen_reg_rtx (DImode
);
26547 emit_insn (gen_lshrdi3 (tmp4
, tmp3
, GEN_INT (16)));
26548 tmp5
= gen_reg_rtx (DImode
);
26549 emit_insn (gen_xordi3 (tmp5
, tmp3
, tmp4
));
26551 tmp6
= gen_reg_rtx (DImode
);
26552 emit_insn (gen_lshrdi3 (tmp6
, tmp5
, GEN_INT (8)));
26553 emit_insn (gen_xordi3 (tmp
, tmp5
, tmp6
));
26556 rs6000_emit_popcount (tmp
, src
);
26557 emit_insn (gen_anddi3 (dst
, tmp
, const1_rtx
));
26561 /* Return an RTX representing where to find the function value of a
26562 function returning MODE. */
26564 rs6000_complex_function_value (enum machine_mode mode
)
26566 unsigned int regno
;
26568 enum machine_mode inner
= GET_MODE_INNER (mode
);
26569 unsigned int inner_bytes
= GET_MODE_SIZE (inner
);
26571 if (FLOAT_MODE_P (mode
) && TARGET_HARD_FLOAT
&& TARGET_FPRS
)
26572 regno
= FP_ARG_RETURN
;
26575 regno
= GP_ARG_RETURN
;
26577 /* 32-bit is OK since it'll go in r3/r4. */
26578 if (TARGET_32BIT
&& inner_bytes
>= 4)
26579 return gen_rtx_REG (mode
, regno
);
26582 if (inner_bytes
>= 8)
26583 return gen_rtx_REG (mode
, regno
);
26585 r1
= gen_rtx_EXPR_LIST (inner
, gen_rtx_REG (inner
, regno
),
26587 r2
= gen_rtx_EXPR_LIST (inner
, gen_rtx_REG (inner
, regno
+ 1),
26588 GEN_INT (inner_bytes
));
26589 return gen_rtx_PARALLEL (mode
, gen_rtvec (2, r1
, r2
));
26592 /* Target hook for TARGET_FUNCTION_VALUE.
26594 On the SPE, both FPs and vectors are returned in r3.
26596 On RS/6000 an integer value is in r3 and a floating-point value is in
26597 fp1, unless -msoft-float. */
26600 rs6000_function_value (const_tree valtype
,
26601 const_tree fn_decl_or_type ATTRIBUTE_UNUSED
,
26602 bool outgoing ATTRIBUTE_UNUSED
)
26604 enum machine_mode mode
;
26605 unsigned int regno
;
26607 /* Special handling for structs in darwin64. */
26609 && rs6000_darwin64_struct_check_p (TYPE_MODE (valtype
), valtype
))
26611 CUMULATIVE_ARGS valcum
;
26615 valcum
.fregno
= FP_ARG_MIN_REG
;
26616 valcum
.vregno
= ALTIVEC_ARG_MIN_REG
;
26617 /* Do a trial code generation as if this were going to be passed as
26618 an argument; if any part goes in memory, we return NULL. */
26619 valret
= rs6000_darwin64_record_arg (&valcum
, valtype
, true, true);
26622 /* Otherwise fall through to standard ABI rules. */
26625 if (TARGET_32BIT
&& TARGET_POWERPC64
&& TYPE_MODE (valtype
) == DImode
)
26627 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
26628 return gen_rtx_PARALLEL (DImode
,
26630 gen_rtx_EXPR_LIST (VOIDmode
,
26631 gen_rtx_REG (SImode
, GP_ARG_RETURN
),
26633 gen_rtx_EXPR_LIST (VOIDmode
,
26634 gen_rtx_REG (SImode
,
26635 GP_ARG_RETURN
+ 1),
26638 if (TARGET_32BIT
&& TARGET_POWERPC64
&& TYPE_MODE (valtype
) == DCmode
)
26640 return gen_rtx_PARALLEL (DCmode
,
26642 gen_rtx_EXPR_LIST (VOIDmode
,
26643 gen_rtx_REG (SImode
, GP_ARG_RETURN
),
26645 gen_rtx_EXPR_LIST (VOIDmode
,
26646 gen_rtx_REG (SImode
,
26647 GP_ARG_RETURN
+ 1),
26649 gen_rtx_EXPR_LIST (VOIDmode
,
26650 gen_rtx_REG (SImode
,
26651 GP_ARG_RETURN
+ 2),
26653 gen_rtx_EXPR_LIST (VOIDmode
,
26654 gen_rtx_REG (SImode
,
26655 GP_ARG_RETURN
+ 3),
26659 mode
= TYPE_MODE (valtype
);
26660 if ((INTEGRAL_TYPE_P (valtype
) && GET_MODE_BITSIZE (mode
) < BITS_PER_WORD
)
26661 || POINTER_TYPE_P (valtype
))
26662 mode
= TARGET_32BIT
? SImode
: DImode
;
26664 if (DECIMAL_FLOAT_MODE_P (mode
) && TARGET_HARD_FLOAT
&& TARGET_FPRS
)
26665 /* _Decimal128 must use an even/odd register pair. */
26666 regno
= (mode
== TDmode
) ? FP_ARG_RETURN
+ 1 : FP_ARG_RETURN
;
26667 else if (SCALAR_FLOAT_TYPE_P (valtype
) && TARGET_HARD_FLOAT
&& TARGET_FPRS
26668 && ((TARGET_SINGLE_FLOAT
&& (mode
== SFmode
)) || TARGET_DOUBLE_FLOAT
))
26669 regno
= FP_ARG_RETURN
;
26670 else if (TREE_CODE (valtype
) == COMPLEX_TYPE
26671 && targetm
.calls
.split_complex_arg
)
26672 return rs6000_complex_function_value (mode
);
26673 else if (TREE_CODE (valtype
) == VECTOR_TYPE
26674 && TARGET_ALTIVEC
&& TARGET_ALTIVEC_ABI
26675 && ALTIVEC_VECTOR_MODE (mode
))
26676 regno
= ALTIVEC_ARG_RETURN
;
26677 else if (TREE_CODE (valtype
) == VECTOR_TYPE
26678 && TARGET_VSX
&& TARGET_ALTIVEC_ABI
26679 && VSX_VECTOR_MODE (mode
))
26680 regno
= ALTIVEC_ARG_RETURN
;
26681 else if (TARGET_E500_DOUBLE
&& TARGET_HARD_FLOAT
26682 && (mode
== DFmode
|| mode
== DCmode
26683 || mode
== TFmode
|| mode
== TCmode
))
26684 return spe_build_register_parallel (mode
, GP_ARG_RETURN
);
26686 regno
= GP_ARG_RETURN
;
26688 return gen_rtx_REG (mode
, regno
);
26691 /* Define how to find the value returned by a library function
26692 assuming the value has mode MODE. */
26694 rs6000_libcall_value (enum machine_mode mode
)
26696 unsigned int regno
;
26698 if (TARGET_32BIT
&& TARGET_POWERPC64
&& mode
== DImode
)
26700 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
26701 return gen_rtx_PARALLEL (DImode
,
26703 gen_rtx_EXPR_LIST (VOIDmode
,
26704 gen_rtx_REG (SImode
, GP_ARG_RETURN
),
26706 gen_rtx_EXPR_LIST (VOIDmode
,
26707 gen_rtx_REG (SImode
,
26708 GP_ARG_RETURN
+ 1),
26712 if (DECIMAL_FLOAT_MODE_P (mode
) && TARGET_HARD_FLOAT
&& TARGET_FPRS
)
26713 /* _Decimal128 must use an even/odd register pair. */
26714 regno
= (mode
== TDmode
) ? FP_ARG_RETURN
+ 1 : FP_ARG_RETURN
;
26715 else if (SCALAR_FLOAT_MODE_P (mode
)
26716 && TARGET_HARD_FLOAT
&& TARGET_FPRS
26717 && ((TARGET_SINGLE_FLOAT
&& mode
== SFmode
) || TARGET_DOUBLE_FLOAT
))
26718 regno
= FP_ARG_RETURN
;
26719 else if (ALTIVEC_VECTOR_MODE (mode
)
26720 && TARGET_ALTIVEC
&& TARGET_ALTIVEC_ABI
)
26721 regno
= ALTIVEC_ARG_RETURN
;
26722 else if (VSX_VECTOR_MODE (mode
)
26723 && TARGET_VSX
&& TARGET_ALTIVEC_ABI
)
26724 regno
= ALTIVEC_ARG_RETURN
;
26725 else if (COMPLEX_MODE_P (mode
) && targetm
.calls
.split_complex_arg
)
26726 return rs6000_complex_function_value (mode
);
26727 else if (TARGET_E500_DOUBLE
&& TARGET_HARD_FLOAT
26728 && (mode
== DFmode
|| mode
== DCmode
26729 || mode
== TFmode
|| mode
== TCmode
))
26730 return spe_build_register_parallel (mode
, GP_ARG_RETURN
);
26732 regno
= GP_ARG_RETURN
;
26734 return gen_rtx_REG (mode
, regno
);
26738 /* Given FROM and TO register numbers, say whether this elimination is allowed.
26739 Frame pointer elimination is automatically handled.
26741 For the RS/6000, if frame pointer elimination is being done, we would like
26742 to convert ap into fp, not sp.
26744 We need r30 if -mminimal-toc was specified, and there are constant pool
26748 rs6000_can_eliminate (const int from
, const int to
)
26750 return (from
== ARG_POINTER_REGNUM
&& to
== STACK_POINTER_REGNUM
26751 ? ! frame_pointer_needed
26752 : from
== RS6000_PIC_OFFSET_TABLE_REGNUM
26753 ? ! TARGET_MINIMAL_TOC
|| TARGET_NO_TOC
|| get_pool_size () == 0
26757 /* Define the offset between two registers, FROM to be eliminated and its
26758 replacement TO, at the start of a routine. */
26760 rs6000_initial_elimination_offset (int from
, int to
)
26762 rs6000_stack_t
*info
= rs6000_stack_info ();
26763 HOST_WIDE_INT offset
;
26765 if (from
== HARD_FRAME_POINTER_REGNUM
&& to
== STACK_POINTER_REGNUM
)
26766 offset
= info
->push_p
? 0 : -info
->total_size
;
26767 else if (from
== FRAME_POINTER_REGNUM
&& to
== STACK_POINTER_REGNUM
)
26769 offset
= info
->push_p
? 0 : -info
->total_size
;
26770 if (FRAME_GROWS_DOWNWARD
)
26771 offset
+= info
->fixed_size
+ info
->vars_size
+ info
->parm_size
;
26773 else if (from
== FRAME_POINTER_REGNUM
&& to
== HARD_FRAME_POINTER_REGNUM
)
26774 offset
= FRAME_GROWS_DOWNWARD
26775 ? info
->fixed_size
+ info
->vars_size
+ info
->parm_size
26777 else if (from
== ARG_POINTER_REGNUM
&& to
== HARD_FRAME_POINTER_REGNUM
)
26778 offset
= info
->total_size
;
26779 else if (from
== ARG_POINTER_REGNUM
&& to
== STACK_POINTER_REGNUM
)
26780 offset
= info
->push_p
? info
->total_size
: 0;
26781 else if (from
== RS6000_PIC_OFFSET_TABLE_REGNUM
)
26784 gcc_unreachable ();
26790 rs6000_dwarf_register_span (rtx reg
)
26794 unsigned regno
= REGNO (reg
);
26795 enum machine_mode mode
= GET_MODE (reg
);
26799 && (SPE_VECTOR_MODE (GET_MODE (reg
))
26800 || (TARGET_E500_DOUBLE
&& FLOAT_MODE_P (mode
)
26801 && mode
!= SFmode
&& mode
!= SDmode
&& mode
!= SCmode
)))
26806 regno
= REGNO (reg
);
26808 /* The duality of the SPE register size wreaks all kinds of havoc.
26809 This is a way of distinguishing r0 in 32-bits from r0 in
26811 words
= (GET_MODE_SIZE (mode
) + UNITS_PER_FP_WORD
- 1) / UNITS_PER_FP_WORD
;
26812 gcc_assert (words
<= 4);
26813 for (i
= 0; i
< words
; i
++, regno
++)
26815 if (BYTES_BIG_ENDIAN
)
26817 parts
[2 * i
] = gen_rtx_REG (SImode
, regno
+ 1200);
26818 parts
[2 * i
+ 1] = gen_rtx_REG (SImode
, regno
);
26822 parts
[2 * i
] = gen_rtx_REG (SImode
, regno
);
26823 parts
[2 * i
+ 1] = gen_rtx_REG (SImode
, regno
+ 1200);
26827 return gen_rtx_PARALLEL (VOIDmode
, gen_rtvec_v (words
* 2, parts
));
26830 /* Fill in sizes for SPE register high parts in table used by unwinder. */
26833 rs6000_init_dwarf_reg_sizes_extra (tree address
)
26838 enum machine_mode mode
= TYPE_MODE (char_type_node
);
26839 rtx addr
= expand_expr (address
, NULL_RTX
, VOIDmode
, EXPAND_NORMAL
);
26840 rtx mem
= gen_rtx_MEM (BLKmode
, addr
);
26841 rtx value
= gen_int_mode (4, mode
);
26843 for (i
= 1201; i
< 1232; i
++)
26845 int column
= DWARF_REG_TO_UNWIND_COLUMN (i
);
26846 HOST_WIDE_INT offset
26847 = DWARF_FRAME_REGNUM (column
) * GET_MODE_SIZE (mode
);
26849 emit_move_insn (adjust_address (mem
, mode
, offset
), value
);
26854 /* Map internal gcc register numbers to DWARF2 register numbers. */
26857 rs6000_dbx_register_number (unsigned int regno
)
26859 if (regno
<= 63 || write_symbols
!= DWARF2_DEBUG
)
26861 if (regno
== MQ_REGNO
)
26863 if (regno
== LR_REGNO
)
26865 if (regno
== CTR_REGNO
)
26867 if (CR_REGNO_P (regno
))
26868 return regno
- CR0_REGNO
+ 86;
26869 if (regno
== CA_REGNO
)
26870 return 101; /* XER */
26871 if (ALTIVEC_REGNO_P (regno
))
26872 return regno
- FIRST_ALTIVEC_REGNO
+ 1124;
26873 if (regno
== VRSAVE_REGNO
)
26875 if (regno
== VSCR_REGNO
)
26877 if (regno
== SPE_ACC_REGNO
)
26879 if (regno
== SPEFSCR_REGNO
)
26881 /* SPE high reg number. We get these values of regno from
26882 rs6000_dwarf_register_span. */
26883 gcc_assert (regno
>= 1200 && regno
< 1232);
26887 /* target hook eh_return_filter_mode */
26888 static enum machine_mode
26889 rs6000_eh_return_filter_mode (void)
26891 return TARGET_32BIT
? SImode
: word_mode
;
26894 /* Target hook for scalar_mode_supported_p. */
26896 rs6000_scalar_mode_supported_p (enum machine_mode mode
)
26898 if (DECIMAL_FLOAT_MODE_P (mode
))
26899 return default_decimal_float_supported_p ();
26901 return default_scalar_mode_supported_p (mode
);
26904 /* Target hook for vector_mode_supported_p. */
26906 rs6000_vector_mode_supported_p (enum machine_mode mode
)
26909 if (TARGET_PAIRED_FLOAT
&& PAIRED_VECTOR_MODE (mode
))
26912 if (TARGET_SPE
&& SPE_VECTOR_MODE (mode
))
26915 else if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode
))
26922 /* Target hook for invalid_arg_for_unprototyped_fn. */
26923 static const char *
26924 invalid_arg_for_unprototyped_fn (const_tree typelist
, const_tree funcdecl
, const_tree val
)
26926 return (!rs6000_darwin64_abi
26928 && TREE_CODE (TREE_TYPE (val
)) == VECTOR_TYPE
26929 && (funcdecl
== NULL_TREE
26930 || (TREE_CODE (funcdecl
) == FUNCTION_DECL
26931 && DECL_BUILT_IN_CLASS (funcdecl
) != BUILT_IN_MD
)))
26932 ? N_("AltiVec argument passed to unprototyped function")
26936 /* For TARGET_SECURE_PLT 32-bit PIC code we can save PIC register
26937 setup by using __stack_chk_fail_local hidden function instead of
26938 calling __stack_chk_fail directly. Otherwise it is better to call
26939 __stack_chk_fail directly. */
26942 rs6000_stack_protect_fail (void)
26944 return (DEFAULT_ABI
== ABI_V4
&& TARGET_SECURE_PLT
&& flag_pic
)
26945 ? default_hidden_stack_protect_fail ()
26946 : default_external_stack_protect_fail ();
26950 rs6000_final_prescan_insn (rtx insn
, rtx
*operand ATTRIBUTE_UNUSED
,
26951 int num_operands ATTRIBUTE_UNUSED
)
26953 if (rs6000_warn_cell_microcode
)
26956 int insn_code_number
= recog_memoized (insn
);
26957 location_t location
= locator_location (INSN_LOCATOR (insn
));
26959 /* Punt on insns we cannot recognize. */
26960 if (insn_code_number
< 0)
26963 temp
= get_insn_template (insn_code_number
, insn
);
26965 if (get_attr_cell_micro (insn
) == CELL_MICRO_ALWAYS
)
26966 warning_at (location
, OPT_mwarn_cell_microcode
,
26967 "emitting microcode insn %s\t[%s] #%d",
26968 temp
, insn_data
[INSN_CODE (insn
)].name
, INSN_UID (insn
));
26969 else if (get_attr_cell_micro (insn
) == CELL_MICRO_CONDITIONAL
)
26970 warning_at (location
, OPT_mwarn_cell_microcode
,
26971 "emitting conditional microcode insn %s\t[%s] #%d",
26972 temp
, insn_data
[INSN_CODE (insn
)].name
, INSN_UID (insn
));
26977 /* Allocate a stack temp and fixup the address so it meets the particular
26978 memory requirements (either offetable or REG+REG addressing). */
26981 rs6000_allocate_stack_temp (enum machine_mode mode
,
26982 bool offsettable_p
,
26985 rtx stack
= assign_stack_temp (mode
, GET_MODE_SIZE (mode
), 0);
26986 rtx addr
= XEXP (stack
, 0);
26987 int strict_p
= (reload_in_progress
|| reload_completed
);
26989 if (!legitimate_indirect_address_p (addr
, strict_p
))
26992 && !rs6000_legitimate_offset_address_p (mode
, addr
, strict_p
))
26993 stack
= replace_equiv_address (stack
, copy_addr_to_reg (addr
));
26995 else if (reg_reg_p
&& !legitimate_indexed_address_p (addr
, strict_p
))
26996 stack
= replace_equiv_address (stack
, copy_addr_to_reg (addr
));
27002 /* Given a memory reference, if it is not a reg or reg+reg addressing, convert
27003 to such a form to deal with memory reference instructions like STFIWX that
27004 only take reg+reg addressing. */
27007 rs6000_address_for_fpconvert (rtx x
)
27009 int strict_p
= (reload_in_progress
|| reload_completed
);
27012 gcc_assert (MEM_P (x
));
27013 addr
= XEXP (x
, 0);
27014 if (! legitimate_indirect_address_p (addr
, strict_p
)
27015 && ! legitimate_indexed_address_p (addr
, strict_p
))
27016 x
= replace_equiv_address (x
, copy_addr_to_reg (addr
));
27021 /* Expand 32-bit int -> floating point conversions. Return true if
27025 rs6000_expand_convert_si_to_sfdf (rtx dest
, rtx src
, bool unsigned_p
)
27027 enum machine_mode dmode
= GET_MODE (dest
);
27028 rtx (*func_si
) (rtx
, rtx
, rtx
, rtx
);
27029 rtx (*func_si_mem
) (rtx
, rtx
);
27030 rtx (*func_di
) (rtx
, rtx
);
27033 gcc_assert (GET_MODE (src
) == SImode
);
27035 if (dmode
== SFmode
)
27039 gcc_assert (TARGET_FCFIDUS
&& TARGET_LFIWZX
);
27040 func_si
= gen_floatunssisf2_lfiwzx
;
27041 func_si_mem
= gen_floatunssisf2_lfiwzx_mem
;
27042 func_di
= gen_floatunsdisf2
;
27046 gcc_assert (TARGET_FCFIDS
&& TARGET_LFIWAX
);
27047 func_si
= gen_floatsisf2_lfiwax
;
27048 func_si_mem
= gen_floatsisf2_lfiwax_mem
;
27049 func_di
= gen_floatdisf2
;
27053 else if (dmode
== DFmode
)
27057 gcc_assert (TARGET_FCFIDU
&& TARGET_LFIWZX
);
27058 func_si
= gen_floatunssidf2_lfiwzx
;
27059 func_si_mem
= gen_floatunssidf2_lfiwzx_mem
;
27060 func_di
= gen_floatunsdidf2
;
27064 gcc_assert (TARGET_FCFID
&& TARGET_LFIWAX
);
27065 func_si
= gen_floatsidf2_lfiwax
;
27066 func_si_mem
= gen_floatsidf2_lfiwax_mem
;
27067 func_di
= gen_floatdidf2
;
27072 gcc_unreachable ();
27076 src
= rs6000_address_for_fpconvert (src
);
27077 emit_insn (func_si_mem (dest
, src
));
27079 else if (!TARGET_MFPGPR
)
27081 reg
= gen_reg_rtx (DImode
);
27082 stack
= rs6000_allocate_stack_temp (SImode
, false, true);
27083 emit_insn (func_si (dest
, src
, stack
, reg
));
27088 src
= force_reg (SImode
, src
);
27089 reg
= convert_to_mode (DImode
, src
, unsigned_p
);
27090 emit_insn (func_di (dest
, reg
));
27094 #include "gt-rs6000.h"