Fix 40671, 41145
[official-gcc.git] / gcc / config / rs6000 / rs6000.c
blob95f8ab5aae20bdb69fd01367ba6fa232e09d640a
1 /* Subroutines used for code generation on IBM RS/6000.
2 Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
4 Free Software Foundation, Inc.
5 Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
7 This file is part of GCC.
9 GCC is free software; you can redistribute it and/or modify it
10 under the terms of the GNU General Public License as published
11 by the Free Software Foundation; either version 3, or (at your
12 option) any later version.
14 GCC is distributed in the hope that it will be useful, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
17 License for more details.
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING3. If not see
21 <http://www.gnu.org/licenses/>. */
23 #include "config.h"
24 #include "system.h"
25 #include "coretypes.h"
26 #include "tm.h"
27 #include "rtl.h"
28 #include "regs.h"
29 #include "hard-reg-set.h"
30 #include "real.h"
31 #include "insn-config.h"
32 #include "conditions.h"
33 #include "insn-attr.h"
34 #include "flags.h"
35 #include "recog.h"
36 #include "obstack.h"
37 #include "tree.h"
38 #include "expr.h"
39 #include "optabs.h"
40 #include "except.h"
41 #include "function.h"
42 #include "output.h"
43 #include "basic-block.h"
44 #include "integrate.h"
45 #include "toplev.h"
46 #include "ggc.h"
47 #include "hashtab.h"
48 #include "tm_p.h"
49 #include "target.h"
50 #include "target-def.h"
51 #include "langhooks.h"
52 #include "reload.h"
53 #include "cfglayout.h"
54 #include "sched-int.h"
55 #include "gimple.h"
56 #include "tree-flow.h"
57 #include "intl.h"
58 #include "params.h"
59 #include "tm-constrs.h"
60 #if TARGET_XCOFF
61 #include "xcoffout.h" /* get declarations of xcoff_*_section_name */
62 #endif
63 #if TARGET_MACHO
64 #include "gstab.h" /* for N_SLINE */
65 #endif
67 #ifndef TARGET_NO_PROTOTYPE
68 #define TARGET_NO_PROTOTYPE 0
69 #endif
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
107 not in save_size */
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;
112 } rs6000_stack_t;
114 /* A C structure for machine-specific, per-function data.
115 This is added to the cfun structure. */
116 typedef struct GTY(()) machine_function
118 /* Flags if __builtin_return_address (n) with n >= 1 was used. */
119 int ra_needs_full_frame;
120 /* Some local-dynamic symbol. */
121 const char *some_ld_name;
122 /* Whether the instruction chain has been scanned already. */
123 int insn_chain_scanned_p;
124 /* Flags if __builtin_return_address (0) was used. */
125 int ra_need_lr;
126 /* Offset from virtual_stack_vars_rtx to the start of the ABI_V4
127 varargs save area. */
128 HOST_WIDE_INT varargs_save_offset;
129 /* Temporary stack slot to use for SDmode copies. This slot is
130 64-bits wide and is allocated early enough so that the offset
131 does not overflow the 16-bit load/store offset field. */
132 rtx sdmode_stack_slot;
133 } machine_function;
135 /* Target cpu type */
137 enum processor_type rs6000_cpu;
138 struct rs6000_cpu_select rs6000_select[3] =
140 /* switch name, tune arch */
141 { (const char *)0, "--with-cpu=", 1, 1 },
142 { (const char *)0, "-mcpu=", 1, 1 },
143 { (const char *)0, "-mtune=", 1, 0 },
146 /* Always emit branch hint bits. */
147 static GTY(()) bool rs6000_always_hint;
149 /* Schedule instructions for group formation. */
150 static GTY(()) bool rs6000_sched_groups;
152 /* Align branch targets. */
153 static GTY(()) bool rs6000_align_branch_targets;
155 /* Support for -msched-costly-dep option. */
156 const char *rs6000_sched_costly_dep_str;
157 enum rs6000_dependence_cost rs6000_sched_costly_dep;
159 /* Support for -minsert-sched-nops option. */
160 const char *rs6000_sched_insert_nops_str;
161 enum rs6000_nop_insertion rs6000_sched_insert_nops;
163 /* Support targetm.vectorize.builtin_mask_for_load. */
164 static GTY(()) tree altivec_builtin_mask_for_load;
166 /* Size of long double. */
167 int rs6000_long_double_type_size;
169 /* IEEE quad extended precision long double. */
170 int rs6000_ieeequad;
172 /* Nonzero to use AltiVec ABI. */
173 int rs6000_altivec_abi;
175 /* Nonzero if we want SPE SIMD instructions. */
176 int rs6000_spe;
178 /* Nonzero if we want SPE ABI extensions. */
179 int rs6000_spe_abi;
181 /* Nonzero if floating point operations are done in the GPRs. */
182 int rs6000_float_gprs = 0;
184 /* Nonzero if we want Darwin's struct-by-value-in-regs ABI. */
185 int rs6000_darwin64_abi;
187 /* Set to nonzero once AIX common-mode calls have been defined. */
188 static GTY(()) int common_mode_defined;
190 /* Label number of label created for -mrelocatable, to call to so we can
191 get the address of the GOT section */
192 int rs6000_pic_labelno;
194 #ifdef USING_ELFOS_H
195 /* Which abi to adhere to */
196 const char *rs6000_abi_name;
198 /* Semantics of the small data area */
199 enum rs6000_sdata_type rs6000_sdata = SDATA_DATA;
201 /* Which small data model to use */
202 const char *rs6000_sdata_name = (char *)0;
204 /* Counter for labels which are to be placed in .fixup. */
205 int fixuplabelno = 0;
206 #endif
208 /* Bit size of immediate TLS offsets and string from which it is decoded. */
209 int rs6000_tls_size = 32;
210 const char *rs6000_tls_size_string;
212 /* ABI enumeration available for subtarget to use. */
213 enum rs6000_abi rs6000_current_abi;
215 /* Whether to use variant of AIX ABI for PowerPC64 Linux. */
216 int dot_symbols;
218 /* Debug flags */
219 const char *rs6000_debug_name;
220 int rs6000_debug_stack; /* debug stack applications */
221 int rs6000_debug_arg; /* debug argument handling */
222 int rs6000_debug_reg; /* debug register classes */
223 int rs6000_debug_addr; /* debug memory addressing */
224 int rs6000_debug_cost; /* debug rtx_costs */
226 /* Specify the machine mode that pointers have. After generation of rtl, the
227 compiler makes no further distinction between pointers and any other objects
228 of this machine mode. The type is unsigned since not all things that
229 include rs6000.h also include machmode.h. */
230 unsigned rs6000_pmode;
232 /* Width in bits of a pointer. */
233 unsigned rs6000_pointer_size;
236 /* Value is TRUE if register/mode pair is acceptable. */
237 bool rs6000_hard_regno_mode_ok_p[NUM_MACHINE_MODES][FIRST_PSEUDO_REGISTER];
239 /* Maximum number of registers needed for a given register class and mode. */
240 unsigned char rs6000_class_max_nregs[NUM_MACHINE_MODES][LIM_REG_CLASSES];
242 /* How many registers are needed for a given register and mode. */
243 unsigned char rs6000_hard_regno_nregs[NUM_MACHINE_MODES][FIRST_PSEUDO_REGISTER];
245 /* Map register number to register class. */
246 enum reg_class rs6000_regno_regclass[FIRST_PSEUDO_REGISTER];
248 /* Reload functions based on the type and the vector unit. */
249 static enum insn_code rs6000_vector_reload[NUM_MACHINE_MODES][2];
251 /* Built in types. */
252 tree rs6000_builtin_types[RS6000_BTI_MAX];
253 tree rs6000_builtin_decls[RS6000_BUILTIN_COUNT];
255 const char *rs6000_traceback_name;
256 static enum {
257 traceback_default = 0,
258 traceback_none,
259 traceback_part,
260 traceback_full
261 } rs6000_traceback;
263 /* Flag to say the TOC is initialized */
264 int toc_initialized;
265 char toc_label_name[10];
267 /* Cached value of rs6000_variable_issue. This is cached in
268 rs6000_variable_issue hook and returned from rs6000_sched_reorder2. */
269 static short cached_can_issue_more;
271 static GTY(()) section *read_only_data_section;
272 static GTY(()) section *private_data_section;
273 static GTY(()) section *read_only_private_data_section;
274 static GTY(()) section *sdata2_section;
275 static GTY(()) section *toc_section;
277 /* Control alignment for fields within structures. */
278 /* String from -malign-XXXXX. */
279 int rs6000_alignment_flags;
281 /* True for any options that were explicitly set. */
282 static struct {
283 bool aix_struct_ret; /* True if -maix-struct-ret was used. */
284 bool alignment; /* True if -malign- was used. */
285 bool spe_abi; /* True if -mabi=spe/no-spe was used. */
286 bool altivec_abi; /* True if -mabi=altivec/no-altivec used. */
287 bool spe; /* True if -mspe= was used. */
288 bool float_gprs; /* True if -mfloat-gprs= was used. */
289 bool long_double; /* True if -mlong-double- was used. */
290 bool ieee; /* True if -mabi=ieee/ibmlongdouble used. */
291 bool vrsave; /* True if -mvrsave was used. */
292 } rs6000_explicit_options;
294 struct builtin_description
296 /* mask is not const because we're going to alter it below. This
297 nonsense will go away when we rewrite the -march infrastructure
298 to give us more target flag bits. */
299 unsigned int mask;
300 const enum insn_code icode;
301 const char *const name;
302 const enum rs6000_builtins code;
305 /* Describe the vector unit used for modes. */
306 enum rs6000_vector rs6000_vector_unit[NUM_MACHINE_MODES];
307 enum rs6000_vector rs6000_vector_mem[NUM_MACHINE_MODES];
309 /* Register classes for various constraints that are based on the target
310 switches. */
311 enum reg_class rs6000_constraints[RS6000_CONSTRAINT_MAX];
313 /* Describe the alignment of a vector. */
314 int rs6000_vector_align[NUM_MACHINE_MODES];
316 /* Map selected modes to types for builtins. */
317 static GTY(()) tree builtin_mode_to_type[MAX_MACHINE_MODE][2];
319 /* Target cpu costs. */
321 struct processor_costs {
322 const int mulsi; /* cost of SImode multiplication. */
323 const int mulsi_const; /* cost of SImode multiplication by constant. */
324 const int mulsi_const9; /* cost of SImode mult by short constant. */
325 const int muldi; /* cost of DImode multiplication. */
326 const int divsi; /* cost of SImode division. */
327 const int divdi; /* cost of DImode division. */
328 const int fp; /* cost of simple SFmode and DFmode insns. */
329 const int dmul; /* cost of DFmode multiplication (and fmadd). */
330 const int sdiv; /* cost of SFmode division (fdivs). */
331 const int ddiv; /* cost of DFmode division (fdiv). */
332 const int cache_line_size; /* cache line size in bytes. */
333 const int l1_cache_size; /* size of l1 cache, in kilobytes. */
334 const int l2_cache_size; /* size of l2 cache, in kilobytes. */
335 const int simultaneous_prefetches; /* number of parallel prefetch
336 operations. */
339 const struct processor_costs *rs6000_cost;
341 /* Processor costs (relative to an add) */
343 /* Instruction size costs on 32bit processors. */
344 static const
345 struct processor_costs size32_cost = {
346 COSTS_N_INSNS (1), /* mulsi */
347 COSTS_N_INSNS (1), /* mulsi_const */
348 COSTS_N_INSNS (1), /* mulsi_const9 */
349 COSTS_N_INSNS (1), /* muldi */
350 COSTS_N_INSNS (1), /* divsi */
351 COSTS_N_INSNS (1), /* divdi */
352 COSTS_N_INSNS (1), /* fp */
353 COSTS_N_INSNS (1), /* dmul */
354 COSTS_N_INSNS (1), /* sdiv */
355 COSTS_N_INSNS (1), /* ddiv */
362 /* Instruction size costs on 64bit processors. */
363 static const
364 struct processor_costs size64_cost = {
365 COSTS_N_INSNS (1), /* mulsi */
366 COSTS_N_INSNS (1), /* mulsi_const */
367 COSTS_N_INSNS (1), /* mulsi_const9 */
368 COSTS_N_INSNS (1), /* muldi */
369 COSTS_N_INSNS (1), /* divsi */
370 COSTS_N_INSNS (1), /* divdi */
371 COSTS_N_INSNS (1), /* fp */
372 COSTS_N_INSNS (1), /* dmul */
373 COSTS_N_INSNS (1), /* sdiv */
374 COSTS_N_INSNS (1), /* ddiv */
375 128,
381 /* Instruction costs on RIOS1 processors. */
382 static const
383 struct processor_costs rios1_cost = {
384 COSTS_N_INSNS (5), /* mulsi */
385 COSTS_N_INSNS (4), /* mulsi_const */
386 COSTS_N_INSNS (3), /* mulsi_const9 */
387 COSTS_N_INSNS (5), /* muldi */
388 COSTS_N_INSNS (19), /* divsi */
389 COSTS_N_INSNS (19), /* divdi */
390 COSTS_N_INSNS (2), /* fp */
391 COSTS_N_INSNS (2), /* dmul */
392 COSTS_N_INSNS (19), /* sdiv */
393 COSTS_N_INSNS (19), /* ddiv */
394 128, /* cache line size */
395 64, /* l1 cache */
396 512, /* l2 cache */
397 0, /* streams */
400 /* Instruction costs on RIOS2 processors. */
401 static const
402 struct processor_costs rios2_cost = {
403 COSTS_N_INSNS (2), /* mulsi */
404 COSTS_N_INSNS (2), /* mulsi_const */
405 COSTS_N_INSNS (2), /* mulsi_const9 */
406 COSTS_N_INSNS (2), /* muldi */
407 COSTS_N_INSNS (13), /* divsi */
408 COSTS_N_INSNS (13), /* divdi */
409 COSTS_N_INSNS (2), /* fp */
410 COSTS_N_INSNS (2), /* dmul */
411 COSTS_N_INSNS (17), /* sdiv */
412 COSTS_N_INSNS (17), /* ddiv */
413 256, /* cache line size */
414 256, /* l1 cache */
415 1024, /* l2 cache */
416 0, /* streams */
419 /* Instruction costs on RS64A processors. */
420 static const
421 struct processor_costs rs64a_cost = {
422 COSTS_N_INSNS (20), /* mulsi */
423 COSTS_N_INSNS (12), /* mulsi_const */
424 COSTS_N_INSNS (8), /* mulsi_const9 */
425 COSTS_N_INSNS (34), /* muldi */
426 COSTS_N_INSNS (65), /* divsi */
427 COSTS_N_INSNS (67), /* divdi */
428 COSTS_N_INSNS (4), /* fp */
429 COSTS_N_INSNS (4), /* dmul */
430 COSTS_N_INSNS (31), /* sdiv */
431 COSTS_N_INSNS (31), /* ddiv */
432 128, /* cache line size */
433 128, /* l1 cache */
434 2048, /* l2 cache */
435 1, /* streams */
438 /* Instruction costs on MPCCORE processors. */
439 static const
440 struct processor_costs mpccore_cost = {
441 COSTS_N_INSNS (2), /* mulsi */
442 COSTS_N_INSNS (2), /* mulsi_const */
443 COSTS_N_INSNS (2), /* mulsi_const9 */
444 COSTS_N_INSNS (2), /* muldi */
445 COSTS_N_INSNS (6), /* divsi */
446 COSTS_N_INSNS (6), /* divdi */
447 COSTS_N_INSNS (4), /* fp */
448 COSTS_N_INSNS (5), /* dmul */
449 COSTS_N_INSNS (10), /* sdiv */
450 COSTS_N_INSNS (17), /* ddiv */
451 32, /* cache line size */
452 4, /* l1 cache */
453 16, /* l2 cache */
454 1, /* streams */
457 /* Instruction costs on PPC403 processors. */
458 static const
459 struct processor_costs ppc403_cost = {
460 COSTS_N_INSNS (4), /* mulsi */
461 COSTS_N_INSNS (4), /* mulsi_const */
462 COSTS_N_INSNS (4), /* mulsi_const9 */
463 COSTS_N_INSNS (4), /* muldi */
464 COSTS_N_INSNS (33), /* divsi */
465 COSTS_N_INSNS (33), /* divdi */
466 COSTS_N_INSNS (11), /* fp */
467 COSTS_N_INSNS (11), /* dmul */
468 COSTS_N_INSNS (11), /* sdiv */
469 COSTS_N_INSNS (11), /* ddiv */
470 32, /* cache line size */
471 4, /* l1 cache */
472 16, /* l2 cache */
473 1, /* streams */
476 /* Instruction costs on PPC405 processors. */
477 static const
478 struct processor_costs ppc405_cost = {
479 COSTS_N_INSNS (5), /* mulsi */
480 COSTS_N_INSNS (4), /* mulsi_const */
481 COSTS_N_INSNS (3), /* mulsi_const9 */
482 COSTS_N_INSNS (5), /* muldi */
483 COSTS_N_INSNS (35), /* divsi */
484 COSTS_N_INSNS (35), /* divdi */
485 COSTS_N_INSNS (11), /* fp */
486 COSTS_N_INSNS (11), /* dmul */
487 COSTS_N_INSNS (11), /* sdiv */
488 COSTS_N_INSNS (11), /* ddiv */
489 32, /* cache line size */
490 16, /* l1 cache */
491 128, /* l2 cache */
492 1, /* streams */
495 /* Instruction costs on PPC440 processors. */
496 static const
497 struct processor_costs ppc440_cost = {
498 COSTS_N_INSNS (3), /* mulsi */
499 COSTS_N_INSNS (2), /* mulsi_const */
500 COSTS_N_INSNS (2), /* mulsi_const9 */
501 COSTS_N_INSNS (3), /* muldi */
502 COSTS_N_INSNS (34), /* divsi */
503 COSTS_N_INSNS (34), /* divdi */
504 COSTS_N_INSNS (5), /* fp */
505 COSTS_N_INSNS (5), /* dmul */
506 COSTS_N_INSNS (19), /* sdiv */
507 COSTS_N_INSNS (33), /* ddiv */
508 32, /* cache line size */
509 32, /* l1 cache */
510 256, /* l2 cache */
511 1, /* streams */
514 /* Instruction costs on PPC601 processors. */
515 static const
516 struct processor_costs ppc601_cost = {
517 COSTS_N_INSNS (5), /* mulsi */
518 COSTS_N_INSNS (5), /* mulsi_const */
519 COSTS_N_INSNS (5), /* mulsi_const9 */
520 COSTS_N_INSNS (5), /* muldi */
521 COSTS_N_INSNS (36), /* divsi */
522 COSTS_N_INSNS (36), /* divdi */
523 COSTS_N_INSNS (4), /* fp */
524 COSTS_N_INSNS (5), /* dmul */
525 COSTS_N_INSNS (17), /* sdiv */
526 COSTS_N_INSNS (31), /* ddiv */
527 32, /* cache line size */
528 32, /* l1 cache */
529 256, /* l2 cache */
530 1, /* streams */
533 /* Instruction costs on PPC603 processors. */
534 static const
535 struct processor_costs ppc603_cost = {
536 COSTS_N_INSNS (5), /* mulsi */
537 COSTS_N_INSNS (3), /* mulsi_const */
538 COSTS_N_INSNS (2), /* mulsi_const9 */
539 COSTS_N_INSNS (5), /* muldi */
540 COSTS_N_INSNS (37), /* divsi */
541 COSTS_N_INSNS (37), /* divdi */
542 COSTS_N_INSNS (3), /* fp */
543 COSTS_N_INSNS (4), /* dmul */
544 COSTS_N_INSNS (18), /* sdiv */
545 COSTS_N_INSNS (33), /* ddiv */
546 32, /* cache line size */
547 8, /* l1 cache */
548 64, /* l2 cache */
549 1, /* streams */
552 /* Instruction costs on PPC604 processors. */
553 static const
554 struct processor_costs ppc604_cost = {
555 COSTS_N_INSNS (4), /* mulsi */
556 COSTS_N_INSNS (4), /* mulsi_const */
557 COSTS_N_INSNS (4), /* mulsi_const9 */
558 COSTS_N_INSNS (4), /* muldi */
559 COSTS_N_INSNS (20), /* divsi */
560 COSTS_N_INSNS (20), /* divdi */
561 COSTS_N_INSNS (3), /* fp */
562 COSTS_N_INSNS (3), /* dmul */
563 COSTS_N_INSNS (18), /* sdiv */
564 COSTS_N_INSNS (32), /* ddiv */
565 32, /* cache line size */
566 16, /* l1 cache */
567 512, /* l2 cache */
568 1, /* streams */
571 /* Instruction costs on PPC604e processors. */
572 static const
573 struct processor_costs ppc604e_cost = {
574 COSTS_N_INSNS (2), /* mulsi */
575 COSTS_N_INSNS (2), /* mulsi_const */
576 COSTS_N_INSNS (2), /* mulsi_const9 */
577 COSTS_N_INSNS (2), /* muldi */
578 COSTS_N_INSNS (20), /* divsi */
579 COSTS_N_INSNS (20), /* divdi */
580 COSTS_N_INSNS (3), /* fp */
581 COSTS_N_INSNS (3), /* dmul */
582 COSTS_N_INSNS (18), /* sdiv */
583 COSTS_N_INSNS (32), /* ddiv */
584 32, /* cache line size */
585 32, /* l1 cache */
586 1024, /* l2 cache */
587 1, /* streams */
590 /* Instruction costs on PPC620 processors. */
591 static const
592 struct processor_costs ppc620_cost = {
593 COSTS_N_INSNS (5), /* mulsi */
594 COSTS_N_INSNS (4), /* mulsi_const */
595 COSTS_N_INSNS (3), /* mulsi_const9 */
596 COSTS_N_INSNS (7), /* muldi */
597 COSTS_N_INSNS (21), /* divsi */
598 COSTS_N_INSNS (37), /* divdi */
599 COSTS_N_INSNS (3), /* fp */
600 COSTS_N_INSNS (3), /* dmul */
601 COSTS_N_INSNS (18), /* sdiv */
602 COSTS_N_INSNS (32), /* ddiv */
603 128, /* cache line size */
604 32, /* l1 cache */
605 1024, /* l2 cache */
606 1, /* streams */
609 /* Instruction costs on PPC630 processors. */
610 static const
611 struct processor_costs ppc630_cost = {
612 COSTS_N_INSNS (5), /* mulsi */
613 COSTS_N_INSNS (4), /* mulsi_const */
614 COSTS_N_INSNS (3), /* mulsi_const9 */
615 COSTS_N_INSNS (7), /* muldi */
616 COSTS_N_INSNS (21), /* divsi */
617 COSTS_N_INSNS (37), /* divdi */
618 COSTS_N_INSNS (3), /* fp */
619 COSTS_N_INSNS (3), /* dmul */
620 COSTS_N_INSNS (17), /* sdiv */
621 COSTS_N_INSNS (21), /* ddiv */
622 128, /* cache line size */
623 64, /* l1 cache */
624 1024, /* l2 cache */
625 1, /* streams */
628 /* Instruction costs on Cell processor. */
629 /* COSTS_N_INSNS (1) ~ one add. */
630 static const
631 struct processor_costs ppccell_cost = {
632 COSTS_N_INSNS (9/2)+2, /* mulsi */
633 COSTS_N_INSNS (6/2), /* mulsi_const */
634 COSTS_N_INSNS (6/2), /* mulsi_const9 */
635 COSTS_N_INSNS (15/2)+2, /* muldi */
636 COSTS_N_INSNS (38/2), /* divsi */
637 COSTS_N_INSNS (70/2), /* divdi */
638 COSTS_N_INSNS (10/2), /* fp */
639 COSTS_N_INSNS (10/2), /* dmul */
640 COSTS_N_INSNS (74/2), /* sdiv */
641 COSTS_N_INSNS (74/2), /* ddiv */
642 128, /* cache line size */
643 32, /* l1 cache */
644 512, /* l2 cache */
645 6, /* streams */
648 /* Instruction costs on PPC750 and PPC7400 processors. */
649 static const
650 struct processor_costs ppc750_cost = {
651 COSTS_N_INSNS (5), /* mulsi */
652 COSTS_N_INSNS (3), /* mulsi_const */
653 COSTS_N_INSNS (2), /* mulsi_const9 */
654 COSTS_N_INSNS (5), /* muldi */
655 COSTS_N_INSNS (17), /* divsi */
656 COSTS_N_INSNS (17), /* divdi */
657 COSTS_N_INSNS (3), /* fp */
658 COSTS_N_INSNS (3), /* dmul */
659 COSTS_N_INSNS (17), /* sdiv */
660 COSTS_N_INSNS (31), /* ddiv */
661 32, /* cache line size */
662 32, /* l1 cache */
663 512, /* l2 cache */
664 1, /* streams */
667 /* Instruction costs on PPC7450 processors. */
668 static const
669 struct processor_costs ppc7450_cost = {
670 COSTS_N_INSNS (4), /* mulsi */
671 COSTS_N_INSNS (3), /* mulsi_const */
672 COSTS_N_INSNS (3), /* mulsi_const9 */
673 COSTS_N_INSNS (4), /* muldi */
674 COSTS_N_INSNS (23), /* divsi */
675 COSTS_N_INSNS (23), /* divdi */
676 COSTS_N_INSNS (5), /* fp */
677 COSTS_N_INSNS (5), /* dmul */
678 COSTS_N_INSNS (21), /* sdiv */
679 COSTS_N_INSNS (35), /* ddiv */
680 32, /* cache line size */
681 32, /* l1 cache */
682 1024, /* l2 cache */
683 1, /* streams */
686 /* Instruction costs on PPC8540 processors. */
687 static const
688 struct processor_costs ppc8540_cost = {
689 COSTS_N_INSNS (4), /* mulsi */
690 COSTS_N_INSNS (4), /* mulsi_const */
691 COSTS_N_INSNS (4), /* mulsi_const9 */
692 COSTS_N_INSNS (4), /* muldi */
693 COSTS_N_INSNS (19), /* divsi */
694 COSTS_N_INSNS (19), /* divdi */
695 COSTS_N_INSNS (4), /* fp */
696 COSTS_N_INSNS (4), /* dmul */
697 COSTS_N_INSNS (29), /* sdiv */
698 COSTS_N_INSNS (29), /* ddiv */
699 32, /* cache line size */
700 32, /* l1 cache */
701 256, /* l2 cache */
702 1, /* prefetch streams /*/
705 /* Instruction costs on E300C2 and E300C3 cores. */
706 static const
707 struct processor_costs ppce300c2c3_cost = {
708 COSTS_N_INSNS (4), /* mulsi */
709 COSTS_N_INSNS (4), /* mulsi_const */
710 COSTS_N_INSNS (4), /* mulsi_const9 */
711 COSTS_N_INSNS (4), /* muldi */
712 COSTS_N_INSNS (19), /* divsi */
713 COSTS_N_INSNS (19), /* divdi */
714 COSTS_N_INSNS (3), /* fp */
715 COSTS_N_INSNS (4), /* dmul */
716 COSTS_N_INSNS (18), /* sdiv */
717 COSTS_N_INSNS (33), /* ddiv */
719 16, /* l1 cache */
720 16, /* l2 cache */
721 1, /* prefetch streams /*/
724 /* Instruction costs on PPCE500MC processors. */
725 static const
726 struct processor_costs ppce500mc_cost = {
727 COSTS_N_INSNS (4), /* mulsi */
728 COSTS_N_INSNS (4), /* mulsi_const */
729 COSTS_N_INSNS (4), /* mulsi_const9 */
730 COSTS_N_INSNS (4), /* muldi */
731 COSTS_N_INSNS (14), /* divsi */
732 COSTS_N_INSNS (14), /* divdi */
733 COSTS_N_INSNS (8), /* fp */
734 COSTS_N_INSNS (10), /* dmul */
735 COSTS_N_INSNS (36), /* sdiv */
736 COSTS_N_INSNS (66), /* ddiv */
737 64, /* cache line size */
738 32, /* l1 cache */
739 128, /* l2 cache */
740 1, /* prefetch streams /*/
743 /* Instruction costs on POWER4 and POWER5 processors. */
744 static const
745 struct processor_costs power4_cost = {
746 COSTS_N_INSNS (3), /* mulsi */
747 COSTS_N_INSNS (2), /* mulsi_const */
748 COSTS_N_INSNS (2), /* mulsi_const9 */
749 COSTS_N_INSNS (4), /* muldi */
750 COSTS_N_INSNS (18), /* divsi */
751 COSTS_N_INSNS (34), /* divdi */
752 COSTS_N_INSNS (3), /* fp */
753 COSTS_N_INSNS (3), /* dmul */
754 COSTS_N_INSNS (17), /* sdiv */
755 COSTS_N_INSNS (17), /* ddiv */
756 128, /* cache line size */
757 32, /* l1 cache */
758 1024, /* l2 cache */
759 8, /* prefetch streams /*/
762 /* Instruction costs on POWER6 processors. */
763 static const
764 struct processor_costs power6_cost = {
765 COSTS_N_INSNS (8), /* mulsi */
766 COSTS_N_INSNS (8), /* mulsi_const */
767 COSTS_N_INSNS (8), /* mulsi_const9 */
768 COSTS_N_INSNS (8), /* muldi */
769 COSTS_N_INSNS (22), /* divsi */
770 COSTS_N_INSNS (28), /* divdi */
771 COSTS_N_INSNS (3), /* fp */
772 COSTS_N_INSNS (3), /* dmul */
773 COSTS_N_INSNS (13), /* sdiv */
774 COSTS_N_INSNS (16), /* ddiv */
775 128, /* cache line size */
776 64, /* l1 cache */
777 2048, /* l2 cache */
778 16, /* prefetch streams */
781 /* Instruction costs on POWER7 processors. */
782 static const
783 struct processor_costs power7_cost = {
784 COSTS_N_INSNS (2), /* mulsi */
785 COSTS_N_INSNS (2), /* mulsi_const */
786 COSTS_N_INSNS (2), /* mulsi_const9 */
787 COSTS_N_INSNS (2), /* muldi */
788 COSTS_N_INSNS (18), /* divsi */
789 COSTS_N_INSNS (34), /* divdi */
790 COSTS_N_INSNS (3), /* fp */
791 COSTS_N_INSNS (3), /* dmul */
792 COSTS_N_INSNS (13), /* sdiv */
793 COSTS_N_INSNS (16), /* ddiv */
794 128, /* cache line size */
795 32, /* l1 cache */
796 256, /* l2 cache */
797 12, /* prefetch streams */
801 static bool rs6000_function_ok_for_sibcall (tree, tree);
802 static const char *rs6000_invalid_within_doloop (const_rtx);
803 static bool rs6000_legitimate_address_p (enum machine_mode, rtx, bool);
804 static bool rs6000_debug_legitimate_address_p (enum machine_mode, rtx, bool);
805 static rtx rs6000_generate_compare (rtx, enum machine_mode);
806 static void rs6000_emit_stack_tie (void);
807 static void rs6000_frame_related (rtx, rtx, HOST_WIDE_INT, rtx, rtx);
808 static bool spe_func_has_64bit_regs_p (void);
809 static void emit_frame_save (rtx, rtx, enum machine_mode, unsigned int,
810 int, HOST_WIDE_INT);
811 static rtx gen_frame_mem_offset (enum machine_mode, rtx, int);
812 static void rs6000_emit_allocate_stack (HOST_WIDE_INT, int, int);
813 static unsigned rs6000_hash_constant (rtx);
814 static unsigned toc_hash_function (const void *);
815 static int toc_hash_eq (const void *, const void *);
816 static bool reg_offset_addressing_ok_p (enum machine_mode);
817 static bool virtual_stack_registers_memory_p (rtx);
818 static bool constant_pool_expr_p (rtx);
819 static bool legitimate_small_data_p (enum machine_mode, rtx);
820 static bool legitimate_lo_sum_address_p (enum machine_mode, rtx, int);
821 static struct machine_function * rs6000_init_machine_status (void);
822 static bool rs6000_assemble_integer (rtx, unsigned int, int);
823 static bool no_global_regs_above (int, bool);
824 #ifdef HAVE_GAS_HIDDEN
825 static void rs6000_assemble_visibility (tree, int);
826 #endif
827 static int rs6000_ra_ever_killed (void);
828 static tree rs6000_handle_longcall_attribute (tree *, tree, tree, int, bool *);
829 static tree rs6000_handle_altivec_attribute (tree *, tree, tree, int, bool *);
830 static bool rs6000_ms_bitfield_layout_p (const_tree);
831 static tree rs6000_handle_struct_attribute (tree *, tree, tree, int, bool *);
832 static void rs6000_eliminate_indexed_memrefs (rtx operands[2]);
833 static const char *rs6000_mangle_type (const_tree);
834 static void rs6000_set_default_type_attributes (tree);
835 static rtx rs6000_savres_routine_sym (rs6000_stack_t *, bool, bool, bool);
836 static rtx rs6000_emit_stack_reset (rs6000_stack_t *, rtx, rtx, int, bool);
837 static rtx rs6000_make_savres_rtx (rs6000_stack_t *, rtx, int,
838 enum machine_mode, bool, bool, bool);
839 static bool rs6000_reg_live_or_pic_offset_p (int);
840 static tree rs6000_builtin_vectorized_function (unsigned int, tree, tree);
841 static int rs6000_savres_strategy (rs6000_stack_t *, bool, int, int);
842 static void rs6000_restore_saved_cr (rtx, int);
843 static void rs6000_output_function_prologue (FILE *, HOST_WIDE_INT);
844 static void rs6000_output_function_epilogue (FILE *, HOST_WIDE_INT);
845 static void rs6000_output_mi_thunk (FILE *, tree, HOST_WIDE_INT, HOST_WIDE_INT,
846 tree);
847 static rtx rs6000_emit_set_long_const (rtx, HOST_WIDE_INT, HOST_WIDE_INT);
848 static bool rs6000_return_in_memory (const_tree, const_tree);
849 static void rs6000_file_start (void);
850 #if TARGET_ELF
851 static int rs6000_elf_reloc_rw_mask (void);
852 static void rs6000_elf_asm_out_constructor (rtx, int);
853 static void rs6000_elf_asm_out_destructor (rtx, int);
854 static void rs6000_elf_end_indicate_exec_stack (void) ATTRIBUTE_UNUSED;
855 static void rs6000_elf_asm_init_sections (void);
856 static section *rs6000_elf_select_rtx_section (enum machine_mode, rtx,
857 unsigned HOST_WIDE_INT);
858 static void rs6000_elf_encode_section_info (tree, rtx, int)
859 ATTRIBUTE_UNUSED;
860 #endif
861 static bool rs6000_use_blocks_for_constant_p (enum machine_mode, const_rtx);
862 static void rs6000_alloc_sdmode_stack_slot (void);
863 static void rs6000_instantiate_decls (void);
864 #if TARGET_XCOFF
865 static void rs6000_xcoff_asm_output_anchor (rtx);
866 static void rs6000_xcoff_asm_globalize_label (FILE *, const char *);
867 static void rs6000_xcoff_asm_init_sections (void);
868 static int rs6000_xcoff_reloc_rw_mask (void);
869 static void rs6000_xcoff_asm_named_section (const char *, unsigned int, tree);
870 static section *rs6000_xcoff_select_section (tree, int,
871 unsigned HOST_WIDE_INT);
872 static void rs6000_xcoff_unique_section (tree, int);
873 static section *rs6000_xcoff_select_rtx_section
874 (enum machine_mode, rtx, unsigned HOST_WIDE_INT);
875 static const char * rs6000_xcoff_strip_name_encoding (const char *);
876 static unsigned int rs6000_xcoff_section_type_flags (tree, const char *, int);
877 static void rs6000_xcoff_file_start (void);
878 static void rs6000_xcoff_file_end (void);
879 #endif
880 static int rs6000_variable_issue (FILE *, int, rtx, int);
881 static bool rs6000_rtx_costs (rtx, int, int, int *, bool);
882 static bool rs6000_debug_rtx_costs (rtx, int, int, int *, bool);
883 static int rs6000_debug_address_cost (rtx, bool);
884 static int rs6000_adjust_cost (rtx, rtx, rtx, int);
885 static int rs6000_debug_adjust_cost (rtx, rtx, rtx, int);
886 static void rs6000_sched_init (FILE *, int, int);
887 static bool is_microcoded_insn (rtx);
888 static bool is_nonpipeline_insn (rtx);
889 static bool is_cracked_insn (rtx);
890 static bool is_branch_slot_insn (rtx);
891 static bool is_load_insn (rtx);
892 static rtx get_store_dest (rtx pat);
893 static bool is_store_insn (rtx);
894 static bool set_to_load_agen (rtx,rtx);
895 static bool adjacent_mem_locations (rtx,rtx);
896 static int rs6000_adjust_priority (rtx, int);
897 static int rs6000_issue_rate (void);
898 static bool rs6000_is_costly_dependence (dep_t, int, int);
899 static rtx get_next_active_insn (rtx, rtx);
900 static bool insn_terminates_group_p (rtx , enum group_termination);
901 static bool insn_must_be_first_in_group (rtx);
902 static bool insn_must_be_last_in_group (rtx);
903 static bool is_costly_group (rtx *, rtx);
904 static int force_new_group (int, FILE *, rtx *, rtx, bool *, int, int *);
905 static int redefine_groups (FILE *, int, rtx, rtx);
906 static int pad_groups (FILE *, int, rtx, rtx);
907 static void rs6000_sched_finish (FILE *, int);
908 static int rs6000_sched_reorder (FILE *, int, rtx *, int *, int);
909 static int rs6000_sched_reorder2 (FILE *, int, rtx *, int *, int);
910 static int rs6000_use_sched_lookahead (void);
911 static int rs6000_use_sched_lookahead_guard (rtx);
912 static void * rs6000_alloc_sched_context (void);
913 static void rs6000_init_sched_context (void *, bool);
914 static void rs6000_set_sched_context (void *);
915 static void rs6000_free_sched_context (void *);
916 static tree rs6000_builtin_reciprocal (unsigned int, bool, bool);
917 static tree rs6000_builtin_mask_for_load (void);
918 static tree rs6000_builtin_mul_widen_even (tree);
919 static tree rs6000_builtin_mul_widen_odd (tree);
920 static tree rs6000_builtin_conversion (unsigned int, tree);
921 static tree rs6000_builtin_vec_perm (tree, tree *);
923 static void def_builtin (int, const char *, tree, int);
924 static bool rs6000_vector_alignment_reachable (const_tree, bool);
925 static void rs6000_init_builtins (void);
926 static rtx rs6000_expand_unop_builtin (enum insn_code, tree, rtx);
927 static rtx rs6000_expand_binop_builtin (enum insn_code, tree, rtx);
928 static rtx rs6000_expand_ternop_builtin (enum insn_code, tree, rtx);
929 static rtx rs6000_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
930 static void altivec_init_builtins (void);
931 static unsigned builtin_hash_function (const void *);
932 static int builtin_hash_eq (const void *, const void *);
933 static tree builtin_function_type (enum machine_mode, enum machine_mode,
934 enum machine_mode, enum machine_mode,
935 enum rs6000_builtins, const char *name);
936 static void rs6000_common_init_builtins (void);
937 static void rs6000_init_libfuncs (void);
939 static void paired_init_builtins (void);
940 static rtx paired_expand_builtin (tree, rtx, bool *);
941 static rtx paired_expand_lv_builtin (enum insn_code, tree, rtx);
942 static rtx paired_expand_stv_builtin (enum insn_code, tree);
943 static rtx paired_expand_predicate_builtin (enum insn_code, tree, rtx);
945 static void enable_mask_for_builtins (struct builtin_description *, int,
946 enum rs6000_builtins,
947 enum rs6000_builtins);
948 static void spe_init_builtins (void);
949 static rtx spe_expand_builtin (tree, rtx, bool *);
950 static rtx spe_expand_stv_builtin (enum insn_code, tree);
951 static rtx spe_expand_predicate_builtin (enum insn_code, tree, rtx);
952 static rtx spe_expand_evsel_builtin (enum insn_code, tree, rtx);
953 static int rs6000_emit_int_cmove (rtx, rtx, rtx, rtx);
954 static rs6000_stack_t *rs6000_stack_info (void);
955 static void debug_stack_info (rs6000_stack_t *);
957 static rtx altivec_expand_builtin (tree, rtx, bool *);
958 static rtx altivec_expand_ld_builtin (tree, rtx, bool *);
959 static rtx altivec_expand_st_builtin (tree, rtx, bool *);
960 static rtx altivec_expand_dst_builtin (tree, rtx, bool *);
961 static rtx altivec_expand_abs_builtin (enum insn_code, tree, rtx);
962 static rtx altivec_expand_predicate_builtin (enum insn_code, tree, rtx);
963 static rtx altivec_expand_stv_builtin (enum insn_code, tree);
964 static rtx altivec_expand_vec_init_builtin (tree, tree, rtx);
965 static rtx altivec_expand_vec_set_builtin (tree);
966 static rtx altivec_expand_vec_ext_builtin (tree, rtx);
967 static int get_element_number (tree, tree);
968 static bool rs6000_handle_option (size_t, const char *, int);
969 static void rs6000_parse_tls_size_option (void);
970 static void rs6000_parse_yes_no_option (const char *, const char *, int *);
971 static int first_altivec_reg_to_save (void);
972 static unsigned int compute_vrsave_mask (void);
973 static void compute_save_world_info (rs6000_stack_t *info_ptr);
974 static void is_altivec_return_reg (rtx, void *);
975 static rtx generate_set_vrsave (rtx, rs6000_stack_t *, int);
976 int easy_vector_constant (rtx, enum machine_mode);
977 static rtx rs6000_dwarf_register_span (rtx);
978 static void rs6000_init_dwarf_reg_sizes_extra (tree);
979 static rtx rs6000_legitimize_address (rtx, rtx, enum machine_mode);
980 static rtx rs6000_debug_legitimize_address (rtx, rtx, enum machine_mode);
981 static rtx rs6000_legitimize_tls_address (rtx, enum tls_model);
982 static void rs6000_output_dwarf_dtprel (FILE *, int, rtx) ATTRIBUTE_UNUSED;
983 static rtx rs6000_tls_get_addr (void);
984 static rtx rs6000_got_sym (void);
985 static int rs6000_tls_symbol_ref_1 (rtx *, void *);
986 static const char *rs6000_get_some_local_dynamic_name (void);
987 static int rs6000_get_some_local_dynamic_name_1 (rtx *, void *);
988 static rtx rs6000_complex_function_value (enum machine_mode);
989 static rtx rs6000_spe_function_arg (CUMULATIVE_ARGS *,
990 enum machine_mode, tree);
991 static void rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS *,
992 HOST_WIDE_INT);
993 static void rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS *,
994 tree, HOST_WIDE_INT);
995 static void rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS *,
996 HOST_WIDE_INT,
997 rtx[], int *);
998 static void rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *,
999 const_tree, HOST_WIDE_INT,
1000 rtx[], int *);
1001 static rtx rs6000_darwin64_record_arg (CUMULATIVE_ARGS *, const_tree, int, bool);
1002 static rtx rs6000_mixed_function_arg (enum machine_mode, tree, int);
1003 static void rs6000_move_block_from_reg (int regno, rtx x, int nregs);
1004 static void setup_incoming_varargs (CUMULATIVE_ARGS *,
1005 enum machine_mode, tree,
1006 int *, int);
1007 static bool rs6000_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode,
1008 const_tree, bool);
1009 static int rs6000_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode,
1010 tree, bool);
1011 static const char *invalid_arg_for_unprototyped_fn (const_tree, const_tree, const_tree);
1012 #if TARGET_MACHO
1013 static void macho_branch_islands (void);
1014 static int no_previous_def (tree function_name);
1015 static tree get_prev_label (tree function_name);
1016 static void rs6000_darwin_file_start (void);
1017 #endif
1019 static tree rs6000_build_builtin_va_list (void);
1020 static void rs6000_va_start (tree, rtx);
1021 static tree rs6000_gimplify_va_arg (tree, tree, gimple_seq *, gimple_seq *);
1022 static bool rs6000_must_pass_in_stack (enum machine_mode, const_tree);
1023 static bool rs6000_scalar_mode_supported_p (enum machine_mode);
1024 static bool rs6000_vector_mode_supported_p (enum machine_mode);
1025 static rtx rs6000_emit_vector_compare_inner (enum rtx_code, rtx, rtx);
1026 static rtx rs6000_emit_vector_compare (enum rtx_code, rtx, rtx,
1027 enum machine_mode);
1028 static tree rs6000_stack_protect_fail (void);
1030 static rtx rs6000_legitimize_reload_address (rtx, enum machine_mode, int, int,
1031 int, int *);
1033 static rtx rs6000_debug_legitimize_reload_address (rtx, enum machine_mode, int,
1034 int, int, int *);
1036 rtx (*rs6000_legitimize_reload_address_ptr) (rtx, enum machine_mode, int, int,
1037 int, int *)
1038 = rs6000_legitimize_reload_address;
1040 static bool rs6000_mode_dependent_address (rtx);
1041 static bool rs6000_debug_mode_dependent_address (rtx);
1042 bool (*rs6000_mode_dependent_address_ptr) (rtx)
1043 = rs6000_mode_dependent_address;
1045 static enum reg_class rs6000_secondary_reload_class (enum reg_class,
1046 enum machine_mode, rtx);
1047 static enum reg_class rs6000_debug_secondary_reload_class (enum reg_class,
1048 enum machine_mode,
1049 rtx);
1050 enum reg_class (*rs6000_secondary_reload_class_ptr) (enum reg_class,
1051 enum machine_mode, rtx)
1052 = rs6000_secondary_reload_class;
1054 static enum reg_class rs6000_preferred_reload_class (rtx, enum reg_class);
1055 static enum reg_class rs6000_debug_preferred_reload_class (rtx,
1056 enum reg_class);
1057 enum reg_class (*rs6000_preferred_reload_class_ptr) (rtx, enum reg_class)
1058 = rs6000_preferred_reload_class;
1060 static bool rs6000_secondary_memory_needed (enum reg_class, enum reg_class,
1061 enum machine_mode);
1063 static bool rs6000_debug_secondary_memory_needed (enum reg_class,
1064 enum reg_class,
1065 enum machine_mode);
1067 bool (*rs6000_secondary_memory_needed_ptr) (enum reg_class, enum reg_class,
1068 enum machine_mode)
1069 = rs6000_secondary_memory_needed;
1071 static bool rs6000_cannot_change_mode_class (enum machine_mode,
1072 enum machine_mode,
1073 enum reg_class);
1074 static bool rs6000_debug_cannot_change_mode_class (enum machine_mode,
1075 enum machine_mode,
1076 enum reg_class);
1078 bool (*rs6000_cannot_change_mode_class_ptr) (enum machine_mode,
1079 enum machine_mode,
1080 enum reg_class)
1081 = rs6000_cannot_change_mode_class;
1083 static enum reg_class rs6000_secondary_reload (bool, rtx, enum reg_class,
1084 enum machine_mode,
1085 struct secondary_reload_info *);
1087 static const enum reg_class *rs6000_ira_cover_classes (void);
1089 const int INSN_NOT_AVAILABLE = -1;
1090 static enum machine_mode rs6000_eh_return_filter_mode (void);
1092 /* Hash table stuff for keeping track of TOC entries. */
1094 struct GTY(()) toc_hash_struct
1096 /* `key' will satisfy CONSTANT_P; in fact, it will satisfy
1097 ASM_OUTPUT_SPECIAL_POOL_ENTRY_P. */
1098 rtx key;
1099 enum machine_mode key_mode;
1100 int labelno;
1103 static GTY ((param_is (struct toc_hash_struct))) htab_t toc_hash_table;
1105 /* Hash table to keep track of the argument types for builtin functions. */
1107 struct GTY(()) builtin_hash_struct
1109 tree type;
1110 enum machine_mode mode[4]; /* return value + 3 arguments. */
1111 unsigned char uns_p[4]; /* and whether the types are unsigned. */
1114 static GTY ((param_is (struct builtin_hash_struct))) htab_t builtin_hash_table;
1116 /* Default register names. */
1117 char rs6000_reg_names[][8] =
1119 "0", "1", "2", "3", "4", "5", "6", "7",
1120 "8", "9", "10", "11", "12", "13", "14", "15",
1121 "16", "17", "18", "19", "20", "21", "22", "23",
1122 "24", "25", "26", "27", "28", "29", "30", "31",
1123 "0", "1", "2", "3", "4", "5", "6", "7",
1124 "8", "9", "10", "11", "12", "13", "14", "15",
1125 "16", "17", "18", "19", "20", "21", "22", "23",
1126 "24", "25", "26", "27", "28", "29", "30", "31",
1127 "mq", "lr", "ctr","ap",
1128 "0", "1", "2", "3", "4", "5", "6", "7",
1129 "xer",
1130 /* AltiVec registers. */
1131 "0", "1", "2", "3", "4", "5", "6", "7",
1132 "8", "9", "10", "11", "12", "13", "14", "15",
1133 "16", "17", "18", "19", "20", "21", "22", "23",
1134 "24", "25", "26", "27", "28", "29", "30", "31",
1135 "vrsave", "vscr",
1136 /* SPE registers. */
1137 "spe_acc", "spefscr",
1138 /* Soft frame pointer. */
1139 "sfp"
1142 #ifdef TARGET_REGNAMES
1143 static const char alt_reg_names[][8] =
1145 "%r0", "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7",
1146 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15",
1147 "%r16", "%r17", "%r18", "%r19", "%r20", "%r21", "%r22", "%r23",
1148 "%r24", "%r25", "%r26", "%r27", "%r28", "%r29", "%r30", "%r31",
1149 "%f0", "%f1", "%f2", "%f3", "%f4", "%f5", "%f6", "%f7",
1150 "%f8", "%f9", "%f10", "%f11", "%f12", "%f13", "%f14", "%f15",
1151 "%f16", "%f17", "%f18", "%f19", "%f20", "%f21", "%f22", "%f23",
1152 "%f24", "%f25", "%f26", "%f27", "%f28", "%f29", "%f30", "%f31",
1153 "mq", "lr", "ctr", "ap",
1154 "%cr0", "%cr1", "%cr2", "%cr3", "%cr4", "%cr5", "%cr6", "%cr7",
1155 "xer",
1156 /* AltiVec registers. */
1157 "%v0", "%v1", "%v2", "%v3", "%v4", "%v5", "%v6", "%v7",
1158 "%v8", "%v9", "%v10", "%v11", "%v12", "%v13", "%v14", "%v15",
1159 "%v16", "%v17", "%v18", "%v19", "%v20", "%v21", "%v22", "%v23",
1160 "%v24", "%v25", "%v26", "%v27", "%v28", "%v29", "%v30", "%v31",
1161 "vrsave", "vscr",
1162 /* SPE registers. */
1163 "spe_acc", "spefscr",
1164 /* Soft frame pointer. */
1165 "sfp"
1167 #endif
1169 /* Table of valid machine attributes. */
1171 static const struct attribute_spec rs6000_attribute_table[] =
1173 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
1174 { "altivec", 1, 1, false, true, false, rs6000_handle_altivec_attribute },
1175 { "longcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute },
1176 { "shortcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute },
1177 { "ms_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute },
1178 { "gcc_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute },
1179 #ifdef SUBTARGET_ATTRIBUTE_TABLE
1180 SUBTARGET_ATTRIBUTE_TABLE,
1181 #endif
1182 { NULL, 0, 0, false, false, false, NULL }
1185 #ifndef MASK_STRICT_ALIGN
1186 #define MASK_STRICT_ALIGN 0
1187 #endif
1188 #ifndef TARGET_PROFILE_KERNEL
1189 #define TARGET_PROFILE_KERNEL 0
1190 #define SET_PROFILE_KERNEL(N)
1191 #else
1192 #define SET_PROFILE_KERNEL(N) TARGET_PROFILE_KERNEL = (N)
1193 #endif
1195 /* The VRSAVE bitmask puts bit %v0 as the most significant bit. */
1196 #define ALTIVEC_REG_BIT(REGNO) (0x80000000 >> ((REGNO) - FIRST_ALTIVEC_REGNO))
1198 /* Initialize the GCC target structure. */
1199 #undef TARGET_ATTRIBUTE_TABLE
1200 #define TARGET_ATTRIBUTE_TABLE rs6000_attribute_table
1201 #undef TARGET_SET_DEFAULT_TYPE_ATTRIBUTES
1202 #define TARGET_SET_DEFAULT_TYPE_ATTRIBUTES rs6000_set_default_type_attributes
1204 #undef TARGET_ASM_ALIGNED_DI_OP
1205 #define TARGET_ASM_ALIGNED_DI_OP DOUBLE_INT_ASM_OP
1207 /* Default unaligned ops are only provided for ELF. Find the ops needed
1208 for non-ELF systems. */
1209 #ifndef OBJECT_FORMAT_ELF
1210 #if TARGET_XCOFF
1211 /* For XCOFF. rs6000_assemble_integer will handle unaligned DIs on
1212 64-bit targets. */
1213 #undef TARGET_ASM_UNALIGNED_HI_OP
1214 #define TARGET_ASM_UNALIGNED_HI_OP "\t.vbyte\t2,"
1215 #undef TARGET_ASM_UNALIGNED_SI_OP
1216 #define TARGET_ASM_UNALIGNED_SI_OP "\t.vbyte\t4,"
1217 #undef TARGET_ASM_UNALIGNED_DI_OP
1218 #define TARGET_ASM_UNALIGNED_DI_OP "\t.vbyte\t8,"
1219 #else
1220 /* For Darwin. */
1221 #undef TARGET_ASM_UNALIGNED_HI_OP
1222 #define TARGET_ASM_UNALIGNED_HI_OP "\t.short\t"
1223 #undef TARGET_ASM_UNALIGNED_SI_OP
1224 #define TARGET_ASM_UNALIGNED_SI_OP "\t.long\t"
1225 #undef TARGET_ASM_UNALIGNED_DI_OP
1226 #define TARGET_ASM_UNALIGNED_DI_OP "\t.quad\t"
1227 #undef TARGET_ASM_ALIGNED_DI_OP
1228 #define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t"
1229 #endif
1230 #endif
1232 /* This hook deals with fixups for relocatable code and DI-mode objects
1233 in 64-bit code. */
1234 #undef TARGET_ASM_INTEGER
1235 #define TARGET_ASM_INTEGER rs6000_assemble_integer
1237 #ifdef HAVE_GAS_HIDDEN
1238 #undef TARGET_ASM_ASSEMBLE_VISIBILITY
1239 #define TARGET_ASM_ASSEMBLE_VISIBILITY rs6000_assemble_visibility
1240 #endif
1242 #undef TARGET_HAVE_TLS
1243 #define TARGET_HAVE_TLS HAVE_AS_TLS
1245 #undef TARGET_CANNOT_FORCE_CONST_MEM
1246 #define TARGET_CANNOT_FORCE_CONST_MEM rs6000_tls_referenced_p
1248 #undef TARGET_ASM_FUNCTION_PROLOGUE
1249 #define TARGET_ASM_FUNCTION_PROLOGUE rs6000_output_function_prologue
1250 #undef TARGET_ASM_FUNCTION_EPILOGUE
1251 #define TARGET_ASM_FUNCTION_EPILOGUE rs6000_output_function_epilogue
1253 #undef TARGET_LEGITIMIZE_ADDRESS
1254 #define TARGET_LEGITIMIZE_ADDRESS rs6000_legitimize_address
1256 #undef TARGET_SCHED_VARIABLE_ISSUE
1257 #define TARGET_SCHED_VARIABLE_ISSUE rs6000_variable_issue
1259 #undef TARGET_SCHED_ISSUE_RATE
1260 #define TARGET_SCHED_ISSUE_RATE rs6000_issue_rate
1261 #undef TARGET_SCHED_ADJUST_COST
1262 #define TARGET_SCHED_ADJUST_COST rs6000_adjust_cost
1263 #undef TARGET_SCHED_ADJUST_PRIORITY
1264 #define TARGET_SCHED_ADJUST_PRIORITY rs6000_adjust_priority
1265 #undef TARGET_SCHED_IS_COSTLY_DEPENDENCE
1266 #define TARGET_SCHED_IS_COSTLY_DEPENDENCE rs6000_is_costly_dependence
1267 #undef TARGET_SCHED_INIT
1268 #define TARGET_SCHED_INIT rs6000_sched_init
1269 #undef TARGET_SCHED_FINISH
1270 #define TARGET_SCHED_FINISH rs6000_sched_finish
1271 #undef TARGET_SCHED_REORDER
1272 #define TARGET_SCHED_REORDER rs6000_sched_reorder
1273 #undef TARGET_SCHED_REORDER2
1274 #define TARGET_SCHED_REORDER2 rs6000_sched_reorder2
1276 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
1277 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD rs6000_use_sched_lookahead
1279 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD
1280 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD rs6000_use_sched_lookahead_guard
1282 #undef TARGET_SCHED_ALLOC_SCHED_CONTEXT
1283 #define TARGET_SCHED_ALLOC_SCHED_CONTEXT rs6000_alloc_sched_context
1284 #undef TARGET_SCHED_INIT_SCHED_CONTEXT
1285 #define TARGET_SCHED_INIT_SCHED_CONTEXT rs6000_init_sched_context
1286 #undef TARGET_SCHED_SET_SCHED_CONTEXT
1287 #define TARGET_SCHED_SET_SCHED_CONTEXT rs6000_set_sched_context
1288 #undef TARGET_SCHED_FREE_SCHED_CONTEXT
1289 #define TARGET_SCHED_FREE_SCHED_CONTEXT rs6000_free_sched_context
1291 #undef TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD
1292 #define TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD rs6000_builtin_mask_for_load
1293 #undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN
1294 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN rs6000_builtin_mul_widen_even
1295 #undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD
1296 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD rs6000_builtin_mul_widen_odd
1297 #undef TARGET_VECTORIZE_BUILTIN_CONVERSION
1298 #define TARGET_VECTORIZE_BUILTIN_CONVERSION rs6000_builtin_conversion
1299 #undef TARGET_VECTORIZE_BUILTIN_VEC_PERM
1300 #define TARGET_VECTORIZE_BUILTIN_VEC_PERM rs6000_builtin_vec_perm
1302 #undef TARGET_VECTOR_ALIGNMENT_REACHABLE
1303 #define TARGET_VECTOR_ALIGNMENT_REACHABLE rs6000_vector_alignment_reachable
1305 #undef TARGET_INIT_BUILTINS
1306 #define TARGET_INIT_BUILTINS rs6000_init_builtins
1308 #undef TARGET_EXPAND_BUILTIN
1309 #define TARGET_EXPAND_BUILTIN rs6000_expand_builtin
1311 #undef TARGET_MANGLE_TYPE
1312 #define TARGET_MANGLE_TYPE rs6000_mangle_type
1314 #undef TARGET_INIT_LIBFUNCS
1315 #define TARGET_INIT_LIBFUNCS rs6000_init_libfuncs
1317 #if TARGET_MACHO
1318 #undef TARGET_BINDS_LOCAL_P
1319 #define TARGET_BINDS_LOCAL_P darwin_binds_local_p
1320 #endif
1322 #undef TARGET_MS_BITFIELD_LAYOUT_P
1323 #define TARGET_MS_BITFIELD_LAYOUT_P rs6000_ms_bitfield_layout_p
1325 #undef TARGET_ASM_OUTPUT_MI_THUNK
1326 #define TARGET_ASM_OUTPUT_MI_THUNK rs6000_output_mi_thunk
1328 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
1329 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true
1331 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
1332 #define TARGET_FUNCTION_OK_FOR_SIBCALL rs6000_function_ok_for_sibcall
1334 #undef TARGET_INVALID_WITHIN_DOLOOP
1335 #define TARGET_INVALID_WITHIN_DOLOOP rs6000_invalid_within_doloop
1337 #undef TARGET_RTX_COSTS
1338 #define TARGET_RTX_COSTS rs6000_rtx_costs
1339 #undef TARGET_ADDRESS_COST
1340 #define TARGET_ADDRESS_COST hook_int_rtx_bool_0
1342 #undef TARGET_DWARF_REGISTER_SPAN
1343 #define TARGET_DWARF_REGISTER_SPAN rs6000_dwarf_register_span
1345 #undef TARGET_INIT_DWARF_REG_SIZES_EXTRA
1346 #define TARGET_INIT_DWARF_REG_SIZES_EXTRA rs6000_init_dwarf_reg_sizes_extra
1348 /* On rs6000, function arguments are promoted, as are function return
1349 values. */
1350 #undef TARGET_PROMOTE_FUNCTION_MODE
1351 #define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote
1353 #undef TARGET_RETURN_IN_MEMORY
1354 #define TARGET_RETURN_IN_MEMORY rs6000_return_in_memory
1356 #undef TARGET_SETUP_INCOMING_VARARGS
1357 #define TARGET_SETUP_INCOMING_VARARGS setup_incoming_varargs
1359 /* Always strict argument naming on rs6000. */
1360 #undef TARGET_STRICT_ARGUMENT_NAMING
1361 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
1362 #undef TARGET_PRETEND_OUTGOING_VARARGS_NAMED
1363 #define TARGET_PRETEND_OUTGOING_VARARGS_NAMED hook_bool_CUMULATIVE_ARGS_true
1364 #undef TARGET_SPLIT_COMPLEX_ARG
1365 #define TARGET_SPLIT_COMPLEX_ARG hook_bool_const_tree_true
1366 #undef TARGET_MUST_PASS_IN_STACK
1367 #define TARGET_MUST_PASS_IN_STACK rs6000_must_pass_in_stack
1368 #undef TARGET_PASS_BY_REFERENCE
1369 #define TARGET_PASS_BY_REFERENCE rs6000_pass_by_reference
1370 #undef TARGET_ARG_PARTIAL_BYTES
1371 #define TARGET_ARG_PARTIAL_BYTES rs6000_arg_partial_bytes
1373 #undef TARGET_BUILD_BUILTIN_VA_LIST
1374 #define TARGET_BUILD_BUILTIN_VA_LIST rs6000_build_builtin_va_list
1376 #undef TARGET_EXPAND_BUILTIN_VA_START
1377 #define TARGET_EXPAND_BUILTIN_VA_START rs6000_va_start
1379 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
1380 #define TARGET_GIMPLIFY_VA_ARG_EXPR rs6000_gimplify_va_arg
1382 #undef TARGET_EH_RETURN_FILTER_MODE
1383 #define TARGET_EH_RETURN_FILTER_MODE rs6000_eh_return_filter_mode
1385 #undef TARGET_SCALAR_MODE_SUPPORTED_P
1386 #define TARGET_SCALAR_MODE_SUPPORTED_P rs6000_scalar_mode_supported_p
1388 #undef TARGET_VECTOR_MODE_SUPPORTED_P
1389 #define TARGET_VECTOR_MODE_SUPPORTED_P rs6000_vector_mode_supported_p
1391 #undef TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN
1392 #define TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN invalid_arg_for_unprototyped_fn
1394 #undef TARGET_HANDLE_OPTION
1395 #define TARGET_HANDLE_OPTION rs6000_handle_option
1397 #undef TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION
1398 #define TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION \
1399 rs6000_builtin_vectorized_function
1401 #undef TARGET_DEFAULT_TARGET_FLAGS
1402 #define TARGET_DEFAULT_TARGET_FLAGS \
1403 (TARGET_DEFAULT)
1405 #undef TARGET_STACK_PROTECT_FAIL
1406 #define TARGET_STACK_PROTECT_FAIL rs6000_stack_protect_fail
1408 /* MPC604EUM 3.5.2 Weak Consistency between Multiple Processors
1409 The PowerPC architecture requires only weak consistency among
1410 processors--that is, memory accesses between processors need not be
1411 sequentially consistent and memory accesses among processors can occur
1412 in any order. The ability to order memory accesses weakly provides
1413 opportunities for more efficient use of the system bus. Unless a
1414 dependency exists, the 604e allows read operations to precede store
1415 operations. */
1416 #undef TARGET_RELAXED_ORDERING
1417 #define TARGET_RELAXED_ORDERING true
1419 #ifdef HAVE_AS_TLS
1420 #undef TARGET_ASM_OUTPUT_DWARF_DTPREL
1421 #define TARGET_ASM_OUTPUT_DWARF_DTPREL rs6000_output_dwarf_dtprel
1422 #endif
1424 /* Use a 32-bit anchor range. This leads to sequences like:
1426 addis tmp,anchor,high
1427 add dest,tmp,low
1429 where tmp itself acts as an anchor, and can be shared between
1430 accesses to the same 64k page. */
1431 #undef TARGET_MIN_ANCHOR_OFFSET
1432 #define TARGET_MIN_ANCHOR_OFFSET -0x7fffffff - 1
1433 #undef TARGET_MAX_ANCHOR_OFFSET
1434 #define TARGET_MAX_ANCHOR_OFFSET 0x7fffffff
1435 #undef TARGET_USE_BLOCKS_FOR_CONSTANT_P
1436 #define TARGET_USE_BLOCKS_FOR_CONSTANT_P rs6000_use_blocks_for_constant_p
1438 #undef TARGET_BUILTIN_RECIPROCAL
1439 #define TARGET_BUILTIN_RECIPROCAL rs6000_builtin_reciprocal
1441 #undef TARGET_EXPAND_TO_RTL_HOOK
1442 #define TARGET_EXPAND_TO_RTL_HOOK rs6000_alloc_sdmode_stack_slot
1444 #undef TARGET_INSTANTIATE_DECLS
1445 #define TARGET_INSTANTIATE_DECLS rs6000_instantiate_decls
1447 #undef TARGET_SECONDARY_RELOAD
1448 #define TARGET_SECONDARY_RELOAD rs6000_secondary_reload
1450 #undef TARGET_IRA_COVER_CLASSES
1451 #define TARGET_IRA_COVER_CLASSES rs6000_ira_cover_classes
1453 #undef TARGET_LEGITIMATE_ADDRESS_P
1454 #define TARGET_LEGITIMATE_ADDRESS_P rs6000_legitimate_address_p
1456 struct gcc_target targetm = TARGET_INITIALIZER;
1458 /* Return number of consecutive hard regs needed starting at reg REGNO
1459 to hold something of mode MODE.
1460 This is ordinarily the length in words of a value of mode MODE
1461 but can be less for certain modes in special long registers.
1463 For the SPE, GPRs are 64 bits but only 32 bits are visible in
1464 scalar instructions. The upper 32 bits are only available to the
1465 SIMD instructions.
1467 POWER and PowerPC GPRs hold 32 bits worth;
1468 PowerPC64 GPRs and FPRs point register holds 64 bits worth. */
1470 static int
1471 rs6000_hard_regno_nregs_internal (int regno, enum machine_mode mode)
1473 unsigned HOST_WIDE_INT reg_size;
1475 if (FP_REGNO_P (regno))
1476 reg_size = (VECTOR_MEM_VSX_P (mode)
1477 ? UNITS_PER_VSX_WORD
1478 : UNITS_PER_FP_WORD);
1480 else if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode))
1481 reg_size = UNITS_PER_SPE_WORD;
1483 else if (ALTIVEC_REGNO_P (regno))
1484 reg_size = UNITS_PER_ALTIVEC_WORD;
1486 /* The value returned for SCmode in the E500 double case is 2 for
1487 ABI compatibility; storing an SCmode value in a single register
1488 would require function_arg and rs6000_spe_function_arg to handle
1489 SCmode so as to pass the value correctly in a pair of
1490 registers. */
1491 else if (TARGET_E500_DOUBLE && FLOAT_MODE_P (mode) && mode != SCmode
1492 && !DECIMAL_FLOAT_MODE_P (mode))
1493 reg_size = UNITS_PER_FP_WORD;
1495 else
1496 reg_size = UNITS_PER_WORD;
1498 return (GET_MODE_SIZE (mode) + reg_size - 1) / reg_size;
1501 /* Value is 1 if hard register REGNO can hold a value of machine-mode
1502 MODE. */
1503 static int
1504 rs6000_hard_regno_mode_ok (int regno, enum machine_mode mode)
1506 int last_regno = regno + rs6000_hard_regno_nregs[mode][regno] - 1;
1508 /* VSX registers that overlap the FPR registers are larger than for non-VSX
1509 implementations. Don't allow an item to be split between a FP register
1510 and an Altivec register. */
1511 if (VECTOR_MEM_VSX_P (mode))
1513 if (FP_REGNO_P (regno))
1514 return FP_REGNO_P (last_regno);
1516 if (ALTIVEC_REGNO_P (regno))
1517 return ALTIVEC_REGNO_P (last_regno);
1520 /* The GPRs can hold any mode, but values bigger than one register
1521 cannot go past R31. */
1522 if (INT_REGNO_P (regno))
1523 return INT_REGNO_P (last_regno);
1525 /* The float registers (except for VSX vector modes) can only hold floating
1526 modes and DImode. This excludes the 32-bit decimal float mode for
1527 now. */
1528 if (FP_REGNO_P (regno))
1530 if (SCALAR_FLOAT_MODE_P (mode)
1531 && (mode != TDmode || (regno % 2) == 0)
1532 && FP_REGNO_P (last_regno))
1533 return 1;
1535 if (GET_MODE_CLASS (mode) == MODE_INT
1536 && GET_MODE_SIZE (mode) == UNITS_PER_FP_WORD)
1537 return 1;
1539 if (PAIRED_SIMD_REGNO_P (regno) && TARGET_PAIRED_FLOAT
1540 && PAIRED_VECTOR_MODE (mode))
1541 return 1;
1543 return 0;
1546 /* The CR register can only hold CC modes. */
1547 if (CR_REGNO_P (regno))
1548 return GET_MODE_CLASS (mode) == MODE_CC;
1550 if (XER_REGNO_P (regno))
1551 return mode == PSImode;
1553 /* AltiVec only in AldyVec registers. */
1554 if (ALTIVEC_REGNO_P (regno))
1555 return VECTOR_MEM_ALTIVEC_OR_VSX_P (mode);
1557 /* ...but GPRs can hold SIMD data on the SPE in one register. */
1558 if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode))
1559 return 1;
1561 /* We cannot put TImode anywhere except general register and it must be able
1562 to fit within the register set. In the future, allow TImode in the
1563 Altivec or VSX registers. */
1565 return GET_MODE_SIZE (mode) <= UNITS_PER_WORD;
1568 /* Print interesting facts about registers. */
1569 static void
1570 rs6000_debug_reg_print (int first_regno, int last_regno, const char *reg_name)
1572 int r, m;
1574 for (r = first_regno; r <= last_regno; ++r)
1576 const char *comma = "";
1577 int len;
1579 if (first_regno == last_regno)
1580 fprintf (stderr, "%s:\t", reg_name);
1581 else
1582 fprintf (stderr, "%s%d:\t", reg_name, r - first_regno);
1584 len = 8;
1585 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1586 if (rs6000_hard_regno_mode_ok_p[m][r] && rs6000_hard_regno_nregs[m][r])
1588 if (len > 70)
1590 fprintf (stderr, ",\n\t");
1591 len = 8;
1592 comma = "";
1595 if (rs6000_hard_regno_nregs[m][r] > 1)
1596 len += fprintf (stderr, "%s%s/%d", comma, GET_MODE_NAME (m),
1597 rs6000_hard_regno_nregs[m][r]);
1598 else
1599 len += fprintf (stderr, "%s%s", comma, GET_MODE_NAME (m));
1601 comma = ", ";
1604 if (call_used_regs[r])
1606 if (len > 70)
1608 fprintf (stderr, ",\n\t");
1609 len = 8;
1610 comma = "";
1613 len += fprintf (stderr, "%s%s", comma, "call-used");
1614 comma = ", ";
1617 if (fixed_regs[r])
1619 if (len > 70)
1621 fprintf (stderr, ",\n\t");
1622 len = 8;
1623 comma = "";
1626 len += fprintf (stderr, "%s%s", comma, "fixed");
1627 comma = ", ";
1630 if (len > 70)
1632 fprintf (stderr, ",\n\t");
1633 comma = "";
1636 fprintf (stderr, "%sregno = %d\n", comma, r);
1640 /* Print various interesting information with -mdebug=reg. */
1641 static void
1642 rs6000_debug_reg_global (void)
1644 const char *nl = (const char *)0;
1645 int m;
1646 char costly_num[20];
1647 char nop_num[20];
1648 const char *costly_str;
1649 const char *nop_str;
1651 /* Map enum rs6000_vector to string. */
1652 static const char *rs6000_debug_vector_unit[] = {
1653 "none",
1654 "altivec",
1655 "vsx",
1656 "paired",
1657 "spe",
1658 "other"
1661 fprintf (stderr, "Register information: (last virtual reg = %d)\n",
1662 LAST_VIRTUAL_REGISTER);
1663 rs6000_debug_reg_print (0, 31, "gr");
1664 rs6000_debug_reg_print (32, 63, "fp");
1665 rs6000_debug_reg_print (FIRST_ALTIVEC_REGNO,
1666 LAST_ALTIVEC_REGNO,
1667 "vs");
1668 rs6000_debug_reg_print (LR_REGNO, LR_REGNO, "lr");
1669 rs6000_debug_reg_print (CTR_REGNO, CTR_REGNO, "ctr");
1670 rs6000_debug_reg_print (CR0_REGNO, CR7_REGNO, "cr");
1671 rs6000_debug_reg_print (MQ_REGNO, MQ_REGNO, "mq");
1672 rs6000_debug_reg_print (XER_REGNO, XER_REGNO, "xer");
1673 rs6000_debug_reg_print (VRSAVE_REGNO, VRSAVE_REGNO, "vrsave");
1674 rs6000_debug_reg_print (VSCR_REGNO, VSCR_REGNO, "vscr");
1675 rs6000_debug_reg_print (SPE_ACC_REGNO, SPE_ACC_REGNO, "spe_a");
1676 rs6000_debug_reg_print (SPEFSCR_REGNO, SPEFSCR_REGNO, "spe_f");
1678 fprintf (stderr,
1679 "\n"
1680 "d reg_class = %s\n"
1681 "f reg_class = %s\n"
1682 "v reg_class = %s\n"
1683 "wa reg_class = %s\n"
1684 "wd reg_class = %s\n"
1685 "wf reg_class = %s\n"
1686 "ws reg_class = %s\n\n",
1687 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_d]],
1688 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_f]],
1689 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_v]],
1690 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wa]],
1691 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wd]],
1692 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wf]],
1693 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_ws]]);
1695 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1696 if (rs6000_vector_unit[m] || rs6000_vector_mem[m])
1698 nl = "\n";
1699 fprintf (stderr, "Vector mode: %-5s arithmetic: %-8s move: %-8s\n",
1700 GET_MODE_NAME (m),
1701 rs6000_debug_vector_unit[ rs6000_vector_unit[m] ],
1702 rs6000_debug_vector_unit[ rs6000_vector_mem[m] ]);
1705 if (nl)
1706 fputs (nl, stderr);
1708 switch (rs6000_sched_costly_dep)
1710 case max_dep_latency:
1711 costly_str = "max_dep_latency";
1712 break;
1714 case no_dep_costly:
1715 costly_str = "no_dep_costly";
1716 break;
1718 case all_deps_costly:
1719 costly_str = "all_deps_costly";
1720 break;
1722 case true_store_to_load_dep_costly:
1723 costly_str = "true_store_to_load_dep_costly";
1724 break;
1726 case store_to_load_dep_costly:
1727 costly_str = "store_to_load_dep_costly";
1728 break;
1730 default:
1731 costly_str = costly_num;
1732 sprintf (costly_num, "%d", (int)rs6000_sched_costly_dep);
1733 break;
1736 switch (rs6000_sched_insert_nops)
1738 case sched_finish_regroup_exact:
1739 nop_str = "sched_finish_regroup_exact";
1740 break;
1742 case sched_finish_pad_groups:
1743 nop_str = "sched_finish_pad_groups";
1744 break;
1746 case sched_finish_none:
1747 nop_str = "sched_finish_none";
1748 break;
1750 default:
1751 nop_str = nop_num;
1752 sprintf (nop_num, "%d", (int)rs6000_sched_insert_nops);
1753 break;
1756 fprintf (stderr,
1757 "always_hint = %s\n"
1758 "align_branch_targets = %s\n"
1759 "sched_restricted_insns_priority = %d\n"
1760 "sched_costly_dep = %s\n"
1761 "sched_insert_nops = %s\n\n",
1762 rs6000_always_hint ? "true" : "false",
1763 rs6000_align_branch_targets ? "true" : "false",
1764 (int)rs6000_sched_restricted_insns_priority,
1765 costly_str, nop_str);
1768 /* Initialize the various global tables that are based on register size. */
1769 static void
1770 rs6000_init_hard_regno_mode_ok (void)
1772 int r, m, c;
1773 int align64;
1774 int align32;
1776 /* Precalculate REGNO_REG_CLASS. */
1777 rs6000_regno_regclass[0] = GENERAL_REGS;
1778 for (r = 1; r < 32; ++r)
1779 rs6000_regno_regclass[r] = BASE_REGS;
1781 for (r = 32; r < 64; ++r)
1782 rs6000_regno_regclass[r] = FLOAT_REGS;
1784 for (r = 64; r < FIRST_PSEUDO_REGISTER; ++r)
1785 rs6000_regno_regclass[r] = NO_REGS;
1787 for (r = FIRST_ALTIVEC_REGNO; r <= LAST_ALTIVEC_REGNO; ++r)
1788 rs6000_regno_regclass[r] = ALTIVEC_REGS;
1790 rs6000_regno_regclass[CR0_REGNO] = CR0_REGS;
1791 for (r = CR1_REGNO; r <= CR7_REGNO; ++r)
1792 rs6000_regno_regclass[r] = CR_REGS;
1794 rs6000_regno_regclass[MQ_REGNO] = MQ_REGS;
1795 rs6000_regno_regclass[LR_REGNO] = LINK_REGS;
1796 rs6000_regno_regclass[CTR_REGNO] = CTR_REGS;
1797 rs6000_regno_regclass[XER_REGNO] = XER_REGS;
1798 rs6000_regno_regclass[VRSAVE_REGNO] = VRSAVE_REGS;
1799 rs6000_regno_regclass[VSCR_REGNO] = VRSAVE_REGS;
1800 rs6000_regno_regclass[SPE_ACC_REGNO] = SPE_ACC_REGS;
1801 rs6000_regno_regclass[SPEFSCR_REGNO] = SPEFSCR_REGS;
1802 rs6000_regno_regclass[ARG_POINTER_REGNUM] = BASE_REGS;
1803 rs6000_regno_regclass[FRAME_POINTER_REGNUM] = BASE_REGS;
1805 /* Precalculate vector information, this must be set up before the
1806 rs6000_hard_regno_nregs_internal below. */
1807 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1809 rs6000_vector_unit[m] = rs6000_vector_mem[m] = VECTOR_NONE;
1810 rs6000_vector_reload[m][0] = CODE_FOR_nothing;
1811 rs6000_vector_reload[m][1] = CODE_FOR_nothing;
1814 for (c = 0; c < (int)(int)RS6000_CONSTRAINT_MAX; c++)
1815 rs6000_constraints[c] = NO_REGS;
1817 /* The VSX hardware allows native alignment for vectors, but control whether the compiler
1818 believes it can use native alignment or still uses 128-bit alignment. */
1819 if (TARGET_VSX && !TARGET_VSX_ALIGN_128)
1821 align64 = 64;
1822 align32 = 32;
1824 else
1826 align64 = 128;
1827 align32 = 128;
1830 /* V2DF mode, VSX only. */
1831 if (TARGET_VSX)
1833 rs6000_vector_unit[V2DFmode] = VECTOR_VSX;
1834 rs6000_vector_mem[V2DFmode] = VECTOR_VSX;
1835 rs6000_vector_align[V2DFmode] = align64;
1838 /* V4SF mode, either VSX or Altivec. */
1839 if (TARGET_VSX)
1841 rs6000_vector_unit[V4SFmode] = VECTOR_VSX;
1842 rs6000_vector_mem[V4SFmode] = VECTOR_VSX;
1843 rs6000_vector_align[V4SFmode] = align32;
1845 else if (TARGET_ALTIVEC)
1847 rs6000_vector_unit[V4SFmode] = VECTOR_ALTIVEC;
1848 rs6000_vector_mem[V4SFmode] = VECTOR_ALTIVEC;
1849 rs6000_vector_align[V4SFmode] = align32;
1852 /* V16QImode, V8HImode, V4SImode are Altivec only, but possibly do VSX loads
1853 and stores. */
1854 if (TARGET_ALTIVEC)
1856 rs6000_vector_unit[V4SImode] = VECTOR_ALTIVEC;
1857 rs6000_vector_unit[V8HImode] = VECTOR_ALTIVEC;
1858 rs6000_vector_unit[V16QImode] = VECTOR_ALTIVEC;
1859 rs6000_vector_align[V4SImode] = align32;
1860 rs6000_vector_align[V8HImode] = align32;
1861 rs6000_vector_align[V16QImode] = align32;
1863 if (TARGET_VSX)
1865 rs6000_vector_mem[V4SImode] = VECTOR_VSX;
1866 rs6000_vector_mem[V8HImode] = VECTOR_VSX;
1867 rs6000_vector_mem[V16QImode] = VECTOR_VSX;
1869 else
1871 rs6000_vector_mem[V4SImode] = VECTOR_ALTIVEC;
1872 rs6000_vector_mem[V8HImode] = VECTOR_ALTIVEC;
1873 rs6000_vector_mem[V16QImode] = VECTOR_ALTIVEC;
1877 /* V2DImode, only allow under VSX, which can do V2DI insert/splat/extract.
1878 Altivec doesn't have 64-bit support. */
1879 if (TARGET_VSX)
1881 rs6000_vector_mem[V2DImode] = VECTOR_VSX;
1882 rs6000_vector_unit[V2DImode] = VECTOR_NONE;
1883 rs6000_vector_align[V2DImode] = align64;
1886 /* DFmode, see if we want to use the VSX unit. */
1887 if (TARGET_VSX && TARGET_VSX_SCALAR_DOUBLE)
1889 rs6000_vector_unit[DFmode] = VECTOR_VSX;
1890 rs6000_vector_mem[DFmode]
1891 = (TARGET_VSX_SCALAR_MEMORY ? VECTOR_VSX : VECTOR_NONE);
1892 rs6000_vector_align[DFmode] = align64;
1895 /* TODO add SPE and paired floating point vector support. */
1897 /* Register class constaints for the constraints that depend on compile
1898 switches. */
1899 if (TARGET_HARD_FLOAT && TARGET_FPRS)
1900 rs6000_constraints[RS6000_CONSTRAINT_f] = FLOAT_REGS;
1902 if (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
1903 rs6000_constraints[RS6000_CONSTRAINT_d] = FLOAT_REGS;
1905 if (TARGET_VSX)
1907 /* At present, we just use VSX_REGS, but we have different constraints
1908 based on the use, in case we want to fine tune the default register
1909 class used. wa = any VSX register, wf = register class to use for
1910 V4SF, wd = register class to use for V2DF, and ws = register classs to
1911 use for DF scalars. */
1912 rs6000_constraints[RS6000_CONSTRAINT_wa] = VSX_REGS;
1913 rs6000_constraints[RS6000_CONSTRAINT_wf] = VSX_REGS;
1914 rs6000_constraints[RS6000_CONSTRAINT_wd] = VSX_REGS;
1915 if (TARGET_VSX_SCALAR_DOUBLE)
1916 rs6000_constraints[RS6000_CONSTRAINT_ws] = VSX_REGS;
1919 if (TARGET_ALTIVEC)
1920 rs6000_constraints[RS6000_CONSTRAINT_v] = ALTIVEC_REGS;
1922 /* Set up the reload helper functions. */
1923 if (TARGET_VSX || TARGET_ALTIVEC)
1925 if (TARGET_64BIT)
1927 rs6000_vector_reload[V16QImode][0] = CODE_FOR_reload_v16qi_di_store;
1928 rs6000_vector_reload[V16QImode][1] = CODE_FOR_reload_v16qi_di_load;
1929 rs6000_vector_reload[V8HImode][0] = CODE_FOR_reload_v8hi_di_store;
1930 rs6000_vector_reload[V8HImode][1] = CODE_FOR_reload_v8hi_di_load;
1931 rs6000_vector_reload[V4SImode][0] = CODE_FOR_reload_v4si_di_store;
1932 rs6000_vector_reload[V4SImode][1] = CODE_FOR_reload_v4si_di_load;
1933 rs6000_vector_reload[V2DImode][0] = CODE_FOR_reload_v2di_di_store;
1934 rs6000_vector_reload[V2DImode][1] = CODE_FOR_reload_v2di_di_load;
1935 rs6000_vector_reload[V4SFmode][0] = CODE_FOR_reload_v4sf_di_store;
1936 rs6000_vector_reload[V4SFmode][1] = CODE_FOR_reload_v4sf_di_load;
1937 rs6000_vector_reload[V2DFmode][0] = CODE_FOR_reload_v2df_di_store;
1938 rs6000_vector_reload[V2DFmode][1] = CODE_FOR_reload_v2df_di_load;
1940 else
1942 rs6000_vector_reload[V16QImode][0] = CODE_FOR_reload_v16qi_si_store;
1943 rs6000_vector_reload[V16QImode][1] = CODE_FOR_reload_v16qi_si_load;
1944 rs6000_vector_reload[V8HImode][0] = CODE_FOR_reload_v8hi_si_store;
1945 rs6000_vector_reload[V8HImode][1] = CODE_FOR_reload_v8hi_si_load;
1946 rs6000_vector_reload[V4SImode][0] = CODE_FOR_reload_v4si_si_store;
1947 rs6000_vector_reload[V4SImode][1] = CODE_FOR_reload_v4si_si_load;
1948 rs6000_vector_reload[V2DImode][0] = CODE_FOR_reload_v2di_si_store;
1949 rs6000_vector_reload[V2DImode][1] = CODE_FOR_reload_v2di_si_load;
1950 rs6000_vector_reload[V4SFmode][0] = CODE_FOR_reload_v4sf_si_store;
1951 rs6000_vector_reload[V4SFmode][1] = CODE_FOR_reload_v4sf_si_load;
1952 rs6000_vector_reload[V2DFmode][0] = CODE_FOR_reload_v2df_si_store;
1953 rs6000_vector_reload[V2DFmode][1] = CODE_FOR_reload_v2df_si_load;
1957 /* Precalculate HARD_REGNO_NREGS. */
1958 for (r = 0; r < FIRST_PSEUDO_REGISTER; ++r)
1959 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1960 rs6000_hard_regno_nregs[m][r]
1961 = rs6000_hard_regno_nregs_internal (r, (enum machine_mode)m);
1963 /* Precalculate HARD_REGNO_MODE_OK. */
1964 for (r = 0; r < FIRST_PSEUDO_REGISTER; ++r)
1965 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1966 if (rs6000_hard_regno_mode_ok (r, (enum machine_mode)m))
1967 rs6000_hard_regno_mode_ok_p[m][r] = true;
1969 /* Precalculate CLASS_MAX_NREGS sizes. */
1970 for (c = 0; c < LIM_REG_CLASSES; ++c)
1972 int reg_size;
1974 if (TARGET_VSX && VSX_REG_CLASS_P (c))
1975 reg_size = UNITS_PER_VSX_WORD;
1977 else if (c == ALTIVEC_REGS)
1978 reg_size = UNITS_PER_ALTIVEC_WORD;
1980 else if (c == FLOAT_REGS)
1981 reg_size = UNITS_PER_FP_WORD;
1983 else
1984 reg_size = UNITS_PER_WORD;
1986 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1987 rs6000_class_max_nregs[m][c]
1988 = (GET_MODE_SIZE (m) + reg_size - 1) / reg_size;
1991 if (TARGET_E500_DOUBLE)
1992 rs6000_class_max_nregs[DFmode][GENERAL_REGS] = 1;
1994 if (TARGET_DEBUG_REG)
1995 rs6000_debug_reg_global ();
1998 #if TARGET_MACHO
1999 /* The Darwin version of SUBTARGET_OVERRIDE_OPTIONS. */
2001 static void
2002 darwin_rs6000_override_options (void)
2004 /* The Darwin ABI always includes AltiVec, can't be (validly) turned
2005 off. */
2006 rs6000_altivec_abi = 1;
2007 TARGET_ALTIVEC_VRSAVE = 1;
2008 if (DEFAULT_ABI == ABI_DARWIN)
2010 if (MACHO_DYNAMIC_NO_PIC_P)
2012 if (flag_pic)
2013 warning (0, "-mdynamic-no-pic overrides -fpic or -fPIC");
2014 flag_pic = 0;
2016 else if (flag_pic == 1)
2018 flag_pic = 2;
2021 if (TARGET_64BIT && ! TARGET_POWERPC64)
2023 target_flags |= MASK_POWERPC64;
2024 warning (0, "-m64 requires PowerPC64 architecture, enabling");
2026 if (flag_mkernel)
2028 rs6000_default_long_calls = 1;
2029 target_flags |= MASK_SOFT_FLOAT;
2032 /* Make -m64 imply -maltivec. Darwin's 64-bit ABI includes
2033 Altivec. */
2034 if (!flag_mkernel && !flag_apple_kext
2035 && TARGET_64BIT
2036 && ! (target_flags_explicit & MASK_ALTIVEC))
2037 target_flags |= MASK_ALTIVEC;
2039 /* Unless the user (not the configurer) has explicitly overridden
2040 it with -mcpu=G3 or -mno-altivec, then 10.5+ targets default to
2041 G4 unless targetting the kernel. */
2042 if (!flag_mkernel
2043 && !flag_apple_kext
2044 && strverscmp (darwin_macosx_version_min, "10.5") >= 0
2045 && ! (target_flags_explicit & MASK_ALTIVEC)
2046 && ! rs6000_select[1].string)
2048 target_flags |= MASK_ALTIVEC;
2051 #endif
2053 /* If not otherwise specified by a target, make 'long double' equivalent to
2054 'double'. */
2056 #ifndef RS6000_DEFAULT_LONG_DOUBLE_SIZE
2057 #define RS6000_DEFAULT_LONG_DOUBLE_SIZE 64
2058 #endif
2060 /* Override command line options. Mostly we process the processor
2061 type and sometimes adjust other TARGET_ options. */
2063 void
2064 rs6000_override_options (const char *default_cpu)
2066 size_t i, j;
2067 struct rs6000_cpu_select *ptr;
2068 int set_masks;
2070 /* Simplifications for entries below. */
2072 enum {
2073 POWERPC_BASE_MASK = MASK_POWERPC | MASK_NEW_MNEMONICS,
2074 POWERPC_7400_MASK = POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_ALTIVEC
2077 /* This table occasionally claims that a processor does not support
2078 a particular feature even though it does, but the feature is slower
2079 than the alternative. Thus, it shouldn't be relied on as a
2080 complete description of the processor's support.
2082 Please keep this list in order, and don't forget to update the
2083 documentation in invoke.texi when adding a new processor or
2084 flag. */
2085 static struct ptt
2087 const char *const name; /* Canonical processor name. */
2088 const enum processor_type processor; /* Processor type enum value. */
2089 const int target_enable; /* Target flags to enable. */
2090 } const processor_target_table[]
2091 = {{"401", PROCESSOR_PPC403, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2092 {"403", PROCESSOR_PPC403,
2093 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_STRICT_ALIGN},
2094 {"405", PROCESSOR_PPC405,
2095 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
2096 {"405fp", PROCESSOR_PPC405,
2097 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
2098 {"440", PROCESSOR_PPC440,
2099 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
2100 {"440fp", PROCESSOR_PPC440,
2101 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
2102 {"464", PROCESSOR_PPC440,
2103 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
2104 {"464fp", PROCESSOR_PPC440,
2105 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
2106 {"505", PROCESSOR_MPCCORE, POWERPC_BASE_MASK},
2107 {"601", PROCESSOR_PPC601,
2108 MASK_POWER | POWERPC_BASE_MASK | MASK_MULTIPLE | MASK_STRING},
2109 {"602", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2110 {"603", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2111 {"603e", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2112 {"604", PROCESSOR_PPC604, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2113 {"604e", PROCESSOR_PPC604e, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2114 {"620", PROCESSOR_PPC620,
2115 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
2116 {"630", PROCESSOR_PPC630,
2117 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
2118 {"740", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2119 {"7400", PROCESSOR_PPC7400, POWERPC_7400_MASK},
2120 {"7450", PROCESSOR_PPC7450, POWERPC_7400_MASK},
2121 {"750", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2122 {"801", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2123 {"821", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2124 {"823", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2125 {"8540", PROCESSOR_PPC8540, POWERPC_BASE_MASK | MASK_STRICT_ALIGN
2126 | MASK_ISEL},
2127 /* 8548 has a dummy entry for now. */
2128 {"8548", PROCESSOR_PPC8540, POWERPC_BASE_MASK | MASK_STRICT_ALIGN
2129 | MASK_ISEL},
2130 {"e300c2", PROCESSOR_PPCE300C2, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2131 {"e300c3", PROCESSOR_PPCE300C3, POWERPC_BASE_MASK},
2132 {"e500mc", PROCESSOR_PPCE500MC, POWERPC_BASE_MASK | MASK_PPC_GFXOPT
2133 | MASK_ISEL},
2134 {"860", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2135 {"970", PROCESSOR_POWER4,
2136 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
2137 {"cell", PROCESSOR_CELL,
2138 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
2139 {"common", PROCESSOR_COMMON, MASK_NEW_MNEMONICS},
2140 {"ec603e", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2141 {"G3", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2142 {"G4", PROCESSOR_PPC7450, POWERPC_7400_MASK},
2143 {"G5", PROCESSOR_POWER4,
2144 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
2145 {"power", PROCESSOR_POWER, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2146 {"power2", PROCESSOR_POWER,
2147 MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING},
2148 {"power3", PROCESSOR_PPC630,
2149 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
2150 {"power4", PROCESSOR_POWER4,
2151 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2152 | MASK_MFCRF},
2153 {"power5", PROCESSOR_POWER5,
2154 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2155 | MASK_MFCRF | MASK_POPCNTB},
2156 {"power5+", PROCESSOR_POWER5,
2157 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2158 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND},
2159 {"power6", PROCESSOR_POWER6,
2160 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2161 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP},
2162 {"power6x", PROCESSOR_POWER6,
2163 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2164 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP
2165 | MASK_MFPGPR},
2166 {"power7", PROCESSOR_POWER7,
2167 POWERPC_7400_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_MFCRF
2168 | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP | MASK_POPCNTD
2169 | MASK_VSX}, /* Don't add MASK_ISEL by default */
2170 {"powerpc", PROCESSOR_POWERPC, POWERPC_BASE_MASK},
2171 {"powerpc64", PROCESSOR_POWERPC64,
2172 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
2173 {"rios", PROCESSOR_RIOS1, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2174 {"rios1", PROCESSOR_RIOS1, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2175 {"rios2", PROCESSOR_RIOS2,
2176 MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING},
2177 {"rsc", PROCESSOR_PPC601, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2178 {"rsc1", PROCESSOR_PPC601, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2179 {"rs64", PROCESSOR_RS64A,
2180 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64}
2183 const size_t ptt_size = ARRAY_SIZE (processor_target_table);
2185 /* Some OSs don't support saving the high part of 64-bit registers on
2186 context switch. Other OSs don't support saving Altivec registers.
2187 On those OSs, we don't touch the MASK_POWERPC64 or MASK_ALTIVEC
2188 settings; if the user wants either, the user must explicitly specify
2189 them and we won't interfere with the user's specification. */
2191 enum {
2192 POWER_MASKS = MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING,
2193 POWERPC_MASKS = (POWERPC_BASE_MASK | MASK_PPC_GPOPT | MASK_STRICT_ALIGN
2194 | MASK_PPC_GFXOPT | MASK_POWERPC64 | MASK_ALTIVEC
2195 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_MULHW
2196 | MASK_DLMZB | MASK_CMPB | MASK_MFPGPR | MASK_DFP
2197 | MASK_POPCNTD | MASK_VSX | MASK_ISEL)
2200 /* Set the pointer size. */
2201 if (TARGET_64BIT)
2203 rs6000_pmode = (int)DImode;
2204 rs6000_pointer_size = 64;
2206 else
2208 rs6000_pmode = (int)SImode;
2209 rs6000_pointer_size = 32;
2212 set_masks = POWER_MASKS | POWERPC_MASKS | MASK_SOFT_FLOAT;
2213 #ifdef OS_MISSING_POWERPC64
2214 if (OS_MISSING_POWERPC64)
2215 set_masks &= ~MASK_POWERPC64;
2216 #endif
2217 #ifdef OS_MISSING_ALTIVEC
2218 if (OS_MISSING_ALTIVEC)
2219 set_masks &= ~MASK_ALTIVEC;
2220 #endif
2222 /* Don't override by the processor default if given explicitly. */
2223 set_masks &= ~target_flags_explicit;
2225 /* Identify the processor type. */
2226 rs6000_select[0].string = default_cpu;
2227 rs6000_cpu = TARGET_POWERPC64 ? PROCESSOR_DEFAULT64 : PROCESSOR_DEFAULT;
2229 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
2231 ptr = &rs6000_select[i];
2232 if (ptr->string != (char *)0 && ptr->string[0] != '\0')
2234 for (j = 0; j < ptt_size; j++)
2235 if (! strcmp (ptr->string, processor_target_table[j].name))
2237 if (ptr->set_tune_p)
2238 rs6000_cpu = processor_target_table[j].processor;
2240 if (ptr->set_arch_p)
2242 target_flags &= ~set_masks;
2243 target_flags |= (processor_target_table[j].target_enable
2244 & set_masks);
2246 break;
2249 if (j == ptt_size)
2250 error ("bad value (%s) for %s switch", ptr->string, ptr->name);
2254 if (rs6000_cpu == PROCESSOR_PPCE300C2 || rs6000_cpu == PROCESSOR_PPCE300C3
2255 || rs6000_cpu == PROCESSOR_PPCE500MC)
2257 if (TARGET_ALTIVEC)
2258 error ("AltiVec not supported in this target");
2259 if (TARGET_SPE)
2260 error ("Spe not supported in this target");
2263 /* Disable Cell microcode if we are optimizing for the Cell
2264 and not optimizing for size. */
2265 if (rs6000_gen_cell_microcode == -1)
2266 rs6000_gen_cell_microcode = !(rs6000_cpu == PROCESSOR_CELL
2267 && !optimize_size);
2269 /* If we are optimizing big endian systems for space, use the load/store
2270 multiple and string instructions unless we are not generating
2271 Cell microcode. */
2272 if (BYTES_BIG_ENDIAN && optimize_size && !rs6000_gen_cell_microcode)
2273 target_flags |= ~target_flags_explicit & (MASK_MULTIPLE | MASK_STRING);
2275 /* Don't allow -mmultiple or -mstring on little endian systems
2276 unless the cpu is a 750, because the hardware doesn't support the
2277 instructions used in little endian mode, and causes an alignment
2278 trap. The 750 does not cause an alignment trap (except when the
2279 target is unaligned). */
2281 if (!BYTES_BIG_ENDIAN && rs6000_cpu != PROCESSOR_PPC750)
2283 if (TARGET_MULTIPLE)
2285 target_flags &= ~MASK_MULTIPLE;
2286 if ((target_flags_explicit & MASK_MULTIPLE) != 0)
2287 warning (0, "-mmultiple is not supported on little endian systems");
2290 if (TARGET_STRING)
2292 target_flags &= ~MASK_STRING;
2293 if ((target_flags_explicit & MASK_STRING) != 0)
2294 warning (0, "-mstring is not supported on little endian systems");
2298 /* Add some warnings for VSX. Enable -maltivec unless the user explicitly
2299 used -mno-altivec */
2300 if (TARGET_VSX)
2302 const char *msg = NULL;
2303 if (!TARGET_HARD_FLOAT || !TARGET_FPRS
2304 || !TARGET_SINGLE_FLOAT || !TARGET_DOUBLE_FLOAT)
2306 if (target_flags_explicit & MASK_VSX)
2307 msg = N_("-mvsx requires hardware floating point");
2308 else
2309 target_flags &= ~ MASK_VSX;
2311 else if (TARGET_PAIRED_FLOAT)
2312 msg = N_("-mvsx and -mpaired are incompatible");
2313 /* The hardware will allow VSX and little endian, but until we make sure
2314 things like vector select, etc. work don't allow VSX on little endian
2315 systems at this point. */
2316 else if (!BYTES_BIG_ENDIAN)
2317 msg = N_("-mvsx used with little endian code");
2318 else if (TARGET_AVOID_XFORM > 0)
2319 msg = N_("-mvsx needs indexed addressing");
2321 if (msg)
2323 warning (0, msg);
2324 target_flags &= ~ MASK_VSX;
2326 else if (TARGET_VSX && !TARGET_ALTIVEC
2327 && (target_flags_explicit & MASK_ALTIVEC) == 0)
2328 target_flags |= MASK_ALTIVEC;
2331 /* Set debug flags */
2332 if (rs6000_debug_name)
2334 if (! strcmp (rs6000_debug_name, "all"))
2335 rs6000_debug_stack = rs6000_debug_arg = rs6000_debug_reg
2336 = rs6000_debug_addr = rs6000_debug_cost = 1;
2337 else if (! strcmp (rs6000_debug_name, "stack"))
2338 rs6000_debug_stack = 1;
2339 else if (! strcmp (rs6000_debug_name, "arg"))
2340 rs6000_debug_arg = 1;
2341 else if (! strcmp (rs6000_debug_name, "reg"))
2342 rs6000_debug_reg = 1;
2343 else if (! strcmp (rs6000_debug_name, "addr"))
2344 rs6000_debug_addr = 1;
2345 else if (! strcmp (rs6000_debug_name, "cost"))
2346 rs6000_debug_cost = 1;
2347 else
2348 error ("unknown -mdebug-%s switch", rs6000_debug_name);
2350 /* If the appropriate debug option is enabled, replace the target hooks
2351 with debug versions that call the real version and then prints
2352 debugging information. */
2353 if (TARGET_DEBUG_COST)
2355 targetm.rtx_costs = rs6000_debug_rtx_costs;
2356 targetm.address_cost = rs6000_debug_address_cost;
2357 targetm.sched.adjust_cost = rs6000_debug_adjust_cost;
2360 if (TARGET_DEBUG_ADDR)
2362 targetm.legitimate_address_p = rs6000_debug_legitimate_address_p;
2363 targetm.legitimize_address = rs6000_debug_legitimize_address;
2364 rs6000_secondary_reload_class_ptr
2365 = rs6000_debug_secondary_reload_class;
2366 rs6000_secondary_memory_needed_ptr
2367 = rs6000_debug_secondary_memory_needed;
2368 rs6000_cannot_change_mode_class_ptr
2369 = rs6000_debug_cannot_change_mode_class;
2370 rs6000_preferred_reload_class_ptr
2371 = rs6000_debug_preferred_reload_class;
2372 rs6000_legitimize_reload_address_ptr
2373 = rs6000_debug_legitimize_reload_address;
2374 rs6000_mode_dependent_address_ptr
2375 = rs6000_debug_mode_dependent_address;
2379 if (rs6000_traceback_name)
2381 if (! strncmp (rs6000_traceback_name, "full", 4))
2382 rs6000_traceback = traceback_full;
2383 else if (! strncmp (rs6000_traceback_name, "part", 4))
2384 rs6000_traceback = traceback_part;
2385 else if (! strncmp (rs6000_traceback_name, "no", 2))
2386 rs6000_traceback = traceback_none;
2387 else
2388 error ("unknown -mtraceback arg %qs; expecting %<full%>, %<partial%> or %<none%>",
2389 rs6000_traceback_name);
2392 if (!rs6000_explicit_options.long_double)
2393 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
2395 #ifndef POWERPC_LINUX
2396 if (!rs6000_explicit_options.ieee)
2397 rs6000_ieeequad = 1;
2398 #endif
2400 /* Enable Altivec ABI for AIX -maltivec. */
2401 if (TARGET_XCOFF && (TARGET_ALTIVEC || TARGET_VSX))
2402 rs6000_altivec_abi = 1;
2404 /* The AltiVec ABI is the default for PowerPC-64 GNU/Linux. For
2405 PowerPC-32 GNU/Linux, -maltivec implies the AltiVec ABI. It can
2406 be explicitly overridden in either case. */
2407 if (TARGET_ELF)
2409 if (!rs6000_explicit_options.altivec_abi
2410 && (TARGET_64BIT || TARGET_ALTIVEC || TARGET_VSX))
2411 rs6000_altivec_abi = 1;
2413 /* Enable VRSAVE for AltiVec ABI, unless explicitly overridden. */
2414 if (!rs6000_explicit_options.vrsave)
2415 TARGET_ALTIVEC_VRSAVE = rs6000_altivec_abi;
2418 /* Set the Darwin64 ABI as default for 64-bit Darwin. */
2419 if (DEFAULT_ABI == ABI_DARWIN && TARGET_64BIT)
2421 rs6000_darwin64_abi = 1;
2422 #if TARGET_MACHO
2423 darwin_one_byte_bool = 1;
2424 #endif
2425 /* Default to natural alignment, for better performance. */
2426 rs6000_alignment_flags = MASK_ALIGN_NATURAL;
2429 /* Place FP constants in the constant pool instead of TOC
2430 if section anchors enabled. */
2431 if (flag_section_anchors)
2432 TARGET_NO_FP_IN_TOC = 1;
2434 /* Handle -mtls-size option. */
2435 rs6000_parse_tls_size_option ();
2437 #ifdef SUBTARGET_OVERRIDE_OPTIONS
2438 SUBTARGET_OVERRIDE_OPTIONS;
2439 #endif
2440 #ifdef SUBSUBTARGET_OVERRIDE_OPTIONS
2441 SUBSUBTARGET_OVERRIDE_OPTIONS;
2442 #endif
2443 #ifdef SUB3TARGET_OVERRIDE_OPTIONS
2444 SUB3TARGET_OVERRIDE_OPTIONS;
2445 #endif
2447 if (TARGET_E500 || rs6000_cpu == PROCESSOR_PPCE500MC)
2449 /* The e500 and e500mc do not have string instructions, and we set
2450 MASK_STRING above when optimizing for size. */
2451 if ((target_flags & MASK_STRING) != 0)
2452 target_flags = target_flags & ~MASK_STRING;
2454 else if (rs6000_select[1].string != NULL)
2456 /* For the powerpc-eabispe configuration, we set all these by
2457 default, so let's unset them if we manually set another
2458 CPU that is not the E500. */
2459 if (!rs6000_explicit_options.spe_abi)
2460 rs6000_spe_abi = 0;
2461 if (!rs6000_explicit_options.spe)
2462 rs6000_spe = 0;
2463 if (!rs6000_explicit_options.float_gprs)
2464 rs6000_float_gprs = 0;
2465 if (!(target_flags_explicit & MASK_ISEL))
2466 target_flags &= ~MASK_ISEL;
2469 /* Detect invalid option combinations with E500. */
2470 CHECK_E500_OPTIONS;
2472 rs6000_always_hint = (rs6000_cpu != PROCESSOR_POWER4
2473 && rs6000_cpu != PROCESSOR_POWER5
2474 && rs6000_cpu != PROCESSOR_POWER6
2475 && rs6000_cpu != PROCESSOR_POWER7
2476 && rs6000_cpu != PROCESSOR_CELL);
2477 rs6000_sched_groups = (rs6000_cpu == PROCESSOR_POWER4
2478 || rs6000_cpu == PROCESSOR_POWER5
2479 || rs6000_cpu == PROCESSOR_POWER7);
2480 rs6000_align_branch_targets = (rs6000_cpu == PROCESSOR_POWER4
2481 || rs6000_cpu == PROCESSOR_POWER5
2482 || rs6000_cpu == PROCESSOR_POWER6
2483 || rs6000_cpu == PROCESSOR_POWER7);
2485 /* Allow debug switches to override the above settings. */
2486 if (TARGET_ALWAYS_HINT > 0)
2487 rs6000_always_hint = TARGET_ALWAYS_HINT;
2489 if (TARGET_SCHED_GROUPS > 0)
2490 rs6000_sched_groups = TARGET_SCHED_GROUPS;
2492 if (TARGET_ALIGN_BRANCH_TARGETS > 0)
2493 rs6000_align_branch_targets = TARGET_ALIGN_BRANCH_TARGETS;
2495 rs6000_sched_restricted_insns_priority
2496 = (rs6000_sched_groups ? 1 : 0);
2498 /* Handle -msched-costly-dep option. */
2499 rs6000_sched_costly_dep
2500 = (rs6000_sched_groups ? store_to_load_dep_costly : no_dep_costly);
2502 if (rs6000_sched_costly_dep_str)
2504 if (! strcmp (rs6000_sched_costly_dep_str, "no"))
2505 rs6000_sched_costly_dep = no_dep_costly;
2506 else if (! strcmp (rs6000_sched_costly_dep_str, "all"))
2507 rs6000_sched_costly_dep = all_deps_costly;
2508 else if (! strcmp (rs6000_sched_costly_dep_str, "true_store_to_load"))
2509 rs6000_sched_costly_dep = true_store_to_load_dep_costly;
2510 else if (! strcmp (rs6000_sched_costly_dep_str, "store_to_load"))
2511 rs6000_sched_costly_dep = store_to_load_dep_costly;
2512 else
2513 rs6000_sched_costly_dep = ((enum rs6000_dependence_cost)
2514 atoi (rs6000_sched_costly_dep_str));
2517 /* Handle -minsert-sched-nops option. */
2518 rs6000_sched_insert_nops
2519 = (rs6000_sched_groups ? sched_finish_regroup_exact : sched_finish_none);
2521 if (rs6000_sched_insert_nops_str)
2523 if (! strcmp (rs6000_sched_insert_nops_str, "no"))
2524 rs6000_sched_insert_nops = sched_finish_none;
2525 else if (! strcmp (rs6000_sched_insert_nops_str, "pad"))
2526 rs6000_sched_insert_nops = sched_finish_pad_groups;
2527 else if (! strcmp (rs6000_sched_insert_nops_str, "regroup_exact"))
2528 rs6000_sched_insert_nops = sched_finish_regroup_exact;
2529 else
2530 rs6000_sched_insert_nops = ((enum rs6000_nop_insertion)
2531 atoi (rs6000_sched_insert_nops_str));
2534 #ifdef TARGET_REGNAMES
2535 /* If the user desires alternate register names, copy in the
2536 alternate names now. */
2537 if (TARGET_REGNAMES)
2538 memcpy (rs6000_reg_names, alt_reg_names, sizeof (rs6000_reg_names));
2539 #endif
2541 /* Set aix_struct_return last, after the ABI is determined.
2542 If -maix-struct-return or -msvr4-struct-return was explicitly
2543 used, don't override with the ABI default. */
2544 if (!rs6000_explicit_options.aix_struct_ret)
2545 aix_struct_return = (DEFAULT_ABI != ABI_V4 || DRAFT_V4_STRUCT_RET);
2547 if (TARGET_LONG_DOUBLE_128 && !TARGET_IEEEQUAD)
2548 REAL_MODE_FORMAT (TFmode) = &ibm_extended_format;
2550 if (TARGET_TOC)
2551 ASM_GENERATE_INTERNAL_LABEL (toc_label_name, "LCTOC", 1);
2553 /* We can only guarantee the availability of DI pseudo-ops when
2554 assembling for 64-bit targets. */
2555 if (!TARGET_64BIT)
2557 targetm.asm_out.aligned_op.di = NULL;
2558 targetm.asm_out.unaligned_op.di = NULL;
2561 /* Set branch target alignment, if not optimizing for size. */
2562 if (!optimize_size)
2564 /* Cell wants to be aligned 8byte for dual issue. */
2565 if (rs6000_cpu == PROCESSOR_CELL)
2567 if (align_functions <= 0)
2568 align_functions = 8;
2569 if (align_jumps <= 0)
2570 align_jumps = 8;
2571 if (align_loops <= 0)
2572 align_loops = 8;
2574 if (rs6000_align_branch_targets)
2576 if (align_functions <= 0)
2577 align_functions = 16;
2578 if (align_jumps <= 0)
2579 align_jumps = 16;
2580 if (align_loops <= 0)
2581 align_loops = 16;
2583 if (align_jumps_max_skip <= 0)
2584 align_jumps_max_skip = 15;
2585 if (align_loops_max_skip <= 0)
2586 align_loops_max_skip = 15;
2589 /* Arrange to save and restore machine status around nested functions. */
2590 init_machine_status = rs6000_init_machine_status;
2592 /* We should always be splitting complex arguments, but we can't break
2593 Linux and Darwin ABIs at the moment. For now, only AIX is fixed. */
2594 if (DEFAULT_ABI != ABI_AIX)
2595 targetm.calls.split_complex_arg = NULL;
2597 /* Initialize rs6000_cost with the appropriate target costs. */
2598 if (optimize_size)
2599 rs6000_cost = TARGET_POWERPC64 ? &size64_cost : &size32_cost;
2600 else
2601 switch (rs6000_cpu)
2603 case PROCESSOR_RIOS1:
2604 rs6000_cost = &rios1_cost;
2605 break;
2607 case PROCESSOR_RIOS2:
2608 rs6000_cost = &rios2_cost;
2609 break;
2611 case PROCESSOR_RS64A:
2612 rs6000_cost = &rs64a_cost;
2613 break;
2615 case PROCESSOR_MPCCORE:
2616 rs6000_cost = &mpccore_cost;
2617 break;
2619 case PROCESSOR_PPC403:
2620 rs6000_cost = &ppc403_cost;
2621 break;
2623 case PROCESSOR_PPC405:
2624 rs6000_cost = &ppc405_cost;
2625 break;
2627 case PROCESSOR_PPC440:
2628 rs6000_cost = &ppc440_cost;
2629 break;
2631 case PROCESSOR_PPC601:
2632 rs6000_cost = &ppc601_cost;
2633 break;
2635 case PROCESSOR_PPC603:
2636 rs6000_cost = &ppc603_cost;
2637 break;
2639 case PROCESSOR_PPC604:
2640 rs6000_cost = &ppc604_cost;
2641 break;
2643 case PROCESSOR_PPC604e:
2644 rs6000_cost = &ppc604e_cost;
2645 break;
2647 case PROCESSOR_PPC620:
2648 rs6000_cost = &ppc620_cost;
2649 break;
2651 case PROCESSOR_PPC630:
2652 rs6000_cost = &ppc630_cost;
2653 break;
2655 case PROCESSOR_CELL:
2656 rs6000_cost = &ppccell_cost;
2657 break;
2659 case PROCESSOR_PPC750:
2660 case PROCESSOR_PPC7400:
2661 rs6000_cost = &ppc750_cost;
2662 break;
2664 case PROCESSOR_PPC7450:
2665 rs6000_cost = &ppc7450_cost;
2666 break;
2668 case PROCESSOR_PPC8540:
2669 rs6000_cost = &ppc8540_cost;
2670 break;
2672 case PROCESSOR_PPCE300C2:
2673 case PROCESSOR_PPCE300C3:
2674 rs6000_cost = &ppce300c2c3_cost;
2675 break;
2677 case PROCESSOR_PPCE500MC:
2678 rs6000_cost = &ppce500mc_cost;
2679 break;
2681 case PROCESSOR_POWER4:
2682 case PROCESSOR_POWER5:
2683 rs6000_cost = &power4_cost;
2684 break;
2686 case PROCESSOR_POWER6:
2687 rs6000_cost = &power6_cost;
2688 break;
2690 case PROCESSOR_POWER7:
2691 rs6000_cost = &power7_cost;
2692 break;
2694 default:
2695 gcc_unreachable ();
2698 if (!PARAM_SET_P (PARAM_SIMULTANEOUS_PREFETCHES))
2699 set_param_value ("simultaneous-prefetches",
2700 rs6000_cost->simultaneous_prefetches);
2701 if (!PARAM_SET_P (PARAM_L1_CACHE_SIZE))
2702 set_param_value ("l1-cache-size", rs6000_cost->l1_cache_size);
2703 if (!PARAM_SET_P (PARAM_L1_CACHE_LINE_SIZE))
2704 set_param_value ("l1-cache-line-size", rs6000_cost->cache_line_size);
2705 if (!PARAM_SET_P (PARAM_L2_CACHE_SIZE))
2706 set_param_value ("l2-cache-size", rs6000_cost->l2_cache_size);
2708 /* If using typedef char *va_list, signal that __builtin_va_start (&ap, 0)
2709 can be optimized to ap = __builtin_next_arg (0). */
2710 if (DEFAULT_ABI != ABI_V4)
2711 targetm.expand_builtin_va_start = NULL;
2713 /* Set up single/double float flags.
2714 If TARGET_HARD_FLOAT is set, but neither single or double is set,
2715 then set both flags. */
2716 if (TARGET_HARD_FLOAT && TARGET_FPRS
2717 && rs6000_single_float == 0 && rs6000_double_float == 0)
2718 rs6000_single_float = rs6000_double_float = 1;
2720 /* Reset single and double FP flags if target is E500. */
2721 if (TARGET_E500)
2723 rs6000_single_float = rs6000_double_float = 0;
2724 if (TARGET_E500_SINGLE)
2725 rs6000_single_float = 1;
2726 if (TARGET_E500_DOUBLE)
2727 rs6000_single_float = rs6000_double_float = 1;
2730 /* If not explicitly specified via option, decide whether to generate indexed
2731 load/store instructions. */
2732 if (TARGET_AVOID_XFORM == -1)
2733 /* Avoid indexed addressing when targeting Power6 in order to avoid
2734 the DERAT mispredict penalty. */
2735 TARGET_AVOID_XFORM = (rs6000_cpu == PROCESSOR_POWER6 && TARGET_CMPB);
2737 rs6000_init_hard_regno_mode_ok ();
2740 /* Implement targetm.vectorize.builtin_mask_for_load. */
2741 static tree
2742 rs6000_builtin_mask_for_load (void)
2744 if (TARGET_ALTIVEC || TARGET_VSX)
2745 return altivec_builtin_mask_for_load;
2746 else
2747 return 0;
2750 /* Implement targetm.vectorize.builtin_conversion.
2751 Returns a decl of a function that implements conversion of an integer vector
2752 into a floating-point vector, or vice-versa. TYPE is the type of the integer
2753 side of the conversion.
2754 Return NULL_TREE if it is not available. */
2755 static tree
2756 rs6000_builtin_conversion (unsigned int tcode, tree type)
2758 enum tree_code code = (enum tree_code) tcode;
2760 switch (code)
2762 case FIX_TRUNC_EXPR:
2763 switch (TYPE_MODE (type))
2765 case V2DImode:
2766 if (!VECTOR_UNIT_VSX_P (V2DFmode))
2767 return NULL_TREE;
2769 return TYPE_UNSIGNED (type)
2770 ? rs6000_builtin_decls[VSX_BUILTIN_XVCVDPUXDS_UNS]
2771 : rs6000_builtin_decls[VSX_BUILTIN_XVCVDPSXDS];
2773 case V4SImode:
2774 if (VECTOR_UNIT_NONE_P (V4SImode) || VECTOR_UNIT_NONE_P (V4SFmode))
2775 return NULL_TREE;
2777 return TYPE_UNSIGNED (type)
2778 ? rs6000_builtin_decls[VECTOR_BUILTIN_FIXUNS_V4SF_V4SI]
2779 : rs6000_builtin_decls[VECTOR_BUILTIN_FIX_V4SF_V4SI];
2781 default:
2782 return NULL_TREE;
2785 case FLOAT_EXPR:
2786 switch (TYPE_MODE (type))
2788 case V2DImode:
2789 if (!VECTOR_UNIT_VSX_P (V2DFmode))
2790 return NULL_TREE;
2792 return TYPE_UNSIGNED (type)
2793 ? rs6000_builtin_decls[VSX_BUILTIN_XVCVUXDDP]
2794 : rs6000_builtin_decls[VSX_BUILTIN_XVCVSXDDP];
2796 case V4SImode:
2797 if (VECTOR_UNIT_NONE_P (V4SImode) || VECTOR_UNIT_NONE_P (V4SFmode))
2798 return NULL_TREE;
2800 return TYPE_UNSIGNED (type)
2801 ? rs6000_builtin_decls[VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF]
2802 : rs6000_builtin_decls[VECTOR_BUILTIN_FLOAT_V4SI_V4SF];
2804 default:
2805 return NULL_TREE;
2808 default:
2809 return NULL_TREE;
2813 /* Implement targetm.vectorize.builtin_mul_widen_even. */
2814 static tree
2815 rs6000_builtin_mul_widen_even (tree type)
2817 if (!TARGET_ALTIVEC)
2818 return NULL_TREE;
2820 switch (TYPE_MODE (type))
2822 case V8HImode:
2823 return TYPE_UNSIGNED (type)
2824 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULEUH_UNS]
2825 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULESH];
2827 case V16QImode:
2828 return TYPE_UNSIGNED (type)
2829 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULEUB_UNS]
2830 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULESB];
2831 default:
2832 return NULL_TREE;
2836 /* Implement targetm.vectorize.builtin_mul_widen_odd. */
2837 static tree
2838 rs6000_builtin_mul_widen_odd (tree type)
2840 if (!TARGET_ALTIVEC)
2841 return NULL_TREE;
2843 switch (TYPE_MODE (type))
2845 case V8HImode:
2846 return TYPE_UNSIGNED (type)
2847 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOUH_UNS]
2848 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOSH];
2850 case V16QImode:
2851 return TYPE_UNSIGNED (type)
2852 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOUB_UNS]
2853 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOSB];
2854 default:
2855 return NULL_TREE;
2860 /* Return true iff, data reference of TYPE can reach vector alignment (16)
2861 after applying N number of iterations. This routine does not determine
2862 how may iterations are required to reach desired alignment. */
2864 static bool
2865 rs6000_vector_alignment_reachable (const_tree type ATTRIBUTE_UNUSED, bool is_packed)
2867 if (is_packed)
2868 return false;
2870 if (TARGET_32BIT)
2872 if (rs6000_alignment_flags == MASK_ALIGN_NATURAL)
2873 return true;
2875 if (rs6000_alignment_flags == MASK_ALIGN_POWER)
2876 return true;
2878 return false;
2880 else
2882 if (TARGET_MACHO)
2883 return false;
2885 /* Assuming that all other types are naturally aligned. CHECKME! */
2886 return true;
2890 /* Implement targetm.vectorize.builtin_vec_perm. */
2891 tree
2892 rs6000_builtin_vec_perm (tree type, tree *mask_element_type)
2894 tree inner_type = TREE_TYPE (type);
2895 bool uns_p = TYPE_UNSIGNED (inner_type);
2896 tree d;
2898 *mask_element_type = unsigned_char_type_node;
2900 switch (TYPE_MODE (type))
2902 case V16QImode:
2903 d = (uns_p
2904 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_16QI_UNS]
2905 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_16QI]);
2906 break;
2908 case V8HImode:
2909 d = (uns_p
2910 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_8HI_UNS]
2911 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_8HI]);
2912 break;
2914 case V4SImode:
2915 d = (uns_p
2916 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SI_UNS]
2917 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SI]);
2918 break;
2920 case V4SFmode:
2921 d = rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SF];
2922 break;
2924 case V2DFmode:
2925 if (!TARGET_ALLOW_DF_PERMUTE)
2926 return NULL_TREE;
2928 d = rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DF];
2929 break;
2931 case V2DImode:
2932 if (!TARGET_ALLOW_DF_PERMUTE)
2933 return NULL_TREE;
2935 d = (uns_p
2936 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DI_UNS]
2937 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DI]);
2938 break;
2940 default:
2941 return NULL_TREE;
2944 gcc_assert (d);
2945 return d;
2948 /* Handle generic options of the form -mfoo=yes/no.
2949 NAME is the option name.
2950 VALUE is the option value.
2951 FLAG is the pointer to the flag where to store a 1 or 0, depending on
2952 whether the option value is 'yes' or 'no' respectively. */
2953 static void
2954 rs6000_parse_yes_no_option (const char *name, const char *value, int *flag)
2956 if (value == 0)
2957 return;
2958 else if (!strcmp (value, "yes"))
2959 *flag = 1;
2960 else if (!strcmp (value, "no"))
2961 *flag = 0;
2962 else
2963 error ("unknown -m%s= option specified: '%s'", name, value);
2966 /* Validate and record the size specified with the -mtls-size option. */
2968 static void
2969 rs6000_parse_tls_size_option (void)
2971 if (rs6000_tls_size_string == 0)
2972 return;
2973 else if (strcmp (rs6000_tls_size_string, "16") == 0)
2974 rs6000_tls_size = 16;
2975 else if (strcmp (rs6000_tls_size_string, "32") == 0)
2976 rs6000_tls_size = 32;
2977 else if (strcmp (rs6000_tls_size_string, "64") == 0)
2978 rs6000_tls_size = 64;
2979 else
2980 error ("bad value %qs for -mtls-size switch", rs6000_tls_size_string);
2983 void
2984 optimization_options (int level ATTRIBUTE_UNUSED, int size ATTRIBUTE_UNUSED)
2986 if (DEFAULT_ABI == ABI_DARWIN)
2987 /* The Darwin libraries never set errno, so we might as well
2988 avoid calling them when that's the only reason we would. */
2989 flag_errno_math = 0;
2991 /* Double growth factor to counter reduced min jump length. */
2992 set_param_value ("max-grow-copy-bb-insns", 16);
2994 /* Enable section anchors by default.
2995 Skip section anchors for Objective C and Objective C++
2996 until front-ends fixed. */
2997 if (!TARGET_MACHO && lang_hooks.name[4] != 'O')
2998 flag_section_anchors = 2;
3001 static enum fpu_type_t
3002 rs6000_parse_fpu_option (const char *option)
3004 if (!strcmp("none", option)) return FPU_NONE;
3005 if (!strcmp("sp_lite", option)) return FPU_SF_LITE;
3006 if (!strcmp("dp_lite", option)) return FPU_DF_LITE;
3007 if (!strcmp("sp_full", option)) return FPU_SF_FULL;
3008 if (!strcmp("dp_full", option)) return FPU_DF_FULL;
3009 error("unknown value %s for -mfpu", option);
3010 return FPU_NONE;
3013 /* Returns a function decl for a vectorized version of the builtin function
3014 with builtin function code FN and the result vector type TYPE, or NULL_TREE
3015 if it is not available. */
3017 static tree
3018 rs6000_builtin_vectorized_function (unsigned int fn, tree type_out,
3019 tree type_in)
3021 enum machine_mode in_mode, out_mode;
3022 int in_n, out_n;
3024 if (TREE_CODE (type_out) != VECTOR_TYPE
3025 || TREE_CODE (type_in) != VECTOR_TYPE
3026 || !TARGET_VECTORIZE_BUILTINS)
3027 return NULL_TREE;
3029 out_mode = TYPE_MODE (TREE_TYPE (type_out));
3030 out_n = TYPE_VECTOR_SUBPARTS (type_out);
3031 in_mode = TYPE_MODE (TREE_TYPE (type_in));
3032 in_n = TYPE_VECTOR_SUBPARTS (type_in);
3034 switch (fn)
3036 case BUILT_IN_COPYSIGN:
3037 if (VECTOR_UNIT_VSX_P (V2DFmode)
3038 && out_mode == DFmode && out_n == 2
3039 && in_mode == DFmode && in_n == 2)
3040 return rs6000_builtin_decls[VSX_BUILTIN_CPSGNDP];
3041 break;
3042 case BUILT_IN_COPYSIGNF:
3043 if (out_mode != SFmode || out_n != 4
3044 || in_mode != SFmode || in_n != 4)
3045 break;
3046 if (VECTOR_UNIT_VSX_P (V4SFmode))
3047 return rs6000_builtin_decls[VSX_BUILTIN_CPSGNSP];
3048 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3049 return rs6000_builtin_decls[ALTIVEC_BUILTIN_COPYSIGN_V4SF];
3050 break;
3051 case BUILT_IN_SQRT:
3052 if (VECTOR_UNIT_VSX_P (V2DFmode)
3053 && out_mode == DFmode && out_n == 2
3054 && in_mode == DFmode && in_n == 2)
3055 return rs6000_builtin_decls[VSX_BUILTIN_XVSQRTDP];
3056 break;
3057 case BUILT_IN_SQRTF:
3058 if (VECTOR_UNIT_VSX_P (V4SFmode)
3059 && out_mode == SFmode && out_n == 4
3060 && in_mode == SFmode && in_n == 4)
3061 return rs6000_builtin_decls[VSX_BUILTIN_XVSQRTSP];
3062 break;
3063 case BUILT_IN_CEIL:
3064 if (VECTOR_UNIT_VSX_P (V2DFmode)
3065 && out_mode == DFmode && out_n == 2
3066 && in_mode == DFmode && in_n == 2)
3067 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIP];
3068 break;
3069 case BUILT_IN_CEILF:
3070 if (out_mode != SFmode || out_n != 4
3071 || in_mode != SFmode || in_n != 4)
3072 break;
3073 if (VECTOR_UNIT_VSX_P (V4SFmode))
3074 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIP];
3075 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3076 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIP];
3077 break;
3078 case BUILT_IN_FLOOR:
3079 if (VECTOR_UNIT_VSX_P (V2DFmode)
3080 && out_mode == DFmode && out_n == 2
3081 && in_mode == DFmode && in_n == 2)
3082 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIM];
3083 break;
3084 case BUILT_IN_FLOORF:
3085 if (out_mode != SFmode || out_n != 4
3086 || in_mode != SFmode || in_n != 4)
3087 break;
3088 if (VECTOR_UNIT_VSX_P (V4SFmode))
3089 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIM];
3090 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3091 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIM];
3092 break;
3093 case BUILT_IN_TRUNC:
3094 if (VECTOR_UNIT_VSX_P (V2DFmode)
3095 && out_mode == DFmode && out_n == 2
3096 && in_mode == DFmode && in_n == 2)
3097 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIZ];
3098 break;
3099 case BUILT_IN_TRUNCF:
3100 if (out_mode != SFmode || out_n != 4
3101 || in_mode != SFmode || in_n != 4)
3102 break;
3103 if (VECTOR_UNIT_VSX_P (V4SFmode))
3104 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIZ];
3105 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3106 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIZ];
3107 break;
3108 case BUILT_IN_NEARBYINT:
3109 if (VECTOR_UNIT_VSX_P (V2DFmode)
3110 && flag_unsafe_math_optimizations
3111 && out_mode == DFmode && out_n == 2
3112 && in_mode == DFmode && in_n == 2)
3113 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPI];
3114 break;
3115 case BUILT_IN_NEARBYINTF:
3116 if (VECTOR_UNIT_VSX_P (V4SFmode)
3117 && flag_unsafe_math_optimizations
3118 && out_mode == SFmode && out_n == 4
3119 && in_mode == SFmode && in_n == 4)
3120 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPI];
3121 break;
3122 case BUILT_IN_RINT:
3123 if (VECTOR_UNIT_VSX_P (V2DFmode)
3124 && !flag_trapping_math
3125 && out_mode == DFmode && out_n == 2
3126 && in_mode == DFmode && in_n == 2)
3127 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIC];
3128 break;
3129 case BUILT_IN_RINTF:
3130 if (VECTOR_UNIT_VSX_P (V4SFmode)
3131 && !flag_trapping_math
3132 && out_mode == SFmode && out_n == 4
3133 && in_mode == SFmode && in_n == 4)
3134 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIC];
3135 break;
3136 default:
3137 break;
3139 return NULL_TREE;
3143 /* Implement TARGET_HANDLE_OPTION. */
3145 static bool
3146 rs6000_handle_option (size_t code, const char *arg, int value)
3148 enum fpu_type_t fpu_type = FPU_NONE;
3149 int isel;
3151 switch (code)
3153 case OPT_mno_power:
3154 target_flags &= ~(MASK_POWER | MASK_POWER2
3155 | MASK_MULTIPLE | MASK_STRING);
3156 target_flags_explicit |= (MASK_POWER | MASK_POWER2
3157 | MASK_MULTIPLE | MASK_STRING);
3158 break;
3159 case OPT_mno_powerpc:
3160 target_flags &= ~(MASK_POWERPC | MASK_PPC_GPOPT
3161 | MASK_PPC_GFXOPT | MASK_POWERPC64);
3162 target_flags_explicit |= (MASK_POWERPC | MASK_PPC_GPOPT
3163 | MASK_PPC_GFXOPT | MASK_POWERPC64);
3164 break;
3165 case OPT_mfull_toc:
3166 target_flags &= ~MASK_MINIMAL_TOC;
3167 TARGET_NO_FP_IN_TOC = 0;
3168 TARGET_NO_SUM_IN_TOC = 0;
3169 target_flags_explicit |= MASK_MINIMAL_TOC;
3170 #ifdef TARGET_USES_SYSV4_OPT
3171 /* Note, V.4 no longer uses a normal TOC, so make -mfull-toc, be
3172 just the same as -mminimal-toc. */
3173 target_flags |= MASK_MINIMAL_TOC;
3174 target_flags_explicit |= MASK_MINIMAL_TOC;
3175 #endif
3176 break;
3178 #ifdef TARGET_USES_SYSV4_OPT
3179 case OPT_mtoc:
3180 /* Make -mtoc behave like -mminimal-toc. */
3181 target_flags |= MASK_MINIMAL_TOC;
3182 target_flags_explicit |= MASK_MINIMAL_TOC;
3183 break;
3184 #endif
3186 #ifdef TARGET_USES_AIX64_OPT
3187 case OPT_maix64:
3188 #else
3189 case OPT_m64:
3190 #endif
3191 target_flags |= MASK_POWERPC64 | MASK_POWERPC;
3192 target_flags |= ~target_flags_explicit & MASK_PPC_GFXOPT;
3193 target_flags_explicit |= MASK_POWERPC64 | MASK_POWERPC;
3194 break;
3196 #ifdef TARGET_USES_AIX64_OPT
3197 case OPT_maix32:
3198 #else
3199 case OPT_m32:
3200 #endif
3201 target_flags &= ~MASK_POWERPC64;
3202 target_flags_explicit |= MASK_POWERPC64;
3203 break;
3205 case OPT_minsert_sched_nops_:
3206 rs6000_sched_insert_nops_str = arg;
3207 break;
3209 case OPT_mminimal_toc:
3210 if (value == 1)
3212 TARGET_NO_FP_IN_TOC = 0;
3213 TARGET_NO_SUM_IN_TOC = 0;
3215 break;
3217 case OPT_mpower:
3218 if (value == 1)
3220 target_flags |= (MASK_MULTIPLE | MASK_STRING);
3221 target_flags_explicit |= (MASK_MULTIPLE | MASK_STRING);
3223 break;
3225 case OPT_mpower2:
3226 if (value == 1)
3228 target_flags |= (MASK_POWER | MASK_MULTIPLE | MASK_STRING);
3229 target_flags_explicit |= (MASK_POWER | MASK_MULTIPLE | MASK_STRING);
3231 break;
3233 case OPT_mpowerpc_gpopt:
3234 case OPT_mpowerpc_gfxopt:
3235 if (value == 1)
3237 target_flags |= MASK_POWERPC;
3238 target_flags_explicit |= MASK_POWERPC;
3240 break;
3242 case OPT_maix_struct_return:
3243 case OPT_msvr4_struct_return:
3244 rs6000_explicit_options.aix_struct_ret = true;
3245 break;
3247 case OPT_mvrsave:
3248 rs6000_explicit_options.vrsave = true;
3249 TARGET_ALTIVEC_VRSAVE = value;
3250 break;
3252 case OPT_mvrsave_:
3253 rs6000_explicit_options.vrsave = true;
3254 rs6000_parse_yes_no_option ("vrsave", arg, &(TARGET_ALTIVEC_VRSAVE));
3255 break;
3257 case OPT_misel_:
3258 target_flags_explicit |= MASK_ISEL;
3259 isel = 0;
3260 rs6000_parse_yes_no_option ("isel", arg, &isel);
3261 if (isel)
3262 target_flags |= MASK_ISEL;
3263 else
3264 target_flags &= ~MASK_ISEL;
3265 break;
3267 case OPT_mspe:
3268 rs6000_explicit_options.spe = true;
3269 rs6000_spe = value;
3270 break;
3272 case OPT_mspe_:
3273 rs6000_explicit_options.spe = true;
3274 rs6000_parse_yes_no_option ("spe", arg, &(rs6000_spe));
3275 break;
3277 case OPT_mdebug_:
3278 rs6000_debug_name = arg;
3279 break;
3281 #ifdef TARGET_USES_SYSV4_OPT
3282 case OPT_mcall_:
3283 rs6000_abi_name = arg;
3284 break;
3286 case OPT_msdata_:
3287 rs6000_sdata_name = arg;
3288 break;
3290 case OPT_mtls_size_:
3291 rs6000_tls_size_string = arg;
3292 break;
3294 case OPT_mrelocatable:
3295 if (value == 1)
3297 target_flags |= MASK_MINIMAL_TOC;
3298 target_flags_explicit |= MASK_MINIMAL_TOC;
3299 TARGET_NO_FP_IN_TOC = 1;
3301 break;
3303 case OPT_mrelocatable_lib:
3304 if (value == 1)
3306 target_flags |= MASK_RELOCATABLE | MASK_MINIMAL_TOC;
3307 target_flags_explicit |= MASK_RELOCATABLE | MASK_MINIMAL_TOC;
3308 TARGET_NO_FP_IN_TOC = 1;
3310 else
3312 target_flags &= ~MASK_RELOCATABLE;
3313 target_flags_explicit |= MASK_RELOCATABLE;
3315 break;
3316 #endif
3318 case OPT_mabi_:
3319 if (!strcmp (arg, "altivec"))
3321 rs6000_explicit_options.altivec_abi = true;
3322 rs6000_altivec_abi = 1;
3324 /* Enabling the AltiVec ABI turns off the SPE ABI. */
3325 rs6000_spe_abi = 0;
3327 else if (! strcmp (arg, "no-altivec"))
3329 rs6000_explicit_options.altivec_abi = true;
3330 rs6000_altivec_abi = 0;
3332 else if (! strcmp (arg, "spe"))
3334 rs6000_explicit_options.spe_abi = true;
3335 rs6000_spe_abi = 1;
3336 rs6000_altivec_abi = 0;
3337 if (!TARGET_SPE_ABI)
3338 error ("not configured for ABI: '%s'", arg);
3340 else if (! strcmp (arg, "no-spe"))
3342 rs6000_explicit_options.spe_abi = true;
3343 rs6000_spe_abi = 0;
3346 /* These are here for testing during development only, do not
3347 document in the manual please. */
3348 else if (! strcmp (arg, "d64"))
3350 rs6000_darwin64_abi = 1;
3351 warning (0, "Using darwin64 ABI");
3353 else if (! strcmp (arg, "d32"))
3355 rs6000_darwin64_abi = 0;
3356 warning (0, "Using old darwin ABI");
3359 else if (! strcmp (arg, "ibmlongdouble"))
3361 rs6000_explicit_options.ieee = true;
3362 rs6000_ieeequad = 0;
3363 warning (0, "Using IBM extended precision long double");
3365 else if (! strcmp (arg, "ieeelongdouble"))
3367 rs6000_explicit_options.ieee = true;
3368 rs6000_ieeequad = 1;
3369 warning (0, "Using IEEE extended precision long double");
3372 else
3374 error ("unknown ABI specified: '%s'", arg);
3375 return false;
3377 break;
3379 case OPT_mcpu_:
3380 rs6000_select[1].string = arg;
3381 break;
3383 case OPT_mtune_:
3384 rs6000_select[2].string = arg;
3385 break;
3387 case OPT_mtraceback_:
3388 rs6000_traceback_name = arg;
3389 break;
3391 case OPT_mfloat_gprs_:
3392 rs6000_explicit_options.float_gprs = true;
3393 if (! strcmp (arg, "yes") || ! strcmp (arg, "single"))
3394 rs6000_float_gprs = 1;
3395 else if (! strcmp (arg, "double"))
3396 rs6000_float_gprs = 2;
3397 else if (! strcmp (arg, "no"))
3398 rs6000_float_gprs = 0;
3399 else
3401 error ("invalid option for -mfloat-gprs: '%s'", arg);
3402 return false;
3404 break;
3406 case OPT_mlong_double_:
3407 rs6000_explicit_options.long_double = true;
3408 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
3409 if (value != 64 && value != 128)
3411 error ("Unknown switch -mlong-double-%s", arg);
3412 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
3413 return false;
3415 else
3416 rs6000_long_double_type_size = value;
3417 break;
3419 case OPT_msched_costly_dep_:
3420 rs6000_sched_costly_dep_str = arg;
3421 break;
3423 case OPT_malign_:
3424 rs6000_explicit_options.alignment = true;
3425 if (! strcmp (arg, "power"))
3427 /* On 64-bit Darwin, power alignment is ABI-incompatible with
3428 some C library functions, so warn about it. The flag may be
3429 useful for performance studies from time to time though, so
3430 don't disable it entirely. */
3431 if (DEFAULT_ABI == ABI_DARWIN && TARGET_64BIT)
3432 warning (0, "-malign-power is not supported for 64-bit Darwin;"
3433 " it is incompatible with the installed C and C++ libraries");
3434 rs6000_alignment_flags = MASK_ALIGN_POWER;
3436 else if (! strcmp (arg, "natural"))
3437 rs6000_alignment_flags = MASK_ALIGN_NATURAL;
3438 else
3440 error ("unknown -malign-XXXXX option specified: '%s'", arg);
3441 return false;
3443 break;
3445 case OPT_msingle_float:
3446 if (!TARGET_SINGLE_FPU)
3447 warning (0, "-msingle-float option equivalent to -mhard-float");
3448 /* -msingle-float implies -mno-double-float and TARGET_HARD_FLOAT. */
3449 rs6000_double_float = 0;
3450 target_flags &= ~MASK_SOFT_FLOAT;
3451 target_flags_explicit |= MASK_SOFT_FLOAT;
3452 break;
3454 case OPT_mdouble_float:
3455 /* -mdouble-float implies -msingle-float and TARGET_HARD_FLOAT. */
3456 rs6000_single_float = 1;
3457 target_flags &= ~MASK_SOFT_FLOAT;
3458 target_flags_explicit |= MASK_SOFT_FLOAT;
3459 break;
3461 case OPT_msimple_fpu:
3462 if (!TARGET_SINGLE_FPU)
3463 warning (0, "-msimple-fpu option ignored");
3464 break;
3466 case OPT_mhard_float:
3467 /* -mhard_float implies -msingle-float and -mdouble-float. */
3468 rs6000_single_float = rs6000_double_float = 1;
3469 break;
3471 case OPT_msoft_float:
3472 /* -msoft_float implies -mnosingle-float and -mnodouble-float. */
3473 rs6000_single_float = rs6000_double_float = 0;
3474 break;
3476 case OPT_mfpu_:
3477 fpu_type = rs6000_parse_fpu_option(arg);
3478 if (fpu_type != FPU_NONE)
3479 /* If -mfpu is not none, then turn off SOFT_FLOAT, turn on HARD_FLOAT. */
3481 target_flags &= ~MASK_SOFT_FLOAT;
3482 target_flags_explicit |= MASK_SOFT_FLOAT;
3483 rs6000_xilinx_fpu = 1;
3484 if (fpu_type == FPU_SF_LITE || fpu_type == FPU_SF_FULL)
3485 rs6000_single_float = 1;
3486 if (fpu_type == FPU_DF_LITE || fpu_type == FPU_DF_FULL)
3487 rs6000_single_float = rs6000_double_float = 1;
3488 if (fpu_type == FPU_SF_LITE || fpu_type == FPU_DF_LITE)
3489 rs6000_simple_fpu = 1;
3491 else
3493 /* -mfpu=none is equivalent to -msoft-float */
3494 target_flags |= MASK_SOFT_FLOAT;
3495 target_flags_explicit |= MASK_SOFT_FLOAT;
3496 rs6000_single_float = rs6000_double_float = 0;
3498 break;
3500 return true;
3503 /* Do anything needed at the start of the asm file. */
3505 static void
3506 rs6000_file_start (void)
3508 size_t i;
3509 char buffer[80];
3510 const char *start = buffer;
3511 struct rs6000_cpu_select *ptr;
3512 const char *default_cpu = TARGET_CPU_DEFAULT;
3513 FILE *file = asm_out_file;
3515 default_file_start ();
3517 #ifdef TARGET_BI_ARCH
3518 if ((TARGET_DEFAULT ^ target_flags) & MASK_64BIT)
3519 default_cpu = 0;
3520 #endif
3522 if (flag_verbose_asm)
3524 sprintf (buffer, "\n%s rs6000/powerpc options:", ASM_COMMENT_START);
3525 rs6000_select[0].string = default_cpu;
3527 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
3529 ptr = &rs6000_select[i];
3530 if (ptr->string != (char *)0 && ptr->string[0] != '\0')
3532 fprintf (file, "%s %s%s", start, ptr->name, ptr->string);
3533 start = "";
3537 if (PPC405_ERRATUM77)
3539 fprintf (file, "%s PPC405CR_ERRATUM77", start);
3540 start = "";
3543 #ifdef USING_ELFOS_H
3544 switch (rs6000_sdata)
3546 case SDATA_NONE: fprintf (file, "%s -msdata=none", start); start = ""; break;
3547 case SDATA_DATA: fprintf (file, "%s -msdata=data", start); start = ""; break;
3548 case SDATA_SYSV: fprintf (file, "%s -msdata=sysv", start); start = ""; break;
3549 case SDATA_EABI: fprintf (file, "%s -msdata=eabi", start); start = ""; break;
3552 if (rs6000_sdata && g_switch_value)
3554 fprintf (file, "%s -G " HOST_WIDE_INT_PRINT_UNSIGNED, start,
3555 g_switch_value);
3556 start = "";
3558 #endif
3560 if (*start == '\0')
3561 putc ('\n', file);
3564 #ifdef HAVE_AS_GNU_ATTRIBUTE
3565 if (TARGET_32BIT && DEFAULT_ABI == ABI_V4)
3567 fprintf (file, "\t.gnu_attribute 4, %d\n",
3568 ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT) ? 1
3569 : (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT) ? 3
3570 : 2));
3571 fprintf (file, "\t.gnu_attribute 8, %d\n",
3572 (TARGET_ALTIVEC_ABI ? 2
3573 : TARGET_SPE_ABI ? 3
3574 : 1));
3575 fprintf (file, "\t.gnu_attribute 12, %d\n",
3576 aix_struct_return ? 2 : 1);
3579 #endif
3581 if (DEFAULT_ABI == ABI_AIX || (TARGET_ELF && flag_pic == 2))
3583 switch_to_section (toc_section);
3584 switch_to_section (text_section);
3589 /* Return nonzero if this function is known to have a null epilogue. */
3592 direct_return (void)
3594 if (reload_completed)
3596 rs6000_stack_t *info = rs6000_stack_info ();
3598 if (info->first_gp_reg_save == 32
3599 && info->first_fp_reg_save == 64
3600 && info->first_altivec_reg_save == LAST_ALTIVEC_REGNO + 1
3601 && ! info->lr_save_p
3602 && ! info->cr_save_p
3603 && info->vrsave_mask == 0
3604 && ! info->push_p)
3605 return 1;
3608 return 0;
3611 /* Return the number of instructions it takes to form a constant in an
3612 integer register. */
3615 num_insns_constant_wide (HOST_WIDE_INT value)
3617 /* signed constant loadable with {cal|addi} */
3618 if ((unsigned HOST_WIDE_INT) (value + 0x8000) < 0x10000)
3619 return 1;
3621 /* constant loadable with {cau|addis} */
3622 else if ((value & 0xffff) == 0
3623 && (value >> 31 == -1 || value >> 31 == 0))
3624 return 1;
3626 #if HOST_BITS_PER_WIDE_INT == 64
3627 else if (TARGET_POWERPC64)
3629 HOST_WIDE_INT low = ((value & 0xffffffff) ^ 0x80000000) - 0x80000000;
3630 HOST_WIDE_INT high = value >> 31;
3632 if (high == 0 || high == -1)
3633 return 2;
3635 high >>= 1;
3637 if (low == 0)
3638 return num_insns_constant_wide (high) + 1;
3639 else
3640 return (num_insns_constant_wide (high)
3641 + num_insns_constant_wide (low) + 1);
3643 #endif
3645 else
3646 return 2;
3650 num_insns_constant (rtx op, enum machine_mode mode)
3652 HOST_WIDE_INT low, high;
3654 switch (GET_CODE (op))
3656 case CONST_INT:
3657 #if HOST_BITS_PER_WIDE_INT == 64
3658 if ((INTVAL (op) >> 31) != 0 && (INTVAL (op) >> 31) != -1
3659 && mask64_operand (op, mode))
3660 return 2;
3661 else
3662 #endif
3663 return num_insns_constant_wide (INTVAL (op));
3665 case CONST_DOUBLE:
3666 if (mode == SFmode || mode == SDmode)
3668 long l;
3669 REAL_VALUE_TYPE rv;
3671 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
3672 if (DECIMAL_FLOAT_MODE_P (mode))
3673 REAL_VALUE_TO_TARGET_DECIMAL32 (rv, l);
3674 else
3675 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
3676 return num_insns_constant_wide ((HOST_WIDE_INT) l);
3679 if (mode == VOIDmode || mode == DImode)
3681 high = CONST_DOUBLE_HIGH (op);
3682 low = CONST_DOUBLE_LOW (op);
3684 else
3686 long l[2];
3687 REAL_VALUE_TYPE rv;
3689 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
3690 if (DECIMAL_FLOAT_MODE_P (mode))
3691 REAL_VALUE_TO_TARGET_DECIMAL64 (rv, l);
3692 else
3693 REAL_VALUE_TO_TARGET_DOUBLE (rv, l);
3694 high = l[WORDS_BIG_ENDIAN == 0];
3695 low = l[WORDS_BIG_ENDIAN != 0];
3698 if (TARGET_32BIT)
3699 return (num_insns_constant_wide (low)
3700 + num_insns_constant_wide (high));
3701 else
3703 if ((high == 0 && low >= 0)
3704 || (high == -1 && low < 0))
3705 return num_insns_constant_wide (low);
3707 else if (mask64_operand (op, mode))
3708 return 2;
3710 else if (low == 0)
3711 return num_insns_constant_wide (high) + 1;
3713 else
3714 return (num_insns_constant_wide (high)
3715 + num_insns_constant_wide (low) + 1);
3718 default:
3719 gcc_unreachable ();
3723 /* Interpret element ELT of the CONST_VECTOR OP as an integer value.
3724 If the mode of OP is MODE_VECTOR_INT, this simply returns the
3725 corresponding element of the vector, but for V4SFmode and V2SFmode,
3726 the corresponding "float" is interpreted as an SImode integer. */
3728 HOST_WIDE_INT
3729 const_vector_elt_as_int (rtx op, unsigned int elt)
3731 rtx tmp = CONST_VECTOR_ELT (op, elt);
3732 if (GET_MODE (op) == V4SFmode
3733 || GET_MODE (op) == V2SFmode)
3734 tmp = gen_lowpart (SImode, tmp);
3735 return INTVAL (tmp);
3738 /* Return true if OP can be synthesized with a particular vspltisb, vspltish
3739 or vspltisw instruction. OP is a CONST_VECTOR. Which instruction is used
3740 depends on STEP and COPIES, one of which will be 1. If COPIES > 1,
3741 all items are set to the same value and contain COPIES replicas of the
3742 vsplt's operand; if STEP > 1, one in STEP elements is set to the vsplt's
3743 operand and the others are set to the value of the operand's msb. */
3745 static bool
3746 vspltis_constant (rtx op, unsigned step, unsigned copies)
3748 enum machine_mode mode = GET_MODE (op);
3749 enum machine_mode inner = GET_MODE_INNER (mode);
3751 unsigned i;
3752 unsigned nunits = GET_MODE_NUNITS (mode);
3753 unsigned bitsize = GET_MODE_BITSIZE (inner);
3754 unsigned mask = GET_MODE_MASK (inner);
3756 HOST_WIDE_INT val = const_vector_elt_as_int (op, nunits - 1);
3757 HOST_WIDE_INT splat_val = val;
3758 HOST_WIDE_INT msb_val = val > 0 ? 0 : -1;
3760 /* Construct the value to be splatted, if possible. If not, return 0. */
3761 for (i = 2; i <= copies; i *= 2)
3763 HOST_WIDE_INT small_val;
3764 bitsize /= 2;
3765 small_val = splat_val >> bitsize;
3766 mask >>= bitsize;
3767 if (splat_val != ((small_val << bitsize) | (small_val & mask)))
3768 return false;
3769 splat_val = small_val;
3772 /* Check if SPLAT_VAL can really be the operand of a vspltis[bhw]. */
3773 if (EASY_VECTOR_15 (splat_val))
3776 /* Also check if we can splat, and then add the result to itself. Do so if
3777 the value is positive, of if the splat instruction is using OP's mode;
3778 for splat_val < 0, the splat and the add should use the same mode. */
3779 else if (EASY_VECTOR_15_ADD_SELF (splat_val)
3780 && (splat_val >= 0 || (step == 1 && copies == 1)))
3783 /* Also check if are loading up the most significant bit which can be done by
3784 loading up -1 and shifting the value left by -1. */
3785 else if (EASY_VECTOR_MSB (splat_val, inner))
3788 else
3789 return false;
3791 /* Check if VAL is present in every STEP-th element, and the
3792 other elements are filled with its most significant bit. */
3793 for (i = 0; i < nunits - 1; ++i)
3795 HOST_WIDE_INT desired_val;
3796 if (((i + 1) & (step - 1)) == 0)
3797 desired_val = val;
3798 else
3799 desired_val = msb_val;
3801 if (desired_val != const_vector_elt_as_int (op, i))
3802 return false;
3805 return true;
3809 /* Return true if OP is of the given MODE and can be synthesized
3810 with a vspltisb, vspltish or vspltisw. */
3812 bool
3813 easy_altivec_constant (rtx op, enum machine_mode mode)
3815 unsigned step, copies;
3817 if (mode == VOIDmode)
3818 mode = GET_MODE (op);
3819 else if (mode != GET_MODE (op))
3820 return false;
3822 /* Start with a vspltisw. */
3823 step = GET_MODE_NUNITS (mode) / 4;
3824 copies = 1;
3826 if (vspltis_constant (op, step, copies))
3827 return true;
3829 /* Then try with a vspltish. */
3830 if (step == 1)
3831 copies <<= 1;
3832 else
3833 step >>= 1;
3835 if (vspltis_constant (op, step, copies))
3836 return true;
3838 /* And finally a vspltisb. */
3839 if (step == 1)
3840 copies <<= 1;
3841 else
3842 step >>= 1;
3844 if (vspltis_constant (op, step, copies))
3845 return true;
3847 return false;
3850 /* Generate a VEC_DUPLICATE representing a vspltis[bhw] instruction whose
3851 result is OP. Abort if it is not possible. */
3854 gen_easy_altivec_constant (rtx op)
3856 enum machine_mode mode = GET_MODE (op);
3857 int nunits = GET_MODE_NUNITS (mode);
3858 rtx last = CONST_VECTOR_ELT (op, nunits - 1);
3859 unsigned step = nunits / 4;
3860 unsigned copies = 1;
3862 /* Start with a vspltisw. */
3863 if (vspltis_constant (op, step, copies))
3864 return gen_rtx_VEC_DUPLICATE (V4SImode, gen_lowpart (SImode, last));
3866 /* Then try with a vspltish. */
3867 if (step == 1)
3868 copies <<= 1;
3869 else
3870 step >>= 1;
3872 if (vspltis_constant (op, step, copies))
3873 return gen_rtx_VEC_DUPLICATE (V8HImode, gen_lowpart (HImode, last));
3875 /* And finally a vspltisb. */
3876 if (step == 1)
3877 copies <<= 1;
3878 else
3879 step >>= 1;
3881 if (vspltis_constant (op, step, copies))
3882 return gen_rtx_VEC_DUPLICATE (V16QImode, gen_lowpart (QImode, last));
3884 gcc_unreachable ();
3887 const char *
3888 output_vec_const_move (rtx *operands)
3890 int cst, cst2;
3891 enum machine_mode mode;
3892 rtx dest, vec;
3894 dest = operands[0];
3895 vec = operands[1];
3896 mode = GET_MODE (dest);
3898 if (TARGET_VSX && zero_constant (vec, mode))
3899 return "xxlxor %x0,%x0,%x0";
3901 if (TARGET_ALTIVEC)
3903 rtx splat_vec;
3904 if (zero_constant (vec, mode))
3905 return "vxor %0,%0,%0";
3907 splat_vec = gen_easy_altivec_constant (vec);
3908 gcc_assert (GET_CODE (splat_vec) == VEC_DUPLICATE);
3909 operands[1] = XEXP (splat_vec, 0);
3910 if (!EASY_VECTOR_15 (INTVAL (operands[1])))
3911 return "#";
3913 switch (GET_MODE (splat_vec))
3915 case V4SImode:
3916 return "vspltisw %0,%1";
3918 case V8HImode:
3919 return "vspltish %0,%1";
3921 case V16QImode:
3922 return "vspltisb %0,%1";
3924 default:
3925 gcc_unreachable ();
3929 gcc_assert (TARGET_SPE);
3931 /* Vector constant 0 is handled as a splitter of V2SI, and in the
3932 pattern of V1DI, V4HI, and V2SF.
3934 FIXME: We should probably return # and add post reload
3935 splitters for these, but this way is so easy ;-). */
3936 cst = INTVAL (CONST_VECTOR_ELT (vec, 0));
3937 cst2 = INTVAL (CONST_VECTOR_ELT (vec, 1));
3938 operands[1] = CONST_VECTOR_ELT (vec, 0);
3939 operands[2] = CONST_VECTOR_ELT (vec, 1);
3940 if (cst == cst2)
3941 return "li %0,%1\n\tevmergelo %0,%0,%0";
3942 else
3943 return "li %0,%1\n\tevmergelo %0,%0,%0\n\tli %0,%2";
3946 /* Initialize TARGET of vector PAIRED to VALS. */
3948 void
3949 paired_expand_vector_init (rtx target, rtx vals)
3951 enum machine_mode mode = GET_MODE (target);
3952 int n_elts = GET_MODE_NUNITS (mode);
3953 int n_var = 0;
3954 rtx x, new_rtx, tmp, constant_op, op1, op2;
3955 int i;
3957 for (i = 0; i < n_elts; ++i)
3959 x = XVECEXP (vals, 0, i);
3960 if (!CONSTANT_P (x))
3961 ++n_var;
3963 if (n_var == 0)
3965 /* Load from constant pool. */
3966 emit_move_insn (target, gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0)));
3967 return;
3970 if (n_var == 2)
3972 /* The vector is initialized only with non-constants. */
3973 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, XVECEXP (vals, 0, 0),
3974 XVECEXP (vals, 0, 1));
3976 emit_move_insn (target, new_rtx);
3977 return;
3980 /* One field is non-constant and the other one is a constant. Load the
3981 constant from the constant pool and use ps_merge instruction to
3982 construct the whole vector. */
3983 op1 = XVECEXP (vals, 0, 0);
3984 op2 = XVECEXP (vals, 0, 1);
3986 constant_op = (CONSTANT_P (op1)) ? op1 : op2;
3988 tmp = gen_reg_rtx (GET_MODE (constant_op));
3989 emit_move_insn (tmp, constant_op);
3991 if (CONSTANT_P (op1))
3992 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, tmp, op2);
3993 else
3994 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, op1, tmp);
3996 emit_move_insn (target, new_rtx);
3999 void
4000 paired_expand_vector_move (rtx operands[])
4002 rtx op0 = operands[0], op1 = operands[1];
4004 emit_move_insn (op0, op1);
4007 /* Emit vector compare for code RCODE. DEST is destination, OP1 and
4008 OP2 are two VEC_COND_EXPR operands, CC_OP0 and CC_OP1 are the two
4009 operands for the relation operation COND. This is a recursive
4010 function. */
4012 static void
4013 paired_emit_vector_compare (enum rtx_code rcode,
4014 rtx dest, rtx op0, rtx op1,
4015 rtx cc_op0, rtx cc_op1)
4017 rtx tmp = gen_reg_rtx (V2SFmode);
4018 rtx tmp1, max, min, equal_zero;
4020 gcc_assert (TARGET_PAIRED_FLOAT);
4021 gcc_assert (GET_MODE (op0) == GET_MODE (op1));
4023 switch (rcode)
4025 case LT:
4026 case LTU:
4027 paired_emit_vector_compare (GE, dest, op1, op0, cc_op0, cc_op1);
4028 return;
4029 case GE:
4030 case GEU:
4031 emit_insn (gen_subv2sf3 (tmp, cc_op0, cc_op1));
4032 emit_insn (gen_selv2sf4 (dest, tmp, op0, op1, CONST0_RTX (SFmode)));
4033 return;
4034 case LE:
4035 case LEU:
4036 paired_emit_vector_compare (GE, dest, op0, op1, cc_op1, cc_op0);
4037 return;
4038 case GT:
4039 paired_emit_vector_compare (LE, dest, op1, op0, cc_op0, cc_op1);
4040 return;
4041 case EQ:
4042 tmp1 = gen_reg_rtx (V2SFmode);
4043 max = gen_reg_rtx (V2SFmode);
4044 min = gen_reg_rtx (V2SFmode);
4045 equal_zero = gen_reg_rtx (V2SFmode);
4047 emit_insn (gen_subv2sf3 (tmp, cc_op0, cc_op1));
4048 emit_insn (gen_selv2sf4
4049 (max, tmp, cc_op0, cc_op1, CONST0_RTX (SFmode)));
4050 emit_insn (gen_subv2sf3 (tmp, cc_op1, cc_op0));
4051 emit_insn (gen_selv2sf4
4052 (min, tmp, cc_op0, cc_op1, CONST0_RTX (SFmode)));
4053 emit_insn (gen_subv2sf3 (tmp1, min, max));
4054 emit_insn (gen_selv2sf4 (dest, tmp1, op0, op1, CONST0_RTX (SFmode)));
4055 return;
4056 case NE:
4057 paired_emit_vector_compare (EQ, dest, op1, op0, cc_op0, cc_op1);
4058 return;
4059 case UNLE:
4060 paired_emit_vector_compare (LE, dest, op1, op0, cc_op0, cc_op1);
4061 return;
4062 case UNLT:
4063 paired_emit_vector_compare (LT, dest, op1, op0, cc_op0, cc_op1);
4064 return;
4065 case UNGE:
4066 paired_emit_vector_compare (GE, dest, op1, op0, cc_op0, cc_op1);
4067 return;
4068 case UNGT:
4069 paired_emit_vector_compare (GT, dest, op1, op0, cc_op0, cc_op1);
4070 return;
4071 default:
4072 gcc_unreachable ();
4075 return;
4078 /* Emit vector conditional expression.
4079 DEST is destination. OP1 and OP2 are two VEC_COND_EXPR operands.
4080 CC_OP0 and CC_OP1 are the two operands for the relation operation COND. */
4083 paired_emit_vector_cond_expr (rtx dest, rtx op1, rtx op2,
4084 rtx cond, rtx cc_op0, rtx cc_op1)
4086 enum rtx_code rcode = GET_CODE (cond);
4088 if (!TARGET_PAIRED_FLOAT)
4089 return 0;
4091 paired_emit_vector_compare (rcode, dest, op1, op2, cc_op0, cc_op1);
4093 return 1;
4096 /* Initialize vector TARGET to VALS. */
4098 void
4099 rs6000_expand_vector_init (rtx target, rtx vals)
4101 enum machine_mode mode = GET_MODE (target);
4102 enum machine_mode inner_mode = GET_MODE_INNER (mode);
4103 int n_elts = GET_MODE_NUNITS (mode);
4104 int n_var = 0, one_var = -1;
4105 bool all_same = true, all_const_zero = true;
4106 rtx x, mem;
4107 int i;
4109 for (i = 0; i < n_elts; ++i)
4111 x = XVECEXP (vals, 0, i);
4112 if (!CONSTANT_P (x))
4113 ++n_var, one_var = i;
4114 else if (x != CONST0_RTX (inner_mode))
4115 all_const_zero = false;
4117 if (i > 0 && !rtx_equal_p (x, XVECEXP (vals, 0, 0)))
4118 all_same = false;
4121 if (n_var == 0)
4123 rtx const_vec = gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0));
4124 bool int_vector_p = (GET_MODE_CLASS (mode) == MODE_VECTOR_INT);
4125 if ((int_vector_p || TARGET_VSX) && all_const_zero)
4127 /* Zero register. */
4128 emit_insn (gen_rtx_SET (VOIDmode, target,
4129 gen_rtx_XOR (mode, target, target)));
4130 return;
4132 else if (int_vector_p && easy_vector_constant (const_vec, mode))
4134 /* Splat immediate. */
4135 emit_insn (gen_rtx_SET (VOIDmode, target, const_vec));
4136 return;
4138 else
4140 /* Load from constant pool. */
4141 emit_move_insn (target, const_vec);
4142 return;
4146 /* Double word values on VSX can use xxpermdi or lxvdsx. */
4147 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
4149 if (all_same)
4151 rtx element = XVECEXP (vals, 0, 0);
4152 if (mode == V2DFmode)
4153 emit_insn (gen_vsx_splat_v2df (target, element));
4154 else
4155 emit_insn (gen_vsx_splat_v2di (target, element));
4157 else
4159 rtx op0 = copy_to_reg (XVECEXP (vals, 0, 0));
4160 rtx op1 = copy_to_reg (XVECEXP (vals, 0, 1));
4161 if (mode == V2DFmode)
4162 emit_insn (gen_vsx_concat_v2df (target, op0, op1));
4163 else
4164 emit_insn (gen_vsx_concat_v2di (target, op0, op1));
4166 return;
4169 /* With single precision floating point on VSX, know that internally single
4170 precision is actually represented as a double, and either make 2 V2DF
4171 vectors, and convert these vectors to single precision, or do one
4172 conversion, and splat the result to the other elements. */
4173 if (mode == V4SFmode && VECTOR_MEM_VSX_P (mode))
4175 if (all_same)
4177 rtx freg = gen_reg_rtx (V4SFmode);
4178 rtx sreg = copy_to_reg (XVECEXP (vals, 0, 0));
4180 emit_insn (gen_vsx_xscvdpsp_scalar (freg, sreg));
4181 emit_insn (gen_vsx_xxspltw_v4sf (target, freg, const0_rtx));
4183 else
4185 rtx dbl_even = gen_reg_rtx (V2DFmode);
4186 rtx dbl_odd = gen_reg_rtx (V2DFmode);
4187 rtx flt_even = gen_reg_rtx (V4SFmode);
4188 rtx flt_odd = gen_reg_rtx (V4SFmode);
4190 emit_insn (gen_vsx_concat_v2sf (dbl_even,
4191 copy_to_reg (XVECEXP (vals, 0, 0)),
4192 copy_to_reg (XVECEXP (vals, 0, 1))));
4193 emit_insn (gen_vsx_concat_v2sf (dbl_odd,
4194 copy_to_reg (XVECEXP (vals, 0, 2)),
4195 copy_to_reg (XVECEXP (vals, 0, 3))));
4196 emit_insn (gen_vsx_xvcvdpsp (flt_even, dbl_even));
4197 emit_insn (gen_vsx_xvcvdpsp (flt_odd, dbl_odd));
4198 emit_insn (gen_vec_extract_evenv4sf (target, flt_even, flt_odd));
4200 return;
4203 /* Store value to stack temp. Load vector element. Splat. However, splat
4204 of 64-bit items is not supported on Altivec. */
4205 if (all_same && GET_MODE_SIZE (mode) <= 4)
4207 mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0);
4208 emit_move_insn (adjust_address_nv (mem, inner_mode, 0),
4209 XVECEXP (vals, 0, 0));
4210 x = gen_rtx_UNSPEC (VOIDmode,
4211 gen_rtvec (1, const0_rtx), UNSPEC_LVE);
4212 emit_insn (gen_rtx_PARALLEL (VOIDmode,
4213 gen_rtvec (2,
4214 gen_rtx_SET (VOIDmode,
4215 target, mem),
4216 x)));
4217 x = gen_rtx_VEC_SELECT (inner_mode, target,
4218 gen_rtx_PARALLEL (VOIDmode,
4219 gen_rtvec (1, const0_rtx)));
4220 emit_insn (gen_rtx_SET (VOIDmode, target,
4221 gen_rtx_VEC_DUPLICATE (mode, x)));
4222 return;
4225 /* One field is non-constant. Load constant then overwrite
4226 varying field. */
4227 if (n_var == 1)
4229 rtx copy = copy_rtx (vals);
4231 /* Load constant part of vector, substitute neighboring value for
4232 varying element. */
4233 XVECEXP (copy, 0, one_var) = XVECEXP (vals, 0, (one_var + 1) % n_elts);
4234 rs6000_expand_vector_init (target, copy);
4236 /* Insert variable. */
4237 rs6000_expand_vector_set (target, XVECEXP (vals, 0, one_var), one_var);
4238 return;
4241 /* Construct the vector in memory one field at a time
4242 and load the whole vector. */
4243 mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
4244 for (i = 0; i < n_elts; i++)
4245 emit_move_insn (adjust_address_nv (mem, inner_mode,
4246 i * GET_MODE_SIZE (inner_mode)),
4247 XVECEXP (vals, 0, i));
4248 emit_move_insn (target, mem);
4251 /* Set field ELT of TARGET to VAL. */
4253 void
4254 rs6000_expand_vector_set (rtx target, rtx val, int elt)
4256 enum machine_mode mode = GET_MODE (target);
4257 enum machine_mode inner_mode = GET_MODE_INNER (mode);
4258 rtx reg = gen_reg_rtx (mode);
4259 rtx mask, mem, x;
4260 int width = GET_MODE_SIZE (inner_mode);
4261 int i;
4263 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
4265 rtx (*set_func) (rtx, rtx, rtx, rtx)
4266 = ((mode == V2DFmode) ? gen_vsx_set_v2df : gen_vsx_set_v2di);
4267 emit_insn (set_func (target, target, val, GEN_INT (elt)));
4268 return;
4271 /* Load single variable value. */
4272 mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0);
4273 emit_move_insn (adjust_address_nv (mem, inner_mode, 0), val);
4274 x = gen_rtx_UNSPEC (VOIDmode,
4275 gen_rtvec (1, const0_rtx), UNSPEC_LVE);
4276 emit_insn (gen_rtx_PARALLEL (VOIDmode,
4277 gen_rtvec (2,
4278 gen_rtx_SET (VOIDmode,
4279 reg, mem),
4280 x)));
4282 /* Linear sequence. */
4283 mask = gen_rtx_PARALLEL (V16QImode, rtvec_alloc (16));
4284 for (i = 0; i < 16; ++i)
4285 XVECEXP (mask, 0, i) = GEN_INT (i);
4287 /* Set permute mask to insert element into target. */
4288 for (i = 0; i < width; ++i)
4289 XVECEXP (mask, 0, elt*width + i)
4290 = GEN_INT (i + 0x10);
4291 x = gen_rtx_CONST_VECTOR (V16QImode, XVEC (mask, 0));
4292 x = gen_rtx_UNSPEC (mode,
4293 gen_rtvec (3, target, reg,
4294 force_reg (V16QImode, x)),
4295 UNSPEC_VPERM);
4296 emit_insn (gen_rtx_SET (VOIDmode, target, x));
4299 /* Extract field ELT from VEC into TARGET. */
4301 void
4302 rs6000_expand_vector_extract (rtx target, rtx vec, int elt)
4304 enum machine_mode mode = GET_MODE (vec);
4305 enum machine_mode inner_mode = GET_MODE_INNER (mode);
4306 rtx mem, x;
4308 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
4310 rtx (*extract_func) (rtx, rtx, rtx)
4311 = ((mode == V2DFmode) ? gen_vsx_extract_v2df : gen_vsx_extract_v2di);
4312 emit_insn (extract_func (target, vec, GEN_INT (elt)));
4313 return;
4316 /* Allocate mode-sized buffer. */
4317 mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
4319 /* Add offset to field within buffer matching vector element. */
4320 mem = adjust_address_nv (mem, mode, elt * GET_MODE_SIZE (inner_mode));
4322 /* Store single field into mode-sized buffer. */
4323 x = gen_rtx_UNSPEC (VOIDmode,
4324 gen_rtvec (1, const0_rtx), UNSPEC_STVE);
4325 emit_insn (gen_rtx_PARALLEL (VOIDmode,
4326 gen_rtvec (2,
4327 gen_rtx_SET (VOIDmode,
4328 mem, vec),
4329 x)));
4330 emit_move_insn (target, adjust_address_nv (mem, inner_mode, 0));
4333 /* Generates shifts and masks for a pair of rldicl or rldicr insns to
4334 implement ANDing by the mask IN. */
4335 void
4336 build_mask64_2_operands (rtx in, rtx *out)
4338 #if HOST_BITS_PER_WIDE_INT >= 64
4339 unsigned HOST_WIDE_INT c, lsb, m1, m2;
4340 int shift;
4342 gcc_assert (GET_CODE (in) == CONST_INT);
4344 c = INTVAL (in);
4345 if (c & 1)
4347 /* Assume c initially something like 0x00fff000000fffff. The idea
4348 is to rotate the word so that the middle ^^^^^^ group of zeros
4349 is at the MS end and can be cleared with an rldicl mask. We then
4350 rotate back and clear off the MS ^^ group of zeros with a
4351 second rldicl. */
4352 c = ~c; /* c == 0xff000ffffff00000 */
4353 lsb = c & -c; /* lsb == 0x0000000000100000 */
4354 m1 = -lsb; /* m1 == 0xfffffffffff00000 */
4355 c = ~c; /* c == 0x00fff000000fffff */
4356 c &= -lsb; /* c == 0x00fff00000000000 */
4357 lsb = c & -c; /* lsb == 0x0000100000000000 */
4358 c = ~c; /* c == 0xff000fffffffffff */
4359 c &= -lsb; /* c == 0xff00000000000000 */
4360 shift = 0;
4361 while ((lsb >>= 1) != 0)
4362 shift++; /* shift == 44 on exit from loop */
4363 m1 <<= 64 - shift; /* m1 == 0xffffff0000000000 */
4364 m1 = ~m1; /* m1 == 0x000000ffffffffff */
4365 m2 = ~c; /* m2 == 0x00ffffffffffffff */
4367 else
4369 /* Assume c initially something like 0xff000f0000000000. The idea
4370 is to rotate the word so that the ^^^ middle group of zeros
4371 is at the LS end and can be cleared with an rldicr mask. We then
4372 rotate back and clear off the LS group of ^^^^^^^^^^ zeros with
4373 a second rldicr. */
4374 lsb = c & -c; /* lsb == 0x0000010000000000 */
4375 m2 = -lsb; /* m2 == 0xffffff0000000000 */
4376 c = ~c; /* c == 0x00fff0ffffffffff */
4377 c &= -lsb; /* c == 0x00fff00000000000 */
4378 lsb = c & -c; /* lsb == 0x0000100000000000 */
4379 c = ~c; /* c == 0xff000fffffffffff */
4380 c &= -lsb; /* c == 0xff00000000000000 */
4381 shift = 0;
4382 while ((lsb >>= 1) != 0)
4383 shift++; /* shift == 44 on exit from loop */
4384 m1 = ~c; /* m1 == 0x00ffffffffffffff */
4385 m1 >>= shift; /* m1 == 0x0000000000000fff */
4386 m1 = ~m1; /* m1 == 0xfffffffffffff000 */
4389 /* Note that when we only have two 0->1 and 1->0 transitions, one of the
4390 masks will be all 1's. We are guaranteed more than one transition. */
4391 out[0] = GEN_INT (64 - shift);
4392 out[1] = GEN_INT (m1);
4393 out[2] = GEN_INT (shift);
4394 out[3] = GEN_INT (m2);
4395 #else
4396 (void)in;
4397 (void)out;
4398 gcc_unreachable ();
4399 #endif
4402 /* Return TRUE if OP is an invalid SUBREG operation on the e500. */
4404 bool
4405 invalid_e500_subreg (rtx op, enum machine_mode mode)
4407 if (TARGET_E500_DOUBLE)
4409 /* Reject (subreg:SI (reg:DF)); likewise with subreg:DI or
4410 subreg:TI and reg:TF. Decimal float modes are like integer
4411 modes (only low part of each register used) for this
4412 purpose. */
4413 if (GET_CODE (op) == SUBREG
4414 && (mode == SImode || mode == DImode || mode == TImode
4415 || mode == DDmode || mode == TDmode)
4416 && REG_P (SUBREG_REG (op))
4417 && (GET_MODE (SUBREG_REG (op)) == DFmode
4418 || GET_MODE (SUBREG_REG (op)) == TFmode))
4419 return true;
4421 /* Reject (subreg:DF (reg:DI)); likewise with subreg:TF and
4422 reg:TI. */
4423 if (GET_CODE (op) == SUBREG
4424 && (mode == DFmode || mode == TFmode)
4425 && REG_P (SUBREG_REG (op))
4426 && (GET_MODE (SUBREG_REG (op)) == DImode
4427 || GET_MODE (SUBREG_REG (op)) == TImode
4428 || GET_MODE (SUBREG_REG (op)) == DDmode
4429 || GET_MODE (SUBREG_REG (op)) == TDmode))
4430 return true;
4433 if (TARGET_SPE
4434 && GET_CODE (op) == SUBREG
4435 && mode == SImode
4436 && REG_P (SUBREG_REG (op))
4437 && SPE_VECTOR_MODE (GET_MODE (SUBREG_REG (op))))
4438 return true;
4440 return false;
4443 /* AIX increases natural record alignment to doubleword if the first
4444 field is an FP double while the FP fields remain word aligned. */
4446 unsigned int
4447 rs6000_special_round_type_align (tree type, unsigned int computed,
4448 unsigned int specified)
4450 unsigned int align = MAX (computed, specified);
4451 tree field = TYPE_FIELDS (type);
4453 /* Skip all non field decls */
4454 while (field != NULL && TREE_CODE (field) != FIELD_DECL)
4455 field = TREE_CHAIN (field);
4457 if (field != NULL && field != type)
4459 type = TREE_TYPE (field);
4460 while (TREE_CODE (type) == ARRAY_TYPE)
4461 type = TREE_TYPE (type);
4463 if (type != error_mark_node && TYPE_MODE (type) == DFmode)
4464 align = MAX (align, 64);
4467 return align;
4470 /* Darwin increases record alignment to the natural alignment of
4471 the first field. */
4473 unsigned int
4474 darwin_rs6000_special_round_type_align (tree type, unsigned int computed,
4475 unsigned int specified)
4477 unsigned int align = MAX (computed, specified);
4479 if (TYPE_PACKED (type))
4480 return align;
4482 /* Find the first field, looking down into aggregates. */
4483 do {
4484 tree field = TYPE_FIELDS (type);
4485 /* Skip all non field decls */
4486 while (field != NULL && TREE_CODE (field) != FIELD_DECL)
4487 field = TREE_CHAIN (field);
4488 if (! field)
4489 break;
4490 type = TREE_TYPE (field);
4491 while (TREE_CODE (type) == ARRAY_TYPE)
4492 type = TREE_TYPE (type);
4493 } while (AGGREGATE_TYPE_P (type));
4495 if (! AGGREGATE_TYPE_P (type) && type != error_mark_node)
4496 align = MAX (align, TYPE_ALIGN (type));
4498 return align;
4501 /* Return 1 for an operand in small memory on V.4/eabi. */
4504 small_data_operand (rtx op ATTRIBUTE_UNUSED,
4505 enum machine_mode mode ATTRIBUTE_UNUSED)
4507 #if TARGET_ELF
4508 rtx sym_ref;
4510 if (rs6000_sdata == SDATA_NONE || rs6000_sdata == SDATA_DATA)
4511 return 0;
4513 if (DEFAULT_ABI != ABI_V4)
4514 return 0;
4516 /* Vector and float memory instructions have a limited offset on the
4517 SPE, so using a vector or float variable directly as an operand is
4518 not useful. */
4519 if (TARGET_SPE
4520 && (SPE_VECTOR_MODE (mode) || FLOAT_MODE_P (mode)))
4521 return 0;
4523 if (GET_CODE (op) == SYMBOL_REF)
4524 sym_ref = op;
4526 else if (GET_CODE (op) != CONST
4527 || GET_CODE (XEXP (op, 0)) != PLUS
4528 || GET_CODE (XEXP (XEXP (op, 0), 0)) != SYMBOL_REF
4529 || GET_CODE (XEXP (XEXP (op, 0), 1)) != CONST_INT)
4530 return 0;
4532 else
4534 rtx sum = XEXP (op, 0);
4535 HOST_WIDE_INT summand;
4537 /* We have to be careful here, because it is the referenced address
4538 that must be 32k from _SDA_BASE_, not just the symbol. */
4539 summand = INTVAL (XEXP (sum, 1));
4540 if (summand < 0 || (unsigned HOST_WIDE_INT) summand > g_switch_value)
4541 return 0;
4543 sym_ref = XEXP (sum, 0);
4546 return SYMBOL_REF_SMALL_P (sym_ref);
4547 #else
4548 return 0;
4549 #endif
4552 /* Return true if either operand is a general purpose register. */
4554 bool
4555 gpr_or_gpr_p (rtx op0, rtx op1)
4557 return ((REG_P (op0) && INT_REGNO_P (REGNO (op0)))
4558 || (REG_P (op1) && INT_REGNO_P (REGNO (op1))));
4562 /* Subroutines of rs6000_legitimize_address and rs6000_legitimate_address_p. */
4564 static bool
4565 reg_offset_addressing_ok_p (enum machine_mode mode)
4567 switch (mode)
4569 case V16QImode:
4570 case V8HImode:
4571 case V4SFmode:
4572 case V4SImode:
4573 case V2DFmode:
4574 case V2DImode:
4575 /* AltiVec/VSX vector modes. Only reg+reg addressing is valid. */
4576 if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode))
4577 return false;
4578 break;
4580 case V4HImode:
4581 case V2SImode:
4582 case V1DImode:
4583 case V2SFmode:
4584 /* Paired vector modes. Only reg+reg addressing is valid. */
4585 if (TARGET_PAIRED_FLOAT)
4586 return false;
4587 break;
4589 default:
4590 break;
4593 return true;
4596 static bool
4597 virtual_stack_registers_memory_p (rtx op)
4599 int regnum;
4601 if (GET_CODE (op) == REG)
4602 regnum = REGNO (op);
4604 else if (GET_CODE (op) == PLUS
4605 && GET_CODE (XEXP (op, 0)) == REG
4606 && GET_CODE (XEXP (op, 1)) == CONST_INT)
4607 regnum = REGNO (XEXP (op, 0));
4609 else
4610 return false;
4612 return (regnum >= FIRST_VIRTUAL_REGISTER
4613 && regnum <= LAST_VIRTUAL_REGISTER);
4616 static bool
4617 constant_pool_expr_p (rtx op)
4619 rtx base, offset;
4621 split_const (op, &base, &offset);
4622 return (GET_CODE (base) == SYMBOL_REF
4623 && CONSTANT_POOL_ADDRESS_P (base)
4624 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (base), Pmode));
4627 bool
4628 toc_relative_expr_p (rtx op)
4630 rtx base, offset;
4632 if (GET_CODE (op) != CONST)
4633 return false;
4635 split_const (op, &base, &offset);
4636 return (GET_CODE (base) == UNSPEC
4637 && XINT (base, 1) == UNSPEC_TOCREL);
4640 bool
4641 legitimate_constant_pool_address_p (rtx x)
4643 return (TARGET_TOC
4644 && GET_CODE (x) == PLUS
4645 && GET_CODE (XEXP (x, 0)) == REG
4646 && (TARGET_MINIMAL_TOC || REGNO (XEXP (x, 0)) == TOC_REGISTER)
4647 && toc_relative_expr_p (XEXP (x, 1)));
4650 static bool
4651 legitimate_small_data_p (enum machine_mode mode, rtx x)
4653 return (DEFAULT_ABI == ABI_V4
4654 && !flag_pic && !TARGET_TOC
4655 && (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST)
4656 && small_data_operand (x, mode));
4659 /* SPE offset addressing is limited to 5-bits worth of double words. */
4660 #define SPE_CONST_OFFSET_OK(x) (((x) & ~0xf8) == 0)
4662 bool
4663 rs6000_legitimate_offset_address_p (enum machine_mode mode, rtx x, int strict)
4665 unsigned HOST_WIDE_INT offset, extra;
4667 if (GET_CODE (x) != PLUS)
4668 return false;
4669 if (GET_CODE (XEXP (x, 0)) != REG)
4670 return false;
4671 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
4672 return false;
4673 if (!reg_offset_addressing_ok_p (mode))
4674 return virtual_stack_registers_memory_p (x);
4675 if (legitimate_constant_pool_address_p (x))
4676 return true;
4677 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
4678 return false;
4680 offset = INTVAL (XEXP (x, 1));
4681 extra = 0;
4682 switch (mode)
4684 case V4HImode:
4685 case V2SImode:
4686 case V1DImode:
4687 case V2SFmode:
4688 /* SPE vector modes. */
4689 return SPE_CONST_OFFSET_OK (offset);
4691 case DFmode:
4692 if (TARGET_E500_DOUBLE)
4693 return SPE_CONST_OFFSET_OK (offset);
4695 /* If we are using VSX scalar loads, restrict ourselves to reg+reg
4696 addressing. */
4697 if (VECTOR_MEM_VSX_P (DFmode))
4698 return false;
4700 case DDmode:
4701 case DImode:
4702 /* On e500v2, we may have:
4704 (subreg:DF (mem:DI (plus (reg) (const_int))) 0).
4706 Which gets addressed with evldd instructions. */
4707 if (TARGET_E500_DOUBLE)
4708 return SPE_CONST_OFFSET_OK (offset);
4710 if (mode == DFmode || mode == DDmode || !TARGET_POWERPC64)
4711 extra = 4;
4712 else if (offset & 3)
4713 return false;
4714 break;
4716 case TFmode:
4717 if (TARGET_E500_DOUBLE)
4718 return (SPE_CONST_OFFSET_OK (offset)
4719 && SPE_CONST_OFFSET_OK (offset + 8));
4721 case TDmode:
4722 case TImode:
4723 if (mode == TFmode || mode == TDmode || !TARGET_POWERPC64)
4724 extra = 12;
4725 else if (offset & 3)
4726 return false;
4727 else
4728 extra = 8;
4729 break;
4731 default:
4732 break;
4735 offset += 0x8000;
4736 return (offset < 0x10000) && (offset + extra < 0x10000);
4739 bool
4740 legitimate_indexed_address_p (rtx x, int strict)
4742 rtx op0, op1;
4744 if (GET_CODE (x) != PLUS)
4745 return false;
4747 op0 = XEXP (x, 0);
4748 op1 = XEXP (x, 1);
4750 /* Recognize the rtl generated by reload which we know will later be
4751 replaced with proper base and index regs. */
4752 if (!strict
4753 && reload_in_progress
4754 && (REG_P (op0) || GET_CODE (op0) == PLUS)
4755 && REG_P (op1))
4756 return true;
4758 return (REG_P (op0) && REG_P (op1)
4759 && ((INT_REG_OK_FOR_BASE_P (op0, strict)
4760 && INT_REG_OK_FOR_INDEX_P (op1, strict))
4761 || (INT_REG_OK_FOR_BASE_P (op1, strict)
4762 && INT_REG_OK_FOR_INDEX_P (op0, strict))));
4765 bool
4766 avoiding_indexed_address_p (enum machine_mode mode)
4768 /* Avoid indexed addressing for modes that have non-indexed
4769 load/store instruction forms. */
4770 return (TARGET_AVOID_XFORM && VECTOR_MEM_NONE_P (mode));
4773 inline bool
4774 legitimate_indirect_address_p (rtx x, int strict)
4776 return GET_CODE (x) == REG && INT_REG_OK_FOR_BASE_P (x, strict);
4779 bool
4780 macho_lo_sum_memory_operand (rtx x, enum machine_mode mode)
4782 if (!TARGET_MACHO || !flag_pic
4783 || mode != SImode || GET_CODE (x) != MEM)
4784 return false;
4785 x = XEXP (x, 0);
4787 if (GET_CODE (x) != LO_SUM)
4788 return false;
4789 if (GET_CODE (XEXP (x, 0)) != REG)
4790 return false;
4791 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 0))
4792 return false;
4793 x = XEXP (x, 1);
4795 return CONSTANT_P (x);
4798 static bool
4799 legitimate_lo_sum_address_p (enum machine_mode mode, rtx x, int strict)
4801 if (GET_CODE (x) != LO_SUM)
4802 return false;
4803 if (GET_CODE (XEXP (x, 0)) != REG)
4804 return false;
4805 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
4806 return false;
4807 /* Restrict addressing for DI because of our SUBREG hackery. */
4808 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
4809 || mode == DDmode || mode == TDmode
4810 || mode == DImode))
4811 return false;
4812 x = XEXP (x, 1);
4814 if (TARGET_ELF || TARGET_MACHO)
4816 if (DEFAULT_ABI != ABI_AIX && DEFAULT_ABI != ABI_DARWIN && flag_pic)
4817 return false;
4818 if (TARGET_TOC)
4819 return false;
4820 if (GET_MODE_NUNITS (mode) != 1)
4821 return false;
4822 if (GET_MODE_BITSIZE (mode) > 64
4823 || (GET_MODE_BITSIZE (mode) > 32 && !TARGET_POWERPC64
4824 && !(TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
4825 && (mode == DFmode || mode == DDmode))))
4826 return false;
4828 return CONSTANT_P (x);
4831 return false;
4835 /* Try machine-dependent ways of modifying an illegitimate address
4836 to be legitimate. If we find one, return the new, valid address.
4837 This is used from only one place: `memory_address' in explow.c.
4839 OLDX is the address as it was before break_out_memory_refs was
4840 called. In some cases it is useful to look at this to decide what
4841 needs to be done.
4843 It is always safe for this function to do nothing. It exists to
4844 recognize opportunities to optimize the output.
4846 On RS/6000, first check for the sum of a register with a constant
4847 integer that is out of range. If so, generate code to add the
4848 constant with the low-order 16 bits masked to the register and force
4849 this result into another register (this can be done with `cau').
4850 Then generate an address of REG+(CONST&0xffff), allowing for the
4851 possibility of bit 16 being a one.
4853 Then check for the sum of a register and something not constant, try to
4854 load the other things into a register and return the sum. */
4856 static rtx
4857 rs6000_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
4858 enum machine_mode mode)
4860 unsigned int extra = 0;
4862 if (!reg_offset_addressing_ok_p (mode))
4864 if (virtual_stack_registers_memory_p (x))
4865 return x;
4867 /* In theory we should not be seeing addresses of the form reg+0,
4868 but just in case it is generated, optimize it away. */
4869 if (GET_CODE (x) == PLUS && XEXP (x, 1) == const0_rtx)
4870 return force_reg (Pmode, XEXP (x, 0));
4872 /* Make sure both operands are registers. */
4873 else if (GET_CODE (x) == PLUS)
4874 return gen_rtx_PLUS (Pmode,
4875 force_reg (Pmode, XEXP (x, 0)),
4876 force_reg (Pmode, XEXP (x, 1)));
4877 else
4878 return force_reg (Pmode, x);
4880 if (GET_CODE (x) == SYMBOL_REF)
4882 enum tls_model model = SYMBOL_REF_TLS_MODEL (x);
4883 if (model != 0)
4884 return rs6000_legitimize_tls_address (x, model);
4887 switch (mode)
4889 case DFmode:
4890 case DDmode:
4891 extra = 4;
4892 break;
4893 case DImode:
4894 if (!TARGET_POWERPC64)
4895 extra = 4;
4896 break;
4897 case TFmode:
4898 case TDmode:
4899 extra = 12;
4900 break;
4901 case TImode:
4902 extra = TARGET_POWERPC64 ? 8 : 12;
4903 break;
4904 default:
4905 break;
4908 if (GET_CODE (x) == PLUS
4909 && GET_CODE (XEXP (x, 0)) == REG
4910 && GET_CODE (XEXP (x, 1)) == CONST_INT
4911 && ((unsigned HOST_WIDE_INT) (INTVAL (XEXP (x, 1)) + 0x8000)
4912 >= 0x10000 - extra)
4913 && !((TARGET_POWERPC64
4914 && (mode == DImode || mode == TImode)
4915 && (INTVAL (XEXP (x, 1)) & 3) != 0)
4916 || SPE_VECTOR_MODE (mode)
4917 || (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
4918 || mode == DImode || mode == DDmode
4919 || mode == TDmode))))
4921 HOST_WIDE_INT high_int, low_int;
4922 rtx sum;
4923 low_int = ((INTVAL (XEXP (x, 1)) & 0xffff) ^ 0x8000) - 0x8000;
4924 if (low_int >= 0x8000 - extra)
4925 low_int = 0;
4926 high_int = INTVAL (XEXP (x, 1)) - low_int;
4927 sum = force_operand (gen_rtx_PLUS (Pmode, XEXP (x, 0),
4928 GEN_INT (high_int)), 0);
4929 return plus_constant (sum, low_int);
4931 else if (GET_CODE (x) == PLUS
4932 && GET_CODE (XEXP (x, 0)) == REG
4933 && GET_CODE (XEXP (x, 1)) != CONST_INT
4934 && GET_MODE_NUNITS (mode) == 1
4935 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
4936 || TARGET_POWERPC64
4937 || ((mode != DImode && mode != DFmode && mode != DDmode)
4938 || (TARGET_E500_DOUBLE && mode != DDmode)))
4939 && (TARGET_POWERPC64 || mode != DImode)
4940 && !avoiding_indexed_address_p (mode)
4941 && mode != TImode
4942 && mode != TFmode
4943 && mode != TDmode)
4945 return gen_rtx_PLUS (Pmode, XEXP (x, 0),
4946 force_reg (Pmode, force_operand (XEXP (x, 1), 0)));
4948 else if (SPE_VECTOR_MODE (mode)
4949 || (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
4950 || mode == DDmode || mode == TDmode
4951 || mode == DImode)))
4953 if (mode == DImode)
4954 return x;
4955 /* We accept [reg + reg] and [reg + OFFSET]. */
4957 if (GET_CODE (x) == PLUS)
4959 rtx op1 = XEXP (x, 0);
4960 rtx op2 = XEXP (x, 1);
4961 rtx y;
4963 op1 = force_reg (Pmode, op1);
4965 if (GET_CODE (op2) != REG
4966 && (GET_CODE (op2) != CONST_INT
4967 || !SPE_CONST_OFFSET_OK (INTVAL (op2))
4968 || (GET_MODE_SIZE (mode) > 8
4969 && !SPE_CONST_OFFSET_OK (INTVAL (op2) + 8))))
4970 op2 = force_reg (Pmode, op2);
4972 /* We can't always do [reg + reg] for these, because [reg +
4973 reg + offset] is not a legitimate addressing mode. */
4974 y = gen_rtx_PLUS (Pmode, op1, op2);
4976 if ((GET_MODE_SIZE (mode) > 8 || mode == DDmode) && REG_P (op2))
4977 return force_reg (Pmode, y);
4978 else
4979 return y;
4982 return force_reg (Pmode, x);
4984 else if (TARGET_ELF
4985 && TARGET_32BIT
4986 && TARGET_NO_TOC
4987 && ! flag_pic
4988 && GET_CODE (x) != CONST_INT
4989 && GET_CODE (x) != CONST_DOUBLE
4990 && CONSTANT_P (x)
4991 && GET_MODE_NUNITS (mode) == 1
4992 && (GET_MODE_BITSIZE (mode) <= 32
4993 || ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
4994 && (mode == DFmode || mode == DDmode))))
4996 rtx reg = gen_reg_rtx (Pmode);
4997 emit_insn (gen_elf_high (reg, x));
4998 return gen_rtx_LO_SUM (Pmode, reg, x);
5000 else if (TARGET_MACHO && TARGET_32BIT && TARGET_NO_TOC
5001 && ! flag_pic
5002 #if TARGET_MACHO
5003 && ! MACHO_DYNAMIC_NO_PIC_P
5004 #endif
5005 && GET_CODE (x) != CONST_INT
5006 && GET_CODE (x) != CONST_DOUBLE
5007 && CONSTANT_P (x)
5008 && GET_MODE_NUNITS (mode) == 1
5009 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5010 || (mode != DFmode && mode != DDmode))
5011 && mode != DImode
5012 && mode != TImode)
5014 rtx reg = gen_reg_rtx (Pmode);
5015 emit_insn (gen_macho_high (reg, x));
5016 return gen_rtx_LO_SUM (Pmode, reg, x);
5018 else if (TARGET_TOC
5019 && GET_CODE (x) == SYMBOL_REF
5020 && constant_pool_expr_p (x)
5021 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), Pmode))
5023 return create_TOC_reference (x);
5025 else
5026 return x;
5029 /* Debug version of rs6000_legitimize_address. */
5030 static rtx
5031 rs6000_debug_legitimize_address (rtx x, rtx oldx, enum machine_mode mode)
5033 rtx ret;
5034 rtx insns;
5036 start_sequence ();
5037 ret = rs6000_legitimize_address (x, oldx, mode);
5038 insns = get_insns ();
5039 end_sequence ();
5041 if (ret != x)
5043 fprintf (stderr,
5044 "\nrs6000_legitimize_address: mode %s, old code %s, "
5045 "new code %s, modified\n",
5046 GET_MODE_NAME (mode), GET_RTX_NAME (GET_CODE (x)),
5047 GET_RTX_NAME (GET_CODE (ret)));
5049 fprintf (stderr, "Original address:\n");
5050 debug_rtx (x);
5052 fprintf (stderr, "oldx:\n");
5053 debug_rtx (oldx);
5055 fprintf (stderr, "New address:\n");
5056 debug_rtx (ret);
5058 if (insns)
5060 fprintf (stderr, "Insns added:\n");
5061 debug_rtx_list (insns, 20);
5064 else
5066 fprintf (stderr,
5067 "\nrs6000_legitimize_address: mode %s, code %s, no change:\n",
5068 GET_MODE_NAME (mode), GET_RTX_NAME (GET_CODE (x)));
5070 debug_rtx (x);
5073 if (insns)
5074 emit_insn (insns);
5076 return ret;
5079 /* This is called from dwarf2out.c via TARGET_ASM_OUTPUT_DWARF_DTPREL.
5080 We need to emit DTP-relative relocations. */
5082 static void
5083 rs6000_output_dwarf_dtprel (FILE *file, int size, rtx x)
5085 switch (size)
5087 case 4:
5088 fputs ("\t.long\t", file);
5089 break;
5090 case 8:
5091 fputs (DOUBLE_INT_ASM_OP, file);
5092 break;
5093 default:
5094 gcc_unreachable ();
5096 output_addr_const (file, x);
5097 fputs ("@dtprel+0x8000", file);
5100 /* Construct the SYMBOL_REF for the tls_get_addr function. */
5102 static GTY(()) rtx rs6000_tls_symbol;
5103 static rtx
5104 rs6000_tls_get_addr (void)
5106 if (!rs6000_tls_symbol)
5107 rs6000_tls_symbol = init_one_libfunc ("__tls_get_addr");
5109 return rs6000_tls_symbol;
5112 /* Construct the SYMBOL_REF for TLS GOT references. */
5114 static GTY(()) rtx rs6000_got_symbol;
5115 static rtx
5116 rs6000_got_sym (void)
5118 if (!rs6000_got_symbol)
5120 rs6000_got_symbol = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
5121 SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_LOCAL;
5122 SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_EXTERNAL;
5125 return rs6000_got_symbol;
5128 /* ADDR contains a thread-local SYMBOL_REF. Generate code to compute
5129 this (thread-local) address. */
5131 static rtx
5132 rs6000_legitimize_tls_address (rtx addr, enum tls_model model)
5134 rtx dest, insn;
5136 dest = gen_reg_rtx (Pmode);
5137 if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 16)
5139 rtx tlsreg;
5141 if (TARGET_64BIT)
5143 tlsreg = gen_rtx_REG (Pmode, 13);
5144 insn = gen_tls_tprel_64 (dest, tlsreg, addr);
5146 else
5148 tlsreg = gen_rtx_REG (Pmode, 2);
5149 insn = gen_tls_tprel_32 (dest, tlsreg, addr);
5151 emit_insn (insn);
5153 else if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 32)
5155 rtx tlsreg, tmp;
5157 tmp = gen_reg_rtx (Pmode);
5158 if (TARGET_64BIT)
5160 tlsreg = gen_rtx_REG (Pmode, 13);
5161 insn = gen_tls_tprel_ha_64 (tmp, tlsreg, addr);
5163 else
5165 tlsreg = gen_rtx_REG (Pmode, 2);
5166 insn = gen_tls_tprel_ha_32 (tmp, tlsreg, addr);
5168 emit_insn (insn);
5169 if (TARGET_64BIT)
5170 insn = gen_tls_tprel_lo_64 (dest, tmp, addr);
5171 else
5172 insn = gen_tls_tprel_lo_32 (dest, tmp, addr);
5173 emit_insn (insn);
5175 else
5177 rtx r3, got, tga, tmp1, tmp2, eqv;
5179 /* We currently use relocations like @got@tlsgd for tls, which
5180 means the linker will handle allocation of tls entries, placing
5181 them in the .got section. So use a pointer to the .got section,
5182 not one to secondary TOC sections used by 64-bit -mminimal-toc,
5183 or to secondary GOT sections used by 32-bit -fPIC. */
5184 if (TARGET_64BIT)
5185 got = gen_rtx_REG (Pmode, 2);
5186 else
5188 if (flag_pic == 1)
5189 got = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
5190 else
5192 rtx gsym = rs6000_got_sym ();
5193 got = gen_reg_rtx (Pmode);
5194 if (flag_pic == 0)
5195 rs6000_emit_move (got, gsym, Pmode);
5196 else
5198 rtx tmp3, mem;
5199 rtx first, last;
5201 tmp1 = gen_reg_rtx (Pmode);
5202 tmp2 = gen_reg_rtx (Pmode);
5203 tmp3 = gen_reg_rtx (Pmode);
5204 mem = gen_const_mem (Pmode, tmp1);
5206 first = emit_insn (gen_load_toc_v4_PIC_1b (gsym));
5207 emit_move_insn (tmp1,
5208 gen_rtx_REG (Pmode, LR_REGNO));
5209 emit_move_insn (tmp2, mem);
5210 emit_insn (gen_addsi3 (tmp3, tmp1, tmp2));
5211 last = emit_move_insn (got, tmp3);
5212 set_unique_reg_note (last, REG_EQUAL, gsym);
5217 if (model == TLS_MODEL_GLOBAL_DYNAMIC)
5219 r3 = gen_rtx_REG (Pmode, 3);
5220 tga = rs6000_tls_get_addr ();
5222 if (DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
5223 insn = gen_tls_gd_aix64 (r3, got, addr, tga, const0_rtx);
5224 else if (DEFAULT_ABI == ABI_AIX && !TARGET_64BIT)
5225 insn = gen_tls_gd_aix32 (r3, got, addr, tga, const0_rtx);
5226 else if (DEFAULT_ABI == ABI_V4)
5227 insn = gen_tls_gd_sysvsi (r3, got, addr, tga, const0_rtx);
5228 else
5229 gcc_unreachable ();
5231 start_sequence ();
5232 insn = emit_call_insn (insn);
5233 RTL_CONST_CALL_P (insn) = 1;
5234 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), r3);
5235 if (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
5236 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), pic_offset_table_rtx);
5237 insn = get_insns ();
5238 end_sequence ();
5239 emit_libcall_block (insn, dest, r3, addr);
5241 else if (model == TLS_MODEL_LOCAL_DYNAMIC)
5243 r3 = gen_rtx_REG (Pmode, 3);
5244 tga = rs6000_tls_get_addr ();
5246 if (DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
5247 insn = gen_tls_ld_aix64 (r3, got, tga, const0_rtx);
5248 else if (DEFAULT_ABI == ABI_AIX && !TARGET_64BIT)
5249 insn = gen_tls_ld_aix32 (r3, got, tga, const0_rtx);
5250 else if (DEFAULT_ABI == ABI_V4)
5251 insn = gen_tls_ld_sysvsi (r3, got, tga, const0_rtx);
5252 else
5253 gcc_unreachable ();
5255 start_sequence ();
5256 insn = emit_call_insn (insn);
5257 RTL_CONST_CALL_P (insn) = 1;
5258 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), r3);
5259 if (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
5260 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), pic_offset_table_rtx);
5261 insn = get_insns ();
5262 end_sequence ();
5263 tmp1 = gen_reg_rtx (Pmode);
5264 eqv = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
5265 UNSPEC_TLSLD);
5266 emit_libcall_block (insn, tmp1, r3, eqv);
5267 if (rs6000_tls_size == 16)
5269 if (TARGET_64BIT)
5270 insn = gen_tls_dtprel_64 (dest, tmp1, addr);
5271 else
5272 insn = gen_tls_dtprel_32 (dest, tmp1, addr);
5274 else if (rs6000_tls_size == 32)
5276 tmp2 = gen_reg_rtx (Pmode);
5277 if (TARGET_64BIT)
5278 insn = gen_tls_dtprel_ha_64 (tmp2, tmp1, addr);
5279 else
5280 insn = gen_tls_dtprel_ha_32 (tmp2, tmp1, addr);
5281 emit_insn (insn);
5282 if (TARGET_64BIT)
5283 insn = gen_tls_dtprel_lo_64 (dest, tmp2, addr);
5284 else
5285 insn = gen_tls_dtprel_lo_32 (dest, tmp2, addr);
5287 else
5289 tmp2 = gen_reg_rtx (Pmode);
5290 if (TARGET_64BIT)
5291 insn = gen_tls_got_dtprel_64 (tmp2, got, addr);
5292 else
5293 insn = gen_tls_got_dtprel_32 (tmp2, got, addr);
5294 emit_insn (insn);
5295 insn = gen_rtx_SET (Pmode, dest,
5296 gen_rtx_PLUS (Pmode, tmp2, tmp1));
5298 emit_insn (insn);
5300 else
5302 /* IE, or 64-bit offset LE. */
5303 tmp2 = gen_reg_rtx (Pmode);
5304 if (TARGET_64BIT)
5305 insn = gen_tls_got_tprel_64 (tmp2, got, addr);
5306 else
5307 insn = gen_tls_got_tprel_32 (tmp2, got, addr);
5308 emit_insn (insn);
5309 if (TARGET_64BIT)
5310 insn = gen_tls_tls_64 (dest, tmp2, addr);
5311 else
5312 insn = gen_tls_tls_32 (dest, tmp2, addr);
5313 emit_insn (insn);
5317 return dest;
5320 /* Return 1 if X contains a thread-local symbol. */
5322 bool
5323 rs6000_tls_referenced_p (rtx x)
5325 if (! TARGET_HAVE_TLS)
5326 return false;
5328 return for_each_rtx (&x, &rs6000_tls_symbol_ref_1, 0);
5331 /* Return 1 if *X is a thread-local symbol. This is the same as
5332 rs6000_tls_symbol_ref except for the type of the unused argument. */
5334 static int
5335 rs6000_tls_symbol_ref_1 (rtx *x, void *data ATTRIBUTE_UNUSED)
5337 return RS6000_SYMBOL_REF_TLS_P (*x);
5340 /* Our implementation of LEGITIMIZE_RELOAD_ADDRESS. Returns a value to
5341 replace the input X, or the original X if no replacement is called for.
5342 The output parameter *WIN is 1 if the calling macro should goto WIN,
5343 0 if it should not.
5345 For RS/6000, we wish to handle large displacements off a base
5346 register by splitting the addend across an addiu/addis and the mem insn.
5347 This cuts number of extra insns needed from 3 to 1.
5349 On Darwin, we use this to generate code for floating point constants.
5350 A movsf_low is generated so we wind up with 2 instructions rather than 3.
5351 The Darwin code is inside #if TARGET_MACHO because only then are the
5352 machopic_* functions defined. */
5353 static rtx
5354 rs6000_legitimize_reload_address (rtx x, enum machine_mode mode,
5355 int opnum, int type,
5356 int ind_levels ATTRIBUTE_UNUSED, int *win)
5358 bool reg_offset_p = reg_offset_addressing_ok_p (mode);
5360 /* We must recognize output that we have already generated ourselves. */
5361 if (GET_CODE (x) == PLUS
5362 && GET_CODE (XEXP (x, 0)) == PLUS
5363 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
5364 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
5365 && GET_CODE (XEXP (x, 1)) == CONST_INT)
5367 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
5368 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
5369 opnum, (enum reload_type)type);
5370 *win = 1;
5371 return x;
5374 #if TARGET_MACHO
5375 if (DEFAULT_ABI == ABI_DARWIN && flag_pic
5376 && GET_CODE (x) == LO_SUM
5377 && GET_CODE (XEXP (x, 0)) == PLUS
5378 && XEXP (XEXP (x, 0), 0) == pic_offset_table_rtx
5379 && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH
5380 && XEXP (XEXP (XEXP (x, 0), 1), 0) == XEXP (x, 1)
5381 && machopic_operand_p (XEXP (x, 1)))
5383 /* Result of previous invocation of this function on Darwin
5384 floating point constant. */
5385 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
5386 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
5387 opnum, (enum reload_type)type);
5388 *win = 1;
5389 return x;
5391 #endif
5393 /* Force ld/std non-word aligned offset into base register by wrapping
5394 in offset 0. */
5395 if (GET_CODE (x) == PLUS
5396 && GET_CODE (XEXP (x, 0)) == REG
5397 && REGNO (XEXP (x, 0)) < 32
5398 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 1)
5399 && GET_CODE (XEXP (x, 1)) == CONST_INT
5400 && reg_offset_p
5401 && (INTVAL (XEXP (x, 1)) & 3) != 0
5402 && VECTOR_MEM_NONE_P (mode)
5403 && GET_MODE_SIZE (mode) >= UNITS_PER_WORD
5404 && TARGET_POWERPC64)
5406 x = gen_rtx_PLUS (GET_MODE (x), x, GEN_INT (0));
5407 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
5408 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
5409 opnum, (enum reload_type) type);
5410 *win = 1;
5411 return x;
5414 if (GET_CODE (x) == PLUS
5415 && GET_CODE (XEXP (x, 0)) == REG
5416 && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER
5417 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 1)
5418 && GET_CODE (XEXP (x, 1)) == CONST_INT
5419 && reg_offset_p
5420 && !SPE_VECTOR_MODE (mode)
5421 && !(TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
5422 || mode == DDmode || mode == TDmode
5423 || mode == DImode))
5424 && VECTOR_MEM_NONE_P (mode))
5426 HOST_WIDE_INT val = INTVAL (XEXP (x, 1));
5427 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
5428 HOST_WIDE_INT high
5429 = (((val - low) & 0xffffffff) ^ 0x80000000) - 0x80000000;
5431 /* Check for 32-bit overflow. */
5432 if (high + low != val)
5434 *win = 0;
5435 return x;
5438 /* Reload the high part into a base reg; leave the low part
5439 in the mem directly. */
5441 x = gen_rtx_PLUS (GET_MODE (x),
5442 gen_rtx_PLUS (GET_MODE (x), XEXP (x, 0),
5443 GEN_INT (high)),
5444 GEN_INT (low));
5446 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
5447 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
5448 opnum, (enum reload_type)type);
5449 *win = 1;
5450 return x;
5453 if (GET_CODE (x) == SYMBOL_REF
5454 && reg_offset_p
5455 && VECTOR_MEM_NONE_P (mode)
5456 && !SPE_VECTOR_MODE (mode)
5457 #if TARGET_MACHO
5458 && DEFAULT_ABI == ABI_DARWIN
5459 && (flag_pic || MACHO_DYNAMIC_NO_PIC_P)
5460 #else
5461 && DEFAULT_ABI == ABI_V4
5462 && !flag_pic
5463 #endif
5464 /* Don't do this for TFmode or TDmode, since the result isn't offsettable.
5465 The same goes for DImode without 64-bit gprs and DFmode and DDmode
5466 without fprs. */
5467 && mode != TFmode
5468 && mode != TDmode
5469 && (mode != DImode || TARGET_POWERPC64)
5470 && ((mode != DFmode && mode != DDmode) || TARGET_POWERPC64
5471 || (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)))
5473 #if TARGET_MACHO
5474 if (flag_pic)
5476 rtx offset = machopic_gen_offset (x);
5477 x = gen_rtx_LO_SUM (GET_MODE (x),
5478 gen_rtx_PLUS (Pmode, pic_offset_table_rtx,
5479 gen_rtx_HIGH (Pmode, offset)), offset);
5481 else
5482 #endif
5483 x = gen_rtx_LO_SUM (GET_MODE (x),
5484 gen_rtx_HIGH (Pmode, x), x);
5486 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
5487 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
5488 opnum, (enum reload_type)type);
5489 *win = 1;
5490 return x;
5493 /* Reload an offset address wrapped by an AND that represents the
5494 masking of the lower bits. Strip the outer AND and let reload
5495 convert the offset address into an indirect address. For VSX,
5496 force reload to create the address with an AND in a separate
5497 register, because we can't guarantee an altivec register will
5498 be used. */
5499 if (VECTOR_MEM_ALTIVEC_P (mode)
5500 && GET_CODE (x) == AND
5501 && GET_CODE (XEXP (x, 0)) == PLUS
5502 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
5503 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
5504 && GET_CODE (XEXP (x, 1)) == CONST_INT
5505 && INTVAL (XEXP (x, 1)) == -16)
5507 x = XEXP (x, 0);
5508 *win = 1;
5509 return x;
5512 if (TARGET_TOC
5513 && reg_offset_p
5514 && GET_CODE (x) == SYMBOL_REF
5515 && constant_pool_expr_p (x)
5516 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), mode))
5518 x = create_TOC_reference (x);
5519 *win = 1;
5520 return x;
5522 *win = 0;
5523 return x;
5526 /* Debug version of rs6000_legitimize_reload_address. */
5527 static rtx
5528 rs6000_debug_legitimize_reload_address (rtx x, enum machine_mode mode,
5529 int opnum, int type,
5530 int ind_levels, int *win)
5532 rtx ret = rs6000_legitimize_reload_address (x, mode, opnum, type,
5533 ind_levels, win);
5534 fprintf (stderr,
5535 "\nrs6000_legitimize_reload_address: mode = %s, opnum = %d, "
5536 "type = %d, ind_levels = %d, win = %d, original addr:\n",
5537 GET_MODE_NAME (mode), opnum, type, ind_levels, *win);
5538 debug_rtx (x);
5540 if (x == ret)
5541 fprintf (stderr, "Same address returned\n");
5542 else if (!ret)
5543 fprintf (stderr, "NULL returned\n");
5544 else
5546 fprintf (stderr, "New address:\n");
5547 debug_rtx (ret);
5550 return ret;
5553 /* TARGET_LEGITIMATE_ADDRESS_P recognizes an RTL expression
5554 that is a valid memory address for an instruction.
5555 The MODE argument is the machine mode for the MEM expression
5556 that wants to use this address.
5558 On the RS/6000, there are four valid address: a SYMBOL_REF that
5559 refers to a constant pool entry of an address (or the sum of it
5560 plus a constant), a short (16-bit signed) constant plus a register,
5561 the sum of two registers, or a register indirect, possibly with an
5562 auto-increment. For DFmode, DDmode and DImode with a constant plus
5563 register, we must ensure that both words are addressable or PowerPC64
5564 with offset word aligned.
5566 For modes spanning multiple registers (DFmode and DDmode in 32-bit GPRs,
5567 32-bit DImode, TImode, TFmode, TDmode), indexed addressing cannot be used
5568 because adjacent memory cells are accessed by adding word-sized offsets
5569 during assembly output. */
5570 bool
5571 rs6000_legitimate_address_p (enum machine_mode mode, rtx x, bool reg_ok_strict)
5573 bool reg_offset_p = reg_offset_addressing_ok_p (mode);
5575 /* If this is an unaligned stvx/ldvx type address, discard the outer AND. */
5576 if (VECTOR_MEM_ALTIVEC_P (mode)
5577 && GET_CODE (x) == AND
5578 && GET_CODE (XEXP (x, 1)) == CONST_INT
5579 && INTVAL (XEXP (x, 1)) == -16)
5580 x = XEXP (x, 0);
5582 if (RS6000_SYMBOL_REF_TLS_P (x))
5583 return 0;
5584 if (legitimate_indirect_address_p (x, reg_ok_strict))
5585 return 1;
5586 if ((GET_CODE (x) == PRE_INC || GET_CODE (x) == PRE_DEC)
5587 && !VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)
5588 && !SPE_VECTOR_MODE (mode)
5589 && mode != TFmode
5590 && mode != TDmode
5591 /* Restrict addressing for DI because of our SUBREG hackery. */
5592 && !(TARGET_E500_DOUBLE
5593 && (mode == DFmode || mode == DDmode || mode == DImode))
5594 && TARGET_UPDATE
5595 && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict))
5596 return 1;
5597 if (virtual_stack_registers_memory_p (x))
5598 return 1;
5599 if (reg_offset_p && legitimate_small_data_p (mode, x))
5600 return 1;
5601 if (reg_offset_p && legitimate_constant_pool_address_p (x))
5602 return 1;
5603 /* If not REG_OK_STRICT (before reload) let pass any stack offset. */
5604 if (! reg_ok_strict
5605 && reg_offset_p
5606 && GET_CODE (x) == PLUS
5607 && GET_CODE (XEXP (x, 0)) == REG
5608 && (XEXP (x, 0) == virtual_stack_vars_rtx
5609 || XEXP (x, 0) == arg_pointer_rtx)
5610 && GET_CODE (XEXP (x, 1)) == CONST_INT)
5611 return 1;
5612 if (rs6000_legitimate_offset_address_p (mode, x, reg_ok_strict))
5613 return 1;
5614 if (mode != TImode
5615 && mode != TFmode
5616 && mode != TDmode
5617 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5618 || TARGET_POWERPC64
5619 || (mode != DFmode && mode != DDmode)
5620 || (TARGET_E500_DOUBLE && mode != DDmode))
5621 && (TARGET_POWERPC64 || mode != DImode)
5622 && !avoiding_indexed_address_p (mode)
5623 && legitimate_indexed_address_p (x, reg_ok_strict))
5624 return 1;
5625 if (GET_CODE (x) == PRE_MODIFY
5626 && VECTOR_MEM_VSX_P (mode)
5627 && TARGET_UPDATE
5628 && legitimate_indexed_address_p (XEXP (x, 1), reg_ok_strict)
5629 && rtx_equal_p (XEXP (XEXP (x, 1), 0), XEXP (x, 0)))
5630 return 1;
5631 if (GET_CODE (x) == PRE_MODIFY
5632 && mode != TImode
5633 && mode != TFmode
5634 && mode != TDmode
5635 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5636 || TARGET_POWERPC64
5637 || ((mode != DFmode && mode != DDmode) || TARGET_E500_DOUBLE))
5638 && (TARGET_POWERPC64 || mode != DImode)
5639 && !VECTOR_MEM_ALTIVEC_P (mode)
5640 && !SPE_VECTOR_MODE (mode)
5641 /* Restrict addressing for DI because of our SUBREG hackery. */
5642 && !(TARGET_E500_DOUBLE
5643 && (mode == DFmode || mode == DDmode || mode == DImode))
5644 && TARGET_UPDATE
5645 && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict)
5646 && (rs6000_legitimate_offset_address_p (mode, XEXP (x, 1), reg_ok_strict)
5647 || (!avoiding_indexed_address_p (mode)
5648 && legitimate_indexed_address_p (XEXP (x, 1), reg_ok_strict)))
5649 && rtx_equal_p (XEXP (XEXP (x, 1), 0), XEXP (x, 0)))
5650 return 1;
5651 if (reg_offset_p && legitimate_lo_sum_address_p (mode, x, reg_ok_strict))
5652 return 1;
5653 return 0;
5656 /* Debug version of rs6000_legitimate_address_p. */
5657 static bool
5658 rs6000_debug_legitimate_address_p (enum machine_mode mode, rtx x,
5659 bool reg_ok_strict)
5661 bool ret = rs6000_legitimate_address_p (mode, x, reg_ok_strict);
5662 fprintf (stderr,
5663 "\nrs6000_legitimate_address_p: return = %s, mode = %s, "
5664 "strict = %d, code = %s\n",
5665 ret ? "true" : "false",
5666 GET_MODE_NAME (mode),
5667 reg_ok_strict,
5668 GET_RTX_NAME (GET_CODE (x)));
5669 debug_rtx (x);
5671 return ret;
5674 /* Go to LABEL if ADDR (a legitimate address expression)
5675 has an effect that depends on the machine mode it is used for.
5677 On the RS/6000 this is true of all integral offsets (since AltiVec
5678 and VSX modes don't allow them) or is a pre-increment or decrement.
5680 ??? Except that due to conceptual problems in offsettable_address_p
5681 we can't really report the problems of integral offsets. So leave
5682 this assuming that the adjustable offset must be valid for the
5683 sub-words of a TFmode operand, which is what we had before. */
5685 static bool
5686 rs6000_mode_dependent_address (rtx addr)
5688 switch (GET_CODE (addr))
5690 case PLUS:
5691 /* Any offset from virtual_stack_vars_rtx and arg_pointer_rtx
5692 is considered a legitimate address before reload, so there
5693 are no offset restrictions in that case. Note that this
5694 condition is safe in strict mode because any address involving
5695 virtual_stack_vars_rtx or arg_pointer_rtx would already have
5696 been rejected as illegitimate. */
5697 if (XEXP (addr, 0) != virtual_stack_vars_rtx
5698 && XEXP (addr, 0) != arg_pointer_rtx
5699 && GET_CODE (XEXP (addr, 1)) == CONST_INT)
5701 unsigned HOST_WIDE_INT val = INTVAL (XEXP (addr, 1));
5702 return val + 12 + 0x8000 >= 0x10000;
5704 break;
5706 case LO_SUM:
5707 return true;
5709 /* Auto-increment cases are now treated generically in recog.c. */
5710 case PRE_MODIFY:
5711 return TARGET_UPDATE;
5713 /* AND is only allowed in Altivec loads. */
5714 case AND:
5715 return true;
5717 default:
5718 break;
5721 return false;
5724 /* Debug version of rs6000_mode_dependent_address. */
5725 static bool
5726 rs6000_debug_mode_dependent_address (rtx addr)
5728 bool ret = rs6000_mode_dependent_address (addr);
5730 fprintf (stderr, "\nrs6000_mode_dependent_address: ret = %s\n",
5731 ret ? "true" : "false");
5732 debug_rtx (addr);
5734 return ret;
5737 /* Implement FIND_BASE_TERM. */
5740 rs6000_find_base_term (rtx op)
5742 rtx base, offset;
5744 split_const (op, &base, &offset);
5745 if (GET_CODE (base) == UNSPEC)
5746 switch (XINT (base, 1))
5748 case UNSPEC_TOCREL:
5749 case UNSPEC_MACHOPIC_OFFSET:
5750 /* OP represents SYM [+ OFFSET] - ANCHOR. SYM is the base term
5751 for aliasing purposes. */
5752 return XVECEXP (base, 0, 0);
5755 return op;
5758 /* More elaborate version of recog's offsettable_memref_p predicate
5759 that works around the ??? note of rs6000_mode_dependent_address.
5760 In particular it accepts
5762 (mem:DI (plus:SI (reg/f:SI 31 31) (const_int 32760 [0x7ff8])))
5764 in 32-bit mode, that the recog predicate rejects. */
5766 bool
5767 rs6000_offsettable_memref_p (rtx op)
5769 if (!MEM_P (op))
5770 return false;
5772 /* First mimic offsettable_memref_p. */
5773 if (offsettable_address_p (1, GET_MODE (op), XEXP (op, 0)))
5774 return true;
5776 /* offsettable_address_p invokes rs6000_mode_dependent_address, but
5777 the latter predicate knows nothing about the mode of the memory
5778 reference and, therefore, assumes that it is the largest supported
5779 mode (TFmode). As a consequence, legitimate offsettable memory
5780 references are rejected. rs6000_legitimate_offset_address_p contains
5781 the correct logic for the PLUS case of rs6000_mode_dependent_address. */
5782 return rs6000_legitimate_offset_address_p (GET_MODE (op), XEXP (op, 0), 1);
5785 /* Change register usage conditional on target flags. */
5786 void
5787 rs6000_conditional_register_usage (void)
5789 int i;
5791 /* Set MQ register fixed (already call_used) if not POWER
5792 architecture (RIOS1, RIOS2, RSC, and PPC601) so that it will not
5793 be allocated. */
5794 if (! TARGET_POWER)
5795 fixed_regs[64] = 1;
5797 /* 64-bit AIX and Linux reserve GPR13 for thread-private data. */
5798 if (TARGET_64BIT)
5799 fixed_regs[13] = call_used_regs[13]
5800 = call_really_used_regs[13] = 1;
5802 /* Conditionally disable FPRs. */
5803 if (TARGET_SOFT_FLOAT || !TARGET_FPRS)
5804 for (i = 32; i < 64; i++)
5805 fixed_regs[i] = call_used_regs[i]
5806 = call_really_used_regs[i] = 1;
5808 /* The TOC register is not killed across calls in a way that is
5809 visible to the compiler. */
5810 if (DEFAULT_ABI == ABI_AIX)
5811 call_really_used_regs[2] = 0;
5813 if (DEFAULT_ABI == ABI_V4
5814 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
5815 && flag_pic == 2)
5816 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
5818 if (DEFAULT_ABI == ABI_V4
5819 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
5820 && flag_pic == 1)
5821 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
5822 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
5823 = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
5825 if (DEFAULT_ABI == ABI_DARWIN
5826 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM)
5827 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
5828 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
5829 = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
5831 if (TARGET_TOC && TARGET_MINIMAL_TOC)
5832 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
5833 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
5835 if (TARGET_SPE)
5837 global_regs[SPEFSCR_REGNO] = 1;
5838 /* We used to use r14 as FIXED_SCRATCH to address SPE 64-bit
5839 registers in prologues and epilogues. We no longer use r14
5840 for FIXED_SCRATCH, but we're keeping r14 out of the allocation
5841 pool for link-compatibility with older versions of GCC. Once
5842 "old" code has died out, we can return r14 to the allocation
5843 pool. */
5844 fixed_regs[14]
5845 = call_used_regs[14]
5846 = call_really_used_regs[14] = 1;
5849 if (!TARGET_ALTIVEC && !TARGET_VSX)
5851 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
5852 fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1;
5853 call_really_used_regs[VRSAVE_REGNO] = 1;
5856 if (TARGET_ALTIVEC || TARGET_VSX)
5857 global_regs[VSCR_REGNO] = 1;
5859 if (TARGET_ALTIVEC_ABI)
5861 for (i = FIRST_ALTIVEC_REGNO; i < FIRST_ALTIVEC_REGNO + 20; ++i)
5862 call_used_regs[i] = call_really_used_regs[i] = 1;
5864 /* AIX reserves VR20:31 in non-extended ABI mode. */
5865 if (TARGET_XCOFF)
5866 for (i = FIRST_ALTIVEC_REGNO + 20; i < FIRST_ALTIVEC_REGNO + 32; ++i)
5867 fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1;
5871 /* Try to output insns to set TARGET equal to the constant C if it can
5872 be done in less than N insns. Do all computations in MODE.
5873 Returns the place where the output has been placed if it can be
5874 done and the insns have been emitted. If it would take more than N
5875 insns, zero is returned and no insns and emitted. */
5878 rs6000_emit_set_const (rtx dest, enum machine_mode mode,
5879 rtx source, int n ATTRIBUTE_UNUSED)
5881 rtx result, insn, set;
5882 HOST_WIDE_INT c0, c1;
5884 switch (mode)
5886 case QImode:
5887 case HImode:
5888 if (dest == NULL)
5889 dest = gen_reg_rtx (mode);
5890 emit_insn (gen_rtx_SET (VOIDmode, dest, source));
5891 return dest;
5893 case SImode:
5894 result = !can_create_pseudo_p () ? dest : gen_reg_rtx (SImode);
5896 emit_insn (gen_rtx_SET (VOIDmode, copy_rtx (result),
5897 GEN_INT (INTVAL (source)
5898 & (~ (HOST_WIDE_INT) 0xffff))));
5899 emit_insn (gen_rtx_SET (VOIDmode, dest,
5900 gen_rtx_IOR (SImode, copy_rtx (result),
5901 GEN_INT (INTVAL (source) & 0xffff))));
5902 result = dest;
5903 break;
5905 case DImode:
5906 switch (GET_CODE (source))
5908 case CONST_INT:
5909 c0 = INTVAL (source);
5910 c1 = -(c0 < 0);
5911 break;
5913 case CONST_DOUBLE:
5914 #if HOST_BITS_PER_WIDE_INT >= 64
5915 c0 = CONST_DOUBLE_LOW (source);
5916 c1 = -(c0 < 0);
5917 #else
5918 c0 = CONST_DOUBLE_LOW (source);
5919 c1 = CONST_DOUBLE_HIGH (source);
5920 #endif
5921 break;
5923 default:
5924 gcc_unreachable ();
5927 result = rs6000_emit_set_long_const (dest, c0, c1);
5928 break;
5930 default:
5931 gcc_unreachable ();
5934 insn = get_last_insn ();
5935 set = single_set (insn);
5936 if (! CONSTANT_P (SET_SRC (set)))
5937 set_unique_reg_note (insn, REG_EQUAL, source);
5939 return result;
5942 /* Having failed to find a 3 insn sequence in rs6000_emit_set_const,
5943 fall back to a straight forward decomposition. We do this to avoid
5944 exponential run times encountered when looking for longer sequences
5945 with rs6000_emit_set_const. */
5946 static rtx
5947 rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c1, HOST_WIDE_INT c2)
5949 if (!TARGET_POWERPC64)
5951 rtx operand1, operand2;
5953 operand1 = operand_subword_force (dest, WORDS_BIG_ENDIAN == 0,
5954 DImode);
5955 operand2 = operand_subword_force (copy_rtx (dest), WORDS_BIG_ENDIAN != 0,
5956 DImode);
5957 emit_move_insn (operand1, GEN_INT (c1));
5958 emit_move_insn (operand2, GEN_INT (c2));
5960 else
5962 HOST_WIDE_INT ud1, ud2, ud3, ud4;
5964 ud1 = c1 & 0xffff;
5965 ud2 = (c1 & 0xffff0000) >> 16;
5966 #if HOST_BITS_PER_WIDE_INT >= 64
5967 c2 = c1 >> 32;
5968 #endif
5969 ud3 = c2 & 0xffff;
5970 ud4 = (c2 & 0xffff0000) >> 16;
5972 if ((ud4 == 0xffff && ud3 == 0xffff && ud2 == 0xffff && (ud1 & 0x8000))
5973 || (ud4 == 0 && ud3 == 0 && ud2 == 0 && ! (ud1 & 0x8000)))
5975 if (ud1 & 0x8000)
5976 emit_move_insn (dest, GEN_INT (((ud1 ^ 0x8000) - 0x8000)));
5977 else
5978 emit_move_insn (dest, GEN_INT (ud1));
5981 else if ((ud4 == 0xffff && ud3 == 0xffff && (ud2 & 0x8000))
5982 || (ud4 == 0 && ud3 == 0 && ! (ud2 & 0x8000)))
5984 if (ud2 & 0x8000)
5985 emit_move_insn (dest, GEN_INT (((ud2 << 16) ^ 0x80000000)
5986 - 0x80000000));
5987 else
5988 emit_move_insn (dest, GEN_INT (ud2 << 16));
5989 if (ud1 != 0)
5990 emit_move_insn (copy_rtx (dest),
5991 gen_rtx_IOR (DImode, copy_rtx (dest),
5992 GEN_INT (ud1)));
5994 else if ((ud4 == 0xffff && (ud3 & 0x8000))
5995 || (ud4 == 0 && ! (ud3 & 0x8000)))
5997 if (ud3 & 0x8000)
5998 emit_move_insn (dest, GEN_INT (((ud3 << 16) ^ 0x80000000)
5999 - 0x80000000));
6000 else
6001 emit_move_insn (dest, GEN_INT (ud3 << 16));
6003 if (ud2 != 0)
6004 emit_move_insn (copy_rtx (dest),
6005 gen_rtx_IOR (DImode, copy_rtx (dest),
6006 GEN_INT (ud2)));
6007 emit_move_insn (copy_rtx (dest),
6008 gen_rtx_ASHIFT (DImode, copy_rtx (dest),
6009 GEN_INT (16)));
6010 if (ud1 != 0)
6011 emit_move_insn (copy_rtx (dest),
6012 gen_rtx_IOR (DImode, copy_rtx (dest),
6013 GEN_INT (ud1)));
6015 else
6017 if (ud4 & 0x8000)
6018 emit_move_insn (dest, GEN_INT (((ud4 << 16) ^ 0x80000000)
6019 - 0x80000000));
6020 else
6021 emit_move_insn (dest, GEN_INT (ud4 << 16));
6023 if (ud3 != 0)
6024 emit_move_insn (copy_rtx (dest),
6025 gen_rtx_IOR (DImode, copy_rtx (dest),
6026 GEN_INT (ud3)));
6028 emit_move_insn (copy_rtx (dest),
6029 gen_rtx_ASHIFT (DImode, copy_rtx (dest),
6030 GEN_INT (32)));
6031 if (ud2 != 0)
6032 emit_move_insn (copy_rtx (dest),
6033 gen_rtx_IOR (DImode, copy_rtx (dest),
6034 GEN_INT (ud2 << 16)));
6035 if (ud1 != 0)
6036 emit_move_insn (copy_rtx (dest),
6037 gen_rtx_IOR (DImode, copy_rtx (dest), GEN_INT (ud1)));
6040 return dest;
6043 /* Helper for the following. Get rid of [r+r] memory refs
6044 in cases where it won't work (TImode, TFmode, TDmode). */
6046 static void
6047 rs6000_eliminate_indexed_memrefs (rtx operands[2])
6049 if (GET_CODE (operands[0]) == MEM
6050 && GET_CODE (XEXP (operands[0], 0)) != REG
6051 && ! legitimate_constant_pool_address_p (XEXP (operands[0], 0))
6052 && ! reload_in_progress)
6053 operands[0]
6054 = replace_equiv_address (operands[0],
6055 copy_addr_to_reg (XEXP (operands[0], 0)));
6057 if (GET_CODE (operands[1]) == MEM
6058 && GET_CODE (XEXP (operands[1], 0)) != REG
6059 && ! legitimate_constant_pool_address_p (XEXP (operands[1], 0))
6060 && ! reload_in_progress)
6061 operands[1]
6062 = replace_equiv_address (operands[1],
6063 copy_addr_to_reg (XEXP (operands[1], 0)));
6066 /* Emit a move from SOURCE to DEST in mode MODE. */
6067 void
6068 rs6000_emit_move (rtx dest, rtx source, enum machine_mode mode)
6070 rtx operands[2];
6071 operands[0] = dest;
6072 operands[1] = source;
6074 if (TARGET_DEBUG_ADDR)
6076 fprintf (stderr,
6077 "\nrs6000_emit_move: mode = %s, reload_in_progress = %d, "
6078 "reload_completed = %d, can_create_pseudos = %d.\ndest:\n",
6079 GET_MODE_NAME (mode),
6080 reload_in_progress,
6081 reload_completed,
6082 can_create_pseudo_p ());
6083 debug_rtx (dest);
6084 fprintf (stderr, "source:\n");
6085 debug_rtx (source);
6088 /* Sanity checks. Check that we get CONST_DOUBLE only when we should. */
6089 if (GET_CODE (operands[1]) == CONST_DOUBLE
6090 && ! FLOAT_MODE_P (mode)
6091 && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
6093 /* FIXME. This should never happen. */
6094 /* Since it seems that it does, do the safe thing and convert
6095 to a CONST_INT. */
6096 operands[1] = gen_int_mode (CONST_DOUBLE_LOW (operands[1]), mode);
6098 gcc_assert (GET_CODE (operands[1]) != CONST_DOUBLE
6099 || FLOAT_MODE_P (mode)
6100 || ((CONST_DOUBLE_HIGH (operands[1]) != 0
6101 || CONST_DOUBLE_LOW (operands[1]) < 0)
6102 && (CONST_DOUBLE_HIGH (operands[1]) != -1
6103 || CONST_DOUBLE_LOW (operands[1]) >= 0)));
6105 /* Check if GCC is setting up a block move that will end up using FP
6106 registers as temporaries. We must make sure this is acceptable. */
6107 if (GET_CODE (operands[0]) == MEM
6108 && GET_CODE (operands[1]) == MEM
6109 && mode == DImode
6110 && (SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[0]))
6111 || SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[1])))
6112 && ! (SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[0]) > 32
6113 ? 32 : MEM_ALIGN (operands[0])))
6114 || SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[1]) > 32
6115 ? 32
6116 : MEM_ALIGN (operands[1]))))
6117 && ! MEM_VOLATILE_P (operands [0])
6118 && ! MEM_VOLATILE_P (operands [1]))
6120 emit_move_insn (adjust_address (operands[0], SImode, 0),
6121 adjust_address (operands[1], SImode, 0));
6122 emit_move_insn (adjust_address (copy_rtx (operands[0]), SImode, 4),
6123 adjust_address (copy_rtx (operands[1]), SImode, 4));
6124 return;
6127 /* Fix up invalid (const (plus (symbol_ref) (reg))) that seems to be created
6128 in the secondary_reload phase, which evidently overwrites the CONST_INT
6129 with a register. */
6130 if (GET_CODE (source) == CONST && GET_CODE (XEXP (source, 0)) == PLUS
6131 && mode == Pmode)
6133 rtx add_op0 = XEXP (XEXP (source, 0), 0);
6134 rtx add_op1 = XEXP (XEXP (source, 0), 1);
6136 if (GET_CODE (add_op0) == SYMBOL_REF && GET_CODE (add_op1) == REG)
6138 rtx tmp = (can_create_pseudo_p ()) ? gen_reg_rtx (Pmode) : dest;
6140 if (TARGET_DEBUG_ADDR)
6142 fprintf (stderr, "\nrs6000_emit_move: bad source\n");
6143 debug_rtx (source);
6146 rs6000_emit_move (tmp, add_op0, Pmode);
6147 emit_insn (gen_rtx_SET (VOIDmode, dest,
6148 gen_rtx_PLUS (Pmode, tmp, add_op1)));
6149 return;
6153 if (can_create_pseudo_p () && GET_CODE (operands[0]) == MEM
6154 && !gpc_reg_operand (operands[1], mode))
6155 operands[1] = force_reg (mode, operands[1]);
6157 if (mode == SFmode && ! TARGET_POWERPC
6158 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
6159 && GET_CODE (operands[0]) == MEM)
6161 int regnum;
6163 if (reload_in_progress || reload_completed)
6164 regnum = true_regnum (operands[1]);
6165 else if (GET_CODE (operands[1]) == REG)
6166 regnum = REGNO (operands[1]);
6167 else
6168 regnum = -1;
6170 /* If operands[1] is a register, on POWER it may have
6171 double-precision data in it, so truncate it to single
6172 precision. */
6173 if (FP_REGNO_P (regnum) || regnum >= FIRST_PSEUDO_REGISTER)
6175 rtx newreg;
6176 newreg = (!can_create_pseudo_p () ? copy_rtx (operands[1])
6177 : gen_reg_rtx (mode));
6178 emit_insn (gen_aux_truncdfsf2 (newreg, operands[1]));
6179 operands[1] = newreg;
6183 /* Recognize the case where operand[1] is a reference to thread-local
6184 data and load its address to a register. */
6185 if (rs6000_tls_referenced_p (operands[1]))
6187 enum tls_model model;
6188 rtx tmp = operands[1];
6189 rtx addend = NULL;
6191 if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
6193 addend = XEXP (XEXP (tmp, 0), 1);
6194 tmp = XEXP (XEXP (tmp, 0), 0);
6197 gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
6198 model = SYMBOL_REF_TLS_MODEL (tmp);
6199 gcc_assert (model != 0);
6201 tmp = rs6000_legitimize_tls_address (tmp, model);
6202 if (addend)
6204 tmp = gen_rtx_PLUS (mode, tmp, addend);
6205 tmp = force_operand (tmp, operands[0]);
6207 operands[1] = tmp;
6210 /* Handle the case where reload calls us with an invalid address. */
6211 if (reload_in_progress && mode == Pmode
6212 && (! general_operand (operands[1], mode)
6213 || ! nonimmediate_operand (operands[0], mode)))
6214 goto emit_set;
6216 /* 128-bit constant floating-point values on Darwin should really be
6217 loaded as two parts. */
6218 if (!TARGET_IEEEQUAD && TARGET_LONG_DOUBLE_128
6219 && mode == TFmode && GET_CODE (operands[1]) == CONST_DOUBLE)
6221 /* DImode is used, not DFmode, because simplify_gen_subreg doesn't
6222 know how to get a DFmode SUBREG of a TFmode. */
6223 enum machine_mode imode = (TARGET_E500_DOUBLE ? DFmode : DImode);
6224 rs6000_emit_move (simplify_gen_subreg (imode, operands[0], mode, 0),
6225 simplify_gen_subreg (imode, operands[1], mode, 0),
6226 imode);
6227 rs6000_emit_move (simplify_gen_subreg (imode, operands[0], mode,
6228 GET_MODE_SIZE (imode)),
6229 simplify_gen_subreg (imode, operands[1], mode,
6230 GET_MODE_SIZE (imode)),
6231 imode);
6232 return;
6235 if (reload_in_progress && cfun->machine->sdmode_stack_slot != NULL_RTX)
6236 cfun->machine->sdmode_stack_slot =
6237 eliminate_regs (cfun->machine->sdmode_stack_slot, VOIDmode, NULL_RTX);
6239 if (reload_in_progress
6240 && mode == SDmode
6241 && MEM_P (operands[0])
6242 && rtx_equal_p (operands[0], cfun->machine->sdmode_stack_slot)
6243 && REG_P (operands[1]))
6245 if (FP_REGNO_P (REGNO (operands[1])))
6247 rtx mem = adjust_address_nv (operands[0], DDmode, 0);
6248 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
6249 emit_insn (gen_movsd_store (mem, operands[1]));
6251 else if (INT_REGNO_P (REGNO (operands[1])))
6253 rtx mem = adjust_address_nv (operands[0], mode, 4);
6254 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
6255 emit_insn (gen_movsd_hardfloat (mem, operands[1]));
6257 else
6258 gcc_unreachable();
6259 return;
6261 if (reload_in_progress
6262 && mode == SDmode
6263 && REG_P (operands[0])
6264 && MEM_P (operands[1])
6265 && rtx_equal_p (operands[1], cfun->machine->sdmode_stack_slot))
6267 if (FP_REGNO_P (REGNO (operands[0])))
6269 rtx mem = adjust_address_nv (operands[1], DDmode, 0);
6270 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
6271 emit_insn (gen_movsd_load (operands[0], mem));
6273 else if (INT_REGNO_P (REGNO (operands[0])))
6275 rtx mem = adjust_address_nv (operands[1], mode, 4);
6276 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
6277 emit_insn (gen_movsd_hardfloat (operands[0], mem));
6279 else
6280 gcc_unreachable();
6281 return;
6284 /* FIXME: In the long term, this switch statement should go away
6285 and be replaced by a sequence of tests based on things like
6286 mode == Pmode. */
6287 switch (mode)
6289 case HImode:
6290 case QImode:
6291 if (CONSTANT_P (operands[1])
6292 && GET_CODE (operands[1]) != CONST_INT)
6293 operands[1] = force_const_mem (mode, operands[1]);
6294 break;
6296 case TFmode:
6297 case TDmode:
6298 rs6000_eliminate_indexed_memrefs (operands);
6299 /* fall through */
6301 case DFmode:
6302 case DDmode:
6303 case SFmode:
6304 case SDmode:
6305 if (CONSTANT_P (operands[1])
6306 && ! easy_fp_constant (operands[1], mode))
6307 operands[1] = force_const_mem (mode, operands[1]);
6308 break;
6310 case V16QImode:
6311 case V8HImode:
6312 case V4SFmode:
6313 case V4SImode:
6314 case V4HImode:
6315 case V2SFmode:
6316 case V2SImode:
6317 case V1DImode:
6318 case V2DFmode:
6319 case V2DImode:
6320 if (CONSTANT_P (operands[1])
6321 && !easy_vector_constant (operands[1], mode))
6322 operands[1] = force_const_mem (mode, operands[1]);
6323 break;
6325 case SImode:
6326 case DImode:
6327 /* Use default pattern for address of ELF small data */
6328 if (TARGET_ELF
6329 && mode == Pmode
6330 && DEFAULT_ABI == ABI_V4
6331 && (GET_CODE (operands[1]) == SYMBOL_REF
6332 || GET_CODE (operands[1]) == CONST)
6333 && small_data_operand (operands[1], mode))
6335 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
6336 return;
6339 if (DEFAULT_ABI == ABI_V4
6340 && mode == Pmode && mode == SImode
6341 && flag_pic == 1 && got_operand (operands[1], mode))
6343 emit_insn (gen_movsi_got (operands[0], operands[1]));
6344 return;
6347 if ((TARGET_ELF || DEFAULT_ABI == ABI_DARWIN)
6348 && TARGET_NO_TOC
6349 && ! flag_pic
6350 && mode == Pmode
6351 && CONSTANT_P (operands[1])
6352 && GET_CODE (operands[1]) != HIGH
6353 && GET_CODE (operands[1]) != CONST_INT)
6355 rtx target = (!can_create_pseudo_p ()
6356 ? operands[0]
6357 : gen_reg_rtx (mode));
6359 /* If this is a function address on -mcall-aixdesc,
6360 convert it to the address of the descriptor. */
6361 if (DEFAULT_ABI == ABI_AIX
6362 && GET_CODE (operands[1]) == SYMBOL_REF
6363 && XSTR (operands[1], 0)[0] == '.')
6365 const char *name = XSTR (operands[1], 0);
6366 rtx new_ref;
6367 while (*name == '.')
6368 name++;
6369 new_ref = gen_rtx_SYMBOL_REF (Pmode, name);
6370 CONSTANT_POOL_ADDRESS_P (new_ref)
6371 = CONSTANT_POOL_ADDRESS_P (operands[1]);
6372 SYMBOL_REF_FLAGS (new_ref) = SYMBOL_REF_FLAGS (operands[1]);
6373 SYMBOL_REF_USED (new_ref) = SYMBOL_REF_USED (operands[1]);
6374 SYMBOL_REF_DATA (new_ref) = SYMBOL_REF_DATA (operands[1]);
6375 operands[1] = new_ref;
6378 if (DEFAULT_ABI == ABI_DARWIN)
6380 #if TARGET_MACHO
6381 if (MACHO_DYNAMIC_NO_PIC_P)
6383 /* Take care of any required data indirection. */
6384 operands[1] = rs6000_machopic_legitimize_pic_address (
6385 operands[1], mode, operands[0]);
6386 if (operands[0] != operands[1])
6387 emit_insn (gen_rtx_SET (VOIDmode,
6388 operands[0], operands[1]));
6389 return;
6391 #endif
6392 emit_insn (gen_macho_high (target, operands[1]));
6393 emit_insn (gen_macho_low (operands[0], target, operands[1]));
6394 return;
6397 emit_insn (gen_elf_high (target, operands[1]));
6398 emit_insn (gen_elf_low (operands[0], target, operands[1]));
6399 return;
6402 /* If this is a SYMBOL_REF that refers to a constant pool entry,
6403 and we have put it in the TOC, we just need to make a TOC-relative
6404 reference to it. */
6405 if (TARGET_TOC
6406 && GET_CODE (operands[1]) == SYMBOL_REF
6407 && constant_pool_expr_p (operands[1])
6408 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (operands[1]),
6409 get_pool_mode (operands[1])))
6411 operands[1] = create_TOC_reference (operands[1]);
6413 else if (mode == Pmode
6414 && CONSTANT_P (operands[1])
6415 && ((GET_CODE (operands[1]) != CONST_INT
6416 && ! easy_fp_constant (operands[1], mode))
6417 || (GET_CODE (operands[1]) == CONST_INT
6418 && num_insns_constant (operands[1], mode) > 2)
6419 || (GET_CODE (operands[0]) == REG
6420 && FP_REGNO_P (REGNO (operands[0]))))
6421 && GET_CODE (operands[1]) != HIGH
6422 && ! legitimate_constant_pool_address_p (operands[1])
6423 && ! toc_relative_expr_p (operands[1]))
6426 #if TARGET_MACHO
6427 /* Darwin uses a special PIC legitimizer. */
6428 if (DEFAULT_ABI == ABI_DARWIN && MACHOPIC_INDIRECT)
6430 operands[1] =
6431 rs6000_machopic_legitimize_pic_address (operands[1], mode,
6432 operands[0]);
6433 if (operands[0] != operands[1])
6434 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
6435 return;
6437 #endif
6439 /* If we are to limit the number of things we put in the TOC and
6440 this is a symbol plus a constant we can add in one insn,
6441 just put the symbol in the TOC and add the constant. Don't do
6442 this if reload is in progress. */
6443 if (GET_CODE (operands[1]) == CONST
6444 && TARGET_NO_SUM_IN_TOC && ! reload_in_progress
6445 && GET_CODE (XEXP (operands[1], 0)) == PLUS
6446 && add_operand (XEXP (XEXP (operands[1], 0), 1), mode)
6447 && (GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == LABEL_REF
6448 || GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == SYMBOL_REF)
6449 && ! side_effects_p (operands[0]))
6451 rtx sym =
6452 force_const_mem (mode, XEXP (XEXP (operands[1], 0), 0));
6453 rtx other = XEXP (XEXP (operands[1], 0), 1);
6455 sym = force_reg (mode, sym);
6456 if (mode == SImode)
6457 emit_insn (gen_addsi3 (operands[0], sym, other));
6458 else
6459 emit_insn (gen_adddi3 (operands[0], sym, other));
6460 return;
6463 operands[1] = force_const_mem (mode, operands[1]);
6465 if (TARGET_TOC
6466 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
6467 && constant_pool_expr_p (XEXP (operands[1], 0))
6468 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (
6469 get_pool_constant (XEXP (operands[1], 0)),
6470 get_pool_mode (XEXP (operands[1], 0))))
6472 operands[1]
6473 = gen_const_mem (mode,
6474 create_TOC_reference (XEXP (operands[1], 0)));
6475 set_mem_alias_set (operands[1], get_TOC_alias_set ());
6478 break;
6480 case TImode:
6481 rs6000_eliminate_indexed_memrefs (operands);
6483 if (TARGET_POWER)
6485 emit_insn (gen_rtx_PARALLEL (VOIDmode,
6486 gen_rtvec (2,
6487 gen_rtx_SET (VOIDmode,
6488 operands[0], operands[1]),
6489 gen_rtx_CLOBBER (VOIDmode,
6490 gen_rtx_SCRATCH (SImode)))));
6491 return;
6493 break;
6495 default:
6496 fatal_insn ("bad move", gen_rtx_SET (VOIDmode, dest, source));
6499 /* Above, we may have called force_const_mem which may have returned
6500 an invalid address. If we can, fix this up; otherwise, reload will
6501 have to deal with it. */
6502 if (GET_CODE (operands[1]) == MEM && ! reload_in_progress)
6503 operands[1] = validize_mem (operands[1]);
6505 emit_set:
6506 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
6509 /* Nonzero if we can use a floating-point register to pass this arg. */
6510 #define USE_FP_FOR_ARG_P(CUM,MODE,TYPE) \
6511 (SCALAR_FLOAT_MODE_P (MODE) \
6512 && (CUM)->fregno <= FP_ARG_MAX_REG \
6513 && TARGET_HARD_FLOAT && TARGET_FPRS)
6515 /* Nonzero if we can use an AltiVec register to pass this arg. */
6516 #define USE_ALTIVEC_FOR_ARG_P(CUM,MODE,TYPE,NAMED) \
6517 ((ALTIVEC_VECTOR_MODE (MODE) || VSX_VECTOR_MODE (MODE)) \
6518 && (CUM)->vregno <= ALTIVEC_ARG_MAX_REG \
6519 && TARGET_ALTIVEC_ABI \
6520 && (NAMED))
6522 /* Return a nonzero value to say to return the function value in
6523 memory, just as large structures are always returned. TYPE will be
6524 the data type of the value, and FNTYPE will be the type of the
6525 function doing the returning, or @code{NULL} for libcalls.
6527 The AIX ABI for the RS/6000 specifies that all structures are
6528 returned in memory. The Darwin ABI does the same. The SVR4 ABI
6529 specifies that structures <= 8 bytes are returned in r3/r4, but a
6530 draft put them in memory, and GCC used to implement the draft
6531 instead of the final standard. Therefore, aix_struct_return
6532 controls this instead of DEFAULT_ABI; V.4 targets needing backward
6533 compatibility can change DRAFT_V4_STRUCT_RET to override the
6534 default, and -m switches get the final word. See
6535 rs6000_override_options for more details.
6537 The PPC32 SVR4 ABI uses IEEE double extended for long double, if 128-bit
6538 long double support is enabled. These values are returned in memory.
6540 int_size_in_bytes returns -1 for variable size objects, which go in
6541 memory always. The cast to unsigned makes -1 > 8. */
6543 static bool
6544 rs6000_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
6546 /* In the darwin64 abi, try to use registers for larger structs
6547 if possible. */
6548 if (rs6000_darwin64_abi
6549 && TREE_CODE (type) == RECORD_TYPE
6550 && int_size_in_bytes (type) > 0)
6552 CUMULATIVE_ARGS valcum;
6553 rtx valret;
6555 valcum.words = 0;
6556 valcum.fregno = FP_ARG_MIN_REG;
6557 valcum.vregno = ALTIVEC_ARG_MIN_REG;
6558 /* Do a trial code generation as if this were going to be passed
6559 as an argument; if any part goes in memory, we return NULL. */
6560 valret = rs6000_darwin64_record_arg (&valcum, type, 1, true);
6561 if (valret)
6562 return false;
6563 /* Otherwise fall through to more conventional ABI rules. */
6566 if (AGGREGATE_TYPE_P (type)
6567 && (aix_struct_return
6568 || (unsigned HOST_WIDE_INT) int_size_in_bytes (type) > 8))
6569 return true;
6571 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
6572 modes only exist for GCC vector types if -maltivec. */
6573 if (TARGET_32BIT && !TARGET_ALTIVEC_ABI
6574 && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
6575 return false;
6577 /* Return synthetic vectors in memory. */
6578 if (TREE_CODE (type) == VECTOR_TYPE
6579 && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
6581 static bool warned_for_return_big_vectors = false;
6582 if (!warned_for_return_big_vectors)
6584 warning (0, "GCC vector returned by reference: "
6585 "non-standard ABI extension with no compatibility guarantee");
6586 warned_for_return_big_vectors = true;
6588 return true;
6591 if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && TYPE_MODE (type) == TFmode)
6592 return true;
6594 return false;
6597 /* Initialize a variable CUM of type CUMULATIVE_ARGS
6598 for a call to a function whose data type is FNTYPE.
6599 For a library call, FNTYPE is 0.
6601 For incoming args we set the number of arguments in the prototype large
6602 so we never return a PARALLEL. */
6604 void
6605 init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype,
6606 rtx libname ATTRIBUTE_UNUSED, int incoming,
6607 int libcall, int n_named_args)
6609 static CUMULATIVE_ARGS zero_cumulative;
6611 *cum = zero_cumulative;
6612 cum->words = 0;
6613 cum->fregno = FP_ARG_MIN_REG;
6614 cum->vregno = ALTIVEC_ARG_MIN_REG;
6615 cum->prototype = (fntype && TYPE_ARG_TYPES (fntype));
6616 cum->call_cookie = ((DEFAULT_ABI == ABI_V4 && libcall)
6617 ? CALL_LIBCALL : CALL_NORMAL);
6618 cum->sysv_gregno = GP_ARG_MIN_REG;
6619 cum->stdarg = fntype
6620 && (TYPE_ARG_TYPES (fntype) != 0
6621 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
6622 != void_type_node));
6624 cum->nargs_prototype = 0;
6625 if (incoming || cum->prototype)
6626 cum->nargs_prototype = n_named_args;
6628 /* Check for a longcall attribute. */
6629 if ((!fntype && rs6000_default_long_calls)
6630 || (fntype
6631 && lookup_attribute ("longcall", TYPE_ATTRIBUTES (fntype))
6632 && !lookup_attribute ("shortcall", TYPE_ATTRIBUTES (fntype))))
6633 cum->call_cookie |= CALL_LONG;
6635 if (TARGET_DEBUG_ARG)
6637 fprintf (stderr, "\ninit_cumulative_args:");
6638 if (fntype)
6640 tree ret_type = TREE_TYPE (fntype);
6641 fprintf (stderr, " ret code = %s,",
6642 tree_code_name[ (int)TREE_CODE (ret_type) ]);
6645 if (cum->call_cookie & CALL_LONG)
6646 fprintf (stderr, " longcall,");
6648 fprintf (stderr, " proto = %d, nargs = %d\n",
6649 cum->prototype, cum->nargs_prototype);
6652 if (fntype
6653 && !TARGET_ALTIVEC
6654 && TARGET_ALTIVEC_ABI
6655 && ALTIVEC_VECTOR_MODE (TYPE_MODE (TREE_TYPE (fntype))))
6657 error ("cannot return value in vector register because"
6658 " altivec instructions are disabled, use -maltivec"
6659 " to enable them");
6663 /* Return true if TYPE must be passed on the stack and not in registers. */
6665 static bool
6666 rs6000_must_pass_in_stack (enum machine_mode mode, const_tree type)
6668 if (DEFAULT_ABI == ABI_AIX || TARGET_64BIT)
6669 return must_pass_in_stack_var_size (mode, type);
6670 else
6671 return must_pass_in_stack_var_size_or_pad (mode, type);
6674 /* If defined, a C expression which determines whether, and in which
6675 direction, to pad out an argument with extra space. The value
6676 should be of type `enum direction': either `upward' to pad above
6677 the argument, `downward' to pad below, or `none' to inhibit
6678 padding.
6680 For the AIX ABI structs are always stored left shifted in their
6681 argument slot. */
6683 enum direction
6684 function_arg_padding (enum machine_mode mode, const_tree type)
6686 #ifndef AGGREGATE_PADDING_FIXED
6687 #define AGGREGATE_PADDING_FIXED 0
6688 #endif
6689 #ifndef AGGREGATES_PAD_UPWARD_ALWAYS
6690 #define AGGREGATES_PAD_UPWARD_ALWAYS 0
6691 #endif
6693 if (!AGGREGATE_PADDING_FIXED)
6695 /* GCC used to pass structures of the same size as integer types as
6696 if they were in fact integers, ignoring FUNCTION_ARG_PADDING.
6697 i.e. Structures of size 1 or 2 (or 4 when TARGET_64BIT) were
6698 passed padded downward, except that -mstrict-align further
6699 muddied the water in that multi-component structures of 2 and 4
6700 bytes in size were passed padded upward.
6702 The following arranges for best compatibility with previous
6703 versions of gcc, but removes the -mstrict-align dependency. */
6704 if (BYTES_BIG_ENDIAN)
6706 HOST_WIDE_INT size = 0;
6708 if (mode == BLKmode)
6710 if (type && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST)
6711 size = int_size_in_bytes (type);
6713 else
6714 size = GET_MODE_SIZE (mode);
6716 if (size == 1 || size == 2 || size == 4)
6717 return downward;
6719 return upward;
6722 if (AGGREGATES_PAD_UPWARD_ALWAYS)
6724 if (type != 0 && AGGREGATE_TYPE_P (type))
6725 return upward;
6728 /* Fall back to the default. */
6729 return DEFAULT_FUNCTION_ARG_PADDING (mode, type);
6732 /* If defined, a C expression that gives the alignment boundary, in bits,
6733 of an argument with the specified mode and type. If it is not defined,
6734 PARM_BOUNDARY is used for all arguments.
6736 V.4 wants long longs and doubles to be double word aligned. Just
6737 testing the mode size is a boneheaded way to do this as it means
6738 that other types such as complex int are also double word aligned.
6739 However, we're stuck with this because changing the ABI might break
6740 existing library interfaces.
6742 Doubleword align SPE vectors.
6743 Quadword align Altivec vectors.
6744 Quadword align large synthetic vector types. */
6747 function_arg_boundary (enum machine_mode mode, tree type)
6749 if (DEFAULT_ABI == ABI_V4
6750 && (GET_MODE_SIZE (mode) == 8
6751 || (TARGET_HARD_FLOAT
6752 && TARGET_FPRS
6753 && (mode == TFmode || mode == TDmode))))
6754 return 64;
6755 else if (SPE_VECTOR_MODE (mode)
6756 || (type && TREE_CODE (type) == VECTOR_TYPE
6757 && int_size_in_bytes (type) >= 8
6758 && int_size_in_bytes (type) < 16))
6759 return 64;
6760 else if ((ALTIVEC_VECTOR_MODE (mode) || VSX_VECTOR_MODE (mode))
6761 || (type && TREE_CODE (type) == VECTOR_TYPE
6762 && int_size_in_bytes (type) >= 16))
6763 return 128;
6764 else if (rs6000_darwin64_abi && mode == BLKmode
6765 && type && TYPE_ALIGN (type) > 64)
6766 return 128;
6767 else
6768 return PARM_BOUNDARY;
6771 /* For a function parm of MODE and TYPE, return the starting word in
6772 the parameter area. NWORDS of the parameter area are already used. */
6774 static unsigned int
6775 rs6000_parm_start (enum machine_mode mode, tree type, unsigned int nwords)
6777 unsigned int align;
6778 unsigned int parm_offset;
6780 align = function_arg_boundary (mode, type) / PARM_BOUNDARY - 1;
6781 parm_offset = DEFAULT_ABI == ABI_V4 ? 2 : 6;
6782 return nwords + (-(parm_offset + nwords) & align);
6785 /* Compute the size (in words) of a function argument. */
6787 static unsigned long
6788 rs6000_arg_size (enum machine_mode mode, tree type)
6790 unsigned long size;
6792 if (mode != BLKmode)
6793 size = GET_MODE_SIZE (mode);
6794 else
6795 size = int_size_in_bytes (type);
6797 if (TARGET_32BIT)
6798 return (size + 3) >> 2;
6799 else
6800 return (size + 7) >> 3;
6803 /* Use this to flush pending int fields. */
6805 static void
6806 rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS *cum,
6807 HOST_WIDE_INT bitpos)
6809 unsigned int startbit, endbit;
6810 int intregs, intoffset;
6811 enum machine_mode mode;
6813 if (cum->intoffset == -1)
6814 return;
6816 intoffset = cum->intoffset;
6817 cum->intoffset = -1;
6819 if (intoffset % BITS_PER_WORD != 0)
6821 mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD,
6822 MODE_INT, 0);
6823 if (mode == BLKmode)
6825 /* We couldn't find an appropriate mode, which happens,
6826 e.g., in packed structs when there are 3 bytes to load.
6827 Back intoffset back to the beginning of the word in this
6828 case. */
6829 intoffset = intoffset & -BITS_PER_WORD;
6833 startbit = intoffset & -BITS_PER_WORD;
6834 endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD;
6835 intregs = (endbit - startbit) / BITS_PER_WORD;
6836 cum->words += intregs;
6839 /* The darwin64 ABI calls for us to recurse down through structs,
6840 looking for elements passed in registers. Unfortunately, we have
6841 to track int register count here also because of misalignments
6842 in powerpc alignment mode. */
6844 static void
6845 rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS *cum,
6846 tree type,
6847 HOST_WIDE_INT startbitpos)
6849 tree f;
6851 for (f = TYPE_FIELDS (type); f ; f = TREE_CHAIN (f))
6852 if (TREE_CODE (f) == FIELD_DECL)
6854 HOST_WIDE_INT bitpos = startbitpos;
6855 tree ftype = TREE_TYPE (f);
6856 enum machine_mode mode;
6857 if (ftype == error_mark_node)
6858 continue;
6859 mode = TYPE_MODE (ftype);
6861 if (DECL_SIZE (f) != 0
6862 && host_integerp (bit_position (f), 1))
6863 bitpos += int_bit_position (f);
6865 /* ??? FIXME: else assume zero offset. */
6867 if (TREE_CODE (ftype) == RECORD_TYPE)
6868 rs6000_darwin64_record_arg_advance_recurse (cum, ftype, bitpos);
6869 else if (USE_FP_FOR_ARG_P (cum, mode, ftype))
6871 rs6000_darwin64_record_arg_advance_flush (cum, bitpos);
6872 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
6873 cum->words += (GET_MODE_SIZE (mode) + 7) >> 3;
6875 else if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, 1))
6877 rs6000_darwin64_record_arg_advance_flush (cum, bitpos);
6878 cum->vregno++;
6879 cum->words += 2;
6881 else if (cum->intoffset == -1)
6882 cum->intoffset = bitpos;
6886 /* Update the data in CUM to advance over an argument
6887 of mode MODE and data type TYPE.
6888 (TYPE is null for libcalls where that information may not be available.)
6890 Note that for args passed by reference, function_arg will be called
6891 with MODE and TYPE set to that of the pointer to the arg, not the arg
6892 itself. */
6894 void
6895 function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
6896 tree type, int named, int depth)
6898 int size;
6900 /* Only tick off an argument if we're not recursing. */
6901 if (depth == 0)
6902 cum->nargs_prototype--;
6904 if (TARGET_ALTIVEC_ABI
6905 && (ALTIVEC_VECTOR_MODE (mode)
6906 || VSX_VECTOR_MODE (mode)
6907 || (type && TREE_CODE (type) == VECTOR_TYPE
6908 && int_size_in_bytes (type) == 16)))
6910 bool stack = false;
6912 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
6914 cum->vregno++;
6915 if (!TARGET_ALTIVEC)
6916 error ("cannot pass argument in vector register because"
6917 " altivec instructions are disabled, use -maltivec"
6918 " to enable them");
6920 /* PowerPC64 Linux and AIX allocate GPRs for a vector argument
6921 even if it is going to be passed in a vector register.
6922 Darwin does the same for variable-argument functions. */
6923 if ((DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
6924 || (cum->stdarg && DEFAULT_ABI != ABI_V4))
6925 stack = true;
6927 else
6928 stack = true;
6930 if (stack)
6932 int align;
6934 /* Vector parameters must be 16-byte aligned. This places
6935 them at 2 mod 4 in terms of words in 32-bit mode, since
6936 the parameter save area starts at offset 24 from the
6937 stack. In 64-bit mode, they just have to start on an
6938 even word, since the parameter save area is 16-byte
6939 aligned. Space for GPRs is reserved even if the argument
6940 will be passed in memory. */
6941 if (TARGET_32BIT)
6942 align = (2 - cum->words) & 3;
6943 else
6944 align = cum->words & 1;
6945 cum->words += align + rs6000_arg_size (mode, type);
6947 if (TARGET_DEBUG_ARG)
6949 fprintf (stderr, "function_adv: words = %2d, align=%d, ",
6950 cum->words, align);
6951 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s\n",
6952 cum->nargs_prototype, cum->prototype,
6953 GET_MODE_NAME (mode));
6957 else if (TARGET_SPE_ABI && TARGET_SPE && SPE_VECTOR_MODE (mode)
6958 && !cum->stdarg
6959 && cum->sysv_gregno <= GP_ARG_MAX_REG)
6960 cum->sysv_gregno++;
6962 else if (rs6000_darwin64_abi
6963 && mode == BLKmode
6964 && TREE_CODE (type) == RECORD_TYPE
6965 && (size = int_size_in_bytes (type)) > 0)
6967 /* Variable sized types have size == -1 and are
6968 treated as if consisting entirely of ints.
6969 Pad to 16 byte boundary if needed. */
6970 if (TYPE_ALIGN (type) >= 2 * BITS_PER_WORD
6971 && (cum->words % 2) != 0)
6972 cum->words++;
6973 /* For varargs, we can just go up by the size of the struct. */
6974 if (!named)
6975 cum->words += (size + 7) / 8;
6976 else
6978 /* It is tempting to say int register count just goes up by
6979 sizeof(type)/8, but this is wrong in a case such as
6980 { int; double; int; } [powerpc alignment]. We have to
6981 grovel through the fields for these too. */
6982 cum->intoffset = 0;
6983 rs6000_darwin64_record_arg_advance_recurse (cum, type, 0);
6984 rs6000_darwin64_record_arg_advance_flush (cum,
6985 size * BITS_PER_UNIT);
6988 else if (DEFAULT_ABI == ABI_V4)
6990 if (TARGET_HARD_FLOAT && TARGET_FPRS
6991 && ((TARGET_SINGLE_FLOAT && mode == SFmode)
6992 || (TARGET_DOUBLE_FLOAT && mode == DFmode)
6993 || (mode == TFmode && !TARGET_IEEEQUAD)
6994 || mode == SDmode || mode == DDmode || mode == TDmode))
6996 /* _Decimal128 must use an even/odd register pair. This assumes
6997 that the register number is odd when fregno is odd. */
6998 if (mode == TDmode && (cum->fregno % 2) == 1)
6999 cum->fregno++;
7001 if (cum->fregno + (mode == TFmode || mode == TDmode ? 1 : 0)
7002 <= FP_ARG_V4_MAX_REG)
7003 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
7004 else
7006 cum->fregno = FP_ARG_V4_MAX_REG + 1;
7007 if (mode == DFmode || mode == TFmode
7008 || mode == DDmode || mode == TDmode)
7009 cum->words += cum->words & 1;
7010 cum->words += rs6000_arg_size (mode, type);
7013 else
7015 int n_words = rs6000_arg_size (mode, type);
7016 int gregno = cum->sysv_gregno;
7018 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
7019 (r7,r8) or (r9,r10). As does any other 2 word item such
7020 as complex int due to a historical mistake. */
7021 if (n_words == 2)
7022 gregno += (1 - gregno) & 1;
7024 /* Multi-reg args are not split between registers and stack. */
7025 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
7027 /* Long long and SPE vectors are aligned on the stack.
7028 So are other 2 word items such as complex int due to
7029 a historical mistake. */
7030 if (n_words == 2)
7031 cum->words += cum->words & 1;
7032 cum->words += n_words;
7035 /* Note: continuing to accumulate gregno past when we've started
7036 spilling to the stack indicates the fact that we've started
7037 spilling to the stack to expand_builtin_saveregs. */
7038 cum->sysv_gregno = gregno + n_words;
7041 if (TARGET_DEBUG_ARG)
7043 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
7044 cum->words, cum->fregno);
7045 fprintf (stderr, "gregno = %2d, nargs = %4d, proto = %d, ",
7046 cum->sysv_gregno, cum->nargs_prototype, cum->prototype);
7047 fprintf (stderr, "mode = %4s, named = %d\n",
7048 GET_MODE_NAME (mode), named);
7051 else
7053 int n_words = rs6000_arg_size (mode, type);
7054 int start_words = cum->words;
7055 int align_words = rs6000_parm_start (mode, type, start_words);
7057 cum->words = align_words + n_words;
7059 if (SCALAR_FLOAT_MODE_P (mode)
7060 && TARGET_HARD_FLOAT && TARGET_FPRS)
7062 /* _Decimal128 must be passed in an even/odd float register pair.
7063 This assumes that the register number is odd when fregno is
7064 odd. */
7065 if (mode == TDmode && (cum->fregno % 2) == 1)
7066 cum->fregno++;
7067 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
7070 if (TARGET_DEBUG_ARG)
7072 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
7073 cum->words, cum->fregno);
7074 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s, ",
7075 cum->nargs_prototype, cum->prototype, GET_MODE_NAME (mode));
7076 fprintf (stderr, "named = %d, align = %d, depth = %d\n",
7077 named, align_words - start_words, depth);
7082 static rtx
7083 spe_build_register_parallel (enum machine_mode mode, int gregno)
7085 rtx r1, r3, r5, r7;
7087 switch (mode)
7089 case DFmode:
7090 r1 = gen_rtx_REG (DImode, gregno);
7091 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
7092 return gen_rtx_PARALLEL (mode, gen_rtvec (1, r1));
7094 case DCmode:
7095 case TFmode:
7096 r1 = gen_rtx_REG (DImode, gregno);
7097 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
7098 r3 = gen_rtx_REG (DImode, gregno + 2);
7099 r3 = gen_rtx_EXPR_LIST (VOIDmode, r3, GEN_INT (8));
7100 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r3));
7102 case TCmode:
7103 r1 = gen_rtx_REG (DImode, gregno);
7104 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
7105 r3 = gen_rtx_REG (DImode, gregno + 2);
7106 r3 = gen_rtx_EXPR_LIST (VOIDmode, r3, GEN_INT (8));
7107 r5 = gen_rtx_REG (DImode, gregno + 4);
7108 r5 = gen_rtx_EXPR_LIST (VOIDmode, r5, GEN_INT (16));
7109 r7 = gen_rtx_REG (DImode, gregno + 6);
7110 r7 = gen_rtx_EXPR_LIST (VOIDmode, r7, GEN_INT (24));
7111 return gen_rtx_PARALLEL (mode, gen_rtvec (4, r1, r3, r5, r7));
7113 default:
7114 gcc_unreachable ();
7118 /* Determine where to put a SIMD argument on the SPE. */
7119 static rtx
7120 rs6000_spe_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
7121 tree type)
7123 int gregno = cum->sysv_gregno;
7125 /* On E500 v2, double arithmetic is done on the full 64-bit GPR, but
7126 are passed and returned in a pair of GPRs for ABI compatibility. */
7127 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
7128 || mode == DCmode || mode == TCmode))
7130 int n_words = rs6000_arg_size (mode, type);
7132 /* Doubles go in an odd/even register pair (r5/r6, etc). */
7133 if (mode == DFmode)
7134 gregno += (1 - gregno) & 1;
7136 /* Multi-reg args are not split between registers and stack. */
7137 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
7138 return NULL_RTX;
7140 return spe_build_register_parallel (mode, gregno);
7142 if (cum->stdarg)
7144 int n_words = rs6000_arg_size (mode, type);
7146 /* SPE vectors are put in odd registers. */
7147 if (n_words == 2 && (gregno & 1) == 0)
7148 gregno += 1;
7150 if (gregno + n_words - 1 <= GP_ARG_MAX_REG)
7152 rtx r1, r2;
7153 enum machine_mode m = SImode;
7155 r1 = gen_rtx_REG (m, gregno);
7156 r1 = gen_rtx_EXPR_LIST (m, r1, const0_rtx);
7157 r2 = gen_rtx_REG (m, gregno + 1);
7158 r2 = gen_rtx_EXPR_LIST (m, r2, GEN_INT (4));
7159 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
7161 else
7162 return NULL_RTX;
7164 else
7166 if (gregno <= GP_ARG_MAX_REG)
7167 return gen_rtx_REG (mode, gregno);
7168 else
7169 return NULL_RTX;
7173 /* A subroutine of rs6000_darwin64_record_arg. Assign the bits of the
7174 structure between cum->intoffset and bitpos to integer registers. */
7176 static void
7177 rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS *cum,
7178 HOST_WIDE_INT bitpos, rtx rvec[], int *k)
7180 enum machine_mode mode;
7181 unsigned int regno;
7182 unsigned int startbit, endbit;
7183 int this_regno, intregs, intoffset;
7184 rtx reg;
7186 if (cum->intoffset == -1)
7187 return;
7189 intoffset = cum->intoffset;
7190 cum->intoffset = -1;
7192 /* If this is the trailing part of a word, try to only load that
7193 much into the register. Otherwise load the whole register. Note
7194 that in the latter case we may pick up unwanted bits. It's not a
7195 problem at the moment but may wish to revisit. */
7197 if (intoffset % BITS_PER_WORD != 0)
7199 mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD,
7200 MODE_INT, 0);
7201 if (mode == BLKmode)
7203 /* We couldn't find an appropriate mode, which happens,
7204 e.g., in packed structs when there are 3 bytes to load.
7205 Back intoffset back to the beginning of the word in this
7206 case. */
7207 intoffset = intoffset & -BITS_PER_WORD;
7208 mode = word_mode;
7211 else
7212 mode = word_mode;
7214 startbit = intoffset & -BITS_PER_WORD;
7215 endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD;
7216 intregs = (endbit - startbit) / BITS_PER_WORD;
7217 this_regno = cum->words + intoffset / BITS_PER_WORD;
7219 if (intregs > 0 && intregs > GP_ARG_NUM_REG - this_regno)
7220 cum->use_stack = 1;
7222 intregs = MIN (intregs, GP_ARG_NUM_REG - this_regno);
7223 if (intregs <= 0)
7224 return;
7226 intoffset /= BITS_PER_UNIT;
7229 regno = GP_ARG_MIN_REG + this_regno;
7230 reg = gen_rtx_REG (mode, regno);
7231 rvec[(*k)++] =
7232 gen_rtx_EXPR_LIST (VOIDmode, reg, GEN_INT (intoffset));
7234 this_regno += 1;
7235 intoffset = (intoffset | (UNITS_PER_WORD-1)) + 1;
7236 mode = word_mode;
7237 intregs -= 1;
7239 while (intregs > 0);
7242 /* Recursive workhorse for the following. */
7244 static void
7245 rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *cum, const_tree type,
7246 HOST_WIDE_INT startbitpos, rtx rvec[],
7247 int *k)
7249 tree f;
7251 for (f = TYPE_FIELDS (type); f ; f = TREE_CHAIN (f))
7252 if (TREE_CODE (f) == FIELD_DECL)
7254 HOST_WIDE_INT bitpos = startbitpos;
7255 tree ftype = TREE_TYPE (f);
7256 enum machine_mode mode;
7257 if (ftype == error_mark_node)
7258 continue;
7259 mode = TYPE_MODE (ftype);
7261 if (DECL_SIZE (f) != 0
7262 && host_integerp (bit_position (f), 1))
7263 bitpos += int_bit_position (f);
7265 /* ??? FIXME: else assume zero offset. */
7267 if (TREE_CODE (ftype) == RECORD_TYPE)
7268 rs6000_darwin64_record_arg_recurse (cum, ftype, bitpos, rvec, k);
7269 else if (cum->named && USE_FP_FOR_ARG_P (cum, mode, ftype))
7271 #if 0
7272 switch (mode)
7274 case SCmode: mode = SFmode; break;
7275 case DCmode: mode = DFmode; break;
7276 case TCmode: mode = TFmode; break;
7277 default: break;
7279 #endif
7280 rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
7281 rvec[(*k)++]
7282 = gen_rtx_EXPR_LIST (VOIDmode,
7283 gen_rtx_REG (mode, cum->fregno++),
7284 GEN_INT (bitpos / BITS_PER_UNIT));
7285 if (mode == TFmode || mode == TDmode)
7286 cum->fregno++;
7288 else if (cum->named && USE_ALTIVEC_FOR_ARG_P (cum, mode, ftype, 1))
7290 rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
7291 rvec[(*k)++]
7292 = gen_rtx_EXPR_LIST (VOIDmode,
7293 gen_rtx_REG (mode, cum->vregno++),
7294 GEN_INT (bitpos / BITS_PER_UNIT));
7296 else if (cum->intoffset == -1)
7297 cum->intoffset = bitpos;
7301 /* For the darwin64 ABI, we want to construct a PARALLEL consisting of
7302 the register(s) to be used for each field and subfield of a struct
7303 being passed by value, along with the offset of where the
7304 register's value may be found in the block. FP fields go in FP
7305 register, vector fields go in vector registers, and everything
7306 else goes in int registers, packed as in memory.
7308 This code is also used for function return values. RETVAL indicates
7309 whether this is the case.
7311 Much of this is taken from the SPARC V9 port, which has a similar
7312 calling convention. */
7314 static rtx
7315 rs6000_darwin64_record_arg (CUMULATIVE_ARGS *orig_cum, const_tree type,
7316 int named, bool retval)
7318 rtx rvec[FIRST_PSEUDO_REGISTER];
7319 int k = 1, kbase = 1;
7320 HOST_WIDE_INT typesize = int_size_in_bytes (type);
7321 /* This is a copy; modifications are not visible to our caller. */
7322 CUMULATIVE_ARGS copy_cum = *orig_cum;
7323 CUMULATIVE_ARGS *cum = &copy_cum;
7325 /* Pad to 16 byte boundary if needed. */
7326 if (!retval && TYPE_ALIGN (type) >= 2 * BITS_PER_WORD
7327 && (cum->words % 2) != 0)
7328 cum->words++;
7330 cum->intoffset = 0;
7331 cum->use_stack = 0;
7332 cum->named = named;
7334 /* Put entries into rvec[] for individual FP and vector fields, and
7335 for the chunks of memory that go in int regs. Note we start at
7336 element 1; 0 is reserved for an indication of using memory, and
7337 may or may not be filled in below. */
7338 rs6000_darwin64_record_arg_recurse (cum, type, 0, rvec, &k);
7339 rs6000_darwin64_record_arg_flush (cum, typesize * BITS_PER_UNIT, rvec, &k);
7341 /* If any part of the struct went on the stack put all of it there.
7342 This hack is because the generic code for
7343 FUNCTION_ARG_PARTIAL_NREGS cannot handle cases where the register
7344 parts of the struct are not at the beginning. */
7345 if (cum->use_stack)
7347 if (retval)
7348 return NULL_RTX; /* doesn't go in registers at all */
7349 kbase = 0;
7350 rvec[0] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
7352 if (k > 1 || cum->use_stack)
7353 return gen_rtx_PARALLEL (BLKmode, gen_rtvec_v (k - kbase, &rvec[kbase]));
7354 else
7355 return NULL_RTX;
7358 /* Determine where to place an argument in 64-bit mode with 32-bit ABI. */
7360 static rtx
7361 rs6000_mixed_function_arg (enum machine_mode mode, tree type, int align_words)
7363 int n_units;
7364 int i, k;
7365 rtx rvec[GP_ARG_NUM_REG + 1];
7367 if (align_words >= GP_ARG_NUM_REG)
7368 return NULL_RTX;
7370 n_units = rs6000_arg_size (mode, type);
7372 /* Optimize the simple case where the arg fits in one gpr, except in
7373 the case of BLKmode due to assign_parms assuming that registers are
7374 BITS_PER_WORD wide. */
7375 if (n_units == 0
7376 || (n_units == 1 && mode != BLKmode))
7377 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
7379 k = 0;
7380 if (align_words + n_units > GP_ARG_NUM_REG)
7381 /* Not all of the arg fits in gprs. Say that it goes in memory too,
7382 using a magic NULL_RTX component.
7383 This is not strictly correct. Only some of the arg belongs in
7384 memory, not all of it. However, the normal scheme using
7385 function_arg_partial_nregs can result in unusual subregs, eg.
7386 (subreg:SI (reg:DF) 4), which are not handled well. The code to
7387 store the whole arg to memory is often more efficient than code
7388 to store pieces, and we know that space is available in the right
7389 place for the whole arg. */
7390 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
7392 i = 0;
7395 rtx r = gen_rtx_REG (SImode, GP_ARG_MIN_REG + align_words);
7396 rtx off = GEN_INT (i++ * 4);
7397 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
7399 while (++align_words < GP_ARG_NUM_REG && --n_units != 0);
7401 return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
7404 /* Determine where to put an argument to a function.
7405 Value is zero to push the argument on the stack,
7406 or a hard register in which to store the argument.
7408 MODE is the argument's machine mode.
7409 TYPE is the data type of the argument (as a tree).
7410 This is null for libcalls where that information may
7411 not be available.
7412 CUM is a variable of type CUMULATIVE_ARGS which gives info about
7413 the preceding args and about the function being called. It is
7414 not modified in this routine.
7415 NAMED is nonzero if this argument is a named parameter
7416 (otherwise it is an extra parameter matching an ellipsis).
7418 On RS/6000 the first eight words of non-FP are normally in registers
7419 and the rest are pushed. Under AIX, the first 13 FP args are in registers.
7420 Under V.4, the first 8 FP args are in registers.
7422 If this is floating-point and no prototype is specified, we use
7423 both an FP and integer register (or possibly FP reg and stack). Library
7424 functions (when CALL_LIBCALL is set) always have the proper types for args,
7425 so we can pass the FP value just in one register. emit_library_function
7426 doesn't support PARALLEL anyway.
7428 Note that for args passed by reference, function_arg will be called
7429 with MODE and TYPE set to that of the pointer to the arg, not the arg
7430 itself. */
7433 function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
7434 tree type, int named)
7436 enum rs6000_abi abi = DEFAULT_ABI;
7438 /* Return a marker to indicate whether CR1 needs to set or clear the
7439 bit that V.4 uses to say fp args were passed in registers.
7440 Assume that we don't need the marker for software floating point,
7441 or compiler generated library calls. */
7442 if (mode == VOIDmode)
7444 if (abi == ABI_V4
7445 && (cum->call_cookie & CALL_LIBCALL) == 0
7446 && (cum->stdarg
7447 || (cum->nargs_prototype < 0
7448 && (cum->prototype || TARGET_NO_PROTOTYPE))))
7450 /* For the SPE, we need to crxor CR6 always. */
7451 if (TARGET_SPE_ABI)
7452 return GEN_INT (cum->call_cookie | CALL_V4_SET_FP_ARGS);
7453 else if (TARGET_HARD_FLOAT && TARGET_FPRS)
7454 return GEN_INT (cum->call_cookie
7455 | ((cum->fregno == FP_ARG_MIN_REG)
7456 ? CALL_V4_SET_FP_ARGS
7457 : CALL_V4_CLEAR_FP_ARGS));
7460 return GEN_INT (cum->call_cookie);
7463 if (rs6000_darwin64_abi && mode == BLKmode
7464 && TREE_CODE (type) == RECORD_TYPE)
7466 rtx rslt = rs6000_darwin64_record_arg (cum, type, named, false);
7467 if (rslt != NULL_RTX)
7468 return rslt;
7469 /* Else fall through to usual handling. */
7472 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
7473 if (TARGET_64BIT && ! cum->prototype)
7475 /* Vector parameters get passed in vector register
7476 and also in GPRs or memory, in absence of prototype. */
7477 int align_words;
7478 rtx slot;
7479 align_words = (cum->words + 1) & ~1;
7481 if (align_words >= GP_ARG_NUM_REG)
7483 slot = NULL_RTX;
7485 else
7487 slot = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
7489 return gen_rtx_PARALLEL (mode,
7490 gen_rtvec (2,
7491 gen_rtx_EXPR_LIST (VOIDmode,
7492 slot, const0_rtx),
7493 gen_rtx_EXPR_LIST (VOIDmode,
7494 gen_rtx_REG (mode, cum->vregno),
7495 const0_rtx)));
7497 else
7498 return gen_rtx_REG (mode, cum->vregno);
7499 else if (TARGET_ALTIVEC_ABI
7500 && (ALTIVEC_VECTOR_MODE (mode)
7501 || VSX_VECTOR_MODE (mode)
7502 || (type && TREE_CODE (type) == VECTOR_TYPE
7503 && int_size_in_bytes (type) == 16)))
7505 if (named || abi == ABI_V4)
7506 return NULL_RTX;
7507 else
7509 /* Vector parameters to varargs functions under AIX or Darwin
7510 get passed in memory and possibly also in GPRs. */
7511 int align, align_words, n_words;
7512 enum machine_mode part_mode;
7514 /* Vector parameters must be 16-byte aligned. This places them at
7515 2 mod 4 in terms of words in 32-bit mode, since the parameter
7516 save area starts at offset 24 from the stack. In 64-bit mode,
7517 they just have to start on an even word, since the parameter
7518 save area is 16-byte aligned. */
7519 if (TARGET_32BIT)
7520 align = (2 - cum->words) & 3;
7521 else
7522 align = cum->words & 1;
7523 align_words = cum->words + align;
7525 /* Out of registers? Memory, then. */
7526 if (align_words >= GP_ARG_NUM_REG)
7527 return NULL_RTX;
7529 if (TARGET_32BIT && TARGET_POWERPC64)
7530 return rs6000_mixed_function_arg (mode, type, align_words);
7532 /* The vector value goes in GPRs. Only the part of the
7533 value in GPRs is reported here. */
7534 part_mode = mode;
7535 n_words = rs6000_arg_size (mode, type);
7536 if (align_words + n_words > GP_ARG_NUM_REG)
7537 /* Fortunately, there are only two possibilities, the value
7538 is either wholly in GPRs or half in GPRs and half not. */
7539 part_mode = DImode;
7541 return gen_rtx_REG (part_mode, GP_ARG_MIN_REG + align_words);
7544 else if (TARGET_SPE_ABI && TARGET_SPE
7545 && (SPE_VECTOR_MODE (mode)
7546 || (TARGET_E500_DOUBLE && (mode == DFmode
7547 || mode == DCmode
7548 || mode == TFmode
7549 || mode == TCmode))))
7550 return rs6000_spe_function_arg (cum, mode, type);
7552 else if (abi == ABI_V4)
7554 if (TARGET_HARD_FLOAT && TARGET_FPRS
7555 && ((TARGET_SINGLE_FLOAT && mode == SFmode)
7556 || (TARGET_DOUBLE_FLOAT && mode == DFmode)
7557 || (mode == TFmode && !TARGET_IEEEQUAD)
7558 || mode == SDmode || mode == DDmode || mode == TDmode))
7560 /* _Decimal128 must use an even/odd register pair. This assumes
7561 that the register number is odd when fregno is odd. */
7562 if (mode == TDmode && (cum->fregno % 2) == 1)
7563 cum->fregno++;
7565 if (cum->fregno + (mode == TFmode || mode == TDmode ? 1 : 0)
7566 <= FP_ARG_V4_MAX_REG)
7567 return gen_rtx_REG (mode, cum->fregno);
7568 else
7569 return NULL_RTX;
7571 else
7573 int n_words = rs6000_arg_size (mode, type);
7574 int gregno = cum->sysv_gregno;
7576 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
7577 (r7,r8) or (r9,r10). As does any other 2 word item such
7578 as complex int due to a historical mistake. */
7579 if (n_words == 2)
7580 gregno += (1 - gregno) & 1;
7582 /* Multi-reg args are not split between registers and stack. */
7583 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
7584 return NULL_RTX;
7586 if (TARGET_32BIT && TARGET_POWERPC64)
7587 return rs6000_mixed_function_arg (mode, type,
7588 gregno - GP_ARG_MIN_REG);
7589 return gen_rtx_REG (mode, gregno);
7592 else
7594 int align_words = rs6000_parm_start (mode, type, cum->words);
7596 /* _Decimal128 must be passed in an even/odd float register pair.
7597 This assumes that the register number is odd when fregno is odd. */
7598 if (mode == TDmode && (cum->fregno % 2) == 1)
7599 cum->fregno++;
7601 if (USE_FP_FOR_ARG_P (cum, mode, type))
7603 rtx rvec[GP_ARG_NUM_REG + 1];
7604 rtx r;
7605 int k;
7606 bool needs_psave;
7607 enum machine_mode fmode = mode;
7608 unsigned long n_fpreg = (GET_MODE_SIZE (mode) + 7) >> 3;
7610 if (cum->fregno + n_fpreg > FP_ARG_MAX_REG + 1)
7612 /* Currently, we only ever need one reg here because complex
7613 doubles are split. */
7614 gcc_assert (cum->fregno == FP_ARG_MAX_REG
7615 && (fmode == TFmode || fmode == TDmode));
7617 /* Long double or _Decimal128 split over regs and memory. */
7618 fmode = DECIMAL_FLOAT_MODE_P (fmode) ? DDmode : DFmode;
7621 /* Do we also need to pass this arg in the parameter save
7622 area? */
7623 needs_psave = (type
7624 && (cum->nargs_prototype <= 0
7625 || (DEFAULT_ABI == ABI_AIX
7626 && TARGET_XL_COMPAT
7627 && align_words >= GP_ARG_NUM_REG)));
7629 if (!needs_psave && mode == fmode)
7630 return gen_rtx_REG (fmode, cum->fregno);
7632 k = 0;
7633 if (needs_psave)
7635 /* Describe the part that goes in gprs or the stack.
7636 This piece must come first, before the fprs. */
7637 if (align_words < GP_ARG_NUM_REG)
7639 unsigned long n_words = rs6000_arg_size (mode, type);
7641 if (align_words + n_words > GP_ARG_NUM_REG
7642 || (TARGET_32BIT && TARGET_POWERPC64))
7644 /* If this is partially on the stack, then we only
7645 include the portion actually in registers here. */
7646 enum machine_mode rmode = TARGET_32BIT ? SImode : DImode;
7647 rtx off;
7648 int i = 0;
7649 if (align_words + n_words > GP_ARG_NUM_REG)
7650 /* Not all of the arg fits in gprs. Say that it
7651 goes in memory too, using a magic NULL_RTX
7652 component. Also see comment in
7653 rs6000_mixed_function_arg for why the normal
7654 function_arg_partial_nregs scheme doesn't work
7655 in this case. */
7656 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX,
7657 const0_rtx);
7660 r = gen_rtx_REG (rmode,
7661 GP_ARG_MIN_REG + align_words);
7662 off = GEN_INT (i++ * GET_MODE_SIZE (rmode));
7663 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
7665 while (++align_words < GP_ARG_NUM_REG && --n_words != 0);
7667 else
7669 /* The whole arg fits in gprs. */
7670 r = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
7671 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
7674 else
7675 /* It's entirely in memory. */
7676 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
7679 /* Describe where this piece goes in the fprs. */
7680 r = gen_rtx_REG (fmode, cum->fregno);
7681 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
7683 return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
7685 else if (align_words < GP_ARG_NUM_REG)
7687 if (TARGET_32BIT && TARGET_POWERPC64)
7688 return rs6000_mixed_function_arg (mode, type, align_words);
7690 if (mode == BLKmode)
7691 mode = Pmode;
7693 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
7695 else
7696 return NULL_RTX;
7700 /* For an arg passed partly in registers and partly in memory, this is
7701 the number of bytes passed in registers. For args passed entirely in
7702 registers or entirely in memory, zero. When an arg is described by a
7703 PARALLEL, perhaps using more than one register type, this function
7704 returns the number of bytes used by the first element of the PARALLEL. */
7706 static int
7707 rs6000_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode,
7708 tree type, bool named)
7710 int ret = 0;
7711 int align_words;
7713 if (DEFAULT_ABI == ABI_V4)
7714 return 0;
7716 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named)
7717 && cum->nargs_prototype >= 0)
7718 return 0;
7720 /* In this complicated case we just disable the partial_nregs code. */
7721 if (rs6000_darwin64_abi && mode == BLKmode
7722 && TREE_CODE (type) == RECORD_TYPE
7723 && int_size_in_bytes (type) > 0)
7724 return 0;
7726 align_words = rs6000_parm_start (mode, type, cum->words);
7728 if (USE_FP_FOR_ARG_P (cum, mode, type))
7730 /* If we are passing this arg in the fixed parameter save area
7731 (gprs or memory) as well as fprs, then this function should
7732 return the number of partial bytes passed in the parameter
7733 save area rather than partial bytes passed in fprs. */
7734 if (type
7735 && (cum->nargs_prototype <= 0
7736 || (DEFAULT_ABI == ABI_AIX
7737 && TARGET_XL_COMPAT
7738 && align_words >= GP_ARG_NUM_REG)))
7739 return 0;
7740 else if (cum->fregno + ((GET_MODE_SIZE (mode) + 7) >> 3)
7741 > FP_ARG_MAX_REG + 1)
7742 ret = (FP_ARG_MAX_REG + 1 - cum->fregno) * 8;
7743 else if (cum->nargs_prototype >= 0)
7744 return 0;
7747 if (align_words < GP_ARG_NUM_REG
7748 && GP_ARG_NUM_REG < align_words + rs6000_arg_size (mode, type))
7749 ret = (GP_ARG_NUM_REG - align_words) * (TARGET_32BIT ? 4 : 8);
7751 if (ret != 0 && TARGET_DEBUG_ARG)
7752 fprintf (stderr, "rs6000_arg_partial_bytes: %d\n", ret);
7754 return ret;
7757 /* A C expression that indicates when an argument must be passed by
7758 reference. If nonzero for an argument, a copy of that argument is
7759 made in memory and a pointer to the argument is passed instead of
7760 the argument itself. The pointer is passed in whatever way is
7761 appropriate for passing a pointer to that type.
7763 Under V.4, aggregates and long double are passed by reference.
7765 As an extension to all 32-bit ABIs, AltiVec vectors are passed by
7766 reference unless the AltiVec vector extension ABI is in force.
7768 As an extension to all ABIs, variable sized types are passed by
7769 reference. */
7771 static bool
7772 rs6000_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
7773 enum machine_mode mode, const_tree type,
7774 bool named ATTRIBUTE_UNUSED)
7776 if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && mode == TFmode)
7778 if (TARGET_DEBUG_ARG)
7779 fprintf (stderr, "function_arg_pass_by_reference: V4 long double\n");
7780 return 1;
7783 if (!type)
7784 return 0;
7786 if (DEFAULT_ABI == ABI_V4 && AGGREGATE_TYPE_P (type))
7788 if (TARGET_DEBUG_ARG)
7789 fprintf (stderr, "function_arg_pass_by_reference: V4 aggregate\n");
7790 return 1;
7793 if (int_size_in_bytes (type) < 0)
7795 if (TARGET_DEBUG_ARG)
7796 fprintf (stderr, "function_arg_pass_by_reference: variable size\n");
7797 return 1;
7800 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
7801 modes only exist for GCC vector types if -maltivec. */
7802 if (TARGET_32BIT && !TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
7804 if (TARGET_DEBUG_ARG)
7805 fprintf (stderr, "function_arg_pass_by_reference: AltiVec\n");
7806 return 1;
7809 /* Pass synthetic vectors in memory. */
7810 if (TREE_CODE (type) == VECTOR_TYPE
7811 && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
7813 static bool warned_for_pass_big_vectors = false;
7814 if (TARGET_DEBUG_ARG)
7815 fprintf (stderr, "function_arg_pass_by_reference: synthetic vector\n");
7816 if (!warned_for_pass_big_vectors)
7818 warning (0, "GCC vector passed by reference: "
7819 "non-standard ABI extension with no compatibility guarantee");
7820 warned_for_pass_big_vectors = true;
7822 return 1;
7825 return 0;
7828 static void
7829 rs6000_move_block_from_reg (int regno, rtx x, int nregs)
7831 int i;
7832 enum machine_mode reg_mode = TARGET_32BIT ? SImode : DImode;
7834 if (nregs == 0)
7835 return;
7837 for (i = 0; i < nregs; i++)
7839 rtx tem = adjust_address_nv (x, reg_mode, i * GET_MODE_SIZE (reg_mode));
7840 if (reload_completed)
7842 if (! strict_memory_address_p (reg_mode, XEXP (tem, 0)))
7843 tem = NULL_RTX;
7844 else
7845 tem = simplify_gen_subreg (reg_mode, x, BLKmode,
7846 i * GET_MODE_SIZE (reg_mode));
7848 else
7849 tem = replace_equiv_address (tem, XEXP (tem, 0));
7851 gcc_assert (tem);
7853 emit_move_insn (tem, gen_rtx_REG (reg_mode, regno + i));
7857 /* Perform any needed actions needed for a function that is receiving a
7858 variable number of arguments.
7860 CUM is as above.
7862 MODE and TYPE are the mode and type of the current parameter.
7864 PRETEND_SIZE is a variable that should be set to the amount of stack
7865 that must be pushed by the prolog to pretend that our caller pushed
7868 Normally, this macro will push all remaining incoming registers on the
7869 stack and set PRETEND_SIZE to the length of the registers pushed. */
7871 static void
7872 setup_incoming_varargs (CUMULATIVE_ARGS *cum, enum machine_mode mode,
7873 tree type, int *pretend_size ATTRIBUTE_UNUSED,
7874 int no_rtl)
7876 CUMULATIVE_ARGS next_cum;
7877 int reg_size = TARGET_32BIT ? 4 : 8;
7878 rtx save_area = NULL_RTX, mem;
7879 int first_reg_offset;
7880 alias_set_type set;
7882 /* Skip the last named argument. */
7883 next_cum = *cum;
7884 function_arg_advance (&next_cum, mode, type, 1, 0);
7886 if (DEFAULT_ABI == ABI_V4)
7888 first_reg_offset = next_cum.sysv_gregno - GP_ARG_MIN_REG;
7890 if (! no_rtl)
7892 int gpr_reg_num = 0, gpr_size = 0, fpr_size = 0;
7893 HOST_WIDE_INT offset = 0;
7895 /* Try to optimize the size of the varargs save area.
7896 The ABI requires that ap.reg_save_area is doubleword
7897 aligned, but we don't need to allocate space for all
7898 the bytes, only those to which we actually will save
7899 anything. */
7900 if (cfun->va_list_gpr_size && first_reg_offset < GP_ARG_NUM_REG)
7901 gpr_reg_num = GP_ARG_NUM_REG - first_reg_offset;
7902 if (TARGET_HARD_FLOAT && TARGET_FPRS
7903 && next_cum.fregno <= FP_ARG_V4_MAX_REG
7904 && cfun->va_list_fpr_size)
7906 if (gpr_reg_num)
7907 fpr_size = (next_cum.fregno - FP_ARG_MIN_REG)
7908 * UNITS_PER_FP_WORD;
7909 if (cfun->va_list_fpr_size
7910 < FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
7911 fpr_size += cfun->va_list_fpr_size * UNITS_PER_FP_WORD;
7912 else
7913 fpr_size += (FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
7914 * UNITS_PER_FP_WORD;
7916 if (gpr_reg_num)
7918 offset = -((first_reg_offset * reg_size) & ~7);
7919 if (!fpr_size && gpr_reg_num > cfun->va_list_gpr_size)
7921 gpr_reg_num = cfun->va_list_gpr_size;
7922 if (reg_size == 4 && (first_reg_offset & 1))
7923 gpr_reg_num++;
7925 gpr_size = (gpr_reg_num * reg_size + 7) & ~7;
7927 else if (fpr_size)
7928 offset = - (int) (next_cum.fregno - FP_ARG_MIN_REG)
7929 * UNITS_PER_FP_WORD
7930 - (int) (GP_ARG_NUM_REG * reg_size);
7932 if (gpr_size + fpr_size)
7934 rtx reg_save_area
7935 = assign_stack_local (BLKmode, gpr_size + fpr_size, 64);
7936 gcc_assert (GET_CODE (reg_save_area) == MEM);
7937 reg_save_area = XEXP (reg_save_area, 0);
7938 if (GET_CODE (reg_save_area) == PLUS)
7940 gcc_assert (XEXP (reg_save_area, 0)
7941 == virtual_stack_vars_rtx);
7942 gcc_assert (GET_CODE (XEXP (reg_save_area, 1)) == CONST_INT);
7943 offset += INTVAL (XEXP (reg_save_area, 1));
7945 else
7946 gcc_assert (reg_save_area == virtual_stack_vars_rtx);
7949 cfun->machine->varargs_save_offset = offset;
7950 save_area = plus_constant (virtual_stack_vars_rtx, offset);
7953 else
7955 first_reg_offset = next_cum.words;
7956 save_area = virtual_incoming_args_rtx;
7958 if (targetm.calls.must_pass_in_stack (mode, type))
7959 first_reg_offset += rs6000_arg_size (TYPE_MODE (type), type);
7962 set = get_varargs_alias_set ();
7963 if (! no_rtl && first_reg_offset < GP_ARG_NUM_REG
7964 && cfun->va_list_gpr_size)
7966 int nregs = GP_ARG_NUM_REG - first_reg_offset;
7968 if (va_list_gpr_counter_field)
7970 /* V4 va_list_gpr_size counts number of registers needed. */
7971 if (nregs > cfun->va_list_gpr_size)
7972 nregs = cfun->va_list_gpr_size;
7974 else
7976 /* char * va_list instead counts number of bytes needed. */
7977 if (nregs > cfun->va_list_gpr_size / reg_size)
7978 nregs = cfun->va_list_gpr_size / reg_size;
7981 mem = gen_rtx_MEM (BLKmode,
7982 plus_constant (save_area,
7983 first_reg_offset * reg_size));
7984 MEM_NOTRAP_P (mem) = 1;
7985 set_mem_alias_set (mem, set);
7986 set_mem_align (mem, BITS_PER_WORD);
7988 rs6000_move_block_from_reg (GP_ARG_MIN_REG + first_reg_offset, mem,
7989 nregs);
7992 /* Save FP registers if needed. */
7993 if (DEFAULT_ABI == ABI_V4
7994 && TARGET_HARD_FLOAT && TARGET_FPRS
7995 && ! no_rtl
7996 && next_cum.fregno <= FP_ARG_V4_MAX_REG
7997 && cfun->va_list_fpr_size)
7999 int fregno = next_cum.fregno, nregs;
8000 rtx cr1 = gen_rtx_REG (CCmode, CR1_REGNO);
8001 rtx lab = gen_label_rtx ();
8002 int off = (GP_ARG_NUM_REG * reg_size) + ((fregno - FP_ARG_MIN_REG)
8003 * UNITS_PER_FP_WORD);
8005 emit_jump_insn
8006 (gen_rtx_SET (VOIDmode,
8007 pc_rtx,
8008 gen_rtx_IF_THEN_ELSE (VOIDmode,
8009 gen_rtx_NE (VOIDmode, cr1,
8010 const0_rtx),
8011 gen_rtx_LABEL_REF (VOIDmode, lab),
8012 pc_rtx)));
8014 for (nregs = 0;
8015 fregno <= FP_ARG_V4_MAX_REG && nregs < cfun->va_list_fpr_size;
8016 fregno++, off += UNITS_PER_FP_WORD, nregs++)
8018 mem = gen_rtx_MEM ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
8019 ? DFmode : SFmode,
8020 plus_constant (save_area, off));
8021 MEM_NOTRAP_P (mem) = 1;
8022 set_mem_alias_set (mem, set);
8023 set_mem_align (mem, GET_MODE_ALIGNMENT (
8024 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
8025 ? DFmode : SFmode));
8026 emit_move_insn (mem, gen_rtx_REG (
8027 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
8028 ? DFmode : SFmode, fregno));
8031 emit_label (lab);
8035 /* Create the va_list data type. */
8037 static tree
8038 rs6000_build_builtin_va_list (void)
8040 tree f_gpr, f_fpr, f_res, f_ovf, f_sav, record, type_decl;
8042 /* For AIX, prefer 'char *' because that's what the system
8043 header files like. */
8044 if (DEFAULT_ABI != ABI_V4)
8045 return build_pointer_type (char_type_node);
8047 record = (*lang_hooks.types.make_type) (RECORD_TYPE);
8048 type_decl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
8049 get_identifier ("__va_list_tag"), record);
8051 f_gpr = build_decl (BUILTINS_LOCATION, FIELD_DECL, get_identifier ("gpr"),
8052 unsigned_char_type_node);
8053 f_fpr = build_decl (BUILTINS_LOCATION, FIELD_DECL, get_identifier ("fpr"),
8054 unsigned_char_type_node);
8055 /* Give the two bytes of padding a name, so that -Wpadded won't warn on
8056 every user file. */
8057 f_res = build_decl (BUILTINS_LOCATION, FIELD_DECL,
8058 get_identifier ("reserved"), short_unsigned_type_node);
8059 f_ovf = build_decl (BUILTINS_LOCATION, FIELD_DECL,
8060 get_identifier ("overflow_arg_area"),
8061 ptr_type_node);
8062 f_sav = build_decl (BUILTINS_LOCATION, FIELD_DECL,
8063 get_identifier ("reg_save_area"),
8064 ptr_type_node);
8066 va_list_gpr_counter_field = f_gpr;
8067 va_list_fpr_counter_field = f_fpr;
8069 DECL_FIELD_CONTEXT (f_gpr) = record;
8070 DECL_FIELD_CONTEXT (f_fpr) = record;
8071 DECL_FIELD_CONTEXT (f_res) = record;
8072 DECL_FIELD_CONTEXT (f_ovf) = record;
8073 DECL_FIELD_CONTEXT (f_sav) = record;
8075 TREE_CHAIN (record) = type_decl;
8076 TYPE_NAME (record) = type_decl;
8077 TYPE_FIELDS (record) = f_gpr;
8078 TREE_CHAIN (f_gpr) = f_fpr;
8079 TREE_CHAIN (f_fpr) = f_res;
8080 TREE_CHAIN (f_res) = f_ovf;
8081 TREE_CHAIN (f_ovf) = f_sav;
8083 layout_type (record);
8085 /* The correct type is an array type of one element. */
8086 return build_array_type (record, build_index_type (size_zero_node));
8089 /* Implement va_start. */
8091 static void
8092 rs6000_va_start (tree valist, rtx nextarg)
8094 HOST_WIDE_INT words, n_gpr, n_fpr;
8095 tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
8096 tree gpr, fpr, ovf, sav, t;
8098 /* Only SVR4 needs something special. */
8099 if (DEFAULT_ABI != ABI_V4)
8101 std_expand_builtin_va_start (valist, nextarg);
8102 return;
8105 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
8106 f_fpr = TREE_CHAIN (f_gpr);
8107 f_res = TREE_CHAIN (f_fpr);
8108 f_ovf = TREE_CHAIN (f_res);
8109 f_sav = TREE_CHAIN (f_ovf);
8111 valist = build_va_arg_indirect_ref (valist);
8112 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
8113 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), unshare_expr (valist),
8114 f_fpr, NULL_TREE);
8115 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), unshare_expr (valist),
8116 f_ovf, NULL_TREE);
8117 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), unshare_expr (valist),
8118 f_sav, NULL_TREE);
8120 /* Count number of gp and fp argument registers used. */
8121 words = crtl->args.info.words;
8122 n_gpr = MIN (crtl->args.info.sysv_gregno - GP_ARG_MIN_REG,
8123 GP_ARG_NUM_REG);
8124 n_fpr = MIN (crtl->args.info.fregno - FP_ARG_MIN_REG,
8125 FP_ARG_NUM_REG);
8127 if (TARGET_DEBUG_ARG)
8128 fprintf (stderr, "va_start: words = "HOST_WIDE_INT_PRINT_DEC", n_gpr = "
8129 HOST_WIDE_INT_PRINT_DEC", n_fpr = "HOST_WIDE_INT_PRINT_DEC"\n",
8130 words, n_gpr, n_fpr);
8132 if (cfun->va_list_gpr_size)
8134 t = build2 (MODIFY_EXPR, TREE_TYPE (gpr), gpr,
8135 build_int_cst (NULL_TREE, n_gpr));
8136 TREE_SIDE_EFFECTS (t) = 1;
8137 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
8140 if (cfun->va_list_fpr_size)
8142 t = build2 (MODIFY_EXPR, TREE_TYPE (fpr), fpr,
8143 build_int_cst (NULL_TREE, n_fpr));
8144 TREE_SIDE_EFFECTS (t) = 1;
8145 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
8148 /* Find the overflow area. */
8149 t = make_tree (TREE_TYPE (ovf), virtual_incoming_args_rtx);
8150 if (words != 0)
8151 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (ovf), t,
8152 size_int (words * UNITS_PER_WORD));
8153 t = build2 (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
8154 TREE_SIDE_EFFECTS (t) = 1;
8155 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
8157 /* If there were no va_arg invocations, don't set up the register
8158 save area. */
8159 if (!cfun->va_list_gpr_size
8160 && !cfun->va_list_fpr_size
8161 && n_gpr < GP_ARG_NUM_REG
8162 && n_fpr < FP_ARG_V4_MAX_REG)
8163 return;
8165 /* Find the register save area. */
8166 t = make_tree (TREE_TYPE (sav), virtual_stack_vars_rtx);
8167 if (cfun->machine->varargs_save_offset)
8168 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (sav), t,
8169 size_int (cfun->machine->varargs_save_offset));
8170 t = build2 (MODIFY_EXPR, TREE_TYPE (sav), sav, t);
8171 TREE_SIDE_EFFECTS (t) = 1;
8172 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
8175 /* Implement va_arg. */
8177 tree
8178 rs6000_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
8179 gimple_seq *post_p)
8181 tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
8182 tree gpr, fpr, ovf, sav, reg, t, u;
8183 int size, rsize, n_reg, sav_ofs, sav_scale;
8184 tree lab_false, lab_over, addr;
8185 int align;
8186 tree ptrtype = build_pointer_type_for_mode (type, ptr_mode, true);
8187 int regalign = 0;
8188 gimple stmt;
8190 if (pass_by_reference (NULL, TYPE_MODE (type), type, false))
8192 t = rs6000_gimplify_va_arg (valist, ptrtype, pre_p, post_p);
8193 return build_va_arg_indirect_ref (t);
8196 if (DEFAULT_ABI != ABI_V4)
8198 if (targetm.calls.split_complex_arg && TREE_CODE (type) == COMPLEX_TYPE)
8200 tree elem_type = TREE_TYPE (type);
8201 enum machine_mode elem_mode = TYPE_MODE (elem_type);
8202 int elem_size = GET_MODE_SIZE (elem_mode);
8204 if (elem_size < UNITS_PER_WORD)
8206 tree real_part, imag_part;
8207 gimple_seq post = NULL;
8209 real_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
8210 &post);
8211 /* Copy the value into a temporary, lest the formal temporary
8212 be reused out from under us. */
8213 real_part = get_initialized_tmp_var (real_part, pre_p, &post);
8214 gimple_seq_add_seq (pre_p, post);
8216 imag_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
8217 post_p);
8219 return build2 (COMPLEX_EXPR, type, real_part, imag_part);
8223 return std_gimplify_va_arg_expr (valist, type, pre_p, post_p);
8226 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
8227 f_fpr = TREE_CHAIN (f_gpr);
8228 f_res = TREE_CHAIN (f_fpr);
8229 f_ovf = TREE_CHAIN (f_res);
8230 f_sav = TREE_CHAIN (f_ovf);
8232 valist = build_va_arg_indirect_ref (valist);
8233 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
8234 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), unshare_expr (valist),
8235 f_fpr, NULL_TREE);
8236 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), unshare_expr (valist),
8237 f_ovf, NULL_TREE);
8238 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), unshare_expr (valist),
8239 f_sav, NULL_TREE);
8241 size = int_size_in_bytes (type);
8242 rsize = (size + 3) / 4;
8243 align = 1;
8245 if (TARGET_HARD_FLOAT && TARGET_FPRS
8246 && ((TARGET_SINGLE_FLOAT && TYPE_MODE (type) == SFmode)
8247 || (TARGET_DOUBLE_FLOAT
8248 && (TYPE_MODE (type) == DFmode
8249 || TYPE_MODE (type) == TFmode
8250 || TYPE_MODE (type) == SDmode
8251 || TYPE_MODE (type) == DDmode
8252 || TYPE_MODE (type) == TDmode))))
8254 /* FP args go in FP registers, if present. */
8255 reg = fpr;
8256 n_reg = (size + 7) / 8;
8257 sav_ofs = ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? 8 : 4) * 4;
8258 sav_scale = ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? 8 : 4);
8259 if (TYPE_MODE (type) != SFmode && TYPE_MODE (type) != SDmode)
8260 align = 8;
8262 else
8264 /* Otherwise into GP registers. */
8265 reg = gpr;
8266 n_reg = rsize;
8267 sav_ofs = 0;
8268 sav_scale = 4;
8269 if (n_reg == 2)
8270 align = 8;
8273 /* Pull the value out of the saved registers.... */
8275 lab_over = NULL;
8276 addr = create_tmp_var (ptr_type_node, "addr");
8278 /* AltiVec vectors never go in registers when -mabi=altivec. */
8279 if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
8280 align = 16;
8281 else
8283 lab_false = create_artificial_label (input_location);
8284 lab_over = create_artificial_label (input_location);
8286 /* Long long and SPE vectors are aligned in the registers.
8287 As are any other 2 gpr item such as complex int due to a
8288 historical mistake. */
8289 u = reg;
8290 if (n_reg == 2 && reg == gpr)
8292 regalign = 1;
8293 u = build2 (BIT_AND_EXPR, TREE_TYPE (reg), unshare_expr (reg),
8294 build_int_cst (TREE_TYPE (reg), n_reg - 1));
8295 u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg),
8296 unshare_expr (reg), u);
8298 /* _Decimal128 is passed in even/odd fpr pairs; the stored
8299 reg number is 0 for f1, so we want to make it odd. */
8300 else if (reg == fpr && TYPE_MODE (type) == TDmode)
8302 t = build2 (BIT_IOR_EXPR, TREE_TYPE (reg), unshare_expr (reg),
8303 build_int_cst (TREE_TYPE (reg), 1));
8304 u = build2 (MODIFY_EXPR, void_type_node, unshare_expr (reg), t);
8307 t = fold_convert (TREE_TYPE (reg), size_int (8 - n_reg + 1));
8308 t = build2 (GE_EXPR, boolean_type_node, u, t);
8309 u = build1 (GOTO_EXPR, void_type_node, lab_false);
8310 t = build3 (COND_EXPR, void_type_node, t, u, NULL_TREE);
8311 gimplify_and_add (t, pre_p);
8313 t = sav;
8314 if (sav_ofs)
8315 t = build2 (POINTER_PLUS_EXPR, ptr_type_node, sav, size_int (sav_ofs));
8317 u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg), unshare_expr (reg),
8318 build_int_cst (TREE_TYPE (reg), n_reg));
8319 u = fold_convert (sizetype, u);
8320 u = build2 (MULT_EXPR, sizetype, u, size_int (sav_scale));
8321 t = build2 (POINTER_PLUS_EXPR, ptr_type_node, t, u);
8323 /* _Decimal32 varargs are located in the second word of the 64-bit
8324 FP register for 32-bit binaries. */
8325 if (!TARGET_POWERPC64
8326 && TARGET_HARD_FLOAT && TARGET_FPRS
8327 && TYPE_MODE (type) == SDmode)
8328 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (size));
8330 gimplify_assign (addr, t, pre_p);
8332 gimple_seq_add_stmt (pre_p, gimple_build_goto (lab_over));
8334 stmt = gimple_build_label (lab_false);
8335 gimple_seq_add_stmt (pre_p, stmt);
8337 if ((n_reg == 2 && !regalign) || n_reg > 2)
8339 /* Ensure that we don't find any more args in regs.
8340 Alignment has taken care of for special cases. */
8341 gimplify_assign (reg, build_int_cst (TREE_TYPE (reg), 8), pre_p);
8345 /* ... otherwise out of the overflow area. */
8347 /* Care for on-stack alignment if needed. */
8348 t = ovf;
8349 if (align != 1)
8351 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (align - 1));
8352 t = fold_convert (sizetype, t);
8353 t = build2 (BIT_AND_EXPR, TREE_TYPE (t), t,
8354 size_int (-align));
8355 t = fold_convert (TREE_TYPE (ovf), t);
8357 gimplify_expr (&t, pre_p, NULL, is_gimple_val, fb_rvalue);
8359 gimplify_assign (unshare_expr (addr), t, pre_p);
8361 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (size));
8362 gimplify_assign (unshare_expr (ovf), t, pre_p);
8364 if (lab_over)
8366 stmt = gimple_build_label (lab_over);
8367 gimple_seq_add_stmt (pre_p, stmt);
8370 if (STRICT_ALIGNMENT
8371 && (TYPE_ALIGN (type)
8372 > (unsigned) BITS_PER_UNIT * (align < 4 ? 4 : align)))
8374 /* The value (of type complex double, for example) may not be
8375 aligned in memory in the saved registers, so copy via a
8376 temporary. (This is the same code as used for SPARC.) */
8377 tree tmp = create_tmp_var (type, "va_arg_tmp");
8378 tree dest_addr = build_fold_addr_expr (tmp);
8380 tree copy = build_call_expr (implicit_built_in_decls[BUILT_IN_MEMCPY],
8381 3, dest_addr, addr, size_int (rsize * 4));
8383 gimplify_and_add (copy, pre_p);
8384 addr = dest_addr;
8387 addr = fold_convert (ptrtype, addr);
8388 return build_va_arg_indirect_ref (addr);
8391 /* Builtins. */
8393 static void
8394 def_builtin (int mask, const char *name, tree type, int code)
8396 if ((mask & target_flags) || TARGET_PAIRED_FLOAT)
8398 if (rs6000_builtin_decls[code])
8399 fatal_error ("internal error: builtin function to %s already processed.",
8400 name);
8402 rs6000_builtin_decls[code] =
8403 add_builtin_function (name, type, code, BUILT_IN_MD,
8404 NULL, NULL_TREE);
8408 /* Simple ternary operations: VECd = foo (VECa, VECb, VECc). */
8410 static const struct builtin_description bdesc_3arg[] =
8412 { MASK_ALTIVEC, CODE_FOR_altivec_vmaddfp, "__builtin_altivec_vmaddfp", ALTIVEC_BUILTIN_VMADDFP },
8413 { MASK_ALTIVEC, CODE_FOR_altivec_vmhaddshs, "__builtin_altivec_vmhaddshs", ALTIVEC_BUILTIN_VMHADDSHS },
8414 { MASK_ALTIVEC, CODE_FOR_altivec_vmhraddshs, "__builtin_altivec_vmhraddshs", ALTIVEC_BUILTIN_VMHRADDSHS },
8415 { MASK_ALTIVEC, CODE_FOR_altivec_vmladduhm, "__builtin_altivec_vmladduhm", ALTIVEC_BUILTIN_VMLADDUHM},
8416 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumubm, "__builtin_altivec_vmsumubm", ALTIVEC_BUILTIN_VMSUMUBM },
8417 { MASK_ALTIVEC, CODE_FOR_altivec_vmsummbm, "__builtin_altivec_vmsummbm", ALTIVEC_BUILTIN_VMSUMMBM },
8418 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhm, "__builtin_altivec_vmsumuhm", ALTIVEC_BUILTIN_VMSUMUHM },
8419 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshm, "__builtin_altivec_vmsumshm", ALTIVEC_BUILTIN_VMSUMSHM },
8420 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhs, "__builtin_altivec_vmsumuhs", ALTIVEC_BUILTIN_VMSUMUHS },
8421 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshs, "__builtin_altivec_vmsumshs", ALTIVEC_BUILTIN_VMSUMSHS },
8422 { MASK_ALTIVEC, CODE_FOR_altivec_vnmsubfp, "__builtin_altivec_vnmsubfp", ALTIVEC_BUILTIN_VNMSUBFP },
8423 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2df, "__builtin_altivec_vperm_2df", ALTIVEC_BUILTIN_VPERM_2DF },
8424 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2di, "__builtin_altivec_vperm_2di", ALTIVEC_BUILTIN_VPERM_2DI },
8425 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4sf, "__builtin_altivec_vperm_4sf", ALTIVEC_BUILTIN_VPERM_4SF },
8426 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4si, "__builtin_altivec_vperm_4si", ALTIVEC_BUILTIN_VPERM_4SI },
8427 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v8hi, "__builtin_altivec_vperm_8hi", ALTIVEC_BUILTIN_VPERM_8HI },
8428 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_altivec_vperm_16qi", ALTIVEC_BUILTIN_VPERM_16QI },
8429 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2di_uns, "__builtin_altivec_vperm_2di_uns", ALTIVEC_BUILTIN_VPERM_2DI_UNS },
8430 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4si_uns, "__builtin_altivec_vperm_4si_uns", ALTIVEC_BUILTIN_VPERM_4SI_UNS },
8431 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v8hi_uns, "__builtin_altivec_vperm_8hi_uns", ALTIVEC_BUILTIN_VPERM_8HI_UNS },
8432 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_altivec_vperm_16qi_uns", ALTIVEC_BUILTIN_VPERM_16QI_UNS },
8433 { MASK_ALTIVEC, CODE_FOR_vector_select_v4sf, "__builtin_altivec_vsel_4sf", ALTIVEC_BUILTIN_VSEL_4SF },
8434 { MASK_ALTIVEC, CODE_FOR_vector_select_v4si, "__builtin_altivec_vsel_4si", ALTIVEC_BUILTIN_VSEL_4SI },
8435 { MASK_ALTIVEC, CODE_FOR_vector_select_v8hi, "__builtin_altivec_vsel_8hi", ALTIVEC_BUILTIN_VSEL_8HI },
8436 { MASK_ALTIVEC, CODE_FOR_vector_select_v16qi, "__builtin_altivec_vsel_16qi", ALTIVEC_BUILTIN_VSEL_16QI },
8437 { MASK_ALTIVEC, CODE_FOR_vector_select_v2df, "__builtin_altivec_vsel_2df", ALTIVEC_BUILTIN_VSEL_2DF },
8438 { MASK_ALTIVEC, CODE_FOR_vector_select_v2di, "__builtin_altivec_vsel_2di", ALTIVEC_BUILTIN_VSEL_2DI },
8439 { MASK_ALTIVEC, CODE_FOR_vector_select_v4si_uns, "__builtin_altivec_vsel_4si_uns", ALTIVEC_BUILTIN_VSEL_4SI_UNS },
8440 { MASK_ALTIVEC, CODE_FOR_vector_select_v8hi_uns, "__builtin_altivec_vsel_8hi_uns", ALTIVEC_BUILTIN_VSEL_8HI_UNS },
8441 { MASK_ALTIVEC, CODE_FOR_vector_select_v16qi_uns, "__builtin_altivec_vsel_16qi_uns", ALTIVEC_BUILTIN_VSEL_16QI_UNS },
8442 { MASK_ALTIVEC, CODE_FOR_vector_select_v2di_uns, "__builtin_altivec_vsel_2di_uns", ALTIVEC_BUILTIN_VSEL_2DI_UNS },
8443 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v16qi, "__builtin_altivec_vsldoi_16qi", ALTIVEC_BUILTIN_VSLDOI_16QI },
8444 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v8hi, "__builtin_altivec_vsldoi_8hi", ALTIVEC_BUILTIN_VSLDOI_8HI },
8445 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v4si, "__builtin_altivec_vsldoi_4si", ALTIVEC_BUILTIN_VSLDOI_4SI },
8446 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v4sf, "__builtin_altivec_vsldoi_4sf", ALTIVEC_BUILTIN_VSLDOI_4SF },
8448 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_madd", ALTIVEC_BUILTIN_VEC_MADD },
8449 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_madds", ALTIVEC_BUILTIN_VEC_MADDS },
8450 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mladd", ALTIVEC_BUILTIN_VEC_MLADD },
8451 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mradds", ALTIVEC_BUILTIN_VEC_MRADDS },
8452 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msum", ALTIVEC_BUILTIN_VEC_MSUM },
8453 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumshm", ALTIVEC_BUILTIN_VEC_VMSUMSHM },
8454 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumuhm", ALTIVEC_BUILTIN_VEC_VMSUMUHM },
8455 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsummbm", ALTIVEC_BUILTIN_VEC_VMSUMMBM },
8456 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumubm", ALTIVEC_BUILTIN_VEC_VMSUMUBM },
8457 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msums", ALTIVEC_BUILTIN_VEC_MSUMS },
8458 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumshs", ALTIVEC_BUILTIN_VEC_VMSUMSHS },
8459 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumuhs", ALTIVEC_BUILTIN_VEC_VMSUMUHS },
8460 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nmsub", ALTIVEC_BUILTIN_VEC_NMSUB },
8461 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_perm", ALTIVEC_BUILTIN_VEC_PERM },
8462 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sel", ALTIVEC_BUILTIN_VEC_SEL },
8464 { MASK_VSX, CODE_FOR_vsx_fmaddv2df4, "__builtin_vsx_xvmadddp", VSX_BUILTIN_XVMADDDP },
8465 { MASK_VSX, CODE_FOR_vsx_fmsubv2df4, "__builtin_vsx_xvmsubdp", VSX_BUILTIN_XVMSUBDP },
8466 { MASK_VSX, CODE_FOR_vsx_fnmaddv2df4, "__builtin_vsx_xvnmadddp", VSX_BUILTIN_XVNMADDDP },
8467 { MASK_VSX, CODE_FOR_vsx_fnmsubv2df4, "__builtin_vsx_xvnmsubdp", VSX_BUILTIN_XVNMSUBDP },
8469 { MASK_VSX, CODE_FOR_vsx_fmaddv4sf4, "__builtin_vsx_xvmaddsp", VSX_BUILTIN_XVMADDSP },
8470 { MASK_VSX, CODE_FOR_vsx_fmsubv4sf4, "__builtin_vsx_xvmsubsp", VSX_BUILTIN_XVMSUBSP },
8471 { MASK_VSX, CODE_FOR_vsx_fnmaddv4sf4, "__builtin_vsx_xvnmaddsp", VSX_BUILTIN_XVNMADDSP },
8472 { MASK_VSX, CODE_FOR_vsx_fnmsubv4sf4, "__builtin_vsx_xvnmsubsp", VSX_BUILTIN_XVNMSUBSP },
8474 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msub", VSX_BUILTIN_VEC_MSUB },
8475 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nmadd", VSX_BUILTIN_VEC_NMADD },
8477 { MASK_VSX, CODE_FOR_vector_select_v2di, "__builtin_vsx_xxsel_2di", VSX_BUILTIN_XXSEL_2DI },
8478 { MASK_VSX, CODE_FOR_vector_select_v2df, "__builtin_vsx_xxsel_2df", VSX_BUILTIN_XXSEL_2DF },
8479 { MASK_VSX, CODE_FOR_vector_select_v4sf, "__builtin_vsx_xxsel_4sf", VSX_BUILTIN_XXSEL_4SF },
8480 { MASK_VSX, CODE_FOR_vector_select_v4si, "__builtin_vsx_xxsel_4si", VSX_BUILTIN_XXSEL_4SI },
8481 { MASK_VSX, CODE_FOR_vector_select_v8hi, "__builtin_vsx_xxsel_8hi", VSX_BUILTIN_XXSEL_8HI },
8482 { MASK_VSX, CODE_FOR_vector_select_v16qi, "__builtin_vsx_xxsel_16qi", VSX_BUILTIN_XXSEL_16QI },
8483 { MASK_VSX, CODE_FOR_vector_select_v2di_uns, "__builtin_vsx_xxsel_2di_uns", VSX_BUILTIN_XXSEL_2DI_UNS },
8484 { MASK_VSX, CODE_FOR_vector_select_v4si_uns, "__builtin_vsx_xxsel_4si_uns", VSX_BUILTIN_XXSEL_4SI_UNS },
8485 { MASK_VSX, CODE_FOR_vector_select_v8hi_uns, "__builtin_vsx_xxsel_8hi_uns", VSX_BUILTIN_XXSEL_8HI_UNS },
8486 { MASK_VSX, CODE_FOR_vector_select_v16qi_uns, "__builtin_vsx_xxsel_16qi_uns", VSX_BUILTIN_XXSEL_16QI_UNS },
8488 { MASK_VSX, CODE_FOR_altivec_vperm_v2di, "__builtin_vsx_vperm_2di", VSX_BUILTIN_VPERM_2DI },
8489 { MASK_VSX, CODE_FOR_altivec_vperm_v2df, "__builtin_vsx_vperm_2df", VSX_BUILTIN_VPERM_2DF },
8490 { MASK_VSX, CODE_FOR_altivec_vperm_v4sf, "__builtin_vsx_vperm_4sf", VSX_BUILTIN_VPERM_4SF },
8491 { MASK_VSX, CODE_FOR_altivec_vperm_v4si, "__builtin_vsx_vperm_4si", VSX_BUILTIN_VPERM_4SI },
8492 { MASK_VSX, CODE_FOR_altivec_vperm_v8hi, "__builtin_vsx_vperm_8hi", VSX_BUILTIN_VPERM_8HI },
8493 { MASK_VSX, CODE_FOR_altivec_vperm_v16qi, "__builtin_vsx_vperm_16qi", VSX_BUILTIN_VPERM_16QI },
8494 { MASK_VSX, CODE_FOR_altivec_vperm_v2di_uns, "__builtin_vsx_vperm_2di_uns", VSX_BUILTIN_VPERM_2DI_UNS },
8495 { MASK_VSX, CODE_FOR_altivec_vperm_v4si_uns, "__builtin_vsx_vperm_4si_uns", VSX_BUILTIN_VPERM_4SI_UNS },
8496 { MASK_VSX, CODE_FOR_altivec_vperm_v8hi_uns, "__builtin_vsx_vperm_8hi_uns", VSX_BUILTIN_VPERM_8HI_UNS },
8497 { MASK_VSX, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_vsx_vperm_16qi_uns", VSX_BUILTIN_VPERM_16QI_UNS },
8499 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v2df, "__builtin_vsx_xxpermdi_2df", VSX_BUILTIN_XXPERMDI_2DF },
8500 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v2di, "__builtin_vsx_xxpermdi_2di", VSX_BUILTIN_XXPERMDI_2DI },
8501 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v4sf, "__builtin_vsx_xxpermdi_4sf", VSX_BUILTIN_XXPERMDI_4SF },
8502 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v4si, "__builtin_vsx_xxpermdi_4si", VSX_BUILTIN_XXPERMDI_4SI },
8503 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v8hi, "__builtin_vsx_xxpermdi_8hi", VSX_BUILTIN_XXPERMDI_8HI },
8504 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v16qi, "__builtin_vsx_xxpermdi_16qi", VSX_BUILTIN_XXPERMDI_16QI },
8505 { MASK_VSX, CODE_FOR_nothing, "__builtin_vsx_xxpermdi", VSX_BUILTIN_VEC_XXPERMDI },
8506 { MASK_VSX, CODE_FOR_vsx_set_v2df, "__builtin_vsx_set_2df", VSX_BUILTIN_SET_2DF },
8507 { MASK_VSX, CODE_FOR_vsx_set_v2di, "__builtin_vsx_set_2di", VSX_BUILTIN_SET_2DI },
8509 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v2di, "__builtin_vsx_xxsldwi_2di", VSX_BUILTIN_XXSLDWI_2DI },
8510 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v2df, "__builtin_vsx_xxsldwi_2df", VSX_BUILTIN_XXSLDWI_2DF },
8511 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v4sf, "__builtin_vsx_xxsldwi_4sf", VSX_BUILTIN_XXSLDWI_4SF },
8512 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v4si, "__builtin_vsx_xxsldwi_4si", VSX_BUILTIN_XXSLDWI_4SI },
8513 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v8hi, "__builtin_vsx_xxsldwi_8hi", VSX_BUILTIN_XXSLDWI_8HI },
8514 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v16qi, "__builtin_vsx_xxsldwi_16qi", VSX_BUILTIN_XXSLDWI_16QI },
8515 { MASK_VSX, CODE_FOR_nothing, "__builtin_vsx_xxsldwi", VSX_BUILTIN_VEC_XXSLDWI },
8517 { 0, CODE_FOR_paired_msub, "__builtin_paired_msub", PAIRED_BUILTIN_MSUB },
8518 { 0, CODE_FOR_paired_madd, "__builtin_paired_madd", PAIRED_BUILTIN_MADD },
8519 { 0, CODE_FOR_paired_madds0, "__builtin_paired_madds0", PAIRED_BUILTIN_MADDS0 },
8520 { 0, CODE_FOR_paired_madds1, "__builtin_paired_madds1", PAIRED_BUILTIN_MADDS1 },
8521 { 0, CODE_FOR_paired_nmsub, "__builtin_paired_nmsub", PAIRED_BUILTIN_NMSUB },
8522 { 0, CODE_FOR_paired_nmadd, "__builtin_paired_nmadd", PAIRED_BUILTIN_NMADD },
8523 { 0, CODE_FOR_paired_sum0, "__builtin_paired_sum0", PAIRED_BUILTIN_SUM0 },
8524 { 0, CODE_FOR_paired_sum1, "__builtin_paired_sum1", PAIRED_BUILTIN_SUM1 },
8525 { 0, CODE_FOR_selv2sf4, "__builtin_paired_selv2sf4", PAIRED_BUILTIN_SELV2SF4 },
8528 /* DST operations: void foo (void *, const int, const char). */
8530 static const struct builtin_description bdesc_dst[] =
8532 { MASK_ALTIVEC, CODE_FOR_altivec_dst, "__builtin_altivec_dst", ALTIVEC_BUILTIN_DST },
8533 { MASK_ALTIVEC, CODE_FOR_altivec_dstt, "__builtin_altivec_dstt", ALTIVEC_BUILTIN_DSTT },
8534 { MASK_ALTIVEC, CODE_FOR_altivec_dstst, "__builtin_altivec_dstst", ALTIVEC_BUILTIN_DSTST },
8535 { MASK_ALTIVEC, CODE_FOR_altivec_dststt, "__builtin_altivec_dststt", ALTIVEC_BUILTIN_DSTSTT },
8537 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dst", ALTIVEC_BUILTIN_VEC_DST },
8538 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dstt", ALTIVEC_BUILTIN_VEC_DSTT },
8539 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dstst", ALTIVEC_BUILTIN_VEC_DSTST },
8540 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dststt", ALTIVEC_BUILTIN_VEC_DSTSTT }
8543 /* Simple binary operations: VECc = foo (VECa, VECb). */
8545 static struct builtin_description bdesc_2arg[] =
8547 { MASK_ALTIVEC, CODE_FOR_addv16qi3, "__builtin_altivec_vaddubm", ALTIVEC_BUILTIN_VADDUBM },
8548 { MASK_ALTIVEC, CODE_FOR_addv8hi3, "__builtin_altivec_vadduhm", ALTIVEC_BUILTIN_VADDUHM },
8549 { MASK_ALTIVEC, CODE_FOR_addv4si3, "__builtin_altivec_vadduwm", ALTIVEC_BUILTIN_VADDUWM },
8550 { MASK_ALTIVEC, CODE_FOR_addv4sf3, "__builtin_altivec_vaddfp", ALTIVEC_BUILTIN_VADDFP },
8551 { MASK_ALTIVEC, CODE_FOR_altivec_vaddcuw, "__builtin_altivec_vaddcuw", ALTIVEC_BUILTIN_VADDCUW },
8552 { MASK_ALTIVEC, CODE_FOR_altivec_vaddubs, "__builtin_altivec_vaddubs", ALTIVEC_BUILTIN_VADDUBS },
8553 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsbs, "__builtin_altivec_vaddsbs", ALTIVEC_BUILTIN_VADDSBS },
8554 { MASK_ALTIVEC, CODE_FOR_altivec_vadduhs, "__builtin_altivec_vadduhs", ALTIVEC_BUILTIN_VADDUHS },
8555 { MASK_ALTIVEC, CODE_FOR_altivec_vaddshs, "__builtin_altivec_vaddshs", ALTIVEC_BUILTIN_VADDSHS },
8556 { MASK_ALTIVEC, CODE_FOR_altivec_vadduws, "__builtin_altivec_vadduws", ALTIVEC_BUILTIN_VADDUWS },
8557 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsws, "__builtin_altivec_vaddsws", ALTIVEC_BUILTIN_VADDSWS },
8558 { MASK_ALTIVEC, CODE_FOR_andv4si3, "__builtin_altivec_vand", ALTIVEC_BUILTIN_VAND },
8559 { MASK_ALTIVEC, CODE_FOR_andcv4si3, "__builtin_altivec_vandc", ALTIVEC_BUILTIN_VANDC },
8560 { MASK_ALTIVEC, CODE_FOR_altivec_vavgub, "__builtin_altivec_vavgub", ALTIVEC_BUILTIN_VAVGUB },
8561 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsb, "__builtin_altivec_vavgsb", ALTIVEC_BUILTIN_VAVGSB },
8562 { MASK_ALTIVEC, CODE_FOR_altivec_vavguh, "__builtin_altivec_vavguh", ALTIVEC_BUILTIN_VAVGUH },
8563 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsh, "__builtin_altivec_vavgsh", ALTIVEC_BUILTIN_VAVGSH },
8564 { MASK_ALTIVEC, CODE_FOR_altivec_vavguw, "__builtin_altivec_vavguw", ALTIVEC_BUILTIN_VAVGUW },
8565 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsw, "__builtin_altivec_vavgsw", ALTIVEC_BUILTIN_VAVGSW },
8566 { MASK_ALTIVEC, CODE_FOR_altivec_vcfux, "__builtin_altivec_vcfux", ALTIVEC_BUILTIN_VCFUX },
8567 { MASK_ALTIVEC, CODE_FOR_altivec_vcfsx, "__builtin_altivec_vcfsx", ALTIVEC_BUILTIN_VCFSX },
8568 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpbfp, "__builtin_altivec_vcmpbfp", ALTIVEC_BUILTIN_VCMPBFP },
8569 { MASK_ALTIVEC, CODE_FOR_vector_eqv16qi, "__builtin_altivec_vcmpequb", ALTIVEC_BUILTIN_VCMPEQUB },
8570 { MASK_ALTIVEC, CODE_FOR_vector_eqv8hi, "__builtin_altivec_vcmpequh", ALTIVEC_BUILTIN_VCMPEQUH },
8571 { MASK_ALTIVEC, CODE_FOR_vector_eqv4si, "__builtin_altivec_vcmpequw", ALTIVEC_BUILTIN_VCMPEQUW },
8572 { MASK_ALTIVEC, CODE_FOR_vector_eqv4sf, "__builtin_altivec_vcmpeqfp", ALTIVEC_BUILTIN_VCMPEQFP },
8573 { MASK_ALTIVEC, CODE_FOR_vector_gev4sf, "__builtin_altivec_vcmpgefp", ALTIVEC_BUILTIN_VCMPGEFP },
8574 { MASK_ALTIVEC, CODE_FOR_vector_gtuv16qi, "__builtin_altivec_vcmpgtub", ALTIVEC_BUILTIN_VCMPGTUB },
8575 { MASK_ALTIVEC, CODE_FOR_vector_gtuv8hi, "__builtin_altivec_vcmpgtsb", ALTIVEC_BUILTIN_VCMPGTSB },
8576 { MASK_ALTIVEC, CODE_FOR_vector_gtuv4si, "__builtin_altivec_vcmpgtuh", ALTIVEC_BUILTIN_VCMPGTUH },
8577 { MASK_ALTIVEC, CODE_FOR_vector_gtv16qi, "__builtin_altivec_vcmpgtsh", ALTIVEC_BUILTIN_VCMPGTSH },
8578 { MASK_ALTIVEC, CODE_FOR_vector_gtv8hi, "__builtin_altivec_vcmpgtuw", ALTIVEC_BUILTIN_VCMPGTUW },
8579 { MASK_ALTIVEC, CODE_FOR_vector_gtv4si, "__builtin_altivec_vcmpgtsw", ALTIVEC_BUILTIN_VCMPGTSW },
8580 { MASK_ALTIVEC, CODE_FOR_vector_gtv4sf, "__builtin_altivec_vcmpgtfp", ALTIVEC_BUILTIN_VCMPGTFP },
8581 { MASK_ALTIVEC, CODE_FOR_altivec_vctsxs, "__builtin_altivec_vctsxs", ALTIVEC_BUILTIN_VCTSXS },
8582 { MASK_ALTIVEC, CODE_FOR_altivec_vctuxs, "__builtin_altivec_vctuxs", ALTIVEC_BUILTIN_VCTUXS },
8583 { MASK_ALTIVEC, CODE_FOR_umaxv16qi3, "__builtin_altivec_vmaxub", ALTIVEC_BUILTIN_VMAXUB },
8584 { MASK_ALTIVEC, CODE_FOR_smaxv16qi3, "__builtin_altivec_vmaxsb", ALTIVEC_BUILTIN_VMAXSB },
8585 { MASK_ALTIVEC, CODE_FOR_umaxv8hi3, "__builtin_altivec_vmaxuh", ALTIVEC_BUILTIN_VMAXUH },
8586 { MASK_ALTIVEC, CODE_FOR_smaxv8hi3, "__builtin_altivec_vmaxsh", ALTIVEC_BUILTIN_VMAXSH },
8587 { MASK_ALTIVEC, CODE_FOR_umaxv4si3, "__builtin_altivec_vmaxuw", ALTIVEC_BUILTIN_VMAXUW },
8588 { MASK_ALTIVEC, CODE_FOR_smaxv4si3, "__builtin_altivec_vmaxsw", ALTIVEC_BUILTIN_VMAXSW },
8589 { MASK_ALTIVEC, CODE_FOR_smaxv4sf3, "__builtin_altivec_vmaxfp", ALTIVEC_BUILTIN_VMAXFP },
8590 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghb, "__builtin_altivec_vmrghb", ALTIVEC_BUILTIN_VMRGHB },
8591 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghh, "__builtin_altivec_vmrghh", ALTIVEC_BUILTIN_VMRGHH },
8592 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghw, "__builtin_altivec_vmrghw", ALTIVEC_BUILTIN_VMRGHW },
8593 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglb, "__builtin_altivec_vmrglb", ALTIVEC_BUILTIN_VMRGLB },
8594 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglh, "__builtin_altivec_vmrglh", ALTIVEC_BUILTIN_VMRGLH },
8595 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglw, "__builtin_altivec_vmrglw", ALTIVEC_BUILTIN_VMRGLW },
8596 { MASK_ALTIVEC, CODE_FOR_uminv16qi3, "__builtin_altivec_vminub", ALTIVEC_BUILTIN_VMINUB },
8597 { MASK_ALTIVEC, CODE_FOR_sminv16qi3, "__builtin_altivec_vminsb", ALTIVEC_BUILTIN_VMINSB },
8598 { MASK_ALTIVEC, CODE_FOR_uminv8hi3, "__builtin_altivec_vminuh", ALTIVEC_BUILTIN_VMINUH },
8599 { MASK_ALTIVEC, CODE_FOR_sminv8hi3, "__builtin_altivec_vminsh", ALTIVEC_BUILTIN_VMINSH },
8600 { MASK_ALTIVEC, CODE_FOR_uminv4si3, "__builtin_altivec_vminuw", ALTIVEC_BUILTIN_VMINUW },
8601 { MASK_ALTIVEC, CODE_FOR_sminv4si3, "__builtin_altivec_vminsw", ALTIVEC_BUILTIN_VMINSW },
8602 { MASK_ALTIVEC, CODE_FOR_sminv4sf3, "__builtin_altivec_vminfp", ALTIVEC_BUILTIN_VMINFP },
8603 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleub, "__builtin_altivec_vmuleub", ALTIVEC_BUILTIN_VMULEUB },
8604 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleub, "__builtin_altivec_vmuleub_uns", ALTIVEC_BUILTIN_VMULEUB_UNS },
8605 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesb, "__builtin_altivec_vmulesb", ALTIVEC_BUILTIN_VMULESB },
8606 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleuh, "__builtin_altivec_vmuleuh", ALTIVEC_BUILTIN_VMULEUH },
8607 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleuh, "__builtin_altivec_vmuleuh_uns", ALTIVEC_BUILTIN_VMULEUH_UNS },
8608 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesh, "__builtin_altivec_vmulesh", ALTIVEC_BUILTIN_VMULESH },
8609 { MASK_ALTIVEC, CODE_FOR_altivec_vmuloub, "__builtin_altivec_vmuloub", ALTIVEC_BUILTIN_VMULOUB },
8610 { MASK_ALTIVEC, CODE_FOR_altivec_vmuloub, "__builtin_altivec_vmuloub_uns", ALTIVEC_BUILTIN_VMULOUB_UNS },
8611 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosb, "__builtin_altivec_vmulosb", ALTIVEC_BUILTIN_VMULOSB },
8612 { MASK_ALTIVEC, CODE_FOR_altivec_vmulouh, "__builtin_altivec_vmulouh", ALTIVEC_BUILTIN_VMULOUH },
8613 { MASK_ALTIVEC, CODE_FOR_altivec_vmulouh, "__builtin_altivec_vmulouh_uns", ALTIVEC_BUILTIN_VMULOUH_UNS },
8614 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosh, "__builtin_altivec_vmulosh", ALTIVEC_BUILTIN_VMULOSH },
8615 { MASK_ALTIVEC, CODE_FOR_norv4si3, "__builtin_altivec_vnor", ALTIVEC_BUILTIN_VNOR },
8616 { MASK_ALTIVEC, CODE_FOR_iorv4si3, "__builtin_altivec_vor", ALTIVEC_BUILTIN_VOR },
8617 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhum, "__builtin_altivec_vpkuhum", ALTIVEC_BUILTIN_VPKUHUM },
8618 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwum, "__builtin_altivec_vpkuwum", ALTIVEC_BUILTIN_VPKUWUM },
8619 { MASK_ALTIVEC, CODE_FOR_altivec_vpkpx, "__builtin_altivec_vpkpx", ALTIVEC_BUILTIN_VPKPX },
8620 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshss, "__builtin_altivec_vpkshss", ALTIVEC_BUILTIN_VPKSHSS },
8621 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswss, "__builtin_altivec_vpkswss", ALTIVEC_BUILTIN_VPKSWSS },
8622 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhus, "__builtin_altivec_vpkuhus", ALTIVEC_BUILTIN_VPKUHUS },
8623 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshus, "__builtin_altivec_vpkshus", ALTIVEC_BUILTIN_VPKSHUS },
8624 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwus, "__builtin_altivec_vpkuwus", ALTIVEC_BUILTIN_VPKUWUS },
8625 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswus, "__builtin_altivec_vpkswus", ALTIVEC_BUILTIN_VPKSWUS },
8626 { MASK_ALTIVEC, CODE_FOR_vrotlv16qi3, "__builtin_altivec_vrlb", ALTIVEC_BUILTIN_VRLB },
8627 { MASK_ALTIVEC, CODE_FOR_vrotlv8hi3, "__builtin_altivec_vrlh", ALTIVEC_BUILTIN_VRLH },
8628 { MASK_ALTIVEC, CODE_FOR_vrotlv4si3, "__builtin_altivec_vrlw", ALTIVEC_BUILTIN_VRLW },
8629 { MASK_ALTIVEC, CODE_FOR_vashlv16qi3, "__builtin_altivec_vslb", ALTIVEC_BUILTIN_VSLB },
8630 { MASK_ALTIVEC, CODE_FOR_vashlv8hi3, "__builtin_altivec_vslh", ALTIVEC_BUILTIN_VSLH },
8631 { MASK_ALTIVEC, CODE_FOR_vashlv4si3, "__builtin_altivec_vslw", ALTIVEC_BUILTIN_VSLW },
8632 { MASK_ALTIVEC, CODE_FOR_altivec_vsl, "__builtin_altivec_vsl", ALTIVEC_BUILTIN_VSL },
8633 { MASK_ALTIVEC, CODE_FOR_altivec_vslo, "__builtin_altivec_vslo", ALTIVEC_BUILTIN_VSLO },
8634 { MASK_ALTIVEC, CODE_FOR_altivec_vspltb, "__builtin_altivec_vspltb", ALTIVEC_BUILTIN_VSPLTB },
8635 { MASK_ALTIVEC, CODE_FOR_altivec_vsplth, "__builtin_altivec_vsplth", ALTIVEC_BUILTIN_VSPLTH },
8636 { MASK_ALTIVEC, CODE_FOR_altivec_vspltw, "__builtin_altivec_vspltw", ALTIVEC_BUILTIN_VSPLTW },
8637 { MASK_ALTIVEC, CODE_FOR_vlshrv16qi3, "__builtin_altivec_vsrb", ALTIVEC_BUILTIN_VSRB },
8638 { MASK_ALTIVEC, CODE_FOR_vlshrv8hi3, "__builtin_altivec_vsrh", ALTIVEC_BUILTIN_VSRH },
8639 { MASK_ALTIVEC, CODE_FOR_vlshrv4si3, "__builtin_altivec_vsrw", ALTIVEC_BUILTIN_VSRW },
8640 { MASK_ALTIVEC, CODE_FOR_vashrv16qi3, "__builtin_altivec_vsrab", ALTIVEC_BUILTIN_VSRAB },
8641 { MASK_ALTIVEC, CODE_FOR_vashrv8hi3, "__builtin_altivec_vsrah", ALTIVEC_BUILTIN_VSRAH },
8642 { MASK_ALTIVEC, CODE_FOR_vashrv4si3, "__builtin_altivec_vsraw", ALTIVEC_BUILTIN_VSRAW },
8643 { MASK_ALTIVEC, CODE_FOR_altivec_vsr, "__builtin_altivec_vsr", ALTIVEC_BUILTIN_VSR },
8644 { MASK_ALTIVEC, CODE_FOR_altivec_vsro, "__builtin_altivec_vsro", ALTIVEC_BUILTIN_VSRO },
8645 { MASK_ALTIVEC, CODE_FOR_subv16qi3, "__builtin_altivec_vsububm", ALTIVEC_BUILTIN_VSUBUBM },
8646 { MASK_ALTIVEC, CODE_FOR_subv8hi3, "__builtin_altivec_vsubuhm", ALTIVEC_BUILTIN_VSUBUHM },
8647 { MASK_ALTIVEC, CODE_FOR_subv4si3, "__builtin_altivec_vsubuwm", ALTIVEC_BUILTIN_VSUBUWM },
8648 { MASK_ALTIVEC, CODE_FOR_subv4sf3, "__builtin_altivec_vsubfp", ALTIVEC_BUILTIN_VSUBFP },
8649 { MASK_ALTIVEC, CODE_FOR_altivec_vsubcuw, "__builtin_altivec_vsubcuw", ALTIVEC_BUILTIN_VSUBCUW },
8650 { MASK_ALTIVEC, CODE_FOR_altivec_vsububs, "__builtin_altivec_vsububs", ALTIVEC_BUILTIN_VSUBUBS },
8651 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsbs, "__builtin_altivec_vsubsbs", ALTIVEC_BUILTIN_VSUBSBS },
8652 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuhs, "__builtin_altivec_vsubuhs", ALTIVEC_BUILTIN_VSUBUHS },
8653 { MASK_ALTIVEC, CODE_FOR_altivec_vsubshs, "__builtin_altivec_vsubshs", ALTIVEC_BUILTIN_VSUBSHS },
8654 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuws, "__builtin_altivec_vsubuws", ALTIVEC_BUILTIN_VSUBUWS },
8655 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsws, "__builtin_altivec_vsubsws", ALTIVEC_BUILTIN_VSUBSWS },
8656 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4ubs, "__builtin_altivec_vsum4ubs", ALTIVEC_BUILTIN_VSUM4UBS },
8657 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4sbs, "__builtin_altivec_vsum4sbs", ALTIVEC_BUILTIN_VSUM4SBS },
8658 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4shs, "__builtin_altivec_vsum4shs", ALTIVEC_BUILTIN_VSUM4SHS },
8659 { MASK_ALTIVEC, CODE_FOR_altivec_vsum2sws, "__builtin_altivec_vsum2sws", ALTIVEC_BUILTIN_VSUM2SWS },
8660 { MASK_ALTIVEC, CODE_FOR_altivec_vsumsws, "__builtin_altivec_vsumsws", ALTIVEC_BUILTIN_VSUMSWS },
8661 { MASK_ALTIVEC, CODE_FOR_xorv4si3, "__builtin_altivec_vxor", ALTIVEC_BUILTIN_VXOR },
8662 { MASK_ALTIVEC, CODE_FOR_vector_copysignv4sf3, "__builtin_altivec_copysignfp", ALTIVEC_BUILTIN_COPYSIGN_V4SF },
8664 { MASK_VSX, CODE_FOR_addv2df3, "__builtin_vsx_xvadddp", VSX_BUILTIN_XVADDDP },
8665 { MASK_VSX, CODE_FOR_subv2df3, "__builtin_vsx_xvsubdp", VSX_BUILTIN_XVSUBDP },
8666 { MASK_VSX, CODE_FOR_mulv2df3, "__builtin_vsx_xvmuldp", VSX_BUILTIN_XVMULDP },
8667 { MASK_VSX, CODE_FOR_divv2df3, "__builtin_vsx_xvdivdp", VSX_BUILTIN_XVDIVDP },
8668 { MASK_VSX, CODE_FOR_sminv2df3, "__builtin_vsx_xvmindp", VSX_BUILTIN_XVMINDP },
8669 { MASK_VSX, CODE_FOR_smaxv2df3, "__builtin_vsx_xvmaxdp", VSX_BUILTIN_XVMAXDP },
8670 { MASK_VSX, CODE_FOR_vsx_tdivv2df3_fe, "__builtin_vsx_xvtdivdp_fe", VSX_BUILTIN_XVTDIVDP_FE },
8671 { MASK_VSX, CODE_FOR_vsx_tdivv2df3_fg, "__builtin_vsx_xvtdivdp_fg", VSX_BUILTIN_XVTDIVDP_FG },
8672 { MASK_VSX, CODE_FOR_vector_eqv2df, "__builtin_vsx_xvcmpeqdp", VSX_BUILTIN_XVCMPEQDP },
8673 { MASK_VSX, CODE_FOR_vector_gtv2df, "__builtin_vsx_xvcmpgtdp", VSX_BUILTIN_XVCMPGTDP },
8674 { MASK_VSX, CODE_FOR_vector_gev2df, "__builtin_vsx_xvcmpgedp", VSX_BUILTIN_XVCMPGEDP },
8676 { MASK_VSX, CODE_FOR_addv4sf3, "__builtin_vsx_xvaddsp", VSX_BUILTIN_XVADDSP },
8677 { MASK_VSX, CODE_FOR_subv4sf3, "__builtin_vsx_xvsubsp", VSX_BUILTIN_XVSUBSP },
8678 { MASK_VSX, CODE_FOR_mulv4sf3, "__builtin_vsx_xvmulsp", VSX_BUILTIN_XVMULSP },
8679 { MASK_VSX, CODE_FOR_divv4sf3, "__builtin_vsx_xvdivsp", VSX_BUILTIN_XVDIVSP },
8680 { MASK_VSX, CODE_FOR_sminv4sf3, "__builtin_vsx_xvminsp", VSX_BUILTIN_XVMINSP },
8681 { MASK_VSX, CODE_FOR_smaxv4sf3, "__builtin_vsx_xvmaxsp", VSX_BUILTIN_XVMAXSP },
8682 { MASK_VSX, CODE_FOR_vsx_tdivv4sf3_fe, "__builtin_vsx_xvtdivsp_fe", VSX_BUILTIN_XVTDIVSP_FE },
8683 { MASK_VSX, CODE_FOR_vsx_tdivv4sf3_fg, "__builtin_vsx_xvtdivsp_fg", VSX_BUILTIN_XVTDIVSP_FG },
8684 { MASK_VSX, CODE_FOR_vector_eqv4sf, "__builtin_vsx_xvcmpeqsp", VSX_BUILTIN_XVCMPEQSP },
8685 { MASK_VSX, CODE_FOR_vector_gtv4sf, "__builtin_vsx_xvcmpgtsp", VSX_BUILTIN_XVCMPGTSP },
8686 { MASK_VSX, CODE_FOR_vector_gev4sf, "__builtin_vsx_xvcmpgesp", VSX_BUILTIN_XVCMPGESP },
8688 { MASK_VSX, CODE_FOR_smindf3, "__builtin_vsx_xsmindp", VSX_BUILTIN_XSMINDP },
8689 { MASK_VSX, CODE_FOR_smaxdf3, "__builtin_vsx_xsmaxdp", VSX_BUILTIN_XSMAXDP },
8690 { MASK_VSX, CODE_FOR_vsx_tdivdf3_fe, "__builtin_vsx_xstdivdp_fe", VSX_BUILTIN_XSTDIVDP_FE },
8691 { MASK_VSX, CODE_FOR_vsx_tdivdf3_fg, "__builtin_vsx_xstdivdp_fg", VSX_BUILTIN_XSTDIVDP_FG },
8692 { MASK_VSX, CODE_FOR_vector_copysignv2df3, "__builtin_vsx_cpsgndp", VSX_BUILTIN_CPSGNDP },
8693 { MASK_VSX, CODE_FOR_vector_copysignv4sf3, "__builtin_vsx_cpsgnsp", VSX_BUILTIN_CPSGNSP },
8695 { MASK_VSX, CODE_FOR_vsx_concat_v2df, "__builtin_vsx_concat_2df", VSX_BUILTIN_CONCAT_2DF },
8696 { MASK_VSX, CODE_FOR_vsx_concat_v2di, "__builtin_vsx_concat_2di", VSX_BUILTIN_CONCAT_2DI },
8697 { MASK_VSX, CODE_FOR_vsx_splat_v2df, "__builtin_vsx_splat_2df", VSX_BUILTIN_SPLAT_2DF },
8698 { MASK_VSX, CODE_FOR_vsx_splat_v2di, "__builtin_vsx_splat_2di", VSX_BUILTIN_SPLAT_2DI },
8699 { MASK_VSX, CODE_FOR_vsx_xxmrghw_v4sf, "__builtin_vsx_xxmrghw", VSX_BUILTIN_XXMRGHW_4SF },
8700 { MASK_VSX, CODE_FOR_vsx_xxmrghw_v4si, "__builtin_vsx_xxmrghw_4si", VSX_BUILTIN_XXMRGHW_4SI },
8701 { MASK_VSX, CODE_FOR_vsx_xxmrglw_v4sf, "__builtin_vsx_xxmrglw", VSX_BUILTIN_XXMRGLW_4SF },
8702 { MASK_VSX, CODE_FOR_vsx_xxmrglw_v4si, "__builtin_vsx_xxmrglw_4si", VSX_BUILTIN_XXMRGLW_4SI },
8704 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_add", ALTIVEC_BUILTIN_VEC_ADD },
8705 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vaddfp", ALTIVEC_BUILTIN_VEC_VADDFP },
8706 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduwm", ALTIVEC_BUILTIN_VEC_VADDUWM },
8707 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhm", ALTIVEC_BUILTIN_VEC_VADDUHM },
8708 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubm", ALTIVEC_BUILTIN_VEC_VADDUBM },
8709 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_addc", ALTIVEC_BUILTIN_VEC_ADDC },
8710 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_adds", ALTIVEC_BUILTIN_VEC_ADDS },
8711 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddsws", ALTIVEC_BUILTIN_VEC_VADDSWS },
8712 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduws", ALTIVEC_BUILTIN_VEC_VADDUWS },
8713 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddshs", ALTIVEC_BUILTIN_VEC_VADDSHS },
8714 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhs", ALTIVEC_BUILTIN_VEC_VADDUHS },
8715 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddsbs", ALTIVEC_BUILTIN_VEC_VADDSBS },
8716 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubs", ALTIVEC_BUILTIN_VEC_VADDUBS },
8717 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_and", ALTIVEC_BUILTIN_VEC_AND },
8718 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_andc", ALTIVEC_BUILTIN_VEC_ANDC },
8719 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_avg", ALTIVEC_BUILTIN_VEC_AVG },
8720 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsw", ALTIVEC_BUILTIN_VEC_VAVGSW },
8721 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavguw", ALTIVEC_BUILTIN_VEC_VAVGUW },
8722 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsh", ALTIVEC_BUILTIN_VEC_VAVGSH },
8723 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavguh", ALTIVEC_BUILTIN_VEC_VAVGUH },
8724 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsb", ALTIVEC_BUILTIN_VEC_VAVGSB },
8725 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgub", ALTIVEC_BUILTIN_VEC_VAVGUB },
8726 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpb", ALTIVEC_BUILTIN_VEC_CMPB },
8727 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpeq", ALTIVEC_BUILTIN_VEC_CMPEQ },
8728 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpeqfp", ALTIVEC_BUILTIN_VEC_VCMPEQFP },
8729 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequw", ALTIVEC_BUILTIN_VEC_VCMPEQUW },
8730 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequh", ALTIVEC_BUILTIN_VEC_VCMPEQUH },
8731 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequb", ALTIVEC_BUILTIN_VEC_VCMPEQUB },
8732 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpge", ALTIVEC_BUILTIN_VEC_CMPGE },
8733 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpgt", ALTIVEC_BUILTIN_VEC_CMPGT },
8734 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtfp", ALTIVEC_BUILTIN_VEC_VCMPGTFP },
8735 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsw", ALTIVEC_BUILTIN_VEC_VCMPGTSW },
8736 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtuw", ALTIVEC_BUILTIN_VEC_VCMPGTUW },
8737 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsh", ALTIVEC_BUILTIN_VEC_VCMPGTSH },
8738 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtuh", ALTIVEC_BUILTIN_VEC_VCMPGTUH },
8739 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsb", ALTIVEC_BUILTIN_VEC_VCMPGTSB },
8740 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtub", ALTIVEC_BUILTIN_VEC_VCMPGTUB },
8741 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmple", ALTIVEC_BUILTIN_VEC_CMPLE },
8742 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmplt", ALTIVEC_BUILTIN_VEC_CMPLT },
8743 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_copysign", ALTIVEC_BUILTIN_VEC_COPYSIGN },
8744 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_max", ALTIVEC_BUILTIN_VEC_MAX },
8745 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vmaxfp", ALTIVEC_BUILTIN_VEC_VMAXFP },
8746 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsw", ALTIVEC_BUILTIN_VEC_VMAXSW },
8747 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxuw", ALTIVEC_BUILTIN_VEC_VMAXUW },
8748 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsh", ALTIVEC_BUILTIN_VEC_VMAXSH },
8749 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxuh", ALTIVEC_BUILTIN_VEC_VMAXUH },
8750 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsb", ALTIVEC_BUILTIN_VEC_VMAXSB },
8751 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxub", ALTIVEC_BUILTIN_VEC_VMAXUB },
8752 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mergeh", ALTIVEC_BUILTIN_VEC_MERGEH },
8753 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghw", ALTIVEC_BUILTIN_VEC_VMRGHW },
8754 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghh", ALTIVEC_BUILTIN_VEC_VMRGHH },
8755 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghb", ALTIVEC_BUILTIN_VEC_VMRGHB },
8756 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mergel", ALTIVEC_BUILTIN_VEC_MERGEL },
8757 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglw", ALTIVEC_BUILTIN_VEC_VMRGLW },
8758 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglh", ALTIVEC_BUILTIN_VEC_VMRGLH },
8759 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglb", ALTIVEC_BUILTIN_VEC_VMRGLB },
8760 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_min", ALTIVEC_BUILTIN_VEC_MIN },
8761 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vminfp", ALTIVEC_BUILTIN_VEC_VMINFP },
8762 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsw", ALTIVEC_BUILTIN_VEC_VMINSW },
8763 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminuw", ALTIVEC_BUILTIN_VEC_VMINUW },
8764 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsh", ALTIVEC_BUILTIN_VEC_VMINSH },
8765 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminuh", ALTIVEC_BUILTIN_VEC_VMINUH },
8766 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsb", ALTIVEC_BUILTIN_VEC_VMINSB },
8767 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminub", ALTIVEC_BUILTIN_VEC_VMINUB },
8768 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mule", ALTIVEC_BUILTIN_VEC_MULE },
8769 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuleub", ALTIVEC_BUILTIN_VEC_VMULEUB },
8770 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulesb", ALTIVEC_BUILTIN_VEC_VMULESB },
8771 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuleuh", ALTIVEC_BUILTIN_VEC_VMULEUH },
8772 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulesh", ALTIVEC_BUILTIN_VEC_VMULESH },
8773 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mulo", ALTIVEC_BUILTIN_VEC_MULO },
8774 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulosh", ALTIVEC_BUILTIN_VEC_VMULOSH },
8775 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulouh", ALTIVEC_BUILTIN_VEC_VMULOUH },
8776 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulosb", ALTIVEC_BUILTIN_VEC_VMULOSB },
8777 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuloub", ALTIVEC_BUILTIN_VEC_VMULOUB },
8778 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_nor", ALTIVEC_BUILTIN_VEC_NOR },
8779 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_or", ALTIVEC_BUILTIN_VEC_OR },
8780 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_pack", ALTIVEC_BUILTIN_VEC_PACK },
8781 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuwum", ALTIVEC_BUILTIN_VEC_VPKUWUM },
8782 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuhum", ALTIVEC_BUILTIN_VEC_VPKUHUM },
8783 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packpx", ALTIVEC_BUILTIN_VEC_PACKPX },
8784 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packs", ALTIVEC_BUILTIN_VEC_PACKS },
8785 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkswss", ALTIVEC_BUILTIN_VEC_VPKSWSS },
8786 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuwus", ALTIVEC_BUILTIN_VEC_VPKUWUS },
8787 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkshss", ALTIVEC_BUILTIN_VEC_VPKSHSS },
8788 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuhus", ALTIVEC_BUILTIN_VEC_VPKUHUS },
8789 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packsu", ALTIVEC_BUILTIN_VEC_PACKSU },
8790 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkswus", ALTIVEC_BUILTIN_VEC_VPKSWUS },
8791 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkshus", ALTIVEC_BUILTIN_VEC_VPKSHUS },
8792 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rl", ALTIVEC_BUILTIN_VEC_RL },
8793 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlw", ALTIVEC_BUILTIN_VEC_VRLW },
8794 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlh", ALTIVEC_BUILTIN_VEC_VRLH },
8795 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlb", ALTIVEC_BUILTIN_VEC_VRLB },
8796 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sl", ALTIVEC_BUILTIN_VEC_SL },
8797 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslw", ALTIVEC_BUILTIN_VEC_VSLW },
8798 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslh", ALTIVEC_BUILTIN_VEC_VSLH },
8799 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslb", ALTIVEC_BUILTIN_VEC_VSLB },
8800 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sll", ALTIVEC_BUILTIN_VEC_SLL },
8801 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_slo", ALTIVEC_BUILTIN_VEC_SLO },
8802 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sr", ALTIVEC_BUILTIN_VEC_SR },
8803 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrw", ALTIVEC_BUILTIN_VEC_VSRW },
8804 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrh", ALTIVEC_BUILTIN_VEC_VSRH },
8805 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrb", ALTIVEC_BUILTIN_VEC_VSRB },
8806 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sra", ALTIVEC_BUILTIN_VEC_SRA },
8807 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsraw", ALTIVEC_BUILTIN_VEC_VSRAW },
8808 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrah", ALTIVEC_BUILTIN_VEC_VSRAH },
8809 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrab", ALTIVEC_BUILTIN_VEC_VSRAB },
8810 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_srl", ALTIVEC_BUILTIN_VEC_SRL },
8811 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sro", ALTIVEC_BUILTIN_VEC_SRO },
8812 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_sub", ALTIVEC_BUILTIN_VEC_SUB },
8813 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vsubfp", ALTIVEC_BUILTIN_VEC_VSUBFP },
8814 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuwm", ALTIVEC_BUILTIN_VEC_VSUBUWM },
8815 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuhm", ALTIVEC_BUILTIN_VEC_VSUBUHM },
8816 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsububm", ALTIVEC_BUILTIN_VEC_VSUBUBM },
8817 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_subc", ALTIVEC_BUILTIN_VEC_SUBC },
8818 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_subs", ALTIVEC_BUILTIN_VEC_SUBS },
8819 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubsws", ALTIVEC_BUILTIN_VEC_VSUBSWS },
8820 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuws", ALTIVEC_BUILTIN_VEC_VSUBUWS },
8821 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubshs", ALTIVEC_BUILTIN_VEC_VSUBSHS },
8822 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuhs", ALTIVEC_BUILTIN_VEC_VSUBUHS },
8823 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubsbs", ALTIVEC_BUILTIN_VEC_VSUBSBS },
8824 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsububs", ALTIVEC_BUILTIN_VEC_VSUBUBS },
8825 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sum4s", ALTIVEC_BUILTIN_VEC_SUM4S },
8826 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4shs", ALTIVEC_BUILTIN_VEC_VSUM4SHS },
8827 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4sbs", ALTIVEC_BUILTIN_VEC_VSUM4SBS },
8828 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4ubs", ALTIVEC_BUILTIN_VEC_VSUM4UBS },
8829 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sum2s", ALTIVEC_BUILTIN_VEC_SUM2S },
8830 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sums", ALTIVEC_BUILTIN_VEC_SUMS },
8831 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_xor", ALTIVEC_BUILTIN_VEC_XOR },
8833 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_mul", VSX_BUILTIN_VEC_MUL },
8834 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_div", VSX_BUILTIN_VEC_DIV },
8836 { 0, CODE_FOR_divv2sf3, "__builtin_paired_divv2sf3", PAIRED_BUILTIN_DIVV2SF3 },
8837 { 0, CODE_FOR_addv2sf3, "__builtin_paired_addv2sf3", PAIRED_BUILTIN_ADDV2SF3 },
8838 { 0, CODE_FOR_subv2sf3, "__builtin_paired_subv2sf3", PAIRED_BUILTIN_SUBV2SF3 },
8839 { 0, CODE_FOR_mulv2sf3, "__builtin_paired_mulv2sf3", PAIRED_BUILTIN_MULV2SF3 },
8840 { 0, CODE_FOR_paired_muls0, "__builtin_paired_muls0", PAIRED_BUILTIN_MULS0 },
8841 { 0, CODE_FOR_paired_muls1, "__builtin_paired_muls1", PAIRED_BUILTIN_MULS1 },
8842 { 0, CODE_FOR_paired_merge00, "__builtin_paired_merge00", PAIRED_BUILTIN_MERGE00 },
8843 { 0, CODE_FOR_paired_merge01, "__builtin_paired_merge01", PAIRED_BUILTIN_MERGE01 },
8844 { 0, CODE_FOR_paired_merge10, "__builtin_paired_merge10", PAIRED_BUILTIN_MERGE10 },
8845 { 0, CODE_FOR_paired_merge11, "__builtin_paired_merge11", PAIRED_BUILTIN_MERGE11 },
8847 /* Place holder, leave as first spe builtin. */
8848 { 0, CODE_FOR_spe_evaddw, "__builtin_spe_evaddw", SPE_BUILTIN_EVADDW },
8849 { 0, CODE_FOR_spe_evand, "__builtin_spe_evand", SPE_BUILTIN_EVAND },
8850 { 0, CODE_FOR_spe_evandc, "__builtin_spe_evandc", SPE_BUILTIN_EVANDC },
8851 { 0, CODE_FOR_spe_evdivws, "__builtin_spe_evdivws", SPE_BUILTIN_EVDIVWS },
8852 { 0, CODE_FOR_spe_evdivwu, "__builtin_spe_evdivwu", SPE_BUILTIN_EVDIVWU },
8853 { 0, CODE_FOR_spe_eveqv, "__builtin_spe_eveqv", SPE_BUILTIN_EVEQV },
8854 { 0, CODE_FOR_spe_evfsadd, "__builtin_spe_evfsadd", SPE_BUILTIN_EVFSADD },
8855 { 0, CODE_FOR_spe_evfsdiv, "__builtin_spe_evfsdiv", SPE_BUILTIN_EVFSDIV },
8856 { 0, CODE_FOR_spe_evfsmul, "__builtin_spe_evfsmul", SPE_BUILTIN_EVFSMUL },
8857 { 0, CODE_FOR_spe_evfssub, "__builtin_spe_evfssub", SPE_BUILTIN_EVFSSUB },
8858 { 0, CODE_FOR_spe_evmergehi, "__builtin_spe_evmergehi", SPE_BUILTIN_EVMERGEHI },
8859 { 0, CODE_FOR_spe_evmergehilo, "__builtin_spe_evmergehilo", SPE_BUILTIN_EVMERGEHILO },
8860 { 0, CODE_FOR_spe_evmergelo, "__builtin_spe_evmergelo", SPE_BUILTIN_EVMERGELO },
8861 { 0, CODE_FOR_spe_evmergelohi, "__builtin_spe_evmergelohi", SPE_BUILTIN_EVMERGELOHI },
8862 { 0, CODE_FOR_spe_evmhegsmfaa, "__builtin_spe_evmhegsmfaa", SPE_BUILTIN_EVMHEGSMFAA },
8863 { 0, CODE_FOR_spe_evmhegsmfan, "__builtin_spe_evmhegsmfan", SPE_BUILTIN_EVMHEGSMFAN },
8864 { 0, CODE_FOR_spe_evmhegsmiaa, "__builtin_spe_evmhegsmiaa", SPE_BUILTIN_EVMHEGSMIAA },
8865 { 0, CODE_FOR_spe_evmhegsmian, "__builtin_spe_evmhegsmian", SPE_BUILTIN_EVMHEGSMIAN },
8866 { 0, CODE_FOR_spe_evmhegumiaa, "__builtin_spe_evmhegumiaa", SPE_BUILTIN_EVMHEGUMIAA },
8867 { 0, CODE_FOR_spe_evmhegumian, "__builtin_spe_evmhegumian", SPE_BUILTIN_EVMHEGUMIAN },
8868 { 0, CODE_FOR_spe_evmhesmf, "__builtin_spe_evmhesmf", SPE_BUILTIN_EVMHESMF },
8869 { 0, CODE_FOR_spe_evmhesmfa, "__builtin_spe_evmhesmfa", SPE_BUILTIN_EVMHESMFA },
8870 { 0, CODE_FOR_spe_evmhesmfaaw, "__builtin_spe_evmhesmfaaw", SPE_BUILTIN_EVMHESMFAAW },
8871 { 0, CODE_FOR_spe_evmhesmfanw, "__builtin_spe_evmhesmfanw", SPE_BUILTIN_EVMHESMFANW },
8872 { 0, CODE_FOR_spe_evmhesmi, "__builtin_spe_evmhesmi", SPE_BUILTIN_EVMHESMI },
8873 { 0, CODE_FOR_spe_evmhesmia, "__builtin_spe_evmhesmia", SPE_BUILTIN_EVMHESMIA },
8874 { 0, CODE_FOR_spe_evmhesmiaaw, "__builtin_spe_evmhesmiaaw", SPE_BUILTIN_EVMHESMIAAW },
8875 { 0, CODE_FOR_spe_evmhesmianw, "__builtin_spe_evmhesmianw", SPE_BUILTIN_EVMHESMIANW },
8876 { 0, CODE_FOR_spe_evmhessf, "__builtin_spe_evmhessf", SPE_BUILTIN_EVMHESSF },
8877 { 0, CODE_FOR_spe_evmhessfa, "__builtin_spe_evmhessfa", SPE_BUILTIN_EVMHESSFA },
8878 { 0, CODE_FOR_spe_evmhessfaaw, "__builtin_spe_evmhessfaaw", SPE_BUILTIN_EVMHESSFAAW },
8879 { 0, CODE_FOR_spe_evmhessfanw, "__builtin_spe_evmhessfanw", SPE_BUILTIN_EVMHESSFANW },
8880 { 0, CODE_FOR_spe_evmhessiaaw, "__builtin_spe_evmhessiaaw", SPE_BUILTIN_EVMHESSIAAW },
8881 { 0, CODE_FOR_spe_evmhessianw, "__builtin_spe_evmhessianw", SPE_BUILTIN_EVMHESSIANW },
8882 { 0, CODE_FOR_spe_evmheumi, "__builtin_spe_evmheumi", SPE_BUILTIN_EVMHEUMI },
8883 { 0, CODE_FOR_spe_evmheumia, "__builtin_spe_evmheumia", SPE_BUILTIN_EVMHEUMIA },
8884 { 0, CODE_FOR_spe_evmheumiaaw, "__builtin_spe_evmheumiaaw", SPE_BUILTIN_EVMHEUMIAAW },
8885 { 0, CODE_FOR_spe_evmheumianw, "__builtin_spe_evmheumianw", SPE_BUILTIN_EVMHEUMIANW },
8886 { 0, CODE_FOR_spe_evmheusiaaw, "__builtin_spe_evmheusiaaw", SPE_BUILTIN_EVMHEUSIAAW },
8887 { 0, CODE_FOR_spe_evmheusianw, "__builtin_spe_evmheusianw", SPE_BUILTIN_EVMHEUSIANW },
8888 { 0, CODE_FOR_spe_evmhogsmfaa, "__builtin_spe_evmhogsmfaa", SPE_BUILTIN_EVMHOGSMFAA },
8889 { 0, CODE_FOR_spe_evmhogsmfan, "__builtin_spe_evmhogsmfan", SPE_BUILTIN_EVMHOGSMFAN },
8890 { 0, CODE_FOR_spe_evmhogsmiaa, "__builtin_spe_evmhogsmiaa", SPE_BUILTIN_EVMHOGSMIAA },
8891 { 0, CODE_FOR_spe_evmhogsmian, "__builtin_spe_evmhogsmian", SPE_BUILTIN_EVMHOGSMIAN },
8892 { 0, CODE_FOR_spe_evmhogumiaa, "__builtin_spe_evmhogumiaa", SPE_BUILTIN_EVMHOGUMIAA },
8893 { 0, CODE_FOR_spe_evmhogumian, "__builtin_spe_evmhogumian", SPE_BUILTIN_EVMHOGUMIAN },
8894 { 0, CODE_FOR_spe_evmhosmf, "__builtin_spe_evmhosmf", SPE_BUILTIN_EVMHOSMF },
8895 { 0, CODE_FOR_spe_evmhosmfa, "__builtin_spe_evmhosmfa", SPE_BUILTIN_EVMHOSMFA },
8896 { 0, CODE_FOR_spe_evmhosmfaaw, "__builtin_spe_evmhosmfaaw", SPE_BUILTIN_EVMHOSMFAAW },
8897 { 0, CODE_FOR_spe_evmhosmfanw, "__builtin_spe_evmhosmfanw", SPE_BUILTIN_EVMHOSMFANW },
8898 { 0, CODE_FOR_spe_evmhosmi, "__builtin_spe_evmhosmi", SPE_BUILTIN_EVMHOSMI },
8899 { 0, CODE_FOR_spe_evmhosmia, "__builtin_spe_evmhosmia", SPE_BUILTIN_EVMHOSMIA },
8900 { 0, CODE_FOR_spe_evmhosmiaaw, "__builtin_spe_evmhosmiaaw", SPE_BUILTIN_EVMHOSMIAAW },
8901 { 0, CODE_FOR_spe_evmhosmianw, "__builtin_spe_evmhosmianw", SPE_BUILTIN_EVMHOSMIANW },
8902 { 0, CODE_FOR_spe_evmhossf, "__builtin_spe_evmhossf", SPE_BUILTIN_EVMHOSSF },
8903 { 0, CODE_FOR_spe_evmhossfa, "__builtin_spe_evmhossfa", SPE_BUILTIN_EVMHOSSFA },
8904 { 0, CODE_FOR_spe_evmhossfaaw, "__builtin_spe_evmhossfaaw", SPE_BUILTIN_EVMHOSSFAAW },
8905 { 0, CODE_FOR_spe_evmhossfanw, "__builtin_spe_evmhossfanw", SPE_BUILTIN_EVMHOSSFANW },
8906 { 0, CODE_FOR_spe_evmhossiaaw, "__builtin_spe_evmhossiaaw", SPE_BUILTIN_EVMHOSSIAAW },
8907 { 0, CODE_FOR_spe_evmhossianw, "__builtin_spe_evmhossianw", SPE_BUILTIN_EVMHOSSIANW },
8908 { 0, CODE_FOR_spe_evmhoumi, "__builtin_spe_evmhoumi", SPE_BUILTIN_EVMHOUMI },
8909 { 0, CODE_FOR_spe_evmhoumia, "__builtin_spe_evmhoumia", SPE_BUILTIN_EVMHOUMIA },
8910 { 0, CODE_FOR_spe_evmhoumiaaw, "__builtin_spe_evmhoumiaaw", SPE_BUILTIN_EVMHOUMIAAW },
8911 { 0, CODE_FOR_spe_evmhoumianw, "__builtin_spe_evmhoumianw", SPE_BUILTIN_EVMHOUMIANW },
8912 { 0, CODE_FOR_spe_evmhousiaaw, "__builtin_spe_evmhousiaaw", SPE_BUILTIN_EVMHOUSIAAW },
8913 { 0, CODE_FOR_spe_evmhousianw, "__builtin_spe_evmhousianw", SPE_BUILTIN_EVMHOUSIANW },
8914 { 0, CODE_FOR_spe_evmwhsmf, "__builtin_spe_evmwhsmf", SPE_BUILTIN_EVMWHSMF },
8915 { 0, CODE_FOR_spe_evmwhsmfa, "__builtin_spe_evmwhsmfa", SPE_BUILTIN_EVMWHSMFA },
8916 { 0, CODE_FOR_spe_evmwhsmi, "__builtin_spe_evmwhsmi", SPE_BUILTIN_EVMWHSMI },
8917 { 0, CODE_FOR_spe_evmwhsmia, "__builtin_spe_evmwhsmia", SPE_BUILTIN_EVMWHSMIA },
8918 { 0, CODE_FOR_spe_evmwhssf, "__builtin_spe_evmwhssf", SPE_BUILTIN_EVMWHSSF },
8919 { 0, CODE_FOR_spe_evmwhssfa, "__builtin_spe_evmwhssfa", SPE_BUILTIN_EVMWHSSFA },
8920 { 0, CODE_FOR_spe_evmwhumi, "__builtin_spe_evmwhumi", SPE_BUILTIN_EVMWHUMI },
8921 { 0, CODE_FOR_spe_evmwhumia, "__builtin_spe_evmwhumia", SPE_BUILTIN_EVMWHUMIA },
8922 { 0, CODE_FOR_spe_evmwlsmiaaw, "__builtin_spe_evmwlsmiaaw", SPE_BUILTIN_EVMWLSMIAAW },
8923 { 0, CODE_FOR_spe_evmwlsmianw, "__builtin_spe_evmwlsmianw", SPE_BUILTIN_EVMWLSMIANW },
8924 { 0, CODE_FOR_spe_evmwlssiaaw, "__builtin_spe_evmwlssiaaw", SPE_BUILTIN_EVMWLSSIAAW },
8925 { 0, CODE_FOR_spe_evmwlssianw, "__builtin_spe_evmwlssianw", SPE_BUILTIN_EVMWLSSIANW },
8926 { 0, CODE_FOR_spe_evmwlumi, "__builtin_spe_evmwlumi", SPE_BUILTIN_EVMWLUMI },
8927 { 0, CODE_FOR_spe_evmwlumia, "__builtin_spe_evmwlumia", SPE_BUILTIN_EVMWLUMIA },
8928 { 0, CODE_FOR_spe_evmwlumiaaw, "__builtin_spe_evmwlumiaaw", SPE_BUILTIN_EVMWLUMIAAW },
8929 { 0, CODE_FOR_spe_evmwlumianw, "__builtin_spe_evmwlumianw", SPE_BUILTIN_EVMWLUMIANW },
8930 { 0, CODE_FOR_spe_evmwlusiaaw, "__builtin_spe_evmwlusiaaw", SPE_BUILTIN_EVMWLUSIAAW },
8931 { 0, CODE_FOR_spe_evmwlusianw, "__builtin_spe_evmwlusianw", SPE_BUILTIN_EVMWLUSIANW },
8932 { 0, CODE_FOR_spe_evmwsmf, "__builtin_spe_evmwsmf", SPE_BUILTIN_EVMWSMF },
8933 { 0, CODE_FOR_spe_evmwsmfa, "__builtin_spe_evmwsmfa", SPE_BUILTIN_EVMWSMFA },
8934 { 0, CODE_FOR_spe_evmwsmfaa, "__builtin_spe_evmwsmfaa", SPE_BUILTIN_EVMWSMFAA },
8935 { 0, CODE_FOR_spe_evmwsmfan, "__builtin_spe_evmwsmfan", SPE_BUILTIN_EVMWSMFAN },
8936 { 0, CODE_FOR_spe_evmwsmi, "__builtin_spe_evmwsmi", SPE_BUILTIN_EVMWSMI },
8937 { 0, CODE_FOR_spe_evmwsmia, "__builtin_spe_evmwsmia", SPE_BUILTIN_EVMWSMIA },
8938 { 0, CODE_FOR_spe_evmwsmiaa, "__builtin_spe_evmwsmiaa", SPE_BUILTIN_EVMWSMIAA },
8939 { 0, CODE_FOR_spe_evmwsmian, "__builtin_spe_evmwsmian", SPE_BUILTIN_EVMWSMIAN },
8940 { 0, CODE_FOR_spe_evmwssf, "__builtin_spe_evmwssf", SPE_BUILTIN_EVMWSSF },
8941 { 0, CODE_FOR_spe_evmwssfa, "__builtin_spe_evmwssfa", SPE_BUILTIN_EVMWSSFA },
8942 { 0, CODE_FOR_spe_evmwssfaa, "__builtin_spe_evmwssfaa", SPE_BUILTIN_EVMWSSFAA },
8943 { 0, CODE_FOR_spe_evmwssfan, "__builtin_spe_evmwssfan", SPE_BUILTIN_EVMWSSFAN },
8944 { 0, CODE_FOR_spe_evmwumi, "__builtin_spe_evmwumi", SPE_BUILTIN_EVMWUMI },
8945 { 0, CODE_FOR_spe_evmwumia, "__builtin_spe_evmwumia", SPE_BUILTIN_EVMWUMIA },
8946 { 0, CODE_FOR_spe_evmwumiaa, "__builtin_spe_evmwumiaa", SPE_BUILTIN_EVMWUMIAA },
8947 { 0, CODE_FOR_spe_evmwumian, "__builtin_spe_evmwumian", SPE_BUILTIN_EVMWUMIAN },
8948 { 0, CODE_FOR_spe_evnand, "__builtin_spe_evnand", SPE_BUILTIN_EVNAND },
8949 { 0, CODE_FOR_spe_evnor, "__builtin_spe_evnor", SPE_BUILTIN_EVNOR },
8950 { 0, CODE_FOR_spe_evor, "__builtin_spe_evor", SPE_BUILTIN_EVOR },
8951 { 0, CODE_FOR_spe_evorc, "__builtin_spe_evorc", SPE_BUILTIN_EVORC },
8952 { 0, CODE_FOR_spe_evrlw, "__builtin_spe_evrlw", SPE_BUILTIN_EVRLW },
8953 { 0, CODE_FOR_spe_evslw, "__builtin_spe_evslw", SPE_BUILTIN_EVSLW },
8954 { 0, CODE_FOR_spe_evsrws, "__builtin_spe_evsrws", SPE_BUILTIN_EVSRWS },
8955 { 0, CODE_FOR_spe_evsrwu, "__builtin_spe_evsrwu", SPE_BUILTIN_EVSRWU },
8956 { 0, CODE_FOR_spe_evsubfw, "__builtin_spe_evsubfw", SPE_BUILTIN_EVSUBFW },
8958 /* SPE binary operations expecting a 5-bit unsigned literal. */
8959 { 0, CODE_FOR_spe_evaddiw, "__builtin_spe_evaddiw", SPE_BUILTIN_EVADDIW },
8961 { 0, CODE_FOR_spe_evrlwi, "__builtin_spe_evrlwi", SPE_BUILTIN_EVRLWI },
8962 { 0, CODE_FOR_spe_evslwi, "__builtin_spe_evslwi", SPE_BUILTIN_EVSLWI },
8963 { 0, CODE_FOR_spe_evsrwis, "__builtin_spe_evsrwis", SPE_BUILTIN_EVSRWIS },
8964 { 0, CODE_FOR_spe_evsrwiu, "__builtin_spe_evsrwiu", SPE_BUILTIN_EVSRWIU },
8965 { 0, CODE_FOR_spe_evsubifw, "__builtin_spe_evsubifw", SPE_BUILTIN_EVSUBIFW },
8966 { 0, CODE_FOR_spe_evmwhssfaa, "__builtin_spe_evmwhssfaa", SPE_BUILTIN_EVMWHSSFAA },
8967 { 0, CODE_FOR_spe_evmwhssmaa, "__builtin_spe_evmwhssmaa", SPE_BUILTIN_EVMWHSSMAA },
8968 { 0, CODE_FOR_spe_evmwhsmfaa, "__builtin_spe_evmwhsmfaa", SPE_BUILTIN_EVMWHSMFAA },
8969 { 0, CODE_FOR_spe_evmwhsmiaa, "__builtin_spe_evmwhsmiaa", SPE_BUILTIN_EVMWHSMIAA },
8970 { 0, CODE_FOR_spe_evmwhusiaa, "__builtin_spe_evmwhusiaa", SPE_BUILTIN_EVMWHUSIAA },
8971 { 0, CODE_FOR_spe_evmwhumiaa, "__builtin_spe_evmwhumiaa", SPE_BUILTIN_EVMWHUMIAA },
8972 { 0, CODE_FOR_spe_evmwhssfan, "__builtin_spe_evmwhssfan", SPE_BUILTIN_EVMWHSSFAN },
8973 { 0, CODE_FOR_spe_evmwhssian, "__builtin_spe_evmwhssian", SPE_BUILTIN_EVMWHSSIAN },
8974 { 0, CODE_FOR_spe_evmwhsmfan, "__builtin_spe_evmwhsmfan", SPE_BUILTIN_EVMWHSMFAN },
8975 { 0, CODE_FOR_spe_evmwhsmian, "__builtin_spe_evmwhsmian", SPE_BUILTIN_EVMWHSMIAN },
8976 { 0, CODE_FOR_spe_evmwhusian, "__builtin_spe_evmwhusian", SPE_BUILTIN_EVMWHUSIAN },
8977 { 0, CODE_FOR_spe_evmwhumian, "__builtin_spe_evmwhumian", SPE_BUILTIN_EVMWHUMIAN },
8978 { 0, CODE_FOR_spe_evmwhgssfaa, "__builtin_spe_evmwhgssfaa", SPE_BUILTIN_EVMWHGSSFAA },
8979 { 0, CODE_FOR_spe_evmwhgsmfaa, "__builtin_spe_evmwhgsmfaa", SPE_BUILTIN_EVMWHGSMFAA },
8980 { 0, CODE_FOR_spe_evmwhgsmiaa, "__builtin_spe_evmwhgsmiaa", SPE_BUILTIN_EVMWHGSMIAA },
8981 { 0, CODE_FOR_spe_evmwhgumiaa, "__builtin_spe_evmwhgumiaa", SPE_BUILTIN_EVMWHGUMIAA },
8982 { 0, CODE_FOR_spe_evmwhgssfan, "__builtin_spe_evmwhgssfan", SPE_BUILTIN_EVMWHGSSFAN },
8983 { 0, CODE_FOR_spe_evmwhgsmfan, "__builtin_spe_evmwhgsmfan", SPE_BUILTIN_EVMWHGSMFAN },
8984 { 0, CODE_FOR_spe_evmwhgsmian, "__builtin_spe_evmwhgsmian", SPE_BUILTIN_EVMWHGSMIAN },
8985 { 0, CODE_FOR_spe_evmwhgumian, "__builtin_spe_evmwhgumian", SPE_BUILTIN_EVMWHGUMIAN },
8986 { 0, CODE_FOR_spe_brinc, "__builtin_spe_brinc", SPE_BUILTIN_BRINC },
8988 /* Place-holder. Leave as last binary SPE builtin. */
8989 { 0, CODE_FOR_xorv2si3, "__builtin_spe_evxor", SPE_BUILTIN_EVXOR }
8992 /* AltiVec predicates. */
8994 struct builtin_description_predicates
8996 const unsigned int mask;
8997 const enum insn_code icode;
8998 const char *const name;
8999 const enum rs6000_builtins code;
9002 static const struct builtin_description_predicates bdesc_altivec_preds[] =
9004 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpbfp_p, "__builtin_altivec_vcmpbfp_p",
9005 ALTIVEC_BUILTIN_VCMPBFP_P },
9006 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_eq_v4sf_p,
9007 "__builtin_altivec_vcmpeqfp_p", ALTIVEC_BUILTIN_VCMPEQFP_P },
9008 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_ge_v4sf_p,
9009 "__builtin_altivec_vcmpgefp_p", ALTIVEC_BUILTIN_VCMPGEFP_P },
9010 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_gt_v4sf_p,
9011 "__builtin_altivec_vcmpgtfp_p", ALTIVEC_BUILTIN_VCMPGTFP_P },
9012 { MASK_ALTIVEC, CODE_FOR_vector_eq_v4si_p, "__builtin_altivec_vcmpequw_p",
9013 ALTIVEC_BUILTIN_VCMPEQUW_P },
9014 { MASK_ALTIVEC, CODE_FOR_vector_gt_v4si_p, "__builtin_altivec_vcmpgtsw_p",
9015 ALTIVEC_BUILTIN_VCMPGTSW_P },
9016 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v4si_p, "__builtin_altivec_vcmpgtuw_p",
9017 ALTIVEC_BUILTIN_VCMPGTUW_P },
9018 { MASK_ALTIVEC, CODE_FOR_vector_eq_v8hi_p, "__builtin_altivec_vcmpequh_p",
9019 ALTIVEC_BUILTIN_VCMPEQUH_P },
9020 { MASK_ALTIVEC, CODE_FOR_vector_gt_v8hi_p, "__builtin_altivec_vcmpgtsh_p",
9021 ALTIVEC_BUILTIN_VCMPGTSH_P },
9022 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v8hi_p, "__builtin_altivec_vcmpgtuh_p",
9023 ALTIVEC_BUILTIN_VCMPGTUH_P },
9024 { MASK_ALTIVEC, CODE_FOR_vector_eq_v16qi_p, "__builtin_altivec_vcmpequb_p",
9025 ALTIVEC_BUILTIN_VCMPEQUB_P },
9026 { MASK_ALTIVEC, CODE_FOR_vector_gt_v16qi_p, "__builtin_altivec_vcmpgtsb_p",
9027 ALTIVEC_BUILTIN_VCMPGTSB_P },
9028 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v16qi_p, "__builtin_altivec_vcmpgtub_p",
9029 ALTIVEC_BUILTIN_VCMPGTUB_P },
9031 { MASK_VSX, CODE_FOR_vector_eq_v4sf_p, "__builtin_vsx_xvcmpeqsp_p",
9032 VSX_BUILTIN_XVCMPEQSP_P },
9033 { MASK_VSX, CODE_FOR_vector_ge_v4sf_p, "__builtin_vsx_xvcmpgesp_p",
9034 VSX_BUILTIN_XVCMPGESP_P },
9035 { MASK_VSX, CODE_FOR_vector_gt_v4sf_p, "__builtin_vsx_xvcmpgtsp_p",
9036 VSX_BUILTIN_XVCMPGTSP_P },
9037 { MASK_VSX, CODE_FOR_vector_eq_v2df_p, "__builtin_vsx_xvcmpeqdp_p",
9038 VSX_BUILTIN_XVCMPEQDP_P },
9039 { MASK_VSX, CODE_FOR_vector_ge_v2df_p, "__builtin_vsx_xvcmpgedp_p",
9040 VSX_BUILTIN_XVCMPGEDP_P },
9041 { MASK_VSX, CODE_FOR_vector_gt_v2df_p, "__builtin_vsx_xvcmpgtdp_p",
9042 VSX_BUILTIN_XVCMPGTDP_P },
9044 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpeq_p",
9045 ALTIVEC_BUILTIN_VCMPEQ_P },
9046 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpgt_p",
9047 ALTIVEC_BUILTIN_VCMPGT_P },
9048 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpge_p",
9049 ALTIVEC_BUILTIN_VCMPGE_P }
9052 /* SPE predicates. */
9053 static struct builtin_description bdesc_spe_predicates[] =
9055 /* Place-holder. Leave as first. */
9056 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evcmpeq", SPE_BUILTIN_EVCMPEQ },
9057 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evcmpgts", SPE_BUILTIN_EVCMPGTS },
9058 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evcmpgtu", SPE_BUILTIN_EVCMPGTU },
9059 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evcmplts", SPE_BUILTIN_EVCMPLTS },
9060 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evcmpltu", SPE_BUILTIN_EVCMPLTU },
9061 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evfscmpeq", SPE_BUILTIN_EVFSCMPEQ },
9062 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evfscmpgt", SPE_BUILTIN_EVFSCMPGT },
9063 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evfscmplt", SPE_BUILTIN_EVFSCMPLT },
9064 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evfststeq", SPE_BUILTIN_EVFSTSTEQ },
9065 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evfststgt", SPE_BUILTIN_EVFSTSTGT },
9066 /* Place-holder. Leave as last. */
9067 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evfststlt", SPE_BUILTIN_EVFSTSTLT },
9070 /* SPE evsel predicates. */
9071 static struct builtin_description bdesc_spe_evsel[] =
9073 /* Place-holder. Leave as first. */
9074 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evsel_gts", SPE_BUILTIN_EVSEL_CMPGTS },
9075 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evsel_gtu", SPE_BUILTIN_EVSEL_CMPGTU },
9076 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evsel_lts", SPE_BUILTIN_EVSEL_CMPLTS },
9077 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evsel_ltu", SPE_BUILTIN_EVSEL_CMPLTU },
9078 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evsel_eq", SPE_BUILTIN_EVSEL_CMPEQ },
9079 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evsel_fsgt", SPE_BUILTIN_EVSEL_FSCMPGT },
9080 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evsel_fslt", SPE_BUILTIN_EVSEL_FSCMPLT },
9081 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evsel_fseq", SPE_BUILTIN_EVSEL_FSCMPEQ },
9082 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evsel_fststgt", SPE_BUILTIN_EVSEL_FSTSTGT },
9083 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evsel_fststlt", SPE_BUILTIN_EVSEL_FSTSTLT },
9084 /* Place-holder. Leave as last. */
9085 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evsel_fststeq", SPE_BUILTIN_EVSEL_FSTSTEQ },
9088 /* PAIRED predicates. */
9089 static const struct builtin_description bdesc_paired_preds[] =
9091 /* Place-holder. Leave as first. */
9092 { 0, CODE_FOR_paired_cmpu0, "__builtin_paired_cmpu0", PAIRED_BUILTIN_CMPU0 },
9093 /* Place-holder. Leave as last. */
9094 { 0, CODE_FOR_paired_cmpu1, "__builtin_paired_cmpu1", PAIRED_BUILTIN_CMPU1 },
9097 /* ABS* operations. */
9099 static const struct builtin_description bdesc_abs[] =
9101 { MASK_ALTIVEC, CODE_FOR_absv4si2, "__builtin_altivec_abs_v4si", ALTIVEC_BUILTIN_ABS_V4SI },
9102 { MASK_ALTIVEC, CODE_FOR_absv8hi2, "__builtin_altivec_abs_v8hi", ALTIVEC_BUILTIN_ABS_V8HI },
9103 { MASK_ALTIVEC, CODE_FOR_absv4sf2, "__builtin_altivec_abs_v4sf", ALTIVEC_BUILTIN_ABS_V4SF },
9104 { MASK_ALTIVEC, CODE_FOR_absv16qi2, "__builtin_altivec_abs_v16qi", ALTIVEC_BUILTIN_ABS_V16QI },
9105 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v4si, "__builtin_altivec_abss_v4si", ALTIVEC_BUILTIN_ABSS_V4SI },
9106 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v8hi, "__builtin_altivec_abss_v8hi", ALTIVEC_BUILTIN_ABSS_V8HI },
9107 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v16qi, "__builtin_altivec_abss_v16qi", ALTIVEC_BUILTIN_ABSS_V16QI },
9108 { MASK_VSX, CODE_FOR_absv2df2, "__builtin_vsx_xvabsdp", VSX_BUILTIN_XVABSDP },
9109 { MASK_VSX, CODE_FOR_vsx_nabsv2df2, "__builtin_vsx_xvnabsdp", VSX_BUILTIN_XVNABSDP },
9110 { MASK_VSX, CODE_FOR_absv4sf2, "__builtin_vsx_xvabssp", VSX_BUILTIN_XVABSSP },
9111 { MASK_VSX, CODE_FOR_vsx_nabsv4sf2, "__builtin_vsx_xvnabssp", VSX_BUILTIN_XVNABSSP },
9114 /* Simple unary operations: VECb = foo (unsigned literal) or VECb =
9115 foo (VECa). */
9117 static struct builtin_description bdesc_1arg[] =
9119 { MASK_ALTIVEC, CODE_FOR_altivec_vexptefp, "__builtin_altivec_vexptefp", ALTIVEC_BUILTIN_VEXPTEFP },
9120 { MASK_ALTIVEC, CODE_FOR_altivec_vlogefp, "__builtin_altivec_vlogefp", ALTIVEC_BUILTIN_VLOGEFP },
9121 { MASK_ALTIVEC, CODE_FOR_altivec_vrefp, "__builtin_altivec_vrefp", ALTIVEC_BUILTIN_VREFP },
9122 { MASK_ALTIVEC, CODE_FOR_vector_floorv4sf2, "__builtin_altivec_vrfim", ALTIVEC_BUILTIN_VRFIM },
9123 { MASK_ALTIVEC, CODE_FOR_altivec_vrfin, "__builtin_altivec_vrfin", ALTIVEC_BUILTIN_VRFIN },
9124 { MASK_ALTIVEC, CODE_FOR_vector_ceilv4sf2, "__builtin_altivec_vrfip", ALTIVEC_BUILTIN_VRFIP },
9125 { MASK_ALTIVEC, CODE_FOR_vector_btruncv4sf2, "__builtin_altivec_vrfiz", ALTIVEC_BUILTIN_VRFIZ },
9126 { MASK_ALTIVEC, CODE_FOR_altivec_vrsqrtefp, "__builtin_altivec_vrsqrtefp", ALTIVEC_BUILTIN_VRSQRTEFP },
9127 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisb, "__builtin_altivec_vspltisb", ALTIVEC_BUILTIN_VSPLTISB },
9128 { MASK_ALTIVEC, CODE_FOR_altivec_vspltish, "__builtin_altivec_vspltish", ALTIVEC_BUILTIN_VSPLTISH },
9129 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisw, "__builtin_altivec_vspltisw", ALTIVEC_BUILTIN_VSPLTISW },
9130 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsb, "__builtin_altivec_vupkhsb", ALTIVEC_BUILTIN_VUPKHSB },
9131 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhpx, "__builtin_altivec_vupkhpx", ALTIVEC_BUILTIN_VUPKHPX },
9132 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsh, "__builtin_altivec_vupkhsh", ALTIVEC_BUILTIN_VUPKHSH },
9133 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsb, "__builtin_altivec_vupklsb", ALTIVEC_BUILTIN_VUPKLSB },
9134 { MASK_ALTIVEC, CODE_FOR_altivec_vupklpx, "__builtin_altivec_vupklpx", ALTIVEC_BUILTIN_VUPKLPX },
9135 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsh, "__builtin_altivec_vupklsh", ALTIVEC_BUILTIN_VUPKLSH },
9137 { MASK_VSX, CODE_FOR_negv2df2, "__builtin_vsx_xvnegdp", VSX_BUILTIN_XVNEGDP },
9138 { MASK_VSX, CODE_FOR_sqrtv2df2, "__builtin_vsx_xvsqrtdp", VSX_BUILTIN_XVSQRTDP },
9139 { MASK_VSX, CODE_FOR_vsx_rsqrtev2df2, "__builtin_vsx_xvrsqrtedp", VSX_BUILTIN_XVRSQRTEDP },
9140 { MASK_VSX, CODE_FOR_vsx_tsqrtv2df2_fe, "__builtin_vsx_xvtsqrtdp_fe", VSX_BUILTIN_XVTSQRTDP_FE },
9141 { MASK_VSX, CODE_FOR_vsx_tsqrtv2df2_fg, "__builtin_vsx_xvtsqrtdp_fg", VSX_BUILTIN_XVTSQRTDP_FG },
9142 { MASK_VSX, CODE_FOR_vsx_frev2df2, "__builtin_vsx_xvredp", VSX_BUILTIN_XVREDP },
9144 { MASK_VSX, CODE_FOR_negv4sf2, "__builtin_vsx_xvnegsp", VSX_BUILTIN_XVNEGSP },
9145 { MASK_VSX, CODE_FOR_sqrtv4sf2, "__builtin_vsx_xvsqrtsp", VSX_BUILTIN_XVSQRTSP },
9146 { MASK_VSX, CODE_FOR_vsx_rsqrtev4sf2, "__builtin_vsx_xvrsqrtesp", VSX_BUILTIN_XVRSQRTESP },
9147 { MASK_VSX, CODE_FOR_vsx_tsqrtv4sf2_fe, "__builtin_vsx_xvtsqrtsp_fe", VSX_BUILTIN_XVTSQRTSP_FE },
9148 { MASK_VSX, CODE_FOR_vsx_tsqrtv4sf2_fg, "__builtin_vsx_xvtsqrtsp_fg", VSX_BUILTIN_XVTSQRTSP_FG },
9149 { MASK_VSX, CODE_FOR_vsx_frev4sf2, "__builtin_vsx_xvresp", VSX_BUILTIN_XVRESP },
9151 { MASK_VSX, CODE_FOR_vsx_xscvdpsp, "__builtin_vsx_xscvdpsp", VSX_BUILTIN_XSCVDPSP },
9152 { MASK_VSX, CODE_FOR_vsx_xscvdpsp, "__builtin_vsx_xscvspdp", VSX_BUILTIN_XSCVSPDP },
9153 { MASK_VSX, CODE_FOR_vsx_xvcvdpsp, "__builtin_vsx_xvcvdpsp", VSX_BUILTIN_XVCVDPSP },
9154 { MASK_VSX, CODE_FOR_vsx_xvcvspdp, "__builtin_vsx_xvcvspdp", VSX_BUILTIN_XVCVSPDP },
9155 { MASK_VSX, CODE_FOR_vsx_tsqrtdf2_fe, "__builtin_vsx_xstsqrtdp_fe", VSX_BUILTIN_XSTSQRTDP_FE },
9156 { MASK_VSX, CODE_FOR_vsx_tsqrtdf2_fg, "__builtin_vsx_xstsqrtdp_fg", VSX_BUILTIN_XSTSQRTDP_FG },
9158 { MASK_VSX, CODE_FOR_vsx_fix_truncv2dfv2di2, "__builtin_vsx_xvcvdpsxds", VSX_BUILTIN_XVCVDPSXDS },
9159 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv2dfv2di2, "__builtin_vsx_xvcvdpuxds", VSX_BUILTIN_XVCVDPUXDS },
9160 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv2dfv2di2, "__builtin_vsx_xvcvdpuxds_uns", VSX_BUILTIN_XVCVDPUXDS_UNS },
9161 { MASK_VSX, CODE_FOR_vsx_floatv2div2df2, "__builtin_vsx_xvcvsxddp", VSX_BUILTIN_XVCVSXDDP },
9162 { MASK_VSX, CODE_FOR_vsx_floatunsv2div2df2, "__builtin_vsx_xvcvuxddp", VSX_BUILTIN_XVCVUXDDP },
9163 { MASK_VSX, CODE_FOR_vsx_floatunsv2div2df2, "__builtin_vsx_xvcvuxddp_uns", VSX_BUILTIN_XVCVUXDDP_UNS },
9165 { MASK_VSX, CODE_FOR_vsx_fix_truncv4sfv4si2, "__builtin_vsx_xvcvspsxws", VSX_BUILTIN_XVCVSPSXWS },
9166 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv4sfv4si2, "__builtin_vsx_xvcvspuxws", VSX_BUILTIN_XVCVSPUXWS },
9167 { MASK_VSX, CODE_FOR_vsx_floatv4siv4sf2, "__builtin_vsx_xvcvsxwsp", VSX_BUILTIN_XVCVSXWSP },
9168 { MASK_VSX, CODE_FOR_vsx_floatunsv4siv4sf2, "__builtin_vsx_xvcvuxwsp", VSX_BUILTIN_XVCVUXWSP },
9170 { MASK_VSX, CODE_FOR_vsx_xvcvdpsxws, "__builtin_vsx_xvcvdpsxws", VSX_BUILTIN_XVCVDPSXWS },
9171 { MASK_VSX, CODE_FOR_vsx_xvcvdpuxws, "__builtin_vsx_xvcvdpuxws", VSX_BUILTIN_XVCVDPUXWS },
9172 { MASK_VSX, CODE_FOR_vsx_xvcvsxwdp, "__builtin_vsx_xvcvsxwdp", VSX_BUILTIN_XVCVSXWDP },
9173 { MASK_VSX, CODE_FOR_vsx_xvcvuxwdp, "__builtin_vsx_xvcvuxwdp", VSX_BUILTIN_XVCVUXWDP },
9174 { MASK_VSX, CODE_FOR_vsx_xvrdpi, "__builtin_vsx_xvrdpi", VSX_BUILTIN_XVRDPI },
9175 { MASK_VSX, CODE_FOR_vsx_xvrdpic, "__builtin_vsx_xvrdpic", VSX_BUILTIN_XVRDPIC },
9176 { MASK_VSX, CODE_FOR_vsx_floorv2df2, "__builtin_vsx_xvrdpim", VSX_BUILTIN_XVRDPIM },
9177 { MASK_VSX, CODE_FOR_vsx_ceilv2df2, "__builtin_vsx_xvrdpip", VSX_BUILTIN_XVRDPIP },
9178 { MASK_VSX, CODE_FOR_vsx_btruncv2df2, "__builtin_vsx_xvrdpiz", VSX_BUILTIN_XVRDPIZ },
9180 { MASK_VSX, CODE_FOR_vsx_xvcvspsxds, "__builtin_vsx_xvcvspsxds", VSX_BUILTIN_XVCVSPSXDS },
9181 { MASK_VSX, CODE_FOR_vsx_xvcvspuxds, "__builtin_vsx_xvcvspuxds", VSX_BUILTIN_XVCVSPUXDS },
9182 { MASK_VSX, CODE_FOR_vsx_xvcvsxdsp, "__builtin_vsx_xvcvsxdsp", VSX_BUILTIN_XVCVSXDSP },
9183 { MASK_VSX, CODE_FOR_vsx_xvcvuxdsp, "__builtin_vsx_xvcvuxdsp", VSX_BUILTIN_XVCVUXDSP },
9184 { MASK_VSX, CODE_FOR_vsx_xvrspi, "__builtin_vsx_xvrspi", VSX_BUILTIN_XVRSPI },
9185 { MASK_VSX, CODE_FOR_vsx_xvrspic, "__builtin_vsx_xvrspic", VSX_BUILTIN_XVRSPIC },
9186 { MASK_VSX, CODE_FOR_vsx_floorv4sf2, "__builtin_vsx_xvrspim", VSX_BUILTIN_XVRSPIM },
9187 { MASK_VSX, CODE_FOR_vsx_ceilv4sf2, "__builtin_vsx_xvrspip", VSX_BUILTIN_XVRSPIP },
9188 { MASK_VSX, CODE_FOR_vsx_btruncv4sf2, "__builtin_vsx_xvrspiz", VSX_BUILTIN_XVRSPIZ },
9190 { MASK_VSX, CODE_FOR_vsx_xsrdpi, "__builtin_vsx_xsrdpi", VSX_BUILTIN_XSRDPI },
9191 { MASK_VSX, CODE_FOR_vsx_xsrdpic, "__builtin_vsx_xsrdpic", VSX_BUILTIN_XSRDPIC },
9192 { MASK_VSX, CODE_FOR_vsx_floordf2, "__builtin_vsx_xsrdpim", VSX_BUILTIN_XSRDPIM },
9193 { MASK_VSX, CODE_FOR_vsx_ceildf2, "__builtin_vsx_xsrdpip", VSX_BUILTIN_XSRDPIP },
9194 { MASK_VSX, CODE_FOR_vsx_btruncdf2, "__builtin_vsx_xsrdpiz", VSX_BUILTIN_XSRDPIZ },
9196 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abs", ALTIVEC_BUILTIN_VEC_ABS },
9197 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abss", ALTIVEC_BUILTIN_VEC_ABSS },
9198 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_ceil", ALTIVEC_BUILTIN_VEC_CEIL },
9199 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_expte", ALTIVEC_BUILTIN_VEC_EXPTE },
9200 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_floor", ALTIVEC_BUILTIN_VEC_FLOOR },
9201 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_loge", ALTIVEC_BUILTIN_VEC_LOGE },
9202 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mtvscr", ALTIVEC_BUILTIN_VEC_MTVSCR },
9203 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_re", ALTIVEC_BUILTIN_VEC_RE },
9204 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_round", ALTIVEC_BUILTIN_VEC_ROUND },
9205 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rsqrte", ALTIVEC_BUILTIN_VEC_RSQRTE },
9206 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_trunc", ALTIVEC_BUILTIN_VEC_TRUNC },
9207 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_unpackh", ALTIVEC_BUILTIN_VEC_UNPACKH },
9208 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhsh", ALTIVEC_BUILTIN_VEC_VUPKHSH },
9209 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhpx", ALTIVEC_BUILTIN_VEC_VUPKHPX },
9210 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhsb", ALTIVEC_BUILTIN_VEC_VUPKHSB },
9211 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_unpackl", ALTIVEC_BUILTIN_VEC_UNPACKL },
9212 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklpx", ALTIVEC_BUILTIN_VEC_VUPKLPX },
9213 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsh", ALTIVEC_BUILTIN_VEC_VUPKLSH },
9214 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsb", ALTIVEC_BUILTIN_VEC_VUPKLSB },
9216 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_nearbyint", ALTIVEC_BUILTIN_VEC_NEARBYINT },
9217 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_rint", ALTIVEC_BUILTIN_VEC_RINT },
9218 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_sqrt", ALTIVEC_BUILTIN_VEC_SQRT },
9220 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_floatv4siv4sf2, "__builtin_vec_float_sisf", VECTOR_BUILTIN_FLOAT_V4SI_V4SF },
9221 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_unsigned_floatv4siv4sf2, "__builtin_vec_uns_float_sisf", VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF },
9222 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_fix_truncv4sfv4si2, "__builtin_vec_fix_sfsi", VECTOR_BUILTIN_FIX_V4SF_V4SI },
9223 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_fixuns_truncv4sfv4si2, "__builtin_vec_fixuns_sfsi", VECTOR_BUILTIN_FIXUNS_V4SF_V4SI },
9225 /* The SPE unary builtins must start with SPE_BUILTIN_EVABS and
9226 end with SPE_BUILTIN_EVSUBFUSIAAW. */
9227 { 0, CODE_FOR_spe_evabs, "__builtin_spe_evabs", SPE_BUILTIN_EVABS },
9228 { 0, CODE_FOR_spe_evaddsmiaaw, "__builtin_spe_evaddsmiaaw", SPE_BUILTIN_EVADDSMIAAW },
9229 { 0, CODE_FOR_spe_evaddssiaaw, "__builtin_spe_evaddssiaaw", SPE_BUILTIN_EVADDSSIAAW },
9230 { 0, CODE_FOR_spe_evaddumiaaw, "__builtin_spe_evaddumiaaw", SPE_BUILTIN_EVADDUMIAAW },
9231 { 0, CODE_FOR_spe_evaddusiaaw, "__builtin_spe_evaddusiaaw", SPE_BUILTIN_EVADDUSIAAW },
9232 { 0, CODE_FOR_spe_evcntlsw, "__builtin_spe_evcntlsw", SPE_BUILTIN_EVCNTLSW },
9233 { 0, CODE_FOR_spe_evcntlzw, "__builtin_spe_evcntlzw", SPE_BUILTIN_EVCNTLZW },
9234 { 0, CODE_FOR_spe_evextsb, "__builtin_spe_evextsb", SPE_BUILTIN_EVEXTSB },
9235 { 0, CODE_FOR_spe_evextsh, "__builtin_spe_evextsh", SPE_BUILTIN_EVEXTSH },
9236 { 0, CODE_FOR_spe_evfsabs, "__builtin_spe_evfsabs", SPE_BUILTIN_EVFSABS },
9237 { 0, CODE_FOR_spe_evfscfsf, "__builtin_spe_evfscfsf", SPE_BUILTIN_EVFSCFSF },
9238 { 0, CODE_FOR_spe_evfscfsi, "__builtin_spe_evfscfsi", SPE_BUILTIN_EVFSCFSI },
9239 { 0, CODE_FOR_spe_evfscfuf, "__builtin_spe_evfscfuf", SPE_BUILTIN_EVFSCFUF },
9240 { 0, CODE_FOR_spe_evfscfui, "__builtin_spe_evfscfui", SPE_BUILTIN_EVFSCFUI },
9241 { 0, CODE_FOR_spe_evfsctsf, "__builtin_spe_evfsctsf", SPE_BUILTIN_EVFSCTSF },
9242 { 0, CODE_FOR_spe_evfsctsi, "__builtin_spe_evfsctsi", SPE_BUILTIN_EVFSCTSI },
9243 { 0, CODE_FOR_spe_evfsctsiz, "__builtin_spe_evfsctsiz", SPE_BUILTIN_EVFSCTSIZ },
9244 { 0, CODE_FOR_spe_evfsctuf, "__builtin_spe_evfsctuf", SPE_BUILTIN_EVFSCTUF },
9245 { 0, CODE_FOR_spe_evfsctui, "__builtin_spe_evfsctui", SPE_BUILTIN_EVFSCTUI },
9246 { 0, CODE_FOR_spe_evfsctuiz, "__builtin_spe_evfsctuiz", SPE_BUILTIN_EVFSCTUIZ },
9247 { 0, CODE_FOR_spe_evfsnabs, "__builtin_spe_evfsnabs", SPE_BUILTIN_EVFSNABS },
9248 { 0, CODE_FOR_spe_evfsneg, "__builtin_spe_evfsneg", SPE_BUILTIN_EVFSNEG },
9249 { 0, CODE_FOR_spe_evmra, "__builtin_spe_evmra", SPE_BUILTIN_EVMRA },
9250 { 0, CODE_FOR_negv2si2, "__builtin_spe_evneg", SPE_BUILTIN_EVNEG },
9251 { 0, CODE_FOR_spe_evrndw, "__builtin_spe_evrndw", SPE_BUILTIN_EVRNDW },
9252 { 0, CODE_FOR_spe_evsubfsmiaaw, "__builtin_spe_evsubfsmiaaw", SPE_BUILTIN_EVSUBFSMIAAW },
9253 { 0, CODE_FOR_spe_evsubfssiaaw, "__builtin_spe_evsubfssiaaw", SPE_BUILTIN_EVSUBFSSIAAW },
9254 { 0, CODE_FOR_spe_evsubfumiaaw, "__builtin_spe_evsubfumiaaw", SPE_BUILTIN_EVSUBFUMIAAW },
9256 /* Place-holder. Leave as last unary SPE builtin. */
9257 { 0, CODE_FOR_spe_evsubfusiaaw, "__builtin_spe_evsubfusiaaw", SPE_BUILTIN_EVSUBFUSIAAW },
9259 { 0, CODE_FOR_absv2sf2, "__builtin_paired_absv2sf2", PAIRED_BUILTIN_ABSV2SF2 },
9260 { 0, CODE_FOR_nabsv2sf2, "__builtin_paired_nabsv2sf2", PAIRED_BUILTIN_NABSV2SF2 },
9261 { 0, CODE_FOR_negv2sf2, "__builtin_paired_negv2sf2", PAIRED_BUILTIN_NEGV2SF2 },
9262 { 0, CODE_FOR_sqrtv2sf2, "__builtin_paired_sqrtv2sf2", PAIRED_BUILTIN_SQRTV2SF2 },
9263 { 0, CODE_FOR_resv2sf2, "__builtin_paired_resv2sf2", PAIRED_BUILTIN_RESV2SF2 }
9266 static rtx
9267 rs6000_expand_unop_builtin (enum insn_code icode, tree exp, rtx target)
9269 rtx pat;
9270 tree arg0 = CALL_EXPR_ARG (exp, 0);
9271 rtx op0 = expand_normal (arg0);
9272 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9273 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
9275 if (icode == CODE_FOR_nothing)
9276 /* Builtin not supported on this processor. */
9277 return 0;
9279 /* If we got invalid arguments bail out before generating bad rtl. */
9280 if (arg0 == error_mark_node)
9281 return const0_rtx;
9283 if (icode == CODE_FOR_altivec_vspltisb
9284 || icode == CODE_FOR_altivec_vspltish
9285 || icode == CODE_FOR_altivec_vspltisw
9286 || icode == CODE_FOR_spe_evsplatfi
9287 || icode == CODE_FOR_spe_evsplati)
9289 /* Only allow 5-bit *signed* literals. */
9290 if (GET_CODE (op0) != CONST_INT
9291 || INTVAL (op0) > 15
9292 || INTVAL (op0) < -16)
9294 error ("argument 1 must be a 5-bit signed literal");
9295 return const0_rtx;
9299 if (target == 0
9300 || GET_MODE (target) != tmode
9301 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
9302 target = gen_reg_rtx (tmode);
9304 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
9305 op0 = copy_to_mode_reg (mode0, op0);
9307 pat = GEN_FCN (icode) (target, op0);
9308 if (! pat)
9309 return 0;
9310 emit_insn (pat);
9312 return target;
9315 static rtx
9316 altivec_expand_abs_builtin (enum insn_code icode, tree exp, rtx target)
9318 rtx pat, scratch1, scratch2;
9319 tree arg0 = CALL_EXPR_ARG (exp, 0);
9320 rtx op0 = expand_normal (arg0);
9321 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9322 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
9324 /* If we have invalid arguments, bail out before generating bad rtl. */
9325 if (arg0 == error_mark_node)
9326 return const0_rtx;
9328 if (target == 0
9329 || GET_MODE (target) != tmode
9330 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
9331 target = gen_reg_rtx (tmode);
9333 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
9334 op0 = copy_to_mode_reg (mode0, op0);
9336 scratch1 = gen_reg_rtx (mode0);
9337 scratch2 = gen_reg_rtx (mode0);
9339 pat = GEN_FCN (icode) (target, op0, scratch1, scratch2);
9340 if (! pat)
9341 return 0;
9342 emit_insn (pat);
9344 return target;
9347 static rtx
9348 rs6000_expand_binop_builtin (enum insn_code icode, tree exp, rtx target)
9350 rtx pat;
9351 tree arg0 = CALL_EXPR_ARG (exp, 0);
9352 tree arg1 = CALL_EXPR_ARG (exp, 1);
9353 rtx op0 = expand_normal (arg0);
9354 rtx op1 = expand_normal (arg1);
9355 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9356 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
9357 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
9359 if (icode == CODE_FOR_nothing)
9360 /* Builtin not supported on this processor. */
9361 return 0;
9363 /* If we got invalid arguments bail out before generating bad rtl. */
9364 if (arg0 == error_mark_node || arg1 == error_mark_node)
9365 return const0_rtx;
9367 if (icode == CODE_FOR_altivec_vcfux
9368 || icode == CODE_FOR_altivec_vcfsx
9369 || icode == CODE_FOR_altivec_vctsxs
9370 || icode == CODE_FOR_altivec_vctuxs
9371 || icode == CODE_FOR_altivec_vspltb
9372 || icode == CODE_FOR_altivec_vsplth
9373 || icode == CODE_FOR_altivec_vspltw
9374 || icode == CODE_FOR_spe_evaddiw
9375 || icode == CODE_FOR_spe_evldd
9376 || icode == CODE_FOR_spe_evldh
9377 || icode == CODE_FOR_spe_evldw
9378 || icode == CODE_FOR_spe_evlhhesplat
9379 || icode == CODE_FOR_spe_evlhhossplat
9380 || icode == CODE_FOR_spe_evlhhousplat
9381 || icode == CODE_FOR_spe_evlwhe
9382 || icode == CODE_FOR_spe_evlwhos
9383 || icode == CODE_FOR_spe_evlwhou
9384 || icode == CODE_FOR_spe_evlwhsplat
9385 || icode == CODE_FOR_spe_evlwwsplat
9386 || icode == CODE_FOR_spe_evrlwi
9387 || icode == CODE_FOR_spe_evslwi
9388 || icode == CODE_FOR_spe_evsrwis
9389 || icode == CODE_FOR_spe_evsubifw
9390 || icode == CODE_FOR_spe_evsrwiu)
9392 /* Only allow 5-bit unsigned literals. */
9393 STRIP_NOPS (arg1);
9394 if (TREE_CODE (arg1) != INTEGER_CST
9395 || TREE_INT_CST_LOW (arg1) & ~0x1f)
9397 error ("argument 2 must be a 5-bit unsigned literal");
9398 return const0_rtx;
9402 if (target == 0
9403 || GET_MODE (target) != tmode
9404 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
9405 target = gen_reg_rtx (tmode);
9407 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
9408 op0 = copy_to_mode_reg (mode0, op0);
9409 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
9410 op1 = copy_to_mode_reg (mode1, op1);
9412 pat = GEN_FCN (icode) (target, op0, op1);
9413 if (! pat)
9414 return 0;
9415 emit_insn (pat);
9417 return target;
9420 static rtx
9421 altivec_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
9423 rtx pat, scratch;
9424 tree cr6_form = CALL_EXPR_ARG (exp, 0);
9425 tree arg0 = CALL_EXPR_ARG (exp, 1);
9426 tree arg1 = CALL_EXPR_ARG (exp, 2);
9427 rtx op0 = expand_normal (arg0);
9428 rtx op1 = expand_normal (arg1);
9429 enum machine_mode tmode = SImode;
9430 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
9431 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
9432 int cr6_form_int;
9434 if (TREE_CODE (cr6_form) != INTEGER_CST)
9436 error ("argument 1 of __builtin_altivec_predicate must be a constant");
9437 return const0_rtx;
9439 else
9440 cr6_form_int = TREE_INT_CST_LOW (cr6_form);
9442 gcc_assert (mode0 == mode1);
9444 /* If we have invalid arguments, bail out before generating bad rtl. */
9445 if (arg0 == error_mark_node || arg1 == error_mark_node)
9446 return const0_rtx;
9448 if (target == 0
9449 || GET_MODE (target) != tmode
9450 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
9451 target = gen_reg_rtx (tmode);
9453 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
9454 op0 = copy_to_mode_reg (mode0, op0);
9455 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
9456 op1 = copy_to_mode_reg (mode1, op1);
9458 scratch = gen_reg_rtx (mode0);
9460 pat = GEN_FCN (icode) (scratch, op0, op1);
9461 if (! pat)
9462 return 0;
9463 emit_insn (pat);
9465 /* The vec_any* and vec_all* predicates use the same opcodes for two
9466 different operations, but the bits in CR6 will be different
9467 depending on what information we want. So we have to play tricks
9468 with CR6 to get the right bits out.
9470 If you think this is disgusting, look at the specs for the
9471 AltiVec predicates. */
9473 switch (cr6_form_int)
9475 case 0:
9476 emit_insn (gen_cr6_test_for_zero (target));
9477 break;
9478 case 1:
9479 emit_insn (gen_cr6_test_for_zero_reverse (target));
9480 break;
9481 case 2:
9482 emit_insn (gen_cr6_test_for_lt (target));
9483 break;
9484 case 3:
9485 emit_insn (gen_cr6_test_for_lt_reverse (target));
9486 break;
9487 default:
9488 error ("argument 1 of __builtin_altivec_predicate is out of range");
9489 break;
9492 return target;
9495 static rtx
9496 paired_expand_lv_builtin (enum insn_code icode, tree exp, rtx target)
9498 rtx pat, addr;
9499 tree arg0 = CALL_EXPR_ARG (exp, 0);
9500 tree arg1 = CALL_EXPR_ARG (exp, 1);
9501 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9502 enum machine_mode mode0 = Pmode;
9503 enum machine_mode mode1 = Pmode;
9504 rtx op0 = expand_normal (arg0);
9505 rtx op1 = expand_normal (arg1);
9507 if (icode == CODE_FOR_nothing)
9508 /* Builtin not supported on this processor. */
9509 return 0;
9511 /* If we got invalid arguments bail out before generating bad rtl. */
9512 if (arg0 == error_mark_node || arg1 == error_mark_node)
9513 return const0_rtx;
9515 if (target == 0
9516 || GET_MODE (target) != tmode
9517 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
9518 target = gen_reg_rtx (tmode);
9520 op1 = copy_to_mode_reg (mode1, op1);
9522 if (op0 == const0_rtx)
9524 addr = gen_rtx_MEM (tmode, op1);
9526 else
9528 op0 = copy_to_mode_reg (mode0, op0);
9529 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op0, op1));
9532 pat = GEN_FCN (icode) (target, addr);
9534 if (! pat)
9535 return 0;
9536 emit_insn (pat);
9538 return target;
9541 static rtx
9542 altivec_expand_lv_builtin (enum insn_code icode, tree exp, rtx target, bool blk)
9544 rtx pat, addr;
9545 tree arg0 = CALL_EXPR_ARG (exp, 0);
9546 tree arg1 = CALL_EXPR_ARG (exp, 1);
9547 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9548 enum machine_mode mode0 = Pmode;
9549 enum machine_mode mode1 = Pmode;
9550 rtx op0 = expand_normal (arg0);
9551 rtx op1 = expand_normal (arg1);
9553 if (icode == CODE_FOR_nothing)
9554 /* Builtin not supported on this processor. */
9555 return 0;
9557 /* If we got invalid arguments bail out before generating bad rtl. */
9558 if (arg0 == error_mark_node || arg1 == error_mark_node)
9559 return const0_rtx;
9561 if (target == 0
9562 || GET_MODE (target) != tmode
9563 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
9564 target = gen_reg_rtx (tmode);
9566 op1 = copy_to_mode_reg (mode1, op1);
9568 if (op0 == const0_rtx)
9570 addr = gen_rtx_MEM (blk ? BLKmode : tmode, op1);
9572 else
9574 op0 = copy_to_mode_reg (mode0, op0);
9575 addr = gen_rtx_MEM (blk ? BLKmode : tmode, gen_rtx_PLUS (Pmode, op0, op1));
9578 pat = GEN_FCN (icode) (target, addr);
9580 if (! pat)
9581 return 0;
9582 emit_insn (pat);
9584 return target;
9587 static rtx
9588 spe_expand_stv_builtin (enum insn_code icode, tree exp)
9590 tree arg0 = CALL_EXPR_ARG (exp, 0);
9591 tree arg1 = CALL_EXPR_ARG (exp, 1);
9592 tree arg2 = CALL_EXPR_ARG (exp, 2);
9593 rtx op0 = expand_normal (arg0);
9594 rtx op1 = expand_normal (arg1);
9595 rtx op2 = expand_normal (arg2);
9596 rtx pat;
9597 enum machine_mode mode0 = insn_data[icode].operand[0].mode;
9598 enum machine_mode mode1 = insn_data[icode].operand[1].mode;
9599 enum machine_mode mode2 = insn_data[icode].operand[2].mode;
9601 /* Invalid arguments. Bail before doing anything stoopid! */
9602 if (arg0 == error_mark_node
9603 || arg1 == error_mark_node
9604 || arg2 == error_mark_node)
9605 return const0_rtx;
9607 if (! (*insn_data[icode].operand[2].predicate) (op0, mode2))
9608 op0 = copy_to_mode_reg (mode2, op0);
9609 if (! (*insn_data[icode].operand[0].predicate) (op1, mode0))
9610 op1 = copy_to_mode_reg (mode0, op1);
9611 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
9612 op2 = copy_to_mode_reg (mode1, op2);
9614 pat = GEN_FCN (icode) (op1, op2, op0);
9615 if (pat)
9616 emit_insn (pat);
9617 return NULL_RTX;
9620 static rtx
9621 paired_expand_stv_builtin (enum insn_code icode, tree exp)
9623 tree arg0 = CALL_EXPR_ARG (exp, 0);
9624 tree arg1 = CALL_EXPR_ARG (exp, 1);
9625 tree arg2 = CALL_EXPR_ARG (exp, 2);
9626 rtx op0 = expand_normal (arg0);
9627 rtx op1 = expand_normal (arg1);
9628 rtx op2 = expand_normal (arg2);
9629 rtx pat, addr;
9630 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9631 enum machine_mode mode1 = Pmode;
9632 enum machine_mode mode2 = Pmode;
9634 /* Invalid arguments. Bail before doing anything stoopid! */
9635 if (arg0 == error_mark_node
9636 || arg1 == error_mark_node
9637 || arg2 == error_mark_node)
9638 return const0_rtx;
9640 if (! (*insn_data[icode].operand[1].predicate) (op0, tmode))
9641 op0 = copy_to_mode_reg (tmode, op0);
9643 op2 = copy_to_mode_reg (mode2, op2);
9645 if (op1 == const0_rtx)
9647 addr = gen_rtx_MEM (tmode, op2);
9649 else
9651 op1 = copy_to_mode_reg (mode1, op1);
9652 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op1, op2));
9655 pat = GEN_FCN (icode) (addr, op0);
9656 if (pat)
9657 emit_insn (pat);
9658 return NULL_RTX;
9661 static rtx
9662 altivec_expand_stv_builtin (enum insn_code icode, tree exp)
9664 tree arg0 = CALL_EXPR_ARG (exp, 0);
9665 tree arg1 = CALL_EXPR_ARG (exp, 1);
9666 tree arg2 = CALL_EXPR_ARG (exp, 2);
9667 rtx op0 = expand_normal (arg0);
9668 rtx op1 = expand_normal (arg1);
9669 rtx op2 = expand_normal (arg2);
9670 rtx pat, addr;
9671 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9672 enum machine_mode mode1 = Pmode;
9673 enum machine_mode mode2 = Pmode;
9675 /* Invalid arguments. Bail before doing anything stoopid! */
9676 if (arg0 == error_mark_node
9677 || arg1 == error_mark_node
9678 || arg2 == error_mark_node)
9679 return const0_rtx;
9681 if (! (*insn_data[icode].operand[1].predicate) (op0, tmode))
9682 op0 = copy_to_mode_reg (tmode, op0);
9684 op2 = copy_to_mode_reg (mode2, op2);
9686 if (op1 == const0_rtx)
9688 addr = gen_rtx_MEM (tmode, op2);
9690 else
9692 op1 = copy_to_mode_reg (mode1, op1);
9693 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op1, op2));
9696 pat = GEN_FCN (icode) (addr, op0);
9697 if (pat)
9698 emit_insn (pat);
9699 return NULL_RTX;
9702 static rtx
9703 rs6000_expand_ternop_builtin (enum insn_code icode, tree exp, rtx target)
9705 rtx pat;
9706 tree arg0 = CALL_EXPR_ARG (exp, 0);
9707 tree arg1 = CALL_EXPR_ARG (exp, 1);
9708 tree arg2 = CALL_EXPR_ARG (exp, 2);
9709 rtx op0 = expand_normal (arg0);
9710 rtx op1 = expand_normal (arg1);
9711 rtx op2 = expand_normal (arg2);
9712 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9713 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
9714 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
9715 enum machine_mode mode2 = insn_data[icode].operand[3].mode;
9717 if (icode == CODE_FOR_nothing)
9718 /* Builtin not supported on this processor. */
9719 return 0;
9721 /* If we got invalid arguments bail out before generating bad rtl. */
9722 if (arg0 == error_mark_node
9723 || arg1 == error_mark_node
9724 || arg2 == error_mark_node)
9725 return const0_rtx;
9727 switch (icode)
9729 case CODE_FOR_altivec_vsldoi_v4sf:
9730 case CODE_FOR_altivec_vsldoi_v4si:
9731 case CODE_FOR_altivec_vsldoi_v8hi:
9732 case CODE_FOR_altivec_vsldoi_v16qi:
9733 /* Only allow 4-bit unsigned literals. */
9734 STRIP_NOPS (arg2);
9735 if (TREE_CODE (arg2) != INTEGER_CST
9736 || TREE_INT_CST_LOW (arg2) & ~0xf)
9738 error ("argument 3 must be a 4-bit unsigned literal");
9739 return const0_rtx;
9741 break;
9743 case CODE_FOR_vsx_xxpermdi_v2df:
9744 case CODE_FOR_vsx_xxpermdi_v2di:
9745 case CODE_FOR_vsx_xxsldwi_v16qi:
9746 case CODE_FOR_vsx_xxsldwi_v8hi:
9747 case CODE_FOR_vsx_xxsldwi_v4si:
9748 case CODE_FOR_vsx_xxsldwi_v4sf:
9749 case CODE_FOR_vsx_xxsldwi_v2di:
9750 case CODE_FOR_vsx_xxsldwi_v2df:
9751 /* Only allow 2-bit unsigned literals. */
9752 STRIP_NOPS (arg2);
9753 if (TREE_CODE (arg2) != INTEGER_CST
9754 || TREE_INT_CST_LOW (arg2) & ~0x3)
9756 error ("argument 3 must be a 2-bit unsigned literal");
9757 return const0_rtx;
9759 break;
9761 case CODE_FOR_vsx_set_v2df:
9762 case CODE_FOR_vsx_set_v2di:
9763 /* Only allow 1-bit unsigned literals. */
9764 STRIP_NOPS (arg2);
9765 if (TREE_CODE (arg2) != INTEGER_CST
9766 || TREE_INT_CST_LOW (arg2) & ~0x1)
9768 error ("argument 3 must be a 1-bit unsigned literal");
9769 return const0_rtx;
9771 break;
9773 default:
9774 break;
9777 if (target == 0
9778 || GET_MODE (target) != tmode
9779 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
9780 target = gen_reg_rtx (tmode);
9782 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
9783 op0 = copy_to_mode_reg (mode0, op0);
9784 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
9785 op1 = copy_to_mode_reg (mode1, op1);
9786 if (! (*insn_data[icode].operand[3].predicate) (op2, mode2))
9787 op2 = copy_to_mode_reg (mode2, op2);
9789 if (TARGET_PAIRED_FLOAT && icode == CODE_FOR_selv2sf4)
9790 pat = GEN_FCN (icode) (target, op0, op1, op2, CONST0_RTX (SFmode));
9791 else
9792 pat = GEN_FCN (icode) (target, op0, op1, op2);
9793 if (! pat)
9794 return 0;
9795 emit_insn (pat);
9797 return target;
9800 /* Expand the lvx builtins. */
9801 static rtx
9802 altivec_expand_ld_builtin (tree exp, rtx target, bool *expandedp)
9804 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
9805 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
9806 tree arg0;
9807 enum machine_mode tmode, mode0;
9808 rtx pat, op0;
9809 enum insn_code icode;
9811 switch (fcode)
9813 case ALTIVEC_BUILTIN_LD_INTERNAL_16qi:
9814 icode = CODE_FOR_vector_load_v16qi;
9815 break;
9816 case ALTIVEC_BUILTIN_LD_INTERNAL_8hi:
9817 icode = CODE_FOR_vector_load_v8hi;
9818 break;
9819 case ALTIVEC_BUILTIN_LD_INTERNAL_4si:
9820 icode = CODE_FOR_vector_load_v4si;
9821 break;
9822 case ALTIVEC_BUILTIN_LD_INTERNAL_4sf:
9823 icode = CODE_FOR_vector_load_v4sf;
9824 break;
9825 default:
9826 *expandedp = false;
9827 return NULL_RTX;
9830 *expandedp = true;
9832 arg0 = CALL_EXPR_ARG (exp, 0);
9833 op0 = expand_normal (arg0);
9834 tmode = insn_data[icode].operand[0].mode;
9835 mode0 = insn_data[icode].operand[1].mode;
9837 if (target == 0
9838 || GET_MODE (target) != tmode
9839 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
9840 target = gen_reg_rtx (tmode);
9842 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
9843 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
9845 pat = GEN_FCN (icode) (target, op0);
9846 if (! pat)
9847 return 0;
9848 emit_insn (pat);
9849 return target;
9852 /* Expand the stvx builtins. */
9853 static rtx
9854 altivec_expand_st_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
9855 bool *expandedp)
9857 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
9858 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
9859 tree arg0, arg1;
9860 enum machine_mode mode0, mode1;
9861 rtx pat, op0, op1;
9862 enum insn_code icode;
9864 switch (fcode)
9866 case ALTIVEC_BUILTIN_ST_INTERNAL_16qi:
9867 icode = CODE_FOR_vector_store_v16qi;
9868 break;
9869 case ALTIVEC_BUILTIN_ST_INTERNAL_8hi:
9870 icode = CODE_FOR_vector_store_v8hi;
9871 break;
9872 case ALTIVEC_BUILTIN_ST_INTERNAL_4si:
9873 icode = CODE_FOR_vector_store_v4si;
9874 break;
9875 case ALTIVEC_BUILTIN_ST_INTERNAL_4sf:
9876 icode = CODE_FOR_vector_store_v4sf;
9877 break;
9878 default:
9879 *expandedp = false;
9880 return NULL_RTX;
9883 arg0 = CALL_EXPR_ARG (exp, 0);
9884 arg1 = CALL_EXPR_ARG (exp, 1);
9885 op0 = expand_normal (arg0);
9886 op1 = expand_normal (arg1);
9887 mode0 = insn_data[icode].operand[0].mode;
9888 mode1 = insn_data[icode].operand[1].mode;
9890 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
9891 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
9892 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
9893 op1 = copy_to_mode_reg (mode1, op1);
9895 pat = GEN_FCN (icode) (op0, op1);
9896 if (pat)
9897 emit_insn (pat);
9899 *expandedp = true;
9900 return NULL_RTX;
9903 /* Expand the dst builtins. */
9904 static rtx
9905 altivec_expand_dst_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
9906 bool *expandedp)
9908 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
9909 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
9910 tree arg0, arg1, arg2;
9911 enum machine_mode mode0, mode1, mode2;
9912 rtx pat, op0, op1, op2;
9913 const struct builtin_description *d;
9914 size_t i;
9916 *expandedp = false;
9918 /* Handle DST variants. */
9919 d = bdesc_dst;
9920 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
9921 if (d->code == fcode)
9923 arg0 = CALL_EXPR_ARG (exp, 0);
9924 arg1 = CALL_EXPR_ARG (exp, 1);
9925 arg2 = CALL_EXPR_ARG (exp, 2);
9926 op0 = expand_normal (arg0);
9927 op1 = expand_normal (arg1);
9928 op2 = expand_normal (arg2);
9929 mode0 = insn_data[d->icode].operand[0].mode;
9930 mode1 = insn_data[d->icode].operand[1].mode;
9931 mode2 = insn_data[d->icode].operand[2].mode;
9933 /* Invalid arguments, bail out before generating bad rtl. */
9934 if (arg0 == error_mark_node
9935 || arg1 == error_mark_node
9936 || arg2 == error_mark_node)
9937 return const0_rtx;
9939 *expandedp = true;
9940 STRIP_NOPS (arg2);
9941 if (TREE_CODE (arg2) != INTEGER_CST
9942 || TREE_INT_CST_LOW (arg2) & ~0x3)
9944 error ("argument to %qs must be a 2-bit unsigned literal", d->name);
9945 return const0_rtx;
9948 if (! (*insn_data[d->icode].operand[0].predicate) (op0, mode0))
9949 op0 = copy_to_mode_reg (Pmode, op0);
9950 if (! (*insn_data[d->icode].operand[1].predicate) (op1, mode1))
9951 op1 = copy_to_mode_reg (mode1, op1);
9953 pat = GEN_FCN (d->icode) (op0, op1, op2);
9954 if (pat != 0)
9955 emit_insn (pat);
9957 return NULL_RTX;
9960 return NULL_RTX;
9963 /* Expand vec_init builtin. */
9964 static rtx
9965 altivec_expand_vec_init_builtin (tree type, tree exp, rtx target)
9967 enum machine_mode tmode = TYPE_MODE (type);
9968 enum machine_mode inner_mode = GET_MODE_INNER (tmode);
9969 int i, n_elt = GET_MODE_NUNITS (tmode);
9970 rtvec v = rtvec_alloc (n_elt);
9972 gcc_assert (VECTOR_MODE_P (tmode));
9973 gcc_assert (n_elt == call_expr_nargs (exp));
9975 for (i = 0; i < n_elt; ++i)
9977 rtx x = expand_normal (CALL_EXPR_ARG (exp, i));
9978 RTVEC_ELT (v, i) = gen_lowpart (inner_mode, x);
9981 if (!target || !register_operand (target, tmode))
9982 target = gen_reg_rtx (tmode);
9984 rs6000_expand_vector_init (target, gen_rtx_PARALLEL (tmode, v));
9985 return target;
9988 /* Return the integer constant in ARG. Constrain it to be in the range
9989 of the subparts of VEC_TYPE; issue an error if not. */
9991 static int
9992 get_element_number (tree vec_type, tree arg)
9994 unsigned HOST_WIDE_INT elt, max = TYPE_VECTOR_SUBPARTS (vec_type) - 1;
9996 if (!host_integerp (arg, 1)
9997 || (elt = tree_low_cst (arg, 1), elt > max))
9999 error ("selector must be an integer constant in the range 0..%wi", max);
10000 return 0;
10003 return elt;
10006 /* Expand vec_set builtin. */
10007 static rtx
10008 altivec_expand_vec_set_builtin (tree exp)
10010 enum machine_mode tmode, mode1;
10011 tree arg0, arg1, arg2;
10012 int elt;
10013 rtx op0, op1;
10015 arg0 = CALL_EXPR_ARG (exp, 0);
10016 arg1 = CALL_EXPR_ARG (exp, 1);
10017 arg2 = CALL_EXPR_ARG (exp, 2);
10019 tmode = TYPE_MODE (TREE_TYPE (arg0));
10020 mode1 = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
10021 gcc_assert (VECTOR_MODE_P (tmode));
10023 op0 = expand_expr (arg0, NULL_RTX, tmode, EXPAND_NORMAL);
10024 op1 = expand_expr (arg1, NULL_RTX, mode1, EXPAND_NORMAL);
10025 elt = get_element_number (TREE_TYPE (arg0), arg2);
10027 if (GET_MODE (op1) != mode1 && GET_MODE (op1) != VOIDmode)
10028 op1 = convert_modes (mode1, GET_MODE (op1), op1, true);
10030 op0 = force_reg (tmode, op0);
10031 op1 = force_reg (mode1, op1);
10033 rs6000_expand_vector_set (op0, op1, elt);
10035 return op0;
10038 /* Expand vec_ext builtin. */
10039 static rtx
10040 altivec_expand_vec_ext_builtin (tree exp, rtx target)
10042 enum machine_mode tmode, mode0;
10043 tree arg0, arg1;
10044 int elt;
10045 rtx op0;
10047 arg0 = CALL_EXPR_ARG (exp, 0);
10048 arg1 = CALL_EXPR_ARG (exp, 1);
10050 op0 = expand_normal (arg0);
10051 elt = get_element_number (TREE_TYPE (arg0), arg1);
10053 tmode = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
10054 mode0 = TYPE_MODE (TREE_TYPE (arg0));
10055 gcc_assert (VECTOR_MODE_P (mode0));
10057 op0 = force_reg (mode0, op0);
10059 if (optimize || !target || !register_operand (target, tmode))
10060 target = gen_reg_rtx (tmode);
10062 rs6000_expand_vector_extract (target, op0, elt);
10064 return target;
10067 /* Expand the builtin in EXP and store the result in TARGET. Store
10068 true in *EXPANDEDP if we found a builtin to expand. */
10069 static rtx
10070 altivec_expand_builtin (tree exp, rtx target, bool *expandedp)
10072 const struct builtin_description *d;
10073 const struct builtin_description_predicates *dp;
10074 size_t i;
10075 enum insn_code icode;
10076 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10077 tree arg0;
10078 rtx op0, pat;
10079 enum machine_mode tmode, mode0;
10080 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10082 if ((fcode >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
10083 && fcode <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
10084 || (fcode >= VSX_BUILTIN_OVERLOADED_FIRST
10085 && fcode <= VSX_BUILTIN_OVERLOADED_LAST))
10087 *expandedp = true;
10088 error ("unresolved overload for Altivec builtin %qF", fndecl);
10089 return const0_rtx;
10092 target = altivec_expand_ld_builtin (exp, target, expandedp);
10093 if (*expandedp)
10094 return target;
10096 target = altivec_expand_st_builtin (exp, target, expandedp);
10097 if (*expandedp)
10098 return target;
10100 target = altivec_expand_dst_builtin (exp, target, expandedp);
10101 if (*expandedp)
10102 return target;
10104 *expandedp = true;
10106 switch (fcode)
10108 case ALTIVEC_BUILTIN_STVX:
10109 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx, exp);
10110 case ALTIVEC_BUILTIN_STVEBX:
10111 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvebx, exp);
10112 case ALTIVEC_BUILTIN_STVEHX:
10113 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvehx, exp);
10114 case ALTIVEC_BUILTIN_STVEWX:
10115 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvewx, exp);
10116 case ALTIVEC_BUILTIN_STVXL:
10117 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvxl, exp);
10119 case ALTIVEC_BUILTIN_STVLX:
10120 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlx, exp);
10121 case ALTIVEC_BUILTIN_STVLXL:
10122 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlxl, exp);
10123 case ALTIVEC_BUILTIN_STVRX:
10124 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrx, exp);
10125 case ALTIVEC_BUILTIN_STVRXL:
10126 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrxl, exp);
10128 case ALTIVEC_BUILTIN_MFVSCR:
10129 icode = CODE_FOR_altivec_mfvscr;
10130 tmode = insn_data[icode].operand[0].mode;
10132 if (target == 0
10133 || GET_MODE (target) != tmode
10134 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10135 target = gen_reg_rtx (tmode);
10137 pat = GEN_FCN (icode) (target);
10138 if (! pat)
10139 return 0;
10140 emit_insn (pat);
10141 return target;
10143 case ALTIVEC_BUILTIN_MTVSCR:
10144 icode = CODE_FOR_altivec_mtvscr;
10145 arg0 = CALL_EXPR_ARG (exp, 0);
10146 op0 = expand_normal (arg0);
10147 mode0 = insn_data[icode].operand[0].mode;
10149 /* If we got invalid arguments bail out before generating bad rtl. */
10150 if (arg0 == error_mark_node)
10151 return const0_rtx;
10153 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
10154 op0 = copy_to_mode_reg (mode0, op0);
10156 pat = GEN_FCN (icode) (op0);
10157 if (pat)
10158 emit_insn (pat);
10159 return NULL_RTX;
10161 case ALTIVEC_BUILTIN_DSSALL:
10162 emit_insn (gen_altivec_dssall ());
10163 return NULL_RTX;
10165 case ALTIVEC_BUILTIN_DSS:
10166 icode = CODE_FOR_altivec_dss;
10167 arg0 = CALL_EXPR_ARG (exp, 0);
10168 STRIP_NOPS (arg0);
10169 op0 = expand_normal (arg0);
10170 mode0 = insn_data[icode].operand[0].mode;
10172 /* If we got invalid arguments bail out before generating bad rtl. */
10173 if (arg0 == error_mark_node)
10174 return const0_rtx;
10176 if (TREE_CODE (arg0) != INTEGER_CST
10177 || TREE_INT_CST_LOW (arg0) & ~0x3)
10179 error ("argument to dss must be a 2-bit unsigned literal");
10180 return const0_rtx;
10183 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
10184 op0 = copy_to_mode_reg (mode0, op0);
10186 emit_insn (gen_altivec_dss (op0));
10187 return NULL_RTX;
10189 case ALTIVEC_BUILTIN_VEC_INIT_V4SI:
10190 case ALTIVEC_BUILTIN_VEC_INIT_V8HI:
10191 case ALTIVEC_BUILTIN_VEC_INIT_V16QI:
10192 case ALTIVEC_BUILTIN_VEC_INIT_V4SF:
10193 case VSX_BUILTIN_VEC_INIT_V2DF:
10194 case VSX_BUILTIN_VEC_INIT_V2DI:
10195 return altivec_expand_vec_init_builtin (TREE_TYPE (exp), exp, target);
10197 case ALTIVEC_BUILTIN_VEC_SET_V4SI:
10198 case ALTIVEC_BUILTIN_VEC_SET_V8HI:
10199 case ALTIVEC_BUILTIN_VEC_SET_V16QI:
10200 case ALTIVEC_BUILTIN_VEC_SET_V4SF:
10201 case VSX_BUILTIN_VEC_SET_V2DF:
10202 case VSX_BUILTIN_VEC_SET_V2DI:
10203 return altivec_expand_vec_set_builtin (exp);
10205 case ALTIVEC_BUILTIN_VEC_EXT_V4SI:
10206 case ALTIVEC_BUILTIN_VEC_EXT_V8HI:
10207 case ALTIVEC_BUILTIN_VEC_EXT_V16QI:
10208 case ALTIVEC_BUILTIN_VEC_EXT_V4SF:
10209 case VSX_BUILTIN_VEC_EXT_V2DF:
10210 case VSX_BUILTIN_VEC_EXT_V2DI:
10211 return altivec_expand_vec_ext_builtin (exp, target);
10213 default:
10214 break;
10215 /* Fall through. */
10218 /* Expand abs* operations. */
10219 d = bdesc_abs;
10220 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
10221 if (d->code == fcode)
10222 return altivec_expand_abs_builtin (d->icode, exp, target);
10224 /* Expand the AltiVec predicates. */
10225 dp = bdesc_altivec_preds;
10226 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
10227 if (dp->code == fcode)
10228 return altivec_expand_predicate_builtin (dp->icode, exp, target);
10230 /* LV* are funky. We initialized them differently. */
10231 switch (fcode)
10233 case ALTIVEC_BUILTIN_LVSL:
10234 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsl,
10235 exp, target, false);
10236 case ALTIVEC_BUILTIN_LVSR:
10237 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsr,
10238 exp, target, false);
10239 case ALTIVEC_BUILTIN_LVEBX:
10240 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvebx,
10241 exp, target, false);
10242 case ALTIVEC_BUILTIN_LVEHX:
10243 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvehx,
10244 exp, target, false);
10245 case ALTIVEC_BUILTIN_LVEWX:
10246 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvewx,
10247 exp, target, false);
10248 case ALTIVEC_BUILTIN_LVXL:
10249 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvxl,
10250 exp, target, false);
10251 case ALTIVEC_BUILTIN_LVX:
10252 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx,
10253 exp, target, false);
10254 case ALTIVEC_BUILTIN_LVLX:
10255 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlx,
10256 exp, target, true);
10257 case ALTIVEC_BUILTIN_LVLXL:
10258 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlxl,
10259 exp, target, true);
10260 case ALTIVEC_BUILTIN_LVRX:
10261 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrx,
10262 exp, target, true);
10263 case ALTIVEC_BUILTIN_LVRXL:
10264 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrxl,
10265 exp, target, true);
10266 default:
10267 break;
10268 /* Fall through. */
10271 *expandedp = false;
10272 return NULL_RTX;
10275 /* Expand the builtin in EXP and store the result in TARGET. Store
10276 true in *EXPANDEDP if we found a builtin to expand. */
10277 static rtx
10278 paired_expand_builtin (tree exp, rtx target, bool * expandedp)
10280 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10281 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10282 const struct builtin_description *d;
10283 size_t i;
10285 *expandedp = true;
10287 switch (fcode)
10289 case PAIRED_BUILTIN_STX:
10290 return paired_expand_stv_builtin (CODE_FOR_paired_stx, exp);
10291 case PAIRED_BUILTIN_LX:
10292 return paired_expand_lv_builtin (CODE_FOR_paired_lx, exp, target);
10293 default:
10294 break;
10295 /* Fall through. */
10298 /* Expand the paired predicates. */
10299 d = bdesc_paired_preds;
10300 for (i = 0; i < ARRAY_SIZE (bdesc_paired_preds); i++, d++)
10301 if (d->code == fcode)
10302 return paired_expand_predicate_builtin (d->icode, exp, target);
10304 *expandedp = false;
10305 return NULL_RTX;
10308 /* Binops that need to be initialized manually, but can be expanded
10309 automagically by rs6000_expand_binop_builtin. */
10310 static struct builtin_description bdesc_2arg_spe[] =
10312 { 0, CODE_FOR_spe_evlddx, "__builtin_spe_evlddx", SPE_BUILTIN_EVLDDX },
10313 { 0, CODE_FOR_spe_evldwx, "__builtin_spe_evldwx", SPE_BUILTIN_EVLDWX },
10314 { 0, CODE_FOR_spe_evldhx, "__builtin_spe_evldhx", SPE_BUILTIN_EVLDHX },
10315 { 0, CODE_FOR_spe_evlwhex, "__builtin_spe_evlwhex", SPE_BUILTIN_EVLWHEX },
10316 { 0, CODE_FOR_spe_evlwhoux, "__builtin_spe_evlwhoux", SPE_BUILTIN_EVLWHOUX },
10317 { 0, CODE_FOR_spe_evlwhosx, "__builtin_spe_evlwhosx", SPE_BUILTIN_EVLWHOSX },
10318 { 0, CODE_FOR_spe_evlwwsplatx, "__builtin_spe_evlwwsplatx", SPE_BUILTIN_EVLWWSPLATX },
10319 { 0, CODE_FOR_spe_evlwhsplatx, "__builtin_spe_evlwhsplatx", SPE_BUILTIN_EVLWHSPLATX },
10320 { 0, CODE_FOR_spe_evlhhesplatx, "__builtin_spe_evlhhesplatx", SPE_BUILTIN_EVLHHESPLATX },
10321 { 0, CODE_FOR_spe_evlhhousplatx, "__builtin_spe_evlhhousplatx", SPE_BUILTIN_EVLHHOUSPLATX },
10322 { 0, CODE_FOR_spe_evlhhossplatx, "__builtin_spe_evlhhossplatx", SPE_BUILTIN_EVLHHOSSPLATX },
10323 { 0, CODE_FOR_spe_evldd, "__builtin_spe_evldd", SPE_BUILTIN_EVLDD },
10324 { 0, CODE_FOR_spe_evldw, "__builtin_spe_evldw", SPE_BUILTIN_EVLDW },
10325 { 0, CODE_FOR_spe_evldh, "__builtin_spe_evldh", SPE_BUILTIN_EVLDH },
10326 { 0, CODE_FOR_spe_evlwhe, "__builtin_spe_evlwhe", SPE_BUILTIN_EVLWHE },
10327 { 0, CODE_FOR_spe_evlwhou, "__builtin_spe_evlwhou", SPE_BUILTIN_EVLWHOU },
10328 { 0, CODE_FOR_spe_evlwhos, "__builtin_spe_evlwhos", SPE_BUILTIN_EVLWHOS },
10329 { 0, CODE_FOR_spe_evlwwsplat, "__builtin_spe_evlwwsplat", SPE_BUILTIN_EVLWWSPLAT },
10330 { 0, CODE_FOR_spe_evlwhsplat, "__builtin_spe_evlwhsplat", SPE_BUILTIN_EVLWHSPLAT },
10331 { 0, CODE_FOR_spe_evlhhesplat, "__builtin_spe_evlhhesplat", SPE_BUILTIN_EVLHHESPLAT },
10332 { 0, CODE_FOR_spe_evlhhousplat, "__builtin_spe_evlhhousplat", SPE_BUILTIN_EVLHHOUSPLAT },
10333 { 0, CODE_FOR_spe_evlhhossplat, "__builtin_spe_evlhhossplat", SPE_BUILTIN_EVLHHOSSPLAT }
10336 /* Expand the builtin in EXP and store the result in TARGET. Store
10337 true in *EXPANDEDP if we found a builtin to expand.
10339 This expands the SPE builtins that are not simple unary and binary
10340 operations. */
10341 static rtx
10342 spe_expand_builtin (tree exp, rtx target, bool *expandedp)
10344 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10345 tree arg1, arg0;
10346 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10347 enum insn_code icode;
10348 enum machine_mode tmode, mode0;
10349 rtx pat, op0;
10350 struct builtin_description *d;
10351 size_t i;
10353 *expandedp = true;
10355 /* Syntax check for a 5-bit unsigned immediate. */
10356 switch (fcode)
10358 case SPE_BUILTIN_EVSTDD:
10359 case SPE_BUILTIN_EVSTDH:
10360 case SPE_BUILTIN_EVSTDW:
10361 case SPE_BUILTIN_EVSTWHE:
10362 case SPE_BUILTIN_EVSTWHO:
10363 case SPE_BUILTIN_EVSTWWE:
10364 case SPE_BUILTIN_EVSTWWO:
10365 arg1 = CALL_EXPR_ARG (exp, 2);
10366 if (TREE_CODE (arg1) != INTEGER_CST
10367 || TREE_INT_CST_LOW (arg1) & ~0x1f)
10369 error ("argument 2 must be a 5-bit unsigned literal");
10370 return const0_rtx;
10372 break;
10373 default:
10374 break;
10377 /* The evsplat*i instructions are not quite generic. */
10378 switch (fcode)
10380 case SPE_BUILTIN_EVSPLATFI:
10381 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplatfi,
10382 exp, target);
10383 case SPE_BUILTIN_EVSPLATI:
10384 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplati,
10385 exp, target);
10386 default:
10387 break;
10390 d = (struct builtin_description *) bdesc_2arg_spe;
10391 for (i = 0; i < ARRAY_SIZE (bdesc_2arg_spe); ++i, ++d)
10392 if (d->code == fcode)
10393 return rs6000_expand_binop_builtin (d->icode, exp, target);
10395 d = (struct builtin_description *) bdesc_spe_predicates;
10396 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, ++d)
10397 if (d->code == fcode)
10398 return spe_expand_predicate_builtin (d->icode, exp, target);
10400 d = (struct builtin_description *) bdesc_spe_evsel;
10401 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, ++d)
10402 if (d->code == fcode)
10403 return spe_expand_evsel_builtin (d->icode, exp, target);
10405 switch (fcode)
10407 case SPE_BUILTIN_EVSTDDX:
10408 return spe_expand_stv_builtin (CODE_FOR_spe_evstddx, exp);
10409 case SPE_BUILTIN_EVSTDHX:
10410 return spe_expand_stv_builtin (CODE_FOR_spe_evstdhx, exp);
10411 case SPE_BUILTIN_EVSTDWX:
10412 return spe_expand_stv_builtin (CODE_FOR_spe_evstdwx, exp);
10413 case SPE_BUILTIN_EVSTWHEX:
10414 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhex, exp);
10415 case SPE_BUILTIN_EVSTWHOX:
10416 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhox, exp);
10417 case SPE_BUILTIN_EVSTWWEX:
10418 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwex, exp);
10419 case SPE_BUILTIN_EVSTWWOX:
10420 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwox, exp);
10421 case SPE_BUILTIN_EVSTDD:
10422 return spe_expand_stv_builtin (CODE_FOR_spe_evstdd, exp);
10423 case SPE_BUILTIN_EVSTDH:
10424 return spe_expand_stv_builtin (CODE_FOR_spe_evstdh, exp);
10425 case SPE_BUILTIN_EVSTDW:
10426 return spe_expand_stv_builtin (CODE_FOR_spe_evstdw, exp);
10427 case SPE_BUILTIN_EVSTWHE:
10428 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhe, exp);
10429 case SPE_BUILTIN_EVSTWHO:
10430 return spe_expand_stv_builtin (CODE_FOR_spe_evstwho, exp);
10431 case SPE_BUILTIN_EVSTWWE:
10432 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwe, exp);
10433 case SPE_BUILTIN_EVSTWWO:
10434 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwo, exp);
10435 case SPE_BUILTIN_MFSPEFSCR:
10436 icode = CODE_FOR_spe_mfspefscr;
10437 tmode = insn_data[icode].operand[0].mode;
10439 if (target == 0
10440 || GET_MODE (target) != tmode
10441 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10442 target = gen_reg_rtx (tmode);
10444 pat = GEN_FCN (icode) (target);
10445 if (! pat)
10446 return 0;
10447 emit_insn (pat);
10448 return target;
10449 case SPE_BUILTIN_MTSPEFSCR:
10450 icode = CODE_FOR_spe_mtspefscr;
10451 arg0 = CALL_EXPR_ARG (exp, 0);
10452 op0 = expand_normal (arg0);
10453 mode0 = insn_data[icode].operand[0].mode;
10455 if (arg0 == error_mark_node)
10456 return const0_rtx;
10458 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
10459 op0 = copy_to_mode_reg (mode0, op0);
10461 pat = GEN_FCN (icode) (op0);
10462 if (pat)
10463 emit_insn (pat);
10464 return NULL_RTX;
10465 default:
10466 break;
10469 *expandedp = false;
10470 return NULL_RTX;
10473 static rtx
10474 paired_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
10476 rtx pat, scratch, tmp;
10477 tree form = CALL_EXPR_ARG (exp, 0);
10478 tree arg0 = CALL_EXPR_ARG (exp, 1);
10479 tree arg1 = CALL_EXPR_ARG (exp, 2);
10480 rtx op0 = expand_normal (arg0);
10481 rtx op1 = expand_normal (arg1);
10482 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10483 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
10484 int form_int;
10485 enum rtx_code code;
10487 if (TREE_CODE (form) != INTEGER_CST)
10489 error ("argument 1 of __builtin_paired_predicate must be a constant");
10490 return const0_rtx;
10492 else
10493 form_int = TREE_INT_CST_LOW (form);
10495 gcc_assert (mode0 == mode1);
10497 if (arg0 == error_mark_node || arg1 == error_mark_node)
10498 return const0_rtx;
10500 if (target == 0
10501 || GET_MODE (target) != SImode
10502 || !(*insn_data[icode].operand[0].predicate) (target, SImode))
10503 target = gen_reg_rtx (SImode);
10504 if (!(*insn_data[icode].operand[1].predicate) (op0, mode0))
10505 op0 = copy_to_mode_reg (mode0, op0);
10506 if (!(*insn_data[icode].operand[2].predicate) (op1, mode1))
10507 op1 = copy_to_mode_reg (mode1, op1);
10509 scratch = gen_reg_rtx (CCFPmode);
10511 pat = GEN_FCN (icode) (scratch, op0, op1);
10512 if (!pat)
10513 return const0_rtx;
10515 emit_insn (pat);
10517 switch (form_int)
10519 /* LT bit. */
10520 case 0:
10521 code = LT;
10522 break;
10523 /* GT bit. */
10524 case 1:
10525 code = GT;
10526 break;
10527 /* EQ bit. */
10528 case 2:
10529 code = EQ;
10530 break;
10531 /* UN bit. */
10532 case 3:
10533 emit_insn (gen_move_from_CR_ov_bit (target, scratch));
10534 return target;
10535 default:
10536 error ("argument 1 of __builtin_paired_predicate is out of range");
10537 return const0_rtx;
10540 tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx);
10541 emit_move_insn (target, tmp);
10542 return target;
10545 static rtx
10546 spe_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
10548 rtx pat, scratch, tmp;
10549 tree form = CALL_EXPR_ARG (exp, 0);
10550 tree arg0 = CALL_EXPR_ARG (exp, 1);
10551 tree arg1 = CALL_EXPR_ARG (exp, 2);
10552 rtx op0 = expand_normal (arg0);
10553 rtx op1 = expand_normal (arg1);
10554 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10555 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
10556 int form_int;
10557 enum rtx_code code;
10559 if (TREE_CODE (form) != INTEGER_CST)
10561 error ("argument 1 of __builtin_spe_predicate must be a constant");
10562 return const0_rtx;
10564 else
10565 form_int = TREE_INT_CST_LOW (form);
10567 gcc_assert (mode0 == mode1);
10569 if (arg0 == error_mark_node || arg1 == error_mark_node)
10570 return const0_rtx;
10572 if (target == 0
10573 || GET_MODE (target) != SImode
10574 || ! (*insn_data[icode].operand[0].predicate) (target, SImode))
10575 target = gen_reg_rtx (SImode);
10577 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10578 op0 = copy_to_mode_reg (mode0, op0);
10579 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
10580 op1 = copy_to_mode_reg (mode1, op1);
10582 scratch = gen_reg_rtx (CCmode);
10584 pat = GEN_FCN (icode) (scratch, op0, op1);
10585 if (! pat)
10586 return const0_rtx;
10587 emit_insn (pat);
10589 /* There are 4 variants for each predicate: _any_, _all_, _upper_,
10590 _lower_. We use one compare, but look in different bits of the
10591 CR for each variant.
10593 There are 2 elements in each SPE simd type (upper/lower). The CR
10594 bits are set as follows:
10596 BIT0 | BIT 1 | BIT 2 | BIT 3
10597 U | L | (U | L) | (U & L)
10599 So, for an "all" relationship, BIT 3 would be set.
10600 For an "any" relationship, BIT 2 would be set. Etc.
10602 Following traditional nomenclature, these bits map to:
10604 BIT0 | BIT 1 | BIT 2 | BIT 3
10605 LT | GT | EQ | OV
10607 Later, we will generate rtl to look in the LT/EQ/EQ/OV bits.
10610 switch (form_int)
10612 /* All variant. OV bit. */
10613 case 0:
10614 /* We need to get to the OV bit, which is the ORDERED bit. We
10615 could generate (ordered:SI (reg:CC xx) (const_int 0)), but
10616 that's ugly and will make validate_condition_mode die.
10617 So let's just use another pattern. */
10618 emit_insn (gen_move_from_CR_ov_bit (target, scratch));
10619 return target;
10620 /* Any variant. EQ bit. */
10621 case 1:
10622 code = EQ;
10623 break;
10624 /* Upper variant. LT bit. */
10625 case 2:
10626 code = LT;
10627 break;
10628 /* Lower variant. GT bit. */
10629 case 3:
10630 code = GT;
10631 break;
10632 default:
10633 error ("argument 1 of __builtin_spe_predicate is out of range");
10634 return const0_rtx;
10637 tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx);
10638 emit_move_insn (target, tmp);
10640 return target;
10643 /* The evsel builtins look like this:
10645 e = __builtin_spe_evsel_OP (a, b, c, d);
10647 and work like this:
10649 e[upper] = a[upper] *OP* b[upper] ? c[upper] : d[upper];
10650 e[lower] = a[lower] *OP* b[lower] ? c[lower] : d[lower];
10653 static rtx
10654 spe_expand_evsel_builtin (enum insn_code icode, tree exp, rtx target)
10656 rtx pat, scratch;
10657 tree arg0 = CALL_EXPR_ARG (exp, 0);
10658 tree arg1 = CALL_EXPR_ARG (exp, 1);
10659 tree arg2 = CALL_EXPR_ARG (exp, 2);
10660 tree arg3 = CALL_EXPR_ARG (exp, 3);
10661 rtx op0 = expand_normal (arg0);
10662 rtx op1 = expand_normal (arg1);
10663 rtx op2 = expand_normal (arg2);
10664 rtx op3 = expand_normal (arg3);
10665 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10666 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
10668 gcc_assert (mode0 == mode1);
10670 if (arg0 == error_mark_node || arg1 == error_mark_node
10671 || arg2 == error_mark_node || arg3 == error_mark_node)
10672 return const0_rtx;
10674 if (target == 0
10675 || GET_MODE (target) != mode0
10676 || ! (*insn_data[icode].operand[0].predicate) (target, mode0))
10677 target = gen_reg_rtx (mode0);
10679 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10680 op0 = copy_to_mode_reg (mode0, op0);
10681 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
10682 op1 = copy_to_mode_reg (mode0, op1);
10683 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
10684 op2 = copy_to_mode_reg (mode0, op2);
10685 if (! (*insn_data[icode].operand[1].predicate) (op3, mode1))
10686 op3 = copy_to_mode_reg (mode0, op3);
10688 /* Generate the compare. */
10689 scratch = gen_reg_rtx (CCmode);
10690 pat = GEN_FCN (icode) (scratch, op0, op1);
10691 if (! pat)
10692 return const0_rtx;
10693 emit_insn (pat);
10695 if (mode0 == V2SImode)
10696 emit_insn (gen_spe_evsel (target, op2, op3, scratch));
10697 else
10698 emit_insn (gen_spe_evsel_fs (target, op2, op3, scratch));
10700 return target;
10703 /* Expand an expression EXP that calls a built-in function,
10704 with result going to TARGET if that's convenient
10705 (and in mode MODE if that's convenient).
10706 SUBTARGET may be used as the target for computing one of EXP's operands.
10707 IGNORE is nonzero if the value is to be ignored. */
10709 static rtx
10710 rs6000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
10711 enum machine_mode mode ATTRIBUTE_UNUSED,
10712 int ignore ATTRIBUTE_UNUSED)
10714 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10715 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10716 const struct builtin_description *d;
10717 size_t i;
10718 rtx ret;
10719 bool success;
10721 if (fcode == RS6000_BUILTIN_RECIP)
10722 return rs6000_expand_binop_builtin (CODE_FOR_recipdf3, exp, target);
10724 if (fcode == RS6000_BUILTIN_RECIPF)
10725 return rs6000_expand_binop_builtin (CODE_FOR_recipsf3, exp, target);
10727 if (fcode == RS6000_BUILTIN_RSQRTF)
10728 return rs6000_expand_unop_builtin (CODE_FOR_rsqrtsf2, exp, target);
10730 if (fcode == RS6000_BUILTIN_BSWAP_HI)
10731 return rs6000_expand_unop_builtin (CODE_FOR_bswaphi2, exp, target);
10733 if (fcode == POWER7_BUILTIN_BPERMD)
10734 return rs6000_expand_binop_builtin (((TARGET_64BIT)
10735 ? CODE_FOR_bpermd_di
10736 : CODE_FOR_bpermd_si), exp, target);
10738 if (fcode == ALTIVEC_BUILTIN_MASK_FOR_LOAD
10739 || fcode == ALTIVEC_BUILTIN_MASK_FOR_STORE)
10741 int icode = (int) CODE_FOR_altivec_lvsr;
10742 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10743 enum machine_mode mode = insn_data[icode].operand[1].mode;
10744 tree arg;
10745 rtx op, addr, pat;
10747 gcc_assert (TARGET_ALTIVEC);
10749 arg = CALL_EXPR_ARG (exp, 0);
10750 gcc_assert (TREE_CODE (TREE_TYPE (arg)) == POINTER_TYPE);
10751 op = expand_expr (arg, NULL_RTX, Pmode, EXPAND_NORMAL);
10752 addr = memory_address (mode, op);
10753 if (fcode == ALTIVEC_BUILTIN_MASK_FOR_STORE)
10754 op = addr;
10755 else
10757 /* For the load case need to negate the address. */
10758 op = gen_reg_rtx (GET_MODE (addr));
10759 emit_insn (gen_rtx_SET (VOIDmode, op,
10760 gen_rtx_NEG (GET_MODE (addr), addr)));
10762 op = gen_rtx_MEM (mode, op);
10764 if (target == 0
10765 || GET_MODE (target) != tmode
10766 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10767 target = gen_reg_rtx (tmode);
10769 /*pat = gen_altivec_lvsr (target, op);*/
10770 pat = GEN_FCN (icode) (target, op);
10771 if (!pat)
10772 return 0;
10773 emit_insn (pat);
10775 return target;
10778 /* FIXME: There's got to be a nicer way to handle this case than
10779 constructing a new CALL_EXPR. */
10780 if (fcode == ALTIVEC_BUILTIN_VCFUX
10781 || fcode == ALTIVEC_BUILTIN_VCFSX
10782 || fcode == ALTIVEC_BUILTIN_VCTUXS
10783 || fcode == ALTIVEC_BUILTIN_VCTSXS)
10785 if (call_expr_nargs (exp) == 1)
10786 exp = build_call_nary (TREE_TYPE (exp), CALL_EXPR_FN (exp),
10787 2, CALL_EXPR_ARG (exp, 0), integer_zero_node);
10790 if (TARGET_ALTIVEC)
10792 ret = altivec_expand_builtin (exp, target, &success);
10794 if (success)
10795 return ret;
10797 if (TARGET_SPE)
10799 ret = spe_expand_builtin (exp, target, &success);
10801 if (success)
10802 return ret;
10804 if (TARGET_PAIRED_FLOAT)
10806 ret = paired_expand_builtin (exp, target, &success);
10808 if (success)
10809 return ret;
10812 gcc_assert (TARGET_ALTIVEC || TARGET_VSX || TARGET_SPE || TARGET_PAIRED_FLOAT);
10814 /* Handle simple unary operations. */
10815 d = (struct builtin_description *) bdesc_1arg;
10816 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
10817 if (d->code == fcode)
10818 return rs6000_expand_unop_builtin (d->icode, exp, target);
10820 /* Handle simple binary operations. */
10821 d = (struct builtin_description *) bdesc_2arg;
10822 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
10823 if (d->code == fcode)
10824 return rs6000_expand_binop_builtin (d->icode, exp, target);
10826 /* Handle simple ternary operations. */
10827 d = bdesc_3arg;
10828 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
10829 if (d->code == fcode)
10830 return rs6000_expand_ternop_builtin (d->icode, exp, target);
10832 gcc_unreachable ();
10835 static void
10836 rs6000_init_builtins (void)
10838 tree tdecl;
10840 V2SI_type_node = build_vector_type (intSI_type_node, 2);
10841 V2SF_type_node = build_vector_type (float_type_node, 2);
10842 V2DI_type_node = build_vector_type (intDI_type_node, 2);
10843 V2DF_type_node = build_vector_type (double_type_node, 2);
10844 V4HI_type_node = build_vector_type (intHI_type_node, 4);
10845 V4SI_type_node = build_vector_type (intSI_type_node, 4);
10846 V4SF_type_node = build_vector_type (float_type_node, 4);
10847 V8HI_type_node = build_vector_type (intHI_type_node, 8);
10848 V16QI_type_node = build_vector_type (intQI_type_node, 16);
10850 unsigned_V16QI_type_node = build_vector_type (unsigned_intQI_type_node, 16);
10851 unsigned_V8HI_type_node = build_vector_type (unsigned_intHI_type_node, 8);
10852 unsigned_V4SI_type_node = build_vector_type (unsigned_intSI_type_node, 4);
10853 unsigned_V2DI_type_node = build_vector_type (unsigned_intDI_type_node, 2);
10855 opaque_V2SF_type_node = build_opaque_vector_type (float_type_node, 2);
10856 opaque_V2SI_type_node = build_opaque_vector_type (intSI_type_node, 2);
10857 opaque_p_V2SI_type_node = build_pointer_type (opaque_V2SI_type_node);
10858 opaque_V4SI_type_node = build_opaque_vector_type (intSI_type_node, 4);
10860 /* The 'vector bool ...' types must be kept distinct from 'vector unsigned ...'
10861 types, especially in C++ land. Similarly, 'vector pixel' is distinct from
10862 'vector unsigned short'. */
10864 bool_char_type_node = build_distinct_type_copy (unsigned_intQI_type_node);
10865 bool_short_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
10866 bool_int_type_node = build_distinct_type_copy (unsigned_intSI_type_node);
10867 bool_long_type_node = build_distinct_type_copy (unsigned_intDI_type_node);
10868 pixel_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
10870 long_integer_type_internal_node = long_integer_type_node;
10871 long_unsigned_type_internal_node = long_unsigned_type_node;
10872 intQI_type_internal_node = intQI_type_node;
10873 uintQI_type_internal_node = unsigned_intQI_type_node;
10874 intHI_type_internal_node = intHI_type_node;
10875 uintHI_type_internal_node = unsigned_intHI_type_node;
10876 intSI_type_internal_node = intSI_type_node;
10877 uintSI_type_internal_node = unsigned_intSI_type_node;
10878 intDI_type_internal_node = intDI_type_node;
10879 uintDI_type_internal_node = unsigned_intDI_type_node;
10880 float_type_internal_node = float_type_node;
10881 double_type_internal_node = float_type_node;
10882 void_type_internal_node = void_type_node;
10884 /* Initialize the modes for builtin_function_type, mapping a machine mode to
10885 tree type node. */
10886 builtin_mode_to_type[QImode][0] = integer_type_node;
10887 builtin_mode_to_type[HImode][0] = integer_type_node;
10888 builtin_mode_to_type[SImode][0] = intSI_type_node;
10889 builtin_mode_to_type[SImode][1] = unsigned_intSI_type_node;
10890 builtin_mode_to_type[DImode][0] = intDI_type_node;
10891 builtin_mode_to_type[DImode][1] = unsigned_intDI_type_node;
10892 builtin_mode_to_type[SFmode][0] = float_type_node;
10893 builtin_mode_to_type[DFmode][0] = double_type_node;
10894 builtin_mode_to_type[V2SImode][0] = V2SI_type_node;
10895 builtin_mode_to_type[V2SFmode][0] = V2SF_type_node;
10896 builtin_mode_to_type[V2DImode][0] = V2DI_type_node;
10897 builtin_mode_to_type[V2DImode][1] = unsigned_V2DI_type_node;
10898 builtin_mode_to_type[V2DFmode][0] = V2DF_type_node;
10899 builtin_mode_to_type[V4HImode][0] = V4HI_type_node;
10900 builtin_mode_to_type[V4SImode][0] = V4SI_type_node;
10901 builtin_mode_to_type[V4SImode][1] = unsigned_V4SI_type_node;
10902 builtin_mode_to_type[V4SFmode][0] = V4SF_type_node;
10903 builtin_mode_to_type[V8HImode][0] = V8HI_type_node;
10904 builtin_mode_to_type[V8HImode][1] = unsigned_V8HI_type_node;
10905 builtin_mode_to_type[V16QImode][0] = V16QI_type_node;
10906 builtin_mode_to_type[V16QImode][1] = unsigned_V16QI_type_node;
10908 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
10909 get_identifier ("__bool char"),
10910 bool_char_type_node);
10911 TYPE_NAME (bool_char_type_node) = tdecl;
10912 (*lang_hooks.decls.pushdecl) (tdecl);
10913 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
10914 get_identifier ("__bool short"),
10915 bool_short_type_node);
10916 TYPE_NAME (bool_short_type_node) = tdecl;
10917 (*lang_hooks.decls.pushdecl) (tdecl);
10918 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
10919 get_identifier ("__bool int"),
10920 bool_int_type_node);
10921 TYPE_NAME (bool_int_type_node) = tdecl;
10922 (*lang_hooks.decls.pushdecl) (tdecl);
10923 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL, get_identifier ("__pixel"),
10924 pixel_type_node);
10925 TYPE_NAME (pixel_type_node) = tdecl;
10926 (*lang_hooks.decls.pushdecl) (tdecl);
10928 bool_V16QI_type_node = build_vector_type (bool_char_type_node, 16);
10929 bool_V8HI_type_node = build_vector_type (bool_short_type_node, 8);
10930 bool_V4SI_type_node = build_vector_type (bool_int_type_node, 4);
10931 bool_V2DI_type_node = build_vector_type (bool_long_type_node, 2);
10932 pixel_V8HI_type_node = build_vector_type (pixel_type_node, 8);
10934 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
10935 get_identifier ("__vector unsigned char"),
10936 unsigned_V16QI_type_node);
10937 TYPE_NAME (unsigned_V16QI_type_node) = tdecl;
10938 (*lang_hooks.decls.pushdecl) (tdecl);
10939 tdecl = build_decl (BUILTINS_LOCATION,
10940 TYPE_DECL, get_identifier ("__vector signed char"),
10941 V16QI_type_node);
10942 TYPE_NAME (V16QI_type_node) = tdecl;
10943 (*lang_hooks.decls.pushdecl) (tdecl);
10944 tdecl = build_decl (BUILTINS_LOCATION,
10945 TYPE_DECL, get_identifier ("__vector __bool char"),
10946 bool_V16QI_type_node);
10947 TYPE_NAME ( bool_V16QI_type_node) = tdecl;
10948 (*lang_hooks.decls.pushdecl) (tdecl);
10950 tdecl = build_decl (BUILTINS_LOCATION,
10951 TYPE_DECL, get_identifier ("__vector unsigned short"),
10952 unsigned_V8HI_type_node);
10953 TYPE_NAME (unsigned_V8HI_type_node) = tdecl;
10954 (*lang_hooks.decls.pushdecl) (tdecl);
10955 tdecl = build_decl (BUILTINS_LOCATION,
10956 TYPE_DECL, get_identifier ("__vector signed short"),
10957 V8HI_type_node);
10958 TYPE_NAME (V8HI_type_node) = tdecl;
10959 (*lang_hooks.decls.pushdecl) (tdecl);
10960 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
10961 get_identifier ("__vector __bool short"),
10962 bool_V8HI_type_node);
10963 TYPE_NAME (bool_V8HI_type_node) = tdecl;
10964 (*lang_hooks.decls.pushdecl) (tdecl);
10966 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
10967 get_identifier ("__vector unsigned int"),
10968 unsigned_V4SI_type_node);
10969 TYPE_NAME (unsigned_V4SI_type_node) = tdecl;
10970 (*lang_hooks.decls.pushdecl) (tdecl);
10971 tdecl = build_decl (BUILTINS_LOCATION,
10972 TYPE_DECL, get_identifier ("__vector signed int"),
10973 V4SI_type_node);
10974 TYPE_NAME (V4SI_type_node) = tdecl;
10975 (*lang_hooks.decls.pushdecl) (tdecl);
10976 tdecl = build_decl (BUILTINS_LOCATION,
10977 TYPE_DECL, get_identifier ("__vector __bool int"),
10978 bool_V4SI_type_node);
10979 TYPE_NAME (bool_V4SI_type_node) = tdecl;
10980 (*lang_hooks.decls.pushdecl) (tdecl);
10982 tdecl = build_decl (BUILTINS_LOCATION,
10983 TYPE_DECL, get_identifier ("__vector float"),
10984 V4SF_type_node);
10985 TYPE_NAME (V4SF_type_node) = tdecl;
10986 (*lang_hooks.decls.pushdecl) (tdecl);
10987 tdecl = build_decl (BUILTINS_LOCATION,
10988 TYPE_DECL, get_identifier ("__vector __pixel"),
10989 pixel_V8HI_type_node);
10990 TYPE_NAME (pixel_V8HI_type_node) = tdecl;
10991 (*lang_hooks.decls.pushdecl) (tdecl);
10993 if (TARGET_VSX)
10995 tdecl = build_decl (BUILTINS_LOCATION,
10996 TYPE_DECL, get_identifier ("__vector double"),
10997 V2DF_type_node);
10998 TYPE_NAME (V2DF_type_node) = tdecl;
10999 (*lang_hooks.decls.pushdecl) (tdecl);
11001 tdecl = build_decl (BUILTINS_LOCATION,
11002 TYPE_DECL, get_identifier ("__vector long"),
11003 V2DI_type_node);
11004 TYPE_NAME (V2DI_type_node) = tdecl;
11005 (*lang_hooks.decls.pushdecl) (tdecl);
11007 tdecl = build_decl (BUILTINS_LOCATION,
11008 TYPE_DECL, get_identifier ("__vector unsigned long"),
11009 unsigned_V2DI_type_node);
11010 TYPE_NAME (unsigned_V2DI_type_node) = tdecl;
11011 (*lang_hooks.decls.pushdecl) (tdecl);
11013 tdecl = build_decl (BUILTINS_LOCATION,
11014 TYPE_DECL, get_identifier ("__vector __bool long"),
11015 bool_V2DI_type_node);
11016 TYPE_NAME (bool_V2DI_type_node) = tdecl;
11017 (*lang_hooks.decls.pushdecl) (tdecl);
11020 if (TARGET_PAIRED_FLOAT)
11021 paired_init_builtins ();
11022 if (TARGET_SPE)
11023 spe_init_builtins ();
11024 if (TARGET_ALTIVEC)
11025 altivec_init_builtins ();
11026 if (TARGET_ALTIVEC || TARGET_SPE || TARGET_PAIRED_FLOAT || TARGET_VSX)
11027 rs6000_common_init_builtins ();
11028 if (TARGET_PPC_GFXOPT)
11030 tree ftype = builtin_function_type (SFmode, SFmode, SFmode, VOIDmode,
11031 RS6000_BUILTIN_RECIPF,
11032 "__builtin_recipdivf");
11033 def_builtin (MASK_PPC_GFXOPT, "__builtin_recipdivf", ftype,
11034 RS6000_BUILTIN_RECIPF);
11036 ftype = builtin_function_type (SFmode, SFmode, VOIDmode, VOIDmode,
11037 RS6000_BUILTIN_RSQRTF,
11038 "__builtin_rsqrtf");
11039 def_builtin (MASK_PPC_GFXOPT, "__builtin_rsqrtf", ftype,
11040 RS6000_BUILTIN_RSQRTF);
11042 if (TARGET_POPCNTB)
11044 tree ftype = builtin_function_type (DFmode, DFmode, DFmode, VOIDmode,
11045 RS6000_BUILTIN_RECIP,
11046 "__builtin_recipdiv");
11047 def_builtin (MASK_POPCNTB, "__builtin_recipdiv", ftype,
11048 RS6000_BUILTIN_RECIP);
11051 if (TARGET_POPCNTD)
11053 enum machine_mode mode = (TARGET_64BIT) ? DImode : SImode;
11054 tree ftype = builtin_function_type (mode, mode, mode, VOIDmode,
11055 POWER7_BUILTIN_BPERMD,
11056 "__builtin_bpermd");
11057 def_builtin (MASK_POPCNTD, "__builtin_bpermd", ftype,
11058 POWER7_BUILTIN_BPERMD);
11060 if (TARGET_POWERPC)
11062 /* Don't use builtin_function_type here, as it maps HI/QI to SI. */
11063 tree ftype = build_function_type_list (unsigned_intHI_type_node,
11064 unsigned_intHI_type_node,
11065 NULL_TREE);
11066 def_builtin (MASK_POWERPC, "__builtin_bswap16", ftype,
11067 RS6000_BUILTIN_BSWAP_HI);
11070 #if TARGET_XCOFF
11071 /* AIX libm provides clog as __clog. */
11072 if (built_in_decls [BUILT_IN_CLOG])
11073 set_user_assembler_name (built_in_decls [BUILT_IN_CLOG], "__clog");
11074 #endif
11076 #ifdef SUBTARGET_INIT_BUILTINS
11077 SUBTARGET_INIT_BUILTINS;
11078 #endif
11081 /* Search through a set of builtins and enable the mask bits.
11082 DESC is an array of builtins.
11083 SIZE is the total number of builtins.
11084 START is the builtin enum at which to start.
11085 END is the builtin enum at which to end. */
11086 static void
11087 enable_mask_for_builtins (struct builtin_description *desc, int size,
11088 enum rs6000_builtins start,
11089 enum rs6000_builtins end)
11091 int i;
11093 for (i = 0; i < size; ++i)
11094 if (desc[i].code == start)
11095 break;
11097 if (i == size)
11098 return;
11100 for (; i < size; ++i)
11102 /* Flip all the bits on. */
11103 desc[i].mask = target_flags;
11104 if (desc[i].code == end)
11105 break;
11109 static void
11110 spe_init_builtins (void)
11112 tree endlink = void_list_node;
11113 tree puint_type_node = build_pointer_type (unsigned_type_node);
11114 tree pushort_type_node = build_pointer_type (short_unsigned_type_node);
11115 struct builtin_description *d;
11116 size_t i;
11118 tree v2si_ftype_4_v2si
11119 = build_function_type
11120 (opaque_V2SI_type_node,
11121 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11122 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11123 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11124 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11125 endlink)))));
11127 tree v2sf_ftype_4_v2sf
11128 = build_function_type
11129 (opaque_V2SF_type_node,
11130 tree_cons (NULL_TREE, opaque_V2SF_type_node,
11131 tree_cons (NULL_TREE, opaque_V2SF_type_node,
11132 tree_cons (NULL_TREE, opaque_V2SF_type_node,
11133 tree_cons (NULL_TREE, opaque_V2SF_type_node,
11134 endlink)))));
11136 tree int_ftype_int_v2si_v2si
11137 = build_function_type
11138 (integer_type_node,
11139 tree_cons (NULL_TREE, integer_type_node,
11140 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11141 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11142 endlink))));
11144 tree int_ftype_int_v2sf_v2sf
11145 = build_function_type
11146 (integer_type_node,
11147 tree_cons (NULL_TREE, integer_type_node,
11148 tree_cons (NULL_TREE, opaque_V2SF_type_node,
11149 tree_cons (NULL_TREE, opaque_V2SF_type_node,
11150 endlink))));
11152 tree void_ftype_v2si_puint_int
11153 = build_function_type (void_type_node,
11154 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11155 tree_cons (NULL_TREE, puint_type_node,
11156 tree_cons (NULL_TREE,
11157 integer_type_node,
11158 endlink))));
11160 tree void_ftype_v2si_puint_char
11161 = build_function_type (void_type_node,
11162 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11163 tree_cons (NULL_TREE, puint_type_node,
11164 tree_cons (NULL_TREE,
11165 char_type_node,
11166 endlink))));
11168 tree void_ftype_v2si_pv2si_int
11169 = build_function_type (void_type_node,
11170 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11171 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
11172 tree_cons (NULL_TREE,
11173 integer_type_node,
11174 endlink))));
11176 tree void_ftype_v2si_pv2si_char
11177 = build_function_type (void_type_node,
11178 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11179 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
11180 tree_cons (NULL_TREE,
11181 char_type_node,
11182 endlink))));
11184 tree void_ftype_int
11185 = build_function_type (void_type_node,
11186 tree_cons (NULL_TREE, integer_type_node, endlink));
11188 tree int_ftype_void
11189 = build_function_type (integer_type_node, endlink);
11191 tree v2si_ftype_pv2si_int
11192 = build_function_type (opaque_V2SI_type_node,
11193 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
11194 tree_cons (NULL_TREE, integer_type_node,
11195 endlink)));
11197 tree v2si_ftype_puint_int
11198 = build_function_type (opaque_V2SI_type_node,
11199 tree_cons (NULL_TREE, puint_type_node,
11200 tree_cons (NULL_TREE, integer_type_node,
11201 endlink)));
11203 tree v2si_ftype_pushort_int
11204 = build_function_type (opaque_V2SI_type_node,
11205 tree_cons (NULL_TREE, pushort_type_node,
11206 tree_cons (NULL_TREE, integer_type_node,
11207 endlink)));
11209 tree v2si_ftype_signed_char
11210 = build_function_type (opaque_V2SI_type_node,
11211 tree_cons (NULL_TREE, signed_char_type_node,
11212 endlink));
11214 /* The initialization of the simple binary and unary builtins is
11215 done in rs6000_common_init_builtins, but we have to enable the
11216 mask bits here manually because we have run out of `target_flags'
11217 bits. We really need to redesign this mask business. */
11219 enable_mask_for_builtins ((struct builtin_description *) bdesc_2arg,
11220 ARRAY_SIZE (bdesc_2arg),
11221 SPE_BUILTIN_EVADDW,
11222 SPE_BUILTIN_EVXOR);
11223 enable_mask_for_builtins ((struct builtin_description *) bdesc_1arg,
11224 ARRAY_SIZE (bdesc_1arg),
11225 SPE_BUILTIN_EVABS,
11226 SPE_BUILTIN_EVSUBFUSIAAW);
11227 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_predicates,
11228 ARRAY_SIZE (bdesc_spe_predicates),
11229 SPE_BUILTIN_EVCMPEQ,
11230 SPE_BUILTIN_EVFSTSTLT);
11231 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_evsel,
11232 ARRAY_SIZE (bdesc_spe_evsel),
11233 SPE_BUILTIN_EVSEL_CMPGTS,
11234 SPE_BUILTIN_EVSEL_FSTSTEQ);
11236 (*lang_hooks.decls.pushdecl)
11237 (build_decl (BUILTINS_LOCATION, TYPE_DECL,
11238 get_identifier ("__ev64_opaque__"),
11239 opaque_V2SI_type_node));
11241 /* Initialize irregular SPE builtins. */
11243 def_builtin (target_flags, "__builtin_spe_mtspefscr", void_ftype_int, SPE_BUILTIN_MTSPEFSCR);
11244 def_builtin (target_flags, "__builtin_spe_mfspefscr", int_ftype_void, SPE_BUILTIN_MFSPEFSCR);
11245 def_builtin (target_flags, "__builtin_spe_evstddx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDDX);
11246 def_builtin (target_flags, "__builtin_spe_evstdhx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDHX);
11247 def_builtin (target_flags, "__builtin_spe_evstdwx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDWX);
11248 def_builtin (target_flags, "__builtin_spe_evstwhex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHEX);
11249 def_builtin (target_flags, "__builtin_spe_evstwhox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHOX);
11250 def_builtin (target_flags, "__builtin_spe_evstwwex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWEX);
11251 def_builtin (target_flags, "__builtin_spe_evstwwox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWOX);
11252 def_builtin (target_flags, "__builtin_spe_evstdd", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDD);
11253 def_builtin (target_flags, "__builtin_spe_evstdh", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDH);
11254 def_builtin (target_flags, "__builtin_spe_evstdw", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDW);
11255 def_builtin (target_flags, "__builtin_spe_evstwhe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHE);
11256 def_builtin (target_flags, "__builtin_spe_evstwho", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHO);
11257 def_builtin (target_flags, "__builtin_spe_evstwwe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWE);
11258 def_builtin (target_flags, "__builtin_spe_evstwwo", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWO);
11259 def_builtin (target_flags, "__builtin_spe_evsplatfi", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATFI);
11260 def_builtin (target_flags, "__builtin_spe_evsplati", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATI);
11262 /* Loads. */
11263 def_builtin (target_flags, "__builtin_spe_evlddx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDDX);
11264 def_builtin (target_flags, "__builtin_spe_evldwx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDWX);
11265 def_builtin (target_flags, "__builtin_spe_evldhx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDHX);
11266 def_builtin (target_flags, "__builtin_spe_evlwhex", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHEX);
11267 def_builtin (target_flags, "__builtin_spe_evlwhoux", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOUX);
11268 def_builtin (target_flags, "__builtin_spe_evlwhosx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOSX);
11269 def_builtin (target_flags, "__builtin_spe_evlwwsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLATX);
11270 def_builtin (target_flags, "__builtin_spe_evlwhsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLATX);
11271 def_builtin (target_flags, "__builtin_spe_evlhhesplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLATX);
11272 def_builtin (target_flags, "__builtin_spe_evlhhousplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLATX);
11273 def_builtin (target_flags, "__builtin_spe_evlhhossplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLATX);
11274 def_builtin (target_flags, "__builtin_spe_evldd", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDD);
11275 def_builtin (target_flags, "__builtin_spe_evldw", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDW);
11276 def_builtin (target_flags, "__builtin_spe_evldh", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDH);
11277 def_builtin (target_flags, "__builtin_spe_evlhhesplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLAT);
11278 def_builtin (target_flags, "__builtin_spe_evlhhossplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLAT);
11279 def_builtin (target_flags, "__builtin_spe_evlhhousplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLAT);
11280 def_builtin (target_flags, "__builtin_spe_evlwhe", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHE);
11281 def_builtin (target_flags, "__builtin_spe_evlwhos", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOS);
11282 def_builtin (target_flags, "__builtin_spe_evlwhou", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOU);
11283 def_builtin (target_flags, "__builtin_spe_evlwhsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLAT);
11284 def_builtin (target_flags, "__builtin_spe_evlwwsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLAT);
11286 /* Predicates. */
11287 d = (struct builtin_description *) bdesc_spe_predicates;
11288 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, d++)
11290 tree type;
11292 switch (insn_data[d->icode].operand[1].mode)
11294 case V2SImode:
11295 type = int_ftype_int_v2si_v2si;
11296 break;
11297 case V2SFmode:
11298 type = int_ftype_int_v2sf_v2sf;
11299 break;
11300 default:
11301 gcc_unreachable ();
11304 def_builtin (d->mask, d->name, type, d->code);
11307 /* Evsel predicates. */
11308 d = (struct builtin_description *) bdesc_spe_evsel;
11309 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, d++)
11311 tree type;
11313 switch (insn_data[d->icode].operand[1].mode)
11315 case V2SImode:
11316 type = v2si_ftype_4_v2si;
11317 break;
11318 case V2SFmode:
11319 type = v2sf_ftype_4_v2sf;
11320 break;
11321 default:
11322 gcc_unreachable ();
11325 def_builtin (d->mask, d->name, type, d->code);
11329 static void
11330 paired_init_builtins (void)
11332 const struct builtin_description *d;
11333 size_t i;
11334 tree endlink = void_list_node;
11336 tree int_ftype_int_v2sf_v2sf
11337 = build_function_type
11338 (integer_type_node,
11339 tree_cons (NULL_TREE, integer_type_node,
11340 tree_cons (NULL_TREE, V2SF_type_node,
11341 tree_cons (NULL_TREE, V2SF_type_node,
11342 endlink))));
11343 tree pcfloat_type_node =
11344 build_pointer_type (build_qualified_type
11345 (float_type_node, TYPE_QUAL_CONST));
11347 tree v2sf_ftype_long_pcfloat = build_function_type_list (V2SF_type_node,
11348 long_integer_type_node,
11349 pcfloat_type_node,
11350 NULL_TREE);
11351 tree void_ftype_v2sf_long_pcfloat =
11352 build_function_type_list (void_type_node,
11353 V2SF_type_node,
11354 long_integer_type_node,
11355 pcfloat_type_node,
11356 NULL_TREE);
11359 def_builtin (0, "__builtin_paired_lx", v2sf_ftype_long_pcfloat,
11360 PAIRED_BUILTIN_LX);
11363 def_builtin (0, "__builtin_paired_stx", void_ftype_v2sf_long_pcfloat,
11364 PAIRED_BUILTIN_STX);
11366 /* Predicates. */
11367 d = bdesc_paired_preds;
11368 for (i = 0; i < ARRAY_SIZE (bdesc_paired_preds); ++i, d++)
11370 tree type;
11372 switch (insn_data[d->icode].operand[1].mode)
11374 case V2SFmode:
11375 type = int_ftype_int_v2sf_v2sf;
11376 break;
11377 default:
11378 gcc_unreachable ();
11381 def_builtin (d->mask, d->name, type, d->code);
11385 static void
11386 altivec_init_builtins (void)
11388 const struct builtin_description *d;
11389 const struct builtin_description_predicates *dp;
11390 size_t i;
11391 tree ftype;
11393 tree pfloat_type_node = build_pointer_type (float_type_node);
11394 tree pint_type_node = build_pointer_type (integer_type_node);
11395 tree pshort_type_node = build_pointer_type (short_integer_type_node);
11396 tree pchar_type_node = build_pointer_type (char_type_node);
11398 tree pvoid_type_node = build_pointer_type (void_type_node);
11400 tree pcfloat_type_node = build_pointer_type (build_qualified_type (float_type_node, TYPE_QUAL_CONST));
11401 tree pcint_type_node = build_pointer_type (build_qualified_type (integer_type_node, TYPE_QUAL_CONST));
11402 tree pcshort_type_node = build_pointer_type (build_qualified_type (short_integer_type_node, TYPE_QUAL_CONST));
11403 tree pcchar_type_node = build_pointer_type (build_qualified_type (char_type_node, TYPE_QUAL_CONST));
11405 tree pcvoid_type_node = build_pointer_type (build_qualified_type (void_type_node, TYPE_QUAL_CONST));
11407 tree int_ftype_opaque
11408 = build_function_type_list (integer_type_node,
11409 opaque_V4SI_type_node, NULL_TREE);
11410 tree opaque_ftype_opaque
11411 = build_function_type (integer_type_node,
11412 NULL_TREE);
11413 tree opaque_ftype_opaque_int
11414 = build_function_type_list (opaque_V4SI_type_node,
11415 opaque_V4SI_type_node, integer_type_node, NULL_TREE);
11416 tree opaque_ftype_opaque_opaque_int
11417 = build_function_type_list (opaque_V4SI_type_node,
11418 opaque_V4SI_type_node, opaque_V4SI_type_node,
11419 integer_type_node, NULL_TREE);
11420 tree int_ftype_int_opaque_opaque
11421 = build_function_type_list (integer_type_node,
11422 integer_type_node, opaque_V4SI_type_node,
11423 opaque_V4SI_type_node, NULL_TREE);
11424 tree int_ftype_int_v4si_v4si
11425 = build_function_type_list (integer_type_node,
11426 integer_type_node, V4SI_type_node,
11427 V4SI_type_node, NULL_TREE);
11428 tree v4sf_ftype_pcfloat
11429 = build_function_type_list (V4SF_type_node, pcfloat_type_node, NULL_TREE);
11430 tree void_ftype_pfloat_v4sf
11431 = build_function_type_list (void_type_node,
11432 pfloat_type_node, V4SF_type_node, NULL_TREE);
11433 tree v4si_ftype_pcint
11434 = build_function_type_list (V4SI_type_node, pcint_type_node, NULL_TREE);
11435 tree void_ftype_pint_v4si
11436 = build_function_type_list (void_type_node,
11437 pint_type_node, V4SI_type_node, NULL_TREE);
11438 tree v8hi_ftype_pcshort
11439 = build_function_type_list (V8HI_type_node, pcshort_type_node, NULL_TREE);
11440 tree void_ftype_pshort_v8hi
11441 = build_function_type_list (void_type_node,
11442 pshort_type_node, V8HI_type_node, NULL_TREE);
11443 tree v16qi_ftype_pcchar
11444 = build_function_type_list (V16QI_type_node, pcchar_type_node, NULL_TREE);
11445 tree void_ftype_pchar_v16qi
11446 = build_function_type_list (void_type_node,
11447 pchar_type_node, V16QI_type_node, NULL_TREE);
11448 tree void_ftype_v4si
11449 = build_function_type_list (void_type_node, V4SI_type_node, NULL_TREE);
11450 tree v8hi_ftype_void
11451 = build_function_type (V8HI_type_node, void_list_node);
11452 tree void_ftype_void
11453 = build_function_type (void_type_node, void_list_node);
11454 tree void_ftype_int
11455 = build_function_type_list (void_type_node, integer_type_node, NULL_TREE);
11457 tree opaque_ftype_long_pcvoid
11458 = build_function_type_list (opaque_V4SI_type_node,
11459 long_integer_type_node, pcvoid_type_node, NULL_TREE);
11460 tree v16qi_ftype_long_pcvoid
11461 = build_function_type_list (V16QI_type_node,
11462 long_integer_type_node, pcvoid_type_node, NULL_TREE);
11463 tree v8hi_ftype_long_pcvoid
11464 = build_function_type_list (V8HI_type_node,
11465 long_integer_type_node, pcvoid_type_node, NULL_TREE);
11466 tree v4si_ftype_long_pcvoid
11467 = build_function_type_list (V4SI_type_node,
11468 long_integer_type_node, pcvoid_type_node, NULL_TREE);
11470 tree void_ftype_opaque_long_pvoid
11471 = build_function_type_list (void_type_node,
11472 opaque_V4SI_type_node, long_integer_type_node,
11473 pvoid_type_node, NULL_TREE);
11474 tree void_ftype_v4si_long_pvoid
11475 = build_function_type_list (void_type_node,
11476 V4SI_type_node, long_integer_type_node,
11477 pvoid_type_node, NULL_TREE);
11478 tree void_ftype_v16qi_long_pvoid
11479 = build_function_type_list (void_type_node,
11480 V16QI_type_node, long_integer_type_node,
11481 pvoid_type_node, NULL_TREE);
11482 tree void_ftype_v8hi_long_pvoid
11483 = build_function_type_list (void_type_node,
11484 V8HI_type_node, long_integer_type_node,
11485 pvoid_type_node, NULL_TREE);
11486 tree int_ftype_int_v8hi_v8hi
11487 = build_function_type_list (integer_type_node,
11488 integer_type_node, V8HI_type_node,
11489 V8HI_type_node, NULL_TREE);
11490 tree int_ftype_int_v16qi_v16qi
11491 = build_function_type_list (integer_type_node,
11492 integer_type_node, V16QI_type_node,
11493 V16QI_type_node, NULL_TREE);
11494 tree int_ftype_int_v4sf_v4sf
11495 = build_function_type_list (integer_type_node,
11496 integer_type_node, V4SF_type_node,
11497 V4SF_type_node, NULL_TREE);
11498 tree int_ftype_int_v2df_v2df
11499 = build_function_type_list (integer_type_node,
11500 integer_type_node, V2DF_type_node,
11501 V2DF_type_node, NULL_TREE);
11502 tree v4si_ftype_v4si
11503 = build_function_type_list (V4SI_type_node, V4SI_type_node, NULL_TREE);
11504 tree v8hi_ftype_v8hi
11505 = build_function_type_list (V8HI_type_node, V8HI_type_node, NULL_TREE);
11506 tree v16qi_ftype_v16qi
11507 = build_function_type_list (V16QI_type_node, V16QI_type_node, NULL_TREE);
11508 tree v4sf_ftype_v4sf
11509 = build_function_type_list (V4SF_type_node, V4SF_type_node, NULL_TREE);
11510 tree v2df_ftype_v2df
11511 = build_function_type_list (V2DF_type_node, V2DF_type_node, NULL_TREE);
11512 tree void_ftype_pcvoid_int_int
11513 = build_function_type_list (void_type_node,
11514 pcvoid_type_node, integer_type_node,
11515 integer_type_node, NULL_TREE);
11517 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_4sf", v4sf_ftype_pcfloat,
11518 ALTIVEC_BUILTIN_LD_INTERNAL_4sf);
11519 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_4sf", void_ftype_pfloat_v4sf,
11520 ALTIVEC_BUILTIN_ST_INTERNAL_4sf);
11521 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_4si", v4si_ftype_pcint,
11522 ALTIVEC_BUILTIN_LD_INTERNAL_4si);
11523 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_4si", void_ftype_pint_v4si,
11524 ALTIVEC_BUILTIN_ST_INTERNAL_4si);
11525 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_8hi", v8hi_ftype_pcshort,
11526 ALTIVEC_BUILTIN_LD_INTERNAL_8hi);
11527 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_8hi", void_ftype_pshort_v8hi,
11528 ALTIVEC_BUILTIN_ST_INTERNAL_8hi);
11529 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_16qi", v16qi_ftype_pcchar,
11530 ALTIVEC_BUILTIN_LD_INTERNAL_16qi);
11531 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_16qi", void_ftype_pchar_v16qi,
11532 ALTIVEC_BUILTIN_ST_INTERNAL_16qi);
11533 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mtvscr", void_ftype_v4si, ALTIVEC_BUILTIN_MTVSCR);
11534 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mfvscr", v8hi_ftype_void, ALTIVEC_BUILTIN_MFVSCR);
11535 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dssall", void_ftype_void, ALTIVEC_BUILTIN_DSSALL);
11536 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dss", void_ftype_int, ALTIVEC_BUILTIN_DSS);
11537 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSL);
11538 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSR);
11539 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEBX);
11540 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEHX);
11541 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEWX);
11542 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvxl", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVXL);
11543 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVX);
11544 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVX);
11545 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvewx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVEWX);
11546 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvxl", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVXL);
11547 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvebx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVEBX);
11548 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvehx", void_ftype_v8hi_long_pvoid, ALTIVEC_BUILTIN_STVEHX);
11549 def_builtin (MASK_ALTIVEC, "__builtin_vec_ld", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LD);
11550 def_builtin (MASK_ALTIVEC, "__builtin_vec_lde", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDE);
11551 def_builtin (MASK_ALTIVEC, "__builtin_vec_ldl", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDL);
11552 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSL);
11553 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSR);
11554 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEBX);
11555 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEHX);
11556 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEWX);
11557 def_builtin (MASK_ALTIVEC, "__builtin_vec_st", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_ST);
11558 def_builtin (MASK_ALTIVEC, "__builtin_vec_ste", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STE);
11559 def_builtin (MASK_ALTIVEC, "__builtin_vec_stl", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STL);
11560 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvewx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEWX);
11561 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvebx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEBX);
11562 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvehx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEHX);
11564 if (rs6000_cpu == PROCESSOR_CELL)
11566 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvlx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVLX);
11567 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvlxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVLXL);
11568 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvrx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVRX);
11569 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvrxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVRXL);
11571 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvlx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVLX);
11572 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvlxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVLXL);
11573 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvrx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVRX);
11574 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvrxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVRXL);
11576 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvlx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVLX);
11577 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvlxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVLXL);
11578 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvrx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVRX);
11579 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvrxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVRXL);
11581 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvlx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVLX);
11582 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvlxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVLXL);
11583 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvrx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVRX);
11584 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvrxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVRXL);
11586 def_builtin (MASK_ALTIVEC, "__builtin_vec_step", int_ftype_opaque, ALTIVEC_BUILTIN_VEC_STEP);
11587 def_builtin (MASK_ALTIVEC, "__builtin_vec_splats", opaque_ftype_opaque, ALTIVEC_BUILTIN_VEC_SPLATS);
11588 def_builtin (MASK_ALTIVEC, "__builtin_vec_promote", opaque_ftype_opaque, ALTIVEC_BUILTIN_VEC_PROMOTE);
11590 def_builtin (MASK_ALTIVEC, "__builtin_vec_sld", opaque_ftype_opaque_opaque_int, ALTIVEC_BUILTIN_VEC_SLD);
11591 def_builtin (MASK_ALTIVEC, "__builtin_vec_splat", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_SPLAT);
11592 def_builtin (MASK_ALTIVEC, "__builtin_vec_extract", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_EXTRACT);
11593 def_builtin (MASK_ALTIVEC, "__builtin_vec_insert", opaque_ftype_opaque_opaque_int, ALTIVEC_BUILTIN_VEC_INSERT);
11594 def_builtin (MASK_ALTIVEC, "__builtin_vec_vspltw", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTW);
11595 def_builtin (MASK_ALTIVEC, "__builtin_vec_vsplth", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTH);
11596 def_builtin (MASK_ALTIVEC, "__builtin_vec_vspltb", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTB);
11597 def_builtin (MASK_ALTIVEC, "__builtin_vec_ctf", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTF);
11598 def_builtin (MASK_ALTIVEC, "__builtin_vec_vcfsx", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFSX);
11599 def_builtin (MASK_ALTIVEC, "__builtin_vec_vcfux", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFUX);
11600 def_builtin (MASK_ALTIVEC, "__builtin_vec_cts", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTS);
11601 def_builtin (MASK_ALTIVEC, "__builtin_vec_ctu", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTU);
11603 /* Add the DST variants. */
11604 d = bdesc_dst;
11605 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
11606 def_builtin (d->mask, d->name, void_ftype_pcvoid_int_int, d->code);
11608 /* Initialize the predicates. */
11609 dp = bdesc_altivec_preds;
11610 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
11612 enum machine_mode mode1;
11613 tree type;
11614 bool is_overloaded = ((dp->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
11615 && dp->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
11616 || (dp->code >= VSX_BUILTIN_OVERLOADED_FIRST
11617 && dp->code <= VSX_BUILTIN_OVERLOADED_LAST));
11619 if (is_overloaded)
11620 mode1 = VOIDmode;
11621 else
11622 mode1 = insn_data[dp->icode].operand[1].mode;
11624 switch (mode1)
11626 case VOIDmode:
11627 type = int_ftype_int_opaque_opaque;
11628 break;
11629 case V4SImode:
11630 type = int_ftype_int_v4si_v4si;
11631 break;
11632 case V8HImode:
11633 type = int_ftype_int_v8hi_v8hi;
11634 break;
11635 case V16QImode:
11636 type = int_ftype_int_v16qi_v16qi;
11637 break;
11638 case V4SFmode:
11639 type = int_ftype_int_v4sf_v4sf;
11640 break;
11641 case V2DFmode:
11642 type = int_ftype_int_v2df_v2df;
11643 break;
11644 default:
11645 gcc_unreachable ();
11648 def_builtin (dp->mask, dp->name, type, dp->code);
11651 /* Initialize the abs* operators. */
11652 d = bdesc_abs;
11653 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
11655 enum machine_mode mode0;
11656 tree type;
11658 mode0 = insn_data[d->icode].operand[0].mode;
11660 switch (mode0)
11662 case V4SImode:
11663 type = v4si_ftype_v4si;
11664 break;
11665 case V8HImode:
11666 type = v8hi_ftype_v8hi;
11667 break;
11668 case V16QImode:
11669 type = v16qi_ftype_v16qi;
11670 break;
11671 case V4SFmode:
11672 type = v4sf_ftype_v4sf;
11673 break;
11674 case V2DFmode:
11675 type = v2df_ftype_v2df;
11676 break;
11677 default:
11678 gcc_unreachable ();
11681 def_builtin (d->mask, d->name, type, d->code);
11684 if (TARGET_ALTIVEC)
11686 tree decl;
11688 /* Initialize target builtin that implements
11689 targetm.vectorize.builtin_mask_for_load. */
11691 decl = add_builtin_function ("__builtin_altivec_mask_for_load",
11692 v16qi_ftype_long_pcvoid,
11693 ALTIVEC_BUILTIN_MASK_FOR_LOAD,
11694 BUILT_IN_MD, NULL, NULL_TREE);
11695 TREE_READONLY (decl) = 1;
11696 /* Record the decl. Will be used by rs6000_builtin_mask_for_load. */
11697 altivec_builtin_mask_for_load = decl;
11700 /* Access to the vec_init patterns. */
11701 ftype = build_function_type_list (V4SI_type_node, integer_type_node,
11702 integer_type_node, integer_type_node,
11703 integer_type_node, NULL_TREE);
11704 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v4si", ftype,
11705 ALTIVEC_BUILTIN_VEC_INIT_V4SI);
11707 ftype = build_function_type_list (V8HI_type_node, short_integer_type_node,
11708 short_integer_type_node,
11709 short_integer_type_node,
11710 short_integer_type_node,
11711 short_integer_type_node,
11712 short_integer_type_node,
11713 short_integer_type_node,
11714 short_integer_type_node, NULL_TREE);
11715 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v8hi", ftype,
11716 ALTIVEC_BUILTIN_VEC_INIT_V8HI);
11718 ftype = build_function_type_list (V16QI_type_node, char_type_node,
11719 char_type_node, char_type_node,
11720 char_type_node, char_type_node,
11721 char_type_node, char_type_node,
11722 char_type_node, char_type_node,
11723 char_type_node, char_type_node,
11724 char_type_node, char_type_node,
11725 char_type_node, char_type_node,
11726 char_type_node, NULL_TREE);
11727 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v16qi", ftype,
11728 ALTIVEC_BUILTIN_VEC_INIT_V16QI);
11730 ftype = build_function_type_list (V4SF_type_node, float_type_node,
11731 float_type_node, float_type_node,
11732 float_type_node, NULL_TREE);
11733 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v4sf", ftype,
11734 ALTIVEC_BUILTIN_VEC_INIT_V4SF);
11736 if (TARGET_VSX)
11738 ftype = build_function_type_list (V2DF_type_node, double_type_node,
11739 double_type_node, NULL_TREE);
11740 def_builtin (MASK_VSX, "__builtin_vec_init_v2df", ftype,
11741 VSX_BUILTIN_VEC_INIT_V2DF);
11743 ftype = build_function_type_list (V2DI_type_node, intDI_type_node,
11744 intDI_type_node, NULL_TREE);
11745 def_builtin (MASK_VSX, "__builtin_vec_init_v2di", ftype,
11746 VSX_BUILTIN_VEC_INIT_V2DI);
11749 /* Access to the vec_set patterns. */
11750 ftype = build_function_type_list (V4SI_type_node, V4SI_type_node,
11751 intSI_type_node,
11752 integer_type_node, NULL_TREE);
11753 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v4si", ftype,
11754 ALTIVEC_BUILTIN_VEC_SET_V4SI);
11756 ftype = build_function_type_list (V8HI_type_node, V8HI_type_node,
11757 intHI_type_node,
11758 integer_type_node, NULL_TREE);
11759 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v8hi", ftype,
11760 ALTIVEC_BUILTIN_VEC_SET_V8HI);
11762 ftype = build_function_type_list (V16QI_type_node, V16QI_type_node,
11763 intQI_type_node,
11764 integer_type_node, NULL_TREE);
11765 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v16qi", ftype,
11766 ALTIVEC_BUILTIN_VEC_SET_V16QI);
11768 ftype = build_function_type_list (V4SF_type_node, V4SF_type_node,
11769 float_type_node,
11770 integer_type_node, NULL_TREE);
11771 def_builtin (MASK_ALTIVEC|MASK_VSX, "__builtin_vec_set_v4sf", ftype,
11772 ALTIVEC_BUILTIN_VEC_SET_V4SF);
11774 if (TARGET_VSX)
11776 ftype = build_function_type_list (V2DF_type_node, V2DF_type_node,
11777 double_type_node,
11778 integer_type_node, NULL_TREE);
11779 def_builtin (MASK_VSX, "__builtin_vec_set_v2df", ftype,
11780 VSX_BUILTIN_VEC_SET_V2DF);
11782 ftype = build_function_type_list (V2DI_type_node, V2DI_type_node,
11783 intDI_type_node,
11784 integer_type_node, NULL_TREE);
11785 def_builtin (MASK_VSX, "__builtin_vec_set_v2di", ftype,
11786 VSX_BUILTIN_VEC_SET_V2DI);
11789 /* Access to the vec_extract patterns. */
11790 ftype = build_function_type_list (intSI_type_node, V4SI_type_node,
11791 integer_type_node, NULL_TREE);
11792 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v4si", ftype,
11793 ALTIVEC_BUILTIN_VEC_EXT_V4SI);
11795 ftype = build_function_type_list (intHI_type_node, V8HI_type_node,
11796 integer_type_node, NULL_TREE);
11797 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v8hi", ftype,
11798 ALTIVEC_BUILTIN_VEC_EXT_V8HI);
11800 ftype = build_function_type_list (intQI_type_node, V16QI_type_node,
11801 integer_type_node, NULL_TREE);
11802 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v16qi", ftype,
11803 ALTIVEC_BUILTIN_VEC_EXT_V16QI);
11805 ftype = build_function_type_list (float_type_node, V4SF_type_node,
11806 integer_type_node, NULL_TREE);
11807 def_builtin (MASK_ALTIVEC|MASK_VSX, "__builtin_vec_ext_v4sf", ftype,
11808 ALTIVEC_BUILTIN_VEC_EXT_V4SF);
11810 if (TARGET_VSX)
11812 ftype = build_function_type_list (double_type_node, V2DF_type_node,
11813 integer_type_node, NULL_TREE);
11814 def_builtin (MASK_VSX, "__builtin_vec_ext_v2df", ftype,
11815 VSX_BUILTIN_VEC_EXT_V2DF);
11817 ftype = build_function_type_list (intDI_type_node, V2DI_type_node,
11818 integer_type_node, NULL_TREE);
11819 def_builtin (MASK_VSX, "__builtin_vec_ext_v2di", ftype,
11820 VSX_BUILTIN_VEC_EXT_V2DI);
11824 /* Hash function for builtin functions with up to 3 arguments and a return
11825 type. */
11826 static unsigned
11827 builtin_hash_function (const void *hash_entry)
11829 unsigned ret = 0;
11830 int i;
11831 const struct builtin_hash_struct *bh =
11832 (const struct builtin_hash_struct *) hash_entry;
11834 for (i = 0; i < 4; i++)
11836 ret = (ret * (unsigned)MAX_MACHINE_MODE) + ((unsigned)bh->mode[i]);
11837 ret = (ret * 2) + bh->uns_p[i];
11840 return ret;
11843 /* Compare builtin hash entries H1 and H2 for equivalence. */
11844 static int
11845 builtin_hash_eq (const void *h1, const void *h2)
11847 const struct builtin_hash_struct *p1 = (const struct builtin_hash_struct *) h1;
11848 const struct builtin_hash_struct *p2 = (const struct builtin_hash_struct *) h2;
11850 return ((p1->mode[0] == p2->mode[0])
11851 && (p1->mode[1] == p2->mode[1])
11852 && (p1->mode[2] == p2->mode[2])
11853 && (p1->mode[3] == p2->mode[3])
11854 && (p1->uns_p[0] == p2->uns_p[0])
11855 && (p1->uns_p[1] == p2->uns_p[1])
11856 && (p1->uns_p[2] == p2->uns_p[2])
11857 && (p1->uns_p[3] == p2->uns_p[3]));
11860 /* Map types for builtin functions with an explicit return type and up to 3
11861 arguments. Functions with fewer than 3 arguments use VOIDmode as the type
11862 of the argument. */
11863 static tree
11864 builtin_function_type (enum machine_mode mode_ret, enum machine_mode mode_arg0,
11865 enum machine_mode mode_arg1, enum machine_mode mode_arg2,
11866 enum rs6000_builtins builtin, const char *name)
11868 struct builtin_hash_struct h;
11869 struct builtin_hash_struct *h2;
11870 void **found;
11871 int num_args = 3;
11872 int i;
11873 tree ret_type = NULL_TREE;
11874 tree arg_type[3] = { NULL_TREE, NULL_TREE, NULL_TREE };
11875 tree args;
11877 /* Create builtin_hash_table. */
11878 if (builtin_hash_table == NULL)
11879 builtin_hash_table = htab_create_ggc (1500, builtin_hash_function,
11880 builtin_hash_eq, NULL);
11882 h.type = NULL_TREE;
11883 h.mode[0] = mode_ret;
11884 h.mode[1] = mode_arg0;
11885 h.mode[2] = mode_arg1;
11886 h.mode[3] = mode_arg2;
11887 h.uns_p[0] = 0;
11888 h.uns_p[1] = 0;
11889 h.uns_p[2] = 0;
11890 h.uns_p[3] = 0;
11892 /* If the builtin is a type that produces unsigned results or takes unsigned
11893 arguments, and it is returned as a decl for the vectorizer (such as
11894 widening multiplies, permute), make sure the arguments and return value
11895 are type correct. */
11896 switch (builtin)
11898 /* unsigned 2 argument functions. */
11899 case ALTIVEC_BUILTIN_VMULEUB_UNS:
11900 case ALTIVEC_BUILTIN_VMULEUH_UNS:
11901 case ALTIVEC_BUILTIN_VMULOUB_UNS:
11902 case ALTIVEC_BUILTIN_VMULOUH_UNS:
11903 h.uns_p[0] = 1;
11904 h.uns_p[1] = 1;
11905 h.uns_p[2] = 1;
11906 break;
11908 /* unsigned 3 argument functions. */
11909 case ALTIVEC_BUILTIN_VPERM_16QI_UNS:
11910 case ALTIVEC_BUILTIN_VPERM_8HI_UNS:
11911 case ALTIVEC_BUILTIN_VPERM_4SI_UNS:
11912 case ALTIVEC_BUILTIN_VPERM_2DI_UNS:
11913 case ALTIVEC_BUILTIN_VSEL_16QI_UNS:
11914 case ALTIVEC_BUILTIN_VSEL_8HI_UNS:
11915 case ALTIVEC_BUILTIN_VSEL_4SI_UNS:
11916 case ALTIVEC_BUILTIN_VSEL_2DI_UNS:
11917 case VSX_BUILTIN_VPERM_16QI_UNS:
11918 case VSX_BUILTIN_VPERM_8HI_UNS:
11919 case VSX_BUILTIN_VPERM_4SI_UNS:
11920 case VSX_BUILTIN_VPERM_2DI_UNS:
11921 case VSX_BUILTIN_XXSEL_16QI_UNS:
11922 case VSX_BUILTIN_XXSEL_8HI_UNS:
11923 case VSX_BUILTIN_XXSEL_4SI_UNS:
11924 case VSX_BUILTIN_XXSEL_2DI_UNS:
11925 h.uns_p[0] = 1;
11926 h.uns_p[1] = 1;
11927 h.uns_p[2] = 1;
11928 h.uns_p[3] = 1;
11929 break;
11931 /* signed permute functions with unsigned char mask. */
11932 case ALTIVEC_BUILTIN_VPERM_16QI:
11933 case ALTIVEC_BUILTIN_VPERM_8HI:
11934 case ALTIVEC_BUILTIN_VPERM_4SI:
11935 case ALTIVEC_BUILTIN_VPERM_4SF:
11936 case ALTIVEC_BUILTIN_VPERM_2DI:
11937 case ALTIVEC_BUILTIN_VPERM_2DF:
11938 case VSX_BUILTIN_VPERM_16QI:
11939 case VSX_BUILTIN_VPERM_8HI:
11940 case VSX_BUILTIN_VPERM_4SI:
11941 case VSX_BUILTIN_VPERM_4SF:
11942 case VSX_BUILTIN_VPERM_2DI:
11943 case VSX_BUILTIN_VPERM_2DF:
11944 h.uns_p[3] = 1;
11945 break;
11947 /* unsigned args, signed return. */
11948 case VSX_BUILTIN_XVCVUXDDP_UNS:
11949 case VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF:
11950 h.uns_p[1] = 1;
11951 break;
11953 /* signed args, unsigned return. */
11954 case VSX_BUILTIN_XVCVDPUXDS_UNS:
11955 case VECTOR_BUILTIN_FIXUNS_V4SF_V4SI:
11956 h.uns_p[0] = 1;
11957 break;
11959 default:
11960 break;
11963 /* Figure out how many args are present. */
11964 while (num_args > 0 && h.mode[num_args] == VOIDmode)
11965 num_args--;
11967 if (num_args == 0)
11968 fatal_error ("internal error: builtin function %s had no type", name);
11970 ret_type = builtin_mode_to_type[h.mode[0]][h.uns_p[0]];
11971 if (!ret_type && h.uns_p[0])
11972 ret_type = builtin_mode_to_type[h.mode[0]][0];
11974 if (!ret_type)
11975 fatal_error ("internal error: builtin function %s had an unexpected "
11976 "return type %s", name, GET_MODE_NAME (h.mode[0]));
11978 for (i = 0; i < num_args; i++)
11980 int m = (int) h.mode[i+1];
11981 int uns_p = h.uns_p[i+1];
11983 arg_type[i] = builtin_mode_to_type[m][uns_p];
11984 if (!arg_type[i] && uns_p)
11985 arg_type[i] = builtin_mode_to_type[m][0];
11987 if (!arg_type[i])
11988 fatal_error ("internal error: builtin function %s, argument %d "
11989 "had unexpected argument type %s", name, i,
11990 GET_MODE_NAME (m));
11993 found = htab_find_slot (builtin_hash_table, &h, INSERT);
11994 if (*found == NULL)
11996 h2 = GGC_NEW (struct builtin_hash_struct);
11997 *h2 = h;
11998 *found = (void *)h2;
11999 args = void_list_node;
12001 for (i = num_args - 1; i >= 0; i--)
12002 args = tree_cons (NULL_TREE, arg_type[i], args);
12004 h2->type = build_function_type (ret_type, args);
12007 return ((struct builtin_hash_struct *)(*found))->type;
12010 static void
12011 rs6000_common_init_builtins (void)
12013 const struct builtin_description *d;
12014 size_t i;
12016 tree opaque_ftype_opaque = NULL_TREE;
12017 tree opaque_ftype_opaque_opaque = NULL_TREE;
12018 tree opaque_ftype_opaque_opaque_opaque = NULL_TREE;
12019 tree v2si_ftype_qi = NULL_TREE;
12020 tree v2si_ftype_v2si_qi = NULL_TREE;
12021 tree v2si_ftype_int_qi = NULL_TREE;
12023 if (!TARGET_PAIRED_FLOAT)
12025 builtin_mode_to_type[V2SImode][0] = opaque_V2SI_type_node;
12026 builtin_mode_to_type[V2SFmode][0] = opaque_V2SF_type_node;
12029 /* Add the ternary operators. */
12030 d = bdesc_3arg;
12031 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
12033 tree type;
12034 int mask = d->mask;
12036 if ((mask != 0 && (mask & target_flags) == 0)
12037 || (mask == 0 && !TARGET_PAIRED_FLOAT))
12038 continue;
12040 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
12041 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
12042 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
12043 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
12045 if (! (type = opaque_ftype_opaque_opaque_opaque))
12046 type = opaque_ftype_opaque_opaque_opaque
12047 = build_function_type_list (opaque_V4SI_type_node,
12048 opaque_V4SI_type_node,
12049 opaque_V4SI_type_node,
12050 opaque_V4SI_type_node,
12051 NULL_TREE);
12053 else
12055 enum insn_code icode = d->icode;
12056 if (d->name == 0 || icode == CODE_FOR_nothing)
12057 continue;
12059 type = builtin_function_type (insn_data[icode].operand[0].mode,
12060 insn_data[icode].operand[1].mode,
12061 insn_data[icode].operand[2].mode,
12062 insn_data[icode].operand[3].mode,
12063 d->code, d->name);
12066 def_builtin (d->mask, d->name, type, d->code);
12069 /* Add the binary operators. */
12070 d = bdesc_2arg;
12071 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
12073 enum machine_mode mode0, mode1, mode2;
12074 tree type;
12075 int mask = d->mask;
12077 if ((mask != 0 && (mask & target_flags) == 0)
12078 || (mask == 0 && !TARGET_PAIRED_FLOAT))
12079 continue;
12081 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
12082 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
12083 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
12084 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
12086 if (! (type = opaque_ftype_opaque_opaque))
12087 type = opaque_ftype_opaque_opaque
12088 = build_function_type_list (opaque_V4SI_type_node,
12089 opaque_V4SI_type_node,
12090 opaque_V4SI_type_node,
12091 NULL_TREE);
12093 else
12095 enum insn_code icode = d->icode;
12096 if (d->name == 0 || icode == CODE_FOR_nothing)
12097 continue;
12099 mode0 = insn_data[icode].operand[0].mode;
12100 mode1 = insn_data[icode].operand[1].mode;
12101 mode2 = insn_data[icode].operand[2].mode;
12103 if (mode0 == V2SImode && mode1 == V2SImode && mode2 == QImode)
12105 if (! (type = v2si_ftype_v2si_qi))
12106 type = v2si_ftype_v2si_qi
12107 = build_function_type_list (opaque_V2SI_type_node,
12108 opaque_V2SI_type_node,
12109 char_type_node,
12110 NULL_TREE);
12113 else if (mode0 == V2SImode && GET_MODE_CLASS (mode1) == MODE_INT
12114 && mode2 == QImode)
12116 if (! (type = v2si_ftype_int_qi))
12117 type = v2si_ftype_int_qi
12118 = build_function_type_list (opaque_V2SI_type_node,
12119 integer_type_node,
12120 char_type_node,
12121 NULL_TREE);
12124 else
12125 type = builtin_function_type (mode0, mode1, mode2, VOIDmode,
12126 d->code, d->name);
12129 def_builtin (d->mask, d->name, type, d->code);
12132 /* Add the simple unary operators. */
12133 d = (struct builtin_description *) bdesc_1arg;
12134 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
12136 enum machine_mode mode0, mode1;
12137 tree type;
12138 int mask = d->mask;
12140 if ((mask != 0 && (mask & target_flags) == 0)
12141 || (mask == 0 && !TARGET_PAIRED_FLOAT))
12142 continue;
12144 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
12145 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
12146 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
12147 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
12149 if (! (type = opaque_ftype_opaque))
12150 type = opaque_ftype_opaque
12151 = build_function_type_list (opaque_V4SI_type_node,
12152 opaque_V4SI_type_node,
12153 NULL_TREE);
12155 else
12157 enum insn_code icode = d->icode;
12158 if (d->name == 0 || icode == CODE_FOR_nothing)
12159 continue;
12161 mode0 = insn_data[icode].operand[0].mode;
12162 mode1 = insn_data[icode].operand[1].mode;
12164 if (mode0 == V2SImode && mode1 == QImode)
12166 if (! (type = v2si_ftype_qi))
12167 type = v2si_ftype_qi
12168 = build_function_type_list (opaque_V2SI_type_node,
12169 char_type_node,
12170 NULL_TREE);
12173 else
12174 type = builtin_function_type (mode0, mode1, VOIDmode, VOIDmode,
12175 d->code, d->name);
12178 def_builtin (d->mask, d->name, type, d->code);
12182 static void
12183 rs6000_init_libfuncs (void)
12185 if (DEFAULT_ABI != ABI_V4 && TARGET_XCOFF
12186 && !TARGET_POWER2 && !TARGET_POWERPC)
12188 /* AIX library routines for float->int conversion. */
12189 set_conv_libfunc (sfix_optab, SImode, DFmode, "__itrunc");
12190 set_conv_libfunc (ufix_optab, SImode, DFmode, "__uitrunc");
12191 set_conv_libfunc (sfix_optab, SImode, TFmode, "_qitrunc");
12192 set_conv_libfunc (ufix_optab, SImode, TFmode, "_quitrunc");
12195 if (!TARGET_IEEEQUAD)
12196 /* AIX/Darwin/64-bit Linux quad floating point routines. */
12197 if (!TARGET_XL_COMPAT)
12199 set_optab_libfunc (add_optab, TFmode, "__gcc_qadd");
12200 set_optab_libfunc (sub_optab, TFmode, "__gcc_qsub");
12201 set_optab_libfunc (smul_optab, TFmode, "__gcc_qmul");
12202 set_optab_libfunc (sdiv_optab, TFmode, "__gcc_qdiv");
12204 if (!(TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)))
12206 set_optab_libfunc (neg_optab, TFmode, "__gcc_qneg");
12207 set_optab_libfunc (eq_optab, TFmode, "__gcc_qeq");
12208 set_optab_libfunc (ne_optab, TFmode, "__gcc_qne");
12209 set_optab_libfunc (gt_optab, TFmode, "__gcc_qgt");
12210 set_optab_libfunc (ge_optab, TFmode, "__gcc_qge");
12211 set_optab_libfunc (lt_optab, TFmode, "__gcc_qlt");
12212 set_optab_libfunc (le_optab, TFmode, "__gcc_qle");
12214 set_conv_libfunc (sext_optab, TFmode, SFmode, "__gcc_stoq");
12215 set_conv_libfunc (sext_optab, TFmode, DFmode, "__gcc_dtoq");
12216 set_conv_libfunc (trunc_optab, SFmode, TFmode, "__gcc_qtos");
12217 set_conv_libfunc (trunc_optab, DFmode, TFmode, "__gcc_qtod");
12218 set_conv_libfunc (sfix_optab, SImode, TFmode, "__gcc_qtoi");
12219 set_conv_libfunc (ufix_optab, SImode, TFmode, "__gcc_qtou");
12220 set_conv_libfunc (sfloat_optab, TFmode, SImode, "__gcc_itoq");
12221 set_conv_libfunc (ufloat_optab, TFmode, SImode, "__gcc_utoq");
12224 if (!(TARGET_HARD_FLOAT && TARGET_FPRS))
12225 set_optab_libfunc (unord_optab, TFmode, "__gcc_qunord");
12227 else
12229 set_optab_libfunc (add_optab, TFmode, "_xlqadd");
12230 set_optab_libfunc (sub_optab, TFmode, "_xlqsub");
12231 set_optab_libfunc (smul_optab, TFmode, "_xlqmul");
12232 set_optab_libfunc (sdiv_optab, TFmode, "_xlqdiv");
12234 else
12236 /* 32-bit SVR4 quad floating point routines. */
12238 set_optab_libfunc (add_optab, TFmode, "_q_add");
12239 set_optab_libfunc (sub_optab, TFmode, "_q_sub");
12240 set_optab_libfunc (neg_optab, TFmode, "_q_neg");
12241 set_optab_libfunc (smul_optab, TFmode, "_q_mul");
12242 set_optab_libfunc (sdiv_optab, TFmode, "_q_div");
12243 if (TARGET_PPC_GPOPT || TARGET_POWER2)
12244 set_optab_libfunc (sqrt_optab, TFmode, "_q_sqrt");
12246 set_optab_libfunc (eq_optab, TFmode, "_q_feq");
12247 set_optab_libfunc (ne_optab, TFmode, "_q_fne");
12248 set_optab_libfunc (gt_optab, TFmode, "_q_fgt");
12249 set_optab_libfunc (ge_optab, TFmode, "_q_fge");
12250 set_optab_libfunc (lt_optab, TFmode, "_q_flt");
12251 set_optab_libfunc (le_optab, TFmode, "_q_fle");
12253 set_conv_libfunc (sext_optab, TFmode, SFmode, "_q_stoq");
12254 set_conv_libfunc (sext_optab, TFmode, DFmode, "_q_dtoq");
12255 set_conv_libfunc (trunc_optab, SFmode, TFmode, "_q_qtos");
12256 set_conv_libfunc (trunc_optab, DFmode, TFmode, "_q_qtod");
12257 set_conv_libfunc (sfix_optab, SImode, TFmode, "_q_qtoi");
12258 set_conv_libfunc (ufix_optab, SImode, TFmode, "_q_qtou");
12259 set_conv_libfunc (sfloat_optab, TFmode, SImode, "_q_itoq");
12260 set_conv_libfunc (ufloat_optab, TFmode, SImode, "_q_utoq");
12265 /* Expand a block clear operation, and return 1 if successful. Return 0
12266 if we should let the compiler generate normal code.
12268 operands[0] is the destination
12269 operands[1] is the length
12270 operands[3] is the alignment */
12273 expand_block_clear (rtx operands[])
12275 rtx orig_dest = operands[0];
12276 rtx bytes_rtx = operands[1];
12277 rtx align_rtx = operands[3];
12278 bool constp = (GET_CODE (bytes_rtx) == CONST_INT);
12279 HOST_WIDE_INT align;
12280 HOST_WIDE_INT bytes;
12281 int offset;
12282 int clear_bytes;
12283 int clear_step;
12285 /* If this is not a fixed size move, just call memcpy */
12286 if (! constp)
12287 return 0;
12289 /* This must be a fixed size alignment */
12290 gcc_assert (GET_CODE (align_rtx) == CONST_INT);
12291 align = INTVAL (align_rtx) * BITS_PER_UNIT;
12293 /* Anything to clear? */
12294 bytes = INTVAL (bytes_rtx);
12295 if (bytes <= 0)
12296 return 1;
12298 /* Use the builtin memset after a point, to avoid huge code bloat.
12299 When optimize_size, avoid any significant code bloat; calling
12300 memset is about 4 instructions, so allow for one instruction to
12301 load zero and three to do clearing. */
12302 if (TARGET_ALTIVEC && align >= 128)
12303 clear_step = 16;
12304 else if (TARGET_POWERPC64 && align >= 32)
12305 clear_step = 8;
12306 else if (TARGET_SPE && align >= 64)
12307 clear_step = 8;
12308 else
12309 clear_step = 4;
12311 if (optimize_size && bytes > 3 * clear_step)
12312 return 0;
12313 if (! optimize_size && bytes > 8 * clear_step)
12314 return 0;
12316 for (offset = 0; bytes > 0; offset += clear_bytes, bytes -= clear_bytes)
12318 enum machine_mode mode = BLKmode;
12319 rtx dest;
12321 if (bytes >= 16 && TARGET_ALTIVEC && align >= 128)
12323 clear_bytes = 16;
12324 mode = V4SImode;
12326 else if (bytes >= 8 && TARGET_SPE && align >= 64)
12328 clear_bytes = 8;
12329 mode = V2SImode;
12331 else if (bytes >= 8 && TARGET_POWERPC64
12332 /* 64-bit loads and stores require word-aligned
12333 displacements. */
12334 && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
12336 clear_bytes = 8;
12337 mode = DImode;
12339 else if (bytes >= 4 && (align >= 32 || !STRICT_ALIGNMENT))
12340 { /* move 4 bytes */
12341 clear_bytes = 4;
12342 mode = SImode;
12344 else if (bytes >= 2 && (align >= 16 || !STRICT_ALIGNMENT))
12345 { /* move 2 bytes */
12346 clear_bytes = 2;
12347 mode = HImode;
12349 else /* move 1 byte at a time */
12351 clear_bytes = 1;
12352 mode = QImode;
12355 dest = adjust_address (orig_dest, mode, offset);
12357 emit_move_insn (dest, CONST0_RTX (mode));
12360 return 1;
12364 /* Expand a block move operation, and return 1 if successful. Return 0
12365 if we should let the compiler generate normal code.
12367 operands[0] is the destination
12368 operands[1] is the source
12369 operands[2] is the length
12370 operands[3] is the alignment */
12372 #define MAX_MOVE_REG 4
12375 expand_block_move (rtx operands[])
12377 rtx orig_dest = operands[0];
12378 rtx orig_src = operands[1];
12379 rtx bytes_rtx = operands[2];
12380 rtx align_rtx = operands[3];
12381 int constp = (GET_CODE (bytes_rtx) == CONST_INT);
12382 int align;
12383 int bytes;
12384 int offset;
12385 int move_bytes;
12386 rtx stores[MAX_MOVE_REG];
12387 int num_reg = 0;
12389 /* If this is not a fixed size move, just call memcpy */
12390 if (! constp)
12391 return 0;
12393 /* This must be a fixed size alignment */
12394 gcc_assert (GET_CODE (align_rtx) == CONST_INT);
12395 align = INTVAL (align_rtx) * BITS_PER_UNIT;
12397 /* Anything to move? */
12398 bytes = INTVAL (bytes_rtx);
12399 if (bytes <= 0)
12400 return 1;
12402 /* store_one_arg depends on expand_block_move to handle at least the size of
12403 reg_parm_stack_space. */
12404 if (bytes > (TARGET_POWERPC64 ? 64 : 32))
12405 return 0;
12407 for (offset = 0; bytes > 0; offset += move_bytes, bytes -= move_bytes)
12409 union {
12410 rtx (*movmemsi) (rtx, rtx, rtx, rtx);
12411 rtx (*mov) (rtx, rtx);
12412 } gen_func;
12413 enum machine_mode mode = BLKmode;
12414 rtx src, dest;
12416 /* Altivec first, since it will be faster than a string move
12417 when it applies, and usually not significantly larger. */
12418 if (TARGET_ALTIVEC && bytes >= 16 && align >= 128)
12420 move_bytes = 16;
12421 mode = V4SImode;
12422 gen_func.mov = gen_movv4si;
12424 else if (TARGET_SPE && bytes >= 8 && align >= 64)
12426 move_bytes = 8;
12427 mode = V2SImode;
12428 gen_func.mov = gen_movv2si;
12430 else if (TARGET_STRING
12431 && bytes > 24 /* move up to 32 bytes at a time */
12432 && ! fixed_regs[5]
12433 && ! fixed_regs[6]
12434 && ! fixed_regs[7]
12435 && ! fixed_regs[8]
12436 && ! fixed_regs[9]
12437 && ! fixed_regs[10]
12438 && ! fixed_regs[11]
12439 && ! fixed_regs[12])
12441 move_bytes = (bytes > 32) ? 32 : bytes;
12442 gen_func.movmemsi = gen_movmemsi_8reg;
12444 else if (TARGET_STRING
12445 && bytes > 16 /* move up to 24 bytes at a time */
12446 && ! fixed_regs[5]
12447 && ! fixed_regs[6]
12448 && ! fixed_regs[7]
12449 && ! fixed_regs[8]
12450 && ! fixed_regs[9]
12451 && ! fixed_regs[10])
12453 move_bytes = (bytes > 24) ? 24 : bytes;
12454 gen_func.movmemsi = gen_movmemsi_6reg;
12456 else if (TARGET_STRING
12457 && bytes > 8 /* move up to 16 bytes at a time */
12458 && ! fixed_regs[5]
12459 && ! fixed_regs[6]
12460 && ! fixed_regs[7]
12461 && ! fixed_regs[8])
12463 move_bytes = (bytes > 16) ? 16 : bytes;
12464 gen_func.movmemsi = gen_movmemsi_4reg;
12466 else if (bytes >= 8 && TARGET_POWERPC64
12467 /* 64-bit loads and stores require word-aligned
12468 displacements. */
12469 && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
12471 move_bytes = 8;
12472 mode = DImode;
12473 gen_func.mov = gen_movdi;
12475 else if (TARGET_STRING && bytes > 4 && !TARGET_POWERPC64)
12476 { /* move up to 8 bytes at a time */
12477 move_bytes = (bytes > 8) ? 8 : bytes;
12478 gen_func.movmemsi = gen_movmemsi_2reg;
12480 else if (bytes >= 4 && (align >= 32 || !STRICT_ALIGNMENT))
12481 { /* move 4 bytes */
12482 move_bytes = 4;
12483 mode = SImode;
12484 gen_func.mov = gen_movsi;
12486 else if (bytes >= 2 && (align >= 16 || !STRICT_ALIGNMENT))
12487 { /* move 2 bytes */
12488 move_bytes = 2;
12489 mode = HImode;
12490 gen_func.mov = gen_movhi;
12492 else if (TARGET_STRING && bytes > 1)
12493 { /* move up to 4 bytes at a time */
12494 move_bytes = (bytes > 4) ? 4 : bytes;
12495 gen_func.movmemsi = gen_movmemsi_1reg;
12497 else /* move 1 byte at a time */
12499 move_bytes = 1;
12500 mode = QImode;
12501 gen_func.mov = gen_movqi;
12504 src = adjust_address (orig_src, mode, offset);
12505 dest = adjust_address (orig_dest, mode, offset);
12507 if (mode != BLKmode)
12509 rtx tmp_reg = gen_reg_rtx (mode);
12511 emit_insn ((*gen_func.mov) (tmp_reg, src));
12512 stores[num_reg++] = (*gen_func.mov) (dest, tmp_reg);
12515 if (mode == BLKmode || num_reg >= MAX_MOVE_REG || bytes == move_bytes)
12517 int i;
12518 for (i = 0; i < num_reg; i++)
12519 emit_insn (stores[i]);
12520 num_reg = 0;
12523 if (mode == BLKmode)
12525 /* Move the address into scratch registers. The movmemsi
12526 patterns require zero offset. */
12527 if (!REG_P (XEXP (src, 0)))
12529 rtx src_reg = copy_addr_to_reg (XEXP (src, 0));
12530 src = replace_equiv_address (src, src_reg);
12532 set_mem_size (src, GEN_INT (move_bytes));
12534 if (!REG_P (XEXP (dest, 0)))
12536 rtx dest_reg = copy_addr_to_reg (XEXP (dest, 0));
12537 dest = replace_equiv_address (dest, dest_reg);
12539 set_mem_size (dest, GEN_INT (move_bytes));
12541 emit_insn ((*gen_func.movmemsi) (dest, src,
12542 GEN_INT (move_bytes & 31),
12543 align_rtx));
12547 return 1;
12551 /* Return a string to perform a load_multiple operation.
12552 operands[0] is the vector.
12553 operands[1] is the source address.
12554 operands[2] is the first destination register. */
12556 const char *
12557 rs6000_output_load_multiple (rtx operands[3])
12559 /* We have to handle the case where the pseudo used to contain the address
12560 is assigned to one of the output registers. */
12561 int i, j;
12562 int words = XVECLEN (operands[0], 0);
12563 rtx xop[10];
12565 if (XVECLEN (operands[0], 0) == 1)
12566 return "{l|lwz} %2,0(%1)";
12568 for (i = 0; i < words; i++)
12569 if (refers_to_regno_p (REGNO (operands[2]) + i,
12570 REGNO (operands[2]) + i + 1, operands[1], 0))
12572 if (i == words-1)
12574 xop[0] = GEN_INT (4 * (words-1));
12575 xop[1] = operands[1];
12576 xop[2] = operands[2];
12577 output_asm_insn ("{lsi|lswi} %2,%1,%0\n\t{l|lwz} %1,%0(%1)", xop);
12578 return "";
12580 else if (i == 0)
12582 xop[0] = GEN_INT (4 * (words-1));
12583 xop[1] = operands[1];
12584 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + 1);
12585 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);
12586 return "";
12588 else
12590 for (j = 0; j < words; j++)
12591 if (j != i)
12593 xop[0] = GEN_INT (j * 4);
12594 xop[1] = operands[1];
12595 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + j);
12596 output_asm_insn ("{l|lwz} %2,%0(%1)", xop);
12598 xop[0] = GEN_INT (i * 4);
12599 xop[1] = operands[1];
12600 output_asm_insn ("{l|lwz} %1,%0(%1)", xop);
12601 return "";
12605 return "{lsi|lswi} %2,%1,%N0";
12609 /* A validation routine: say whether CODE, a condition code, and MODE
12610 match. The other alternatives either don't make sense or should
12611 never be generated. */
12613 void
12614 validate_condition_mode (enum rtx_code code, enum machine_mode mode)
12616 gcc_assert ((GET_RTX_CLASS (code) == RTX_COMPARE
12617 || GET_RTX_CLASS (code) == RTX_COMM_COMPARE)
12618 && GET_MODE_CLASS (mode) == MODE_CC);
12620 /* These don't make sense. */
12621 gcc_assert ((code != GT && code != LT && code != GE && code != LE)
12622 || mode != CCUNSmode);
12624 gcc_assert ((code != GTU && code != LTU && code != GEU && code != LEU)
12625 || mode == CCUNSmode);
12627 gcc_assert (mode == CCFPmode
12628 || (code != ORDERED && code != UNORDERED
12629 && code != UNEQ && code != LTGT
12630 && code != UNGT && code != UNLT
12631 && code != UNGE && code != UNLE));
12633 /* These should never be generated except for
12634 flag_finite_math_only. */
12635 gcc_assert (mode != CCFPmode
12636 || flag_finite_math_only
12637 || (code != LE && code != GE
12638 && code != UNEQ && code != LTGT
12639 && code != UNGT && code != UNLT));
12641 /* These are invalid; the information is not there. */
12642 gcc_assert (mode != CCEQmode || code == EQ || code == NE);
12646 /* Return 1 if ANDOP is a mask that has no bits on that are not in the
12647 mask required to convert the result of a rotate insn into a shift
12648 left insn of SHIFTOP bits. Both are known to be SImode CONST_INT. */
12651 includes_lshift_p (rtx shiftop, rtx andop)
12653 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
12655 shift_mask <<= INTVAL (shiftop);
12657 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
12660 /* Similar, but for right shift. */
12663 includes_rshift_p (rtx shiftop, rtx andop)
12665 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
12667 shift_mask >>= INTVAL (shiftop);
12669 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
12672 /* Return 1 if ANDOP is a mask suitable for use with an rldic insn
12673 to perform a left shift. It must have exactly SHIFTOP least
12674 significant 0's, then one or more 1's, then zero or more 0's. */
12677 includes_rldic_lshift_p (rtx shiftop, rtx andop)
12679 if (GET_CODE (andop) == CONST_INT)
12681 HOST_WIDE_INT c, lsb, shift_mask;
12683 c = INTVAL (andop);
12684 if (c == 0 || c == ~0)
12685 return 0;
12687 shift_mask = ~0;
12688 shift_mask <<= INTVAL (shiftop);
12690 /* Find the least significant one bit. */
12691 lsb = c & -c;
12693 /* It must coincide with the LSB of the shift mask. */
12694 if (-lsb != shift_mask)
12695 return 0;
12697 /* Invert to look for the next transition (if any). */
12698 c = ~c;
12700 /* Remove the low group of ones (originally low group of zeros). */
12701 c &= -lsb;
12703 /* Again find the lsb, and check we have all 1's above. */
12704 lsb = c & -c;
12705 return c == -lsb;
12707 else if (GET_CODE (andop) == CONST_DOUBLE
12708 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
12710 HOST_WIDE_INT low, high, lsb;
12711 HOST_WIDE_INT shift_mask_low, shift_mask_high;
12713 low = CONST_DOUBLE_LOW (andop);
12714 if (HOST_BITS_PER_WIDE_INT < 64)
12715 high = CONST_DOUBLE_HIGH (andop);
12717 if ((low == 0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == 0))
12718 || (low == ~0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0)))
12719 return 0;
12721 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
12723 shift_mask_high = ~0;
12724 if (INTVAL (shiftop) > 32)
12725 shift_mask_high <<= INTVAL (shiftop) - 32;
12727 lsb = high & -high;
12729 if (-lsb != shift_mask_high || INTVAL (shiftop) < 32)
12730 return 0;
12732 high = ~high;
12733 high &= -lsb;
12735 lsb = high & -high;
12736 return high == -lsb;
12739 shift_mask_low = ~0;
12740 shift_mask_low <<= INTVAL (shiftop);
12742 lsb = low & -low;
12744 if (-lsb != shift_mask_low)
12745 return 0;
12747 if (HOST_BITS_PER_WIDE_INT < 64)
12748 high = ~high;
12749 low = ~low;
12750 low &= -lsb;
12752 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
12754 lsb = high & -high;
12755 return high == -lsb;
12758 lsb = low & -low;
12759 return low == -lsb && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0);
12761 else
12762 return 0;
12765 /* Return 1 if ANDOP is a mask suitable for use with an rldicr insn
12766 to perform a left shift. It must have SHIFTOP or more least
12767 significant 0's, with the remainder of the word 1's. */
12770 includes_rldicr_lshift_p (rtx shiftop, rtx andop)
12772 if (GET_CODE (andop) == CONST_INT)
12774 HOST_WIDE_INT c, lsb, shift_mask;
12776 shift_mask = ~0;
12777 shift_mask <<= INTVAL (shiftop);
12778 c = INTVAL (andop);
12780 /* Find the least significant one bit. */
12781 lsb = c & -c;
12783 /* It must be covered by the shift mask.
12784 This test also rejects c == 0. */
12785 if ((lsb & shift_mask) == 0)
12786 return 0;
12788 /* Check we have all 1's above the transition, and reject all 1's. */
12789 return c == -lsb && lsb != 1;
12791 else if (GET_CODE (andop) == CONST_DOUBLE
12792 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
12794 HOST_WIDE_INT low, lsb, shift_mask_low;
12796 low = CONST_DOUBLE_LOW (andop);
12798 if (HOST_BITS_PER_WIDE_INT < 64)
12800 HOST_WIDE_INT high, shift_mask_high;
12802 high = CONST_DOUBLE_HIGH (andop);
12804 if (low == 0)
12806 shift_mask_high = ~0;
12807 if (INTVAL (shiftop) > 32)
12808 shift_mask_high <<= INTVAL (shiftop) - 32;
12810 lsb = high & -high;
12812 if ((lsb & shift_mask_high) == 0)
12813 return 0;
12815 return high == -lsb;
12817 if (high != ~0)
12818 return 0;
12821 shift_mask_low = ~0;
12822 shift_mask_low <<= INTVAL (shiftop);
12824 lsb = low & -low;
12826 if ((lsb & shift_mask_low) == 0)
12827 return 0;
12829 return low == -lsb && lsb != 1;
12831 else
12832 return 0;
12835 /* Return 1 if operands will generate a valid arguments to rlwimi
12836 instruction for insert with right shift in 64-bit mode. The mask may
12837 not start on the first bit or stop on the last bit because wrap-around
12838 effects of instruction do not correspond to semantics of RTL insn. */
12841 insvdi_rshift_rlwimi_p (rtx sizeop, rtx startop, rtx shiftop)
12843 if (INTVAL (startop) > 32
12844 && INTVAL (startop) < 64
12845 && INTVAL (sizeop) > 1
12846 && INTVAL (sizeop) + INTVAL (startop) < 64
12847 && INTVAL (shiftop) > 0
12848 && INTVAL (sizeop) + INTVAL (shiftop) < 32
12849 && (64 - (INTVAL (shiftop) & 63)) >= INTVAL (sizeop))
12850 return 1;
12852 return 0;
12855 /* Return 1 if REGNO (reg1) == REGNO (reg2) - 1 making them candidates
12856 for lfq and stfq insns iff the registers are hard registers. */
12859 registers_ok_for_quad_peep (rtx reg1, rtx reg2)
12861 /* We might have been passed a SUBREG. */
12862 if (GET_CODE (reg1) != REG || GET_CODE (reg2) != REG)
12863 return 0;
12865 /* We might have been passed non floating point registers. */
12866 if (!FP_REGNO_P (REGNO (reg1))
12867 || !FP_REGNO_P (REGNO (reg2)))
12868 return 0;
12870 return (REGNO (reg1) == REGNO (reg2) - 1);
12873 /* Return 1 if addr1 and addr2 are suitable for lfq or stfq insn.
12874 addr1 and addr2 must be in consecutive memory locations
12875 (addr2 == addr1 + 8). */
12878 mems_ok_for_quad_peep (rtx mem1, rtx mem2)
12880 rtx addr1, addr2;
12881 unsigned int reg1, reg2;
12882 int offset1, offset2;
12884 /* The mems cannot be volatile. */
12885 if (MEM_VOLATILE_P (mem1) || MEM_VOLATILE_P (mem2))
12886 return 0;
12888 addr1 = XEXP (mem1, 0);
12889 addr2 = XEXP (mem2, 0);
12891 /* Extract an offset (if used) from the first addr. */
12892 if (GET_CODE (addr1) == PLUS)
12894 /* If not a REG, return zero. */
12895 if (GET_CODE (XEXP (addr1, 0)) != REG)
12896 return 0;
12897 else
12899 reg1 = REGNO (XEXP (addr1, 0));
12900 /* The offset must be constant! */
12901 if (GET_CODE (XEXP (addr1, 1)) != CONST_INT)
12902 return 0;
12903 offset1 = INTVAL (XEXP (addr1, 1));
12906 else if (GET_CODE (addr1) != REG)
12907 return 0;
12908 else
12910 reg1 = REGNO (addr1);
12911 /* This was a simple (mem (reg)) expression. Offset is 0. */
12912 offset1 = 0;
12915 /* And now for the second addr. */
12916 if (GET_CODE (addr2) == PLUS)
12918 /* If not a REG, return zero. */
12919 if (GET_CODE (XEXP (addr2, 0)) != REG)
12920 return 0;
12921 else
12923 reg2 = REGNO (XEXP (addr2, 0));
12924 /* The offset must be constant. */
12925 if (GET_CODE (XEXP (addr2, 1)) != CONST_INT)
12926 return 0;
12927 offset2 = INTVAL (XEXP (addr2, 1));
12930 else if (GET_CODE (addr2) != REG)
12931 return 0;
12932 else
12934 reg2 = REGNO (addr2);
12935 /* This was a simple (mem (reg)) expression. Offset is 0. */
12936 offset2 = 0;
12939 /* Both of these must have the same base register. */
12940 if (reg1 != reg2)
12941 return 0;
12943 /* The offset for the second addr must be 8 more than the first addr. */
12944 if (offset2 != offset1 + 8)
12945 return 0;
12947 /* All the tests passed. addr1 and addr2 are valid for lfq or stfq
12948 instructions. */
12949 return 1;
12954 rs6000_secondary_memory_needed_rtx (enum machine_mode mode)
12956 static bool eliminated = false;
12957 rtx ret;
12959 if (mode != SDmode)
12960 ret = assign_stack_local (mode, GET_MODE_SIZE (mode), 0);
12961 else
12963 rtx mem = cfun->machine->sdmode_stack_slot;
12964 gcc_assert (mem != NULL_RTX);
12966 if (!eliminated)
12968 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
12969 cfun->machine->sdmode_stack_slot = mem;
12970 eliminated = true;
12972 ret = mem;
12975 if (TARGET_DEBUG_ADDR)
12977 fprintf (stderr, "\nrs6000_secondary_memory_needed_rtx, mode %s, rtx:\n",
12978 GET_MODE_NAME (mode));
12979 if (!ret)
12980 fprintf (stderr, "\tNULL_RTX\n");
12981 else
12982 debug_rtx (ret);
12985 return ret;
12988 static tree
12989 rs6000_check_sdmode (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
12991 /* Don't walk into types. */
12992 if (*tp == NULL_TREE || *tp == error_mark_node || TYPE_P (*tp))
12994 *walk_subtrees = 0;
12995 return NULL_TREE;
12998 switch (TREE_CODE (*tp))
13000 case VAR_DECL:
13001 case PARM_DECL:
13002 case FIELD_DECL:
13003 case RESULT_DECL:
13004 case SSA_NAME:
13005 case REAL_CST:
13006 case INDIRECT_REF:
13007 case ALIGN_INDIRECT_REF:
13008 case MISALIGNED_INDIRECT_REF:
13009 case VIEW_CONVERT_EXPR:
13010 if (TYPE_MODE (TREE_TYPE (*tp)) == SDmode)
13011 return *tp;
13012 break;
13013 default:
13014 break;
13017 return NULL_TREE;
13020 enum reload_reg_type {
13021 GPR_REGISTER_TYPE,
13022 VECTOR_REGISTER_TYPE,
13023 OTHER_REGISTER_TYPE
13026 static enum reload_reg_type
13027 rs6000_reload_register_type (enum reg_class rclass)
13029 switch (rclass)
13031 case GENERAL_REGS:
13032 case BASE_REGS:
13033 return GPR_REGISTER_TYPE;
13035 case FLOAT_REGS:
13036 case ALTIVEC_REGS:
13037 case VSX_REGS:
13038 return VECTOR_REGISTER_TYPE;
13040 default:
13041 return OTHER_REGISTER_TYPE;
13045 /* Inform reload about cases where moving X with a mode MODE to a register in
13046 RCLASS requires an extra scratch or immediate register. Return the class
13047 needed for the immediate register.
13049 For VSX and Altivec, we may need a register to convert sp+offset into
13050 reg+sp. */
13052 static enum reg_class
13053 rs6000_secondary_reload (bool in_p,
13054 rtx x,
13055 enum reg_class rclass,
13056 enum machine_mode mode,
13057 secondary_reload_info *sri)
13059 enum reg_class ret = ALL_REGS;
13060 enum insn_code icode;
13061 bool default_p = false;
13063 sri->icode = CODE_FOR_nothing;
13065 /* Convert vector loads and stores into gprs to use an additional base
13066 register. */
13067 icode = rs6000_vector_reload[mode][in_p != false];
13068 if (icode != CODE_FOR_nothing)
13070 ret = NO_REGS;
13071 sri->icode = CODE_FOR_nothing;
13072 sri->extra_cost = 0;
13074 if (GET_CODE (x) == MEM)
13076 rtx addr = XEXP (x, 0);
13078 /* Loads to and stores from gprs can do reg+offset, and wouldn't need
13079 an extra register in that case, but it would need an extra
13080 register if the addressing is reg+reg or (reg+reg)&(-16). */
13081 if (rclass == GENERAL_REGS || rclass == BASE_REGS)
13083 if (!legitimate_indirect_address_p (addr, false)
13084 && !rs6000_legitimate_offset_address_p (TImode, addr, false))
13086 sri->icode = icode;
13087 /* account for splitting the loads, and converting the
13088 address from reg+reg to reg. */
13089 sri->extra_cost = (((TARGET_64BIT) ? 3 : 5)
13090 + ((GET_CODE (addr) == AND) ? 1 : 0));
13093 /* Loads to and stores from vector registers can only do reg+reg
13094 addressing. Altivec registers can also do (reg+reg)&(-16). */
13095 else if (rclass == VSX_REGS || rclass == ALTIVEC_REGS
13096 || rclass == FLOAT_REGS || rclass == NO_REGS)
13098 if (!VECTOR_MEM_ALTIVEC_P (mode)
13099 && GET_CODE (addr) == AND
13100 && GET_CODE (XEXP (addr, 1)) == CONST_INT
13101 && INTVAL (XEXP (addr, 1)) == -16
13102 && (legitimate_indirect_address_p (XEXP (addr, 0), false)
13103 || legitimate_indexed_address_p (XEXP (addr, 0), false)))
13105 sri->icode = icode;
13106 sri->extra_cost = ((GET_CODE (XEXP (addr, 0)) == PLUS)
13107 ? 2 : 1);
13109 else if (!legitimate_indirect_address_p (addr, false)
13110 && (rclass == NO_REGS
13111 || !legitimate_indexed_address_p (addr, false)))
13113 sri->icode = icode;
13114 sri->extra_cost = 1;
13116 else
13117 icode = CODE_FOR_nothing;
13119 /* Any other loads, including to pseudo registers which haven't been
13120 assigned to a register yet, default to require a scratch
13121 register. */
13122 else
13124 sri->icode = icode;
13125 sri->extra_cost = 2;
13128 else if (REG_P (x))
13130 int regno = true_regnum (x);
13132 icode = CODE_FOR_nothing;
13133 if (regno < 0 || regno >= FIRST_PSEUDO_REGISTER)
13134 default_p = true;
13135 else
13137 enum reg_class xclass = REGNO_REG_CLASS (regno);
13138 enum reload_reg_type rtype1 = rs6000_reload_register_type (rclass);
13139 enum reload_reg_type rtype2 = rs6000_reload_register_type (xclass);
13141 /* If memory is needed, use default_secondary_reload to create the
13142 stack slot. */
13143 if (rtype1 != rtype2 || rtype1 == OTHER_REGISTER_TYPE)
13144 default_p = true;
13145 else
13146 ret = NO_REGS;
13149 else
13150 default_p = true;
13152 else
13153 default_p = true;
13155 if (default_p)
13156 ret = default_secondary_reload (in_p, x, rclass, mode, sri);
13158 gcc_assert (ret != ALL_REGS);
13160 if (TARGET_DEBUG_ADDR)
13162 fprintf (stderr,
13163 "\nrs6000_secondary_reload, return %s, in_p = %s, rclass = %s, "
13164 "mode = %s",
13165 reg_class_names[ret],
13166 in_p ? "true" : "false",
13167 reg_class_names[rclass],
13168 GET_MODE_NAME (mode));
13170 if (default_p)
13171 fprintf (stderr, ", default secondary reload");
13173 if (sri->icode != CODE_FOR_nothing)
13174 fprintf (stderr, ", reload func = %s, extra cost = %d\n",
13175 insn_data[sri->icode].name, sri->extra_cost);
13176 else
13177 fprintf (stderr, "\n");
13179 debug_rtx (x);
13182 return ret;
13185 /* Fixup reload addresses for Altivec or VSX loads/stores to change SP+offset
13186 to SP+reg addressing. */
13188 void
13189 rs6000_secondary_reload_inner (rtx reg, rtx mem, rtx scratch, bool store_p)
13191 int regno = true_regnum (reg);
13192 enum machine_mode mode = GET_MODE (reg);
13193 enum reg_class rclass;
13194 rtx addr;
13195 rtx and_op2 = NULL_RTX;
13196 rtx addr_op1;
13197 rtx addr_op2;
13198 rtx scratch_or_premodify = scratch;
13199 rtx and_rtx;
13200 rtx cc_clobber;
13202 if (TARGET_DEBUG_ADDR)
13204 fprintf (stderr, "\nrs6000_secondary_reload_inner, type = %s\n",
13205 store_p ? "store" : "load");
13206 fprintf (stderr, "reg:\n");
13207 debug_rtx (reg);
13208 fprintf (stderr, "mem:\n");
13209 debug_rtx (mem);
13210 fprintf (stderr, "scratch:\n");
13211 debug_rtx (scratch);
13214 gcc_assert (regno >= 0 && regno < FIRST_PSEUDO_REGISTER);
13215 gcc_assert (GET_CODE (mem) == MEM);
13216 rclass = REGNO_REG_CLASS (regno);
13217 addr = XEXP (mem, 0);
13219 switch (rclass)
13221 /* GPRs can handle reg + small constant, all other addresses need to use
13222 the scratch register. */
13223 case GENERAL_REGS:
13224 case BASE_REGS:
13225 if (GET_CODE (addr) == AND)
13227 and_op2 = XEXP (addr, 1);
13228 addr = XEXP (addr, 0);
13231 if (GET_CODE (addr) == PRE_MODIFY)
13233 scratch_or_premodify = XEXP (addr, 0);
13234 gcc_assert (REG_P (scratch_or_premodify));
13235 gcc_assert (GET_CODE (XEXP (addr, 1)) == PLUS);
13236 addr = XEXP (addr, 1);
13239 if (GET_CODE (addr) == PLUS
13240 && (!rs6000_legitimate_offset_address_p (TImode, addr, false)
13241 || and_op2 != NULL_RTX))
13243 addr_op1 = XEXP (addr, 0);
13244 addr_op2 = XEXP (addr, 1);
13245 gcc_assert (legitimate_indirect_address_p (addr_op1, false));
13247 if (!REG_P (addr_op2)
13248 && (GET_CODE (addr_op2) != CONST_INT
13249 || !satisfies_constraint_I (addr_op2)))
13251 if (TARGET_DEBUG_ADDR)
13253 fprintf (stderr,
13254 "\nMove plus addr to register %s, mode = %s: ",
13255 rs6000_reg_names[REGNO (scratch)],
13256 GET_MODE_NAME (mode));
13257 debug_rtx (addr_op2);
13259 rs6000_emit_move (scratch, addr_op2, Pmode);
13260 addr_op2 = scratch;
13263 emit_insn (gen_rtx_SET (VOIDmode,
13264 scratch_or_premodify,
13265 gen_rtx_PLUS (Pmode,
13266 addr_op1,
13267 addr_op2)));
13269 addr = scratch_or_premodify;
13270 scratch_or_premodify = scratch;
13272 else if (!legitimate_indirect_address_p (addr, false)
13273 && !rs6000_legitimate_offset_address_p (TImode, addr, false))
13275 if (TARGET_DEBUG_ADDR)
13277 fprintf (stderr, "\nMove addr to register %s, mode = %s: ",
13278 rs6000_reg_names[REGNO (scratch_or_premodify)],
13279 GET_MODE_NAME (mode));
13280 debug_rtx (addr);
13282 rs6000_emit_move (scratch_or_premodify, addr, Pmode);
13283 addr = scratch_or_premodify;
13284 scratch_or_premodify = scratch;
13286 break;
13288 /* Float/Altivec registers can only handle reg+reg addressing. Move
13289 other addresses into a scratch register. */
13290 case FLOAT_REGS:
13291 case VSX_REGS:
13292 case ALTIVEC_REGS:
13294 /* With float regs, we need to handle the AND ourselves, since we can't
13295 use the Altivec instruction with an implicit AND -16. Allow scalar
13296 loads to float registers to use reg+offset even if VSX. */
13297 if (GET_CODE (addr) == AND
13298 && (rclass != ALTIVEC_REGS || GET_MODE_SIZE (mode) != 16
13299 || GET_CODE (XEXP (addr, 1)) != CONST_INT
13300 || INTVAL (XEXP (addr, 1)) != -16
13301 || !VECTOR_MEM_ALTIVEC_P (mode)))
13303 and_op2 = XEXP (addr, 1);
13304 addr = XEXP (addr, 0);
13307 /* If we aren't using a VSX load, save the PRE_MODIFY register and use it
13308 as the address later. */
13309 if (GET_CODE (addr) == PRE_MODIFY
13310 && (!VECTOR_MEM_VSX_P (mode)
13311 || and_op2 != NULL_RTX
13312 || !legitimate_indexed_address_p (XEXP (addr, 1), false)))
13314 scratch_or_premodify = XEXP (addr, 0);
13315 gcc_assert (legitimate_indirect_address_p (scratch_or_premodify,
13316 false));
13317 gcc_assert (GET_CODE (XEXP (addr, 1)) == PLUS);
13318 addr = XEXP (addr, 1);
13321 if (legitimate_indirect_address_p (addr, false) /* reg */
13322 || legitimate_indexed_address_p (addr, false) /* reg+reg */
13323 || GET_CODE (addr) == PRE_MODIFY /* VSX pre-modify */
13324 || (GET_CODE (addr) == AND /* Altivec memory */
13325 && GET_CODE (XEXP (addr, 1)) == CONST_INT
13326 && INTVAL (XEXP (addr, 1)) == -16
13327 && VECTOR_MEM_ALTIVEC_P (mode))
13328 || (rclass == FLOAT_REGS /* legacy float mem */
13329 && GET_MODE_SIZE (mode) == 8
13330 && and_op2 == NULL_RTX
13331 && scratch_or_premodify == scratch
13332 && rs6000_legitimate_offset_address_p (mode, addr, false)))
13335 else if (GET_CODE (addr) == PLUS)
13337 addr_op1 = XEXP (addr, 0);
13338 addr_op2 = XEXP (addr, 1);
13339 gcc_assert (REG_P (addr_op1));
13341 if (TARGET_DEBUG_ADDR)
13343 fprintf (stderr, "\nMove plus addr to register %s, mode = %s: ",
13344 rs6000_reg_names[REGNO (scratch)], GET_MODE_NAME (mode));
13345 debug_rtx (addr_op2);
13347 rs6000_emit_move (scratch, addr_op2, Pmode);
13348 emit_insn (gen_rtx_SET (VOIDmode,
13349 scratch_or_premodify,
13350 gen_rtx_PLUS (Pmode,
13351 addr_op1,
13352 scratch)));
13353 addr = scratch_or_premodify;
13354 scratch_or_premodify = scratch;
13357 else if (GET_CODE (addr) == SYMBOL_REF || GET_CODE (addr) == CONST
13358 || GET_CODE (addr) == CONST_INT || REG_P (addr))
13360 if (TARGET_DEBUG_ADDR)
13362 fprintf (stderr, "\nMove addr to register %s, mode = %s: ",
13363 rs6000_reg_names[REGNO (scratch_or_premodify)],
13364 GET_MODE_NAME (mode));
13365 debug_rtx (addr);
13368 rs6000_emit_move (scratch_or_premodify, addr, Pmode);
13369 addr = scratch_or_premodify;
13370 scratch_or_premodify = scratch;
13373 else
13374 gcc_unreachable ();
13376 break;
13378 default:
13379 gcc_unreachable ();
13382 /* If the original address involved a pre-modify that we couldn't use the VSX
13383 memory instruction with update, and we haven't taken care of already,
13384 store the address in the pre-modify register and use that as the
13385 address. */
13386 if (scratch_or_premodify != scratch && scratch_or_premodify != addr)
13388 emit_insn (gen_rtx_SET (VOIDmode, scratch_or_premodify, addr));
13389 addr = scratch_or_premodify;
13392 /* If the original address involved an AND -16 and we couldn't use an ALTIVEC
13393 memory instruction, recreate the AND now, including the clobber which is
13394 generated by the general ANDSI3/ANDDI3 patterns for the
13395 andi. instruction. */
13396 if (and_op2 != NULL_RTX)
13398 if (! legitimate_indirect_address_p (addr, false))
13400 emit_insn (gen_rtx_SET (VOIDmode, scratch, addr));
13401 addr = scratch;
13404 if (TARGET_DEBUG_ADDR)
13406 fprintf (stderr, "\nAnd addr to register %s, mode = %s: ",
13407 rs6000_reg_names[REGNO (scratch)], GET_MODE_NAME (mode));
13408 debug_rtx (and_op2);
13411 and_rtx = gen_rtx_SET (VOIDmode,
13412 scratch,
13413 gen_rtx_AND (Pmode,
13414 addr,
13415 and_op2));
13417 cc_clobber = gen_rtx_CLOBBER (CCmode, gen_rtx_SCRATCH (CCmode));
13418 emit_insn (gen_rtx_PARALLEL (VOIDmode,
13419 gen_rtvec (2, and_rtx, cc_clobber)));
13420 addr = scratch;
13423 /* Adjust the address if it changed. */
13424 if (addr != XEXP (mem, 0))
13426 mem = change_address (mem, mode, addr);
13427 if (TARGET_DEBUG_ADDR)
13428 fprintf (stderr, "\nrs6000_secondary_reload_inner, mem adjusted.\n");
13431 /* Now create the move. */
13432 if (store_p)
13433 emit_insn (gen_rtx_SET (VOIDmode, mem, reg));
13434 else
13435 emit_insn (gen_rtx_SET (VOIDmode, reg, mem));
13437 return;
13440 /* Target hook to return the cover classes for Integrated Register Allocator.
13441 Cover classes is a set of non-intersected register classes covering all hard
13442 registers used for register allocation purpose. Any move between two
13443 registers of a cover class should be cheaper than load or store of the
13444 registers. The value is array of register classes with LIM_REG_CLASSES used
13445 as the end marker.
13447 We need two IRA_COVER_CLASSES, one for pre-VSX, and the other for VSX to
13448 account for the Altivec and Floating registers being subsets of the VSX
13449 register set under VSX, but distinct register sets on pre-VSX machines. */
13451 static const enum reg_class *
13452 rs6000_ira_cover_classes (void)
13454 static const enum reg_class cover_pre_vsx[] = IRA_COVER_CLASSES_PRE_VSX;
13455 static const enum reg_class cover_vsx[] = IRA_COVER_CLASSES_VSX;
13457 return (TARGET_VSX) ? cover_vsx : cover_pre_vsx;
13460 /* Allocate a 64-bit stack slot to be used for copying SDmode
13461 values through if this function has any SDmode references. */
13463 static void
13464 rs6000_alloc_sdmode_stack_slot (void)
13466 tree t;
13467 basic_block bb;
13468 gimple_stmt_iterator gsi;
13470 gcc_assert (cfun->machine->sdmode_stack_slot == NULL_RTX);
13472 FOR_EACH_BB (bb)
13473 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
13475 tree ret = walk_gimple_op (gsi_stmt (gsi), rs6000_check_sdmode, NULL);
13476 if (ret)
13478 rtx stack = assign_stack_local (DDmode, GET_MODE_SIZE (DDmode), 0);
13479 cfun->machine->sdmode_stack_slot = adjust_address_nv (stack,
13480 SDmode, 0);
13481 return;
13485 /* Check for any SDmode parameters of the function. */
13486 for (t = DECL_ARGUMENTS (cfun->decl); t; t = TREE_CHAIN (t))
13488 if (TREE_TYPE (t) == error_mark_node)
13489 continue;
13491 if (TYPE_MODE (TREE_TYPE (t)) == SDmode
13492 || TYPE_MODE (DECL_ARG_TYPE (t)) == SDmode)
13494 rtx stack = assign_stack_local (DDmode, GET_MODE_SIZE (DDmode), 0);
13495 cfun->machine->sdmode_stack_slot = adjust_address_nv (stack,
13496 SDmode, 0);
13497 return;
13502 static void
13503 rs6000_instantiate_decls (void)
13505 if (cfun->machine->sdmode_stack_slot != NULL_RTX)
13506 instantiate_decl_rtl (cfun->machine->sdmode_stack_slot);
13509 /* Given an rtx X being reloaded into a reg required to be
13510 in class CLASS, return the class of reg to actually use.
13511 In general this is just CLASS; but on some machines
13512 in some cases it is preferable to use a more restrictive class.
13514 On the RS/6000, we have to return NO_REGS when we want to reload a
13515 floating-point CONST_DOUBLE to force it to be copied to memory.
13517 We also don't want to reload integer values into floating-point
13518 registers if we can at all help it. In fact, this can
13519 cause reload to die, if it tries to generate a reload of CTR
13520 into a FP register and discovers it doesn't have the memory location
13521 required.
13523 ??? Would it be a good idea to have reload do the converse, that is
13524 try to reload floating modes into FP registers if possible?
13527 static enum reg_class
13528 rs6000_preferred_reload_class (rtx x, enum reg_class rclass)
13530 enum machine_mode mode = GET_MODE (x);
13532 if (VECTOR_UNIT_VSX_P (mode)
13533 && x == CONST0_RTX (mode) && VSX_REG_CLASS_P (rclass))
13534 return rclass;
13536 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode)
13537 && (rclass == ALTIVEC_REGS || rclass == VSX_REGS)
13538 && easy_vector_constant (x, mode))
13539 return ALTIVEC_REGS;
13541 if (CONSTANT_P (x) && reg_classes_intersect_p (rclass, FLOAT_REGS))
13542 return NO_REGS;
13544 if (GET_MODE_CLASS (mode) == MODE_INT && rclass == NON_SPECIAL_REGS)
13545 return GENERAL_REGS;
13547 /* For VSX, prefer the traditional registers for DF if the address is of the
13548 form reg+offset because we can use the non-VSX loads. Prefer the Altivec
13549 registers if Altivec is handling the vector operations (i.e. V16QI, V8HI,
13550 and V4SI). */
13551 if (rclass == VSX_REGS && VECTOR_MEM_VSX_P (mode))
13553 if (mode == DFmode && GET_CODE (x) == MEM)
13555 rtx addr = XEXP (x, 0);
13557 if (legitimate_indirect_address_p (addr, false)) /* reg */
13558 return VSX_REGS;
13560 if (legitimate_indexed_address_p (addr, false)) /* reg+reg */
13561 return VSX_REGS;
13563 if (GET_CODE (addr) == PRE_MODIFY
13564 && legitimate_indexed_address_p (XEXP (addr, 0), false))
13565 return VSX_REGS;
13567 return FLOAT_REGS;
13570 if (VECTOR_UNIT_ALTIVEC_P (mode))
13571 return ALTIVEC_REGS;
13573 return rclass;
13576 return rclass;
13579 /* Debug version of rs6000_preferred_reload_class. */
13580 static enum reg_class
13581 rs6000_debug_preferred_reload_class (rtx x, enum reg_class rclass)
13583 enum reg_class ret = rs6000_preferred_reload_class (x, rclass);
13585 fprintf (stderr,
13586 "\nrs6000_preferred_reload_class, return %s, rclass = %s, "
13587 "mode = %s, x:\n",
13588 reg_class_names[ret], reg_class_names[rclass],
13589 GET_MODE_NAME (GET_MODE (x)));
13590 debug_rtx (x);
13592 return ret;
13595 /* If we are copying between FP or AltiVec registers and anything else, we need
13596 a memory location. The exception is when we are targeting ppc64 and the
13597 move to/from fpr to gpr instructions are available. Also, under VSX, you
13598 can copy vector registers from the FP register set to the Altivec register
13599 set and vice versa. */
13601 static bool
13602 rs6000_secondary_memory_needed (enum reg_class class1,
13603 enum reg_class class2,
13604 enum machine_mode mode)
13606 if (class1 == class2)
13607 return false;
13609 /* Under VSX, there are 3 register classes that values could be in (VSX_REGS,
13610 ALTIVEC_REGS, and FLOAT_REGS). We don't need to use memory to copy
13611 between these classes. But we need memory for other things that can go in
13612 FLOAT_REGS like SFmode. */
13613 if (TARGET_VSX
13614 && (VECTOR_MEM_VSX_P (mode) || VECTOR_UNIT_VSX_P (mode))
13615 && (class1 == VSX_REGS || class1 == ALTIVEC_REGS
13616 || class1 == FLOAT_REGS))
13617 return (class2 != VSX_REGS && class2 != ALTIVEC_REGS
13618 && class2 != FLOAT_REGS);
13620 if (class1 == VSX_REGS || class2 == VSX_REGS)
13621 return true;
13623 if (class1 == FLOAT_REGS
13624 && (!TARGET_MFPGPR || !TARGET_POWERPC64
13625 || ((mode != DFmode)
13626 && (mode != DDmode)
13627 && (mode != DImode))))
13628 return true;
13630 if (class2 == FLOAT_REGS
13631 && (!TARGET_MFPGPR || !TARGET_POWERPC64
13632 || ((mode != DFmode)
13633 && (mode != DDmode)
13634 && (mode != DImode))))
13635 return true;
13637 if (class1 == ALTIVEC_REGS || class2 == ALTIVEC_REGS)
13638 return true;
13640 return false;
13643 /* Debug version of rs6000_secondary_memory_needed. */
13644 static bool
13645 rs6000_debug_secondary_memory_needed (enum reg_class class1,
13646 enum reg_class class2,
13647 enum machine_mode mode)
13649 bool ret = rs6000_secondary_memory_needed (class1, class2, mode);
13651 fprintf (stderr,
13652 "rs6000_secondary_memory_needed, return: %s, class1 = %s, "
13653 "class2 = %s, mode = %s\n",
13654 ret ? "true" : "false", reg_class_names[class1],
13655 reg_class_names[class2], GET_MODE_NAME (mode));
13657 return ret;
13660 /* Return the register class of a scratch register needed to copy IN into
13661 or out of a register in RCLASS in MODE. If it can be done directly,
13662 NO_REGS is returned. */
13664 static enum reg_class
13665 rs6000_secondary_reload_class (enum reg_class rclass, enum machine_mode mode,
13666 rtx in)
13668 int regno;
13670 if (TARGET_ELF || (DEFAULT_ABI == ABI_DARWIN
13671 #if TARGET_MACHO
13672 && MACHOPIC_INDIRECT
13673 #endif
13676 /* We cannot copy a symbolic operand directly into anything
13677 other than BASE_REGS for TARGET_ELF. So indicate that a
13678 register from BASE_REGS is needed as an intermediate
13679 register.
13681 On Darwin, pic addresses require a load from memory, which
13682 needs a base register. */
13683 if (rclass != BASE_REGS
13684 && (GET_CODE (in) == SYMBOL_REF
13685 || GET_CODE (in) == HIGH
13686 || GET_CODE (in) == LABEL_REF
13687 || GET_CODE (in) == CONST))
13688 return BASE_REGS;
13691 if (GET_CODE (in) == REG)
13693 regno = REGNO (in);
13694 if (regno >= FIRST_PSEUDO_REGISTER)
13696 regno = true_regnum (in);
13697 if (regno >= FIRST_PSEUDO_REGISTER)
13698 regno = -1;
13701 else if (GET_CODE (in) == SUBREG)
13703 regno = true_regnum (in);
13704 if (regno >= FIRST_PSEUDO_REGISTER)
13705 regno = -1;
13707 else
13708 regno = -1;
13710 /* We can place anything into GENERAL_REGS and can put GENERAL_REGS
13711 into anything. */
13712 if (rclass == GENERAL_REGS || rclass == BASE_REGS
13713 || (regno >= 0 && INT_REGNO_P (regno)))
13714 return NO_REGS;
13716 /* Constants, memory, and FP registers can go into FP registers. */
13717 if ((regno == -1 || FP_REGNO_P (regno))
13718 && (rclass == FLOAT_REGS || rclass == NON_SPECIAL_REGS))
13719 return (mode != SDmode) ? NO_REGS : GENERAL_REGS;
13721 /* Memory, and FP/altivec registers can go into fp/altivec registers under
13722 VSX. */
13723 if (TARGET_VSX
13724 && (regno == -1 || VSX_REGNO_P (regno))
13725 && VSX_REG_CLASS_P (rclass))
13726 return NO_REGS;
13728 /* Memory, and AltiVec registers can go into AltiVec registers. */
13729 if ((regno == -1 || ALTIVEC_REGNO_P (regno))
13730 && rclass == ALTIVEC_REGS)
13731 return NO_REGS;
13733 /* We can copy among the CR registers. */
13734 if ((rclass == CR_REGS || rclass == CR0_REGS)
13735 && regno >= 0 && CR_REGNO_P (regno))
13736 return NO_REGS;
13738 /* Otherwise, we need GENERAL_REGS. */
13739 return GENERAL_REGS;
13742 /* Debug version of rs6000_secondary_reload_class. */
13743 static enum reg_class
13744 rs6000_debug_secondary_reload_class (enum reg_class rclass,
13745 enum machine_mode mode, rtx in)
13747 enum reg_class ret = rs6000_secondary_reload_class (rclass, mode, in);
13748 fprintf (stderr,
13749 "\nrs6000_secondary_reload_class, return %s, rclass = %s, "
13750 "mode = %s, input rtx:\n",
13751 reg_class_names[ret], reg_class_names[rclass],
13752 GET_MODE_NAME (mode));
13753 debug_rtx (in);
13755 return ret;
13758 /* Return nonzero if for CLASS a mode change from FROM to TO is invalid. */
13760 static bool
13761 rs6000_cannot_change_mode_class (enum machine_mode from,
13762 enum machine_mode to,
13763 enum reg_class rclass)
13765 unsigned from_size = GET_MODE_SIZE (from);
13766 unsigned to_size = GET_MODE_SIZE (to);
13768 if (from_size != to_size)
13770 enum reg_class xclass = (TARGET_VSX) ? VSX_REGS : FLOAT_REGS;
13771 return ((from_size < 8 || to_size < 8 || TARGET_IEEEQUAD)
13772 && reg_classes_intersect_p (xclass, rclass));
13775 if (TARGET_E500_DOUBLE
13776 && ((((to) == DFmode) + ((from) == DFmode)) == 1
13777 || (((to) == TFmode) + ((from) == TFmode)) == 1
13778 || (((to) == DDmode) + ((from) == DDmode)) == 1
13779 || (((to) == TDmode) + ((from) == TDmode)) == 1
13780 || (((to) == DImode) + ((from) == DImode)) == 1))
13781 return true;
13783 /* Since the VSX register set includes traditional floating point registers
13784 and altivec registers, just check for the size being different instead of
13785 trying to check whether the modes are vector modes. Otherwise it won't
13786 allow say DF and DI to change classes. */
13787 if (TARGET_VSX && VSX_REG_CLASS_P (rclass))
13788 return (from_size != 8 && from_size != 16);
13790 if (TARGET_ALTIVEC && rclass == ALTIVEC_REGS
13791 && (ALTIVEC_VECTOR_MODE (from) + ALTIVEC_VECTOR_MODE (to)) == 1)
13792 return true;
13794 if (TARGET_SPE && (SPE_VECTOR_MODE (from) + SPE_VECTOR_MODE (to)) == 1
13795 && reg_classes_intersect_p (GENERAL_REGS, rclass))
13796 return true;
13798 return false;
13801 /* Debug version of rs6000_cannot_change_mode_class. */
13802 static bool
13803 rs6000_debug_cannot_change_mode_class (enum machine_mode from,
13804 enum machine_mode to,
13805 enum reg_class rclass)
13807 bool ret = rs6000_cannot_change_mode_class (from, to, rclass);
13809 fprintf (stderr,
13810 "rs6000_cannot_change_mode_class, return %s, from = %s, "
13811 "to = %s, rclass = %s\n",
13812 ret ? "true" : "false",
13813 GET_MODE_NAME (from), GET_MODE_NAME (to),
13814 reg_class_names[rclass]);
13816 return ret;
13819 /* Given a comparison operation, return the bit number in CCR to test. We
13820 know this is a valid comparison.
13822 SCC_P is 1 if this is for an scc. That means that %D will have been
13823 used instead of %C, so the bits will be in different places.
13825 Return -1 if OP isn't a valid comparison for some reason. */
13828 ccr_bit (rtx op, int scc_p)
13830 enum rtx_code code = GET_CODE (op);
13831 enum machine_mode cc_mode;
13832 int cc_regnum;
13833 int base_bit;
13834 rtx reg;
13836 if (!COMPARISON_P (op))
13837 return -1;
13839 reg = XEXP (op, 0);
13841 gcc_assert (GET_CODE (reg) == REG && CR_REGNO_P (REGNO (reg)));
13843 cc_mode = GET_MODE (reg);
13844 cc_regnum = REGNO (reg);
13845 base_bit = 4 * (cc_regnum - CR0_REGNO);
13847 validate_condition_mode (code, cc_mode);
13849 /* When generating a sCOND operation, only positive conditions are
13850 allowed. */
13851 gcc_assert (!scc_p
13852 || code == EQ || code == GT || code == LT || code == UNORDERED
13853 || code == GTU || code == LTU);
13855 switch (code)
13857 case NE:
13858 return scc_p ? base_bit + 3 : base_bit + 2;
13859 case EQ:
13860 return base_bit + 2;
13861 case GT: case GTU: case UNLE:
13862 return base_bit + 1;
13863 case LT: case LTU: case UNGE:
13864 return base_bit;
13865 case ORDERED: case UNORDERED:
13866 return base_bit + 3;
13868 case GE: case GEU:
13869 /* If scc, we will have done a cror to put the bit in the
13870 unordered position. So test that bit. For integer, this is ! LT
13871 unless this is an scc insn. */
13872 return scc_p ? base_bit + 3 : base_bit;
13874 case LE: case LEU:
13875 return scc_p ? base_bit + 3 : base_bit + 1;
13877 default:
13878 gcc_unreachable ();
13882 /* Return the GOT register. */
13885 rs6000_got_register (rtx value ATTRIBUTE_UNUSED)
13887 /* The second flow pass currently (June 1999) can't update
13888 regs_ever_live without disturbing other parts of the compiler, so
13889 update it here to make the prolog/epilogue code happy. */
13890 if (!can_create_pseudo_p ()
13891 && !df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM))
13892 df_set_regs_ever_live (RS6000_PIC_OFFSET_TABLE_REGNUM, true);
13894 crtl->uses_pic_offset_table = 1;
13896 return pic_offset_table_rtx;
13899 /* Function to init struct machine_function.
13900 This will be called, via a pointer variable,
13901 from push_function_context. */
13903 static struct machine_function *
13904 rs6000_init_machine_status (void)
13906 return GGC_CNEW (machine_function);
13909 /* These macros test for integers and extract the low-order bits. */
13910 #define INT_P(X) \
13911 ((GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST_DOUBLE) \
13912 && GET_MODE (X) == VOIDmode)
13914 #define INT_LOWPART(X) \
13915 (GET_CODE (X) == CONST_INT ? INTVAL (X) : CONST_DOUBLE_LOW (X))
13918 extract_MB (rtx op)
13920 int i;
13921 unsigned long val = INT_LOWPART (op);
13923 /* If the high bit is zero, the value is the first 1 bit we find
13924 from the left. */
13925 if ((val & 0x80000000) == 0)
13927 gcc_assert (val & 0xffffffff);
13929 i = 1;
13930 while (((val <<= 1) & 0x80000000) == 0)
13931 ++i;
13932 return i;
13935 /* If the high bit is set and the low bit is not, or the mask is all
13936 1's, the value is zero. */
13937 if ((val & 1) == 0 || (val & 0xffffffff) == 0xffffffff)
13938 return 0;
13940 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
13941 from the right. */
13942 i = 31;
13943 while (((val >>= 1) & 1) != 0)
13944 --i;
13946 return i;
13950 extract_ME (rtx op)
13952 int i;
13953 unsigned long val = INT_LOWPART (op);
13955 /* If the low bit is zero, the value is the first 1 bit we find from
13956 the right. */
13957 if ((val & 1) == 0)
13959 gcc_assert (val & 0xffffffff);
13961 i = 30;
13962 while (((val >>= 1) & 1) == 0)
13963 --i;
13965 return i;
13968 /* If the low bit is set and the high bit is not, or the mask is all
13969 1's, the value is 31. */
13970 if ((val & 0x80000000) == 0 || (val & 0xffffffff) == 0xffffffff)
13971 return 31;
13973 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
13974 from the left. */
13975 i = 0;
13976 while (((val <<= 1) & 0x80000000) != 0)
13977 ++i;
13979 return i;
13982 /* Locate some local-dynamic symbol still in use by this function
13983 so that we can print its name in some tls_ld pattern. */
13985 static const char *
13986 rs6000_get_some_local_dynamic_name (void)
13988 rtx insn;
13990 if (cfun->machine->some_ld_name)
13991 return cfun->machine->some_ld_name;
13993 for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
13994 if (INSN_P (insn)
13995 && for_each_rtx (&PATTERN (insn),
13996 rs6000_get_some_local_dynamic_name_1, 0))
13997 return cfun->machine->some_ld_name;
13999 gcc_unreachable ();
14002 /* Helper function for rs6000_get_some_local_dynamic_name. */
14004 static int
14005 rs6000_get_some_local_dynamic_name_1 (rtx *px, void *data ATTRIBUTE_UNUSED)
14007 rtx x = *px;
14009 if (GET_CODE (x) == SYMBOL_REF)
14011 const char *str = XSTR (x, 0);
14012 if (SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_DYNAMIC)
14014 cfun->machine->some_ld_name = str;
14015 return 1;
14019 return 0;
14022 /* Write out a function code label. */
14024 void
14025 rs6000_output_function_entry (FILE *file, const char *fname)
14027 if (fname[0] != '.')
14029 switch (DEFAULT_ABI)
14031 default:
14032 gcc_unreachable ();
14034 case ABI_AIX:
14035 if (DOT_SYMBOLS)
14036 putc ('.', file);
14037 else
14038 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "L.");
14039 break;
14041 case ABI_V4:
14042 case ABI_DARWIN:
14043 break;
14046 if (TARGET_AIX)
14047 RS6000_OUTPUT_BASENAME (file, fname);
14048 else
14049 assemble_name (file, fname);
14052 /* Print an operand. Recognize special options, documented below. */
14054 #if TARGET_ELF
14055 #define SMALL_DATA_RELOC ((rs6000_sdata == SDATA_EABI) ? "sda21" : "sdarel")
14056 #define SMALL_DATA_REG ((rs6000_sdata == SDATA_EABI) ? 0 : 13)
14057 #else
14058 #define SMALL_DATA_RELOC "sda21"
14059 #define SMALL_DATA_REG 0
14060 #endif
14062 void
14063 print_operand (FILE *file, rtx x, int code)
14065 int i;
14066 HOST_WIDE_INT val;
14067 unsigned HOST_WIDE_INT uval;
14069 switch (code)
14071 case '.':
14072 /* Write out an instruction after the call which may be replaced
14073 with glue code by the loader. This depends on the AIX version. */
14074 asm_fprintf (file, RS6000_CALL_GLUE);
14075 return;
14077 /* %a is output_address. */
14079 case 'A':
14080 /* If X is a constant integer whose low-order 5 bits are zero,
14081 write 'l'. Otherwise, write 'r'. This is a kludge to fix a bug
14082 in the AIX assembler where "sri" with a zero shift count
14083 writes a trash instruction. */
14084 if (GET_CODE (x) == CONST_INT && (INTVAL (x) & 31) == 0)
14085 putc ('l', file);
14086 else
14087 putc ('r', file);
14088 return;
14090 case 'b':
14091 /* If constant, low-order 16 bits of constant, unsigned.
14092 Otherwise, write normally. */
14093 if (INT_P (x))
14094 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 0xffff);
14095 else
14096 print_operand (file, x, 0);
14097 return;
14099 case 'B':
14100 /* If the low-order bit is zero, write 'r'; otherwise, write 'l'
14101 for 64-bit mask direction. */
14102 putc (((INT_LOWPART (x) & 1) == 0 ? 'r' : 'l'), file);
14103 return;
14105 /* %c is output_addr_const if a CONSTANT_ADDRESS_P, otherwise
14106 output_operand. */
14108 case 'c':
14109 /* X is a CR register. Print the number of the GT bit of the CR. */
14110 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
14111 output_operand_lossage ("invalid %%c value");
14112 else
14113 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 1);
14114 return;
14116 case 'D':
14117 /* Like 'J' but get to the GT bit only. */
14118 gcc_assert (GET_CODE (x) == REG);
14120 /* Bit 1 is GT bit. */
14121 i = 4 * (REGNO (x) - CR0_REGNO) + 1;
14123 /* Add one for shift count in rlinm for scc. */
14124 fprintf (file, "%d", i + 1);
14125 return;
14127 case 'E':
14128 /* X is a CR register. Print the number of the EQ bit of the CR */
14129 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
14130 output_operand_lossage ("invalid %%E value");
14131 else
14132 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 2);
14133 return;
14135 case 'f':
14136 /* X is a CR register. Print the shift count needed to move it
14137 to the high-order four bits. */
14138 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
14139 output_operand_lossage ("invalid %%f value");
14140 else
14141 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO));
14142 return;
14144 case 'F':
14145 /* Similar, but print the count for the rotate in the opposite
14146 direction. */
14147 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
14148 output_operand_lossage ("invalid %%F value");
14149 else
14150 fprintf (file, "%d", 32 - 4 * (REGNO (x) - CR0_REGNO));
14151 return;
14153 case 'G':
14154 /* X is a constant integer. If it is negative, print "m",
14155 otherwise print "z". This is to make an aze or ame insn. */
14156 if (GET_CODE (x) != CONST_INT)
14157 output_operand_lossage ("invalid %%G value");
14158 else if (INTVAL (x) >= 0)
14159 putc ('z', file);
14160 else
14161 putc ('m', file);
14162 return;
14164 case 'h':
14165 /* If constant, output low-order five bits. Otherwise, write
14166 normally. */
14167 if (INT_P (x))
14168 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 31);
14169 else
14170 print_operand (file, x, 0);
14171 return;
14173 case 'H':
14174 /* If constant, output low-order six bits. Otherwise, write
14175 normally. */
14176 if (INT_P (x))
14177 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 63);
14178 else
14179 print_operand (file, x, 0);
14180 return;
14182 case 'I':
14183 /* Print `i' if this is a constant, else nothing. */
14184 if (INT_P (x))
14185 putc ('i', file);
14186 return;
14188 case 'j':
14189 /* Write the bit number in CCR for jump. */
14190 i = ccr_bit (x, 0);
14191 if (i == -1)
14192 output_operand_lossage ("invalid %%j code");
14193 else
14194 fprintf (file, "%d", i);
14195 return;
14197 case 'J':
14198 /* Similar, but add one for shift count in rlinm for scc and pass
14199 scc flag to `ccr_bit'. */
14200 i = ccr_bit (x, 1);
14201 if (i == -1)
14202 output_operand_lossage ("invalid %%J code");
14203 else
14204 /* If we want bit 31, write a shift count of zero, not 32. */
14205 fprintf (file, "%d", i == 31 ? 0 : i + 1);
14206 return;
14208 case 'k':
14209 /* X must be a constant. Write the 1's complement of the
14210 constant. */
14211 if (! INT_P (x))
14212 output_operand_lossage ("invalid %%k value");
14213 else
14214 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ~ INT_LOWPART (x));
14215 return;
14217 case 'K':
14218 /* X must be a symbolic constant on ELF. Write an
14219 expression suitable for an 'addi' that adds in the low 16
14220 bits of the MEM. */
14221 if (GET_CODE (x) != CONST)
14223 print_operand_address (file, x);
14224 fputs ("@l", file);
14226 else
14228 if (GET_CODE (XEXP (x, 0)) != PLUS
14229 || (GET_CODE (XEXP (XEXP (x, 0), 0)) != SYMBOL_REF
14230 && GET_CODE (XEXP (XEXP (x, 0), 0)) != LABEL_REF)
14231 || GET_CODE (XEXP (XEXP (x, 0), 1)) != CONST_INT)
14232 output_operand_lossage ("invalid %%K value");
14233 print_operand_address (file, XEXP (XEXP (x, 0), 0));
14234 fputs ("@l", file);
14235 /* For GNU as, there must be a non-alphanumeric character
14236 between 'l' and the number. The '-' is added by
14237 print_operand() already. */
14238 if (INTVAL (XEXP (XEXP (x, 0), 1)) >= 0)
14239 fputs ("+", file);
14240 print_operand (file, XEXP (XEXP (x, 0), 1), 0);
14242 return;
14244 /* %l is output_asm_label. */
14246 case 'L':
14247 /* Write second word of DImode or DFmode reference. Works on register
14248 or non-indexed memory only. */
14249 if (GET_CODE (x) == REG)
14250 fputs (reg_names[REGNO (x) + 1], file);
14251 else if (GET_CODE (x) == MEM)
14253 /* Handle possible auto-increment. Since it is pre-increment and
14254 we have already done it, we can just use an offset of word. */
14255 if (GET_CODE (XEXP (x, 0)) == PRE_INC
14256 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
14257 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
14258 UNITS_PER_WORD));
14259 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
14260 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
14261 UNITS_PER_WORD));
14262 else
14263 output_address (XEXP (adjust_address_nv (x, SImode,
14264 UNITS_PER_WORD),
14265 0));
14267 if (small_data_operand (x, GET_MODE (x)))
14268 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
14269 reg_names[SMALL_DATA_REG]);
14271 return;
14273 case 'm':
14274 /* MB value for a mask operand. */
14275 if (! mask_operand (x, SImode))
14276 output_operand_lossage ("invalid %%m value");
14278 fprintf (file, "%d", extract_MB (x));
14279 return;
14281 case 'M':
14282 /* ME value for a mask operand. */
14283 if (! mask_operand (x, SImode))
14284 output_operand_lossage ("invalid %%M value");
14286 fprintf (file, "%d", extract_ME (x));
14287 return;
14289 /* %n outputs the negative of its operand. */
14291 case 'N':
14292 /* Write the number of elements in the vector times 4. */
14293 if (GET_CODE (x) != PARALLEL)
14294 output_operand_lossage ("invalid %%N value");
14295 else
14296 fprintf (file, "%d", XVECLEN (x, 0) * 4);
14297 return;
14299 case 'O':
14300 /* Similar, but subtract 1 first. */
14301 if (GET_CODE (x) != PARALLEL)
14302 output_operand_lossage ("invalid %%O value");
14303 else
14304 fprintf (file, "%d", (XVECLEN (x, 0) - 1) * 4);
14305 return;
14307 case 'p':
14308 /* X is a CONST_INT that is a power of two. Output the logarithm. */
14309 if (! INT_P (x)
14310 || INT_LOWPART (x) < 0
14311 || (i = exact_log2 (INT_LOWPART (x))) < 0)
14312 output_operand_lossage ("invalid %%p value");
14313 else
14314 fprintf (file, "%d", i);
14315 return;
14317 case 'P':
14318 /* The operand must be an indirect memory reference. The result
14319 is the register name. */
14320 if (GET_CODE (x) != MEM || GET_CODE (XEXP (x, 0)) != REG
14321 || REGNO (XEXP (x, 0)) >= 32)
14322 output_operand_lossage ("invalid %%P value");
14323 else
14324 fputs (reg_names[REGNO (XEXP (x, 0))], file);
14325 return;
14327 case 'q':
14328 /* This outputs the logical code corresponding to a boolean
14329 expression. The expression may have one or both operands
14330 negated (if one, only the first one). For condition register
14331 logical operations, it will also treat the negated
14332 CR codes as NOTs, but not handle NOTs of them. */
14334 const char *const *t = 0;
14335 const char *s;
14336 enum rtx_code code = GET_CODE (x);
14337 static const char * const tbl[3][3] = {
14338 { "and", "andc", "nor" },
14339 { "or", "orc", "nand" },
14340 { "xor", "eqv", "xor" } };
14342 if (code == AND)
14343 t = tbl[0];
14344 else if (code == IOR)
14345 t = tbl[1];
14346 else if (code == XOR)
14347 t = tbl[2];
14348 else
14349 output_operand_lossage ("invalid %%q value");
14351 if (GET_CODE (XEXP (x, 0)) != NOT)
14352 s = t[0];
14353 else
14355 if (GET_CODE (XEXP (x, 1)) == NOT)
14356 s = t[2];
14357 else
14358 s = t[1];
14361 fputs (s, file);
14363 return;
14365 case 'Q':
14366 if (TARGET_MFCRF)
14367 fputc (',', file);
14368 /* FALLTHRU */
14369 else
14370 return;
14372 case 'R':
14373 /* X is a CR register. Print the mask for `mtcrf'. */
14374 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
14375 output_operand_lossage ("invalid %%R value");
14376 else
14377 fprintf (file, "%d", 128 >> (REGNO (x) - CR0_REGNO));
14378 return;
14380 case 's':
14381 /* Low 5 bits of 32 - value */
14382 if (! INT_P (x))
14383 output_operand_lossage ("invalid %%s value");
14384 else
14385 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (32 - INT_LOWPART (x)) & 31);
14386 return;
14388 case 'S':
14389 /* PowerPC64 mask position. All 0's is excluded.
14390 CONST_INT 32-bit mask is considered sign-extended so any
14391 transition must occur within the CONST_INT, not on the boundary. */
14392 if (! mask64_operand (x, DImode))
14393 output_operand_lossage ("invalid %%S value");
14395 uval = INT_LOWPART (x);
14397 if (uval & 1) /* Clear Left */
14399 #if HOST_BITS_PER_WIDE_INT > 64
14400 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
14401 #endif
14402 i = 64;
14404 else /* Clear Right */
14406 uval = ~uval;
14407 #if HOST_BITS_PER_WIDE_INT > 64
14408 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
14409 #endif
14410 i = 63;
14412 while (uval != 0)
14413 --i, uval >>= 1;
14414 gcc_assert (i >= 0);
14415 fprintf (file, "%d", i);
14416 return;
14418 case 't':
14419 /* Like 'J' but get to the OVERFLOW/UNORDERED bit. */
14420 gcc_assert (GET_CODE (x) == REG && GET_MODE (x) == CCmode);
14422 /* Bit 3 is OV bit. */
14423 i = 4 * (REGNO (x) - CR0_REGNO) + 3;
14425 /* If we want bit 31, write a shift count of zero, not 32. */
14426 fprintf (file, "%d", i == 31 ? 0 : i + 1);
14427 return;
14429 case 'T':
14430 /* Print the symbolic name of a branch target register. */
14431 if (GET_CODE (x) != REG || (REGNO (x) != LR_REGNO
14432 && REGNO (x) != CTR_REGNO))
14433 output_operand_lossage ("invalid %%T value");
14434 else if (REGNO (x) == LR_REGNO)
14435 fputs (TARGET_NEW_MNEMONICS ? "lr" : "r", file);
14436 else
14437 fputs ("ctr", file);
14438 return;
14440 case 'u':
14441 /* High-order 16 bits of constant for use in unsigned operand. */
14442 if (! INT_P (x))
14443 output_operand_lossage ("invalid %%u value");
14444 else
14445 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
14446 (INT_LOWPART (x) >> 16) & 0xffff);
14447 return;
14449 case 'v':
14450 /* High-order 16 bits of constant for use in signed operand. */
14451 if (! INT_P (x))
14452 output_operand_lossage ("invalid %%v value");
14453 else
14454 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
14455 (INT_LOWPART (x) >> 16) & 0xffff);
14456 return;
14458 case 'U':
14459 /* Print `u' if this has an auto-increment or auto-decrement. */
14460 if (GET_CODE (x) == MEM
14461 && (GET_CODE (XEXP (x, 0)) == PRE_INC
14462 || GET_CODE (XEXP (x, 0)) == PRE_DEC
14463 || GET_CODE (XEXP (x, 0)) == PRE_MODIFY))
14464 putc ('u', file);
14465 return;
14467 case 'V':
14468 /* Print the trap code for this operand. */
14469 switch (GET_CODE (x))
14471 case EQ:
14472 fputs ("eq", file); /* 4 */
14473 break;
14474 case NE:
14475 fputs ("ne", file); /* 24 */
14476 break;
14477 case LT:
14478 fputs ("lt", file); /* 16 */
14479 break;
14480 case LE:
14481 fputs ("le", file); /* 20 */
14482 break;
14483 case GT:
14484 fputs ("gt", file); /* 8 */
14485 break;
14486 case GE:
14487 fputs ("ge", file); /* 12 */
14488 break;
14489 case LTU:
14490 fputs ("llt", file); /* 2 */
14491 break;
14492 case LEU:
14493 fputs ("lle", file); /* 6 */
14494 break;
14495 case GTU:
14496 fputs ("lgt", file); /* 1 */
14497 break;
14498 case GEU:
14499 fputs ("lge", file); /* 5 */
14500 break;
14501 default:
14502 gcc_unreachable ();
14504 break;
14506 case 'w':
14507 /* If constant, low-order 16 bits of constant, signed. Otherwise, write
14508 normally. */
14509 if (INT_P (x))
14510 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
14511 ((INT_LOWPART (x) & 0xffff) ^ 0x8000) - 0x8000);
14512 else
14513 print_operand (file, x, 0);
14514 return;
14516 case 'W':
14517 /* MB value for a PowerPC64 rldic operand. */
14518 val = (GET_CODE (x) == CONST_INT
14519 ? INTVAL (x) : CONST_DOUBLE_HIGH (x));
14521 if (val < 0)
14522 i = -1;
14523 else
14524 for (i = 0; i < HOST_BITS_PER_WIDE_INT; i++)
14525 if ((val <<= 1) < 0)
14526 break;
14528 #if HOST_BITS_PER_WIDE_INT == 32
14529 if (GET_CODE (x) == CONST_INT && i >= 0)
14530 i += 32; /* zero-extend high-part was all 0's */
14531 else if (GET_CODE (x) == CONST_DOUBLE && i == 32)
14533 val = CONST_DOUBLE_LOW (x);
14535 gcc_assert (val);
14536 if (val < 0)
14537 --i;
14538 else
14539 for ( ; i < 64; i++)
14540 if ((val <<= 1) < 0)
14541 break;
14543 #endif
14545 fprintf (file, "%d", i + 1);
14546 return;
14548 case 'x':
14549 /* X is a FPR or Altivec register used in a VSX context. */
14550 if (GET_CODE (x) != REG || !VSX_REGNO_P (REGNO (x)))
14551 output_operand_lossage ("invalid %%x value");
14552 else
14554 int reg = REGNO (x);
14555 int vsx_reg = (FP_REGNO_P (reg)
14556 ? reg - 32
14557 : reg - FIRST_ALTIVEC_REGNO + 32);
14559 #ifdef TARGET_REGNAMES
14560 if (TARGET_REGNAMES)
14561 fprintf (file, "%%vs%d", vsx_reg);
14562 else
14563 #endif
14564 fprintf (file, "%d", vsx_reg);
14566 return;
14568 case 'X':
14569 if (GET_CODE (x) == MEM
14570 && (legitimate_indexed_address_p (XEXP (x, 0), 0)
14571 || (GET_CODE (XEXP (x, 0)) == PRE_MODIFY
14572 && legitimate_indexed_address_p (XEXP (XEXP (x, 0), 1), 0))))
14573 putc ('x', file);
14574 return;
14576 case 'Y':
14577 /* Like 'L', for third word of TImode */
14578 if (GET_CODE (x) == REG)
14579 fputs (reg_names[REGNO (x) + 2], file);
14580 else if (GET_CODE (x) == MEM)
14582 if (GET_CODE (XEXP (x, 0)) == PRE_INC
14583 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
14584 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
14585 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
14586 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
14587 else
14588 output_address (XEXP (adjust_address_nv (x, SImode, 8), 0));
14589 if (small_data_operand (x, GET_MODE (x)))
14590 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
14591 reg_names[SMALL_DATA_REG]);
14593 return;
14595 case 'z':
14596 /* X is a SYMBOL_REF. Write out the name preceded by a
14597 period and without any trailing data in brackets. Used for function
14598 names. If we are configured for System V (or the embedded ABI) on
14599 the PowerPC, do not emit the period, since those systems do not use
14600 TOCs and the like. */
14601 gcc_assert (GET_CODE (x) == SYMBOL_REF);
14603 /* Mark the decl as referenced so that cgraph will output the
14604 function. */
14605 if (SYMBOL_REF_DECL (x))
14606 mark_decl_referenced (SYMBOL_REF_DECL (x));
14608 /* For macho, check to see if we need a stub. */
14609 if (TARGET_MACHO)
14611 const char *name = XSTR (x, 0);
14612 #if TARGET_MACHO
14613 if (MACHOPIC_INDIRECT
14614 && machopic_classify_symbol (x) == MACHOPIC_UNDEFINED_FUNCTION)
14615 name = machopic_indirection_name (x, /*stub_p=*/true);
14616 #endif
14617 assemble_name (file, name);
14619 else if (!DOT_SYMBOLS)
14620 assemble_name (file, XSTR (x, 0));
14621 else
14622 rs6000_output_function_entry (file, XSTR (x, 0));
14623 return;
14625 case 'Z':
14626 /* Like 'L', for last word of TImode. */
14627 if (GET_CODE (x) == REG)
14628 fputs (reg_names[REGNO (x) + 3], file);
14629 else if (GET_CODE (x) == MEM)
14631 if (GET_CODE (XEXP (x, 0)) == PRE_INC
14632 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
14633 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
14634 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
14635 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
14636 else
14637 output_address (XEXP (adjust_address_nv (x, SImode, 12), 0));
14638 if (small_data_operand (x, GET_MODE (x)))
14639 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
14640 reg_names[SMALL_DATA_REG]);
14642 return;
14644 /* Print AltiVec or SPE memory operand. */
14645 case 'y':
14647 rtx tmp;
14649 gcc_assert (GET_CODE (x) == MEM);
14651 tmp = XEXP (x, 0);
14653 /* Ugly hack because %y is overloaded. */
14654 if ((TARGET_SPE || TARGET_E500_DOUBLE)
14655 && (GET_MODE_SIZE (GET_MODE (x)) == 8
14656 || GET_MODE (x) == TFmode
14657 || GET_MODE (x) == TImode))
14659 /* Handle [reg]. */
14660 if (GET_CODE (tmp) == REG)
14662 fprintf (file, "0(%s)", reg_names[REGNO (tmp)]);
14663 break;
14665 /* Handle [reg+UIMM]. */
14666 else if (GET_CODE (tmp) == PLUS &&
14667 GET_CODE (XEXP (tmp, 1)) == CONST_INT)
14669 int x;
14671 gcc_assert (GET_CODE (XEXP (tmp, 0)) == REG);
14673 x = INTVAL (XEXP (tmp, 1));
14674 fprintf (file, "%d(%s)", x, reg_names[REGNO (XEXP (tmp, 0))]);
14675 break;
14678 /* Fall through. Must be [reg+reg]. */
14680 if (VECTOR_MEM_ALTIVEC_P (GET_MODE (x))
14681 && GET_CODE (tmp) == AND
14682 && GET_CODE (XEXP (tmp, 1)) == CONST_INT
14683 && INTVAL (XEXP (tmp, 1)) == -16)
14684 tmp = XEXP (tmp, 0);
14685 else if (VECTOR_MEM_VSX_P (GET_MODE (x))
14686 && GET_CODE (tmp) == PRE_MODIFY)
14687 tmp = XEXP (tmp, 1);
14688 if (GET_CODE (tmp) == REG)
14689 fprintf (file, "0,%s", reg_names[REGNO (tmp)]);
14690 else
14692 if (!GET_CODE (tmp) == PLUS
14693 || !REG_P (XEXP (tmp, 0))
14694 || !REG_P (XEXP (tmp, 1)))
14696 output_operand_lossage ("invalid %%y value, try using the 'Z' constraint");
14697 break;
14700 if (REGNO (XEXP (tmp, 0)) == 0)
14701 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 1)) ],
14702 reg_names[ REGNO (XEXP (tmp, 0)) ]);
14703 else
14704 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 0)) ],
14705 reg_names[ REGNO (XEXP (tmp, 1)) ]);
14707 break;
14710 case 0:
14711 if (GET_CODE (x) == REG)
14712 fprintf (file, "%s", reg_names[REGNO (x)]);
14713 else if (GET_CODE (x) == MEM)
14715 /* We need to handle PRE_INC and PRE_DEC here, since we need to
14716 know the width from the mode. */
14717 if (GET_CODE (XEXP (x, 0)) == PRE_INC)
14718 fprintf (file, "%d(%s)", GET_MODE_SIZE (GET_MODE (x)),
14719 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
14720 else if (GET_CODE (XEXP (x, 0)) == PRE_DEC)
14721 fprintf (file, "%d(%s)", - GET_MODE_SIZE (GET_MODE (x)),
14722 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
14723 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
14724 output_address (XEXP (XEXP (x, 0), 1));
14725 else
14726 output_address (XEXP (x, 0));
14728 else
14729 output_addr_const (file, x);
14730 return;
14732 case '&':
14733 assemble_name (file, rs6000_get_some_local_dynamic_name ());
14734 return;
14736 default:
14737 output_operand_lossage ("invalid %%xn code");
14741 /* Print the address of an operand. */
14743 void
14744 print_operand_address (FILE *file, rtx x)
14746 if (GET_CODE (x) == REG)
14747 fprintf (file, "0(%s)", reg_names[ REGNO (x) ]);
14748 else if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST
14749 || GET_CODE (x) == LABEL_REF)
14751 output_addr_const (file, x);
14752 if (small_data_operand (x, GET_MODE (x)))
14753 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
14754 reg_names[SMALL_DATA_REG]);
14755 else
14756 gcc_assert (!TARGET_TOC);
14758 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == REG)
14760 gcc_assert (REG_P (XEXP (x, 0)));
14761 if (REGNO (XEXP (x, 0)) == 0)
14762 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 1)) ],
14763 reg_names[ REGNO (XEXP (x, 0)) ]);
14764 else
14765 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 0)) ],
14766 reg_names[ REGNO (XEXP (x, 1)) ]);
14768 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == CONST_INT)
14769 fprintf (file, HOST_WIDE_INT_PRINT_DEC "(%s)",
14770 INTVAL (XEXP (x, 1)), reg_names[ REGNO (XEXP (x, 0)) ]);
14771 #if TARGET_ELF
14772 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
14773 && CONSTANT_P (XEXP (x, 1)))
14775 output_addr_const (file, XEXP (x, 1));
14776 fprintf (file, "@l(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
14778 #endif
14779 #if TARGET_MACHO
14780 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
14781 && CONSTANT_P (XEXP (x, 1)))
14783 fprintf (file, "lo16(");
14784 output_addr_const (file, XEXP (x, 1));
14785 fprintf (file, ")(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
14787 #endif
14788 else if (legitimate_constant_pool_address_p (x))
14790 output_addr_const (file, XEXP (x, 1));
14791 fprintf (file, "(%s)", reg_names[REGNO (XEXP (x, 0))]);
14793 else
14794 gcc_unreachable ();
14797 /* Implement OUTPUT_ADDR_CONST_EXTRA for address X. */
14799 bool
14800 rs6000_output_addr_const_extra (FILE *file, rtx x)
14802 if (GET_CODE (x) == UNSPEC)
14803 switch (XINT (x, 1))
14805 case UNSPEC_TOCREL:
14806 x = XVECEXP (x, 0, 0);
14807 gcc_assert (GET_CODE (x) == SYMBOL_REF);
14808 output_addr_const (file, x);
14809 if (!TARGET_AIX || (TARGET_ELF && TARGET_MINIMAL_TOC))
14811 putc ('-', file);
14812 assemble_name (file, toc_label_name);
14814 else if (TARGET_ELF)
14815 fputs ("@toc", file);
14816 return true;
14818 #if TARGET_MACHO
14819 case UNSPEC_MACHOPIC_OFFSET:
14820 output_addr_const (file, XVECEXP (x, 0, 0));
14821 putc ('-', file);
14822 machopic_output_function_base_name (file);
14823 return true;
14824 #endif
14826 return false;
14829 /* Target hook for assembling integer objects. The PowerPC version has
14830 to handle fixup entries for relocatable code if RELOCATABLE_NEEDS_FIXUP
14831 is defined. It also needs to handle DI-mode objects on 64-bit
14832 targets. */
14834 static bool
14835 rs6000_assemble_integer (rtx x, unsigned int size, int aligned_p)
14837 #ifdef RELOCATABLE_NEEDS_FIXUP
14838 /* Special handling for SI values. */
14839 if (RELOCATABLE_NEEDS_FIXUP && size == 4 && aligned_p)
14841 static int recurse = 0;
14843 /* For -mrelocatable, we mark all addresses that need to be fixed up
14844 in the .fixup section. */
14845 if (TARGET_RELOCATABLE
14846 && in_section != toc_section
14847 && in_section != text_section
14848 && !unlikely_text_section_p (in_section)
14849 && !recurse
14850 && GET_CODE (x) != CONST_INT
14851 && GET_CODE (x) != CONST_DOUBLE
14852 && CONSTANT_P (x))
14854 char buf[256];
14856 recurse = 1;
14857 ASM_GENERATE_INTERNAL_LABEL (buf, "LCP", fixuplabelno);
14858 fixuplabelno++;
14859 ASM_OUTPUT_LABEL (asm_out_file, buf);
14860 fprintf (asm_out_file, "\t.long\t(");
14861 output_addr_const (asm_out_file, x);
14862 fprintf (asm_out_file, ")@fixup\n");
14863 fprintf (asm_out_file, "\t.section\t\".fixup\",\"aw\"\n");
14864 ASM_OUTPUT_ALIGN (asm_out_file, 2);
14865 fprintf (asm_out_file, "\t.long\t");
14866 assemble_name (asm_out_file, buf);
14867 fprintf (asm_out_file, "\n\t.previous\n");
14868 recurse = 0;
14869 return true;
14871 /* Remove initial .'s to turn a -mcall-aixdesc function
14872 address into the address of the descriptor, not the function
14873 itself. */
14874 else if (GET_CODE (x) == SYMBOL_REF
14875 && XSTR (x, 0)[0] == '.'
14876 && DEFAULT_ABI == ABI_AIX)
14878 const char *name = XSTR (x, 0);
14879 while (*name == '.')
14880 name++;
14882 fprintf (asm_out_file, "\t.long\t%s\n", name);
14883 return true;
14886 #endif /* RELOCATABLE_NEEDS_FIXUP */
14887 return default_assemble_integer (x, size, aligned_p);
14890 #ifdef HAVE_GAS_HIDDEN
14891 /* Emit an assembler directive to set symbol visibility for DECL to
14892 VISIBILITY_TYPE. */
14894 static void
14895 rs6000_assemble_visibility (tree decl, int vis)
14897 /* Functions need to have their entry point symbol visibility set as
14898 well as their descriptor symbol visibility. */
14899 if (DEFAULT_ABI == ABI_AIX
14900 && DOT_SYMBOLS
14901 && TREE_CODE (decl) == FUNCTION_DECL)
14903 static const char * const visibility_types[] = {
14904 NULL, "internal", "hidden", "protected"
14907 const char *name, *type;
14909 name = ((* targetm.strip_name_encoding)
14910 (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))));
14911 type = visibility_types[vis];
14913 fprintf (asm_out_file, "\t.%s\t%s\n", type, name);
14914 fprintf (asm_out_file, "\t.%s\t.%s\n", type, name);
14916 else
14917 default_assemble_visibility (decl, vis);
14919 #endif
14921 enum rtx_code
14922 rs6000_reverse_condition (enum machine_mode mode, enum rtx_code code)
14924 /* Reversal of FP compares takes care -- an ordered compare
14925 becomes an unordered compare and vice versa. */
14926 if (mode == CCFPmode
14927 && (!flag_finite_math_only
14928 || code == UNLT || code == UNLE || code == UNGT || code == UNGE
14929 || code == UNEQ || code == LTGT))
14930 return reverse_condition_maybe_unordered (code);
14931 else
14932 return reverse_condition (code);
14935 /* Generate a compare for CODE. Return a brand-new rtx that
14936 represents the result of the compare. */
14938 static rtx
14939 rs6000_generate_compare (rtx cmp, enum machine_mode mode)
14941 enum machine_mode comp_mode;
14942 rtx compare_result;
14943 enum rtx_code code = GET_CODE (cmp);
14944 rtx op0 = XEXP (cmp, 0);
14945 rtx op1 = XEXP (cmp, 1);
14947 if (FLOAT_MODE_P (mode))
14948 comp_mode = CCFPmode;
14949 else if (code == GTU || code == LTU
14950 || code == GEU || code == LEU)
14951 comp_mode = CCUNSmode;
14952 else if ((code == EQ || code == NE)
14953 && GET_CODE (op0) == SUBREG
14954 && GET_CODE (op1) == SUBREG
14955 && SUBREG_PROMOTED_UNSIGNED_P (op0)
14956 && SUBREG_PROMOTED_UNSIGNED_P (op1))
14957 /* These are unsigned values, perhaps there will be a later
14958 ordering compare that can be shared with this one.
14959 Unfortunately we cannot detect the signedness of the operands
14960 for non-subregs. */
14961 comp_mode = CCUNSmode;
14962 else
14963 comp_mode = CCmode;
14965 /* First, the compare. */
14966 compare_result = gen_reg_rtx (comp_mode);
14968 /* E500 FP compare instructions on the GPRs. Yuck! */
14969 if ((!TARGET_FPRS && TARGET_HARD_FLOAT)
14970 && FLOAT_MODE_P (mode))
14972 rtx cmp, or_result, compare_result2;
14973 enum machine_mode op_mode = GET_MODE (op0);
14975 if (op_mode == VOIDmode)
14976 op_mode = GET_MODE (op1);
14978 /* The E500 FP compare instructions toggle the GT bit (CR bit 1) only.
14979 This explains the following mess. */
14981 switch (code)
14983 case EQ: case UNEQ: case NE: case LTGT:
14984 switch (op_mode)
14986 case SFmode:
14987 cmp = (flag_finite_math_only && !flag_trapping_math)
14988 ? gen_tstsfeq_gpr (compare_result, op0, op1)
14989 : gen_cmpsfeq_gpr (compare_result, op0, op1);
14990 break;
14992 case DFmode:
14993 cmp = (flag_finite_math_only && !flag_trapping_math)
14994 ? gen_tstdfeq_gpr (compare_result, op0, op1)
14995 : gen_cmpdfeq_gpr (compare_result, op0, op1);
14996 break;
14998 case TFmode:
14999 cmp = (flag_finite_math_only && !flag_trapping_math)
15000 ? gen_tsttfeq_gpr (compare_result, op0, op1)
15001 : gen_cmptfeq_gpr (compare_result, op0, op1);
15002 break;
15004 default:
15005 gcc_unreachable ();
15007 break;
15009 case GT: case GTU: case UNGT: case UNGE: case GE: case GEU:
15010 switch (op_mode)
15012 case SFmode:
15013 cmp = (flag_finite_math_only && !flag_trapping_math)
15014 ? gen_tstsfgt_gpr (compare_result, op0, op1)
15015 : gen_cmpsfgt_gpr (compare_result, op0, op1);
15016 break;
15018 case DFmode:
15019 cmp = (flag_finite_math_only && !flag_trapping_math)
15020 ? gen_tstdfgt_gpr (compare_result, op0, op1)
15021 : gen_cmpdfgt_gpr (compare_result, op0, op1);
15022 break;
15024 case TFmode:
15025 cmp = (flag_finite_math_only && !flag_trapping_math)
15026 ? gen_tsttfgt_gpr (compare_result, op0, op1)
15027 : gen_cmptfgt_gpr (compare_result, op0, op1);
15028 break;
15030 default:
15031 gcc_unreachable ();
15033 break;
15035 case LT: case LTU: case UNLT: case UNLE: case LE: case LEU:
15036 switch (op_mode)
15038 case SFmode:
15039 cmp = (flag_finite_math_only && !flag_trapping_math)
15040 ? gen_tstsflt_gpr (compare_result, op0, op1)
15041 : gen_cmpsflt_gpr (compare_result, op0, op1);
15042 break;
15044 case DFmode:
15045 cmp = (flag_finite_math_only && !flag_trapping_math)
15046 ? gen_tstdflt_gpr (compare_result, op0, op1)
15047 : gen_cmpdflt_gpr (compare_result, op0, op1);
15048 break;
15050 case TFmode:
15051 cmp = (flag_finite_math_only && !flag_trapping_math)
15052 ? gen_tsttflt_gpr (compare_result, op0, op1)
15053 : gen_cmptflt_gpr (compare_result, op0, op1);
15054 break;
15056 default:
15057 gcc_unreachable ();
15059 break;
15060 default:
15061 gcc_unreachable ();
15064 /* Synthesize LE and GE from LT/GT || EQ. */
15065 if (code == LE || code == GE || code == LEU || code == GEU)
15067 emit_insn (cmp);
15069 switch (code)
15071 case LE: code = LT; break;
15072 case GE: code = GT; break;
15073 case LEU: code = LT; break;
15074 case GEU: code = GT; break;
15075 default: gcc_unreachable ();
15078 compare_result2 = gen_reg_rtx (CCFPmode);
15080 /* Do the EQ. */
15081 switch (op_mode)
15083 case SFmode:
15084 cmp = (flag_finite_math_only && !flag_trapping_math)
15085 ? gen_tstsfeq_gpr (compare_result2, op0, op1)
15086 : gen_cmpsfeq_gpr (compare_result2, op0, op1);
15087 break;
15089 case DFmode:
15090 cmp = (flag_finite_math_only && !flag_trapping_math)
15091 ? gen_tstdfeq_gpr (compare_result2, op0, op1)
15092 : gen_cmpdfeq_gpr (compare_result2, op0, op1);
15093 break;
15095 case TFmode:
15096 cmp = (flag_finite_math_only && !flag_trapping_math)
15097 ? gen_tsttfeq_gpr (compare_result2, op0, op1)
15098 : gen_cmptfeq_gpr (compare_result2, op0, op1);
15099 break;
15101 default:
15102 gcc_unreachable ();
15104 emit_insn (cmp);
15106 /* OR them together. */
15107 or_result = gen_reg_rtx (CCFPmode);
15108 cmp = gen_e500_cr_ior_compare (or_result, compare_result,
15109 compare_result2);
15110 compare_result = or_result;
15111 code = EQ;
15113 else
15115 if (code == NE || code == LTGT)
15116 code = NE;
15117 else
15118 code = EQ;
15121 emit_insn (cmp);
15123 else
15125 /* Generate XLC-compatible TFmode compare as PARALLEL with extra
15126 CLOBBERs to match cmptf_internal2 pattern. */
15127 if (comp_mode == CCFPmode && TARGET_XL_COMPAT
15128 && GET_MODE (op0) == TFmode
15129 && !TARGET_IEEEQUAD
15130 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128)
15131 emit_insn (gen_rtx_PARALLEL (VOIDmode,
15132 gen_rtvec (9,
15133 gen_rtx_SET (VOIDmode,
15134 compare_result,
15135 gen_rtx_COMPARE (comp_mode, op0, op1)),
15136 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15137 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15138 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15139 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15140 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15141 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15142 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15143 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)))));
15144 else if (GET_CODE (op1) == UNSPEC
15145 && XINT (op1, 1) == UNSPEC_SP_TEST)
15147 rtx op1b = XVECEXP (op1, 0, 0);
15148 comp_mode = CCEQmode;
15149 compare_result = gen_reg_rtx (CCEQmode);
15150 if (TARGET_64BIT)
15151 emit_insn (gen_stack_protect_testdi (compare_result, op0, op1b));
15152 else
15153 emit_insn (gen_stack_protect_testsi (compare_result, op0, op1b));
15155 else
15156 emit_insn (gen_rtx_SET (VOIDmode, compare_result,
15157 gen_rtx_COMPARE (comp_mode, op0, op1)));
15160 /* Some kinds of FP comparisons need an OR operation;
15161 under flag_finite_math_only we don't bother. */
15162 if (FLOAT_MODE_P (mode)
15163 && !flag_finite_math_only
15164 && !(TARGET_HARD_FLOAT && !TARGET_FPRS)
15165 && (code == LE || code == GE
15166 || code == UNEQ || code == LTGT
15167 || code == UNGT || code == UNLT))
15169 enum rtx_code or1, or2;
15170 rtx or1_rtx, or2_rtx, compare2_rtx;
15171 rtx or_result = gen_reg_rtx (CCEQmode);
15173 switch (code)
15175 case LE: or1 = LT; or2 = EQ; break;
15176 case GE: or1 = GT; or2 = EQ; break;
15177 case UNEQ: or1 = UNORDERED; or2 = EQ; break;
15178 case LTGT: or1 = LT; or2 = GT; break;
15179 case UNGT: or1 = UNORDERED; or2 = GT; break;
15180 case UNLT: or1 = UNORDERED; or2 = LT; break;
15181 default: gcc_unreachable ();
15183 validate_condition_mode (or1, comp_mode);
15184 validate_condition_mode (or2, comp_mode);
15185 or1_rtx = gen_rtx_fmt_ee (or1, SImode, compare_result, const0_rtx);
15186 or2_rtx = gen_rtx_fmt_ee (or2, SImode, compare_result, const0_rtx);
15187 compare2_rtx = gen_rtx_COMPARE (CCEQmode,
15188 gen_rtx_IOR (SImode, or1_rtx, or2_rtx),
15189 const_true_rtx);
15190 emit_insn (gen_rtx_SET (VOIDmode, or_result, compare2_rtx));
15192 compare_result = or_result;
15193 code = EQ;
15196 validate_condition_mode (code, GET_MODE (compare_result));
15198 return gen_rtx_fmt_ee (code, VOIDmode, compare_result, const0_rtx);
15202 /* Emit the RTL for an sCOND pattern. */
15204 void
15205 rs6000_emit_sCOND (enum machine_mode mode, rtx operands[])
15207 rtx condition_rtx;
15208 enum machine_mode op_mode;
15209 enum rtx_code cond_code;
15210 rtx result = operands[0];
15212 condition_rtx = rs6000_generate_compare (operands[1], mode);
15213 cond_code = GET_CODE (condition_rtx);
15215 if (FLOAT_MODE_P (mode)
15216 && !TARGET_FPRS && TARGET_HARD_FLOAT)
15218 rtx t;
15220 PUT_MODE (condition_rtx, SImode);
15221 t = XEXP (condition_rtx, 0);
15223 gcc_assert (cond_code == NE || cond_code == EQ);
15225 if (cond_code == NE)
15226 emit_insn (gen_e500_flip_gt_bit (t, t));
15228 emit_insn (gen_move_from_CR_gt_bit (result, t));
15229 return;
15232 if (cond_code == NE
15233 || cond_code == GE || cond_code == LE
15234 || cond_code == GEU || cond_code == LEU
15235 || cond_code == ORDERED || cond_code == UNGE || cond_code == UNLE)
15237 rtx not_result = gen_reg_rtx (CCEQmode);
15238 rtx not_op, rev_cond_rtx;
15239 enum machine_mode cc_mode;
15241 cc_mode = GET_MODE (XEXP (condition_rtx, 0));
15243 rev_cond_rtx = gen_rtx_fmt_ee (rs6000_reverse_condition (cc_mode, cond_code),
15244 SImode, XEXP (condition_rtx, 0), const0_rtx);
15245 not_op = gen_rtx_COMPARE (CCEQmode, rev_cond_rtx, const0_rtx);
15246 emit_insn (gen_rtx_SET (VOIDmode, not_result, not_op));
15247 condition_rtx = gen_rtx_EQ (VOIDmode, not_result, const0_rtx);
15250 op_mode = GET_MODE (XEXP (operands[1], 0));
15251 if (op_mode == VOIDmode)
15252 op_mode = GET_MODE (XEXP (operands[1], 1));
15254 if (TARGET_POWERPC64 && (op_mode == DImode || FLOAT_MODE_P (mode)))
15256 PUT_MODE (condition_rtx, DImode);
15257 convert_move (result, condition_rtx, 0);
15259 else
15261 PUT_MODE (condition_rtx, SImode);
15262 emit_insn (gen_rtx_SET (VOIDmode, result, condition_rtx));
15266 /* Emit a branch of kind CODE to location LOC. */
15268 void
15269 rs6000_emit_cbranch (enum machine_mode mode, rtx operands[])
15271 rtx condition_rtx, loc_ref;
15273 condition_rtx = rs6000_generate_compare (operands[0], mode);
15274 loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands[3]);
15275 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
15276 gen_rtx_IF_THEN_ELSE (VOIDmode, condition_rtx,
15277 loc_ref, pc_rtx)));
15280 /* Return the string to output a conditional branch to LABEL, which is
15281 the operand number of the label, or -1 if the branch is really a
15282 conditional return.
15284 OP is the conditional expression. XEXP (OP, 0) is assumed to be a
15285 condition code register and its mode specifies what kind of
15286 comparison we made.
15288 REVERSED is nonzero if we should reverse the sense of the comparison.
15290 INSN is the insn. */
15292 char *
15293 output_cbranch (rtx op, const char *label, int reversed, rtx insn)
15295 static char string[64];
15296 enum rtx_code code = GET_CODE (op);
15297 rtx cc_reg = XEXP (op, 0);
15298 enum machine_mode mode = GET_MODE (cc_reg);
15299 int cc_regno = REGNO (cc_reg) - CR0_REGNO;
15300 int need_longbranch = label != NULL && get_attr_length (insn) == 8;
15301 int really_reversed = reversed ^ need_longbranch;
15302 char *s = string;
15303 const char *ccode;
15304 const char *pred;
15305 rtx note;
15307 validate_condition_mode (code, mode);
15309 /* Work out which way this really branches. We could use
15310 reverse_condition_maybe_unordered here always but this
15311 makes the resulting assembler clearer. */
15312 if (really_reversed)
15314 /* Reversal of FP compares takes care -- an ordered compare
15315 becomes an unordered compare and vice versa. */
15316 if (mode == CCFPmode)
15317 code = reverse_condition_maybe_unordered (code);
15318 else
15319 code = reverse_condition (code);
15322 if ((!TARGET_FPRS && TARGET_HARD_FLOAT) && mode == CCFPmode)
15324 /* The efscmp/tst* instructions twiddle bit 2, which maps nicely
15325 to the GT bit. */
15326 switch (code)
15328 case EQ:
15329 /* Opposite of GT. */
15330 code = GT;
15331 break;
15333 case NE:
15334 code = UNLE;
15335 break;
15337 default:
15338 gcc_unreachable ();
15342 switch (code)
15344 /* Not all of these are actually distinct opcodes, but
15345 we distinguish them for clarity of the resulting assembler. */
15346 case NE: case LTGT:
15347 ccode = "ne"; break;
15348 case EQ: case UNEQ:
15349 ccode = "eq"; break;
15350 case GE: case GEU:
15351 ccode = "ge"; break;
15352 case GT: case GTU: case UNGT:
15353 ccode = "gt"; break;
15354 case LE: case LEU:
15355 ccode = "le"; break;
15356 case LT: case LTU: case UNLT:
15357 ccode = "lt"; break;
15358 case UNORDERED: ccode = "un"; break;
15359 case ORDERED: ccode = "nu"; break;
15360 case UNGE: ccode = "nl"; break;
15361 case UNLE: ccode = "ng"; break;
15362 default:
15363 gcc_unreachable ();
15366 /* Maybe we have a guess as to how likely the branch is.
15367 The old mnemonics don't have a way to specify this information. */
15368 pred = "";
15369 note = find_reg_note (insn, REG_BR_PROB, NULL_RTX);
15370 if (note != NULL_RTX)
15372 /* PROB is the difference from 50%. */
15373 int prob = INTVAL (XEXP (note, 0)) - REG_BR_PROB_BASE / 2;
15375 /* Only hint for highly probable/improbable branches on newer
15376 cpus as static prediction overrides processor dynamic
15377 prediction. For older cpus we may as well always hint, but
15378 assume not taken for branches that are very close to 50% as a
15379 mispredicted taken branch is more expensive than a
15380 mispredicted not-taken branch. */
15381 if (rs6000_always_hint
15382 || (abs (prob) > REG_BR_PROB_BASE / 100 * 48
15383 && br_prob_note_reliable_p (note)))
15385 if (abs (prob) > REG_BR_PROB_BASE / 20
15386 && ((prob > 0) ^ need_longbranch))
15387 pred = "+";
15388 else
15389 pred = "-";
15393 if (label == NULL)
15394 s += sprintf (s, "{b%sr|b%slr%s} ", ccode, ccode, pred);
15395 else
15396 s += sprintf (s, "{b%s|b%s%s} ", ccode, ccode, pred);
15398 /* We need to escape any '%' characters in the reg_names string.
15399 Assume they'd only be the first character.... */
15400 if (reg_names[cc_regno + CR0_REGNO][0] == '%')
15401 *s++ = '%';
15402 s += sprintf (s, "%s", reg_names[cc_regno + CR0_REGNO]);
15404 if (label != NULL)
15406 /* If the branch distance was too far, we may have to use an
15407 unconditional branch to go the distance. */
15408 if (need_longbranch)
15409 s += sprintf (s, ",$+8\n\tb %s", label);
15410 else
15411 s += sprintf (s, ",%s", label);
15414 return string;
15417 /* Return the string to flip the GT bit on a CR. */
15418 char *
15419 output_e500_flip_gt_bit (rtx dst, rtx src)
15421 static char string[64];
15422 int a, b;
15424 gcc_assert (GET_CODE (dst) == REG && CR_REGNO_P (REGNO (dst))
15425 && GET_CODE (src) == REG && CR_REGNO_P (REGNO (src)));
15427 /* GT bit. */
15428 a = 4 * (REGNO (dst) - CR0_REGNO) + 1;
15429 b = 4 * (REGNO (src) - CR0_REGNO) + 1;
15431 sprintf (string, "crnot %d,%d", a, b);
15432 return string;
15435 /* Return insn for VSX or Altivec comparisons. */
15437 static rtx
15438 rs6000_emit_vector_compare_inner (enum rtx_code code, rtx op0, rtx op1)
15440 rtx mask;
15441 enum machine_mode mode = GET_MODE (op0);
15443 switch (code)
15445 default:
15446 break;
15448 case GE:
15449 if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
15450 return NULL_RTX;
15452 case EQ:
15453 case GT:
15454 case GTU:
15455 mask = gen_reg_rtx (mode);
15456 emit_insn (gen_rtx_SET (VOIDmode,
15457 mask,
15458 gen_rtx_fmt_ee (code, mode, op0, op1)));
15459 return mask;
15462 return NULL_RTX;
15465 /* Emit vector compare for operands OP0 and OP1 using code RCODE.
15466 DMODE is expected destination mode. This is a recursive function. */
15468 static rtx
15469 rs6000_emit_vector_compare (enum rtx_code rcode,
15470 rtx op0, rtx op1,
15471 enum machine_mode dmode)
15473 rtx mask;
15474 bool swap_operands = false;
15475 bool try_again = false;
15477 gcc_assert (VECTOR_UNIT_ALTIVEC_OR_VSX_P (dmode));
15478 gcc_assert (GET_MODE (op0) == GET_MODE (op1));
15480 /* See if the comparison works as is. */
15481 mask = rs6000_emit_vector_compare_inner (rcode, op0, op1);
15482 if (mask)
15483 return mask;
15485 switch (rcode)
15487 case LT:
15488 rcode = GT;
15489 swap_operands = true;
15490 try_again = true;
15491 break;
15492 case LTU:
15493 rcode = GTU;
15494 swap_operands = true;
15495 try_again = true;
15496 break;
15497 case NE:
15498 case UNLE:
15499 case UNLT:
15500 case UNGE:
15501 case UNGT:
15502 /* Invert condition and try again.
15503 e.g., A != B becomes ~(A==B). */
15505 enum rtx_code rev_code;
15506 enum insn_code nor_code;
15507 rtx mask2;
15509 rev_code = reverse_condition_maybe_unordered (rcode);
15510 if (rev_code == UNKNOWN)
15511 return NULL_RTX;
15513 nor_code = optab_handler (one_cmpl_optab, (int)dmode)->insn_code;
15514 if (nor_code == CODE_FOR_nothing)
15515 return NULL_RTX;
15517 mask2 = rs6000_emit_vector_compare (rev_code, op0, op1, dmode);
15518 if (!mask2)
15519 return NULL_RTX;
15521 mask = gen_reg_rtx (dmode);
15522 emit_insn (GEN_FCN (nor_code) (mask, mask2));
15523 return mask;
15525 break;
15526 case GE:
15527 case GEU:
15528 case LE:
15529 case LEU:
15530 /* Try GT/GTU/LT/LTU OR EQ */
15532 rtx c_rtx, eq_rtx;
15533 enum insn_code ior_code;
15534 enum rtx_code new_code;
15536 switch (rcode)
15538 case GE:
15539 new_code = GT;
15540 break;
15542 case GEU:
15543 new_code = GTU;
15544 break;
15546 case LE:
15547 new_code = LT;
15548 break;
15550 case LEU:
15551 new_code = LTU;
15552 break;
15554 default:
15555 gcc_unreachable ();
15558 ior_code = optab_handler (ior_optab, (int)dmode)->insn_code;
15559 if (ior_code == CODE_FOR_nothing)
15560 return NULL_RTX;
15562 c_rtx = rs6000_emit_vector_compare (new_code, op0, op1, dmode);
15563 if (!c_rtx)
15564 return NULL_RTX;
15566 eq_rtx = rs6000_emit_vector_compare (EQ, op0, op1, dmode);
15567 if (!eq_rtx)
15568 return NULL_RTX;
15570 mask = gen_reg_rtx (dmode);
15571 emit_insn (GEN_FCN (ior_code) (mask, c_rtx, eq_rtx));
15572 return mask;
15574 break;
15575 default:
15576 return NULL_RTX;
15579 if (try_again)
15581 if (swap_operands)
15583 rtx tmp;
15584 tmp = op0;
15585 op0 = op1;
15586 op1 = tmp;
15589 mask = rs6000_emit_vector_compare_inner (rcode, op0, op1);
15590 if (mask)
15591 return mask;
15594 /* You only get two chances. */
15595 return NULL_RTX;
15598 /* Emit vector conditional expression. DEST is destination. OP_TRUE and
15599 OP_FALSE are two VEC_COND_EXPR operands. CC_OP0 and CC_OP1 are the two
15600 operands for the relation operation COND. */
15603 rs6000_emit_vector_cond_expr (rtx dest, rtx op_true, rtx op_false,
15604 rtx cond, rtx cc_op0, rtx cc_op1)
15606 enum machine_mode dest_mode = GET_MODE (dest);
15607 enum rtx_code rcode = GET_CODE (cond);
15608 enum machine_mode cc_mode = CCmode;
15609 rtx mask;
15610 rtx cond2;
15611 rtx tmp;
15612 bool invert_move = false;
15614 if (VECTOR_UNIT_NONE_P (dest_mode))
15615 return 0;
15617 switch (rcode)
15619 /* Swap operands if we can, and fall back to doing the operation as
15620 specified, and doing a NOR to invert the test. */
15621 case NE:
15622 case UNLE:
15623 case UNLT:
15624 case UNGE:
15625 case UNGT:
15626 /* Invert condition and try again.
15627 e.g., A = (B != C) ? D : E becomes A = (B == C) ? E : D. */
15628 invert_move = true;
15629 rcode = reverse_condition_maybe_unordered (rcode);
15630 if (rcode == UNKNOWN)
15631 return 0;
15632 break;
15634 /* Mark unsigned tests with CCUNSmode. */
15635 case GTU:
15636 case GEU:
15637 case LTU:
15638 case LEU:
15639 cc_mode = CCUNSmode;
15640 break;
15642 default:
15643 break;
15646 /* Get the vector mask for the given relational operations. */
15647 mask = rs6000_emit_vector_compare (rcode, cc_op0, cc_op1, dest_mode);
15649 if (!mask)
15650 return 0;
15652 if (invert_move)
15654 tmp = op_true;
15655 op_true = op_false;
15656 op_false = tmp;
15659 cond2 = gen_rtx_fmt_ee (NE, cc_mode, mask, const0_rtx);
15660 emit_insn (gen_rtx_SET (VOIDmode,
15661 dest,
15662 gen_rtx_IF_THEN_ELSE (dest_mode,
15663 cond2,
15664 op_true,
15665 op_false)));
15666 return 1;
15669 /* Emit a conditional move: move TRUE_COND to DEST if OP of the
15670 operands of the last comparison is nonzero/true, FALSE_COND if it
15671 is zero/false. Return 0 if the hardware has no such operation. */
15674 rs6000_emit_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
15676 enum rtx_code code = GET_CODE (op);
15677 rtx op0 = XEXP (op, 0);
15678 rtx op1 = XEXP (op, 1);
15679 REAL_VALUE_TYPE c1;
15680 enum machine_mode compare_mode = GET_MODE (op0);
15681 enum machine_mode result_mode = GET_MODE (dest);
15682 rtx temp;
15683 bool is_against_zero;
15685 /* These modes should always match. */
15686 if (GET_MODE (op1) != compare_mode
15687 /* In the isel case however, we can use a compare immediate, so
15688 op1 may be a small constant. */
15689 && (!TARGET_ISEL || !short_cint_operand (op1, VOIDmode)))
15690 return 0;
15691 if (GET_MODE (true_cond) != result_mode)
15692 return 0;
15693 if (GET_MODE (false_cond) != result_mode)
15694 return 0;
15696 /* First, work out if the hardware can do this at all, or
15697 if it's too slow.... */
15698 if (!FLOAT_MODE_P (compare_mode))
15700 if (TARGET_ISEL)
15701 return rs6000_emit_int_cmove (dest, op, true_cond, false_cond);
15702 return 0;
15704 else if (TARGET_HARD_FLOAT && !TARGET_FPRS
15705 && SCALAR_FLOAT_MODE_P (compare_mode))
15706 return 0;
15708 is_against_zero = op1 == CONST0_RTX (compare_mode);
15710 /* A floating-point subtract might overflow, underflow, or produce
15711 an inexact result, thus changing the floating-point flags, so it
15712 can't be generated if we care about that. It's safe if one side
15713 of the construct is zero, since then no subtract will be
15714 generated. */
15715 if (SCALAR_FLOAT_MODE_P (compare_mode)
15716 && flag_trapping_math && ! is_against_zero)
15717 return 0;
15719 /* Eliminate half of the comparisons by switching operands, this
15720 makes the remaining code simpler. */
15721 if (code == UNLT || code == UNGT || code == UNORDERED || code == NE
15722 || code == LTGT || code == LT || code == UNLE)
15724 code = reverse_condition_maybe_unordered (code);
15725 temp = true_cond;
15726 true_cond = false_cond;
15727 false_cond = temp;
15730 /* UNEQ and LTGT take four instructions for a comparison with zero,
15731 it'll probably be faster to use a branch here too. */
15732 if (code == UNEQ && HONOR_NANS (compare_mode))
15733 return 0;
15735 if (GET_CODE (op1) == CONST_DOUBLE)
15736 REAL_VALUE_FROM_CONST_DOUBLE (c1, op1);
15738 /* We're going to try to implement comparisons by performing
15739 a subtract, then comparing against zero. Unfortunately,
15740 Inf - Inf is NaN which is not zero, and so if we don't
15741 know that the operand is finite and the comparison
15742 would treat EQ different to UNORDERED, we can't do it. */
15743 if (HONOR_INFINITIES (compare_mode)
15744 && code != GT && code != UNGE
15745 && (GET_CODE (op1) != CONST_DOUBLE || real_isinf (&c1))
15746 /* Constructs of the form (a OP b ? a : b) are safe. */
15747 && ((! rtx_equal_p (op0, false_cond) && ! rtx_equal_p (op1, false_cond))
15748 || (! rtx_equal_p (op0, true_cond)
15749 && ! rtx_equal_p (op1, true_cond))))
15750 return 0;
15752 /* At this point we know we can use fsel. */
15754 /* Reduce the comparison to a comparison against zero. */
15755 if (! is_against_zero)
15757 temp = gen_reg_rtx (compare_mode);
15758 emit_insn (gen_rtx_SET (VOIDmode, temp,
15759 gen_rtx_MINUS (compare_mode, op0, op1)));
15760 op0 = temp;
15761 op1 = CONST0_RTX (compare_mode);
15764 /* If we don't care about NaNs we can reduce some of the comparisons
15765 down to faster ones. */
15766 if (! HONOR_NANS (compare_mode))
15767 switch (code)
15769 case GT:
15770 code = LE;
15771 temp = true_cond;
15772 true_cond = false_cond;
15773 false_cond = temp;
15774 break;
15775 case UNGE:
15776 code = GE;
15777 break;
15778 case UNEQ:
15779 code = EQ;
15780 break;
15781 default:
15782 break;
15785 /* Now, reduce everything down to a GE. */
15786 switch (code)
15788 case GE:
15789 break;
15791 case LE:
15792 temp = gen_reg_rtx (compare_mode);
15793 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
15794 op0 = temp;
15795 break;
15797 case ORDERED:
15798 temp = gen_reg_rtx (compare_mode);
15799 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_ABS (compare_mode, op0)));
15800 op0 = temp;
15801 break;
15803 case EQ:
15804 temp = gen_reg_rtx (compare_mode);
15805 emit_insn (gen_rtx_SET (VOIDmode, temp,
15806 gen_rtx_NEG (compare_mode,
15807 gen_rtx_ABS (compare_mode, op0))));
15808 op0 = temp;
15809 break;
15811 case UNGE:
15812 /* a UNGE 0 <-> (a GE 0 || -a UNLT 0) */
15813 temp = gen_reg_rtx (result_mode);
15814 emit_insn (gen_rtx_SET (VOIDmode, temp,
15815 gen_rtx_IF_THEN_ELSE (result_mode,
15816 gen_rtx_GE (VOIDmode,
15817 op0, op1),
15818 true_cond, false_cond)));
15819 false_cond = true_cond;
15820 true_cond = temp;
15822 temp = gen_reg_rtx (compare_mode);
15823 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
15824 op0 = temp;
15825 break;
15827 case GT:
15828 /* a GT 0 <-> (a GE 0 && -a UNLT 0) */
15829 temp = gen_reg_rtx (result_mode);
15830 emit_insn (gen_rtx_SET (VOIDmode, temp,
15831 gen_rtx_IF_THEN_ELSE (result_mode,
15832 gen_rtx_GE (VOIDmode,
15833 op0, op1),
15834 true_cond, false_cond)));
15835 true_cond = false_cond;
15836 false_cond = temp;
15838 temp = gen_reg_rtx (compare_mode);
15839 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
15840 op0 = temp;
15841 break;
15843 default:
15844 gcc_unreachable ();
15847 emit_insn (gen_rtx_SET (VOIDmode, dest,
15848 gen_rtx_IF_THEN_ELSE (result_mode,
15849 gen_rtx_GE (VOIDmode,
15850 op0, op1),
15851 true_cond, false_cond)));
15852 return 1;
15855 /* Same as above, but for ints (isel). */
15857 static int
15858 rs6000_emit_int_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
15860 rtx condition_rtx, cr;
15861 enum machine_mode mode = GET_MODE (XEXP (op, 0));
15863 if (mode != SImode && (!TARGET_POWERPC64 || mode != DImode))
15864 return 0;
15866 /* We still have to do the compare, because isel doesn't do a
15867 compare, it just looks at the CRx bits set by a previous compare
15868 instruction. */
15869 condition_rtx = rs6000_generate_compare (op, SImode);
15870 cr = XEXP (condition_rtx, 0);
15872 if (mode == SImode)
15874 if (GET_MODE (cr) == CCmode)
15875 emit_insn (gen_isel_signed_si (dest, condition_rtx,
15876 true_cond, false_cond, cr));
15877 else
15878 emit_insn (gen_isel_unsigned_si (dest, condition_rtx,
15879 true_cond, false_cond, cr));
15881 else
15883 if (GET_MODE (cr) == CCmode)
15884 emit_insn (gen_isel_signed_di (dest, condition_rtx,
15885 true_cond, false_cond, cr));
15886 else
15887 emit_insn (gen_isel_unsigned_di (dest, condition_rtx,
15888 true_cond, false_cond, cr));
15891 return 1;
15894 const char *
15895 output_isel (rtx *operands)
15897 enum rtx_code code;
15899 code = GET_CODE (operands[1]);
15900 if (code == GE || code == GEU || code == LE || code == LEU || code == NE)
15902 PUT_CODE (operands[1], reverse_condition (code));
15903 return "isel %0,%3,%2,%j1";
15905 else
15906 return "isel %0,%2,%3,%j1";
15909 void
15910 rs6000_emit_minmax (rtx dest, enum rtx_code code, rtx op0, rtx op1)
15912 enum machine_mode mode = GET_MODE (op0);
15913 enum rtx_code c;
15914 rtx target;
15916 /* VSX/altivec have direct min/max insns. */
15917 if ((code == SMAX || code == SMIN) && VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode))
15919 emit_insn (gen_rtx_SET (VOIDmode,
15920 dest,
15921 gen_rtx_fmt_ee (code, mode, op0, op1)));
15922 return;
15925 if (code == SMAX || code == SMIN)
15926 c = GE;
15927 else
15928 c = GEU;
15930 if (code == SMAX || code == UMAX)
15931 target = emit_conditional_move (dest, c, op0, op1, mode,
15932 op0, op1, mode, 0);
15933 else
15934 target = emit_conditional_move (dest, c, op0, op1, mode,
15935 op1, op0, mode, 0);
15936 gcc_assert (target);
15937 if (target != dest)
15938 emit_move_insn (dest, target);
15941 /* Emit instructions to perform a load-reserved/store-conditional operation.
15942 The operation performed is an atomic
15943 (set M (CODE:MODE M OP))
15944 If not NULL, BEFORE is atomically set to M before the operation, and
15945 AFTER is set to M after the operation (that is, (CODE:MODE M OP)).
15946 If SYNC_P then a memory barrier is emitted before the operation.
15947 Either OP or M may be wrapped in a NOT operation. */
15949 void
15950 rs6000_emit_sync (enum rtx_code code, enum machine_mode mode,
15951 rtx m, rtx op, rtx before_param, rtx after_param,
15952 bool sync_p)
15954 enum machine_mode used_mode;
15955 rtx the_op, set_before, set_after, set_atomic, cc_scratch, before, after;
15956 rtx used_m;
15957 rtvec vec;
15958 HOST_WIDE_INT imask = GET_MODE_MASK (mode);
15959 rtx shift = NULL_RTX;
15961 if (sync_p)
15962 emit_insn (gen_lwsync ());
15964 used_m = m;
15966 /* If this is smaller than SImode, we'll have to use SImode with
15967 adjustments. */
15968 if (mode == QImode || mode == HImode)
15970 rtx newop, oldop;
15972 if (MEM_ALIGN (used_m) >= 32)
15974 int ishift = 0;
15975 if (BYTES_BIG_ENDIAN)
15976 ishift = GET_MODE_BITSIZE (SImode) - GET_MODE_BITSIZE (mode);
15978 shift = GEN_INT (ishift);
15979 used_m = change_address (used_m, SImode, 0);
15981 else
15983 rtx addrSI, aligned_addr;
15984 int shift_mask = mode == QImode ? 0x18 : 0x10;
15986 addrSI = gen_lowpart_common (SImode,
15987 force_reg (Pmode, XEXP (used_m, 0)));
15988 addrSI = force_reg (SImode, addrSI);
15989 shift = gen_reg_rtx (SImode);
15991 emit_insn (gen_rlwinm (shift, addrSI, GEN_INT (3),
15992 GEN_INT (shift_mask)));
15993 emit_insn (gen_xorsi3 (shift, shift, GEN_INT (shift_mask)));
15995 aligned_addr = expand_binop (Pmode, and_optab,
15996 XEXP (used_m, 0),
15997 GEN_INT (-4), NULL_RTX,
15998 1, OPTAB_LIB_WIDEN);
15999 used_m = change_address (used_m, SImode, aligned_addr);
16000 set_mem_align (used_m, 32);
16002 /* It's safe to keep the old alias set of USED_M, because
16003 the operation is atomic and only affects the original
16004 USED_M. */
16005 m = used_m;
16007 if (GET_CODE (op) == NOT)
16009 oldop = lowpart_subreg (SImode, XEXP (op, 0), mode);
16010 oldop = gen_rtx_NOT (SImode, oldop);
16012 else
16013 oldop = lowpart_subreg (SImode, op, mode);
16015 switch (code)
16017 case IOR:
16018 case XOR:
16019 newop = expand_binop (SImode, and_optab,
16020 oldop, GEN_INT (imask), NULL_RTX,
16021 1, OPTAB_LIB_WIDEN);
16022 emit_insn (gen_ashlsi3 (newop, newop, shift));
16023 break;
16025 case NOT: /* NAND */
16026 newop = expand_binop (SImode, ior_optab,
16027 oldop, GEN_INT (~imask), NULL_RTX,
16028 1, OPTAB_LIB_WIDEN);
16029 emit_insn (gen_rotlsi3 (newop, newop, shift));
16030 break;
16032 case AND:
16033 newop = expand_binop (SImode, ior_optab,
16034 oldop, GEN_INT (~imask), NULL_RTX,
16035 1, OPTAB_LIB_WIDEN);
16036 emit_insn (gen_rotlsi3 (newop, newop, shift));
16037 break;
16039 case PLUS:
16040 case MINUS:
16042 rtx mask;
16044 newop = expand_binop (SImode, and_optab,
16045 oldop, GEN_INT (imask), NULL_RTX,
16046 1, OPTAB_LIB_WIDEN);
16047 emit_insn (gen_ashlsi3 (newop, newop, shift));
16049 mask = gen_reg_rtx (SImode);
16050 emit_move_insn (mask, GEN_INT (imask));
16051 emit_insn (gen_ashlsi3 (mask, mask, shift));
16053 if (code == PLUS)
16054 newop = gen_rtx_PLUS (SImode, m, newop);
16055 else
16056 newop = gen_rtx_MINUS (SImode, m, newop);
16057 newop = gen_rtx_AND (SImode, newop, mask);
16058 newop = gen_rtx_IOR (SImode, newop,
16059 gen_rtx_AND (SImode,
16060 gen_rtx_NOT (SImode, mask),
16061 m));
16062 break;
16065 default:
16066 gcc_unreachable ();
16069 op = newop;
16070 used_mode = SImode;
16071 before = gen_reg_rtx (used_mode);
16072 after = gen_reg_rtx (used_mode);
16074 else
16076 used_mode = mode;
16077 before = before_param;
16078 after = after_param;
16080 if (before == NULL_RTX)
16081 before = gen_reg_rtx (used_mode);
16082 if (after == NULL_RTX)
16083 after = gen_reg_rtx (used_mode);
16086 if ((code == PLUS || code == MINUS)
16087 && used_mode != mode)
16088 the_op = op; /* Computed above. */
16089 else if (GET_CODE (op) == NOT && GET_CODE (m) != NOT)
16090 the_op = gen_rtx_fmt_ee (code, used_mode, op, m);
16091 else if (code == NOT)
16092 the_op = gen_rtx_fmt_ee (IOR, used_mode,
16093 gen_rtx_NOT (used_mode, m),
16094 gen_rtx_NOT (used_mode, op));
16095 else
16096 the_op = gen_rtx_fmt_ee (code, used_mode, m, op);
16098 set_after = gen_rtx_SET (VOIDmode, after, the_op);
16099 set_before = gen_rtx_SET (VOIDmode, before, used_m);
16100 set_atomic = gen_rtx_SET (VOIDmode, used_m,
16101 gen_rtx_UNSPEC (used_mode,
16102 gen_rtvec (1, the_op),
16103 UNSPEC_SYNC_OP));
16104 cc_scratch = gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (CCmode));
16106 if ((code == PLUS || code == MINUS) && used_mode != mode)
16107 vec = gen_rtvec (5, set_after, set_before, set_atomic, cc_scratch,
16108 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (SImode)));
16109 else
16110 vec = gen_rtvec (4, set_after, set_before, set_atomic, cc_scratch);
16111 emit_insn (gen_rtx_PARALLEL (VOIDmode, vec));
16113 /* Shift and mask the return values properly. */
16114 if (used_mode != mode && before_param)
16116 emit_insn (gen_lshrsi3 (before, before, shift));
16117 convert_move (before_param, before, 1);
16120 if (used_mode != mode && after_param)
16122 emit_insn (gen_lshrsi3 (after, after, shift));
16123 convert_move (after_param, after, 1);
16126 /* The previous sequence will end with a branch that's dependent on
16127 the conditional store, so placing an isync will ensure that no
16128 other instructions (especially, no load or store instructions)
16129 can start before the atomic operation completes. */
16130 if (sync_p)
16131 emit_insn (gen_isync ());
16134 /* A subroutine of the atomic operation splitters. Jump to LABEL if
16135 COND is true. Mark the jump as unlikely to be taken. */
16137 static void
16138 emit_unlikely_jump (rtx cond, rtx label)
16140 rtx very_unlikely = GEN_INT (REG_BR_PROB_BASE / 100 - 1);
16141 rtx x;
16143 x = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, label, pc_rtx);
16144 x = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, x));
16145 add_reg_note (x, REG_BR_PROB, very_unlikely);
16148 /* A subroutine of the atomic operation splitters. Emit a load-locked
16149 instruction in MODE. */
16151 static void
16152 emit_load_locked (enum machine_mode mode, rtx reg, rtx mem)
16154 rtx (*fn) (rtx, rtx) = NULL;
16155 if (mode == SImode)
16156 fn = gen_load_locked_si;
16157 else if (mode == DImode)
16158 fn = gen_load_locked_di;
16159 emit_insn (fn (reg, mem));
16162 /* A subroutine of the atomic operation splitters. Emit a store-conditional
16163 instruction in MODE. */
16165 static void
16166 emit_store_conditional (enum machine_mode mode, rtx res, rtx mem, rtx val)
16168 rtx (*fn) (rtx, rtx, rtx) = NULL;
16169 if (mode == SImode)
16170 fn = gen_store_conditional_si;
16171 else if (mode == DImode)
16172 fn = gen_store_conditional_di;
16174 /* Emit sync before stwcx. to address PPC405 Erratum. */
16175 if (PPC405_ERRATUM77)
16176 emit_insn (gen_memory_barrier ());
16178 emit_insn (fn (res, mem, val));
16181 /* Expand an atomic fetch-and-operate pattern. CODE is the binary operation
16182 to perform. MEM is the memory on which to operate. VAL is the second
16183 operand of the binary operator. BEFORE and AFTER are optional locations to
16184 return the value of MEM either before of after the operation. SCRATCH is
16185 a scratch register. */
16187 void
16188 rs6000_split_atomic_op (enum rtx_code code, rtx mem, rtx val,
16189 rtx before, rtx after, rtx scratch)
16191 enum machine_mode mode = GET_MODE (mem);
16192 rtx label, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
16194 emit_insn (gen_lwsync ());
16196 label = gen_label_rtx ();
16197 emit_label (label);
16198 label = gen_rtx_LABEL_REF (VOIDmode, label);
16200 if (before == NULL_RTX)
16201 before = scratch;
16202 emit_load_locked (mode, before, mem);
16204 if (code == NOT)
16205 x = gen_rtx_IOR (mode,
16206 gen_rtx_NOT (mode, before),
16207 gen_rtx_NOT (mode, val));
16208 else if (code == AND)
16209 x = gen_rtx_UNSPEC (mode, gen_rtvec (2, before, val), UNSPEC_AND);
16210 else
16211 x = gen_rtx_fmt_ee (code, mode, before, val);
16213 if (after != NULL_RTX)
16214 emit_insn (gen_rtx_SET (VOIDmode, after, copy_rtx (x)));
16215 emit_insn (gen_rtx_SET (VOIDmode, scratch, x));
16217 emit_store_conditional (mode, cond, mem, scratch);
16219 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
16220 emit_unlikely_jump (x, label);
16222 emit_insn (gen_isync ());
16225 /* Expand an atomic compare and swap operation. MEM is the memory on which
16226 to operate. OLDVAL is the old value to be compared. NEWVAL is the new
16227 value to be stored. SCRATCH is a scratch GPR. */
16229 void
16230 rs6000_split_compare_and_swap (rtx retval, rtx mem, rtx oldval, rtx newval,
16231 rtx scratch)
16233 enum machine_mode mode = GET_MODE (mem);
16234 rtx label1, label2, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
16236 emit_insn (gen_lwsync ());
16238 label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
16239 label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
16240 emit_label (XEXP (label1, 0));
16242 emit_load_locked (mode, retval, mem);
16244 x = gen_rtx_COMPARE (CCmode, retval, oldval);
16245 emit_insn (gen_rtx_SET (VOIDmode, cond, x));
16247 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
16248 emit_unlikely_jump (x, label2);
16250 emit_move_insn (scratch, newval);
16251 emit_store_conditional (mode, cond, mem, scratch);
16253 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
16254 emit_unlikely_jump (x, label1);
16256 emit_insn (gen_isync ());
16257 emit_label (XEXP (label2, 0));
16260 /* Expand an atomic test and set operation. MEM is the memory on which
16261 to operate. VAL is the value set. SCRATCH is a scratch GPR. */
16263 void
16264 rs6000_split_lock_test_and_set (rtx retval, rtx mem, rtx val, rtx scratch)
16266 enum machine_mode mode = GET_MODE (mem);
16267 rtx label, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
16269 label = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
16270 emit_label (XEXP (label, 0));
16272 emit_load_locked (mode, retval, mem);
16273 emit_move_insn (scratch, val);
16274 emit_store_conditional (mode, cond, mem, scratch);
16276 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
16277 emit_unlikely_jump (x, label);
16279 emit_insn (gen_isync ());
16282 void
16283 rs6000_expand_compare_and_swapqhi (rtx dst, rtx mem, rtx oldval, rtx newval)
16285 enum machine_mode mode = GET_MODE (mem);
16286 rtx addrSI, align, wdst, shift, mask;
16287 HOST_WIDE_INT shift_mask = mode == QImode ? 0x18 : 0x10;
16288 HOST_WIDE_INT imask = GET_MODE_MASK (mode);
16290 /* Shift amount for subword relative to aligned word. */
16291 addrSI = force_reg (GET_MODE (XEXP (mem, 0)), XEXP (mem, 0));
16292 addrSI = force_reg (SImode, gen_lowpart_common (SImode, addrSI));
16293 shift = gen_reg_rtx (SImode);
16294 emit_insn (gen_rlwinm (shift, addrSI, GEN_INT (3),
16295 GEN_INT (shift_mask)));
16296 emit_insn (gen_xorsi3 (shift, shift, GEN_INT (shift_mask)));
16298 /* Shift and mask old value into position within word. */
16299 oldval = convert_modes (SImode, mode, oldval, 1);
16300 oldval = expand_binop (SImode, and_optab,
16301 oldval, GEN_INT (imask), NULL_RTX,
16302 1, OPTAB_LIB_WIDEN);
16303 emit_insn (gen_ashlsi3 (oldval, oldval, shift));
16305 /* Shift and mask new value into position within word. */
16306 newval = convert_modes (SImode, mode, newval, 1);
16307 newval = expand_binop (SImode, and_optab,
16308 newval, GEN_INT (imask), NULL_RTX,
16309 1, OPTAB_LIB_WIDEN);
16310 emit_insn (gen_ashlsi3 (newval, newval, shift));
16312 /* Mask for insertion. */
16313 mask = gen_reg_rtx (SImode);
16314 emit_move_insn (mask, GEN_INT (imask));
16315 emit_insn (gen_ashlsi3 (mask, mask, shift));
16317 /* Address of aligned word containing subword. */
16318 align = expand_binop (Pmode, and_optab, XEXP (mem, 0), GEN_INT (-4),
16319 NULL_RTX, 1, OPTAB_LIB_WIDEN);
16320 mem = change_address (mem, SImode, align);
16321 set_mem_align (mem, 32);
16322 MEM_VOLATILE_P (mem) = 1;
16324 wdst = gen_reg_rtx (SImode);
16325 emit_insn (gen_sync_compare_and_swapqhi_internal (wdst, mask,
16326 oldval, newval, mem));
16328 /* Shift the result back. */
16329 emit_insn (gen_lshrsi3 (wdst, wdst, shift));
16331 emit_move_insn (dst, gen_lowpart (mode, wdst));
16334 void
16335 rs6000_split_compare_and_swapqhi (rtx dest, rtx mask,
16336 rtx oldval, rtx newval, rtx mem,
16337 rtx scratch)
16339 rtx label1, label2, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
16341 emit_insn (gen_lwsync ());
16342 label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
16343 label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
16344 emit_label (XEXP (label1, 0));
16346 emit_load_locked (SImode, scratch, mem);
16348 /* Mask subword within loaded value for comparison with oldval.
16349 Use UNSPEC_AND to avoid clobber.*/
16350 emit_insn (gen_rtx_SET (SImode, dest,
16351 gen_rtx_UNSPEC (SImode,
16352 gen_rtvec (2, scratch, mask),
16353 UNSPEC_AND)));
16355 x = gen_rtx_COMPARE (CCmode, dest, oldval);
16356 emit_insn (gen_rtx_SET (VOIDmode, cond, x));
16358 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
16359 emit_unlikely_jump (x, label2);
16361 /* Clear subword within loaded value for insertion of new value. */
16362 emit_insn (gen_rtx_SET (SImode, scratch,
16363 gen_rtx_AND (SImode,
16364 gen_rtx_NOT (SImode, mask), scratch)));
16365 emit_insn (gen_iorsi3 (scratch, scratch, newval));
16366 emit_store_conditional (SImode, cond, mem, scratch);
16368 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
16369 emit_unlikely_jump (x, label1);
16371 emit_insn (gen_isync ());
16372 emit_label (XEXP (label2, 0));
16376 /* Emit instructions to move SRC to DST. Called by splitters for
16377 multi-register moves. It will emit at most one instruction for
16378 each register that is accessed; that is, it won't emit li/lis pairs
16379 (or equivalent for 64-bit code). One of SRC or DST must be a hard
16380 register. */
16382 void
16383 rs6000_split_multireg_move (rtx dst, rtx src)
16385 /* The register number of the first register being moved. */
16386 int reg;
16387 /* The mode that is to be moved. */
16388 enum machine_mode mode;
16389 /* The mode that the move is being done in, and its size. */
16390 enum machine_mode reg_mode;
16391 int reg_mode_size;
16392 /* The number of registers that will be moved. */
16393 int nregs;
16395 reg = REG_P (dst) ? REGNO (dst) : REGNO (src);
16396 mode = GET_MODE (dst);
16397 nregs = hard_regno_nregs[reg][mode];
16398 if (FP_REGNO_P (reg))
16399 reg_mode = DECIMAL_FLOAT_MODE_P (mode) ? DDmode :
16400 ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? DFmode : SFmode);
16401 else if (ALTIVEC_REGNO_P (reg))
16402 reg_mode = V16QImode;
16403 else if (TARGET_E500_DOUBLE && mode == TFmode)
16404 reg_mode = DFmode;
16405 else
16406 reg_mode = word_mode;
16407 reg_mode_size = GET_MODE_SIZE (reg_mode);
16409 gcc_assert (reg_mode_size * nregs == GET_MODE_SIZE (mode));
16411 if (REG_P (src) && REG_P (dst) && (REGNO (src) < REGNO (dst)))
16413 /* Move register range backwards, if we might have destructive
16414 overlap. */
16415 int i;
16416 for (i = nregs - 1; i >= 0; i--)
16417 emit_insn (gen_rtx_SET (VOIDmode,
16418 simplify_gen_subreg (reg_mode, dst, mode,
16419 i * reg_mode_size),
16420 simplify_gen_subreg (reg_mode, src, mode,
16421 i * reg_mode_size)));
16423 else
16425 int i;
16426 int j = -1;
16427 bool used_update = false;
16429 if (MEM_P (src) && INT_REGNO_P (reg))
16431 rtx breg;
16433 if (GET_CODE (XEXP (src, 0)) == PRE_INC
16434 || GET_CODE (XEXP (src, 0)) == PRE_DEC)
16436 rtx delta_rtx;
16437 breg = XEXP (XEXP (src, 0), 0);
16438 delta_rtx = (GET_CODE (XEXP (src, 0)) == PRE_INC
16439 ? GEN_INT (GET_MODE_SIZE (GET_MODE (src)))
16440 : GEN_INT (-GET_MODE_SIZE (GET_MODE (src))));
16441 emit_insn (TARGET_32BIT
16442 ? gen_addsi3 (breg, breg, delta_rtx)
16443 : gen_adddi3 (breg, breg, delta_rtx));
16444 src = replace_equiv_address (src, breg);
16446 else if (! rs6000_offsettable_memref_p (src))
16448 rtx basereg;
16449 basereg = gen_rtx_REG (Pmode, reg);
16450 emit_insn (gen_rtx_SET (VOIDmode, basereg, XEXP (src, 0)));
16451 src = replace_equiv_address (src, basereg);
16454 breg = XEXP (src, 0);
16455 if (GET_CODE (breg) == PLUS || GET_CODE (breg) == LO_SUM)
16456 breg = XEXP (breg, 0);
16458 /* If the base register we are using to address memory is
16459 also a destination reg, then change that register last. */
16460 if (REG_P (breg)
16461 && REGNO (breg) >= REGNO (dst)
16462 && REGNO (breg) < REGNO (dst) + nregs)
16463 j = REGNO (breg) - REGNO (dst);
16466 if (GET_CODE (dst) == MEM && INT_REGNO_P (reg))
16468 rtx breg;
16470 if (GET_CODE (XEXP (dst, 0)) == PRE_INC
16471 || GET_CODE (XEXP (dst, 0)) == PRE_DEC)
16473 rtx delta_rtx;
16474 breg = XEXP (XEXP (dst, 0), 0);
16475 delta_rtx = (GET_CODE (XEXP (dst, 0)) == PRE_INC
16476 ? GEN_INT (GET_MODE_SIZE (GET_MODE (dst)))
16477 : GEN_INT (-GET_MODE_SIZE (GET_MODE (dst))));
16479 /* We have to update the breg before doing the store.
16480 Use store with update, if available. */
16482 if (TARGET_UPDATE)
16484 rtx nsrc = simplify_gen_subreg (reg_mode, src, mode, 0);
16485 emit_insn (TARGET_32BIT
16486 ? (TARGET_POWERPC64
16487 ? gen_movdi_si_update (breg, breg, delta_rtx, nsrc)
16488 : gen_movsi_update (breg, breg, delta_rtx, nsrc))
16489 : gen_movdi_di_update (breg, breg, delta_rtx, nsrc));
16490 used_update = true;
16492 else
16493 emit_insn (TARGET_32BIT
16494 ? gen_addsi3 (breg, breg, delta_rtx)
16495 : gen_adddi3 (breg, breg, delta_rtx));
16496 dst = replace_equiv_address (dst, breg);
16498 else
16499 gcc_assert (rs6000_offsettable_memref_p (dst));
16502 for (i = 0; i < nregs; i++)
16504 /* Calculate index to next subword. */
16505 ++j;
16506 if (j == nregs)
16507 j = 0;
16509 /* If compiler already emitted move of first word by
16510 store with update, no need to do anything. */
16511 if (j == 0 && used_update)
16512 continue;
16514 emit_insn (gen_rtx_SET (VOIDmode,
16515 simplify_gen_subreg (reg_mode, dst, mode,
16516 j * reg_mode_size),
16517 simplify_gen_subreg (reg_mode, src, mode,
16518 j * reg_mode_size)));
16524 /* This page contains routines that are used to determine what the
16525 function prologue and epilogue code will do and write them out. */
16527 /* Return the first fixed-point register that is required to be
16528 saved. 32 if none. */
16531 first_reg_to_save (void)
16533 int first_reg;
16535 /* Find lowest numbered live register. */
16536 for (first_reg = 13; first_reg <= 31; first_reg++)
16537 if (df_regs_ever_live_p (first_reg)
16538 && (! call_used_regs[first_reg]
16539 || (first_reg == RS6000_PIC_OFFSET_TABLE_REGNUM
16540 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
16541 || (DEFAULT_ABI == ABI_DARWIN && flag_pic)
16542 || (TARGET_TOC && TARGET_MINIMAL_TOC)))))
16543 break;
16545 #if TARGET_MACHO
16546 if (flag_pic
16547 && crtl->uses_pic_offset_table
16548 && first_reg > RS6000_PIC_OFFSET_TABLE_REGNUM)
16549 return RS6000_PIC_OFFSET_TABLE_REGNUM;
16550 #endif
16552 return first_reg;
16555 /* Similar, for FP regs. */
16558 first_fp_reg_to_save (void)
16560 int first_reg;
16562 /* Find lowest numbered live register. */
16563 for (first_reg = 14 + 32; first_reg <= 63; first_reg++)
16564 if (df_regs_ever_live_p (first_reg))
16565 break;
16567 return first_reg;
16570 /* Similar, for AltiVec regs. */
16572 static int
16573 first_altivec_reg_to_save (void)
16575 int i;
16577 /* Stack frame remains as is unless we are in AltiVec ABI. */
16578 if (! TARGET_ALTIVEC_ABI)
16579 return LAST_ALTIVEC_REGNO + 1;
16581 /* On Darwin, the unwind routines are compiled without
16582 TARGET_ALTIVEC, and use save_world to save/restore the
16583 altivec registers when necessary. */
16584 if (DEFAULT_ABI == ABI_DARWIN && crtl->calls_eh_return
16585 && ! TARGET_ALTIVEC)
16586 return FIRST_ALTIVEC_REGNO + 20;
16588 /* Find lowest numbered live register. */
16589 for (i = FIRST_ALTIVEC_REGNO + 20; i <= LAST_ALTIVEC_REGNO; ++i)
16590 if (df_regs_ever_live_p (i))
16591 break;
16593 return i;
16596 /* Return a 32-bit mask of the AltiVec registers we need to set in
16597 VRSAVE. Bit n of the return value is 1 if Vn is live. The MSB in
16598 the 32-bit word is 0. */
16600 static unsigned int
16601 compute_vrsave_mask (void)
16603 unsigned int i, mask = 0;
16605 /* On Darwin, the unwind routines are compiled without
16606 TARGET_ALTIVEC, and use save_world to save/restore the
16607 call-saved altivec registers when necessary. */
16608 if (DEFAULT_ABI == ABI_DARWIN && crtl->calls_eh_return
16609 && ! TARGET_ALTIVEC)
16610 mask |= 0xFFF;
16612 /* First, find out if we use _any_ altivec registers. */
16613 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
16614 if (df_regs_ever_live_p (i))
16615 mask |= ALTIVEC_REG_BIT (i);
16617 if (mask == 0)
16618 return mask;
16620 /* Next, remove the argument registers from the set. These must
16621 be in the VRSAVE mask set by the caller, so we don't need to add
16622 them in again. More importantly, the mask we compute here is
16623 used to generate CLOBBERs in the set_vrsave insn, and we do not
16624 wish the argument registers to die. */
16625 for (i = crtl->args.info.vregno - 1; i >= ALTIVEC_ARG_MIN_REG; --i)
16626 mask &= ~ALTIVEC_REG_BIT (i);
16628 /* Similarly, remove the return value from the set. */
16630 bool yes = false;
16631 diddle_return_value (is_altivec_return_reg, &yes);
16632 if (yes)
16633 mask &= ~ALTIVEC_REG_BIT (ALTIVEC_ARG_RETURN);
16636 return mask;
16639 /* For a very restricted set of circumstances, we can cut down the
16640 size of prologues/epilogues by calling our own save/restore-the-world
16641 routines. */
16643 static void
16644 compute_save_world_info (rs6000_stack_t *info_ptr)
16646 info_ptr->world_save_p = 1;
16647 info_ptr->world_save_p
16648 = (WORLD_SAVE_P (info_ptr)
16649 && DEFAULT_ABI == ABI_DARWIN
16650 && ! (cfun->calls_setjmp && flag_exceptions)
16651 && info_ptr->first_fp_reg_save == FIRST_SAVED_FP_REGNO
16652 && info_ptr->first_gp_reg_save == FIRST_SAVED_GP_REGNO
16653 && info_ptr->first_altivec_reg_save == FIRST_SAVED_ALTIVEC_REGNO
16654 && info_ptr->cr_save_p);
16656 /* This will not work in conjunction with sibcalls. Make sure there
16657 are none. (This check is expensive, but seldom executed.) */
16658 if (WORLD_SAVE_P (info_ptr))
16660 rtx insn;
16661 for ( insn = get_last_insn_anywhere (); insn; insn = PREV_INSN (insn))
16662 if ( GET_CODE (insn) == CALL_INSN
16663 && SIBLING_CALL_P (insn))
16665 info_ptr->world_save_p = 0;
16666 break;
16670 if (WORLD_SAVE_P (info_ptr))
16672 /* Even if we're not touching VRsave, make sure there's room on the
16673 stack for it, if it looks like we're calling SAVE_WORLD, which
16674 will attempt to save it. */
16675 info_ptr->vrsave_size = 4;
16677 /* If we are going to save the world, we need to save the link register too. */
16678 info_ptr->lr_save_p = 1;
16680 /* "Save" the VRsave register too if we're saving the world. */
16681 if (info_ptr->vrsave_mask == 0)
16682 info_ptr->vrsave_mask = compute_vrsave_mask ();
16684 /* Because the Darwin register save/restore routines only handle
16685 F14 .. F31 and V20 .. V31 as per the ABI, perform a consistency
16686 check. */
16687 gcc_assert (info_ptr->first_fp_reg_save >= FIRST_SAVED_FP_REGNO
16688 && (info_ptr->first_altivec_reg_save
16689 >= FIRST_SAVED_ALTIVEC_REGNO));
16691 return;
16695 static void
16696 is_altivec_return_reg (rtx reg, void *xyes)
16698 bool *yes = (bool *) xyes;
16699 if (REGNO (reg) == ALTIVEC_ARG_RETURN)
16700 *yes = true;
16704 /* Calculate the stack information for the current function. This is
16705 complicated by having two separate calling sequences, the AIX calling
16706 sequence and the V.4 calling sequence.
16708 AIX (and Darwin/Mac OS X) stack frames look like:
16709 32-bit 64-bit
16710 SP----> +---------------------------------------+
16711 | back chain to caller | 0 0
16712 +---------------------------------------+
16713 | saved CR | 4 8 (8-11)
16714 +---------------------------------------+
16715 | saved LR | 8 16
16716 +---------------------------------------+
16717 | reserved for compilers | 12 24
16718 +---------------------------------------+
16719 | reserved for binders | 16 32
16720 +---------------------------------------+
16721 | saved TOC pointer | 20 40
16722 +---------------------------------------+
16723 | Parameter save area (P) | 24 48
16724 +---------------------------------------+
16725 | Alloca space (A) | 24+P etc.
16726 +---------------------------------------+
16727 | Local variable space (L) | 24+P+A
16728 +---------------------------------------+
16729 | Float/int conversion temporary (X) | 24+P+A+L
16730 +---------------------------------------+
16731 | Save area for AltiVec registers (W) | 24+P+A+L+X
16732 +---------------------------------------+
16733 | AltiVec alignment padding (Y) | 24+P+A+L+X+W
16734 +---------------------------------------+
16735 | Save area for VRSAVE register (Z) | 24+P+A+L+X+W+Y
16736 +---------------------------------------+
16737 | Save area for GP registers (G) | 24+P+A+X+L+X+W+Y+Z
16738 +---------------------------------------+
16739 | Save area for FP registers (F) | 24+P+A+X+L+X+W+Y+Z+G
16740 +---------------------------------------+
16741 old SP->| back chain to caller's caller |
16742 +---------------------------------------+
16744 The required alignment for AIX configurations is two words (i.e., 8
16745 or 16 bytes).
16748 V.4 stack frames look like:
16750 SP----> +---------------------------------------+
16751 | back chain to caller | 0
16752 +---------------------------------------+
16753 | caller's saved LR | 4
16754 +---------------------------------------+
16755 | Parameter save area (P) | 8
16756 +---------------------------------------+
16757 | Alloca space (A) | 8+P
16758 +---------------------------------------+
16759 | Varargs save area (V) | 8+P+A
16760 +---------------------------------------+
16761 | Local variable space (L) | 8+P+A+V
16762 +---------------------------------------+
16763 | Float/int conversion temporary (X) | 8+P+A+V+L
16764 +---------------------------------------+
16765 | Save area for AltiVec registers (W) | 8+P+A+V+L+X
16766 +---------------------------------------+
16767 | AltiVec alignment padding (Y) | 8+P+A+V+L+X+W
16768 +---------------------------------------+
16769 | Save area for VRSAVE register (Z) | 8+P+A+V+L+X+W+Y
16770 +---------------------------------------+
16771 | SPE: area for 64-bit GP registers |
16772 +---------------------------------------+
16773 | SPE alignment padding |
16774 +---------------------------------------+
16775 | saved CR (C) | 8+P+A+V+L+X+W+Y+Z
16776 +---------------------------------------+
16777 | Save area for GP registers (G) | 8+P+A+V+L+X+W+Y+Z+C
16778 +---------------------------------------+
16779 | Save area for FP registers (F) | 8+P+A+V+L+X+W+Y+Z+C+G
16780 +---------------------------------------+
16781 old SP->| back chain to caller's caller |
16782 +---------------------------------------+
16784 The required alignment for V.4 is 16 bytes, or 8 bytes if -meabi is
16785 given. (But note below and in sysv4.h that we require only 8 and
16786 may round up the size of our stack frame anyways. The historical
16787 reason is early versions of powerpc-linux which didn't properly
16788 align the stack at program startup. A happy side-effect is that
16789 -mno-eabi libraries can be used with -meabi programs.)
16791 The EABI configuration defaults to the V.4 layout. However,
16792 the stack alignment requirements may differ. If -mno-eabi is not
16793 given, the required stack alignment is 8 bytes; if -mno-eabi is
16794 given, the required alignment is 16 bytes. (But see V.4 comment
16795 above.) */
16797 #ifndef ABI_STACK_BOUNDARY
16798 #define ABI_STACK_BOUNDARY STACK_BOUNDARY
16799 #endif
16801 static rs6000_stack_t *
16802 rs6000_stack_info (void)
16804 static rs6000_stack_t info;
16805 rs6000_stack_t *info_ptr = &info;
16806 int reg_size = TARGET_32BIT ? 4 : 8;
16807 int ehrd_size;
16808 int save_align;
16809 int first_gp;
16810 HOST_WIDE_INT non_fixed_size;
16812 memset (&info, 0, sizeof (info));
16814 if (TARGET_SPE)
16816 /* Cache value so we don't rescan instruction chain over and over. */
16817 if (cfun->machine->insn_chain_scanned_p == 0)
16818 cfun->machine->insn_chain_scanned_p
16819 = spe_func_has_64bit_regs_p () + 1;
16820 info_ptr->spe_64bit_regs_used = cfun->machine->insn_chain_scanned_p - 1;
16823 /* Select which calling sequence. */
16824 info_ptr->abi = DEFAULT_ABI;
16826 /* Calculate which registers need to be saved & save area size. */
16827 info_ptr->first_gp_reg_save = first_reg_to_save ();
16828 /* Assume that we will have to save RS6000_PIC_OFFSET_TABLE_REGNUM,
16829 even if it currently looks like we won't. Reload may need it to
16830 get at a constant; if so, it will have already created a constant
16831 pool entry for it. */
16832 if (((TARGET_TOC && TARGET_MINIMAL_TOC)
16833 || (flag_pic == 1 && DEFAULT_ABI == ABI_V4)
16834 || (flag_pic && DEFAULT_ABI == ABI_DARWIN))
16835 && crtl->uses_const_pool
16836 && info_ptr->first_gp_reg_save > RS6000_PIC_OFFSET_TABLE_REGNUM)
16837 first_gp = RS6000_PIC_OFFSET_TABLE_REGNUM;
16838 else
16839 first_gp = info_ptr->first_gp_reg_save;
16841 info_ptr->gp_size = reg_size * (32 - first_gp);
16843 /* For the SPE, we have an additional upper 32-bits on each GPR.
16844 Ideally we should save the entire 64-bits only when the upper
16845 half is used in SIMD instructions. Since we only record
16846 registers live (not the size they are used in), this proves
16847 difficult because we'd have to traverse the instruction chain at
16848 the right time, taking reload into account. This is a real pain,
16849 so we opt to save the GPRs in 64-bits always if but one register
16850 gets used in 64-bits. Otherwise, all the registers in the frame
16851 get saved in 32-bits.
16853 So... since when we save all GPRs (except the SP) in 64-bits, the
16854 traditional GP save area will be empty. */
16855 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
16856 info_ptr->gp_size = 0;
16858 info_ptr->first_fp_reg_save = first_fp_reg_to_save ();
16859 info_ptr->fp_size = 8 * (64 - info_ptr->first_fp_reg_save);
16861 info_ptr->first_altivec_reg_save = first_altivec_reg_to_save ();
16862 info_ptr->altivec_size = 16 * (LAST_ALTIVEC_REGNO + 1
16863 - info_ptr->first_altivec_reg_save);
16865 /* Does this function call anything? */
16866 info_ptr->calls_p = (! current_function_is_leaf
16867 || cfun->machine->ra_needs_full_frame);
16869 /* Determine if we need to save the link register. */
16870 if ((DEFAULT_ABI == ABI_AIX
16871 && crtl->profile
16872 && !TARGET_PROFILE_KERNEL)
16873 #ifdef TARGET_RELOCATABLE
16874 || (TARGET_RELOCATABLE && (get_pool_size () != 0))
16875 #endif
16876 || (info_ptr->first_fp_reg_save != 64
16877 && !FP_SAVE_INLINE (info_ptr->first_fp_reg_save))
16878 || (DEFAULT_ABI == ABI_V4 && cfun->calls_alloca)
16879 || info_ptr->calls_p
16880 || rs6000_ra_ever_killed ())
16882 info_ptr->lr_save_p = 1;
16883 df_set_regs_ever_live (LR_REGNO, true);
16886 /* Determine if we need to save the condition code registers. */
16887 if (df_regs_ever_live_p (CR2_REGNO)
16888 || df_regs_ever_live_p (CR3_REGNO)
16889 || df_regs_ever_live_p (CR4_REGNO))
16891 info_ptr->cr_save_p = 1;
16892 if (DEFAULT_ABI == ABI_V4)
16893 info_ptr->cr_size = reg_size;
16896 /* If the current function calls __builtin_eh_return, then we need
16897 to allocate stack space for registers that will hold data for
16898 the exception handler. */
16899 if (crtl->calls_eh_return)
16901 unsigned int i;
16902 for (i = 0; EH_RETURN_DATA_REGNO (i) != INVALID_REGNUM; ++i)
16903 continue;
16905 /* SPE saves EH registers in 64-bits. */
16906 ehrd_size = i * (TARGET_SPE_ABI
16907 && info_ptr->spe_64bit_regs_used != 0
16908 ? UNITS_PER_SPE_WORD : UNITS_PER_WORD);
16910 else
16911 ehrd_size = 0;
16913 /* Determine various sizes. */
16914 info_ptr->reg_size = reg_size;
16915 info_ptr->fixed_size = RS6000_SAVE_AREA;
16916 info_ptr->vars_size = RS6000_ALIGN (get_frame_size (), 8);
16917 info_ptr->parm_size = RS6000_ALIGN (crtl->outgoing_args_size,
16918 TARGET_ALTIVEC ? 16 : 8);
16919 if (FRAME_GROWS_DOWNWARD)
16920 info_ptr->vars_size
16921 += RS6000_ALIGN (info_ptr->fixed_size + info_ptr->vars_size
16922 + info_ptr->parm_size,
16923 ABI_STACK_BOUNDARY / BITS_PER_UNIT)
16924 - (info_ptr->fixed_size + info_ptr->vars_size
16925 + info_ptr->parm_size);
16927 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
16928 info_ptr->spe_gp_size = 8 * (32 - first_gp);
16929 else
16930 info_ptr->spe_gp_size = 0;
16932 if (TARGET_ALTIVEC_ABI)
16933 info_ptr->vrsave_mask = compute_vrsave_mask ();
16934 else
16935 info_ptr->vrsave_mask = 0;
16937 if (TARGET_ALTIVEC_VRSAVE && info_ptr->vrsave_mask)
16938 info_ptr->vrsave_size = 4;
16939 else
16940 info_ptr->vrsave_size = 0;
16942 compute_save_world_info (info_ptr);
16944 /* Calculate the offsets. */
16945 switch (DEFAULT_ABI)
16947 case ABI_NONE:
16948 default:
16949 gcc_unreachable ();
16951 case ABI_AIX:
16952 case ABI_DARWIN:
16953 info_ptr->fp_save_offset = - info_ptr->fp_size;
16954 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
16956 if (TARGET_ALTIVEC_ABI)
16958 info_ptr->vrsave_save_offset
16959 = info_ptr->gp_save_offset - info_ptr->vrsave_size;
16961 /* Align stack so vector save area is on a quadword boundary.
16962 The padding goes above the vectors. */
16963 if (info_ptr->altivec_size != 0)
16964 info_ptr->altivec_padding_size
16965 = info_ptr->vrsave_save_offset & 0xF;
16966 else
16967 info_ptr->altivec_padding_size = 0;
16969 info_ptr->altivec_save_offset
16970 = info_ptr->vrsave_save_offset
16971 - info_ptr->altivec_padding_size
16972 - info_ptr->altivec_size;
16973 gcc_assert (info_ptr->altivec_size == 0
16974 || info_ptr->altivec_save_offset % 16 == 0);
16976 /* Adjust for AltiVec case. */
16977 info_ptr->ehrd_offset = info_ptr->altivec_save_offset - ehrd_size;
16979 else
16980 info_ptr->ehrd_offset = info_ptr->gp_save_offset - ehrd_size;
16981 info_ptr->cr_save_offset = reg_size; /* first word when 64-bit. */
16982 info_ptr->lr_save_offset = 2*reg_size;
16983 break;
16985 case ABI_V4:
16986 info_ptr->fp_save_offset = - info_ptr->fp_size;
16987 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
16988 info_ptr->cr_save_offset = info_ptr->gp_save_offset - info_ptr->cr_size;
16990 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
16992 /* Align stack so SPE GPR save area is aligned on a
16993 double-word boundary. */
16994 if (info_ptr->spe_gp_size != 0 && info_ptr->cr_save_offset != 0)
16995 info_ptr->spe_padding_size
16996 = 8 - (-info_ptr->cr_save_offset % 8);
16997 else
16998 info_ptr->spe_padding_size = 0;
17000 info_ptr->spe_gp_save_offset
17001 = info_ptr->cr_save_offset
17002 - info_ptr->spe_padding_size
17003 - info_ptr->spe_gp_size;
17005 /* Adjust for SPE case. */
17006 info_ptr->ehrd_offset = info_ptr->spe_gp_save_offset;
17008 else if (TARGET_ALTIVEC_ABI)
17010 info_ptr->vrsave_save_offset
17011 = info_ptr->cr_save_offset - info_ptr->vrsave_size;
17013 /* Align stack so vector save area is on a quadword boundary. */
17014 if (info_ptr->altivec_size != 0)
17015 info_ptr->altivec_padding_size
17016 = 16 - (-info_ptr->vrsave_save_offset % 16);
17017 else
17018 info_ptr->altivec_padding_size = 0;
17020 info_ptr->altivec_save_offset
17021 = info_ptr->vrsave_save_offset
17022 - info_ptr->altivec_padding_size
17023 - info_ptr->altivec_size;
17025 /* Adjust for AltiVec case. */
17026 info_ptr->ehrd_offset = info_ptr->altivec_save_offset;
17028 else
17029 info_ptr->ehrd_offset = info_ptr->cr_save_offset;
17030 info_ptr->ehrd_offset -= ehrd_size;
17031 info_ptr->lr_save_offset = reg_size;
17032 break;
17035 save_align = (TARGET_ALTIVEC_ABI || DEFAULT_ABI == ABI_DARWIN) ? 16 : 8;
17036 info_ptr->save_size = RS6000_ALIGN (info_ptr->fp_size
17037 + info_ptr->gp_size
17038 + info_ptr->altivec_size
17039 + info_ptr->altivec_padding_size
17040 + info_ptr->spe_gp_size
17041 + info_ptr->spe_padding_size
17042 + ehrd_size
17043 + info_ptr->cr_size
17044 + info_ptr->vrsave_size,
17045 save_align);
17047 non_fixed_size = (info_ptr->vars_size
17048 + info_ptr->parm_size
17049 + info_ptr->save_size);
17051 info_ptr->total_size = RS6000_ALIGN (non_fixed_size + info_ptr->fixed_size,
17052 ABI_STACK_BOUNDARY / BITS_PER_UNIT);
17054 /* Determine if we need to allocate any stack frame:
17056 For AIX we need to push the stack if a frame pointer is needed
17057 (because the stack might be dynamically adjusted), if we are
17058 debugging, if we make calls, or if the sum of fp_save, gp_save,
17059 and local variables are more than the space needed to save all
17060 non-volatile registers: 32-bit: 18*8 + 19*4 = 220 or 64-bit: 18*8
17061 + 18*8 = 288 (GPR13 reserved).
17063 For V.4 we don't have the stack cushion that AIX uses, but assume
17064 that the debugger can handle stackless frames. */
17066 if (info_ptr->calls_p)
17067 info_ptr->push_p = 1;
17069 else if (DEFAULT_ABI == ABI_V4)
17070 info_ptr->push_p = non_fixed_size != 0;
17072 else if (frame_pointer_needed)
17073 info_ptr->push_p = 1;
17075 else if (TARGET_XCOFF && write_symbols != NO_DEBUG)
17076 info_ptr->push_p = 1;
17078 else
17079 info_ptr->push_p = non_fixed_size > (TARGET_32BIT ? 220 : 288);
17081 /* Zero offsets if we're not saving those registers. */
17082 if (info_ptr->fp_size == 0)
17083 info_ptr->fp_save_offset = 0;
17085 if (info_ptr->gp_size == 0)
17086 info_ptr->gp_save_offset = 0;
17088 if (! TARGET_ALTIVEC_ABI || info_ptr->altivec_size == 0)
17089 info_ptr->altivec_save_offset = 0;
17091 if (! TARGET_ALTIVEC_ABI || info_ptr->vrsave_mask == 0)
17092 info_ptr->vrsave_save_offset = 0;
17094 if (! TARGET_SPE_ABI
17095 || info_ptr->spe_64bit_regs_used == 0
17096 || info_ptr->spe_gp_size == 0)
17097 info_ptr->spe_gp_save_offset = 0;
17099 if (! info_ptr->lr_save_p)
17100 info_ptr->lr_save_offset = 0;
17102 if (! info_ptr->cr_save_p)
17103 info_ptr->cr_save_offset = 0;
17105 return info_ptr;
17108 /* Return true if the current function uses any GPRs in 64-bit SIMD
17109 mode. */
17111 static bool
17112 spe_func_has_64bit_regs_p (void)
17114 rtx insns, insn;
17116 /* Functions that save and restore all the call-saved registers will
17117 need to save/restore the registers in 64-bits. */
17118 if (crtl->calls_eh_return
17119 || cfun->calls_setjmp
17120 || crtl->has_nonlocal_goto)
17121 return true;
17123 insns = get_insns ();
17125 for (insn = NEXT_INSN (insns); insn != NULL_RTX; insn = NEXT_INSN (insn))
17127 if (INSN_P (insn))
17129 rtx i;
17131 /* FIXME: This should be implemented with attributes...
17133 (set_attr "spe64" "true")....then,
17134 if (get_spe64(insn)) return true;
17136 It's the only reliable way to do the stuff below. */
17138 i = PATTERN (insn);
17139 if (GET_CODE (i) == SET)
17141 enum machine_mode mode = GET_MODE (SET_SRC (i));
17143 if (SPE_VECTOR_MODE (mode))
17144 return true;
17145 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode))
17146 return true;
17151 return false;
17154 static void
17155 debug_stack_info (rs6000_stack_t *info)
17157 const char *abi_string;
17159 if (! info)
17160 info = rs6000_stack_info ();
17162 fprintf (stderr, "\nStack information for function %s:\n",
17163 ((current_function_decl && DECL_NAME (current_function_decl))
17164 ? IDENTIFIER_POINTER (DECL_NAME (current_function_decl))
17165 : "<unknown>"));
17167 switch (info->abi)
17169 default: abi_string = "Unknown"; break;
17170 case ABI_NONE: abi_string = "NONE"; break;
17171 case ABI_AIX: abi_string = "AIX"; break;
17172 case ABI_DARWIN: abi_string = "Darwin"; break;
17173 case ABI_V4: abi_string = "V.4"; break;
17176 fprintf (stderr, "\tABI = %5s\n", abi_string);
17178 if (TARGET_ALTIVEC_ABI)
17179 fprintf (stderr, "\tALTIVEC ABI extensions enabled.\n");
17181 if (TARGET_SPE_ABI)
17182 fprintf (stderr, "\tSPE ABI extensions enabled.\n");
17184 if (info->first_gp_reg_save != 32)
17185 fprintf (stderr, "\tfirst_gp_reg_save = %5d\n", info->first_gp_reg_save);
17187 if (info->first_fp_reg_save != 64)
17188 fprintf (stderr, "\tfirst_fp_reg_save = %5d\n", info->first_fp_reg_save);
17190 if (info->first_altivec_reg_save <= LAST_ALTIVEC_REGNO)
17191 fprintf (stderr, "\tfirst_altivec_reg_save = %5d\n",
17192 info->first_altivec_reg_save);
17194 if (info->lr_save_p)
17195 fprintf (stderr, "\tlr_save_p = %5d\n", info->lr_save_p);
17197 if (info->cr_save_p)
17198 fprintf (stderr, "\tcr_save_p = %5d\n", info->cr_save_p);
17200 if (info->vrsave_mask)
17201 fprintf (stderr, "\tvrsave_mask = 0x%x\n", info->vrsave_mask);
17203 if (info->push_p)
17204 fprintf (stderr, "\tpush_p = %5d\n", info->push_p);
17206 if (info->calls_p)
17207 fprintf (stderr, "\tcalls_p = %5d\n", info->calls_p);
17209 if (info->gp_save_offset)
17210 fprintf (stderr, "\tgp_save_offset = %5d\n", info->gp_save_offset);
17212 if (info->fp_save_offset)
17213 fprintf (stderr, "\tfp_save_offset = %5d\n", info->fp_save_offset);
17215 if (info->altivec_save_offset)
17216 fprintf (stderr, "\taltivec_save_offset = %5d\n",
17217 info->altivec_save_offset);
17219 if (info->spe_gp_save_offset)
17220 fprintf (stderr, "\tspe_gp_save_offset = %5d\n",
17221 info->spe_gp_save_offset);
17223 if (info->vrsave_save_offset)
17224 fprintf (stderr, "\tvrsave_save_offset = %5d\n",
17225 info->vrsave_save_offset);
17227 if (info->lr_save_offset)
17228 fprintf (stderr, "\tlr_save_offset = %5d\n", info->lr_save_offset);
17230 if (info->cr_save_offset)
17231 fprintf (stderr, "\tcr_save_offset = %5d\n", info->cr_save_offset);
17233 if (info->varargs_save_offset)
17234 fprintf (stderr, "\tvarargs_save_offset = %5d\n", info->varargs_save_offset);
17236 if (info->total_size)
17237 fprintf (stderr, "\ttotal_size = "HOST_WIDE_INT_PRINT_DEC"\n",
17238 info->total_size);
17240 if (info->vars_size)
17241 fprintf (stderr, "\tvars_size = "HOST_WIDE_INT_PRINT_DEC"\n",
17242 info->vars_size);
17244 if (info->parm_size)
17245 fprintf (stderr, "\tparm_size = %5d\n", info->parm_size);
17247 if (info->fixed_size)
17248 fprintf (stderr, "\tfixed_size = %5d\n", info->fixed_size);
17250 if (info->gp_size)
17251 fprintf (stderr, "\tgp_size = %5d\n", info->gp_size);
17253 if (info->spe_gp_size)
17254 fprintf (stderr, "\tspe_gp_size = %5d\n", info->spe_gp_size);
17256 if (info->fp_size)
17257 fprintf (stderr, "\tfp_size = %5d\n", info->fp_size);
17259 if (info->altivec_size)
17260 fprintf (stderr, "\taltivec_size = %5d\n", info->altivec_size);
17262 if (info->vrsave_size)
17263 fprintf (stderr, "\tvrsave_size = %5d\n", info->vrsave_size);
17265 if (info->altivec_padding_size)
17266 fprintf (stderr, "\taltivec_padding_size= %5d\n",
17267 info->altivec_padding_size);
17269 if (info->spe_padding_size)
17270 fprintf (stderr, "\tspe_padding_size = %5d\n",
17271 info->spe_padding_size);
17273 if (info->cr_size)
17274 fprintf (stderr, "\tcr_size = %5d\n", info->cr_size);
17276 if (info->save_size)
17277 fprintf (stderr, "\tsave_size = %5d\n", info->save_size);
17279 if (info->reg_size != 4)
17280 fprintf (stderr, "\treg_size = %5d\n", info->reg_size);
17282 fprintf (stderr, "\n");
17286 rs6000_return_addr (int count, rtx frame)
17288 /* Currently we don't optimize very well between prolog and body
17289 code and for PIC code the code can be actually quite bad, so
17290 don't try to be too clever here. */
17291 if (count != 0 || (DEFAULT_ABI != ABI_AIX && flag_pic))
17293 cfun->machine->ra_needs_full_frame = 1;
17295 return
17296 gen_rtx_MEM
17297 (Pmode,
17298 memory_address
17299 (Pmode,
17300 plus_constant (copy_to_reg
17301 (gen_rtx_MEM (Pmode,
17302 memory_address (Pmode, frame))),
17303 RETURN_ADDRESS_OFFSET)));
17306 cfun->machine->ra_need_lr = 1;
17307 return get_hard_reg_initial_val (Pmode, LR_REGNO);
17310 /* Say whether a function is a candidate for sibcall handling or not.
17311 We do not allow indirect calls to be optimized into sibling calls.
17312 Also, we can't do it if there are any vector parameters; there's
17313 nowhere to put the VRsave code so it works; note that functions with
17314 vector parameters are required to have a prototype, so the argument
17315 type info must be available here. (The tail recursion case can work
17316 with vector parameters, but there's no way to distinguish here.) */
17317 static bool
17318 rs6000_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED)
17320 tree type;
17321 if (decl)
17323 if (TARGET_ALTIVEC_VRSAVE)
17325 for (type = TYPE_ARG_TYPES (TREE_TYPE (decl));
17326 type; type = TREE_CHAIN (type))
17328 if (TREE_CODE (TREE_VALUE (type)) == VECTOR_TYPE)
17329 return false;
17332 if (DEFAULT_ABI == ABI_DARWIN
17333 || ((*targetm.binds_local_p) (decl)
17334 && (DEFAULT_ABI != ABI_AIX || !DECL_EXTERNAL (decl))))
17336 tree attr_list = TYPE_ATTRIBUTES (TREE_TYPE (decl));
17338 if (!lookup_attribute ("longcall", attr_list)
17339 || lookup_attribute ("shortcall", attr_list))
17340 return true;
17343 return false;
17346 /* NULL if INSN insn is valid within a low-overhead loop.
17347 Otherwise return why doloop cannot be applied.
17348 PowerPC uses the COUNT register for branch on table instructions. */
17350 static const char *
17351 rs6000_invalid_within_doloop (const_rtx insn)
17353 if (CALL_P (insn))
17354 return "Function call in the loop.";
17356 if (JUMP_P (insn)
17357 && (GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC
17358 || GET_CODE (PATTERN (insn)) == ADDR_VEC))
17359 return "Computed branch in the loop.";
17361 return NULL;
17364 static int
17365 rs6000_ra_ever_killed (void)
17367 rtx top;
17368 rtx reg;
17369 rtx insn;
17371 if (cfun->is_thunk)
17372 return 0;
17374 /* regs_ever_live has LR marked as used if any sibcalls are present,
17375 but this should not force saving and restoring in the
17376 pro/epilogue. Likewise, reg_set_between_p thinks a sibcall
17377 clobbers LR, so that is inappropriate. */
17379 /* Also, the prologue can generate a store into LR that
17380 doesn't really count, like this:
17382 move LR->R0
17383 bcl to set PIC register
17384 move LR->R31
17385 move R0->LR
17387 When we're called from the epilogue, we need to avoid counting
17388 this as a store. */
17390 push_topmost_sequence ();
17391 top = get_insns ();
17392 pop_topmost_sequence ();
17393 reg = gen_rtx_REG (Pmode, LR_REGNO);
17395 for (insn = NEXT_INSN (top); insn != NULL_RTX; insn = NEXT_INSN (insn))
17397 if (INSN_P (insn))
17399 if (CALL_P (insn))
17401 if (!SIBLING_CALL_P (insn))
17402 return 1;
17404 else if (find_regno_note (insn, REG_INC, LR_REGNO))
17405 return 1;
17406 else if (set_of (reg, insn) != NULL_RTX
17407 && !prologue_epilogue_contains (insn))
17408 return 1;
17411 return 0;
17414 /* Emit instructions needed to load the TOC register.
17415 This is only needed when TARGET_TOC, TARGET_MINIMAL_TOC, and there is
17416 a constant pool; or for SVR4 -fpic. */
17418 void
17419 rs6000_emit_load_toc_table (int fromprolog)
17421 rtx dest;
17422 dest = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
17424 if (TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI != ABI_AIX && flag_pic)
17426 char buf[30];
17427 rtx lab, tmp1, tmp2, got;
17429 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
17430 lab = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
17431 if (flag_pic == 2)
17432 got = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
17433 else
17434 got = rs6000_got_sym ();
17435 tmp1 = tmp2 = dest;
17436 if (!fromprolog)
17438 tmp1 = gen_reg_rtx (Pmode);
17439 tmp2 = gen_reg_rtx (Pmode);
17441 emit_insn (gen_load_toc_v4_PIC_1 (lab));
17442 emit_move_insn (tmp1,
17443 gen_rtx_REG (Pmode, LR_REGNO));
17444 emit_insn (gen_load_toc_v4_PIC_3b (tmp2, tmp1, got, lab));
17445 emit_insn (gen_load_toc_v4_PIC_3c (dest, tmp2, got, lab));
17447 else if (TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 1)
17449 emit_insn (gen_load_toc_v4_pic_si ());
17450 emit_move_insn (dest, gen_rtx_REG (Pmode, LR_REGNO));
17452 else if (TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2)
17454 char buf[30];
17455 rtx temp0 = (fromprolog
17456 ? gen_rtx_REG (Pmode, 0)
17457 : gen_reg_rtx (Pmode));
17459 if (fromprolog)
17461 rtx symF, symL;
17463 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
17464 symF = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
17466 ASM_GENERATE_INTERNAL_LABEL (buf, "LCL", rs6000_pic_labelno);
17467 symL = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
17469 emit_insn (gen_load_toc_v4_PIC_1 (symF));
17470 emit_move_insn (dest,
17471 gen_rtx_REG (Pmode, LR_REGNO));
17472 emit_insn (gen_load_toc_v4_PIC_2 (temp0, dest, symL, symF));
17474 else
17476 rtx tocsym;
17478 tocsym = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
17479 emit_insn (gen_load_toc_v4_PIC_1b (tocsym));
17480 emit_move_insn (dest,
17481 gen_rtx_REG (Pmode, LR_REGNO));
17482 emit_move_insn (temp0, gen_rtx_MEM (Pmode, dest));
17484 emit_insn (gen_addsi3 (dest, temp0, dest));
17486 else if (TARGET_ELF && !TARGET_AIX && flag_pic == 0 && TARGET_MINIMAL_TOC)
17488 /* This is for AIX code running in non-PIC ELF32. */
17489 char buf[30];
17490 rtx realsym;
17491 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
17492 realsym = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
17494 emit_insn (gen_elf_high (dest, realsym));
17495 emit_insn (gen_elf_low (dest, dest, realsym));
17497 else
17499 gcc_assert (DEFAULT_ABI == ABI_AIX);
17501 if (TARGET_32BIT)
17502 emit_insn (gen_load_toc_aix_si (dest));
17503 else
17504 emit_insn (gen_load_toc_aix_di (dest));
17508 /* Emit instructions to restore the link register after determining where
17509 its value has been stored. */
17511 void
17512 rs6000_emit_eh_reg_restore (rtx source, rtx scratch)
17514 rs6000_stack_t *info = rs6000_stack_info ();
17515 rtx operands[2];
17517 operands[0] = source;
17518 operands[1] = scratch;
17520 if (info->lr_save_p)
17522 rtx frame_rtx = stack_pointer_rtx;
17523 HOST_WIDE_INT sp_offset = 0;
17524 rtx tmp;
17526 if (frame_pointer_needed
17527 || cfun->calls_alloca
17528 || info->total_size > 32767)
17530 tmp = gen_frame_mem (Pmode, frame_rtx);
17531 emit_move_insn (operands[1], tmp);
17532 frame_rtx = operands[1];
17534 else if (info->push_p)
17535 sp_offset = info->total_size;
17537 tmp = plus_constant (frame_rtx, info->lr_save_offset + sp_offset);
17538 tmp = gen_frame_mem (Pmode, tmp);
17539 emit_move_insn (tmp, operands[0]);
17541 else
17542 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO), operands[0]);
17545 static GTY(()) alias_set_type set = -1;
17547 alias_set_type
17548 get_TOC_alias_set (void)
17550 if (set == -1)
17551 set = new_alias_set ();
17552 return set;
17555 /* This returns nonzero if the current function uses the TOC. This is
17556 determined by the presence of (use (unspec ... UNSPEC_TOC)), which
17557 is generated by the ABI_V4 load_toc_* patterns. */
17558 #if TARGET_ELF
17559 static int
17560 uses_TOC (void)
17562 rtx insn;
17564 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
17565 if (INSN_P (insn))
17567 rtx pat = PATTERN (insn);
17568 int i;
17570 if (GET_CODE (pat) == PARALLEL)
17571 for (i = 0; i < XVECLEN (pat, 0); i++)
17573 rtx sub = XVECEXP (pat, 0, i);
17574 if (GET_CODE (sub) == USE)
17576 sub = XEXP (sub, 0);
17577 if (GET_CODE (sub) == UNSPEC
17578 && XINT (sub, 1) == UNSPEC_TOC)
17579 return 1;
17583 return 0;
17585 #endif
17588 create_TOC_reference (rtx symbol)
17590 if (TARGET_DEBUG_ADDR)
17592 if (GET_CODE (symbol) == SYMBOL_REF)
17593 fprintf (stderr, "\ncreate_TOC_reference, (symbol_ref %s)\n",
17594 XSTR (symbol, 0));
17595 else
17597 fprintf (stderr, "\ncreate_TOC_reference, code %s:\n",
17598 GET_RTX_NAME (GET_CODE (symbol)));
17599 debug_rtx (symbol);
17603 if (!can_create_pseudo_p ())
17604 df_set_regs_ever_live (TOC_REGISTER, true);
17605 return gen_rtx_PLUS (Pmode,
17606 gen_rtx_REG (Pmode, TOC_REGISTER),
17607 gen_rtx_CONST (Pmode,
17608 gen_rtx_UNSPEC (Pmode, gen_rtvec (1, symbol), UNSPEC_TOCREL)));
17611 /* If _Unwind_* has been called from within the same module,
17612 toc register is not guaranteed to be saved to 40(1) on function
17613 entry. Save it there in that case. */
17615 void
17616 rs6000_aix_emit_builtin_unwind_init (void)
17618 rtx mem;
17619 rtx stack_top = gen_reg_rtx (Pmode);
17620 rtx opcode_addr = gen_reg_rtx (Pmode);
17621 rtx opcode = gen_reg_rtx (SImode);
17622 rtx tocompare = gen_reg_rtx (SImode);
17623 rtx no_toc_save_needed = gen_label_rtx ();
17625 mem = gen_frame_mem (Pmode, hard_frame_pointer_rtx);
17626 emit_move_insn (stack_top, mem);
17628 mem = gen_frame_mem (Pmode,
17629 gen_rtx_PLUS (Pmode, stack_top,
17630 GEN_INT (2 * GET_MODE_SIZE (Pmode))));
17631 emit_move_insn (opcode_addr, mem);
17632 emit_move_insn (opcode, gen_rtx_MEM (SImode, opcode_addr));
17633 emit_move_insn (tocompare, gen_int_mode (TARGET_32BIT ? 0x80410014
17634 : 0xE8410028, SImode));
17636 do_compare_rtx_and_jump (opcode, tocompare, EQ, 1,
17637 SImode, NULL_RTX, NULL_RTX,
17638 no_toc_save_needed);
17640 mem = gen_frame_mem (Pmode,
17641 gen_rtx_PLUS (Pmode, stack_top,
17642 GEN_INT (5 * GET_MODE_SIZE (Pmode))));
17643 emit_move_insn (mem, gen_rtx_REG (Pmode, 2));
17644 emit_label (no_toc_save_needed);
17647 /* This ties together stack memory (MEM with an alias set of frame_alias_set)
17648 and the change to the stack pointer. */
17650 static void
17651 rs6000_emit_stack_tie (void)
17653 rtx mem = gen_frame_mem (BLKmode,
17654 gen_rtx_REG (Pmode, STACK_POINTER_REGNUM));
17656 emit_insn (gen_stack_tie (mem));
17659 /* Emit the correct code for allocating stack space, as insns.
17660 If COPY_R12, make sure a copy of the old frame is left in r12.
17661 If COPY_R11, make sure a copy of the old frame is left in r11,
17662 in preference to r12 if COPY_R12.
17663 The generated code may use hard register 0 as a temporary. */
17665 static void
17666 rs6000_emit_allocate_stack (HOST_WIDE_INT size, int copy_r12, int copy_r11)
17668 rtx insn;
17669 rtx stack_reg = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
17670 rtx tmp_reg = gen_rtx_REG (Pmode, 0);
17671 rtx todec = gen_int_mode (-size, Pmode);
17672 rtx par, set, mem;
17674 if (INTVAL (todec) != -size)
17676 warning (0, "stack frame too large");
17677 emit_insn (gen_trap ());
17678 return;
17681 if (crtl->limit_stack)
17683 if (REG_P (stack_limit_rtx)
17684 && REGNO (stack_limit_rtx) > 1
17685 && REGNO (stack_limit_rtx) <= 31)
17687 emit_insn (TARGET_32BIT
17688 ? gen_addsi3 (tmp_reg,
17689 stack_limit_rtx,
17690 GEN_INT (size))
17691 : gen_adddi3 (tmp_reg,
17692 stack_limit_rtx,
17693 GEN_INT (size)));
17695 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
17696 const0_rtx));
17698 else if (GET_CODE (stack_limit_rtx) == SYMBOL_REF
17699 && TARGET_32BIT
17700 && DEFAULT_ABI == ABI_V4)
17702 rtx toload = gen_rtx_CONST (VOIDmode,
17703 gen_rtx_PLUS (Pmode,
17704 stack_limit_rtx,
17705 GEN_INT (size)));
17707 emit_insn (gen_elf_high (tmp_reg, toload));
17708 emit_insn (gen_elf_low (tmp_reg, tmp_reg, toload));
17709 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
17710 const0_rtx));
17712 else
17713 warning (0, "stack limit expression is not supported");
17716 if (copy_r12 || copy_r11)
17717 emit_move_insn (copy_r11
17718 ? gen_rtx_REG (Pmode, 11)
17719 : gen_rtx_REG (Pmode, 12),
17720 stack_reg);
17722 if (size > 32767)
17724 /* Need a note here so that try_split doesn't get confused. */
17725 if (get_last_insn () == NULL_RTX)
17726 emit_note (NOTE_INSN_DELETED);
17727 insn = emit_move_insn (tmp_reg, todec);
17728 try_split (PATTERN (insn), insn, 0);
17729 todec = tmp_reg;
17732 insn = emit_insn (TARGET_32BIT
17733 ? gen_movsi_update_stack (stack_reg, stack_reg,
17734 todec, stack_reg)
17735 : gen_movdi_di_update_stack (stack_reg, stack_reg,
17736 todec, stack_reg));
17737 /* Since we didn't use gen_frame_mem to generate the MEM, grab
17738 it now and set the alias set/attributes. The above gen_*_update
17739 calls will generate a PARALLEL with the MEM set being the first
17740 operation. */
17741 par = PATTERN (insn);
17742 gcc_assert (GET_CODE (par) == PARALLEL);
17743 set = XVECEXP (par, 0, 0);
17744 gcc_assert (GET_CODE (set) == SET);
17745 mem = SET_DEST (set);
17746 gcc_assert (MEM_P (mem));
17747 MEM_NOTRAP_P (mem) = 1;
17748 set_mem_alias_set (mem, get_frame_alias_set ());
17750 RTX_FRAME_RELATED_P (insn) = 1;
17751 add_reg_note (insn, REG_FRAME_RELATED_EXPR,
17752 gen_rtx_SET (VOIDmode, stack_reg,
17753 gen_rtx_PLUS (Pmode, stack_reg,
17754 GEN_INT (-size))));
17757 /* Add to 'insn' a note which is PATTERN (INSN) but with REG replaced
17758 with (plus:P (reg 1) VAL), and with REG2 replaced with RREG if REG2
17759 is not NULL. It would be nice if dwarf2out_frame_debug_expr could
17760 deduce these equivalences by itself so it wasn't necessary to hold
17761 its hand so much. */
17763 static void
17764 rs6000_frame_related (rtx insn, rtx reg, HOST_WIDE_INT val,
17765 rtx reg2, rtx rreg)
17767 rtx real, temp;
17769 /* copy_rtx will not make unique copies of registers, so we need to
17770 ensure we don't have unwanted sharing here. */
17771 if (reg == reg2)
17772 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
17774 if (reg == rreg)
17775 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
17777 real = copy_rtx (PATTERN (insn));
17779 if (reg2 != NULL_RTX)
17780 real = replace_rtx (real, reg2, rreg);
17782 real = replace_rtx (real, reg,
17783 gen_rtx_PLUS (Pmode, gen_rtx_REG (Pmode,
17784 STACK_POINTER_REGNUM),
17785 GEN_INT (val)));
17787 /* We expect that 'real' is either a SET or a PARALLEL containing
17788 SETs (and possibly other stuff). In a PARALLEL, all the SETs
17789 are important so they all have to be marked RTX_FRAME_RELATED_P. */
17791 if (GET_CODE (real) == SET)
17793 rtx set = real;
17795 temp = simplify_rtx (SET_SRC (set));
17796 if (temp)
17797 SET_SRC (set) = temp;
17798 temp = simplify_rtx (SET_DEST (set));
17799 if (temp)
17800 SET_DEST (set) = temp;
17801 if (GET_CODE (SET_DEST (set)) == MEM)
17803 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
17804 if (temp)
17805 XEXP (SET_DEST (set), 0) = temp;
17808 else
17810 int i;
17812 gcc_assert (GET_CODE (real) == PARALLEL);
17813 for (i = 0; i < XVECLEN (real, 0); i++)
17814 if (GET_CODE (XVECEXP (real, 0, i)) == SET)
17816 rtx set = XVECEXP (real, 0, i);
17818 temp = simplify_rtx (SET_SRC (set));
17819 if (temp)
17820 SET_SRC (set) = temp;
17821 temp = simplify_rtx (SET_DEST (set));
17822 if (temp)
17823 SET_DEST (set) = temp;
17824 if (GET_CODE (SET_DEST (set)) == MEM)
17826 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
17827 if (temp)
17828 XEXP (SET_DEST (set), 0) = temp;
17830 RTX_FRAME_RELATED_P (set) = 1;
17834 RTX_FRAME_RELATED_P (insn) = 1;
17835 add_reg_note (insn, REG_FRAME_RELATED_EXPR, real);
17838 /* Returns an insn that has a vrsave set operation with the
17839 appropriate CLOBBERs. */
17841 static rtx
17842 generate_set_vrsave (rtx reg, rs6000_stack_t *info, int epiloguep)
17844 int nclobs, i;
17845 rtx insn, clobs[TOTAL_ALTIVEC_REGS + 1];
17846 rtx vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
17848 clobs[0]
17849 = gen_rtx_SET (VOIDmode,
17850 vrsave,
17851 gen_rtx_UNSPEC_VOLATILE (SImode,
17852 gen_rtvec (2, reg, vrsave),
17853 UNSPECV_SET_VRSAVE));
17855 nclobs = 1;
17857 /* We need to clobber the registers in the mask so the scheduler
17858 does not move sets to VRSAVE before sets of AltiVec registers.
17860 However, if the function receives nonlocal gotos, reload will set
17861 all call saved registers live. We will end up with:
17863 (set (reg 999) (mem))
17864 (parallel [ (set (reg vrsave) (unspec blah))
17865 (clobber (reg 999))])
17867 The clobber will cause the store into reg 999 to be dead, and
17868 flow will attempt to delete an epilogue insn. In this case, we
17869 need an unspec use/set of the register. */
17871 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
17872 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
17874 if (!epiloguep || call_used_regs [i])
17875 clobs[nclobs++] = gen_rtx_CLOBBER (VOIDmode,
17876 gen_rtx_REG (V4SImode, i));
17877 else
17879 rtx reg = gen_rtx_REG (V4SImode, i);
17881 clobs[nclobs++]
17882 = gen_rtx_SET (VOIDmode,
17883 reg,
17884 gen_rtx_UNSPEC (V4SImode,
17885 gen_rtvec (1, reg), 27));
17889 insn = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (nclobs));
17891 for (i = 0; i < nclobs; ++i)
17892 XVECEXP (insn, 0, i) = clobs[i];
17894 return insn;
17897 /* Save a register into the frame, and emit RTX_FRAME_RELATED_P notes.
17898 Save REGNO into [FRAME_REG + OFFSET] in mode MODE. */
17900 static void
17901 emit_frame_save (rtx frame_reg, rtx frame_ptr, enum machine_mode mode,
17902 unsigned int regno, int offset, HOST_WIDE_INT total_size)
17904 rtx reg, offset_rtx, insn, mem, addr, int_rtx;
17905 rtx replacea, replaceb;
17907 int_rtx = GEN_INT (offset);
17909 /* Some cases that need register indexed addressing. */
17910 if ((TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
17911 || (TARGET_VSX && VSX_VECTOR_MODE (mode))
17912 || (TARGET_E500_DOUBLE && mode == DFmode)
17913 || (TARGET_SPE_ABI
17914 && SPE_VECTOR_MODE (mode)
17915 && !SPE_CONST_OFFSET_OK (offset)))
17917 /* Whomever calls us must make sure r11 is available in the
17918 flow path of instructions in the prologue. */
17919 offset_rtx = gen_rtx_REG (Pmode, 11);
17920 emit_move_insn (offset_rtx, int_rtx);
17922 replacea = offset_rtx;
17923 replaceb = int_rtx;
17925 else
17927 offset_rtx = int_rtx;
17928 replacea = NULL_RTX;
17929 replaceb = NULL_RTX;
17932 reg = gen_rtx_REG (mode, regno);
17933 addr = gen_rtx_PLUS (Pmode, frame_reg, offset_rtx);
17934 mem = gen_frame_mem (mode, addr);
17936 insn = emit_move_insn (mem, reg);
17938 rs6000_frame_related (insn, frame_ptr, total_size, replacea, replaceb);
17941 /* Emit an offset memory reference suitable for a frame store, while
17942 converting to a valid addressing mode. */
17944 static rtx
17945 gen_frame_mem_offset (enum machine_mode mode, rtx reg, int offset)
17947 rtx int_rtx, offset_rtx;
17949 int_rtx = GEN_INT (offset);
17951 if ((TARGET_SPE_ABI && SPE_VECTOR_MODE (mode))
17952 || (TARGET_E500_DOUBLE && mode == DFmode))
17954 offset_rtx = gen_rtx_REG (Pmode, FIXED_SCRATCH);
17955 emit_move_insn (offset_rtx, int_rtx);
17957 else
17958 offset_rtx = int_rtx;
17960 return gen_frame_mem (mode, gen_rtx_PLUS (Pmode, reg, offset_rtx));
17963 /* Look for user-defined global regs. We should not save and restore these,
17964 and cannot use stmw/lmw if there are any in its range. */
17966 static bool
17967 no_global_regs_above (int first, bool gpr)
17969 int i;
17970 for (i = first; i < gpr ? 32 : 64 ; i++)
17971 if (global_regs[i])
17972 return false;
17973 return true;
17976 #ifndef TARGET_FIX_AND_CONTINUE
17977 #define TARGET_FIX_AND_CONTINUE 0
17978 #endif
17980 /* It's really GPR 13 and FPR 14, but we need the smaller of the two. */
17981 #define FIRST_SAVRES_REGISTER FIRST_SAVED_GP_REGNO
17982 #define LAST_SAVRES_REGISTER 31
17983 #define N_SAVRES_REGISTERS (LAST_SAVRES_REGISTER - FIRST_SAVRES_REGISTER + 1)
17985 static GTY(()) rtx savres_routine_syms[N_SAVRES_REGISTERS][8];
17987 /* Return the symbol for an out-of-line register save/restore routine.
17988 We are saving/restoring GPRs if GPR is true. */
17990 static rtx
17991 rs6000_savres_routine_sym (rs6000_stack_t *info, bool savep, bool gpr, bool exitp)
17993 int regno = gpr ? info->first_gp_reg_save : (info->first_fp_reg_save - 32);
17994 rtx sym;
17995 int select = ((savep ? 1 : 0) << 2
17996 | (gpr
17997 /* On the SPE, we never have any FPRs, but we do have
17998 32/64-bit versions of the routines. */
17999 ? (TARGET_SPE_ABI && info->spe_64bit_regs_used ? 1 : 0)
18000 : 0) << 1
18001 | (exitp ? 1: 0));
18003 /* Don't generate bogus routine names. */
18004 gcc_assert (FIRST_SAVRES_REGISTER <= regno && regno <= LAST_SAVRES_REGISTER);
18006 sym = savres_routine_syms[regno-FIRST_SAVRES_REGISTER][select];
18008 if (sym == NULL)
18010 char name[30];
18011 const char *action;
18012 const char *regkind;
18013 const char *exit_suffix;
18015 action = savep ? "save" : "rest";
18017 /* SPE has slightly different names for its routines depending on
18018 whether we are saving 32-bit or 64-bit registers. */
18019 if (TARGET_SPE_ABI)
18021 /* No floating point saves on the SPE. */
18022 gcc_assert (gpr);
18024 regkind = info->spe_64bit_regs_used ? "64gpr" : "32gpr";
18026 else
18027 regkind = gpr ? "gpr" : "fpr";
18029 exit_suffix = exitp ? "_x" : "";
18031 sprintf (name, "_%s%s_%d%s", action, regkind, regno, exit_suffix);
18033 sym = savres_routine_syms[regno-FIRST_SAVRES_REGISTER][select]
18034 = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (name));
18037 return sym;
18040 /* Emit a sequence of insns, including a stack tie if needed, for
18041 resetting the stack pointer. If SAVRES is true, then don't reset the
18042 stack pointer, but move the base of the frame into r11 for use by
18043 out-of-line register restore routines. */
18045 static rtx
18046 rs6000_emit_stack_reset (rs6000_stack_t *info,
18047 rtx sp_reg_rtx, rtx frame_reg_rtx,
18048 int sp_offset, bool savres)
18050 /* This blockage is needed so that sched doesn't decide to move
18051 the sp change before the register restores. */
18052 if (frame_reg_rtx != sp_reg_rtx
18053 || (TARGET_SPE_ABI
18054 && info->spe_64bit_regs_used != 0
18055 && info->first_gp_reg_save != 32))
18056 rs6000_emit_stack_tie ();
18058 if (frame_reg_rtx != sp_reg_rtx)
18060 if (sp_offset != 0)
18061 return emit_insn (gen_addsi3 (sp_reg_rtx, frame_reg_rtx,
18062 GEN_INT (sp_offset)));
18063 else if (!savres)
18064 return emit_move_insn (sp_reg_rtx, frame_reg_rtx);
18066 else if (sp_offset != 0)
18068 /* If we are restoring registers out-of-line, we will be using the
18069 "exit" variants of the restore routines, which will reset the
18070 stack for us. But we do need to point r11 into the right place
18071 for those routines. */
18072 rtx dest_reg = (savres
18073 ? gen_rtx_REG (Pmode, 11)
18074 : sp_reg_rtx);
18076 rtx insn = emit_insn (gen_add3_insn (dest_reg, sp_reg_rtx,
18077 GEN_INT (sp_offset)));
18078 if (!savres)
18079 return insn;
18081 return NULL_RTX;
18084 /* Construct a parallel rtx describing the effect of a call to an
18085 out-of-line register save/restore routine. */
18087 static rtx
18088 rs6000_make_savres_rtx (rs6000_stack_t *info,
18089 rtx frame_reg_rtx, int save_area_offset,
18090 enum machine_mode reg_mode,
18091 bool savep, bool gpr, bool exitp)
18093 int i;
18094 int offset, start_reg, end_reg, n_regs;
18095 int reg_size = GET_MODE_SIZE (reg_mode);
18096 rtx sym;
18097 rtvec p;
18099 offset = 0;
18100 start_reg = (gpr
18101 ? info->first_gp_reg_save
18102 : info->first_fp_reg_save);
18103 end_reg = gpr ? 32 : 64;
18104 n_regs = end_reg - start_reg;
18105 p = rtvec_alloc ((exitp ? 4 : 3) + n_regs);
18107 /* If we're saving registers, then we should never say we're exiting. */
18108 gcc_assert ((savep && !exitp) || !savep);
18110 if (exitp)
18111 RTVEC_ELT (p, offset++) = gen_rtx_RETURN (VOIDmode);
18113 RTVEC_ELT (p, offset++)
18114 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 65));
18116 sym = rs6000_savres_routine_sym (info, savep, gpr, exitp);
18117 RTVEC_ELT (p, offset++) = gen_rtx_USE (VOIDmode, sym);
18118 RTVEC_ELT (p, offset++) = gen_rtx_USE (VOIDmode, gen_rtx_REG (Pmode, 11));
18120 for (i = 0; i < end_reg - start_reg; i++)
18122 rtx addr, reg, mem;
18123 reg = gen_rtx_REG (reg_mode, start_reg + i);
18124 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18125 GEN_INT (save_area_offset + reg_size*i));
18126 mem = gen_frame_mem (reg_mode, addr);
18128 RTVEC_ELT (p, i + offset) = gen_rtx_SET (VOIDmode,
18129 savep ? mem : reg,
18130 savep ? reg : mem);
18133 return gen_rtx_PARALLEL (VOIDmode, p);
18136 /* Determine whether the gp REG is really used. */
18138 static bool
18139 rs6000_reg_live_or_pic_offset_p (int reg)
18141 return ((df_regs_ever_live_p (reg)
18142 && (!call_used_regs[reg]
18143 || (reg == RS6000_PIC_OFFSET_TABLE_REGNUM
18144 && TARGET_TOC && TARGET_MINIMAL_TOC)))
18145 || (reg == RS6000_PIC_OFFSET_TABLE_REGNUM
18146 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
18147 || (DEFAULT_ABI == ABI_DARWIN && flag_pic))));
18150 enum {
18151 SAVRES_MULTIPLE = 0x1,
18152 SAVRES_INLINE_FPRS = 0x2,
18153 SAVRES_INLINE_GPRS = 0x4
18156 /* Determine the strategy for savings/restoring registers. */
18158 static int
18159 rs6000_savres_strategy (rs6000_stack_t *info, bool savep,
18160 int using_static_chain_p, int sibcall)
18162 bool using_multiple_p;
18163 bool common;
18164 bool savres_fprs_inline;
18165 bool savres_gprs_inline;
18166 bool noclobber_global_gprs
18167 = no_global_regs_above (info->first_gp_reg_save, /*gpr=*/true);
18169 using_multiple_p = (TARGET_MULTIPLE && ! TARGET_POWERPC64
18170 && (!TARGET_SPE_ABI
18171 || info->spe_64bit_regs_used == 0)
18172 && info->first_gp_reg_save < 31
18173 && noclobber_global_gprs);
18174 /* Don't bother to try to save things out-of-line if r11 is occupied
18175 by the static chain. It would require too much fiddling and the
18176 static chain is rarely used anyway. */
18177 common = (using_static_chain_p
18178 || sibcall
18179 || crtl->calls_eh_return
18180 || !info->lr_save_p
18181 || cfun->machine->ra_need_lr
18182 || info->total_size > 32767);
18183 savres_fprs_inline = (common
18184 || info->first_fp_reg_save == 64
18185 || !no_global_regs_above (info->first_fp_reg_save,
18186 /*gpr=*/false)
18187 || FP_SAVE_INLINE (info->first_fp_reg_save));
18188 savres_gprs_inline = (common
18189 /* Saving CR interferes with the exit routines
18190 used on the SPE, so just punt here. */
18191 || (!savep
18192 && TARGET_SPE_ABI
18193 && info->spe_64bit_regs_used != 0
18194 && info->cr_save_p != 0)
18195 || info->first_gp_reg_save == 32
18196 || !noclobber_global_gprs
18197 || GP_SAVE_INLINE (info->first_gp_reg_save));
18199 if (savep)
18200 /* If we are going to use store multiple, then don't even bother
18201 with the out-of-line routines, since the store-multiple instruction
18202 will always be smaller. */
18203 savres_gprs_inline = savres_gprs_inline || using_multiple_p;
18204 else
18206 /* The situation is more complicated with load multiple. We'd
18207 prefer to use the out-of-line routines for restores, since the
18208 "exit" out-of-line routines can handle the restore of LR and
18209 the frame teardown. But we can only use the out-of-line
18210 routines if we know that we've used store multiple or
18211 out-of-line routines in the prologue, i.e. if we've saved all
18212 the registers from first_gp_reg_save. Otherwise, we risk
18213 loading garbage from the stack. Furthermore, we can only use
18214 the "exit" out-of-line gpr restore if we haven't saved any
18215 fprs. */
18216 bool saved_all = !savres_gprs_inline || using_multiple_p;
18218 if (saved_all && info->first_fp_reg_save != 64)
18219 /* We can't use the exit routine; use load multiple if it's
18220 available. */
18221 savres_gprs_inline = savres_gprs_inline || using_multiple_p;
18224 return (using_multiple_p
18225 | (savres_fprs_inline << 1)
18226 | (savres_gprs_inline << 2));
18229 /* Emit function prologue as insns. */
18231 void
18232 rs6000_emit_prologue (void)
18234 rs6000_stack_t *info = rs6000_stack_info ();
18235 enum machine_mode reg_mode = Pmode;
18236 int reg_size = TARGET_32BIT ? 4 : 8;
18237 rtx sp_reg_rtx = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
18238 rtx frame_ptr_rtx = gen_rtx_REG (Pmode, 12);
18239 rtx frame_reg_rtx = sp_reg_rtx;
18240 rtx cr_save_rtx = NULL_RTX;
18241 rtx insn;
18242 int strategy;
18243 int saving_FPRs_inline;
18244 int saving_GPRs_inline;
18245 int using_store_multiple;
18246 int using_static_chain_p = (cfun->static_chain_decl != NULL_TREE
18247 && df_regs_ever_live_p (STATIC_CHAIN_REGNUM)
18248 && !call_used_regs[STATIC_CHAIN_REGNUM]);
18249 HOST_WIDE_INT sp_offset = 0;
18251 if (TARGET_FIX_AND_CONTINUE)
18253 /* gdb on darwin arranges to forward a function from the old
18254 address by modifying the first 5 instructions of the function
18255 to branch to the overriding function. This is necessary to
18256 permit function pointers that point to the old function to
18257 actually forward to the new function. */
18258 emit_insn (gen_nop ());
18259 emit_insn (gen_nop ());
18260 emit_insn (gen_nop ());
18261 emit_insn (gen_nop ());
18262 emit_insn (gen_nop ());
18265 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
18267 reg_mode = V2SImode;
18268 reg_size = 8;
18271 strategy = rs6000_savres_strategy (info, /*savep=*/true,
18272 /*static_chain_p=*/using_static_chain_p,
18273 /*sibcall=*/0);
18274 using_store_multiple = strategy & SAVRES_MULTIPLE;
18275 saving_FPRs_inline = strategy & SAVRES_INLINE_FPRS;
18276 saving_GPRs_inline = strategy & SAVRES_INLINE_GPRS;
18278 /* For V.4, update stack before we do any saving and set back pointer. */
18279 if (! WORLD_SAVE_P (info)
18280 && info->push_p
18281 && (DEFAULT_ABI == ABI_V4
18282 || crtl->calls_eh_return))
18284 bool need_r11 = (TARGET_SPE
18285 ? (!saving_GPRs_inline
18286 && info->spe_64bit_regs_used == 0)
18287 : (!saving_FPRs_inline || !saving_GPRs_inline));
18288 if (info->total_size < 32767)
18289 sp_offset = info->total_size;
18290 else
18291 frame_reg_rtx = (need_r11
18292 ? gen_rtx_REG (Pmode, 11)
18293 : frame_ptr_rtx);
18294 rs6000_emit_allocate_stack (info->total_size,
18295 (frame_reg_rtx != sp_reg_rtx
18296 && (info->cr_save_p
18297 || info->lr_save_p
18298 || info->first_fp_reg_save < 64
18299 || info->first_gp_reg_save < 32
18301 need_r11);
18302 if (frame_reg_rtx != sp_reg_rtx)
18303 rs6000_emit_stack_tie ();
18306 /* Handle world saves specially here. */
18307 if (WORLD_SAVE_P (info))
18309 int i, j, sz;
18310 rtx treg;
18311 rtvec p;
18312 rtx reg0;
18314 /* save_world expects lr in r0. */
18315 reg0 = gen_rtx_REG (Pmode, 0);
18316 if (info->lr_save_p)
18318 insn = emit_move_insn (reg0,
18319 gen_rtx_REG (Pmode, LR_REGNO));
18320 RTX_FRAME_RELATED_P (insn) = 1;
18323 /* The SAVE_WORLD and RESTORE_WORLD routines make a number of
18324 assumptions about the offsets of various bits of the stack
18325 frame. */
18326 gcc_assert (info->gp_save_offset == -220
18327 && info->fp_save_offset == -144
18328 && info->lr_save_offset == 8
18329 && info->cr_save_offset == 4
18330 && info->push_p
18331 && info->lr_save_p
18332 && (!crtl->calls_eh_return
18333 || info->ehrd_offset == -432)
18334 && info->vrsave_save_offset == -224
18335 && info->altivec_save_offset == -416);
18337 treg = gen_rtx_REG (SImode, 11);
18338 emit_move_insn (treg, GEN_INT (-info->total_size));
18340 /* SAVE_WORLD takes the caller's LR in R0 and the frame size
18341 in R11. It also clobbers R12, so beware! */
18343 /* Preserve CR2 for save_world prologues */
18344 sz = 5;
18345 sz += 32 - info->first_gp_reg_save;
18346 sz += 64 - info->first_fp_reg_save;
18347 sz += LAST_ALTIVEC_REGNO - info->first_altivec_reg_save + 1;
18348 p = rtvec_alloc (sz);
18349 j = 0;
18350 RTVEC_ELT (p, j++) = gen_rtx_CLOBBER (VOIDmode,
18351 gen_rtx_REG (SImode,
18352 LR_REGNO));
18353 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
18354 gen_rtx_SYMBOL_REF (Pmode,
18355 "*save_world"));
18356 /* We do floats first so that the instruction pattern matches
18357 properly. */
18358 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
18360 rtx reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
18361 ? DFmode : SFmode),
18362 info->first_fp_reg_save + i);
18363 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18364 GEN_INT (info->fp_save_offset
18365 + sp_offset + 8 * i));
18366 rtx mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
18367 ? DFmode : SFmode), addr);
18369 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
18371 for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++)
18373 rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i);
18374 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18375 GEN_INT (info->altivec_save_offset
18376 + sp_offset + 16 * i));
18377 rtx mem = gen_frame_mem (V4SImode, addr);
18379 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
18381 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
18383 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
18384 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18385 GEN_INT (info->gp_save_offset
18386 + sp_offset + reg_size * i));
18387 rtx mem = gen_frame_mem (reg_mode, addr);
18389 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
18393 /* CR register traditionally saved as CR2. */
18394 rtx reg = gen_rtx_REG (reg_mode, CR2_REGNO);
18395 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18396 GEN_INT (info->cr_save_offset
18397 + sp_offset));
18398 rtx mem = gen_frame_mem (reg_mode, addr);
18400 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
18402 /* Explain about use of R0. */
18403 if (info->lr_save_p)
18405 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18406 GEN_INT (info->lr_save_offset
18407 + sp_offset));
18408 rtx mem = gen_frame_mem (reg_mode, addr);
18410 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg0);
18412 /* Explain what happens to the stack pointer. */
18414 rtx newval = gen_rtx_PLUS (Pmode, sp_reg_rtx, treg);
18415 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, sp_reg_rtx, newval);
18418 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
18419 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
18420 treg, GEN_INT (-info->total_size));
18421 sp_offset = info->total_size;
18424 /* If we use the link register, get it into r0. */
18425 if (!WORLD_SAVE_P (info) && info->lr_save_p)
18427 rtx addr, reg, mem;
18429 insn = emit_move_insn (gen_rtx_REG (Pmode, 0),
18430 gen_rtx_REG (Pmode, LR_REGNO));
18431 RTX_FRAME_RELATED_P (insn) = 1;
18433 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18434 GEN_INT (info->lr_save_offset + sp_offset));
18435 reg = gen_rtx_REG (Pmode, 0);
18436 mem = gen_rtx_MEM (Pmode, addr);
18437 /* This should not be of rs6000_sr_alias_set, because of
18438 __builtin_return_address. */
18440 insn = emit_move_insn (mem, reg);
18441 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
18442 NULL_RTX, NULL_RTX);
18445 /* If we need to save CR, put it into r12. */
18446 if (!WORLD_SAVE_P (info) && info->cr_save_p && frame_reg_rtx != frame_ptr_rtx)
18448 rtx set;
18450 cr_save_rtx = gen_rtx_REG (SImode, 12);
18451 insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
18452 RTX_FRAME_RELATED_P (insn) = 1;
18453 /* Now, there's no way that dwarf2out_frame_debug_expr is going
18454 to understand '(unspec:SI [(reg:CC 68) ...] UNSPEC_MOVESI_FROM_CR)'.
18455 But that's OK. All we have to do is specify that _one_ condition
18456 code register is saved in this stack slot. The thrower's epilogue
18457 will then restore all the call-saved registers.
18458 We use CR2_REGNO (70) to be compatible with gcc-2.95 on Linux. */
18459 set = gen_rtx_SET (VOIDmode, cr_save_rtx,
18460 gen_rtx_REG (SImode, CR2_REGNO));
18461 add_reg_note (insn, REG_FRAME_RELATED_EXPR, set);
18464 /* Do any required saving of fpr's. If only one or two to save, do
18465 it ourselves. Otherwise, call function. */
18466 if (!WORLD_SAVE_P (info) && saving_FPRs_inline)
18468 int i;
18469 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
18470 if ((df_regs_ever_live_p (info->first_fp_reg_save+i)
18471 && ! call_used_regs[info->first_fp_reg_save+i]))
18472 emit_frame_save (frame_reg_rtx, frame_ptr_rtx,
18473 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
18474 ? DFmode : SFmode,
18475 info->first_fp_reg_save + i,
18476 info->fp_save_offset + sp_offset + 8 * i,
18477 info->total_size);
18479 else if (!WORLD_SAVE_P (info) && info->first_fp_reg_save != 64)
18481 rtx par;
18483 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
18484 info->fp_save_offset + sp_offset,
18485 DFmode,
18486 /*savep=*/true, /*gpr=*/false,
18487 /*exitp=*/false);
18488 insn = emit_insn (par);
18489 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
18490 NULL_RTX, NULL_RTX);
18493 /* Save GPRs. This is done as a PARALLEL if we are using
18494 the store-multiple instructions. */
18495 if (!WORLD_SAVE_P (info)
18496 && TARGET_SPE_ABI
18497 && info->spe_64bit_regs_used != 0
18498 && info->first_gp_reg_save != 32)
18500 int i;
18501 rtx spe_save_area_ptr;
18503 /* Determine whether we can address all of the registers that need
18504 to be saved with an offset from the stack pointer that fits in
18505 the small const field for SPE memory instructions. */
18506 int spe_regs_addressable_via_sp
18507 = (SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset
18508 + (32 - info->first_gp_reg_save - 1) * reg_size)
18509 && saving_GPRs_inline);
18510 int spe_offset;
18512 if (spe_regs_addressable_via_sp)
18514 spe_save_area_ptr = frame_reg_rtx;
18515 spe_offset = info->spe_gp_save_offset + sp_offset;
18517 else
18519 /* Make r11 point to the start of the SPE save area. We need
18520 to be careful here if r11 is holding the static chain. If
18521 it is, then temporarily save it in r0. We would use r0 as
18522 our base register here, but using r0 as a base register in
18523 loads and stores means something different from what we
18524 would like. */
18525 int ool_adjust = (saving_GPRs_inline
18527 : (info->first_gp_reg_save
18528 - (FIRST_SAVRES_REGISTER+1))*8);
18529 HOST_WIDE_INT offset = (info->spe_gp_save_offset
18530 + sp_offset - ool_adjust);
18532 if (using_static_chain_p)
18534 rtx r0 = gen_rtx_REG (Pmode, 0);
18535 gcc_assert (info->first_gp_reg_save > 11);
18537 emit_move_insn (r0, gen_rtx_REG (Pmode, 11));
18540 spe_save_area_ptr = gen_rtx_REG (Pmode, 11);
18541 insn = emit_insn (gen_addsi3 (spe_save_area_ptr,
18542 frame_reg_rtx,
18543 GEN_INT (offset)));
18544 /* We need to make sure the move to r11 gets noted for
18545 properly outputting unwind information. */
18546 if (!saving_GPRs_inline)
18547 rs6000_frame_related (insn, frame_reg_rtx, offset,
18548 NULL_RTX, NULL_RTX);
18549 spe_offset = 0;
18552 if (saving_GPRs_inline)
18554 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
18555 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
18557 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
18558 rtx offset, addr, mem;
18560 /* We're doing all this to ensure that the offset fits into
18561 the immediate offset of 'evstdd'. */
18562 gcc_assert (SPE_CONST_OFFSET_OK (reg_size * i + spe_offset));
18564 offset = GEN_INT (reg_size * i + spe_offset);
18565 addr = gen_rtx_PLUS (Pmode, spe_save_area_ptr, offset);
18566 mem = gen_rtx_MEM (V2SImode, addr);
18568 insn = emit_move_insn (mem, reg);
18570 rs6000_frame_related (insn, spe_save_area_ptr,
18571 info->spe_gp_save_offset
18572 + sp_offset + reg_size * i,
18573 offset, const0_rtx);
18576 else
18578 rtx par;
18580 par = rs6000_make_savres_rtx (info, gen_rtx_REG (Pmode, 11),
18581 0, reg_mode,
18582 /*savep=*/true, /*gpr=*/true,
18583 /*exitp=*/false);
18584 insn = emit_insn (par);
18585 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
18586 NULL_RTX, NULL_RTX);
18590 /* Move the static chain pointer back. */
18591 if (using_static_chain_p && !spe_regs_addressable_via_sp)
18592 emit_move_insn (gen_rtx_REG (Pmode, 11), gen_rtx_REG (Pmode, 0));
18594 else if (!WORLD_SAVE_P (info) && !saving_GPRs_inline)
18596 rtx par;
18598 /* Need to adjust r11 if we saved any FPRs. */
18599 if (info->first_fp_reg_save != 64)
18601 rtx r11 = gen_rtx_REG (reg_mode, 11);
18602 rtx offset = GEN_INT (info->total_size
18603 + (-8 * (64-info->first_fp_reg_save)));
18604 rtx ptr_reg = (sp_reg_rtx == frame_reg_rtx
18605 ? sp_reg_rtx : r11);
18607 emit_insn (TARGET_32BIT
18608 ? gen_addsi3 (r11, ptr_reg, offset)
18609 : gen_adddi3 (r11, ptr_reg, offset));
18612 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
18613 info->gp_save_offset + sp_offset,
18614 reg_mode,
18615 /*savep=*/true, /*gpr=*/true,
18616 /*exitp=*/false);
18617 insn = emit_insn (par);
18618 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
18619 NULL_RTX, NULL_RTX);
18621 else if (!WORLD_SAVE_P (info) && using_store_multiple)
18623 rtvec p;
18624 int i;
18625 p = rtvec_alloc (32 - info->first_gp_reg_save);
18626 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
18628 rtx addr, reg, mem;
18629 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
18630 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18631 GEN_INT (info->gp_save_offset
18632 + sp_offset
18633 + reg_size * i));
18634 mem = gen_frame_mem (reg_mode, addr);
18636 RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, mem, reg);
18638 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
18639 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
18640 NULL_RTX, NULL_RTX);
18642 else if (!WORLD_SAVE_P (info))
18644 int i;
18645 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
18646 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
18648 rtx addr, reg, mem;
18649 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
18651 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18652 GEN_INT (info->gp_save_offset
18653 + sp_offset
18654 + reg_size * i));
18655 mem = gen_frame_mem (reg_mode, addr);
18657 insn = emit_move_insn (mem, reg);
18658 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
18659 NULL_RTX, NULL_RTX);
18663 /* ??? There's no need to emit actual instructions here, but it's the
18664 easiest way to get the frame unwind information emitted. */
18665 if (crtl->calls_eh_return)
18667 unsigned int i, regno;
18669 /* In AIX ABI we need to pretend we save r2 here. */
18670 if (TARGET_AIX)
18672 rtx addr, reg, mem;
18674 reg = gen_rtx_REG (reg_mode, 2);
18675 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18676 GEN_INT (sp_offset + 5 * reg_size));
18677 mem = gen_frame_mem (reg_mode, addr);
18679 insn = emit_move_insn (mem, reg);
18680 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
18681 NULL_RTX, NULL_RTX);
18682 PATTERN (insn) = gen_blockage ();
18685 for (i = 0; ; ++i)
18687 regno = EH_RETURN_DATA_REGNO (i);
18688 if (regno == INVALID_REGNUM)
18689 break;
18691 emit_frame_save (frame_reg_rtx, frame_ptr_rtx, reg_mode, regno,
18692 info->ehrd_offset + sp_offset
18693 + reg_size * (int) i,
18694 info->total_size);
18698 /* Save CR if we use any that must be preserved. */
18699 if (!WORLD_SAVE_P (info) && info->cr_save_p)
18701 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18702 GEN_INT (info->cr_save_offset + sp_offset));
18703 rtx mem = gen_frame_mem (SImode, addr);
18704 /* See the large comment above about why CR2_REGNO is used. */
18705 rtx magic_eh_cr_reg = gen_rtx_REG (SImode, CR2_REGNO);
18707 /* If r12 was used to hold the original sp, copy cr into r0 now
18708 that it's free. */
18709 if (REGNO (frame_reg_rtx) == 12)
18711 rtx set;
18713 cr_save_rtx = gen_rtx_REG (SImode, 0);
18714 insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
18715 RTX_FRAME_RELATED_P (insn) = 1;
18716 set = gen_rtx_SET (VOIDmode, cr_save_rtx, magic_eh_cr_reg);
18717 add_reg_note (insn, REG_FRAME_RELATED_EXPR, set);
18719 insn = emit_move_insn (mem, cr_save_rtx);
18721 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
18722 NULL_RTX, NULL_RTX);
18725 /* Update stack and set back pointer unless this is V.4,
18726 for which it was done previously. */
18727 if (!WORLD_SAVE_P (info) && info->push_p
18728 && !(DEFAULT_ABI == ABI_V4 || crtl->calls_eh_return))
18730 if (info->total_size < 32767)
18731 sp_offset = info->total_size;
18732 else
18733 frame_reg_rtx = frame_ptr_rtx;
18734 rs6000_emit_allocate_stack (info->total_size,
18735 (frame_reg_rtx != sp_reg_rtx
18736 && ((info->altivec_size != 0)
18737 || (info->vrsave_mask != 0)
18739 FALSE);
18740 if (frame_reg_rtx != sp_reg_rtx)
18741 rs6000_emit_stack_tie ();
18744 /* Set frame pointer, if needed. */
18745 if (frame_pointer_needed)
18747 insn = emit_move_insn (gen_rtx_REG (Pmode, HARD_FRAME_POINTER_REGNUM),
18748 sp_reg_rtx);
18749 RTX_FRAME_RELATED_P (insn) = 1;
18752 /* Save AltiVec registers if needed. Save here because the red zone does
18753 not include AltiVec registers. */
18754 if (!WORLD_SAVE_P (info) && TARGET_ALTIVEC_ABI && info->altivec_size != 0)
18756 int i;
18758 /* There should be a non inline version of this, for when we
18759 are saving lots of vector registers. */
18760 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
18761 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
18763 rtx areg, savereg, mem;
18764 int offset;
18766 offset = info->altivec_save_offset + sp_offset
18767 + 16 * (i - info->first_altivec_reg_save);
18769 savereg = gen_rtx_REG (V4SImode, i);
18771 areg = gen_rtx_REG (Pmode, 0);
18772 emit_move_insn (areg, GEN_INT (offset));
18774 /* AltiVec addressing mode is [reg+reg]. */
18775 mem = gen_frame_mem (V4SImode,
18776 gen_rtx_PLUS (Pmode, frame_reg_rtx, areg));
18778 insn = emit_move_insn (mem, savereg);
18780 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
18781 areg, GEN_INT (offset));
18785 /* VRSAVE is a bit vector representing which AltiVec registers
18786 are used. The OS uses this to determine which vector
18787 registers to save on a context switch. We need to save
18788 VRSAVE on the stack frame, add whatever AltiVec registers we
18789 used in this function, and do the corresponding magic in the
18790 epilogue. */
18792 if (TARGET_ALTIVEC && TARGET_ALTIVEC_VRSAVE
18793 && info->vrsave_mask != 0)
18795 rtx reg, mem, vrsave;
18796 int offset;
18798 /* Get VRSAVE onto a GPR. Note that ABI_V4 might be using r12
18799 as frame_reg_rtx and r11 as the static chain pointer for
18800 nested functions. */
18801 reg = gen_rtx_REG (SImode, 0);
18802 vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
18803 if (TARGET_MACHO)
18804 emit_insn (gen_get_vrsave_internal (reg));
18805 else
18806 emit_insn (gen_rtx_SET (VOIDmode, reg, vrsave));
18808 if (!WORLD_SAVE_P (info))
18810 /* Save VRSAVE. */
18811 offset = info->vrsave_save_offset + sp_offset;
18812 mem = gen_frame_mem (SImode,
18813 gen_rtx_PLUS (Pmode, frame_reg_rtx,
18814 GEN_INT (offset)));
18815 insn = emit_move_insn (mem, reg);
18818 /* Include the registers in the mask. */
18819 emit_insn (gen_iorsi3 (reg, reg, GEN_INT ((int) info->vrsave_mask)));
18821 insn = emit_insn (generate_set_vrsave (reg, info, 0));
18824 /* If we are using RS6000_PIC_OFFSET_TABLE_REGNUM, we need to set it up. */
18825 if ((TARGET_TOC && TARGET_MINIMAL_TOC && get_pool_size () != 0)
18826 || (DEFAULT_ABI == ABI_V4
18827 && (flag_pic == 1 || (flag_pic && TARGET_SECURE_PLT))
18828 && df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM)))
18830 /* If emit_load_toc_table will use the link register, we need to save
18831 it. We use R12 for this purpose because emit_load_toc_table
18832 can use register 0. This allows us to use a plain 'blr' to return
18833 from the procedure more often. */
18834 int save_LR_around_toc_setup = (TARGET_ELF
18835 && DEFAULT_ABI != ABI_AIX
18836 && flag_pic
18837 && ! info->lr_save_p
18838 && EDGE_COUNT (EXIT_BLOCK_PTR->preds) > 0);
18839 if (save_LR_around_toc_setup)
18841 rtx lr = gen_rtx_REG (Pmode, LR_REGNO);
18843 insn = emit_move_insn (frame_ptr_rtx, lr);
18844 RTX_FRAME_RELATED_P (insn) = 1;
18846 rs6000_emit_load_toc_table (TRUE);
18848 insn = emit_move_insn (lr, frame_ptr_rtx);
18849 RTX_FRAME_RELATED_P (insn) = 1;
18851 else
18852 rs6000_emit_load_toc_table (TRUE);
18855 #if TARGET_MACHO
18856 if (DEFAULT_ABI == ABI_DARWIN
18857 && flag_pic && crtl->uses_pic_offset_table)
18859 rtx lr = gen_rtx_REG (Pmode, LR_REGNO);
18860 rtx src = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
18862 /* Save and restore LR locally around this call (in R0). */
18863 if (!info->lr_save_p)
18864 emit_move_insn (gen_rtx_REG (Pmode, 0), lr);
18866 emit_insn (gen_load_macho_picbase (src));
18868 emit_move_insn (gen_rtx_REG (Pmode,
18869 RS6000_PIC_OFFSET_TABLE_REGNUM),
18870 lr);
18872 if (!info->lr_save_p)
18873 emit_move_insn (lr, gen_rtx_REG (Pmode, 0));
18875 #endif
18878 /* Write function prologue. */
18880 static void
18881 rs6000_output_function_prologue (FILE *file,
18882 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
18884 rs6000_stack_t *info = rs6000_stack_info ();
18886 if (TARGET_DEBUG_STACK)
18887 debug_stack_info (info);
18889 /* Write .extern for any function we will call to save and restore
18890 fp values. */
18891 if (info->first_fp_reg_save < 64
18892 && !FP_SAVE_INLINE (info->first_fp_reg_save))
18893 fprintf (file, "\t.extern %s%d%s\n\t.extern %s%d%s\n",
18894 SAVE_FP_PREFIX, info->first_fp_reg_save - 32, SAVE_FP_SUFFIX,
18895 RESTORE_FP_PREFIX, info->first_fp_reg_save - 32, RESTORE_FP_SUFFIX);
18897 /* Write .extern for AIX common mode routines, if needed. */
18898 if (! TARGET_POWER && ! TARGET_POWERPC && ! common_mode_defined)
18900 fputs ("\t.extern __mulh\n", file);
18901 fputs ("\t.extern __mull\n", file);
18902 fputs ("\t.extern __divss\n", file);
18903 fputs ("\t.extern __divus\n", file);
18904 fputs ("\t.extern __quoss\n", file);
18905 fputs ("\t.extern __quous\n", file);
18906 common_mode_defined = 1;
18909 if (! HAVE_prologue)
18911 start_sequence ();
18913 /* A NOTE_INSN_DELETED is supposed to be at the start and end of
18914 the "toplevel" insn chain. */
18915 emit_note (NOTE_INSN_DELETED);
18916 rs6000_emit_prologue ();
18917 emit_note (NOTE_INSN_DELETED);
18919 /* Expand INSN_ADDRESSES so final() doesn't crash. */
18921 rtx insn;
18922 unsigned addr = 0;
18923 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
18925 INSN_ADDRESSES_NEW (insn, addr);
18926 addr += 4;
18930 if (TARGET_DEBUG_STACK)
18931 debug_rtx_list (get_insns (), 100);
18932 final (get_insns (), file, FALSE);
18933 end_sequence ();
18936 rs6000_pic_labelno++;
18939 /* Non-zero if vmx regs are restored before the frame pop, zero if
18940 we restore after the pop when possible. */
18941 #define ALWAYS_RESTORE_ALTIVEC_BEFORE_POP 0
18943 /* Reload CR from REG. */
18945 static void
18946 rs6000_restore_saved_cr (rtx reg, int using_mfcr_multiple)
18948 int count = 0;
18949 int i;
18951 if (using_mfcr_multiple)
18953 for (i = 0; i < 8; i++)
18954 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
18955 count++;
18956 gcc_assert (count);
18959 if (using_mfcr_multiple && count > 1)
18961 rtvec p;
18962 int ndx;
18964 p = rtvec_alloc (count);
18966 ndx = 0;
18967 for (i = 0; i < 8; i++)
18968 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
18970 rtvec r = rtvec_alloc (2);
18971 RTVEC_ELT (r, 0) = reg;
18972 RTVEC_ELT (r, 1) = GEN_INT (1 << (7-i));
18973 RTVEC_ELT (p, ndx) =
18974 gen_rtx_SET (VOIDmode, gen_rtx_REG (CCmode, CR0_REGNO+i),
18975 gen_rtx_UNSPEC (CCmode, r, UNSPEC_MOVESI_TO_CR));
18976 ndx++;
18978 emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
18979 gcc_assert (ndx == count);
18981 else
18982 for (i = 0; i < 8; i++)
18983 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
18985 emit_insn (gen_movsi_to_cr_one (gen_rtx_REG (CCmode,
18986 CR0_REGNO+i),
18987 reg));
18991 /* Return true if OFFSET from stack pointer can be clobbered by signals.
18992 V.4 doesn't have any stack cushion, AIX ABIs have 220 or 288 bytes
18993 below stack pointer not cloberred by signals. */
18995 static inline bool
18996 offset_below_red_zone_p (HOST_WIDE_INT offset)
18998 return offset < (DEFAULT_ABI == ABI_V4
19000 : TARGET_32BIT ? -220 : -288);
19003 /* Emit function epilogue as insns. */
19005 void
19006 rs6000_emit_epilogue (int sibcall)
19008 rs6000_stack_t *info;
19009 int restoring_GPRs_inline;
19010 int restoring_FPRs_inline;
19011 int using_load_multiple;
19012 int using_mtcr_multiple;
19013 int use_backchain_to_restore_sp;
19014 int restore_lr;
19015 int strategy;
19016 int sp_offset = 0;
19017 rtx sp_reg_rtx = gen_rtx_REG (Pmode, 1);
19018 rtx frame_reg_rtx = sp_reg_rtx;
19019 rtx cfa_restores = NULL_RTX;
19020 rtx insn;
19021 enum machine_mode reg_mode = Pmode;
19022 int reg_size = TARGET_32BIT ? 4 : 8;
19023 int i;
19025 info = rs6000_stack_info ();
19027 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
19029 reg_mode = V2SImode;
19030 reg_size = 8;
19033 strategy = rs6000_savres_strategy (info, /*savep=*/false,
19034 /*static_chain_p=*/0, sibcall);
19035 using_load_multiple = strategy & SAVRES_MULTIPLE;
19036 restoring_FPRs_inline = strategy & SAVRES_INLINE_FPRS;
19037 restoring_GPRs_inline = strategy & SAVRES_INLINE_GPRS;
19038 using_mtcr_multiple = (rs6000_cpu == PROCESSOR_PPC601
19039 || rs6000_cpu == PROCESSOR_PPC603
19040 || rs6000_cpu == PROCESSOR_PPC750
19041 || optimize_size);
19042 /* Restore via the backchain when we have a large frame, since this
19043 is more efficient than an addis, addi pair. The second condition
19044 here will not trigger at the moment; We don't actually need a
19045 frame pointer for alloca, but the generic parts of the compiler
19046 give us one anyway. */
19047 use_backchain_to_restore_sp = (info->total_size > 32767
19048 || info->total_size
19049 + (info->lr_save_p ? info->lr_save_offset : 0)
19050 > 32767
19051 || (cfun->calls_alloca
19052 && !frame_pointer_needed));
19053 restore_lr = (info->lr_save_p
19054 && restoring_GPRs_inline
19055 && restoring_FPRs_inline);
19057 if (WORLD_SAVE_P (info))
19059 int i, j;
19060 char rname[30];
19061 const char *alloc_rname;
19062 rtvec p;
19064 /* eh_rest_world_r10 will return to the location saved in the LR
19065 stack slot (which is not likely to be our caller.)
19066 Input: R10 -- stack adjustment. Clobbers R0, R11, R12, R7, R8.
19067 rest_world is similar, except any R10 parameter is ignored.
19068 The exception-handling stuff that was here in 2.95 is no
19069 longer necessary. */
19071 p = rtvec_alloc (9
19073 + 32 - info->first_gp_reg_save
19074 + LAST_ALTIVEC_REGNO + 1 - info->first_altivec_reg_save
19075 + 63 + 1 - info->first_fp_reg_save);
19077 strcpy (rname, ((crtl->calls_eh_return) ?
19078 "*eh_rest_world_r10" : "*rest_world"));
19079 alloc_rname = ggc_strdup (rname);
19081 j = 0;
19082 RTVEC_ELT (p, j++) = gen_rtx_RETURN (VOIDmode);
19083 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
19084 gen_rtx_REG (Pmode,
19085 LR_REGNO));
19086 RTVEC_ELT (p, j++)
19087 = gen_rtx_USE (VOIDmode, gen_rtx_SYMBOL_REF (Pmode, alloc_rname));
19088 /* The instruction pattern requires a clobber here;
19089 it is shared with the restVEC helper. */
19090 RTVEC_ELT (p, j++)
19091 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 11));
19094 /* CR register traditionally saved as CR2. */
19095 rtx reg = gen_rtx_REG (reg_mode, CR2_REGNO);
19096 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19097 GEN_INT (info->cr_save_offset));
19098 rtx mem = gen_frame_mem (reg_mode, addr);
19100 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
19103 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
19105 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
19106 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19107 GEN_INT (info->gp_save_offset
19108 + reg_size * i));
19109 rtx mem = gen_frame_mem (reg_mode, addr);
19111 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
19113 for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++)
19115 rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i);
19116 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19117 GEN_INT (info->altivec_save_offset
19118 + 16 * i));
19119 rtx mem = gen_frame_mem (V4SImode, addr);
19121 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
19123 for (i = 0; info->first_fp_reg_save + i <= 63; i++)
19125 rtx reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
19126 ? DFmode : SFmode),
19127 info->first_fp_reg_save + i);
19128 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19129 GEN_INT (info->fp_save_offset
19130 + 8 * i));
19131 rtx mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
19132 ? DFmode : SFmode), addr);
19134 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
19136 RTVEC_ELT (p, j++)
19137 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 0));
19138 RTVEC_ELT (p, j++)
19139 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 12));
19140 RTVEC_ELT (p, j++)
19141 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 7));
19142 RTVEC_ELT (p, j++)
19143 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 8));
19144 RTVEC_ELT (p, j++)
19145 = gen_rtx_USE (VOIDmode, gen_rtx_REG (SImode, 10));
19146 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
19148 return;
19151 /* frame_reg_rtx + sp_offset points to the top of this stack frame. */
19152 if (info->push_p)
19153 sp_offset = info->total_size;
19155 /* Restore AltiVec registers if we must do so before adjusting the
19156 stack. */
19157 if (TARGET_ALTIVEC_ABI
19158 && info->altivec_size != 0
19159 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
19160 || (DEFAULT_ABI != ABI_V4
19161 && offset_below_red_zone_p (info->altivec_save_offset))))
19163 int i;
19165 if (use_backchain_to_restore_sp)
19167 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
19168 emit_move_insn (frame_reg_rtx,
19169 gen_rtx_MEM (Pmode, sp_reg_rtx));
19170 sp_offset = 0;
19172 else if (frame_pointer_needed)
19173 frame_reg_rtx = hard_frame_pointer_rtx;
19175 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
19176 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
19178 rtx addr, areg, mem, reg;
19180 areg = gen_rtx_REG (Pmode, 0);
19181 emit_move_insn
19182 (areg, GEN_INT (info->altivec_save_offset
19183 + sp_offset
19184 + 16 * (i - info->first_altivec_reg_save)));
19186 /* AltiVec addressing mode is [reg+reg]. */
19187 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
19188 mem = gen_frame_mem (V4SImode, addr);
19190 reg = gen_rtx_REG (V4SImode, i);
19191 emit_move_insn (reg, mem);
19192 if (offset_below_red_zone_p (info->altivec_save_offset
19193 + (i - info->first_altivec_reg_save)
19194 * 16))
19195 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
19196 cfa_restores);
19200 /* Restore VRSAVE if we must do so before adjusting the stack. */
19201 if (TARGET_ALTIVEC
19202 && TARGET_ALTIVEC_VRSAVE
19203 && info->vrsave_mask != 0
19204 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
19205 || (DEFAULT_ABI != ABI_V4
19206 && offset_below_red_zone_p (info->vrsave_save_offset))))
19208 rtx addr, mem, reg;
19210 if (frame_reg_rtx == sp_reg_rtx)
19212 if (use_backchain_to_restore_sp)
19214 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
19215 emit_move_insn (frame_reg_rtx,
19216 gen_rtx_MEM (Pmode, sp_reg_rtx));
19217 sp_offset = 0;
19219 else if (frame_pointer_needed)
19220 frame_reg_rtx = hard_frame_pointer_rtx;
19223 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19224 GEN_INT (info->vrsave_save_offset + sp_offset));
19225 mem = gen_frame_mem (SImode, addr);
19226 reg = gen_rtx_REG (SImode, 12);
19227 emit_move_insn (reg, mem);
19229 emit_insn (generate_set_vrsave (reg, info, 1));
19232 insn = NULL_RTX;
19233 /* If we have a large stack frame, restore the old stack pointer
19234 using the backchain. */
19235 if (use_backchain_to_restore_sp)
19237 if (frame_reg_rtx == sp_reg_rtx)
19239 /* Under V.4, don't reset the stack pointer until after we're done
19240 loading the saved registers. */
19241 if (DEFAULT_ABI == ABI_V4)
19242 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
19244 insn = emit_move_insn (frame_reg_rtx,
19245 gen_rtx_MEM (Pmode, sp_reg_rtx));
19246 sp_offset = 0;
19248 else if (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
19249 && DEFAULT_ABI == ABI_V4)
19250 /* frame_reg_rtx has been set up by the altivec restore. */
19252 else
19254 insn = emit_move_insn (sp_reg_rtx, frame_reg_rtx);
19255 frame_reg_rtx = sp_reg_rtx;
19258 /* If we have a frame pointer, we can restore the old stack pointer
19259 from it. */
19260 else if (frame_pointer_needed)
19262 frame_reg_rtx = sp_reg_rtx;
19263 if (DEFAULT_ABI == ABI_V4)
19264 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
19266 insn = emit_insn (gen_add3_insn (frame_reg_rtx, hard_frame_pointer_rtx,
19267 GEN_INT (info->total_size)));
19268 sp_offset = 0;
19270 else if (info->push_p
19271 && DEFAULT_ABI != ABI_V4
19272 && !crtl->calls_eh_return)
19274 insn = emit_insn (gen_add3_insn (sp_reg_rtx, sp_reg_rtx,
19275 GEN_INT (info->total_size)));
19276 sp_offset = 0;
19278 if (insn && frame_reg_rtx == sp_reg_rtx)
19280 if (cfa_restores)
19282 REG_NOTES (insn) = cfa_restores;
19283 cfa_restores = NULL_RTX;
19285 add_reg_note (insn, REG_CFA_DEF_CFA, sp_reg_rtx);
19286 RTX_FRAME_RELATED_P (insn) = 1;
19289 /* Restore AltiVec registers if we have not done so already. */
19290 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
19291 && TARGET_ALTIVEC_ABI
19292 && info->altivec_size != 0
19293 && (DEFAULT_ABI == ABI_V4
19294 || !offset_below_red_zone_p (info->altivec_save_offset)))
19296 int i;
19298 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
19299 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
19301 rtx addr, areg, mem, reg;
19303 areg = gen_rtx_REG (Pmode, 0);
19304 emit_move_insn
19305 (areg, GEN_INT (info->altivec_save_offset
19306 + sp_offset
19307 + 16 * (i - info->first_altivec_reg_save)));
19309 /* AltiVec addressing mode is [reg+reg]. */
19310 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
19311 mem = gen_frame_mem (V4SImode, addr);
19313 reg = gen_rtx_REG (V4SImode, i);
19314 emit_move_insn (reg, mem);
19315 if (DEFAULT_ABI == ABI_V4)
19316 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
19317 cfa_restores);
19321 /* Restore VRSAVE if we have not done so already. */
19322 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
19323 && TARGET_ALTIVEC
19324 && TARGET_ALTIVEC_VRSAVE
19325 && info->vrsave_mask != 0
19326 && (DEFAULT_ABI == ABI_V4
19327 || !offset_below_red_zone_p (info->vrsave_save_offset)))
19329 rtx addr, mem, reg;
19331 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19332 GEN_INT (info->vrsave_save_offset + sp_offset));
19333 mem = gen_frame_mem (SImode, addr);
19334 reg = gen_rtx_REG (SImode, 12);
19335 emit_move_insn (reg, mem);
19337 emit_insn (generate_set_vrsave (reg, info, 1));
19340 /* Get the old lr if we saved it. If we are restoring registers
19341 out-of-line, then the out-of-line routines can do this for us. */
19342 if (restore_lr)
19344 rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
19345 info->lr_save_offset + sp_offset);
19347 emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
19350 /* Get the old cr if we saved it. */
19351 if (info->cr_save_p)
19353 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19354 GEN_INT (info->cr_save_offset + sp_offset));
19355 rtx mem = gen_frame_mem (SImode, addr);
19357 emit_move_insn (gen_rtx_REG (SImode, 12), mem);
19360 /* Set LR here to try to overlap restores below. LR is always saved
19361 above incoming stack, so it never needs REG_CFA_RESTORE. */
19362 if (restore_lr)
19363 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO),
19364 gen_rtx_REG (Pmode, 0));
19366 /* Load exception handler data registers, if needed. */
19367 if (crtl->calls_eh_return)
19369 unsigned int i, regno;
19371 if (TARGET_AIX)
19373 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19374 GEN_INT (sp_offset + 5 * reg_size));
19375 rtx mem = gen_frame_mem (reg_mode, addr);
19377 emit_move_insn (gen_rtx_REG (reg_mode, 2), mem);
19380 for (i = 0; ; ++i)
19382 rtx mem;
19384 regno = EH_RETURN_DATA_REGNO (i);
19385 if (regno == INVALID_REGNUM)
19386 break;
19388 mem = gen_frame_mem_offset (reg_mode, frame_reg_rtx,
19389 info->ehrd_offset + sp_offset
19390 + reg_size * (int) i);
19392 emit_move_insn (gen_rtx_REG (reg_mode, regno), mem);
19396 /* Restore GPRs. This is done as a PARALLEL if we are using
19397 the load-multiple instructions. */
19398 if (TARGET_SPE_ABI
19399 && info->spe_64bit_regs_used != 0
19400 && info->first_gp_reg_save != 32)
19402 /* Determine whether we can address all of the registers that need
19403 to be saved with an offset from the stack pointer that fits in
19404 the small const field for SPE memory instructions. */
19405 int spe_regs_addressable_via_sp
19406 = (SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset
19407 + (32 - info->first_gp_reg_save - 1) * reg_size)
19408 && restoring_GPRs_inline);
19409 int spe_offset;
19411 if (spe_regs_addressable_via_sp)
19412 spe_offset = info->spe_gp_save_offset + sp_offset;
19413 else
19415 rtx old_frame_reg_rtx = frame_reg_rtx;
19416 /* Make r11 point to the start of the SPE save area. We worried about
19417 not clobbering it when we were saving registers in the prologue.
19418 There's no need to worry here because the static chain is passed
19419 anew to every function. */
19420 int ool_adjust = (restoring_GPRs_inline
19422 : (info->first_gp_reg_save
19423 - (FIRST_SAVRES_REGISTER+1))*8);
19425 if (frame_reg_rtx == sp_reg_rtx)
19426 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
19427 emit_insn (gen_addsi3 (frame_reg_rtx, old_frame_reg_rtx,
19428 GEN_INT (info->spe_gp_save_offset
19429 + sp_offset
19430 - ool_adjust)));
19431 /* Keep the invariant that frame_reg_rtx + sp_offset points
19432 at the top of the stack frame. */
19433 sp_offset = -info->spe_gp_save_offset;
19435 spe_offset = 0;
19438 if (restoring_GPRs_inline)
19440 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
19441 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
19443 rtx offset, addr, mem, reg;
19445 /* We're doing all this to ensure that the immediate offset
19446 fits into the immediate field of 'evldd'. */
19447 gcc_assert (SPE_CONST_OFFSET_OK (spe_offset + reg_size * i));
19449 offset = GEN_INT (spe_offset + reg_size * i);
19450 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, offset);
19451 mem = gen_rtx_MEM (V2SImode, addr);
19452 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
19454 insn = emit_move_insn (reg, mem);
19455 if (DEFAULT_ABI == ABI_V4)
19457 if (frame_pointer_needed
19458 && info->first_gp_reg_save + i
19459 == HARD_FRAME_POINTER_REGNUM)
19461 add_reg_note (insn, REG_CFA_DEF_CFA,
19462 plus_constant (frame_reg_rtx,
19463 sp_offset));
19464 RTX_FRAME_RELATED_P (insn) = 1;
19467 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
19468 cfa_restores);
19472 else
19474 rtx par;
19476 par = rs6000_make_savres_rtx (info, gen_rtx_REG (Pmode, 11),
19477 0, reg_mode,
19478 /*savep=*/false, /*gpr=*/true,
19479 /*exitp=*/true);
19480 emit_jump_insn (par);
19481 /* We don't want anybody else emitting things after we jumped
19482 back. */
19483 return;
19486 else if (!restoring_GPRs_inline)
19488 /* We are jumping to an out-of-line function. */
19489 bool can_use_exit = info->first_fp_reg_save == 64;
19490 rtx par;
19492 /* Emit stack reset code if we need it. */
19493 if (can_use_exit)
19494 rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx,
19495 sp_offset, can_use_exit);
19496 else
19497 emit_insn (gen_addsi3 (gen_rtx_REG (Pmode, 11),
19498 sp_reg_rtx,
19499 GEN_INT (sp_offset - info->fp_size)));
19501 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
19502 info->gp_save_offset, reg_mode,
19503 /*savep=*/false, /*gpr=*/true,
19504 /*exitp=*/can_use_exit);
19506 if (can_use_exit)
19508 if (info->cr_save_p)
19510 rs6000_restore_saved_cr (gen_rtx_REG (SImode, 12),
19511 using_mtcr_multiple);
19512 if (DEFAULT_ABI == ABI_V4)
19513 cfa_restores
19514 = alloc_reg_note (REG_CFA_RESTORE,
19515 gen_rtx_REG (SImode, CR2_REGNO),
19516 cfa_restores);
19519 emit_jump_insn (par);
19521 /* We don't want anybody else emitting things after we jumped
19522 back. */
19523 return;
19526 insn = emit_insn (par);
19527 if (DEFAULT_ABI == ABI_V4)
19529 if (frame_pointer_needed)
19531 add_reg_note (insn, REG_CFA_DEF_CFA,
19532 plus_constant (frame_reg_rtx, sp_offset));
19533 RTX_FRAME_RELATED_P (insn) = 1;
19536 for (i = info->first_gp_reg_save; i < 32; i++)
19537 cfa_restores
19538 = alloc_reg_note (REG_CFA_RESTORE,
19539 gen_rtx_REG (reg_mode, i), cfa_restores);
19542 else if (using_load_multiple)
19544 rtvec p;
19545 p = rtvec_alloc (32 - info->first_gp_reg_save);
19546 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
19548 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19549 GEN_INT (info->gp_save_offset
19550 + sp_offset
19551 + reg_size * i));
19552 rtx mem = gen_frame_mem (reg_mode, addr);
19553 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
19555 RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, reg, mem);
19556 if (DEFAULT_ABI == ABI_V4)
19557 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
19558 cfa_restores);
19560 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
19561 if (DEFAULT_ABI == ABI_V4 && frame_pointer_needed)
19563 add_reg_note (insn, REG_CFA_DEF_CFA,
19564 plus_constant (frame_reg_rtx, sp_offset));
19565 RTX_FRAME_RELATED_P (insn) = 1;
19568 else
19570 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
19571 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
19573 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19574 GEN_INT (info->gp_save_offset
19575 + sp_offset
19576 + reg_size * i));
19577 rtx mem = gen_frame_mem (reg_mode, addr);
19578 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
19580 insn = emit_move_insn (reg, mem);
19581 if (DEFAULT_ABI == ABI_V4)
19583 if (frame_pointer_needed
19584 && info->first_gp_reg_save + i
19585 == HARD_FRAME_POINTER_REGNUM)
19587 add_reg_note (insn, REG_CFA_DEF_CFA,
19588 plus_constant (frame_reg_rtx, sp_offset));
19589 RTX_FRAME_RELATED_P (insn) = 1;
19592 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
19593 cfa_restores);
19598 /* Restore fpr's if we need to do it without calling a function. */
19599 if (restoring_FPRs_inline)
19600 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
19601 if ((df_regs_ever_live_p (info->first_fp_reg_save+i)
19602 && ! call_used_regs[info->first_fp_reg_save+i]))
19604 rtx addr, mem, reg;
19605 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19606 GEN_INT (info->fp_save_offset
19607 + sp_offset
19608 + 8 * i));
19609 mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
19610 ? DFmode : SFmode), addr);
19611 reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
19612 ? DFmode : SFmode),
19613 info->first_fp_reg_save + i);
19615 emit_move_insn (reg, mem);
19616 if (DEFAULT_ABI == ABI_V4)
19617 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
19618 cfa_restores);
19621 /* If we saved cr, restore it here. Just those that were used. */
19622 if (info->cr_save_p)
19624 rs6000_restore_saved_cr (gen_rtx_REG (SImode, 12), using_mtcr_multiple);
19625 if (DEFAULT_ABI == ABI_V4)
19626 cfa_restores
19627 = alloc_reg_note (REG_CFA_RESTORE, gen_rtx_REG (SImode, CR2_REGNO),
19628 cfa_restores);
19631 /* If this is V.4, unwind the stack pointer after all of the loads
19632 have been done. */
19633 insn = rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx,
19634 sp_offset, !restoring_FPRs_inline);
19635 if (insn)
19637 if (cfa_restores)
19639 REG_NOTES (insn) = cfa_restores;
19640 cfa_restores = NULL_RTX;
19642 add_reg_note (insn, REG_CFA_DEF_CFA, sp_reg_rtx);
19643 RTX_FRAME_RELATED_P (insn) = 1;
19646 if (crtl->calls_eh_return)
19648 rtx sa = EH_RETURN_STACKADJ_RTX;
19649 emit_insn (gen_add3_insn (sp_reg_rtx, sp_reg_rtx, sa));
19652 if (!sibcall)
19654 rtvec p;
19655 if (! restoring_FPRs_inline)
19656 p = rtvec_alloc (4 + 64 - info->first_fp_reg_save);
19657 else
19658 p = rtvec_alloc (2);
19660 RTVEC_ELT (p, 0) = gen_rtx_RETURN (VOIDmode);
19661 RTVEC_ELT (p, 1) = (restoring_FPRs_inline
19662 ? gen_rtx_USE (VOIDmode, gen_rtx_REG (Pmode, 65))
19663 : gen_rtx_CLOBBER (VOIDmode,
19664 gen_rtx_REG (Pmode, 65)));
19666 /* If we have to restore more than two FP registers, branch to the
19667 restore function. It will return to our caller. */
19668 if (! restoring_FPRs_inline)
19670 int i;
19671 rtx sym;
19673 sym = rs6000_savres_routine_sym (info,
19674 /*savep=*/false,
19675 /*gpr=*/false,
19676 /*exitp=*/true);
19677 RTVEC_ELT (p, 2) = gen_rtx_USE (VOIDmode, sym);
19678 RTVEC_ELT (p, 3) = gen_rtx_USE (VOIDmode,
19679 gen_rtx_REG (Pmode, 11));
19680 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
19682 rtx addr, mem;
19683 addr = gen_rtx_PLUS (Pmode, sp_reg_rtx,
19684 GEN_INT (info->fp_save_offset + 8*i));
19685 mem = gen_frame_mem (DFmode, addr);
19687 RTVEC_ELT (p, i+4) =
19688 gen_rtx_SET (VOIDmode,
19689 gen_rtx_REG (DFmode, info->first_fp_reg_save + i),
19690 mem);
19694 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
19698 /* Write function epilogue. */
19700 static void
19701 rs6000_output_function_epilogue (FILE *file,
19702 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
19704 if (! HAVE_epilogue)
19706 rtx insn = get_last_insn ();
19707 /* If the last insn was a BARRIER, we don't have to write anything except
19708 the trace table. */
19709 if (GET_CODE (insn) == NOTE)
19710 insn = prev_nonnote_insn (insn);
19711 if (insn == 0 || GET_CODE (insn) != BARRIER)
19713 /* This is slightly ugly, but at least we don't have two
19714 copies of the epilogue-emitting code. */
19715 start_sequence ();
19717 /* A NOTE_INSN_DELETED is supposed to be at the start
19718 and end of the "toplevel" insn chain. */
19719 emit_note (NOTE_INSN_DELETED);
19720 rs6000_emit_epilogue (FALSE);
19721 emit_note (NOTE_INSN_DELETED);
19723 /* Expand INSN_ADDRESSES so final() doesn't crash. */
19725 rtx insn;
19726 unsigned addr = 0;
19727 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
19729 INSN_ADDRESSES_NEW (insn, addr);
19730 addr += 4;
19734 if (TARGET_DEBUG_STACK)
19735 debug_rtx_list (get_insns (), 100);
19736 final (get_insns (), file, FALSE);
19737 end_sequence ();
19741 #if TARGET_MACHO
19742 macho_branch_islands ();
19743 /* Mach-O doesn't support labels at the end of objects, so if
19744 it looks like we might want one, insert a NOP. */
19746 rtx insn = get_last_insn ();
19747 while (insn
19748 && NOTE_P (insn)
19749 && NOTE_KIND (insn) != NOTE_INSN_DELETED_LABEL)
19750 insn = PREV_INSN (insn);
19751 if (insn
19752 && (LABEL_P (insn)
19753 || (NOTE_P (insn)
19754 && NOTE_KIND (insn) == NOTE_INSN_DELETED_LABEL)))
19755 fputs ("\tnop\n", file);
19757 #endif
19759 /* Output a traceback table here. See /usr/include/sys/debug.h for info
19760 on its format.
19762 We don't output a traceback table if -finhibit-size-directive was
19763 used. The documentation for -finhibit-size-directive reads
19764 ``don't output a @code{.size} assembler directive, or anything
19765 else that would cause trouble if the function is split in the
19766 middle, and the two halves are placed at locations far apart in
19767 memory.'' The traceback table has this property, since it
19768 includes the offset from the start of the function to the
19769 traceback table itself.
19771 System V.4 Powerpc's (and the embedded ABI derived from it) use a
19772 different traceback table. */
19773 if (DEFAULT_ABI == ABI_AIX && ! flag_inhibit_size_directive
19774 && rs6000_traceback != traceback_none && !cfun->is_thunk)
19776 const char *fname = NULL;
19777 const char *language_string = lang_hooks.name;
19778 int fixed_parms = 0, float_parms = 0, parm_info = 0;
19779 int i;
19780 int optional_tbtab;
19781 rs6000_stack_t *info = rs6000_stack_info ();
19783 if (rs6000_traceback == traceback_full)
19784 optional_tbtab = 1;
19785 else if (rs6000_traceback == traceback_part)
19786 optional_tbtab = 0;
19787 else
19788 optional_tbtab = !optimize_size && !TARGET_ELF;
19790 if (optional_tbtab)
19792 fname = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0);
19793 while (*fname == '.') /* V.4 encodes . in the name */
19794 fname++;
19796 /* Need label immediately before tbtab, so we can compute
19797 its offset from the function start. */
19798 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
19799 ASM_OUTPUT_LABEL (file, fname);
19802 /* The .tbtab pseudo-op can only be used for the first eight
19803 expressions, since it can't handle the possibly variable
19804 length fields that follow. However, if you omit the optional
19805 fields, the assembler outputs zeros for all optional fields
19806 anyways, giving each variable length field is minimum length
19807 (as defined in sys/debug.h). Thus we can not use the .tbtab
19808 pseudo-op at all. */
19810 /* An all-zero word flags the start of the tbtab, for debuggers
19811 that have to find it by searching forward from the entry
19812 point or from the current pc. */
19813 fputs ("\t.long 0\n", file);
19815 /* Tbtab format type. Use format type 0. */
19816 fputs ("\t.byte 0,", file);
19818 /* Language type. Unfortunately, there does not seem to be any
19819 official way to discover the language being compiled, so we
19820 use language_string.
19821 C is 0. Fortran is 1. Pascal is 2. Ada is 3. C++ is 9.
19822 Java is 13. Objective-C is 14. Objective-C++ isn't assigned
19823 a number, so for now use 9. */
19824 if (! strcmp (language_string, "GNU C"))
19825 i = 0;
19826 else if (! strcmp (language_string, "GNU F77")
19827 || ! strcmp (language_string, "GNU Fortran"))
19828 i = 1;
19829 else if (! strcmp (language_string, "GNU Pascal"))
19830 i = 2;
19831 else if (! strcmp (language_string, "GNU Ada"))
19832 i = 3;
19833 else if (! strcmp (language_string, "GNU C++")
19834 || ! strcmp (language_string, "GNU Objective-C++"))
19835 i = 9;
19836 else if (! strcmp (language_string, "GNU Java"))
19837 i = 13;
19838 else if (! strcmp (language_string, "GNU Objective-C"))
19839 i = 14;
19840 else
19841 gcc_unreachable ();
19842 fprintf (file, "%d,", i);
19844 /* 8 single bit fields: global linkage (not set for C extern linkage,
19845 apparently a PL/I convention?), out-of-line epilogue/prologue, offset
19846 from start of procedure stored in tbtab, internal function, function
19847 has controlled storage, function has no toc, function uses fp,
19848 function logs/aborts fp operations. */
19849 /* Assume that fp operations are used if any fp reg must be saved. */
19850 fprintf (file, "%d,",
19851 (optional_tbtab << 5) | ((info->first_fp_reg_save != 64) << 1));
19853 /* 6 bitfields: function is interrupt handler, name present in
19854 proc table, function calls alloca, on condition directives
19855 (controls stack walks, 3 bits), saves condition reg, saves
19856 link reg. */
19857 /* The `function calls alloca' bit seems to be set whenever reg 31 is
19858 set up as a frame pointer, even when there is no alloca call. */
19859 fprintf (file, "%d,",
19860 ((optional_tbtab << 6)
19861 | ((optional_tbtab & frame_pointer_needed) << 5)
19862 | (info->cr_save_p << 1)
19863 | (info->lr_save_p)));
19865 /* 3 bitfields: saves backchain, fixup code, number of fpr saved
19866 (6 bits). */
19867 fprintf (file, "%d,",
19868 (info->push_p << 7) | (64 - info->first_fp_reg_save));
19870 /* 2 bitfields: spare bits (2 bits), number of gpr saved (6 bits). */
19871 fprintf (file, "%d,", (32 - first_reg_to_save ()));
19873 if (optional_tbtab)
19875 /* Compute the parameter info from the function decl argument
19876 list. */
19877 tree decl;
19878 int next_parm_info_bit = 31;
19880 for (decl = DECL_ARGUMENTS (current_function_decl);
19881 decl; decl = TREE_CHAIN (decl))
19883 rtx parameter = DECL_INCOMING_RTL (decl);
19884 enum machine_mode mode = GET_MODE (parameter);
19886 if (GET_CODE (parameter) == REG)
19888 if (SCALAR_FLOAT_MODE_P (mode))
19890 int bits;
19892 float_parms++;
19894 switch (mode)
19896 case SFmode:
19897 case SDmode:
19898 bits = 0x2;
19899 break;
19901 case DFmode:
19902 case DDmode:
19903 case TFmode:
19904 case TDmode:
19905 bits = 0x3;
19906 break;
19908 default:
19909 gcc_unreachable ();
19912 /* If only one bit will fit, don't or in this entry. */
19913 if (next_parm_info_bit > 0)
19914 parm_info |= (bits << (next_parm_info_bit - 1));
19915 next_parm_info_bit -= 2;
19917 else
19919 fixed_parms += ((GET_MODE_SIZE (mode)
19920 + (UNITS_PER_WORD - 1))
19921 / UNITS_PER_WORD);
19922 next_parm_info_bit -= 1;
19928 /* Number of fixed point parameters. */
19929 /* This is actually the number of words of fixed point parameters; thus
19930 an 8 byte struct counts as 2; and thus the maximum value is 8. */
19931 fprintf (file, "%d,", fixed_parms);
19933 /* 2 bitfields: number of floating point parameters (7 bits), parameters
19934 all on stack. */
19935 /* This is actually the number of fp registers that hold parameters;
19936 and thus the maximum value is 13. */
19937 /* Set parameters on stack bit if parameters are not in their original
19938 registers, regardless of whether they are on the stack? Xlc
19939 seems to set the bit when not optimizing. */
19940 fprintf (file, "%d\n", ((float_parms << 1) | (! optimize)));
19942 if (! optional_tbtab)
19943 return;
19945 /* Optional fields follow. Some are variable length. */
19947 /* Parameter types, left adjusted bit fields: 0 fixed, 10 single float,
19948 11 double float. */
19949 /* There is an entry for each parameter in a register, in the order that
19950 they occur in the parameter list. Any intervening arguments on the
19951 stack are ignored. If the list overflows a long (max possible length
19952 34 bits) then completely leave off all elements that don't fit. */
19953 /* Only emit this long if there was at least one parameter. */
19954 if (fixed_parms || float_parms)
19955 fprintf (file, "\t.long %d\n", parm_info);
19957 /* Offset from start of code to tb table. */
19958 fputs ("\t.long ", file);
19959 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
19960 if (TARGET_AIX)
19961 RS6000_OUTPUT_BASENAME (file, fname);
19962 else
19963 assemble_name (file, fname);
19964 putc ('-', file);
19965 rs6000_output_function_entry (file, fname);
19966 putc ('\n', file);
19968 /* Interrupt handler mask. */
19969 /* Omit this long, since we never set the interrupt handler bit
19970 above. */
19972 /* Number of CTL (controlled storage) anchors. */
19973 /* Omit this long, since the has_ctl bit is never set above. */
19975 /* Displacement into stack of each CTL anchor. */
19976 /* Omit this list of longs, because there are no CTL anchors. */
19978 /* Length of function name. */
19979 if (*fname == '*')
19980 ++fname;
19981 fprintf (file, "\t.short %d\n", (int) strlen (fname));
19983 /* Function name. */
19984 assemble_string (fname, strlen (fname));
19986 /* Register for alloca automatic storage; this is always reg 31.
19987 Only emit this if the alloca bit was set above. */
19988 if (frame_pointer_needed)
19989 fputs ("\t.byte 31\n", file);
19991 fputs ("\t.align 2\n", file);
19995 /* A C compound statement that outputs the assembler code for a thunk
19996 function, used to implement C++ virtual function calls with
19997 multiple inheritance. The thunk acts as a wrapper around a virtual
19998 function, adjusting the implicit object parameter before handing
19999 control off to the real function.
20001 First, emit code to add the integer DELTA to the location that
20002 contains the incoming first argument. Assume that this argument
20003 contains a pointer, and is the one used to pass the `this' pointer
20004 in C++. This is the incoming argument *before* the function
20005 prologue, e.g. `%o0' on a sparc. The addition must preserve the
20006 values of all other incoming arguments.
20008 After the addition, emit code to jump to FUNCTION, which is a
20009 `FUNCTION_DECL'. This is a direct pure jump, not a call, and does
20010 not touch the return address. Hence returning from FUNCTION will
20011 return to whoever called the current `thunk'.
20013 The effect must be as if FUNCTION had been called directly with the
20014 adjusted first argument. This macro is responsible for emitting
20015 all of the code for a thunk function; output_function_prologue()
20016 and output_function_epilogue() are not invoked.
20018 The THUNK_FNDECL is redundant. (DELTA and FUNCTION have already
20019 been extracted from it.) It might possibly be useful on some
20020 targets, but probably not.
20022 If you do not define this macro, the target-independent code in the
20023 C++ frontend will generate a less efficient heavyweight thunk that
20024 calls FUNCTION instead of jumping to it. The generic approach does
20025 not support varargs. */
20027 static void
20028 rs6000_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
20029 HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
20030 tree function)
20032 rtx this_rtx, insn, funexp;
20034 reload_completed = 1;
20035 epilogue_completed = 1;
20037 /* Mark the end of the (empty) prologue. */
20038 emit_note (NOTE_INSN_PROLOGUE_END);
20040 /* Find the "this" pointer. If the function returns a structure,
20041 the structure return pointer is in r3. */
20042 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function))
20043 this_rtx = gen_rtx_REG (Pmode, 4);
20044 else
20045 this_rtx = gen_rtx_REG (Pmode, 3);
20047 /* Apply the constant offset, if required. */
20048 if (delta)
20050 rtx delta_rtx = GEN_INT (delta);
20051 emit_insn (TARGET_32BIT
20052 ? gen_addsi3 (this_rtx, this_rtx, delta_rtx)
20053 : gen_adddi3 (this_rtx, this_rtx, delta_rtx));
20056 /* Apply the offset from the vtable, if required. */
20057 if (vcall_offset)
20059 rtx vcall_offset_rtx = GEN_INT (vcall_offset);
20060 rtx tmp = gen_rtx_REG (Pmode, 12);
20062 emit_move_insn (tmp, gen_rtx_MEM (Pmode, this_rtx));
20063 if (((unsigned HOST_WIDE_INT) vcall_offset) + 0x8000 >= 0x10000)
20065 emit_insn (TARGET_32BIT
20066 ? gen_addsi3 (tmp, tmp, vcall_offset_rtx)
20067 : gen_adddi3 (tmp, tmp, vcall_offset_rtx));
20068 emit_move_insn (tmp, gen_rtx_MEM (Pmode, tmp));
20070 else
20072 rtx loc = gen_rtx_PLUS (Pmode, tmp, vcall_offset_rtx);
20074 emit_move_insn (tmp, gen_rtx_MEM (Pmode, loc));
20076 emit_insn (TARGET_32BIT
20077 ? gen_addsi3 (this_rtx, this_rtx, tmp)
20078 : gen_adddi3 (this_rtx, this_rtx, tmp));
20081 /* Generate a tail call to the target function. */
20082 if (!TREE_USED (function))
20084 assemble_external (function);
20085 TREE_USED (function) = 1;
20087 funexp = XEXP (DECL_RTL (function), 0);
20088 funexp = gen_rtx_MEM (FUNCTION_MODE, funexp);
20090 #if TARGET_MACHO
20091 if (MACHOPIC_INDIRECT)
20092 funexp = machopic_indirect_call_target (funexp);
20093 #endif
20095 /* gen_sibcall expects reload to convert scratch pseudo to LR so we must
20096 generate sibcall RTL explicitly. */
20097 insn = emit_call_insn (
20098 gen_rtx_PARALLEL (VOIDmode,
20099 gen_rtvec (4,
20100 gen_rtx_CALL (VOIDmode,
20101 funexp, const0_rtx),
20102 gen_rtx_USE (VOIDmode, const0_rtx),
20103 gen_rtx_USE (VOIDmode,
20104 gen_rtx_REG (SImode,
20105 LR_REGNO)),
20106 gen_rtx_RETURN (VOIDmode))));
20107 SIBLING_CALL_P (insn) = 1;
20108 emit_barrier ();
20110 /* Run just enough of rest_of_compilation to get the insns emitted.
20111 There's not really enough bulk here to make other passes such as
20112 instruction scheduling worth while. Note that use_thunk calls
20113 assemble_start_function and assemble_end_function. */
20114 insn = get_insns ();
20115 insn_locators_alloc ();
20116 shorten_branches (insn);
20117 final_start_function (insn, file, 1);
20118 final (insn, file, 1);
20119 final_end_function ();
20121 reload_completed = 0;
20122 epilogue_completed = 0;
20125 /* A quick summary of the various types of 'constant-pool tables'
20126 under PowerPC:
20128 Target Flags Name One table per
20129 AIX (none) AIX TOC object file
20130 AIX -mfull-toc AIX TOC object file
20131 AIX -mminimal-toc AIX minimal TOC translation unit
20132 SVR4/EABI (none) SVR4 SDATA object file
20133 SVR4/EABI -fpic SVR4 pic object file
20134 SVR4/EABI -fPIC SVR4 PIC translation unit
20135 SVR4/EABI -mrelocatable EABI TOC function
20136 SVR4/EABI -maix AIX TOC object file
20137 SVR4/EABI -maix -mminimal-toc
20138 AIX minimal TOC translation unit
20140 Name Reg. Set by entries contains:
20141 made by addrs? fp? sum?
20143 AIX TOC 2 crt0 as Y option option
20144 AIX minimal TOC 30 prolog gcc Y Y option
20145 SVR4 SDATA 13 crt0 gcc N Y N
20146 SVR4 pic 30 prolog ld Y not yet N
20147 SVR4 PIC 30 prolog gcc Y option option
20148 EABI TOC 30 prolog gcc Y option option
20152 /* Hash functions for the hash table. */
20154 static unsigned
20155 rs6000_hash_constant (rtx k)
20157 enum rtx_code code = GET_CODE (k);
20158 enum machine_mode mode = GET_MODE (k);
20159 unsigned result = (code << 3) ^ mode;
20160 const char *format;
20161 int flen, fidx;
20163 format = GET_RTX_FORMAT (code);
20164 flen = strlen (format);
20165 fidx = 0;
20167 switch (code)
20169 case LABEL_REF:
20170 return result * 1231 + (unsigned) INSN_UID (XEXP (k, 0));
20172 case CONST_DOUBLE:
20173 if (mode != VOIDmode)
20174 return real_hash (CONST_DOUBLE_REAL_VALUE (k)) * result;
20175 flen = 2;
20176 break;
20178 case CODE_LABEL:
20179 fidx = 3;
20180 break;
20182 default:
20183 break;
20186 for (; fidx < flen; fidx++)
20187 switch (format[fidx])
20189 case 's':
20191 unsigned i, len;
20192 const char *str = XSTR (k, fidx);
20193 len = strlen (str);
20194 result = result * 613 + len;
20195 for (i = 0; i < len; i++)
20196 result = result * 613 + (unsigned) str[i];
20197 break;
20199 case 'u':
20200 case 'e':
20201 result = result * 1231 + rs6000_hash_constant (XEXP (k, fidx));
20202 break;
20203 case 'i':
20204 case 'n':
20205 result = result * 613 + (unsigned) XINT (k, fidx);
20206 break;
20207 case 'w':
20208 if (sizeof (unsigned) >= sizeof (HOST_WIDE_INT))
20209 result = result * 613 + (unsigned) XWINT (k, fidx);
20210 else
20212 size_t i;
20213 for (i = 0; i < sizeof (HOST_WIDE_INT) / sizeof (unsigned); i++)
20214 result = result * 613 + (unsigned) (XWINT (k, fidx)
20215 >> CHAR_BIT * i);
20217 break;
20218 case '0':
20219 break;
20220 default:
20221 gcc_unreachable ();
20224 return result;
20227 static unsigned
20228 toc_hash_function (const void *hash_entry)
20230 const struct toc_hash_struct *thc =
20231 (const struct toc_hash_struct *) hash_entry;
20232 return rs6000_hash_constant (thc->key) ^ thc->key_mode;
20235 /* Compare H1 and H2 for equivalence. */
20237 static int
20238 toc_hash_eq (const void *h1, const void *h2)
20240 rtx r1 = ((const struct toc_hash_struct *) h1)->key;
20241 rtx r2 = ((const struct toc_hash_struct *) h2)->key;
20243 if (((const struct toc_hash_struct *) h1)->key_mode
20244 != ((const struct toc_hash_struct *) h2)->key_mode)
20245 return 0;
20247 return rtx_equal_p (r1, r2);
20250 /* These are the names given by the C++ front-end to vtables, and
20251 vtable-like objects. Ideally, this logic should not be here;
20252 instead, there should be some programmatic way of inquiring as
20253 to whether or not an object is a vtable. */
20255 #define VTABLE_NAME_P(NAME) \
20256 (strncmp ("_vt.", name, strlen ("_vt.")) == 0 \
20257 || strncmp ("_ZTV", name, strlen ("_ZTV")) == 0 \
20258 || strncmp ("_ZTT", name, strlen ("_ZTT")) == 0 \
20259 || strncmp ("_ZTI", name, strlen ("_ZTI")) == 0 \
20260 || strncmp ("_ZTC", name, strlen ("_ZTC")) == 0)
20262 #ifdef NO_DOLLAR_IN_LABEL
20263 /* Return a GGC-allocated character string translating dollar signs in
20264 input NAME to underscores. Used by XCOFF ASM_OUTPUT_LABELREF. */
20266 const char *
20267 rs6000_xcoff_strip_dollar (const char *name)
20269 char *strip, *p;
20270 int len;
20272 p = strchr (name, '$');
20274 if (p == 0 || p == name)
20275 return name;
20277 len = strlen (name);
20278 strip = (char *) alloca (len + 1);
20279 strcpy (strip, name);
20280 p = strchr (strip, '$');
20281 while (p)
20283 *p = '_';
20284 p = strchr (p + 1, '$');
20287 return ggc_alloc_string (strip, len);
20289 #endif
20291 void
20292 rs6000_output_symbol_ref (FILE *file, rtx x)
20294 /* Currently C++ toc references to vtables can be emitted before it
20295 is decided whether the vtable is public or private. If this is
20296 the case, then the linker will eventually complain that there is
20297 a reference to an unknown section. Thus, for vtables only,
20298 we emit the TOC reference to reference the symbol and not the
20299 section. */
20300 const char *name = XSTR (x, 0);
20302 if (VTABLE_NAME_P (name))
20304 RS6000_OUTPUT_BASENAME (file, name);
20306 else
20307 assemble_name (file, name);
20310 /* Output a TOC entry. We derive the entry name from what is being
20311 written. */
20313 void
20314 output_toc (FILE *file, rtx x, int labelno, enum machine_mode mode)
20316 char buf[256];
20317 const char *name = buf;
20318 rtx base = x;
20319 HOST_WIDE_INT offset = 0;
20321 gcc_assert (!TARGET_NO_TOC);
20323 /* When the linker won't eliminate them, don't output duplicate
20324 TOC entries (this happens on AIX if there is any kind of TOC,
20325 and on SVR4 under -fPIC or -mrelocatable). Don't do this for
20326 CODE_LABELs. */
20327 if (TARGET_TOC && GET_CODE (x) != LABEL_REF)
20329 struct toc_hash_struct *h;
20330 void * * found;
20332 /* Create toc_hash_table. This can't be done at OVERRIDE_OPTIONS
20333 time because GGC is not initialized at that point. */
20334 if (toc_hash_table == NULL)
20335 toc_hash_table = htab_create_ggc (1021, toc_hash_function,
20336 toc_hash_eq, NULL);
20338 h = GGC_NEW (struct toc_hash_struct);
20339 h->key = x;
20340 h->key_mode = mode;
20341 h->labelno = labelno;
20343 found = htab_find_slot (toc_hash_table, h, INSERT);
20344 if (*found == NULL)
20345 *found = h;
20346 else /* This is indeed a duplicate.
20347 Set this label equal to that label. */
20349 fputs ("\t.set ", file);
20350 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
20351 fprintf (file, "%d,", labelno);
20352 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
20353 fprintf (file, "%d\n", ((*(const struct toc_hash_struct **)
20354 found)->labelno));
20355 return;
20359 /* If we're going to put a double constant in the TOC, make sure it's
20360 aligned properly when strict alignment is on. */
20361 if (GET_CODE (x) == CONST_DOUBLE
20362 && STRICT_ALIGNMENT
20363 && GET_MODE_BITSIZE (mode) >= 64
20364 && ! (TARGET_NO_FP_IN_TOC && ! TARGET_MINIMAL_TOC)) {
20365 ASM_OUTPUT_ALIGN (file, 3);
20368 (*targetm.asm_out.internal_label) (file, "LC", labelno);
20370 /* Handle FP constants specially. Note that if we have a minimal
20371 TOC, things we put here aren't actually in the TOC, so we can allow
20372 FP constants. */
20373 if (GET_CODE (x) == CONST_DOUBLE &&
20374 (GET_MODE (x) == TFmode || GET_MODE (x) == TDmode))
20376 REAL_VALUE_TYPE rv;
20377 long k[4];
20379 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
20380 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
20381 REAL_VALUE_TO_TARGET_DECIMAL128 (rv, k);
20382 else
20383 REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv, k);
20385 if (TARGET_64BIT)
20387 if (TARGET_MINIMAL_TOC)
20388 fputs (DOUBLE_INT_ASM_OP, file);
20389 else
20390 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
20391 k[0] & 0xffffffff, k[1] & 0xffffffff,
20392 k[2] & 0xffffffff, k[3] & 0xffffffff);
20393 fprintf (file, "0x%lx%08lx,0x%lx%08lx\n",
20394 k[0] & 0xffffffff, k[1] & 0xffffffff,
20395 k[2] & 0xffffffff, k[3] & 0xffffffff);
20396 return;
20398 else
20400 if (TARGET_MINIMAL_TOC)
20401 fputs ("\t.long ", file);
20402 else
20403 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
20404 k[0] & 0xffffffff, k[1] & 0xffffffff,
20405 k[2] & 0xffffffff, k[3] & 0xffffffff);
20406 fprintf (file, "0x%lx,0x%lx,0x%lx,0x%lx\n",
20407 k[0] & 0xffffffff, k[1] & 0xffffffff,
20408 k[2] & 0xffffffff, k[3] & 0xffffffff);
20409 return;
20412 else if (GET_CODE (x) == CONST_DOUBLE &&
20413 (GET_MODE (x) == DFmode || GET_MODE (x) == DDmode))
20415 REAL_VALUE_TYPE rv;
20416 long k[2];
20418 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
20420 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
20421 REAL_VALUE_TO_TARGET_DECIMAL64 (rv, k);
20422 else
20423 REAL_VALUE_TO_TARGET_DOUBLE (rv, k);
20425 if (TARGET_64BIT)
20427 if (TARGET_MINIMAL_TOC)
20428 fputs (DOUBLE_INT_ASM_OP, file);
20429 else
20430 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
20431 k[0] & 0xffffffff, k[1] & 0xffffffff);
20432 fprintf (file, "0x%lx%08lx\n",
20433 k[0] & 0xffffffff, k[1] & 0xffffffff);
20434 return;
20436 else
20438 if (TARGET_MINIMAL_TOC)
20439 fputs ("\t.long ", file);
20440 else
20441 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
20442 k[0] & 0xffffffff, k[1] & 0xffffffff);
20443 fprintf (file, "0x%lx,0x%lx\n",
20444 k[0] & 0xffffffff, k[1] & 0xffffffff);
20445 return;
20448 else if (GET_CODE (x) == CONST_DOUBLE &&
20449 (GET_MODE (x) == SFmode || GET_MODE (x) == SDmode))
20451 REAL_VALUE_TYPE rv;
20452 long l;
20454 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
20455 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
20456 REAL_VALUE_TO_TARGET_DECIMAL32 (rv, l);
20457 else
20458 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
20460 if (TARGET_64BIT)
20462 if (TARGET_MINIMAL_TOC)
20463 fputs (DOUBLE_INT_ASM_OP, file);
20464 else
20465 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
20466 fprintf (file, "0x%lx00000000\n", l & 0xffffffff);
20467 return;
20469 else
20471 if (TARGET_MINIMAL_TOC)
20472 fputs ("\t.long ", file);
20473 else
20474 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
20475 fprintf (file, "0x%lx\n", l & 0xffffffff);
20476 return;
20479 else if (GET_MODE (x) == VOIDmode
20480 && (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE))
20482 unsigned HOST_WIDE_INT low;
20483 HOST_WIDE_INT high;
20485 if (GET_CODE (x) == CONST_DOUBLE)
20487 low = CONST_DOUBLE_LOW (x);
20488 high = CONST_DOUBLE_HIGH (x);
20490 else
20491 #if HOST_BITS_PER_WIDE_INT == 32
20493 low = INTVAL (x);
20494 high = (low & 0x80000000) ? ~0 : 0;
20496 #else
20498 low = INTVAL (x) & 0xffffffff;
20499 high = (HOST_WIDE_INT) INTVAL (x) >> 32;
20501 #endif
20503 /* TOC entries are always Pmode-sized, but since this
20504 is a bigendian machine then if we're putting smaller
20505 integer constants in the TOC we have to pad them.
20506 (This is still a win over putting the constants in
20507 a separate constant pool, because then we'd have
20508 to have both a TOC entry _and_ the actual constant.)
20510 For a 32-bit target, CONST_INT values are loaded and shifted
20511 entirely within `low' and can be stored in one TOC entry. */
20513 /* It would be easy to make this work, but it doesn't now. */
20514 gcc_assert (!TARGET_64BIT || POINTER_SIZE >= GET_MODE_BITSIZE (mode));
20516 if (POINTER_SIZE > GET_MODE_BITSIZE (mode))
20518 #if HOST_BITS_PER_WIDE_INT == 32
20519 lshift_double (low, high, POINTER_SIZE - GET_MODE_BITSIZE (mode),
20520 POINTER_SIZE, &low, &high, 0);
20521 #else
20522 low |= high << 32;
20523 low <<= POINTER_SIZE - GET_MODE_BITSIZE (mode);
20524 high = (HOST_WIDE_INT) low >> 32;
20525 low &= 0xffffffff;
20526 #endif
20529 if (TARGET_64BIT)
20531 if (TARGET_MINIMAL_TOC)
20532 fputs (DOUBLE_INT_ASM_OP, file);
20533 else
20534 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
20535 (long) high & 0xffffffff, (long) low & 0xffffffff);
20536 fprintf (file, "0x%lx%08lx\n",
20537 (long) high & 0xffffffff, (long) low & 0xffffffff);
20538 return;
20540 else
20542 if (POINTER_SIZE < GET_MODE_BITSIZE (mode))
20544 if (TARGET_MINIMAL_TOC)
20545 fputs ("\t.long ", file);
20546 else
20547 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
20548 (long) high & 0xffffffff, (long) low & 0xffffffff);
20549 fprintf (file, "0x%lx,0x%lx\n",
20550 (long) high & 0xffffffff, (long) low & 0xffffffff);
20552 else
20554 if (TARGET_MINIMAL_TOC)
20555 fputs ("\t.long ", file);
20556 else
20557 fprintf (file, "\t.tc IS_%lx[TC],", (long) low & 0xffffffff);
20558 fprintf (file, "0x%lx\n", (long) low & 0xffffffff);
20560 return;
20564 if (GET_CODE (x) == CONST)
20566 gcc_assert (GET_CODE (XEXP (x, 0)) == PLUS
20567 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT);
20569 base = XEXP (XEXP (x, 0), 0);
20570 offset = INTVAL (XEXP (XEXP (x, 0), 1));
20573 switch (GET_CODE (base))
20575 case SYMBOL_REF:
20576 name = XSTR (base, 0);
20577 break;
20579 case LABEL_REF:
20580 ASM_GENERATE_INTERNAL_LABEL (buf, "L",
20581 CODE_LABEL_NUMBER (XEXP (base, 0)));
20582 break;
20584 case CODE_LABEL:
20585 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (base));
20586 break;
20588 default:
20589 gcc_unreachable ();
20592 if (TARGET_MINIMAL_TOC)
20593 fputs (TARGET_32BIT ? "\t.long " : DOUBLE_INT_ASM_OP, file);
20594 else
20596 fputs ("\t.tc ", file);
20597 RS6000_OUTPUT_BASENAME (file, name);
20599 if (offset < 0)
20600 fprintf (file, ".N" HOST_WIDE_INT_PRINT_UNSIGNED, - offset);
20601 else if (offset)
20602 fprintf (file, ".P" HOST_WIDE_INT_PRINT_UNSIGNED, offset);
20604 fputs ("[TC],", file);
20607 /* Currently C++ toc references to vtables can be emitted before it
20608 is decided whether the vtable is public or private. If this is
20609 the case, then the linker will eventually complain that there is
20610 a TOC reference to an unknown section. Thus, for vtables only,
20611 we emit the TOC reference to reference the symbol and not the
20612 section. */
20613 if (VTABLE_NAME_P (name))
20615 RS6000_OUTPUT_BASENAME (file, name);
20616 if (offset < 0)
20617 fprintf (file, HOST_WIDE_INT_PRINT_DEC, offset);
20618 else if (offset > 0)
20619 fprintf (file, "+" HOST_WIDE_INT_PRINT_DEC, offset);
20621 else
20622 output_addr_const (file, x);
20623 putc ('\n', file);
20626 /* Output an assembler pseudo-op to write an ASCII string of N characters
20627 starting at P to FILE.
20629 On the RS/6000, we have to do this using the .byte operation and
20630 write out special characters outside the quoted string.
20631 Also, the assembler is broken; very long strings are truncated,
20632 so we must artificially break them up early. */
20634 void
20635 output_ascii (FILE *file, const char *p, int n)
20637 char c;
20638 int i, count_string;
20639 const char *for_string = "\t.byte \"";
20640 const char *for_decimal = "\t.byte ";
20641 const char *to_close = NULL;
20643 count_string = 0;
20644 for (i = 0; i < n; i++)
20646 c = *p++;
20647 if (c >= ' ' && c < 0177)
20649 if (for_string)
20650 fputs (for_string, file);
20651 putc (c, file);
20653 /* Write two quotes to get one. */
20654 if (c == '"')
20656 putc (c, file);
20657 ++count_string;
20660 for_string = NULL;
20661 for_decimal = "\"\n\t.byte ";
20662 to_close = "\"\n";
20663 ++count_string;
20665 if (count_string >= 512)
20667 fputs (to_close, file);
20669 for_string = "\t.byte \"";
20670 for_decimal = "\t.byte ";
20671 to_close = NULL;
20672 count_string = 0;
20675 else
20677 if (for_decimal)
20678 fputs (for_decimal, file);
20679 fprintf (file, "%d", c);
20681 for_string = "\n\t.byte \"";
20682 for_decimal = ", ";
20683 to_close = "\n";
20684 count_string = 0;
20688 /* Now close the string if we have written one. Then end the line. */
20689 if (to_close)
20690 fputs (to_close, file);
20693 /* Generate a unique section name for FILENAME for a section type
20694 represented by SECTION_DESC. Output goes into BUF.
20696 SECTION_DESC can be any string, as long as it is different for each
20697 possible section type.
20699 We name the section in the same manner as xlc. The name begins with an
20700 underscore followed by the filename (after stripping any leading directory
20701 names) with the last period replaced by the string SECTION_DESC. If
20702 FILENAME does not contain a period, SECTION_DESC is appended to the end of
20703 the name. */
20705 void
20706 rs6000_gen_section_name (char **buf, const char *filename,
20707 const char *section_desc)
20709 const char *q, *after_last_slash, *last_period = 0;
20710 char *p;
20711 int len;
20713 after_last_slash = filename;
20714 for (q = filename; *q; q++)
20716 if (*q == '/')
20717 after_last_slash = q + 1;
20718 else if (*q == '.')
20719 last_period = q;
20722 len = strlen (after_last_slash) + strlen (section_desc) + 2;
20723 *buf = (char *) xmalloc (len);
20725 p = *buf;
20726 *p++ = '_';
20728 for (q = after_last_slash; *q; q++)
20730 if (q == last_period)
20732 strcpy (p, section_desc);
20733 p += strlen (section_desc);
20734 break;
20737 else if (ISALNUM (*q))
20738 *p++ = *q;
20741 if (last_period == 0)
20742 strcpy (p, section_desc);
20743 else
20744 *p = '\0';
20747 /* Emit profile function. */
20749 void
20750 output_profile_hook (int labelno ATTRIBUTE_UNUSED)
20752 /* Non-standard profiling for kernels, which just saves LR then calls
20753 _mcount without worrying about arg saves. The idea is to change
20754 the function prologue as little as possible as it isn't easy to
20755 account for arg save/restore code added just for _mcount. */
20756 if (TARGET_PROFILE_KERNEL)
20757 return;
20759 if (DEFAULT_ABI == ABI_AIX)
20761 #ifndef NO_PROFILE_COUNTERS
20762 # define NO_PROFILE_COUNTERS 0
20763 #endif
20764 if (NO_PROFILE_COUNTERS)
20765 emit_library_call (init_one_libfunc (RS6000_MCOUNT),
20766 LCT_NORMAL, VOIDmode, 0);
20767 else
20769 char buf[30];
20770 const char *label_name;
20771 rtx fun;
20773 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
20774 label_name = (*targetm.strip_name_encoding) (ggc_strdup (buf));
20775 fun = gen_rtx_SYMBOL_REF (Pmode, label_name);
20777 emit_library_call (init_one_libfunc (RS6000_MCOUNT),
20778 LCT_NORMAL, VOIDmode, 1, fun, Pmode);
20781 else if (DEFAULT_ABI == ABI_DARWIN)
20783 const char *mcount_name = RS6000_MCOUNT;
20784 int caller_addr_regno = LR_REGNO;
20786 /* Be conservative and always set this, at least for now. */
20787 crtl->uses_pic_offset_table = 1;
20789 #if TARGET_MACHO
20790 /* For PIC code, set up a stub and collect the caller's address
20791 from r0, which is where the prologue puts it. */
20792 if (MACHOPIC_INDIRECT
20793 && crtl->uses_pic_offset_table)
20794 caller_addr_regno = 0;
20795 #endif
20796 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, mcount_name),
20797 LCT_NORMAL, VOIDmode, 1,
20798 gen_rtx_REG (Pmode, caller_addr_regno), Pmode);
20802 /* Write function profiler code. */
20804 void
20805 output_function_profiler (FILE *file, int labelno)
20807 char buf[100];
20809 switch (DEFAULT_ABI)
20811 default:
20812 gcc_unreachable ();
20814 case ABI_V4:
20815 if (!TARGET_32BIT)
20817 warning (0, "no profiling of 64-bit code for this ABI");
20818 return;
20820 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
20821 fprintf (file, "\tmflr %s\n", reg_names[0]);
20822 if (NO_PROFILE_COUNTERS)
20824 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
20825 reg_names[0], reg_names[1]);
20827 else if (TARGET_SECURE_PLT && flag_pic)
20829 asm_fprintf (file, "\tbcl 20,31,1f\n1:\n\t{st|stw} %s,4(%s)\n",
20830 reg_names[0], reg_names[1]);
20831 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
20832 asm_fprintf (file, "\t{cau|addis} %s,%s,",
20833 reg_names[12], reg_names[12]);
20834 assemble_name (file, buf);
20835 asm_fprintf (file, "-1b@ha\n\t{cal|la} %s,", reg_names[0]);
20836 assemble_name (file, buf);
20837 asm_fprintf (file, "-1b@l(%s)\n", reg_names[12]);
20839 else if (flag_pic == 1)
20841 fputs ("\tbl _GLOBAL_OFFSET_TABLE_@local-4\n", file);
20842 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
20843 reg_names[0], reg_names[1]);
20844 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
20845 asm_fprintf (file, "\t{l|lwz} %s,", reg_names[0]);
20846 assemble_name (file, buf);
20847 asm_fprintf (file, "@got(%s)\n", reg_names[12]);
20849 else if (flag_pic > 1)
20851 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
20852 reg_names[0], reg_names[1]);
20853 /* Now, we need to get the address of the label. */
20854 fputs ("\tbcl 20,31,1f\n\t.long ", file);
20855 assemble_name (file, buf);
20856 fputs ("-.\n1:", file);
20857 asm_fprintf (file, "\tmflr %s\n", reg_names[11]);
20858 asm_fprintf (file, "\t{l|lwz} %s,0(%s)\n",
20859 reg_names[0], reg_names[11]);
20860 asm_fprintf (file, "\t{cax|add} %s,%s,%s\n",
20861 reg_names[0], reg_names[0], reg_names[11]);
20863 else
20865 asm_fprintf (file, "\t{liu|lis} %s,", reg_names[12]);
20866 assemble_name (file, buf);
20867 fputs ("@ha\n", file);
20868 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
20869 reg_names[0], reg_names[1]);
20870 asm_fprintf (file, "\t{cal|la} %s,", reg_names[0]);
20871 assemble_name (file, buf);
20872 asm_fprintf (file, "@l(%s)\n", reg_names[12]);
20875 /* ABI_V4 saves the static chain reg with ASM_OUTPUT_REG_PUSH. */
20876 fprintf (file, "\tbl %s%s\n",
20877 RS6000_MCOUNT, flag_pic ? "@plt" : "");
20878 break;
20880 case ABI_AIX:
20881 case ABI_DARWIN:
20882 if (!TARGET_PROFILE_KERNEL)
20884 /* Don't do anything, done in output_profile_hook (). */
20886 else
20888 gcc_assert (!TARGET_32BIT);
20890 asm_fprintf (file, "\tmflr %s\n", reg_names[0]);
20891 asm_fprintf (file, "\tstd %s,16(%s)\n", reg_names[0], reg_names[1]);
20893 if (cfun->static_chain_decl != NULL)
20895 asm_fprintf (file, "\tstd %s,24(%s)\n",
20896 reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
20897 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
20898 asm_fprintf (file, "\tld %s,24(%s)\n",
20899 reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
20901 else
20902 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
20904 break;
20910 /* The following variable value is the last issued insn. */
20912 static rtx last_scheduled_insn;
20914 /* The following variable helps to balance issuing of load and
20915 store instructions */
20917 static int load_store_pendulum;
20919 /* Power4 load update and store update instructions are cracked into a
20920 load or store and an integer insn which are executed in the same cycle.
20921 Branches have their own dispatch slot which does not count against the
20922 GCC issue rate, but it changes the program flow so there are no other
20923 instructions to issue in this cycle. */
20925 static int
20926 rs6000_variable_issue (FILE *stream ATTRIBUTE_UNUSED,
20927 int verbose ATTRIBUTE_UNUSED,
20928 rtx insn, int more)
20930 last_scheduled_insn = insn;
20931 if (GET_CODE (PATTERN (insn)) == USE
20932 || GET_CODE (PATTERN (insn)) == CLOBBER)
20934 cached_can_issue_more = more;
20935 return cached_can_issue_more;
20938 if (insn_terminates_group_p (insn, current_group))
20940 cached_can_issue_more = 0;
20941 return cached_can_issue_more;
20944 /* If no reservation, but reach here */
20945 if (recog_memoized (insn) < 0)
20946 return more;
20948 if (rs6000_sched_groups)
20950 if (is_microcoded_insn (insn))
20951 cached_can_issue_more = 0;
20952 else if (is_cracked_insn (insn))
20953 cached_can_issue_more = more > 2 ? more - 2 : 0;
20954 else
20955 cached_can_issue_more = more - 1;
20957 return cached_can_issue_more;
20960 if (rs6000_cpu_attr == CPU_CELL && is_nonpipeline_insn (insn))
20961 return 0;
20963 cached_can_issue_more = more - 1;
20964 return cached_can_issue_more;
20967 /* Adjust the cost of a scheduling dependency. Return the new cost of
20968 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
20970 static int
20971 rs6000_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
20973 enum attr_type attr_type;
20975 if (! recog_memoized (insn))
20976 return 0;
20978 switch (REG_NOTE_KIND (link))
20980 case REG_DEP_TRUE:
20982 /* Data dependency; DEP_INSN writes a register that INSN reads
20983 some cycles later. */
20985 /* Separate a load from a narrower, dependent store. */
20986 if (rs6000_sched_groups
20987 && GET_CODE (PATTERN (insn)) == SET
20988 && GET_CODE (PATTERN (dep_insn)) == SET
20989 && GET_CODE (XEXP (PATTERN (insn), 1)) == MEM
20990 && GET_CODE (XEXP (PATTERN (dep_insn), 0)) == MEM
20991 && (GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (insn), 1)))
20992 > GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (dep_insn), 0)))))
20993 return cost + 14;
20995 attr_type = get_attr_type (insn);
20997 switch (attr_type)
20999 case TYPE_JMPREG:
21000 /* Tell the first scheduling pass about the latency between
21001 a mtctr and bctr (and mtlr and br/blr). The first
21002 scheduling pass will not know about this latency since
21003 the mtctr instruction, which has the latency associated
21004 to it, will be generated by reload. */
21005 return TARGET_POWER ? 5 : 4;
21006 case TYPE_BRANCH:
21007 /* Leave some extra cycles between a compare and its
21008 dependent branch, to inhibit expensive mispredicts. */
21009 if ((rs6000_cpu_attr == CPU_PPC603
21010 || rs6000_cpu_attr == CPU_PPC604
21011 || rs6000_cpu_attr == CPU_PPC604E
21012 || rs6000_cpu_attr == CPU_PPC620
21013 || rs6000_cpu_attr == CPU_PPC630
21014 || rs6000_cpu_attr == CPU_PPC750
21015 || rs6000_cpu_attr == CPU_PPC7400
21016 || rs6000_cpu_attr == CPU_PPC7450
21017 || rs6000_cpu_attr == CPU_POWER4
21018 || rs6000_cpu_attr == CPU_POWER5
21019 || rs6000_cpu_attr == CPU_POWER7
21020 || rs6000_cpu_attr == CPU_CELL)
21021 && recog_memoized (dep_insn)
21022 && (INSN_CODE (dep_insn) >= 0))
21024 switch (get_attr_type (dep_insn))
21026 case TYPE_CMP:
21027 case TYPE_COMPARE:
21028 case TYPE_DELAYED_COMPARE:
21029 case TYPE_IMUL_COMPARE:
21030 case TYPE_LMUL_COMPARE:
21031 case TYPE_FPCOMPARE:
21032 case TYPE_CR_LOGICAL:
21033 case TYPE_DELAYED_CR:
21034 return cost + 2;
21035 default:
21036 break;
21038 break;
21040 case TYPE_STORE:
21041 case TYPE_STORE_U:
21042 case TYPE_STORE_UX:
21043 case TYPE_FPSTORE:
21044 case TYPE_FPSTORE_U:
21045 case TYPE_FPSTORE_UX:
21046 if ((rs6000_cpu == PROCESSOR_POWER6)
21047 && recog_memoized (dep_insn)
21048 && (INSN_CODE (dep_insn) >= 0))
21051 if (GET_CODE (PATTERN (insn)) != SET)
21052 /* If this happens, we have to extend this to schedule
21053 optimally. Return default for now. */
21054 return cost;
21056 /* Adjust the cost for the case where the value written
21057 by a fixed point operation is used as the address
21058 gen value on a store. */
21059 switch (get_attr_type (dep_insn))
21061 case TYPE_LOAD:
21062 case TYPE_LOAD_U:
21063 case TYPE_LOAD_UX:
21064 case TYPE_CNTLZ:
21066 if (! store_data_bypass_p (dep_insn, insn))
21067 return 4;
21068 break;
21070 case TYPE_LOAD_EXT:
21071 case TYPE_LOAD_EXT_U:
21072 case TYPE_LOAD_EXT_UX:
21073 case TYPE_VAR_SHIFT_ROTATE:
21074 case TYPE_VAR_DELAYED_COMPARE:
21076 if (! store_data_bypass_p (dep_insn, insn))
21077 return 6;
21078 break;
21080 case TYPE_INTEGER:
21081 case TYPE_COMPARE:
21082 case TYPE_FAST_COMPARE:
21083 case TYPE_EXTS:
21084 case TYPE_SHIFT:
21085 case TYPE_INSERT_WORD:
21086 case TYPE_INSERT_DWORD:
21087 case TYPE_FPLOAD_U:
21088 case TYPE_FPLOAD_UX:
21089 case TYPE_STORE_U:
21090 case TYPE_STORE_UX:
21091 case TYPE_FPSTORE_U:
21092 case TYPE_FPSTORE_UX:
21094 if (! store_data_bypass_p (dep_insn, insn))
21095 return 3;
21096 break;
21098 case TYPE_IMUL:
21099 case TYPE_IMUL2:
21100 case TYPE_IMUL3:
21101 case TYPE_LMUL:
21102 case TYPE_IMUL_COMPARE:
21103 case TYPE_LMUL_COMPARE:
21105 if (! store_data_bypass_p (dep_insn, insn))
21106 return 17;
21107 break;
21109 case TYPE_IDIV:
21111 if (! store_data_bypass_p (dep_insn, insn))
21112 return 45;
21113 break;
21115 case TYPE_LDIV:
21117 if (! store_data_bypass_p (dep_insn, insn))
21118 return 57;
21119 break;
21121 default:
21122 break;
21125 break;
21127 case TYPE_LOAD:
21128 case TYPE_LOAD_U:
21129 case TYPE_LOAD_UX:
21130 case TYPE_LOAD_EXT:
21131 case TYPE_LOAD_EXT_U:
21132 case TYPE_LOAD_EXT_UX:
21133 if ((rs6000_cpu == PROCESSOR_POWER6)
21134 && recog_memoized (dep_insn)
21135 && (INSN_CODE (dep_insn) >= 0))
21138 /* Adjust the cost for the case where the value written
21139 by a fixed point instruction is used within the address
21140 gen portion of a subsequent load(u)(x) */
21141 switch (get_attr_type (dep_insn))
21143 case TYPE_LOAD:
21144 case TYPE_LOAD_U:
21145 case TYPE_LOAD_UX:
21146 case TYPE_CNTLZ:
21148 if (set_to_load_agen (dep_insn, insn))
21149 return 4;
21150 break;
21152 case TYPE_LOAD_EXT:
21153 case TYPE_LOAD_EXT_U:
21154 case TYPE_LOAD_EXT_UX:
21155 case TYPE_VAR_SHIFT_ROTATE:
21156 case TYPE_VAR_DELAYED_COMPARE:
21158 if (set_to_load_agen (dep_insn, insn))
21159 return 6;
21160 break;
21162 case TYPE_INTEGER:
21163 case TYPE_COMPARE:
21164 case TYPE_FAST_COMPARE:
21165 case TYPE_EXTS:
21166 case TYPE_SHIFT:
21167 case TYPE_INSERT_WORD:
21168 case TYPE_INSERT_DWORD:
21169 case TYPE_FPLOAD_U:
21170 case TYPE_FPLOAD_UX:
21171 case TYPE_STORE_U:
21172 case TYPE_STORE_UX:
21173 case TYPE_FPSTORE_U:
21174 case TYPE_FPSTORE_UX:
21176 if (set_to_load_agen (dep_insn, insn))
21177 return 3;
21178 break;
21180 case TYPE_IMUL:
21181 case TYPE_IMUL2:
21182 case TYPE_IMUL3:
21183 case TYPE_LMUL:
21184 case TYPE_IMUL_COMPARE:
21185 case TYPE_LMUL_COMPARE:
21187 if (set_to_load_agen (dep_insn, insn))
21188 return 17;
21189 break;
21191 case TYPE_IDIV:
21193 if (set_to_load_agen (dep_insn, insn))
21194 return 45;
21195 break;
21197 case TYPE_LDIV:
21199 if (set_to_load_agen (dep_insn, insn))
21200 return 57;
21201 break;
21203 default:
21204 break;
21207 break;
21209 case TYPE_FPLOAD:
21210 if ((rs6000_cpu == PROCESSOR_POWER6)
21211 && recog_memoized (dep_insn)
21212 && (INSN_CODE (dep_insn) >= 0)
21213 && (get_attr_type (dep_insn) == TYPE_MFFGPR))
21214 return 2;
21216 default:
21217 break;
21220 /* Fall out to return default cost. */
21222 break;
21224 case REG_DEP_OUTPUT:
21225 /* Output dependency; DEP_INSN writes a register that INSN writes some
21226 cycles later. */
21227 if ((rs6000_cpu == PROCESSOR_POWER6)
21228 && recog_memoized (dep_insn)
21229 && (INSN_CODE (dep_insn) >= 0))
21231 attr_type = get_attr_type (insn);
21233 switch (attr_type)
21235 case TYPE_FP:
21236 if (get_attr_type (dep_insn) == TYPE_FP)
21237 return 1;
21238 break;
21239 case TYPE_FPLOAD:
21240 if (get_attr_type (dep_insn) == TYPE_MFFGPR)
21241 return 2;
21242 break;
21243 default:
21244 break;
21247 case REG_DEP_ANTI:
21248 /* Anti dependency; DEP_INSN reads a register that INSN writes some
21249 cycles later. */
21250 return 0;
21252 default:
21253 gcc_unreachable ();
21256 return cost;
21259 /* Debug version of rs6000_adjust_cost. */
21261 static int
21262 rs6000_debug_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
21264 int ret = rs6000_adjust_cost (insn, link, dep_insn, cost);
21266 if (ret != cost)
21268 const char *dep;
21270 switch (REG_NOTE_KIND (link))
21272 default: dep = "unknown depencency"; break;
21273 case REG_DEP_TRUE: dep = "data dependency"; break;
21274 case REG_DEP_OUTPUT: dep = "output dependency"; break;
21275 case REG_DEP_ANTI: dep = "anti depencency"; break;
21278 fprintf (stderr,
21279 "\nrs6000_adjust_cost, final cost = %d, orig cost = %d, "
21280 "%s, insn:\n", ret, cost, dep);
21282 debug_rtx (insn);
21285 return ret;
21288 /* The function returns a true if INSN is microcoded.
21289 Return false otherwise. */
21291 static bool
21292 is_microcoded_insn (rtx insn)
21294 if (!insn || !INSN_P (insn)
21295 || GET_CODE (PATTERN (insn)) == USE
21296 || GET_CODE (PATTERN (insn)) == CLOBBER)
21297 return false;
21299 if (rs6000_cpu_attr == CPU_CELL)
21300 return get_attr_cell_micro (insn) == CELL_MICRO_ALWAYS;
21302 if (rs6000_sched_groups)
21304 enum attr_type type = get_attr_type (insn);
21305 if (type == TYPE_LOAD_EXT_U
21306 || type == TYPE_LOAD_EXT_UX
21307 || type == TYPE_LOAD_UX
21308 || type == TYPE_STORE_UX
21309 || type == TYPE_MFCR)
21310 return true;
21313 return false;
21316 /* The function returns true if INSN is cracked into 2 instructions
21317 by the processor (and therefore occupies 2 issue slots). */
21319 static bool
21320 is_cracked_insn (rtx insn)
21322 if (!insn || !INSN_P (insn)
21323 || GET_CODE (PATTERN (insn)) == USE
21324 || GET_CODE (PATTERN (insn)) == CLOBBER)
21325 return false;
21327 if (rs6000_sched_groups)
21329 enum attr_type type = get_attr_type (insn);
21330 if (type == TYPE_LOAD_U || type == TYPE_STORE_U
21331 || type == TYPE_FPLOAD_U || type == TYPE_FPSTORE_U
21332 || type == TYPE_FPLOAD_UX || type == TYPE_FPSTORE_UX
21333 || type == TYPE_LOAD_EXT || type == TYPE_DELAYED_CR
21334 || type == TYPE_COMPARE || type == TYPE_DELAYED_COMPARE
21335 || type == TYPE_IMUL_COMPARE || type == TYPE_LMUL_COMPARE
21336 || type == TYPE_IDIV || type == TYPE_LDIV
21337 || type == TYPE_INSERT_WORD)
21338 return true;
21341 return false;
21344 /* The function returns true if INSN can be issued only from
21345 the branch slot. */
21347 static bool
21348 is_branch_slot_insn (rtx insn)
21350 if (!insn || !INSN_P (insn)
21351 || GET_CODE (PATTERN (insn)) == USE
21352 || GET_CODE (PATTERN (insn)) == CLOBBER)
21353 return false;
21355 if (rs6000_sched_groups)
21357 enum attr_type type = get_attr_type (insn);
21358 if (type == TYPE_BRANCH || type == TYPE_JMPREG)
21359 return true;
21360 return false;
21363 return false;
21366 /* The function returns true if out_inst sets a value that is
21367 used in the address generation computation of in_insn */
21368 static bool
21369 set_to_load_agen (rtx out_insn, rtx in_insn)
21371 rtx out_set, in_set;
21373 /* For performance reasons, only handle the simple case where
21374 both loads are a single_set. */
21375 out_set = single_set (out_insn);
21376 if (out_set)
21378 in_set = single_set (in_insn);
21379 if (in_set)
21380 return reg_mentioned_p (SET_DEST (out_set), SET_SRC (in_set));
21383 return false;
21386 /* The function returns true if the target storage location of
21387 out_insn is adjacent to the target storage location of in_insn */
21388 /* Return 1 if memory locations are adjacent. */
21390 static bool
21391 adjacent_mem_locations (rtx insn1, rtx insn2)
21394 rtx a = get_store_dest (PATTERN (insn1));
21395 rtx b = get_store_dest (PATTERN (insn2));
21397 if ((GET_CODE (XEXP (a, 0)) == REG
21398 || (GET_CODE (XEXP (a, 0)) == PLUS
21399 && GET_CODE (XEXP (XEXP (a, 0), 1)) == CONST_INT))
21400 && (GET_CODE (XEXP (b, 0)) == REG
21401 || (GET_CODE (XEXP (b, 0)) == PLUS
21402 && GET_CODE (XEXP (XEXP (b, 0), 1)) == CONST_INT)))
21404 HOST_WIDE_INT val0 = 0, val1 = 0, val_diff;
21405 rtx reg0, reg1;
21407 if (GET_CODE (XEXP (a, 0)) == PLUS)
21409 reg0 = XEXP (XEXP (a, 0), 0);
21410 val0 = INTVAL (XEXP (XEXP (a, 0), 1));
21412 else
21413 reg0 = XEXP (a, 0);
21415 if (GET_CODE (XEXP (b, 0)) == PLUS)
21417 reg1 = XEXP (XEXP (b, 0), 0);
21418 val1 = INTVAL (XEXP (XEXP (b, 0), 1));
21420 else
21421 reg1 = XEXP (b, 0);
21423 val_diff = val1 - val0;
21425 return ((REGNO (reg0) == REGNO (reg1))
21426 && ((MEM_SIZE (a) && val_diff == INTVAL (MEM_SIZE (a)))
21427 || (MEM_SIZE (b) && val_diff == -INTVAL (MEM_SIZE (b)))));
21430 return false;
21433 /* A C statement (sans semicolon) to update the integer scheduling
21434 priority INSN_PRIORITY (INSN). Increase the priority to execute the
21435 INSN earlier, reduce the priority to execute INSN later. Do not
21436 define this macro if you do not need to adjust the scheduling
21437 priorities of insns. */
21439 static int
21440 rs6000_adjust_priority (rtx insn ATTRIBUTE_UNUSED, int priority)
21442 /* On machines (like the 750) which have asymmetric integer units,
21443 where one integer unit can do multiply and divides and the other
21444 can't, reduce the priority of multiply/divide so it is scheduled
21445 before other integer operations. */
21447 #if 0
21448 if (! INSN_P (insn))
21449 return priority;
21451 if (GET_CODE (PATTERN (insn)) == USE)
21452 return priority;
21454 switch (rs6000_cpu_attr) {
21455 case CPU_PPC750:
21456 switch (get_attr_type (insn))
21458 default:
21459 break;
21461 case TYPE_IMUL:
21462 case TYPE_IDIV:
21463 fprintf (stderr, "priority was %#x (%d) before adjustment\n",
21464 priority, priority);
21465 if (priority >= 0 && priority < 0x01000000)
21466 priority >>= 3;
21467 break;
21470 #endif
21472 if (insn_must_be_first_in_group (insn)
21473 && reload_completed
21474 && current_sched_info->sched_max_insns_priority
21475 && rs6000_sched_restricted_insns_priority)
21478 /* Prioritize insns that can be dispatched only in the first
21479 dispatch slot. */
21480 if (rs6000_sched_restricted_insns_priority == 1)
21481 /* Attach highest priority to insn. This means that in
21482 haifa-sched.c:ready_sort(), dispatch-slot restriction considerations
21483 precede 'priority' (critical path) considerations. */
21484 return current_sched_info->sched_max_insns_priority;
21485 else if (rs6000_sched_restricted_insns_priority == 2)
21486 /* Increase priority of insn by a minimal amount. This means that in
21487 haifa-sched.c:ready_sort(), only 'priority' (critical path)
21488 considerations precede dispatch-slot restriction considerations. */
21489 return (priority + 1);
21492 if (rs6000_cpu == PROCESSOR_POWER6
21493 && ((load_store_pendulum == -2 && is_load_insn (insn))
21494 || (load_store_pendulum == 2 && is_store_insn (insn))))
21495 /* Attach highest priority to insn if the scheduler has just issued two
21496 stores and this instruction is a load, or two loads and this instruction
21497 is a store. Power6 wants loads and stores scheduled alternately
21498 when possible */
21499 return current_sched_info->sched_max_insns_priority;
21501 return priority;
21504 /* Return true if the instruction is nonpipelined on the Cell. */
21505 static bool
21506 is_nonpipeline_insn (rtx insn)
21508 enum attr_type type;
21509 if (!insn || !INSN_P (insn)
21510 || GET_CODE (PATTERN (insn)) == USE
21511 || GET_CODE (PATTERN (insn)) == CLOBBER)
21512 return false;
21514 type = get_attr_type (insn);
21515 if (type == TYPE_IMUL
21516 || type == TYPE_IMUL2
21517 || type == TYPE_IMUL3
21518 || type == TYPE_LMUL
21519 || type == TYPE_IDIV
21520 || type == TYPE_LDIV
21521 || type == TYPE_SDIV
21522 || type == TYPE_DDIV
21523 || type == TYPE_SSQRT
21524 || type == TYPE_DSQRT
21525 || type == TYPE_MFCR
21526 || type == TYPE_MFCRF
21527 || type == TYPE_MFJMPR)
21529 return true;
21531 return false;
21535 /* Return how many instructions the machine can issue per cycle. */
21537 static int
21538 rs6000_issue_rate (void)
21540 /* Use issue rate of 1 for first scheduling pass to decrease degradation. */
21541 if (!reload_completed)
21542 return 1;
21544 switch (rs6000_cpu_attr) {
21545 case CPU_RIOS1: /* ? */
21546 case CPU_RS64A:
21547 case CPU_PPC601: /* ? */
21548 case CPU_PPC7450:
21549 return 3;
21550 case CPU_PPC440:
21551 case CPU_PPC603:
21552 case CPU_PPC750:
21553 case CPU_PPC7400:
21554 case CPU_PPC8540:
21555 case CPU_CELL:
21556 case CPU_PPCE300C2:
21557 case CPU_PPCE300C3:
21558 case CPU_PPCE500MC:
21559 return 2;
21560 case CPU_RIOS2:
21561 case CPU_PPC604:
21562 case CPU_PPC604E:
21563 case CPU_PPC620:
21564 case CPU_PPC630:
21565 return 4;
21566 case CPU_POWER4:
21567 case CPU_POWER5:
21568 case CPU_POWER6:
21569 case CPU_POWER7:
21570 return 5;
21571 default:
21572 return 1;
21576 /* Return how many instructions to look ahead for better insn
21577 scheduling. */
21579 static int
21580 rs6000_use_sched_lookahead (void)
21582 if (rs6000_cpu_attr == CPU_PPC8540)
21583 return 4;
21584 if (rs6000_cpu_attr == CPU_CELL)
21585 return (reload_completed ? 8 : 0);
21586 return 0;
21589 /* We are choosing insn from the ready queue. Return nonzero if INSN can be chosen. */
21590 static int
21591 rs6000_use_sched_lookahead_guard (rtx insn)
21593 if (rs6000_cpu_attr != CPU_CELL)
21594 return 1;
21596 if (insn == NULL_RTX || !INSN_P (insn))
21597 abort ();
21599 if (!reload_completed
21600 || is_nonpipeline_insn (insn)
21601 || is_microcoded_insn (insn))
21602 return 0;
21604 return 1;
21607 /* Determine is PAT refers to memory. */
21609 static bool
21610 is_mem_ref (rtx pat)
21612 const char * fmt;
21613 int i, j;
21614 bool ret = false;
21616 /* stack_tie does not produce any real memory traffic. */
21617 if (GET_CODE (pat) == UNSPEC
21618 && XINT (pat, 1) == UNSPEC_TIE)
21619 return false;
21621 if (GET_CODE (pat) == MEM)
21622 return true;
21624 /* Recursively process the pattern. */
21625 fmt = GET_RTX_FORMAT (GET_CODE (pat));
21627 for (i = GET_RTX_LENGTH (GET_CODE (pat)) - 1; i >= 0 && !ret; i--)
21629 if (fmt[i] == 'e')
21630 ret |= is_mem_ref (XEXP (pat, i));
21631 else if (fmt[i] == 'E')
21632 for (j = XVECLEN (pat, i) - 1; j >= 0; j--)
21633 ret |= is_mem_ref (XVECEXP (pat, i, j));
21636 return ret;
21639 /* Determine if PAT is a PATTERN of a load insn. */
21641 static bool
21642 is_load_insn1 (rtx pat)
21644 if (!pat || pat == NULL_RTX)
21645 return false;
21647 if (GET_CODE (pat) == SET)
21648 return is_mem_ref (SET_SRC (pat));
21650 if (GET_CODE (pat) == PARALLEL)
21652 int i;
21654 for (i = 0; i < XVECLEN (pat, 0); i++)
21655 if (is_load_insn1 (XVECEXP (pat, 0, i)))
21656 return true;
21659 return false;
21662 /* Determine if INSN loads from memory. */
21664 static bool
21665 is_load_insn (rtx insn)
21667 if (!insn || !INSN_P (insn))
21668 return false;
21670 if (GET_CODE (insn) == CALL_INSN)
21671 return false;
21673 return is_load_insn1 (PATTERN (insn));
21676 /* Determine if PAT is a PATTERN of a store insn. */
21678 static bool
21679 is_store_insn1 (rtx pat)
21681 if (!pat || pat == NULL_RTX)
21682 return false;
21684 if (GET_CODE (pat) == SET)
21685 return is_mem_ref (SET_DEST (pat));
21687 if (GET_CODE (pat) == PARALLEL)
21689 int i;
21691 for (i = 0; i < XVECLEN (pat, 0); i++)
21692 if (is_store_insn1 (XVECEXP (pat, 0, i)))
21693 return true;
21696 return false;
21699 /* Determine if INSN stores to memory. */
21701 static bool
21702 is_store_insn (rtx insn)
21704 if (!insn || !INSN_P (insn))
21705 return false;
21707 return is_store_insn1 (PATTERN (insn));
21710 /* Return the dest of a store insn. */
21712 static rtx
21713 get_store_dest (rtx pat)
21715 gcc_assert (is_store_insn1 (pat));
21717 if (GET_CODE (pat) == SET)
21718 return SET_DEST (pat);
21719 else if (GET_CODE (pat) == PARALLEL)
21721 int i;
21723 for (i = 0; i < XVECLEN (pat, 0); i++)
21725 rtx inner_pat = XVECEXP (pat, 0, i);
21726 if (GET_CODE (inner_pat) == SET
21727 && is_mem_ref (SET_DEST (inner_pat)))
21728 return inner_pat;
21731 /* We shouldn't get here, because we should have either a simple
21732 store insn or a store with update which are covered above. */
21733 gcc_unreachable();
21736 /* Returns whether the dependence between INSN and NEXT is considered
21737 costly by the given target. */
21739 static bool
21740 rs6000_is_costly_dependence (dep_t dep, int cost, int distance)
21742 rtx insn;
21743 rtx next;
21745 /* If the flag is not enabled - no dependence is considered costly;
21746 allow all dependent insns in the same group.
21747 This is the most aggressive option. */
21748 if (rs6000_sched_costly_dep == no_dep_costly)
21749 return false;
21751 /* If the flag is set to 1 - a dependence is always considered costly;
21752 do not allow dependent instructions in the same group.
21753 This is the most conservative option. */
21754 if (rs6000_sched_costly_dep == all_deps_costly)
21755 return true;
21757 insn = DEP_PRO (dep);
21758 next = DEP_CON (dep);
21760 if (rs6000_sched_costly_dep == store_to_load_dep_costly
21761 && is_load_insn (next)
21762 && is_store_insn (insn))
21763 /* Prevent load after store in the same group. */
21764 return true;
21766 if (rs6000_sched_costly_dep == true_store_to_load_dep_costly
21767 && is_load_insn (next)
21768 && is_store_insn (insn)
21769 && DEP_TYPE (dep) == REG_DEP_TRUE)
21770 /* Prevent load after store in the same group if it is a true
21771 dependence. */
21772 return true;
21774 /* The flag is set to X; dependences with latency >= X are considered costly,
21775 and will not be scheduled in the same group. */
21776 if (rs6000_sched_costly_dep <= max_dep_latency
21777 && ((cost - distance) >= (int)rs6000_sched_costly_dep))
21778 return true;
21780 return false;
21783 /* Return the next insn after INSN that is found before TAIL is reached,
21784 skipping any "non-active" insns - insns that will not actually occupy
21785 an issue slot. Return NULL_RTX if such an insn is not found. */
21787 static rtx
21788 get_next_active_insn (rtx insn, rtx tail)
21790 if (insn == NULL_RTX || insn == tail)
21791 return NULL_RTX;
21793 while (1)
21795 insn = NEXT_INSN (insn);
21796 if (insn == NULL_RTX || insn == tail)
21797 return NULL_RTX;
21799 if (CALL_P (insn)
21800 || JUMP_P (insn)
21801 || (NONJUMP_INSN_P (insn)
21802 && GET_CODE (PATTERN (insn)) != USE
21803 && GET_CODE (PATTERN (insn)) != CLOBBER
21804 && INSN_CODE (insn) != CODE_FOR_stack_tie))
21805 break;
21807 return insn;
21810 /* We are about to begin issuing insns for this clock cycle. */
21812 static int
21813 rs6000_sched_reorder (FILE *dump ATTRIBUTE_UNUSED, int sched_verbose,
21814 rtx *ready ATTRIBUTE_UNUSED,
21815 int *pn_ready ATTRIBUTE_UNUSED,
21816 int clock_var ATTRIBUTE_UNUSED)
21818 int n_ready = *pn_ready;
21820 if (sched_verbose)
21821 fprintf (dump, "// rs6000_sched_reorder :\n");
21823 /* Reorder the ready list, if the second to last ready insn
21824 is a nonepipeline insn. */
21825 if (rs6000_cpu_attr == CPU_CELL && n_ready > 1)
21827 if (is_nonpipeline_insn (ready[n_ready - 1])
21828 && (recog_memoized (ready[n_ready - 2]) > 0))
21829 /* Simply swap first two insns. */
21831 rtx tmp = ready[n_ready - 1];
21832 ready[n_ready - 1] = ready[n_ready - 2];
21833 ready[n_ready - 2] = tmp;
21837 if (rs6000_cpu == PROCESSOR_POWER6)
21838 load_store_pendulum = 0;
21840 return rs6000_issue_rate ();
21843 /* Like rs6000_sched_reorder, but called after issuing each insn. */
21845 static int
21846 rs6000_sched_reorder2 (FILE *dump, int sched_verbose, rtx *ready,
21847 int *pn_ready, int clock_var ATTRIBUTE_UNUSED)
21849 if (sched_verbose)
21850 fprintf (dump, "// rs6000_sched_reorder2 :\n");
21852 /* For Power6, we need to handle some special cases to try and keep the
21853 store queue from overflowing and triggering expensive flushes.
21855 This code monitors how load and store instructions are being issued
21856 and skews the ready list one way or the other to increase the likelihood
21857 that a desired instruction is issued at the proper time.
21859 A couple of things are done. First, we maintain a "load_store_pendulum"
21860 to track the current state of load/store issue.
21862 - If the pendulum is at zero, then no loads or stores have been
21863 issued in the current cycle so we do nothing.
21865 - If the pendulum is 1, then a single load has been issued in this
21866 cycle and we attempt to locate another load in the ready list to
21867 issue with it.
21869 - If the pendulum is -2, then two stores have already been
21870 issued in this cycle, so we increase the priority of the first load
21871 in the ready list to increase it's likelihood of being chosen first
21872 in the next cycle.
21874 - If the pendulum is -1, then a single store has been issued in this
21875 cycle and we attempt to locate another store in the ready list to
21876 issue with it, preferring a store to an adjacent memory location to
21877 facilitate store pairing in the store queue.
21879 - If the pendulum is 2, then two loads have already been
21880 issued in this cycle, so we increase the priority of the first store
21881 in the ready list to increase it's likelihood of being chosen first
21882 in the next cycle.
21884 - If the pendulum < -2 or > 2, then do nothing.
21886 Note: This code covers the most common scenarios. There exist non
21887 load/store instructions which make use of the LSU and which
21888 would need to be accounted for to strictly model the behavior
21889 of the machine. Those instructions are currently unaccounted
21890 for to help minimize compile time overhead of this code.
21892 if (rs6000_cpu == PROCESSOR_POWER6 && last_scheduled_insn)
21894 int pos;
21895 int i;
21896 rtx tmp;
21898 if (is_store_insn (last_scheduled_insn))
21899 /* Issuing a store, swing the load_store_pendulum to the left */
21900 load_store_pendulum--;
21901 else if (is_load_insn (last_scheduled_insn))
21902 /* Issuing a load, swing the load_store_pendulum to the right */
21903 load_store_pendulum++;
21904 else
21905 return cached_can_issue_more;
21907 /* If the pendulum is balanced, or there is only one instruction on
21908 the ready list, then all is well, so return. */
21909 if ((load_store_pendulum == 0) || (*pn_ready <= 1))
21910 return cached_can_issue_more;
21912 if (load_store_pendulum == 1)
21914 /* A load has been issued in this cycle. Scan the ready list
21915 for another load to issue with it */
21916 pos = *pn_ready-1;
21918 while (pos >= 0)
21920 if (is_load_insn (ready[pos]))
21922 /* Found a load. Move it to the head of the ready list,
21923 and adjust it's priority so that it is more likely to
21924 stay there */
21925 tmp = ready[pos];
21926 for (i=pos; i<*pn_ready-1; i++)
21927 ready[i] = ready[i + 1];
21928 ready[*pn_ready-1] = tmp;
21930 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
21931 INSN_PRIORITY (tmp)++;
21932 break;
21934 pos--;
21937 else if (load_store_pendulum == -2)
21939 /* Two stores have been issued in this cycle. Increase the
21940 priority of the first load in the ready list to favor it for
21941 issuing in the next cycle. */
21942 pos = *pn_ready-1;
21944 while (pos >= 0)
21946 if (is_load_insn (ready[pos])
21947 && !sel_sched_p ()
21948 && INSN_PRIORITY_KNOWN (ready[pos]))
21950 INSN_PRIORITY (ready[pos])++;
21952 /* Adjust the pendulum to account for the fact that a load
21953 was found and increased in priority. This is to prevent
21954 increasing the priority of multiple loads */
21955 load_store_pendulum--;
21957 break;
21959 pos--;
21962 else if (load_store_pendulum == -1)
21964 /* A store has been issued in this cycle. Scan the ready list for
21965 another store to issue with it, preferring a store to an adjacent
21966 memory location */
21967 int first_store_pos = -1;
21969 pos = *pn_ready-1;
21971 while (pos >= 0)
21973 if (is_store_insn (ready[pos]))
21975 /* Maintain the index of the first store found on the
21976 list */
21977 if (first_store_pos == -1)
21978 first_store_pos = pos;
21980 if (is_store_insn (last_scheduled_insn)
21981 && adjacent_mem_locations (last_scheduled_insn,ready[pos]))
21983 /* Found an adjacent store. Move it to the head of the
21984 ready list, and adjust it's priority so that it is
21985 more likely to stay there */
21986 tmp = ready[pos];
21987 for (i=pos; i<*pn_ready-1; i++)
21988 ready[i] = ready[i + 1];
21989 ready[*pn_ready-1] = tmp;
21991 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
21992 INSN_PRIORITY (tmp)++;
21994 first_store_pos = -1;
21996 break;
21999 pos--;
22002 if (first_store_pos >= 0)
22004 /* An adjacent store wasn't found, but a non-adjacent store was,
22005 so move the non-adjacent store to the front of the ready
22006 list, and adjust its priority so that it is more likely to
22007 stay there. */
22008 tmp = ready[first_store_pos];
22009 for (i=first_store_pos; i<*pn_ready-1; i++)
22010 ready[i] = ready[i + 1];
22011 ready[*pn_ready-1] = tmp;
22012 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
22013 INSN_PRIORITY (tmp)++;
22016 else if (load_store_pendulum == 2)
22018 /* Two loads have been issued in this cycle. Increase the priority
22019 of the first store in the ready list to favor it for issuing in
22020 the next cycle. */
22021 pos = *pn_ready-1;
22023 while (pos >= 0)
22025 if (is_store_insn (ready[pos])
22026 && !sel_sched_p ()
22027 && INSN_PRIORITY_KNOWN (ready[pos]))
22029 INSN_PRIORITY (ready[pos])++;
22031 /* Adjust the pendulum to account for the fact that a store
22032 was found and increased in priority. This is to prevent
22033 increasing the priority of multiple stores */
22034 load_store_pendulum++;
22036 break;
22038 pos--;
22043 return cached_can_issue_more;
22046 /* Return whether the presence of INSN causes a dispatch group termination
22047 of group WHICH_GROUP.
22049 If WHICH_GROUP == current_group, this function will return true if INSN
22050 causes the termination of the current group (i.e, the dispatch group to
22051 which INSN belongs). This means that INSN will be the last insn in the
22052 group it belongs to.
22054 If WHICH_GROUP == previous_group, this function will return true if INSN
22055 causes the termination of the previous group (i.e, the dispatch group that
22056 precedes the group to which INSN belongs). This means that INSN will be
22057 the first insn in the group it belongs to). */
22059 static bool
22060 insn_terminates_group_p (rtx insn, enum group_termination which_group)
22062 bool first, last;
22064 if (! insn)
22065 return false;
22067 first = insn_must_be_first_in_group (insn);
22068 last = insn_must_be_last_in_group (insn);
22070 if (first && last)
22071 return true;
22073 if (which_group == current_group)
22074 return last;
22075 else if (which_group == previous_group)
22076 return first;
22078 return false;
22082 static bool
22083 insn_must_be_first_in_group (rtx insn)
22085 enum attr_type type;
22087 if (!insn
22088 || insn == NULL_RTX
22089 || GET_CODE (insn) == NOTE
22090 || GET_CODE (PATTERN (insn)) == USE
22091 || GET_CODE (PATTERN (insn)) == CLOBBER)
22092 return false;
22094 switch (rs6000_cpu)
22096 case PROCESSOR_POWER5:
22097 if (is_cracked_insn (insn))
22098 return true;
22099 case PROCESSOR_POWER4:
22100 if (is_microcoded_insn (insn))
22101 return true;
22103 if (!rs6000_sched_groups)
22104 return false;
22106 type = get_attr_type (insn);
22108 switch (type)
22110 case TYPE_MFCR:
22111 case TYPE_MFCRF:
22112 case TYPE_MTCR:
22113 case TYPE_DELAYED_CR:
22114 case TYPE_CR_LOGICAL:
22115 case TYPE_MTJMPR:
22116 case TYPE_MFJMPR:
22117 case TYPE_IDIV:
22118 case TYPE_LDIV:
22119 case TYPE_LOAD_L:
22120 case TYPE_STORE_C:
22121 case TYPE_ISYNC:
22122 case TYPE_SYNC:
22123 return true;
22124 default:
22125 break;
22127 break;
22128 case PROCESSOR_POWER6:
22129 type = get_attr_type (insn);
22131 switch (type)
22133 case TYPE_INSERT_DWORD:
22134 case TYPE_EXTS:
22135 case TYPE_CNTLZ:
22136 case TYPE_SHIFT:
22137 case TYPE_VAR_SHIFT_ROTATE:
22138 case TYPE_TRAP:
22139 case TYPE_IMUL:
22140 case TYPE_IMUL2:
22141 case TYPE_IMUL3:
22142 case TYPE_LMUL:
22143 case TYPE_IDIV:
22144 case TYPE_INSERT_WORD:
22145 case TYPE_DELAYED_COMPARE:
22146 case TYPE_IMUL_COMPARE:
22147 case TYPE_LMUL_COMPARE:
22148 case TYPE_FPCOMPARE:
22149 case TYPE_MFCR:
22150 case TYPE_MTCR:
22151 case TYPE_MFJMPR:
22152 case TYPE_MTJMPR:
22153 case TYPE_ISYNC:
22154 case TYPE_SYNC:
22155 case TYPE_LOAD_L:
22156 case TYPE_STORE_C:
22157 case TYPE_LOAD_U:
22158 case TYPE_LOAD_UX:
22159 case TYPE_LOAD_EXT_UX:
22160 case TYPE_STORE_U:
22161 case TYPE_STORE_UX:
22162 case TYPE_FPLOAD_U:
22163 case TYPE_FPLOAD_UX:
22164 case TYPE_FPSTORE_U:
22165 case TYPE_FPSTORE_UX:
22166 return true;
22167 default:
22168 break;
22170 break;
22171 case PROCESSOR_POWER7:
22172 type = get_attr_type (insn);
22174 switch (type)
22176 case TYPE_CR_LOGICAL:
22177 case TYPE_MFCR:
22178 case TYPE_MFCRF:
22179 case TYPE_MTCR:
22180 case TYPE_IDIV:
22181 case TYPE_LDIV:
22182 case TYPE_COMPARE:
22183 case TYPE_DELAYED_COMPARE:
22184 case TYPE_VAR_DELAYED_COMPARE:
22185 case TYPE_ISYNC:
22186 case TYPE_LOAD_L:
22187 case TYPE_STORE_C:
22188 case TYPE_LOAD_U:
22189 case TYPE_LOAD_UX:
22190 case TYPE_LOAD_EXT:
22191 case TYPE_LOAD_EXT_U:
22192 case TYPE_LOAD_EXT_UX:
22193 case TYPE_STORE_U:
22194 case TYPE_STORE_UX:
22195 case TYPE_FPLOAD_U:
22196 case TYPE_FPLOAD_UX:
22197 case TYPE_FPSTORE_U:
22198 case TYPE_FPSTORE_UX:
22199 case TYPE_MFJMPR:
22200 case TYPE_MTJMPR:
22201 return true;
22202 default:
22203 break;
22205 break;
22206 default:
22207 break;
22210 return false;
22213 static bool
22214 insn_must_be_last_in_group (rtx insn)
22216 enum attr_type type;
22218 if (!insn
22219 || insn == NULL_RTX
22220 || GET_CODE (insn) == NOTE
22221 || GET_CODE (PATTERN (insn)) == USE
22222 || GET_CODE (PATTERN (insn)) == CLOBBER)
22223 return false;
22225 switch (rs6000_cpu) {
22226 case PROCESSOR_POWER4:
22227 case PROCESSOR_POWER5:
22228 if (is_microcoded_insn (insn))
22229 return true;
22231 if (is_branch_slot_insn (insn))
22232 return true;
22234 break;
22235 case PROCESSOR_POWER6:
22236 type = get_attr_type (insn);
22238 switch (type)
22240 case TYPE_EXTS:
22241 case TYPE_CNTLZ:
22242 case TYPE_SHIFT:
22243 case TYPE_VAR_SHIFT_ROTATE:
22244 case TYPE_TRAP:
22245 case TYPE_IMUL:
22246 case TYPE_IMUL2:
22247 case TYPE_IMUL3:
22248 case TYPE_LMUL:
22249 case TYPE_IDIV:
22250 case TYPE_DELAYED_COMPARE:
22251 case TYPE_IMUL_COMPARE:
22252 case TYPE_LMUL_COMPARE:
22253 case TYPE_FPCOMPARE:
22254 case TYPE_MFCR:
22255 case TYPE_MTCR:
22256 case TYPE_MFJMPR:
22257 case TYPE_MTJMPR:
22258 case TYPE_ISYNC:
22259 case TYPE_SYNC:
22260 case TYPE_LOAD_L:
22261 case TYPE_STORE_C:
22262 return true;
22263 default:
22264 break;
22266 break;
22267 case PROCESSOR_POWER7:
22268 type = get_attr_type (insn);
22270 switch (type)
22272 case TYPE_ISYNC:
22273 case TYPE_SYNC:
22274 case TYPE_LOAD_L:
22275 case TYPE_STORE_C:
22276 case TYPE_LOAD_EXT_U:
22277 case TYPE_LOAD_EXT_UX:
22278 case TYPE_STORE_UX:
22279 return true;
22280 default:
22281 break;
22283 break;
22284 default:
22285 break;
22288 return false;
22291 /* Return true if it is recommended to keep NEXT_INSN "far" (in a separate
22292 dispatch group) from the insns in GROUP_INSNS. Return false otherwise. */
22294 static bool
22295 is_costly_group (rtx *group_insns, rtx next_insn)
22297 int i;
22298 int issue_rate = rs6000_issue_rate ();
22300 for (i = 0; i < issue_rate; i++)
22302 sd_iterator_def sd_it;
22303 dep_t dep;
22304 rtx insn = group_insns[i];
22306 if (!insn)
22307 continue;
22309 FOR_EACH_DEP (insn, SD_LIST_FORW, sd_it, dep)
22311 rtx next = DEP_CON (dep);
22313 if (next == next_insn
22314 && rs6000_is_costly_dependence (dep, dep_cost (dep), 0))
22315 return true;
22319 return false;
22322 /* Utility of the function redefine_groups.
22323 Check if it is too costly to schedule NEXT_INSN together with GROUP_INSNS
22324 in the same dispatch group. If so, insert nops before NEXT_INSN, in order
22325 to keep it "far" (in a separate group) from GROUP_INSNS, following
22326 one of the following schemes, depending on the value of the flag
22327 -minsert_sched_nops = X:
22328 (1) X == sched_finish_regroup_exact: insert exactly as many nops as needed
22329 in order to force NEXT_INSN into a separate group.
22330 (2) X < sched_finish_regroup_exact: insert exactly X nops.
22331 GROUP_END, CAN_ISSUE_MORE and GROUP_COUNT record the state after nop
22332 insertion (has a group just ended, how many vacant issue slots remain in the
22333 last group, and how many dispatch groups were encountered so far). */
22335 static int
22336 force_new_group (int sched_verbose, FILE *dump, rtx *group_insns,
22337 rtx next_insn, bool *group_end, int can_issue_more,
22338 int *group_count)
22340 rtx nop;
22341 bool force;
22342 int issue_rate = rs6000_issue_rate ();
22343 bool end = *group_end;
22344 int i;
22346 if (next_insn == NULL_RTX)
22347 return can_issue_more;
22349 if (rs6000_sched_insert_nops > sched_finish_regroup_exact)
22350 return can_issue_more;
22352 force = is_costly_group (group_insns, next_insn);
22353 if (!force)
22354 return can_issue_more;
22356 if (sched_verbose > 6)
22357 fprintf (dump,"force: group count = %d, can_issue_more = %d\n",
22358 *group_count ,can_issue_more);
22360 if (rs6000_sched_insert_nops == sched_finish_regroup_exact)
22362 if (*group_end)
22363 can_issue_more = 0;
22365 /* Since only a branch can be issued in the last issue_slot, it is
22366 sufficient to insert 'can_issue_more - 1' nops if next_insn is not
22367 a branch. If next_insn is a branch, we insert 'can_issue_more' nops;
22368 in this case the last nop will start a new group and the branch
22369 will be forced to the new group. */
22370 if (can_issue_more && !is_branch_slot_insn (next_insn))
22371 can_issue_more--;
22373 while (can_issue_more > 0)
22375 nop = gen_nop ();
22376 emit_insn_before (nop, next_insn);
22377 can_issue_more--;
22380 *group_end = true;
22381 return 0;
22384 if (rs6000_sched_insert_nops < sched_finish_regroup_exact)
22386 int n_nops = rs6000_sched_insert_nops;
22388 /* Nops can't be issued from the branch slot, so the effective
22389 issue_rate for nops is 'issue_rate - 1'. */
22390 if (can_issue_more == 0)
22391 can_issue_more = issue_rate;
22392 can_issue_more--;
22393 if (can_issue_more == 0)
22395 can_issue_more = issue_rate - 1;
22396 (*group_count)++;
22397 end = true;
22398 for (i = 0; i < issue_rate; i++)
22400 group_insns[i] = 0;
22404 while (n_nops > 0)
22406 nop = gen_nop ();
22407 emit_insn_before (nop, next_insn);
22408 if (can_issue_more == issue_rate - 1) /* new group begins */
22409 end = false;
22410 can_issue_more--;
22411 if (can_issue_more == 0)
22413 can_issue_more = issue_rate - 1;
22414 (*group_count)++;
22415 end = true;
22416 for (i = 0; i < issue_rate; i++)
22418 group_insns[i] = 0;
22421 n_nops--;
22424 /* Scale back relative to 'issue_rate' (instead of 'issue_rate - 1'). */
22425 can_issue_more++;
22427 /* Is next_insn going to start a new group? */
22428 *group_end
22429 = (end
22430 || (can_issue_more == 1 && !is_branch_slot_insn (next_insn))
22431 || (can_issue_more <= 2 && is_cracked_insn (next_insn))
22432 || (can_issue_more < issue_rate &&
22433 insn_terminates_group_p (next_insn, previous_group)));
22434 if (*group_end && end)
22435 (*group_count)--;
22437 if (sched_verbose > 6)
22438 fprintf (dump, "done force: group count = %d, can_issue_more = %d\n",
22439 *group_count, can_issue_more);
22440 return can_issue_more;
22443 return can_issue_more;
22446 /* This function tries to synch the dispatch groups that the compiler "sees"
22447 with the dispatch groups that the processor dispatcher is expected to
22448 form in practice. It tries to achieve this synchronization by forcing the
22449 estimated processor grouping on the compiler (as opposed to the function
22450 'pad_goups' which tries to force the scheduler's grouping on the processor).
22452 The function scans the insn sequence between PREV_HEAD_INSN and TAIL and
22453 examines the (estimated) dispatch groups that will be formed by the processor
22454 dispatcher. It marks these group boundaries to reflect the estimated
22455 processor grouping, overriding the grouping that the scheduler had marked.
22456 Depending on the value of the flag '-minsert-sched-nops' this function can
22457 force certain insns into separate groups or force a certain distance between
22458 them by inserting nops, for example, if there exists a "costly dependence"
22459 between the insns.
22461 The function estimates the group boundaries that the processor will form as
22462 follows: It keeps track of how many vacant issue slots are available after
22463 each insn. A subsequent insn will start a new group if one of the following
22464 4 cases applies:
22465 - no more vacant issue slots remain in the current dispatch group.
22466 - only the last issue slot, which is the branch slot, is vacant, but the next
22467 insn is not a branch.
22468 - only the last 2 or less issue slots, including the branch slot, are vacant,
22469 which means that a cracked insn (which occupies two issue slots) can't be
22470 issued in this group.
22471 - less than 'issue_rate' slots are vacant, and the next insn always needs to
22472 start a new group. */
22474 static int
22475 redefine_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail)
22477 rtx insn, next_insn;
22478 int issue_rate;
22479 int can_issue_more;
22480 int slot, i;
22481 bool group_end;
22482 int group_count = 0;
22483 rtx *group_insns;
22485 /* Initialize. */
22486 issue_rate = rs6000_issue_rate ();
22487 group_insns = XALLOCAVEC (rtx, issue_rate);
22488 for (i = 0; i < issue_rate; i++)
22490 group_insns[i] = 0;
22492 can_issue_more = issue_rate;
22493 slot = 0;
22494 insn = get_next_active_insn (prev_head_insn, tail);
22495 group_end = false;
22497 while (insn != NULL_RTX)
22499 slot = (issue_rate - can_issue_more);
22500 group_insns[slot] = insn;
22501 can_issue_more =
22502 rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more);
22503 if (insn_terminates_group_p (insn, current_group))
22504 can_issue_more = 0;
22506 next_insn = get_next_active_insn (insn, tail);
22507 if (next_insn == NULL_RTX)
22508 return group_count + 1;
22510 /* Is next_insn going to start a new group? */
22511 group_end
22512 = (can_issue_more == 0
22513 || (can_issue_more == 1 && !is_branch_slot_insn (next_insn))
22514 || (can_issue_more <= 2 && is_cracked_insn (next_insn))
22515 || (can_issue_more < issue_rate &&
22516 insn_terminates_group_p (next_insn, previous_group)));
22518 can_issue_more = force_new_group (sched_verbose, dump, group_insns,
22519 next_insn, &group_end, can_issue_more,
22520 &group_count);
22522 if (group_end)
22524 group_count++;
22525 can_issue_more = 0;
22526 for (i = 0; i < issue_rate; i++)
22528 group_insns[i] = 0;
22532 if (GET_MODE (next_insn) == TImode && can_issue_more)
22533 PUT_MODE (next_insn, VOIDmode);
22534 else if (!can_issue_more && GET_MODE (next_insn) != TImode)
22535 PUT_MODE (next_insn, TImode);
22537 insn = next_insn;
22538 if (can_issue_more == 0)
22539 can_issue_more = issue_rate;
22540 } /* while */
22542 return group_count;
22545 /* Scan the insn sequence between PREV_HEAD_INSN and TAIL and examine the
22546 dispatch group boundaries that the scheduler had marked. Pad with nops
22547 any dispatch groups which have vacant issue slots, in order to force the
22548 scheduler's grouping on the processor dispatcher. The function
22549 returns the number of dispatch groups found. */
22551 static int
22552 pad_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail)
22554 rtx insn, next_insn;
22555 rtx nop;
22556 int issue_rate;
22557 int can_issue_more;
22558 int group_end;
22559 int group_count = 0;
22561 /* Initialize issue_rate. */
22562 issue_rate = rs6000_issue_rate ();
22563 can_issue_more = issue_rate;
22565 insn = get_next_active_insn (prev_head_insn, tail);
22566 next_insn = get_next_active_insn (insn, tail);
22568 while (insn != NULL_RTX)
22570 can_issue_more =
22571 rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more);
22573 group_end = (next_insn == NULL_RTX || GET_MODE (next_insn) == TImode);
22575 if (next_insn == NULL_RTX)
22576 break;
22578 if (group_end)
22580 /* If the scheduler had marked group termination at this location
22581 (between insn and next_insn), and neither insn nor next_insn will
22582 force group termination, pad the group with nops to force group
22583 termination. */
22584 if (can_issue_more
22585 && (rs6000_sched_insert_nops == sched_finish_pad_groups)
22586 && !insn_terminates_group_p (insn, current_group)
22587 && !insn_terminates_group_p (next_insn, previous_group))
22589 if (!is_branch_slot_insn (next_insn))
22590 can_issue_more--;
22592 while (can_issue_more)
22594 nop = gen_nop ();
22595 emit_insn_before (nop, next_insn);
22596 can_issue_more--;
22600 can_issue_more = issue_rate;
22601 group_count++;
22604 insn = next_insn;
22605 next_insn = get_next_active_insn (insn, tail);
22608 return group_count;
22611 /* We're beginning a new block. Initialize data structures as necessary. */
22613 static void
22614 rs6000_sched_init (FILE *dump ATTRIBUTE_UNUSED,
22615 int sched_verbose ATTRIBUTE_UNUSED,
22616 int max_ready ATTRIBUTE_UNUSED)
22618 last_scheduled_insn = NULL_RTX;
22619 load_store_pendulum = 0;
22622 /* The following function is called at the end of scheduling BB.
22623 After reload, it inserts nops at insn group bundling. */
22625 static void
22626 rs6000_sched_finish (FILE *dump, int sched_verbose)
22628 int n_groups;
22630 if (sched_verbose)
22631 fprintf (dump, "=== Finishing schedule.\n");
22633 if (reload_completed && rs6000_sched_groups)
22635 /* Do not run sched_finish hook when selective scheduling enabled. */
22636 if (sel_sched_p ())
22637 return;
22639 if (rs6000_sched_insert_nops == sched_finish_none)
22640 return;
22642 if (rs6000_sched_insert_nops == sched_finish_pad_groups)
22643 n_groups = pad_groups (dump, sched_verbose,
22644 current_sched_info->prev_head,
22645 current_sched_info->next_tail);
22646 else
22647 n_groups = redefine_groups (dump, sched_verbose,
22648 current_sched_info->prev_head,
22649 current_sched_info->next_tail);
22651 if (sched_verbose >= 6)
22653 fprintf (dump, "ngroups = %d\n", n_groups);
22654 print_rtl (dump, current_sched_info->prev_head);
22655 fprintf (dump, "Done finish_sched\n");
22660 struct _rs6000_sched_context
22662 short cached_can_issue_more;
22663 rtx last_scheduled_insn;
22664 int load_store_pendulum;
22667 typedef struct _rs6000_sched_context rs6000_sched_context_def;
22668 typedef rs6000_sched_context_def *rs6000_sched_context_t;
22670 /* Allocate store for new scheduling context. */
22671 static void *
22672 rs6000_alloc_sched_context (void)
22674 return xmalloc (sizeof (rs6000_sched_context_def));
22677 /* If CLEAN_P is true then initializes _SC with clean data,
22678 and from the global context otherwise. */
22679 static void
22680 rs6000_init_sched_context (void *_sc, bool clean_p)
22682 rs6000_sched_context_t sc = (rs6000_sched_context_t) _sc;
22684 if (clean_p)
22686 sc->cached_can_issue_more = 0;
22687 sc->last_scheduled_insn = NULL_RTX;
22688 sc->load_store_pendulum = 0;
22690 else
22692 sc->cached_can_issue_more = cached_can_issue_more;
22693 sc->last_scheduled_insn = last_scheduled_insn;
22694 sc->load_store_pendulum = load_store_pendulum;
22698 /* Sets the global scheduling context to the one pointed to by _SC. */
22699 static void
22700 rs6000_set_sched_context (void *_sc)
22702 rs6000_sched_context_t sc = (rs6000_sched_context_t) _sc;
22704 gcc_assert (sc != NULL);
22706 cached_can_issue_more = sc->cached_can_issue_more;
22707 last_scheduled_insn = sc->last_scheduled_insn;
22708 load_store_pendulum = sc->load_store_pendulum;
22711 /* Free _SC. */
22712 static void
22713 rs6000_free_sched_context (void *_sc)
22715 gcc_assert (_sc != NULL);
22717 free (_sc);
22721 /* Length in units of the trampoline for entering a nested function. */
22724 rs6000_trampoline_size (void)
22726 int ret = 0;
22728 switch (DEFAULT_ABI)
22730 default:
22731 gcc_unreachable ();
22733 case ABI_AIX:
22734 ret = (TARGET_32BIT) ? 12 : 24;
22735 break;
22737 case ABI_DARWIN:
22738 case ABI_V4:
22739 ret = (TARGET_32BIT) ? 40 : 48;
22740 break;
22743 return ret;
22746 /* Emit RTL insns to initialize the variable parts of a trampoline.
22747 FNADDR is an RTX for the address of the function's pure code.
22748 CXT is an RTX for the static chain value for the function. */
22750 void
22751 rs6000_initialize_trampoline (rtx addr, rtx fnaddr, rtx cxt)
22753 int regsize = (TARGET_32BIT) ? 4 : 8;
22754 rtx ctx_reg = force_reg (Pmode, cxt);
22756 switch (DEFAULT_ABI)
22758 default:
22759 gcc_unreachable ();
22761 /* Macros to shorten the code expansions below. */
22762 #define MEM_DEREF(addr) gen_rtx_MEM (Pmode, memory_address (Pmode, addr))
22763 #define MEM_PLUS(addr,offset) \
22764 gen_rtx_MEM (Pmode, memory_address (Pmode, plus_constant (addr, offset)))
22766 /* Under AIX, just build the 3 word function descriptor */
22767 case ABI_AIX:
22769 rtx fn_reg = gen_reg_rtx (Pmode);
22770 rtx toc_reg = gen_reg_rtx (Pmode);
22771 emit_move_insn (fn_reg, MEM_DEREF (fnaddr));
22772 emit_move_insn (toc_reg, MEM_PLUS (fnaddr, regsize));
22773 emit_move_insn (MEM_DEREF (addr), fn_reg);
22774 emit_move_insn (MEM_PLUS (addr, regsize), toc_reg);
22775 emit_move_insn (MEM_PLUS (addr, 2*regsize), ctx_reg);
22777 break;
22779 /* Under V.4/eabi/darwin, __trampoline_setup does the real work. */
22780 case ABI_DARWIN:
22781 case ABI_V4:
22782 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__trampoline_setup"),
22783 LCT_NORMAL, VOIDmode, 4,
22784 addr, Pmode,
22785 GEN_INT (rs6000_trampoline_size ()), SImode,
22786 fnaddr, Pmode,
22787 ctx_reg, Pmode);
22788 break;
22791 return;
22795 /* Handle the "altivec" attribute. The attribute may have
22796 arguments as follows:
22798 __attribute__((altivec(vector__)))
22799 __attribute__((altivec(pixel__))) (always followed by 'unsigned short')
22800 __attribute__((altivec(bool__))) (always followed by 'unsigned')
22802 and may appear more than once (e.g., 'vector bool char') in a
22803 given declaration. */
22805 static tree
22806 rs6000_handle_altivec_attribute (tree *node,
22807 tree name ATTRIBUTE_UNUSED,
22808 tree args,
22809 int flags ATTRIBUTE_UNUSED,
22810 bool *no_add_attrs)
22812 tree type = *node, result = NULL_TREE;
22813 enum machine_mode mode;
22814 int unsigned_p;
22815 char altivec_type
22816 = ((args && TREE_CODE (args) == TREE_LIST && TREE_VALUE (args)
22817 && TREE_CODE (TREE_VALUE (args)) == IDENTIFIER_NODE)
22818 ? *IDENTIFIER_POINTER (TREE_VALUE (args))
22819 : '?');
22821 while (POINTER_TYPE_P (type)
22822 || TREE_CODE (type) == FUNCTION_TYPE
22823 || TREE_CODE (type) == METHOD_TYPE
22824 || TREE_CODE (type) == ARRAY_TYPE)
22825 type = TREE_TYPE (type);
22827 mode = TYPE_MODE (type);
22829 /* Check for invalid AltiVec type qualifiers. */
22830 if (type == long_double_type_node)
22831 error ("use of %<long double%> in AltiVec types is invalid");
22832 else if (type == boolean_type_node)
22833 error ("use of boolean types in AltiVec types is invalid");
22834 else if (TREE_CODE (type) == COMPLEX_TYPE)
22835 error ("use of %<complex%> in AltiVec types is invalid");
22836 else if (DECIMAL_FLOAT_MODE_P (mode))
22837 error ("use of decimal floating point types in AltiVec types is invalid");
22838 else if (!TARGET_VSX)
22840 if (type == long_unsigned_type_node || type == long_integer_type_node)
22842 if (TARGET_64BIT)
22843 error ("use of %<long%> in AltiVec types is invalid for "
22844 "64-bit code without -mvsx");
22845 else if (rs6000_warn_altivec_long)
22846 warning (0, "use of %<long%> in AltiVec types is deprecated; "
22847 "use %<int%>");
22849 else if (type == long_long_unsigned_type_node
22850 || type == long_long_integer_type_node)
22851 error ("use of %<long long%> in AltiVec types is invalid without "
22852 "-mvsx");
22853 else if (type == double_type_node)
22854 error ("use of %<double%> in AltiVec types is invalid without -mvsx");
22857 switch (altivec_type)
22859 case 'v':
22860 unsigned_p = TYPE_UNSIGNED (type);
22861 switch (mode)
22863 case DImode:
22864 result = (unsigned_p ? unsigned_V2DI_type_node : V2DI_type_node);
22865 break;
22866 case SImode:
22867 result = (unsigned_p ? unsigned_V4SI_type_node : V4SI_type_node);
22868 break;
22869 case HImode:
22870 result = (unsigned_p ? unsigned_V8HI_type_node : V8HI_type_node);
22871 break;
22872 case QImode:
22873 result = (unsigned_p ? unsigned_V16QI_type_node : V16QI_type_node);
22874 break;
22875 case SFmode: result = V4SF_type_node; break;
22876 case DFmode: result = V2DF_type_node; break;
22877 /* If the user says 'vector int bool', we may be handed the 'bool'
22878 attribute _before_ the 'vector' attribute, and so select the
22879 proper type in the 'b' case below. */
22880 case V4SImode: case V8HImode: case V16QImode: case V4SFmode:
22881 case V2DImode: case V2DFmode:
22882 result = type;
22883 default: break;
22885 break;
22886 case 'b':
22887 switch (mode)
22889 case DImode: case V2DImode: result = bool_V2DI_type_node; break;
22890 case SImode: case V4SImode: result = bool_V4SI_type_node; break;
22891 case HImode: case V8HImode: result = bool_V8HI_type_node; break;
22892 case QImode: case V16QImode: result = bool_V16QI_type_node;
22893 default: break;
22895 break;
22896 case 'p':
22897 switch (mode)
22899 case V8HImode: result = pixel_V8HI_type_node;
22900 default: break;
22902 default: break;
22905 /* Propagate qualifiers attached to the element type
22906 onto the vector type. */
22907 if (result && result != type && TYPE_QUALS (type))
22908 result = build_qualified_type (result, TYPE_QUALS (type));
22910 *no_add_attrs = true; /* No need to hang on to the attribute. */
22912 if (result)
22913 *node = lang_hooks.types.reconstruct_complex_type (*node, result);
22915 return NULL_TREE;
22918 /* AltiVec defines four built-in scalar types that serve as vector
22919 elements; we must teach the compiler how to mangle them. */
22921 static const char *
22922 rs6000_mangle_type (const_tree type)
22924 type = TYPE_MAIN_VARIANT (type);
22926 if (TREE_CODE (type) != VOID_TYPE && TREE_CODE (type) != BOOLEAN_TYPE
22927 && TREE_CODE (type) != INTEGER_TYPE && TREE_CODE (type) != REAL_TYPE)
22928 return NULL;
22930 if (type == bool_char_type_node) return "U6__boolc";
22931 if (type == bool_short_type_node) return "U6__bools";
22932 if (type == pixel_type_node) return "u7__pixel";
22933 if (type == bool_int_type_node) return "U6__booli";
22934 if (type == bool_long_type_node) return "U6__booll";
22936 /* Mangle IBM extended float long double as `g' (__float128) on
22937 powerpc*-linux where long-double-64 previously was the default. */
22938 if (TYPE_MAIN_VARIANT (type) == long_double_type_node
22939 && TARGET_ELF
22940 && TARGET_LONG_DOUBLE_128
22941 && !TARGET_IEEEQUAD)
22942 return "g";
22944 /* For all other types, use normal C++ mangling. */
22945 return NULL;
22948 /* Handle a "longcall" or "shortcall" attribute; arguments as in
22949 struct attribute_spec.handler. */
22951 static tree
22952 rs6000_handle_longcall_attribute (tree *node, tree name,
22953 tree args ATTRIBUTE_UNUSED,
22954 int flags ATTRIBUTE_UNUSED,
22955 bool *no_add_attrs)
22957 if (TREE_CODE (*node) != FUNCTION_TYPE
22958 && TREE_CODE (*node) != FIELD_DECL
22959 && TREE_CODE (*node) != TYPE_DECL)
22961 warning (OPT_Wattributes, "%qE attribute only applies to functions",
22962 name);
22963 *no_add_attrs = true;
22966 return NULL_TREE;
22969 /* Set longcall attributes on all functions declared when
22970 rs6000_default_long_calls is true. */
22971 static void
22972 rs6000_set_default_type_attributes (tree type)
22974 if (rs6000_default_long_calls
22975 && (TREE_CODE (type) == FUNCTION_TYPE
22976 || TREE_CODE (type) == METHOD_TYPE))
22977 TYPE_ATTRIBUTES (type) = tree_cons (get_identifier ("longcall"),
22978 NULL_TREE,
22979 TYPE_ATTRIBUTES (type));
22981 #if TARGET_MACHO
22982 darwin_set_default_type_attributes (type);
22983 #endif
22986 /* Return a reference suitable for calling a function with the
22987 longcall attribute. */
22990 rs6000_longcall_ref (rtx call_ref)
22992 const char *call_name;
22993 tree node;
22995 if (GET_CODE (call_ref) != SYMBOL_REF)
22996 return call_ref;
22998 /* System V adds '.' to the internal name, so skip them. */
22999 call_name = XSTR (call_ref, 0);
23000 if (*call_name == '.')
23002 while (*call_name == '.')
23003 call_name++;
23005 node = get_identifier (call_name);
23006 call_ref = gen_rtx_SYMBOL_REF (VOIDmode, IDENTIFIER_POINTER (node));
23009 return force_reg (Pmode, call_ref);
23012 #ifndef TARGET_USE_MS_BITFIELD_LAYOUT
23013 #define TARGET_USE_MS_BITFIELD_LAYOUT 0
23014 #endif
23016 /* Handle a "ms_struct" or "gcc_struct" attribute; arguments as in
23017 struct attribute_spec.handler. */
23018 static tree
23019 rs6000_handle_struct_attribute (tree *node, tree name,
23020 tree args ATTRIBUTE_UNUSED,
23021 int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
23023 tree *type = NULL;
23024 if (DECL_P (*node))
23026 if (TREE_CODE (*node) == TYPE_DECL)
23027 type = &TREE_TYPE (*node);
23029 else
23030 type = node;
23032 if (!(type && (TREE_CODE (*type) == RECORD_TYPE
23033 || TREE_CODE (*type) == UNION_TYPE)))
23035 warning (OPT_Wattributes, "%qE attribute ignored", name);
23036 *no_add_attrs = true;
23039 else if ((is_attribute_p ("ms_struct", name)
23040 && lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (*type)))
23041 || ((is_attribute_p ("gcc_struct", name)
23042 && lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (*type)))))
23044 warning (OPT_Wattributes, "%qE incompatible attribute ignored",
23045 name);
23046 *no_add_attrs = true;
23049 return NULL_TREE;
23052 static bool
23053 rs6000_ms_bitfield_layout_p (const_tree record_type)
23055 return (TARGET_USE_MS_BITFIELD_LAYOUT &&
23056 !lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (record_type)))
23057 || lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (record_type));
23060 #ifdef USING_ELFOS_H
23062 /* A get_unnamed_section callback, used for switching to toc_section. */
23064 static void
23065 rs6000_elf_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
23067 if (DEFAULT_ABI == ABI_AIX
23068 && TARGET_MINIMAL_TOC
23069 && !TARGET_RELOCATABLE)
23071 if (!toc_initialized)
23073 toc_initialized = 1;
23074 fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);
23075 (*targetm.asm_out.internal_label) (asm_out_file, "LCTOC", 0);
23076 fprintf (asm_out_file, "\t.tc ");
23077 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1[TC],");
23078 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
23079 fprintf (asm_out_file, "\n");
23081 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
23082 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
23083 fprintf (asm_out_file, " = .+32768\n");
23085 else
23086 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
23088 else if (DEFAULT_ABI == ABI_AIX && !TARGET_RELOCATABLE)
23089 fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);
23090 else
23092 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
23093 if (!toc_initialized)
23095 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
23096 fprintf (asm_out_file, " = .+32768\n");
23097 toc_initialized = 1;
23102 /* Implement TARGET_ASM_INIT_SECTIONS. */
23104 static void
23105 rs6000_elf_asm_init_sections (void)
23107 toc_section
23108 = get_unnamed_section (0, rs6000_elf_output_toc_section_asm_op, NULL);
23110 sdata2_section
23111 = get_unnamed_section (SECTION_WRITE, output_section_asm_op,
23112 SDATA2_SECTION_ASM_OP);
23115 /* Implement TARGET_SELECT_RTX_SECTION. */
23117 static section *
23118 rs6000_elf_select_rtx_section (enum machine_mode mode, rtx x,
23119 unsigned HOST_WIDE_INT align)
23121 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
23122 return toc_section;
23123 else
23124 return default_elf_select_rtx_section (mode, x, align);
23127 /* For a SYMBOL_REF, set generic flags and then perform some
23128 target-specific processing.
23130 When the AIX ABI is requested on a non-AIX system, replace the
23131 function name with the real name (with a leading .) rather than the
23132 function descriptor name. This saves a lot of overriding code to
23133 read the prefixes. */
23135 static void
23136 rs6000_elf_encode_section_info (tree decl, rtx rtl, int first)
23138 default_encode_section_info (decl, rtl, first);
23140 if (first
23141 && TREE_CODE (decl) == FUNCTION_DECL
23142 && !TARGET_AIX
23143 && DEFAULT_ABI == ABI_AIX)
23145 rtx sym_ref = XEXP (rtl, 0);
23146 size_t len = strlen (XSTR (sym_ref, 0));
23147 char *str = XALLOCAVEC (char, len + 2);
23148 str[0] = '.';
23149 memcpy (str + 1, XSTR (sym_ref, 0), len + 1);
23150 XSTR (sym_ref, 0) = ggc_alloc_string (str, len + 1);
23154 static inline bool
23155 compare_section_name (const char *section, const char *templ)
23157 int len;
23159 len = strlen (templ);
23160 return (strncmp (section, templ, len) == 0
23161 && (section[len] == 0 || section[len] == '.'));
23164 bool
23165 rs6000_elf_in_small_data_p (const_tree decl)
23167 if (rs6000_sdata == SDATA_NONE)
23168 return false;
23170 /* We want to merge strings, so we never consider them small data. */
23171 if (TREE_CODE (decl) == STRING_CST)
23172 return false;
23174 /* Functions are never in the small data area. */
23175 if (TREE_CODE (decl) == FUNCTION_DECL)
23176 return false;
23178 if (TREE_CODE (decl) == VAR_DECL && DECL_SECTION_NAME (decl))
23180 const char *section = TREE_STRING_POINTER (DECL_SECTION_NAME (decl));
23181 if (compare_section_name (section, ".sdata")
23182 || compare_section_name (section, ".sdata2")
23183 || compare_section_name (section, ".gnu.linkonce.s")
23184 || compare_section_name (section, ".sbss")
23185 || compare_section_name (section, ".sbss2")
23186 || compare_section_name (section, ".gnu.linkonce.sb")
23187 || strcmp (section, ".PPC.EMB.sdata0") == 0
23188 || strcmp (section, ".PPC.EMB.sbss0") == 0)
23189 return true;
23191 else
23193 HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (decl));
23195 if (size > 0
23196 && (unsigned HOST_WIDE_INT) size <= g_switch_value
23197 /* If it's not public, and we're not going to reference it there,
23198 there's no need to put it in the small data section. */
23199 && (rs6000_sdata != SDATA_DATA || TREE_PUBLIC (decl)))
23200 return true;
23203 return false;
23206 #endif /* USING_ELFOS_H */
23208 /* Implement TARGET_USE_BLOCKS_FOR_CONSTANT_P. */
23210 static bool
23211 rs6000_use_blocks_for_constant_p (enum machine_mode mode, const_rtx x)
23213 return !ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode);
23216 /* Return a REG that occurs in ADDR with coefficient 1.
23217 ADDR can be effectively incremented by incrementing REG.
23219 r0 is special and we must not select it as an address
23220 register by this routine since our caller will try to
23221 increment the returned register via an "la" instruction. */
23224 find_addr_reg (rtx addr)
23226 while (GET_CODE (addr) == PLUS)
23228 if (GET_CODE (XEXP (addr, 0)) == REG
23229 && REGNO (XEXP (addr, 0)) != 0)
23230 addr = XEXP (addr, 0);
23231 else if (GET_CODE (XEXP (addr, 1)) == REG
23232 && REGNO (XEXP (addr, 1)) != 0)
23233 addr = XEXP (addr, 1);
23234 else if (CONSTANT_P (XEXP (addr, 0)))
23235 addr = XEXP (addr, 1);
23236 else if (CONSTANT_P (XEXP (addr, 1)))
23237 addr = XEXP (addr, 0);
23238 else
23239 gcc_unreachable ();
23241 gcc_assert (GET_CODE (addr) == REG && REGNO (addr) != 0);
23242 return addr;
23245 void
23246 rs6000_fatal_bad_address (rtx op)
23248 fatal_insn ("bad address", op);
23251 #if TARGET_MACHO
23253 static tree branch_island_list = 0;
23255 /* Remember to generate a branch island for far calls to the given
23256 function. */
23258 static void
23259 add_compiler_branch_island (tree label_name, tree function_name,
23260 int line_number)
23262 tree branch_island = build_tree_list (function_name, label_name);
23263 TREE_TYPE (branch_island) = build_int_cst (NULL_TREE, line_number);
23264 TREE_CHAIN (branch_island) = branch_island_list;
23265 branch_island_list = branch_island;
23268 #define BRANCH_ISLAND_LABEL_NAME(BRANCH_ISLAND) TREE_VALUE (BRANCH_ISLAND)
23269 #define BRANCH_ISLAND_FUNCTION_NAME(BRANCH_ISLAND) TREE_PURPOSE (BRANCH_ISLAND)
23270 #define BRANCH_ISLAND_LINE_NUMBER(BRANCH_ISLAND) \
23271 TREE_INT_CST_LOW (TREE_TYPE (BRANCH_ISLAND))
23273 /* Generate far-jump branch islands for everything on the
23274 branch_island_list. Invoked immediately after the last instruction
23275 of the epilogue has been emitted; the branch-islands must be
23276 appended to, and contiguous with, the function body. Mach-O stubs
23277 are generated in machopic_output_stub(). */
23279 static void
23280 macho_branch_islands (void)
23282 char tmp_buf[512];
23283 tree branch_island;
23285 for (branch_island = branch_island_list;
23286 branch_island;
23287 branch_island = TREE_CHAIN (branch_island))
23289 const char *label =
23290 IDENTIFIER_POINTER (BRANCH_ISLAND_LABEL_NAME (branch_island));
23291 const char *name =
23292 IDENTIFIER_POINTER (BRANCH_ISLAND_FUNCTION_NAME (branch_island));
23293 char name_buf[512];
23294 /* Cheap copy of the details from the Darwin ASM_OUTPUT_LABELREF(). */
23295 if (name[0] == '*' || name[0] == '&')
23296 strcpy (name_buf, name+1);
23297 else
23299 name_buf[0] = '_';
23300 strcpy (name_buf+1, name);
23302 strcpy (tmp_buf, "\n");
23303 strcat (tmp_buf, label);
23304 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
23305 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
23306 dbxout_stabd (N_SLINE, BRANCH_ISLAND_LINE_NUMBER (branch_island));
23307 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
23308 if (flag_pic)
23310 strcat (tmp_buf, ":\n\tmflr r0\n\tbcl 20,31,");
23311 strcat (tmp_buf, label);
23312 strcat (tmp_buf, "_pic\n");
23313 strcat (tmp_buf, label);
23314 strcat (tmp_buf, "_pic:\n\tmflr r11\n");
23316 strcat (tmp_buf, "\taddis r11,r11,ha16(");
23317 strcat (tmp_buf, name_buf);
23318 strcat (tmp_buf, " - ");
23319 strcat (tmp_buf, label);
23320 strcat (tmp_buf, "_pic)\n");
23322 strcat (tmp_buf, "\tmtlr r0\n");
23324 strcat (tmp_buf, "\taddi r12,r11,lo16(");
23325 strcat (tmp_buf, name_buf);
23326 strcat (tmp_buf, " - ");
23327 strcat (tmp_buf, label);
23328 strcat (tmp_buf, "_pic)\n");
23330 strcat (tmp_buf, "\tmtctr r12\n\tbctr\n");
23332 else
23334 strcat (tmp_buf, ":\nlis r12,hi16(");
23335 strcat (tmp_buf, name_buf);
23336 strcat (tmp_buf, ")\n\tori r12,r12,lo16(");
23337 strcat (tmp_buf, name_buf);
23338 strcat (tmp_buf, ")\n\tmtctr r12\n\tbctr");
23340 output_asm_insn (tmp_buf, 0);
23341 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
23342 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
23343 dbxout_stabd (N_SLINE, BRANCH_ISLAND_LINE_NUMBER (branch_island));
23344 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
23347 branch_island_list = 0;
23350 /* NO_PREVIOUS_DEF checks in the link list whether the function name is
23351 already there or not. */
23353 static int
23354 no_previous_def (tree function_name)
23356 tree branch_island;
23357 for (branch_island = branch_island_list;
23358 branch_island;
23359 branch_island = TREE_CHAIN (branch_island))
23360 if (function_name == BRANCH_ISLAND_FUNCTION_NAME (branch_island))
23361 return 0;
23362 return 1;
23365 /* GET_PREV_LABEL gets the label name from the previous definition of
23366 the function. */
23368 static tree
23369 get_prev_label (tree function_name)
23371 tree branch_island;
23372 for (branch_island = branch_island_list;
23373 branch_island;
23374 branch_island = TREE_CHAIN (branch_island))
23375 if (function_name == BRANCH_ISLAND_FUNCTION_NAME (branch_island))
23376 return BRANCH_ISLAND_LABEL_NAME (branch_island);
23377 return 0;
23380 #ifndef DARWIN_LINKER_GENERATES_ISLANDS
23381 #define DARWIN_LINKER_GENERATES_ISLANDS 0
23382 #endif
23384 /* KEXTs still need branch islands. */
23385 #define DARWIN_GENERATE_ISLANDS (!DARWIN_LINKER_GENERATES_ISLANDS \
23386 || flag_mkernel || flag_apple_kext)
23388 /* INSN is either a function call or a millicode call. It may have an
23389 unconditional jump in its delay slot.
23391 CALL_DEST is the routine we are calling. */
23393 char *
23394 output_call (rtx insn, rtx *operands, int dest_operand_number,
23395 int cookie_operand_number)
23397 static char buf[256];
23398 if (DARWIN_GENERATE_ISLANDS
23399 && GET_CODE (operands[dest_operand_number]) == SYMBOL_REF
23400 && (INTVAL (operands[cookie_operand_number]) & CALL_LONG))
23402 tree labelname;
23403 tree funname = get_identifier (XSTR (operands[dest_operand_number], 0));
23405 if (no_previous_def (funname))
23407 rtx label_rtx = gen_label_rtx ();
23408 char *label_buf, temp_buf[256];
23409 ASM_GENERATE_INTERNAL_LABEL (temp_buf, "L",
23410 CODE_LABEL_NUMBER (label_rtx));
23411 label_buf = temp_buf[0] == '*' ? temp_buf + 1 : temp_buf;
23412 labelname = get_identifier (label_buf);
23413 add_compiler_branch_island (labelname, funname, insn_line (insn));
23415 else
23416 labelname = get_prev_label (funname);
23418 /* "jbsr foo, L42" is Mach-O for "Link as 'bl foo' if a 'bl'
23419 instruction will reach 'foo', otherwise link as 'bl L42'".
23420 "L42" should be a 'branch island', that will do a far jump to
23421 'foo'. Branch islands are generated in
23422 macho_branch_islands(). */
23423 sprintf (buf, "jbsr %%z%d,%.246s",
23424 dest_operand_number, IDENTIFIER_POINTER (labelname));
23426 else
23427 sprintf (buf, "bl %%z%d", dest_operand_number);
23428 return buf;
23431 /* Generate PIC and indirect symbol stubs. */
23433 void
23434 machopic_output_stub (FILE *file, const char *symb, const char *stub)
23436 unsigned int length;
23437 char *symbol_name, *lazy_ptr_name;
23438 char *local_label_0;
23439 static int label = 0;
23441 /* Lose our funky encoding stuff so it doesn't contaminate the stub. */
23442 symb = (*targetm.strip_name_encoding) (symb);
23445 length = strlen (symb);
23446 symbol_name = XALLOCAVEC (char, length + 32);
23447 GEN_SYMBOL_NAME_FOR_SYMBOL (symbol_name, symb, length);
23449 lazy_ptr_name = XALLOCAVEC (char, length + 32);
23450 GEN_LAZY_PTR_NAME_FOR_SYMBOL (lazy_ptr_name, symb, length);
23452 if (flag_pic == 2)
23453 switch_to_section (darwin_sections[machopic_picsymbol_stub1_section]);
23454 else
23455 switch_to_section (darwin_sections[machopic_symbol_stub1_section]);
23457 if (flag_pic == 2)
23459 fprintf (file, "\t.align 5\n");
23461 fprintf (file, "%s:\n", stub);
23462 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
23464 label++;
23465 local_label_0 = XALLOCAVEC (char, sizeof ("\"L00000000000$spb\""));
23466 sprintf (local_label_0, "\"L%011d$spb\"", label);
23468 fprintf (file, "\tmflr r0\n");
23469 fprintf (file, "\tbcl 20,31,%s\n", local_label_0);
23470 fprintf (file, "%s:\n\tmflr r11\n", local_label_0);
23471 fprintf (file, "\taddis r11,r11,ha16(%s-%s)\n",
23472 lazy_ptr_name, local_label_0);
23473 fprintf (file, "\tmtlr r0\n");
23474 fprintf (file, "\t%s r12,lo16(%s-%s)(r11)\n",
23475 (TARGET_64BIT ? "ldu" : "lwzu"),
23476 lazy_ptr_name, local_label_0);
23477 fprintf (file, "\tmtctr r12\n");
23478 fprintf (file, "\tbctr\n");
23480 else
23482 fprintf (file, "\t.align 4\n");
23484 fprintf (file, "%s:\n", stub);
23485 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
23487 fprintf (file, "\tlis r11,ha16(%s)\n", lazy_ptr_name);
23488 fprintf (file, "\t%s r12,lo16(%s)(r11)\n",
23489 (TARGET_64BIT ? "ldu" : "lwzu"),
23490 lazy_ptr_name);
23491 fprintf (file, "\tmtctr r12\n");
23492 fprintf (file, "\tbctr\n");
23495 switch_to_section (darwin_sections[machopic_lazy_symbol_ptr_section]);
23496 fprintf (file, "%s:\n", lazy_ptr_name);
23497 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
23498 fprintf (file, "%sdyld_stub_binding_helper\n",
23499 (TARGET_64BIT ? DOUBLE_INT_ASM_OP : "\t.long\t"));
23502 /* Legitimize PIC addresses. If the address is already
23503 position-independent, we return ORIG. Newly generated
23504 position-independent addresses go into a reg. This is REG if non
23505 zero, otherwise we allocate register(s) as necessary. */
23507 #define SMALL_INT(X) ((UINTVAL (X) + 0x8000) < 0x10000)
23510 rs6000_machopic_legitimize_pic_address (rtx orig, enum machine_mode mode,
23511 rtx reg)
23513 rtx base, offset;
23515 if (reg == NULL && ! reload_in_progress && ! reload_completed)
23516 reg = gen_reg_rtx (Pmode);
23518 if (GET_CODE (orig) == CONST)
23520 rtx reg_temp;
23522 if (GET_CODE (XEXP (orig, 0)) == PLUS
23523 && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx)
23524 return orig;
23526 gcc_assert (GET_CODE (XEXP (orig, 0)) == PLUS);
23528 /* Use a different reg for the intermediate value, as
23529 it will be marked UNCHANGING. */
23530 reg_temp = !can_create_pseudo_p () ? reg : gen_reg_rtx (Pmode);
23531 base = rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 0),
23532 Pmode, reg_temp);
23533 offset =
23534 rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 1),
23535 Pmode, reg);
23537 if (GET_CODE (offset) == CONST_INT)
23539 if (SMALL_INT (offset))
23540 return plus_constant (base, INTVAL (offset));
23541 else if (! reload_in_progress && ! reload_completed)
23542 offset = force_reg (Pmode, offset);
23543 else
23545 rtx mem = force_const_mem (Pmode, orig);
23546 return machopic_legitimize_pic_address (mem, Pmode, reg);
23549 return gen_rtx_PLUS (Pmode, base, offset);
23552 /* Fall back on generic machopic code. */
23553 return machopic_legitimize_pic_address (orig, mode, reg);
23556 /* Output a .machine directive for the Darwin assembler, and call
23557 the generic start_file routine. */
23559 static void
23560 rs6000_darwin_file_start (void)
23562 static const struct
23564 const char *arg;
23565 const char *name;
23566 int if_set;
23567 } mapping[] = {
23568 { "ppc64", "ppc64", MASK_64BIT },
23569 { "970", "ppc970", MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64 },
23570 { "power4", "ppc970", 0 },
23571 { "G5", "ppc970", 0 },
23572 { "7450", "ppc7450", 0 },
23573 { "7400", "ppc7400", MASK_ALTIVEC },
23574 { "G4", "ppc7400", 0 },
23575 { "750", "ppc750", 0 },
23576 { "740", "ppc750", 0 },
23577 { "G3", "ppc750", 0 },
23578 { "604e", "ppc604e", 0 },
23579 { "604", "ppc604", 0 },
23580 { "603e", "ppc603", 0 },
23581 { "603", "ppc603", 0 },
23582 { "601", "ppc601", 0 },
23583 { NULL, "ppc", 0 } };
23584 const char *cpu_id = "";
23585 size_t i;
23587 rs6000_file_start ();
23588 darwin_file_start ();
23590 /* Determine the argument to -mcpu=. Default to G3 if not specified. */
23591 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
23592 if (rs6000_select[i].set_arch_p && rs6000_select[i].string
23593 && rs6000_select[i].string[0] != '\0')
23594 cpu_id = rs6000_select[i].string;
23596 /* Look through the mapping array. Pick the first name that either
23597 matches the argument, has a bit set in IF_SET that is also set
23598 in the target flags, or has a NULL name. */
23600 i = 0;
23601 while (mapping[i].arg != NULL
23602 && strcmp (mapping[i].arg, cpu_id) != 0
23603 && (mapping[i].if_set & target_flags) == 0)
23604 i++;
23606 fprintf (asm_out_file, "\t.machine %s\n", mapping[i].name);
23609 #endif /* TARGET_MACHO */
23611 #if TARGET_ELF
23612 static int
23613 rs6000_elf_reloc_rw_mask (void)
23615 if (flag_pic)
23616 return 3;
23617 else if (DEFAULT_ABI == ABI_AIX)
23618 return 2;
23619 else
23620 return 0;
23623 /* Record an element in the table of global constructors. SYMBOL is
23624 a SYMBOL_REF of the function to be called; PRIORITY is a number
23625 between 0 and MAX_INIT_PRIORITY.
23627 This differs from default_named_section_asm_out_constructor in
23628 that we have special handling for -mrelocatable. */
23630 static void
23631 rs6000_elf_asm_out_constructor (rtx symbol, int priority)
23633 const char *section = ".ctors";
23634 char buf[16];
23636 if (priority != DEFAULT_INIT_PRIORITY)
23638 sprintf (buf, ".ctors.%.5u",
23639 /* Invert the numbering so the linker puts us in the proper
23640 order; constructors are run from right to left, and the
23641 linker sorts in increasing order. */
23642 MAX_INIT_PRIORITY - priority);
23643 section = buf;
23646 switch_to_section (get_section (section, SECTION_WRITE, NULL));
23647 assemble_align (POINTER_SIZE);
23649 if (TARGET_RELOCATABLE)
23651 fputs ("\t.long (", asm_out_file);
23652 output_addr_const (asm_out_file, symbol);
23653 fputs (")@fixup\n", asm_out_file);
23655 else
23656 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
23659 static void
23660 rs6000_elf_asm_out_destructor (rtx symbol, int priority)
23662 const char *section = ".dtors";
23663 char buf[16];
23665 if (priority != DEFAULT_INIT_PRIORITY)
23667 sprintf (buf, ".dtors.%.5u",
23668 /* Invert the numbering so the linker puts us in the proper
23669 order; constructors are run from right to left, and the
23670 linker sorts in increasing order. */
23671 MAX_INIT_PRIORITY - priority);
23672 section = buf;
23675 switch_to_section (get_section (section, SECTION_WRITE, NULL));
23676 assemble_align (POINTER_SIZE);
23678 if (TARGET_RELOCATABLE)
23680 fputs ("\t.long (", asm_out_file);
23681 output_addr_const (asm_out_file, symbol);
23682 fputs (")@fixup\n", asm_out_file);
23684 else
23685 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
23688 void
23689 rs6000_elf_declare_function_name (FILE *file, const char *name, tree decl)
23691 if (TARGET_64BIT)
23693 fputs ("\t.section\t\".opd\",\"aw\"\n\t.align 3\n", file);
23694 ASM_OUTPUT_LABEL (file, name);
23695 fputs (DOUBLE_INT_ASM_OP, file);
23696 rs6000_output_function_entry (file, name);
23697 fputs (",.TOC.@tocbase,0\n\t.previous\n", file);
23698 if (DOT_SYMBOLS)
23700 fputs ("\t.size\t", file);
23701 assemble_name (file, name);
23702 fputs (",24\n\t.type\t.", file);
23703 assemble_name (file, name);
23704 fputs (",@function\n", file);
23705 if (TREE_PUBLIC (decl) && ! DECL_WEAK (decl))
23707 fputs ("\t.globl\t.", file);
23708 assemble_name (file, name);
23709 putc ('\n', file);
23712 else
23713 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
23714 ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
23715 rs6000_output_function_entry (file, name);
23716 fputs (":\n", file);
23717 return;
23720 if (TARGET_RELOCATABLE
23721 && !TARGET_SECURE_PLT
23722 && (get_pool_size () != 0 || crtl->profile)
23723 && uses_TOC ())
23725 char buf[256];
23727 (*targetm.asm_out.internal_label) (file, "LCL", rs6000_pic_labelno);
23729 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
23730 fprintf (file, "\t.long ");
23731 assemble_name (file, buf);
23732 putc ('-', file);
23733 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
23734 assemble_name (file, buf);
23735 putc ('\n', file);
23738 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
23739 ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
23741 if (DEFAULT_ABI == ABI_AIX)
23743 const char *desc_name, *orig_name;
23745 orig_name = (*targetm.strip_name_encoding) (name);
23746 desc_name = orig_name;
23747 while (*desc_name == '.')
23748 desc_name++;
23750 if (TREE_PUBLIC (decl))
23751 fprintf (file, "\t.globl %s\n", desc_name);
23753 fprintf (file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
23754 fprintf (file, "%s:\n", desc_name);
23755 fprintf (file, "\t.long %s\n", orig_name);
23756 fputs ("\t.long _GLOBAL_OFFSET_TABLE_\n", file);
23757 if (DEFAULT_ABI == ABI_AIX)
23758 fputs ("\t.long 0\n", file);
23759 fprintf (file, "\t.previous\n");
23761 ASM_OUTPUT_LABEL (file, name);
23764 static void
23765 rs6000_elf_end_indicate_exec_stack (void)
23767 if (TARGET_32BIT)
23768 file_end_indicate_exec_stack ();
23770 #endif
23772 #if TARGET_XCOFF
23773 static void
23774 rs6000_xcoff_asm_output_anchor (rtx symbol)
23776 char buffer[100];
23778 sprintf (buffer, "$ + " HOST_WIDE_INT_PRINT_DEC,
23779 SYMBOL_REF_BLOCK_OFFSET (symbol));
23780 ASM_OUTPUT_DEF (asm_out_file, XSTR (symbol, 0), buffer);
23783 static void
23784 rs6000_xcoff_asm_globalize_label (FILE *stream, const char *name)
23786 fputs (GLOBAL_ASM_OP, stream);
23787 RS6000_OUTPUT_BASENAME (stream, name);
23788 putc ('\n', stream);
23791 /* A get_unnamed_decl callback, used for read-only sections. PTR
23792 points to the section string variable. */
23794 static void
23795 rs6000_xcoff_output_readonly_section_asm_op (const void *directive)
23797 fprintf (asm_out_file, "\t.csect %s[RO],%s\n",
23798 *(const char *const *) directive,
23799 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR);
23802 /* Likewise for read-write sections. */
23804 static void
23805 rs6000_xcoff_output_readwrite_section_asm_op (const void *directive)
23807 fprintf (asm_out_file, "\t.csect %s[RW],%s\n",
23808 *(const char *const *) directive,
23809 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR);
23812 /* A get_unnamed_section callback, used for switching to toc_section. */
23814 static void
23815 rs6000_xcoff_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
23817 if (TARGET_MINIMAL_TOC)
23819 /* toc_section is always selected at least once from
23820 rs6000_xcoff_file_start, so this is guaranteed to
23821 always be defined once and only once in each file. */
23822 if (!toc_initialized)
23824 fputs ("\t.toc\nLCTOC..1:\n", asm_out_file);
23825 fputs ("\t.tc toc_table[TC],toc_table[RW]\n", asm_out_file);
23826 toc_initialized = 1;
23828 fprintf (asm_out_file, "\t.csect toc_table[RW]%s\n",
23829 (TARGET_32BIT ? "" : ",3"));
23831 else
23832 fputs ("\t.toc\n", asm_out_file);
23835 /* Implement TARGET_ASM_INIT_SECTIONS. */
23837 static void
23838 rs6000_xcoff_asm_init_sections (void)
23840 read_only_data_section
23841 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
23842 &xcoff_read_only_section_name);
23844 private_data_section
23845 = get_unnamed_section (SECTION_WRITE,
23846 rs6000_xcoff_output_readwrite_section_asm_op,
23847 &xcoff_private_data_section_name);
23849 read_only_private_data_section
23850 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
23851 &xcoff_private_data_section_name);
23853 toc_section
23854 = get_unnamed_section (0, rs6000_xcoff_output_toc_section_asm_op, NULL);
23856 readonly_data_section = read_only_data_section;
23857 exception_section = data_section;
23860 static int
23861 rs6000_xcoff_reloc_rw_mask (void)
23863 return 3;
23866 static void
23867 rs6000_xcoff_asm_named_section (const char *name, unsigned int flags,
23868 tree decl ATTRIBUTE_UNUSED)
23870 int smclass;
23871 static const char * const suffix[3] = { "PR", "RO", "RW" };
23873 if (flags & SECTION_CODE)
23874 smclass = 0;
23875 else if (flags & SECTION_WRITE)
23876 smclass = 2;
23877 else
23878 smclass = 1;
23880 fprintf (asm_out_file, "\t.csect %s%s[%s],%u\n",
23881 (flags & SECTION_CODE) ? "." : "",
23882 name, suffix[smclass], flags & SECTION_ENTSIZE);
23885 static section *
23886 rs6000_xcoff_select_section (tree decl, int reloc,
23887 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
23889 if (decl_readonly_section (decl, reloc))
23891 if (TREE_PUBLIC (decl))
23892 return read_only_data_section;
23893 else
23894 return read_only_private_data_section;
23896 else
23898 if (TREE_PUBLIC (decl))
23899 return data_section;
23900 else
23901 return private_data_section;
23905 static void
23906 rs6000_xcoff_unique_section (tree decl, int reloc ATTRIBUTE_UNUSED)
23908 const char *name;
23910 /* Use select_section for private and uninitialized data. */
23911 if (!TREE_PUBLIC (decl)
23912 || DECL_COMMON (decl)
23913 || DECL_INITIAL (decl) == NULL_TREE
23914 || DECL_INITIAL (decl) == error_mark_node
23915 || (flag_zero_initialized_in_bss
23916 && initializer_zerop (DECL_INITIAL (decl))))
23917 return;
23919 name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
23920 name = (*targetm.strip_name_encoding) (name);
23921 DECL_SECTION_NAME (decl) = build_string (strlen (name), name);
23924 /* Select section for constant in constant pool.
23926 On RS/6000, all constants are in the private read-only data area.
23927 However, if this is being placed in the TOC it must be output as a
23928 toc entry. */
23930 static section *
23931 rs6000_xcoff_select_rtx_section (enum machine_mode mode, rtx x,
23932 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
23934 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
23935 return toc_section;
23936 else
23937 return read_only_private_data_section;
23940 /* Remove any trailing [DS] or the like from the symbol name. */
23942 static const char *
23943 rs6000_xcoff_strip_name_encoding (const char *name)
23945 size_t len;
23946 if (*name == '*')
23947 name++;
23948 len = strlen (name);
23949 if (name[len - 1] == ']')
23950 return ggc_alloc_string (name, len - 4);
23951 else
23952 return name;
23955 /* Section attributes. AIX is always PIC. */
23957 static unsigned int
23958 rs6000_xcoff_section_type_flags (tree decl, const char *name, int reloc)
23960 unsigned int align;
23961 unsigned int flags = default_section_type_flags (decl, name, reloc);
23963 /* Align to at least UNIT size. */
23964 if (flags & SECTION_CODE)
23965 align = MIN_UNITS_PER_WORD;
23966 else
23967 /* Increase alignment of large objects if not already stricter. */
23968 align = MAX ((DECL_ALIGN (decl) / BITS_PER_UNIT),
23969 int_size_in_bytes (TREE_TYPE (decl)) > MIN_UNITS_PER_WORD
23970 ? UNITS_PER_FP_WORD : MIN_UNITS_PER_WORD);
23972 return flags | (exact_log2 (align) & SECTION_ENTSIZE);
23975 /* Output at beginning of assembler file.
23977 Initialize the section names for the RS/6000 at this point.
23979 Specify filename, including full path, to assembler.
23981 We want to go into the TOC section so at least one .toc will be emitted.
23982 Also, in order to output proper .bs/.es pairs, we need at least one static
23983 [RW] section emitted.
23985 Finally, declare mcount when profiling to make the assembler happy. */
23987 static void
23988 rs6000_xcoff_file_start (void)
23990 rs6000_gen_section_name (&xcoff_bss_section_name,
23991 main_input_filename, ".bss_");
23992 rs6000_gen_section_name (&xcoff_private_data_section_name,
23993 main_input_filename, ".rw_");
23994 rs6000_gen_section_name (&xcoff_read_only_section_name,
23995 main_input_filename, ".ro_");
23997 fputs ("\t.file\t", asm_out_file);
23998 output_quoted_string (asm_out_file, main_input_filename);
23999 fputc ('\n', asm_out_file);
24000 if (write_symbols != NO_DEBUG)
24001 switch_to_section (private_data_section);
24002 switch_to_section (text_section);
24003 if (profile_flag)
24004 fprintf (asm_out_file, "\t.extern %s\n", RS6000_MCOUNT);
24005 rs6000_file_start ();
24008 /* Output at end of assembler file.
24009 On the RS/6000, referencing data should automatically pull in text. */
24011 static void
24012 rs6000_xcoff_file_end (void)
24014 switch_to_section (text_section);
24015 fputs ("_section_.text:\n", asm_out_file);
24016 switch_to_section (data_section);
24017 fputs (TARGET_32BIT
24018 ? "\t.long _section_.text\n" : "\t.llong _section_.text\n",
24019 asm_out_file);
24021 #endif /* TARGET_XCOFF */
24023 /* Compute a (partial) cost for rtx X. Return true if the complete
24024 cost has been computed, and false if subexpressions should be
24025 scanned. In either case, *TOTAL contains the cost result. */
24027 static bool
24028 rs6000_rtx_costs (rtx x, int code, int outer_code, int *total,
24029 bool speed)
24031 enum machine_mode mode = GET_MODE (x);
24033 switch (code)
24035 /* On the RS/6000, if it is valid in the insn, it is free. */
24036 case CONST_INT:
24037 if (((outer_code == SET
24038 || outer_code == PLUS
24039 || outer_code == MINUS)
24040 && (satisfies_constraint_I (x)
24041 || satisfies_constraint_L (x)))
24042 || (outer_code == AND
24043 && (satisfies_constraint_K (x)
24044 || (mode == SImode
24045 ? satisfies_constraint_L (x)
24046 : satisfies_constraint_J (x))
24047 || mask_operand (x, mode)
24048 || (mode == DImode
24049 && mask64_operand (x, DImode))))
24050 || ((outer_code == IOR || outer_code == XOR)
24051 && (satisfies_constraint_K (x)
24052 || (mode == SImode
24053 ? satisfies_constraint_L (x)
24054 : satisfies_constraint_J (x))))
24055 || outer_code == ASHIFT
24056 || outer_code == ASHIFTRT
24057 || outer_code == LSHIFTRT
24058 || outer_code == ROTATE
24059 || outer_code == ROTATERT
24060 || outer_code == ZERO_EXTRACT
24061 || (outer_code == MULT
24062 && satisfies_constraint_I (x))
24063 || ((outer_code == DIV || outer_code == UDIV
24064 || outer_code == MOD || outer_code == UMOD)
24065 && exact_log2 (INTVAL (x)) >= 0)
24066 || (outer_code == COMPARE
24067 && (satisfies_constraint_I (x)
24068 || satisfies_constraint_K (x)))
24069 || (outer_code == EQ
24070 && (satisfies_constraint_I (x)
24071 || satisfies_constraint_K (x)
24072 || (mode == SImode
24073 ? satisfies_constraint_L (x)
24074 : satisfies_constraint_J (x))))
24075 || (outer_code == GTU
24076 && satisfies_constraint_I (x))
24077 || (outer_code == LTU
24078 && satisfies_constraint_P (x)))
24080 *total = 0;
24081 return true;
24083 else if ((outer_code == PLUS
24084 && reg_or_add_cint_operand (x, VOIDmode))
24085 || (outer_code == MINUS
24086 && reg_or_sub_cint_operand (x, VOIDmode))
24087 || ((outer_code == SET
24088 || outer_code == IOR
24089 || outer_code == XOR)
24090 && (INTVAL (x)
24091 & ~ (unsigned HOST_WIDE_INT) 0xffffffff) == 0))
24093 *total = COSTS_N_INSNS (1);
24094 return true;
24096 /* FALLTHRU */
24098 case CONST_DOUBLE:
24099 if (mode == DImode && code == CONST_DOUBLE)
24101 if ((outer_code == IOR || outer_code == XOR)
24102 && CONST_DOUBLE_HIGH (x) == 0
24103 && (CONST_DOUBLE_LOW (x)
24104 & ~ (unsigned HOST_WIDE_INT) 0xffff) == 0)
24106 *total = 0;
24107 return true;
24109 else if ((outer_code == AND && and64_2_operand (x, DImode))
24110 || ((outer_code == SET
24111 || outer_code == IOR
24112 || outer_code == XOR)
24113 && CONST_DOUBLE_HIGH (x) == 0))
24115 *total = COSTS_N_INSNS (1);
24116 return true;
24119 /* FALLTHRU */
24121 case CONST:
24122 case HIGH:
24123 case SYMBOL_REF:
24124 case MEM:
24125 /* When optimizing for size, MEM should be slightly more expensive
24126 than generating address, e.g., (plus (reg) (const)).
24127 L1 cache latency is about two instructions. */
24128 *total = !speed ? COSTS_N_INSNS (1) + 1 : COSTS_N_INSNS (2);
24129 return true;
24131 case LABEL_REF:
24132 *total = 0;
24133 return true;
24135 case PLUS:
24136 if (mode == DFmode)
24138 if (GET_CODE (XEXP (x, 0)) == MULT)
24140 /* FNMA accounted in outer NEG. */
24141 if (outer_code == NEG)
24142 *total = rs6000_cost->dmul - rs6000_cost->fp;
24143 else
24144 *total = rs6000_cost->dmul;
24146 else
24147 *total = rs6000_cost->fp;
24149 else if (mode == SFmode)
24151 /* FNMA accounted in outer NEG. */
24152 if (outer_code == NEG && GET_CODE (XEXP (x, 0)) == MULT)
24153 *total = 0;
24154 else
24155 *total = rs6000_cost->fp;
24157 else
24158 *total = COSTS_N_INSNS (1);
24159 return false;
24161 case MINUS:
24162 if (mode == DFmode)
24164 if (GET_CODE (XEXP (x, 0)) == MULT
24165 || GET_CODE (XEXP (x, 1)) == MULT)
24167 /* FNMA accounted in outer NEG. */
24168 if (outer_code == NEG)
24169 *total = rs6000_cost->dmul - rs6000_cost->fp;
24170 else
24171 *total = rs6000_cost->dmul;
24173 else
24174 *total = rs6000_cost->fp;
24176 else if (mode == SFmode)
24178 /* FNMA accounted in outer NEG. */
24179 if (outer_code == NEG && GET_CODE (XEXP (x, 0)) == MULT)
24180 *total = 0;
24181 else
24182 *total = rs6000_cost->fp;
24184 else
24185 *total = COSTS_N_INSNS (1);
24186 return false;
24188 case MULT:
24189 if (GET_CODE (XEXP (x, 1)) == CONST_INT
24190 && satisfies_constraint_I (XEXP (x, 1)))
24192 if (INTVAL (XEXP (x, 1)) >= -256
24193 && INTVAL (XEXP (x, 1)) <= 255)
24194 *total = rs6000_cost->mulsi_const9;
24195 else
24196 *total = rs6000_cost->mulsi_const;
24198 /* FMA accounted in outer PLUS/MINUS. */
24199 else if ((mode == DFmode || mode == SFmode)
24200 && (outer_code == PLUS || outer_code == MINUS))
24201 *total = 0;
24202 else if (mode == DFmode)
24203 *total = rs6000_cost->dmul;
24204 else if (mode == SFmode)
24205 *total = rs6000_cost->fp;
24206 else if (mode == DImode)
24207 *total = rs6000_cost->muldi;
24208 else
24209 *total = rs6000_cost->mulsi;
24210 return false;
24212 case DIV:
24213 case MOD:
24214 if (FLOAT_MODE_P (mode))
24216 *total = mode == DFmode ? rs6000_cost->ddiv
24217 : rs6000_cost->sdiv;
24218 return false;
24220 /* FALLTHRU */
24222 case UDIV:
24223 case UMOD:
24224 if (GET_CODE (XEXP (x, 1)) == CONST_INT
24225 && exact_log2 (INTVAL (XEXP (x, 1))) >= 0)
24227 if (code == DIV || code == MOD)
24228 /* Shift, addze */
24229 *total = COSTS_N_INSNS (2);
24230 else
24231 /* Shift */
24232 *total = COSTS_N_INSNS (1);
24234 else
24236 if (GET_MODE (XEXP (x, 1)) == DImode)
24237 *total = rs6000_cost->divdi;
24238 else
24239 *total = rs6000_cost->divsi;
24241 /* Add in shift and subtract for MOD. */
24242 if (code == MOD || code == UMOD)
24243 *total += COSTS_N_INSNS (2);
24244 return false;
24246 case CTZ:
24247 case FFS:
24248 *total = COSTS_N_INSNS (4);
24249 return false;
24251 case POPCOUNT:
24252 *total = COSTS_N_INSNS (6);
24253 return false;
24255 case NOT:
24256 if (outer_code == AND || outer_code == IOR || outer_code == XOR)
24258 *total = 0;
24259 return false;
24261 /* FALLTHRU */
24263 case AND:
24264 case CLZ:
24265 case IOR:
24266 case XOR:
24267 case ZERO_EXTRACT:
24268 *total = COSTS_N_INSNS (1);
24269 return false;
24271 case ASHIFT:
24272 case ASHIFTRT:
24273 case LSHIFTRT:
24274 case ROTATE:
24275 case ROTATERT:
24276 /* Handle mul_highpart. */
24277 if (outer_code == TRUNCATE
24278 && GET_CODE (XEXP (x, 0)) == MULT)
24280 if (mode == DImode)
24281 *total = rs6000_cost->muldi;
24282 else
24283 *total = rs6000_cost->mulsi;
24284 return true;
24286 else if (outer_code == AND)
24287 *total = 0;
24288 else
24289 *total = COSTS_N_INSNS (1);
24290 return false;
24292 case SIGN_EXTEND:
24293 case ZERO_EXTEND:
24294 if (GET_CODE (XEXP (x, 0)) == MEM)
24295 *total = 0;
24296 else
24297 *total = COSTS_N_INSNS (1);
24298 return false;
24300 case COMPARE:
24301 case NEG:
24302 case ABS:
24303 if (!FLOAT_MODE_P (mode))
24305 *total = COSTS_N_INSNS (1);
24306 return false;
24308 /* FALLTHRU */
24310 case FLOAT:
24311 case UNSIGNED_FLOAT:
24312 case FIX:
24313 case UNSIGNED_FIX:
24314 case FLOAT_TRUNCATE:
24315 *total = rs6000_cost->fp;
24316 return false;
24318 case FLOAT_EXTEND:
24319 if (mode == DFmode)
24320 *total = 0;
24321 else
24322 *total = rs6000_cost->fp;
24323 return false;
24325 case UNSPEC:
24326 switch (XINT (x, 1))
24328 case UNSPEC_FRSP:
24329 *total = rs6000_cost->fp;
24330 return true;
24332 default:
24333 break;
24335 break;
24337 case CALL:
24338 case IF_THEN_ELSE:
24339 if (!speed)
24341 *total = COSTS_N_INSNS (1);
24342 return true;
24344 else if (FLOAT_MODE_P (mode)
24345 && TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS)
24347 *total = rs6000_cost->fp;
24348 return false;
24350 break;
24352 case EQ:
24353 case GTU:
24354 case LTU:
24355 /* Carry bit requires mode == Pmode.
24356 NEG or PLUS already counted so only add one. */
24357 if (mode == Pmode
24358 && (outer_code == NEG || outer_code == PLUS))
24360 *total = COSTS_N_INSNS (1);
24361 return true;
24363 if (outer_code == SET)
24365 if (XEXP (x, 1) == const0_rtx)
24367 *total = COSTS_N_INSNS (2);
24368 return true;
24370 else if (mode == Pmode)
24372 *total = COSTS_N_INSNS (3);
24373 return false;
24376 /* FALLTHRU */
24378 case GT:
24379 case LT:
24380 case UNORDERED:
24381 if (outer_code == SET && (XEXP (x, 1) == const0_rtx))
24383 *total = COSTS_N_INSNS (2);
24384 return true;
24386 /* CC COMPARE. */
24387 if (outer_code == COMPARE)
24389 *total = 0;
24390 return true;
24392 break;
24394 default:
24395 break;
24398 return false;
24401 /* Debug form of r6000_rtx_costs that is selected if -mdebug=cost. */
24403 static bool
24404 rs6000_debug_rtx_costs (rtx x, int code, int outer_code, int *total,
24405 bool speed)
24407 bool ret = rs6000_rtx_costs (x, code, outer_code, total, speed);
24409 fprintf (stderr,
24410 "\nrs6000_rtx_costs, return = %s, code = %s, outer_code = %s, "
24411 "total = %d, speed = %s, x:\n",
24412 ret ? "complete" : "scan inner",
24413 GET_RTX_NAME (code),
24414 GET_RTX_NAME (outer_code),
24415 *total,
24416 speed ? "true" : "false");
24418 debug_rtx (x);
24420 return ret;
24423 /* Debug form of ADDRESS_COST that is selected if -mdebug=cost. */
24425 static int
24426 rs6000_debug_address_cost (rtx x, bool speed)
24428 int ret = TARGET_ADDRESS_COST (x, speed);
24430 fprintf (stderr, "\nrs6000_address_cost, return = %d, speed = %s, x:\n",
24431 ret, speed ? "true" : "false");
24432 debug_rtx (x);
24434 return ret;
24438 /* A C expression returning the cost of moving data from a register of class
24439 CLASS1 to one of CLASS2. */
24442 rs6000_register_move_cost (enum machine_mode mode,
24443 enum reg_class from, enum reg_class to)
24445 int ret;
24447 /* Moves from/to GENERAL_REGS. */
24448 if (reg_classes_intersect_p (to, GENERAL_REGS)
24449 || reg_classes_intersect_p (from, GENERAL_REGS))
24451 if (! reg_classes_intersect_p (to, GENERAL_REGS))
24452 from = to;
24454 if (from == FLOAT_REGS || from == ALTIVEC_REGS || from == VSX_REGS)
24455 ret = (rs6000_memory_move_cost (mode, from, 0)
24456 + rs6000_memory_move_cost (mode, GENERAL_REGS, 0));
24458 /* It's more expensive to move CR_REGS than CR0_REGS because of the
24459 shift. */
24460 else if (from == CR_REGS)
24461 ret = 4;
24463 /* Power6 has slower LR/CTR moves so make them more expensive than
24464 memory in order to bias spills to memory .*/
24465 else if (rs6000_cpu == PROCESSOR_POWER6
24466 && reg_classes_intersect_p (from, LINK_OR_CTR_REGS))
24467 ret = 6 * hard_regno_nregs[0][mode];
24469 else
24470 /* A move will cost one instruction per GPR moved. */
24471 ret = 2 * hard_regno_nregs[0][mode];
24474 /* If we have VSX, we can easily move between FPR or Altivec registers. */
24475 else if (VECTOR_UNIT_VSX_P (mode)
24476 && reg_classes_intersect_p (to, VSX_REGS)
24477 && reg_classes_intersect_p (from, VSX_REGS))
24478 ret = 2 * hard_regno_nregs[32][mode];
24480 /* Moving between two similar registers is just one instruction. */
24481 else if (reg_classes_intersect_p (to, from))
24482 ret = (mode == TFmode || mode == TDmode) ? 4 : 2;
24484 /* Everything else has to go through GENERAL_REGS. */
24485 else
24486 ret = (rs6000_register_move_cost (mode, GENERAL_REGS, to)
24487 + rs6000_register_move_cost (mode, from, GENERAL_REGS));
24489 if (TARGET_DEBUG_COST)
24490 fprintf (stderr,
24491 "rs6000_register_move_cost:, ret=%d, mode=%s, from=%s, to=%s\n",
24492 ret, GET_MODE_NAME (mode), reg_class_names[from],
24493 reg_class_names[to]);
24495 return ret;
24498 /* A C expressions returning the cost of moving data of MODE from a register to
24499 or from memory. */
24502 rs6000_memory_move_cost (enum machine_mode mode, enum reg_class rclass,
24503 int in ATTRIBUTE_UNUSED)
24505 int ret;
24507 if (reg_classes_intersect_p (rclass, GENERAL_REGS))
24508 ret = 4 * hard_regno_nregs[0][mode];
24509 else if (reg_classes_intersect_p (rclass, FLOAT_REGS))
24510 ret = 4 * hard_regno_nregs[32][mode];
24511 else if (reg_classes_intersect_p (rclass, ALTIVEC_REGS))
24512 ret = 4 * hard_regno_nregs[FIRST_ALTIVEC_REGNO][mode];
24513 else
24514 ret = 4 + rs6000_register_move_cost (mode, rclass, GENERAL_REGS);
24516 if (TARGET_DEBUG_COST)
24517 fprintf (stderr,
24518 "rs6000_memory_move_cost: ret=%d, mode=%s, rclass=%s, in=%d\n",
24519 ret, GET_MODE_NAME (mode), reg_class_names[rclass], in);
24521 return ret;
24524 /* Returns a code for a target-specific builtin that implements
24525 reciprocal of the function, or NULL_TREE if not available. */
24527 static tree
24528 rs6000_builtin_reciprocal (unsigned int fn, bool md_fn,
24529 bool sqrt ATTRIBUTE_UNUSED)
24531 if (! (TARGET_RECIP && TARGET_PPC_GFXOPT && !optimize_size
24532 && flag_finite_math_only && !flag_trapping_math
24533 && flag_unsafe_math_optimizations))
24534 return NULL_TREE;
24536 if (md_fn)
24537 return NULL_TREE;
24538 else
24539 switch (fn)
24541 case BUILT_IN_SQRTF:
24542 return rs6000_builtin_decls[RS6000_BUILTIN_RSQRTF];
24544 default:
24545 return NULL_TREE;
24549 /* Newton-Raphson approximation of single-precision floating point divide n/d.
24550 Assumes no trapping math and finite arguments. */
24552 void
24553 rs6000_emit_swdivsf (rtx dst, rtx n, rtx d)
24555 rtx x0, e0, e1, y1, u0, v0, one;
24557 x0 = gen_reg_rtx (SFmode);
24558 e0 = gen_reg_rtx (SFmode);
24559 e1 = gen_reg_rtx (SFmode);
24560 y1 = gen_reg_rtx (SFmode);
24561 u0 = gen_reg_rtx (SFmode);
24562 v0 = gen_reg_rtx (SFmode);
24563 one = force_reg (SFmode, CONST_DOUBLE_FROM_REAL_VALUE (dconst1, SFmode));
24565 /* x0 = 1./d estimate */
24566 emit_insn (gen_rtx_SET (VOIDmode, x0,
24567 gen_rtx_UNSPEC (SFmode, gen_rtvec (1, d),
24568 UNSPEC_FRES)));
24569 /* e0 = 1. - d * x0 */
24570 emit_insn (gen_rtx_SET (VOIDmode, e0,
24571 gen_rtx_MINUS (SFmode, one,
24572 gen_rtx_MULT (SFmode, d, x0))));
24573 /* e1 = e0 + e0 * e0 */
24574 emit_insn (gen_rtx_SET (VOIDmode, e1,
24575 gen_rtx_PLUS (SFmode,
24576 gen_rtx_MULT (SFmode, e0, e0), e0)));
24577 /* y1 = x0 + e1 * x0 */
24578 emit_insn (gen_rtx_SET (VOIDmode, y1,
24579 gen_rtx_PLUS (SFmode,
24580 gen_rtx_MULT (SFmode, e1, x0), x0)));
24581 /* u0 = n * y1 */
24582 emit_insn (gen_rtx_SET (VOIDmode, u0,
24583 gen_rtx_MULT (SFmode, n, y1)));
24584 /* v0 = n - d * u0 */
24585 emit_insn (gen_rtx_SET (VOIDmode, v0,
24586 gen_rtx_MINUS (SFmode, n,
24587 gen_rtx_MULT (SFmode, d, u0))));
24588 /* dst = u0 + v0 * y1 */
24589 emit_insn (gen_rtx_SET (VOIDmode, dst,
24590 gen_rtx_PLUS (SFmode,
24591 gen_rtx_MULT (SFmode, v0, y1), u0)));
24594 /* Newton-Raphson approximation of double-precision floating point divide n/d.
24595 Assumes no trapping math and finite arguments. */
24597 void
24598 rs6000_emit_swdivdf (rtx dst, rtx n, rtx d)
24600 rtx x0, e0, e1, e2, y1, y2, y3, u0, v0, one;
24602 x0 = gen_reg_rtx (DFmode);
24603 e0 = gen_reg_rtx (DFmode);
24604 e1 = gen_reg_rtx (DFmode);
24605 e2 = gen_reg_rtx (DFmode);
24606 y1 = gen_reg_rtx (DFmode);
24607 y2 = gen_reg_rtx (DFmode);
24608 y3 = gen_reg_rtx (DFmode);
24609 u0 = gen_reg_rtx (DFmode);
24610 v0 = gen_reg_rtx (DFmode);
24611 one = force_reg (DFmode, CONST_DOUBLE_FROM_REAL_VALUE (dconst1, DFmode));
24613 /* x0 = 1./d estimate */
24614 emit_insn (gen_rtx_SET (VOIDmode, x0,
24615 gen_rtx_UNSPEC (DFmode, gen_rtvec (1, d),
24616 UNSPEC_FRES)));
24617 /* e0 = 1. - d * x0 */
24618 emit_insn (gen_rtx_SET (VOIDmode, e0,
24619 gen_rtx_MINUS (DFmode, one,
24620 gen_rtx_MULT (SFmode, d, x0))));
24621 /* y1 = x0 + e0 * x0 */
24622 emit_insn (gen_rtx_SET (VOIDmode, y1,
24623 gen_rtx_PLUS (DFmode,
24624 gen_rtx_MULT (DFmode, e0, x0), x0)));
24625 /* e1 = e0 * e0 */
24626 emit_insn (gen_rtx_SET (VOIDmode, e1,
24627 gen_rtx_MULT (DFmode, e0, e0)));
24628 /* y2 = y1 + e1 * y1 */
24629 emit_insn (gen_rtx_SET (VOIDmode, y2,
24630 gen_rtx_PLUS (DFmode,
24631 gen_rtx_MULT (DFmode, e1, y1), y1)));
24632 /* e2 = e1 * e1 */
24633 emit_insn (gen_rtx_SET (VOIDmode, e2,
24634 gen_rtx_MULT (DFmode, e1, e1)));
24635 /* y3 = y2 + e2 * y2 */
24636 emit_insn (gen_rtx_SET (VOIDmode, y3,
24637 gen_rtx_PLUS (DFmode,
24638 gen_rtx_MULT (DFmode, e2, y2), y2)));
24639 /* u0 = n * y3 */
24640 emit_insn (gen_rtx_SET (VOIDmode, u0,
24641 gen_rtx_MULT (DFmode, n, y3)));
24642 /* v0 = n - d * u0 */
24643 emit_insn (gen_rtx_SET (VOIDmode, v0,
24644 gen_rtx_MINUS (DFmode, n,
24645 gen_rtx_MULT (DFmode, d, u0))));
24646 /* dst = u0 + v0 * y3 */
24647 emit_insn (gen_rtx_SET (VOIDmode, dst,
24648 gen_rtx_PLUS (DFmode,
24649 gen_rtx_MULT (DFmode, v0, y3), u0)));
24653 /* Newton-Raphson approximation of single-precision floating point rsqrt.
24654 Assumes no trapping math and finite arguments. */
24656 void
24657 rs6000_emit_swrsqrtsf (rtx dst, rtx src)
24659 rtx x0, x1, x2, y1, u0, u1, u2, v0, v1, v2, t0,
24660 half, one, halfthree, c1, cond, label;
24662 x0 = gen_reg_rtx (SFmode);
24663 x1 = gen_reg_rtx (SFmode);
24664 x2 = gen_reg_rtx (SFmode);
24665 y1 = gen_reg_rtx (SFmode);
24666 u0 = gen_reg_rtx (SFmode);
24667 u1 = gen_reg_rtx (SFmode);
24668 u2 = gen_reg_rtx (SFmode);
24669 v0 = gen_reg_rtx (SFmode);
24670 v1 = gen_reg_rtx (SFmode);
24671 v2 = gen_reg_rtx (SFmode);
24672 t0 = gen_reg_rtx (SFmode);
24673 halfthree = gen_reg_rtx (SFmode);
24674 cond = gen_rtx_REG (CCFPmode, CR1_REGNO);
24675 label = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
24677 /* check 0.0, 1.0, NaN, Inf by testing src * src = src */
24678 emit_insn (gen_rtx_SET (VOIDmode, t0,
24679 gen_rtx_MULT (SFmode, src, src)));
24681 emit_insn (gen_rtx_SET (VOIDmode, cond,
24682 gen_rtx_COMPARE (CCFPmode, t0, src)));
24683 c1 = gen_rtx_EQ (VOIDmode, cond, const0_rtx);
24684 emit_unlikely_jump (c1, label);
24686 half = force_reg (SFmode, CONST_DOUBLE_FROM_REAL_VALUE (dconsthalf, SFmode));
24687 one = force_reg (SFmode, CONST_DOUBLE_FROM_REAL_VALUE (dconst1, SFmode));
24689 /* halfthree = 1.5 = 1.0 + 0.5 */
24690 emit_insn (gen_rtx_SET (VOIDmode, halfthree,
24691 gen_rtx_PLUS (SFmode, one, half)));
24693 /* x0 = rsqrt estimate */
24694 emit_insn (gen_rtx_SET (VOIDmode, x0,
24695 gen_rtx_UNSPEC (SFmode, gen_rtvec (1, src),
24696 UNSPEC_RSQRT)));
24698 /* y1 = 0.5 * src = 1.5 * src - src -> fewer constants */
24699 emit_insn (gen_rtx_SET (VOIDmode, y1,
24700 gen_rtx_MINUS (SFmode,
24701 gen_rtx_MULT (SFmode, src, halfthree),
24702 src)));
24704 /* x1 = x0 * (1.5 - y1 * (x0 * x0)) */
24705 emit_insn (gen_rtx_SET (VOIDmode, u0,
24706 gen_rtx_MULT (SFmode, x0, x0)));
24707 emit_insn (gen_rtx_SET (VOIDmode, v0,
24708 gen_rtx_MINUS (SFmode,
24709 halfthree,
24710 gen_rtx_MULT (SFmode, y1, u0))));
24711 emit_insn (gen_rtx_SET (VOIDmode, x1,
24712 gen_rtx_MULT (SFmode, x0, v0)));
24714 /* x2 = x1 * (1.5 - y1 * (x1 * x1)) */
24715 emit_insn (gen_rtx_SET (VOIDmode, u1,
24716 gen_rtx_MULT (SFmode, x1, x1)));
24717 emit_insn (gen_rtx_SET (VOIDmode, v1,
24718 gen_rtx_MINUS (SFmode,
24719 halfthree,
24720 gen_rtx_MULT (SFmode, y1, u1))));
24721 emit_insn (gen_rtx_SET (VOIDmode, x2,
24722 gen_rtx_MULT (SFmode, x1, v1)));
24724 /* dst = x2 * (1.5 - y1 * (x2 * x2)) */
24725 emit_insn (gen_rtx_SET (VOIDmode, u2,
24726 gen_rtx_MULT (SFmode, x2, x2)));
24727 emit_insn (gen_rtx_SET (VOIDmode, v2,
24728 gen_rtx_MINUS (SFmode,
24729 halfthree,
24730 gen_rtx_MULT (SFmode, y1, u2))));
24731 emit_insn (gen_rtx_SET (VOIDmode, dst,
24732 gen_rtx_MULT (SFmode, x2, v2)));
24734 emit_label (XEXP (label, 0));
24737 /* Emit popcount intrinsic on TARGET_POPCNTB (Power5) and TARGET_POPCNTD
24738 (Power7) targets. DST is the target, and SRC is the argument operand. */
24740 void
24741 rs6000_emit_popcount (rtx dst, rtx src)
24743 enum machine_mode mode = GET_MODE (dst);
24744 rtx tmp1, tmp2;
24746 /* Use the PPC ISA 2.06 popcnt{w,d} instruction if we can. */
24747 if (TARGET_POPCNTD)
24749 if (mode == SImode)
24750 emit_insn (gen_popcntwsi2 (dst, src));
24751 else
24752 emit_insn (gen_popcntddi2 (dst, src));
24753 return;
24756 tmp1 = gen_reg_rtx (mode);
24758 if (mode == SImode)
24760 emit_insn (gen_popcntbsi2 (tmp1, src));
24761 tmp2 = expand_mult (SImode, tmp1, GEN_INT (0x01010101),
24762 NULL_RTX, 0);
24763 tmp2 = force_reg (SImode, tmp2);
24764 emit_insn (gen_lshrsi3 (dst, tmp2, GEN_INT (24)));
24766 else
24768 emit_insn (gen_popcntbdi2 (tmp1, src));
24769 tmp2 = expand_mult (DImode, tmp1,
24770 GEN_INT ((HOST_WIDE_INT)
24771 0x01010101 << 32 | 0x01010101),
24772 NULL_RTX, 0);
24773 tmp2 = force_reg (DImode, tmp2);
24774 emit_insn (gen_lshrdi3 (dst, tmp2, GEN_INT (56)));
24779 /* Emit parity intrinsic on TARGET_POPCNTB targets. DST is the
24780 target, and SRC is the argument operand. */
24782 void
24783 rs6000_emit_parity (rtx dst, rtx src)
24785 enum machine_mode mode = GET_MODE (dst);
24786 rtx tmp;
24788 tmp = gen_reg_rtx (mode);
24789 if (mode == SImode)
24791 /* Is mult+shift >= shift+xor+shift+xor? */
24792 if (rs6000_cost->mulsi_const >= COSTS_N_INSNS (3))
24794 rtx tmp1, tmp2, tmp3, tmp4;
24796 tmp1 = gen_reg_rtx (SImode);
24797 emit_insn (gen_popcntbsi2 (tmp1, src));
24799 tmp2 = gen_reg_rtx (SImode);
24800 emit_insn (gen_lshrsi3 (tmp2, tmp1, GEN_INT (16)));
24801 tmp3 = gen_reg_rtx (SImode);
24802 emit_insn (gen_xorsi3 (tmp3, tmp1, tmp2));
24804 tmp4 = gen_reg_rtx (SImode);
24805 emit_insn (gen_lshrsi3 (tmp4, tmp3, GEN_INT (8)));
24806 emit_insn (gen_xorsi3 (tmp, tmp3, tmp4));
24808 else
24809 rs6000_emit_popcount (tmp, src);
24810 emit_insn (gen_andsi3 (dst, tmp, const1_rtx));
24812 else
24814 /* Is mult+shift >= shift+xor+shift+xor+shift+xor? */
24815 if (rs6000_cost->muldi >= COSTS_N_INSNS (5))
24817 rtx tmp1, tmp2, tmp3, tmp4, tmp5, tmp6;
24819 tmp1 = gen_reg_rtx (DImode);
24820 emit_insn (gen_popcntbdi2 (tmp1, src));
24822 tmp2 = gen_reg_rtx (DImode);
24823 emit_insn (gen_lshrdi3 (tmp2, tmp1, GEN_INT (32)));
24824 tmp3 = gen_reg_rtx (DImode);
24825 emit_insn (gen_xordi3 (tmp3, tmp1, tmp2));
24827 tmp4 = gen_reg_rtx (DImode);
24828 emit_insn (gen_lshrdi3 (tmp4, tmp3, GEN_INT (16)));
24829 tmp5 = gen_reg_rtx (DImode);
24830 emit_insn (gen_xordi3 (tmp5, tmp3, tmp4));
24832 tmp6 = gen_reg_rtx (DImode);
24833 emit_insn (gen_lshrdi3 (tmp6, tmp5, GEN_INT (8)));
24834 emit_insn (gen_xordi3 (tmp, tmp5, tmp6));
24836 else
24837 rs6000_emit_popcount (tmp, src);
24838 emit_insn (gen_anddi3 (dst, tmp, const1_rtx));
24842 /* Return an RTX representing where to find the function value of a
24843 function returning MODE. */
24844 static rtx
24845 rs6000_complex_function_value (enum machine_mode mode)
24847 unsigned int regno;
24848 rtx r1, r2;
24849 enum machine_mode inner = GET_MODE_INNER (mode);
24850 unsigned int inner_bytes = GET_MODE_SIZE (inner);
24852 if (FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
24853 regno = FP_ARG_RETURN;
24854 else
24856 regno = GP_ARG_RETURN;
24858 /* 32-bit is OK since it'll go in r3/r4. */
24859 if (TARGET_32BIT && inner_bytes >= 4)
24860 return gen_rtx_REG (mode, regno);
24863 if (inner_bytes >= 8)
24864 return gen_rtx_REG (mode, regno);
24866 r1 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno),
24867 const0_rtx);
24868 r2 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno + 1),
24869 GEN_INT (inner_bytes));
24870 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
24873 /* Define how to find the value returned by a function.
24874 VALTYPE is the data type of the value (as a tree).
24875 If the precise function being called is known, FUNC is its FUNCTION_DECL;
24876 otherwise, FUNC is 0.
24878 On the SPE, both FPs and vectors are returned in r3.
24880 On RS/6000 an integer value is in r3 and a floating-point value is in
24881 fp1, unless -msoft-float. */
24884 rs6000_function_value (const_tree valtype, const_tree func ATTRIBUTE_UNUSED)
24886 enum machine_mode mode;
24887 unsigned int regno;
24889 /* Special handling for structs in darwin64. */
24890 if (rs6000_darwin64_abi
24891 && TYPE_MODE (valtype) == BLKmode
24892 && TREE_CODE (valtype) == RECORD_TYPE
24893 && int_size_in_bytes (valtype) > 0)
24895 CUMULATIVE_ARGS valcum;
24896 rtx valret;
24898 valcum.words = 0;
24899 valcum.fregno = FP_ARG_MIN_REG;
24900 valcum.vregno = ALTIVEC_ARG_MIN_REG;
24901 /* Do a trial code generation as if this were going to be passed as
24902 an argument; if any part goes in memory, we return NULL. */
24903 valret = rs6000_darwin64_record_arg (&valcum, valtype, 1, true);
24904 if (valret)
24905 return valret;
24906 /* Otherwise fall through to standard ABI rules. */
24909 if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DImode)
24911 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
24912 return gen_rtx_PARALLEL (DImode,
24913 gen_rtvec (2,
24914 gen_rtx_EXPR_LIST (VOIDmode,
24915 gen_rtx_REG (SImode, GP_ARG_RETURN),
24916 const0_rtx),
24917 gen_rtx_EXPR_LIST (VOIDmode,
24918 gen_rtx_REG (SImode,
24919 GP_ARG_RETURN + 1),
24920 GEN_INT (4))));
24922 if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DCmode)
24924 return gen_rtx_PARALLEL (DCmode,
24925 gen_rtvec (4,
24926 gen_rtx_EXPR_LIST (VOIDmode,
24927 gen_rtx_REG (SImode, GP_ARG_RETURN),
24928 const0_rtx),
24929 gen_rtx_EXPR_LIST (VOIDmode,
24930 gen_rtx_REG (SImode,
24931 GP_ARG_RETURN + 1),
24932 GEN_INT (4)),
24933 gen_rtx_EXPR_LIST (VOIDmode,
24934 gen_rtx_REG (SImode,
24935 GP_ARG_RETURN + 2),
24936 GEN_INT (8)),
24937 gen_rtx_EXPR_LIST (VOIDmode,
24938 gen_rtx_REG (SImode,
24939 GP_ARG_RETURN + 3),
24940 GEN_INT (12))));
24943 mode = TYPE_MODE (valtype);
24944 if ((INTEGRAL_TYPE_P (valtype) && GET_MODE_BITSIZE (mode) < BITS_PER_WORD)
24945 || POINTER_TYPE_P (valtype))
24946 mode = TARGET_32BIT ? SImode : DImode;
24948 if (DECIMAL_FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
24949 /* _Decimal128 must use an even/odd register pair. */
24950 regno = (mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN;
24951 else if (SCALAR_FLOAT_TYPE_P (valtype) && TARGET_HARD_FLOAT && TARGET_FPRS
24952 && ((TARGET_SINGLE_FLOAT && (mode == SFmode)) || TARGET_DOUBLE_FLOAT))
24953 regno = FP_ARG_RETURN;
24954 else if (TREE_CODE (valtype) == COMPLEX_TYPE
24955 && targetm.calls.split_complex_arg)
24956 return rs6000_complex_function_value (mode);
24957 else if (TREE_CODE (valtype) == VECTOR_TYPE
24958 && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI
24959 && ALTIVEC_VECTOR_MODE (mode))
24960 regno = ALTIVEC_ARG_RETURN;
24961 else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
24962 && (mode == DFmode || mode == DCmode
24963 || mode == TFmode || mode == TCmode))
24964 return spe_build_register_parallel (mode, GP_ARG_RETURN);
24965 else
24966 regno = GP_ARG_RETURN;
24968 return gen_rtx_REG (mode, regno);
24971 /* Define how to find the value returned by a library function
24972 assuming the value has mode MODE. */
24974 rs6000_libcall_value (enum machine_mode mode)
24976 unsigned int regno;
24978 if (TARGET_32BIT && TARGET_POWERPC64 && mode == DImode)
24980 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
24981 return gen_rtx_PARALLEL (DImode,
24982 gen_rtvec (2,
24983 gen_rtx_EXPR_LIST (VOIDmode,
24984 gen_rtx_REG (SImode, GP_ARG_RETURN),
24985 const0_rtx),
24986 gen_rtx_EXPR_LIST (VOIDmode,
24987 gen_rtx_REG (SImode,
24988 GP_ARG_RETURN + 1),
24989 GEN_INT (4))));
24992 if (DECIMAL_FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
24993 /* _Decimal128 must use an even/odd register pair. */
24994 regno = (mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN;
24995 else if (SCALAR_FLOAT_MODE_P (mode)
24996 && TARGET_HARD_FLOAT && TARGET_FPRS
24997 && ((TARGET_SINGLE_FLOAT && mode == SFmode) || TARGET_DOUBLE_FLOAT))
24998 regno = FP_ARG_RETURN;
24999 else if (ALTIVEC_VECTOR_MODE (mode)
25000 && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI)
25001 regno = ALTIVEC_ARG_RETURN;
25002 else if (COMPLEX_MODE_P (mode) && targetm.calls.split_complex_arg)
25003 return rs6000_complex_function_value (mode);
25004 else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
25005 && (mode == DFmode || mode == DCmode
25006 || mode == TFmode || mode == TCmode))
25007 return spe_build_register_parallel (mode, GP_ARG_RETURN);
25008 else
25009 regno = GP_ARG_RETURN;
25011 return gen_rtx_REG (mode, regno);
25014 /* Define the offset between two registers, FROM to be eliminated and its
25015 replacement TO, at the start of a routine. */
25016 HOST_WIDE_INT
25017 rs6000_initial_elimination_offset (int from, int to)
25019 rs6000_stack_t *info = rs6000_stack_info ();
25020 HOST_WIDE_INT offset;
25022 if (from == HARD_FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
25023 offset = info->push_p ? 0 : -info->total_size;
25024 else if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
25026 offset = info->push_p ? 0 : -info->total_size;
25027 if (FRAME_GROWS_DOWNWARD)
25028 offset += info->fixed_size + info->vars_size + info->parm_size;
25030 else if (from == FRAME_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
25031 offset = FRAME_GROWS_DOWNWARD
25032 ? info->fixed_size + info->vars_size + info->parm_size
25033 : 0;
25034 else if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
25035 offset = info->total_size;
25036 else if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
25037 offset = info->push_p ? info->total_size : 0;
25038 else if (from == RS6000_PIC_OFFSET_TABLE_REGNUM)
25039 offset = 0;
25040 else
25041 gcc_unreachable ();
25043 return offset;
25046 static rtx
25047 rs6000_dwarf_register_span (rtx reg)
25049 rtx parts[8];
25050 int i, words;
25051 unsigned regno = REGNO (reg);
25052 enum machine_mode mode = GET_MODE (reg);
25054 if (TARGET_SPE
25055 && regno < 32
25056 && (SPE_VECTOR_MODE (GET_MODE (reg))
25057 || (TARGET_E500_DOUBLE && FLOAT_MODE_P (mode)
25058 && mode != SFmode && mode != SDmode && mode != SCmode)))
25060 else
25061 return NULL_RTX;
25063 regno = REGNO (reg);
25065 /* The duality of the SPE register size wreaks all kinds of havoc.
25066 This is a way of distinguishing r0 in 32-bits from r0 in
25067 64-bits. */
25068 words = (GET_MODE_SIZE (mode) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD;
25069 gcc_assert (words <= 4);
25070 for (i = 0; i < words; i++, regno++)
25072 if (BYTES_BIG_ENDIAN)
25074 parts[2 * i] = gen_rtx_REG (SImode, regno + 1200);
25075 parts[2 * i + 1] = gen_rtx_REG (SImode, regno);
25077 else
25079 parts[2 * i] = gen_rtx_REG (SImode, regno);
25080 parts[2 * i + 1] = gen_rtx_REG (SImode, regno + 1200);
25084 return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (words * 2, parts));
25087 /* Fill in sizes for SPE register high parts in table used by unwinder. */
25089 static void
25090 rs6000_init_dwarf_reg_sizes_extra (tree address)
25092 if (TARGET_SPE)
25094 int i;
25095 enum machine_mode mode = TYPE_MODE (char_type_node);
25096 rtx addr = expand_expr (address, NULL_RTX, VOIDmode, EXPAND_NORMAL);
25097 rtx mem = gen_rtx_MEM (BLKmode, addr);
25098 rtx value = gen_int_mode (4, mode);
25100 for (i = 1201; i < 1232; i++)
25102 int column = DWARF_REG_TO_UNWIND_COLUMN (i);
25103 HOST_WIDE_INT offset
25104 = DWARF_FRAME_REGNUM (column) * GET_MODE_SIZE (mode);
25106 emit_move_insn (adjust_address (mem, mode, offset), value);
25111 /* Map internal gcc register numbers to DWARF2 register numbers. */
25113 unsigned int
25114 rs6000_dbx_register_number (unsigned int regno)
25116 if (regno <= 63 || write_symbols != DWARF2_DEBUG)
25117 return regno;
25118 if (regno == MQ_REGNO)
25119 return 100;
25120 if (regno == LR_REGNO)
25121 return 108;
25122 if (regno == CTR_REGNO)
25123 return 109;
25124 if (CR_REGNO_P (regno))
25125 return regno - CR0_REGNO + 86;
25126 if (regno == XER_REGNO)
25127 return 101;
25128 if (ALTIVEC_REGNO_P (regno))
25129 return regno - FIRST_ALTIVEC_REGNO + 1124;
25130 if (regno == VRSAVE_REGNO)
25131 return 356;
25132 if (regno == VSCR_REGNO)
25133 return 67;
25134 if (regno == SPE_ACC_REGNO)
25135 return 99;
25136 if (regno == SPEFSCR_REGNO)
25137 return 612;
25138 /* SPE high reg number. We get these values of regno from
25139 rs6000_dwarf_register_span. */
25140 gcc_assert (regno >= 1200 && regno < 1232);
25141 return regno;
25144 /* target hook eh_return_filter_mode */
25145 static enum machine_mode
25146 rs6000_eh_return_filter_mode (void)
25148 return TARGET_32BIT ? SImode : word_mode;
25151 /* Target hook for scalar_mode_supported_p. */
25152 static bool
25153 rs6000_scalar_mode_supported_p (enum machine_mode mode)
25155 if (DECIMAL_FLOAT_MODE_P (mode))
25156 return true;
25157 else
25158 return default_scalar_mode_supported_p (mode);
25161 /* Target hook for vector_mode_supported_p. */
25162 static bool
25163 rs6000_vector_mode_supported_p (enum machine_mode mode)
25166 if (TARGET_PAIRED_FLOAT && PAIRED_VECTOR_MODE (mode))
25167 return true;
25169 if (TARGET_SPE && SPE_VECTOR_MODE (mode))
25170 return true;
25172 else if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode))
25173 return true;
25175 else
25176 return false;
25179 /* Target hook for invalid_arg_for_unprototyped_fn. */
25180 static const char *
25181 invalid_arg_for_unprototyped_fn (const_tree typelist, const_tree funcdecl, const_tree val)
25183 return (!rs6000_darwin64_abi
25184 && typelist == 0
25185 && TREE_CODE (TREE_TYPE (val)) == VECTOR_TYPE
25186 && (funcdecl == NULL_TREE
25187 || (TREE_CODE (funcdecl) == FUNCTION_DECL
25188 && DECL_BUILT_IN_CLASS (funcdecl) != BUILT_IN_MD)))
25189 ? N_("AltiVec argument passed to unprototyped function")
25190 : NULL;
25193 /* For TARGET_SECURE_PLT 32-bit PIC code we can save PIC register
25194 setup by using __stack_chk_fail_local hidden function instead of
25195 calling __stack_chk_fail directly. Otherwise it is better to call
25196 __stack_chk_fail directly. */
25198 static tree
25199 rs6000_stack_protect_fail (void)
25201 return (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
25202 ? default_hidden_stack_protect_fail ()
25203 : default_external_stack_protect_fail ();
25206 void
25207 rs6000_final_prescan_insn (rtx insn, rtx *operand ATTRIBUTE_UNUSED,
25208 int num_operands ATTRIBUTE_UNUSED)
25210 if (rs6000_warn_cell_microcode)
25212 const char *temp;
25213 int insn_code_number = recog_memoized (insn);
25214 location_t location = locator_location (INSN_LOCATOR (insn));
25216 /* Punt on insns we cannot recognize. */
25217 if (insn_code_number < 0)
25218 return;
25220 temp = get_insn_template (insn_code_number, insn);
25222 if (get_attr_cell_micro (insn) == CELL_MICRO_ALWAYS)
25223 warning_at (location, OPT_mwarn_cell_microcode,
25224 "emitting microcode insn %s\t[%s] #%d",
25225 temp, insn_data[INSN_CODE (insn)].name, INSN_UID (insn));
25226 else if (get_attr_cell_micro (insn) == CELL_MICRO_CONDITIONAL)
25227 warning_at (location, OPT_mwarn_cell_microcode,
25228 "emitting conditional microcode insn %s\t[%s] #%d",
25229 temp, insn_data[INSN_CODE (insn)].name, INSN_UID (insn));
25233 #include "gt-rs6000.h"