rs6000.h (FUNCTION_VALUE): Remove macro.
[official-gcc.git] / gcc / config / rs6000 / rs6000.c
blob2967ff5afe512f30f60be282f7aaf6836fb09323
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 rtx rs6000_function_value (const_tree, const_tree, bool);
850 static void rs6000_file_start (void);
851 #if TARGET_ELF
852 static int rs6000_elf_reloc_rw_mask (void);
853 static void rs6000_elf_asm_out_constructor (rtx, int);
854 static void rs6000_elf_asm_out_destructor (rtx, int);
855 static void rs6000_elf_end_indicate_exec_stack (void) ATTRIBUTE_UNUSED;
856 static void rs6000_elf_asm_init_sections (void);
857 static section *rs6000_elf_select_rtx_section (enum machine_mode, rtx,
858 unsigned HOST_WIDE_INT);
859 static void rs6000_elf_encode_section_info (tree, rtx, int)
860 ATTRIBUTE_UNUSED;
861 #endif
862 static bool rs6000_use_blocks_for_constant_p (enum machine_mode, const_rtx);
863 static void rs6000_alloc_sdmode_stack_slot (void);
864 static void rs6000_instantiate_decls (void);
865 #if TARGET_XCOFF
866 static void rs6000_xcoff_asm_output_anchor (rtx);
867 static void rs6000_xcoff_asm_globalize_label (FILE *, const char *);
868 static void rs6000_xcoff_asm_init_sections (void);
869 static int rs6000_xcoff_reloc_rw_mask (void);
870 static void rs6000_xcoff_asm_named_section (const char *, unsigned int, tree);
871 static section *rs6000_xcoff_select_section (tree, int,
872 unsigned HOST_WIDE_INT);
873 static void rs6000_xcoff_unique_section (tree, int);
874 static section *rs6000_xcoff_select_rtx_section
875 (enum machine_mode, rtx, unsigned HOST_WIDE_INT);
876 static const char * rs6000_xcoff_strip_name_encoding (const char *);
877 static unsigned int rs6000_xcoff_section_type_flags (tree, const char *, int);
878 static void rs6000_xcoff_file_start (void);
879 static void rs6000_xcoff_file_end (void);
880 #endif
881 static int rs6000_variable_issue (FILE *, int, rtx, int);
882 static bool rs6000_rtx_costs (rtx, int, int, int *, bool);
883 static bool rs6000_debug_rtx_costs (rtx, int, int, int *, bool);
884 static int rs6000_debug_address_cost (rtx, bool);
885 static int rs6000_adjust_cost (rtx, rtx, rtx, int);
886 static int rs6000_debug_adjust_cost (rtx, rtx, rtx, int);
887 static void rs6000_sched_init (FILE *, int, int);
888 static bool is_microcoded_insn (rtx);
889 static bool is_nonpipeline_insn (rtx);
890 static bool is_cracked_insn (rtx);
891 static bool is_branch_slot_insn (rtx);
892 static bool is_load_insn (rtx);
893 static rtx get_store_dest (rtx pat);
894 static bool is_store_insn (rtx);
895 static bool set_to_load_agen (rtx,rtx);
896 static bool adjacent_mem_locations (rtx,rtx);
897 static int rs6000_adjust_priority (rtx, int);
898 static int rs6000_issue_rate (void);
899 static bool rs6000_is_costly_dependence (dep_t, int, int);
900 static rtx get_next_active_insn (rtx, rtx);
901 static bool insn_terminates_group_p (rtx , enum group_termination);
902 static bool insn_must_be_first_in_group (rtx);
903 static bool insn_must_be_last_in_group (rtx);
904 static bool is_costly_group (rtx *, rtx);
905 static int force_new_group (int, FILE *, rtx *, rtx, bool *, int, int *);
906 static int redefine_groups (FILE *, int, rtx, rtx);
907 static int pad_groups (FILE *, int, rtx, rtx);
908 static void rs6000_sched_finish (FILE *, int);
909 static int rs6000_sched_reorder (FILE *, int, rtx *, int *, int);
910 static int rs6000_sched_reorder2 (FILE *, int, rtx *, int *, int);
911 static int rs6000_use_sched_lookahead (void);
912 static int rs6000_use_sched_lookahead_guard (rtx);
913 static void * rs6000_alloc_sched_context (void);
914 static void rs6000_init_sched_context (void *, bool);
915 static void rs6000_set_sched_context (void *);
916 static void rs6000_free_sched_context (void *);
917 static tree rs6000_builtin_reciprocal (unsigned int, bool, bool);
918 static tree rs6000_builtin_mask_for_load (void);
919 static tree rs6000_builtin_mul_widen_even (tree);
920 static tree rs6000_builtin_mul_widen_odd (tree);
921 static tree rs6000_builtin_conversion (unsigned int, tree);
922 static tree rs6000_builtin_vec_perm (tree, tree *);
923 static bool rs6000_builtin_support_vector_misalignment (enum
924 machine_mode,
925 const_tree,
926 int, bool);
928 static void def_builtin (int, const char *, tree, int);
929 static bool rs6000_vector_alignment_reachable (const_tree, bool);
930 static void rs6000_init_builtins (void);
931 static rtx rs6000_expand_unop_builtin (enum insn_code, tree, rtx);
932 static rtx rs6000_expand_binop_builtin (enum insn_code, tree, rtx);
933 static rtx rs6000_expand_ternop_builtin (enum insn_code, tree, rtx);
934 static rtx rs6000_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
935 static void altivec_init_builtins (void);
936 static unsigned builtin_hash_function (const void *);
937 static int builtin_hash_eq (const void *, const void *);
938 static tree builtin_function_type (enum machine_mode, enum machine_mode,
939 enum machine_mode, enum machine_mode,
940 enum rs6000_builtins, const char *name);
941 static void rs6000_common_init_builtins (void);
942 static void rs6000_init_libfuncs (void);
944 static void paired_init_builtins (void);
945 static rtx paired_expand_builtin (tree, rtx, bool *);
946 static rtx paired_expand_lv_builtin (enum insn_code, tree, rtx);
947 static rtx paired_expand_stv_builtin (enum insn_code, tree);
948 static rtx paired_expand_predicate_builtin (enum insn_code, tree, rtx);
950 static void enable_mask_for_builtins (struct builtin_description *, int,
951 enum rs6000_builtins,
952 enum rs6000_builtins);
953 static void spe_init_builtins (void);
954 static rtx spe_expand_builtin (tree, rtx, bool *);
955 static rtx spe_expand_stv_builtin (enum insn_code, tree);
956 static rtx spe_expand_predicate_builtin (enum insn_code, tree, rtx);
957 static rtx spe_expand_evsel_builtin (enum insn_code, tree, rtx);
958 static int rs6000_emit_int_cmove (rtx, rtx, rtx, rtx);
959 static rs6000_stack_t *rs6000_stack_info (void);
960 static void debug_stack_info (rs6000_stack_t *);
962 static rtx altivec_expand_builtin (tree, rtx, bool *);
963 static rtx altivec_expand_ld_builtin (tree, rtx, bool *);
964 static rtx altivec_expand_st_builtin (tree, rtx, bool *);
965 static rtx altivec_expand_dst_builtin (tree, rtx, bool *);
966 static rtx altivec_expand_abs_builtin (enum insn_code, tree, rtx);
967 static rtx altivec_expand_predicate_builtin (enum insn_code, tree, rtx);
968 static rtx altivec_expand_stv_builtin (enum insn_code, tree);
969 static rtx altivec_expand_vec_init_builtin (tree, tree, rtx);
970 static rtx altivec_expand_vec_set_builtin (tree);
971 static rtx altivec_expand_vec_ext_builtin (tree, rtx);
972 static int get_element_number (tree, tree);
973 static bool rs6000_handle_option (size_t, const char *, int);
974 static void rs6000_parse_tls_size_option (void);
975 static void rs6000_parse_yes_no_option (const char *, const char *, int *);
976 static int first_altivec_reg_to_save (void);
977 static unsigned int compute_vrsave_mask (void);
978 static void compute_save_world_info (rs6000_stack_t *info_ptr);
979 static void is_altivec_return_reg (rtx, void *);
980 static rtx generate_set_vrsave (rtx, rs6000_stack_t *, int);
981 int easy_vector_constant (rtx, enum machine_mode);
982 static rtx rs6000_dwarf_register_span (rtx);
983 static void rs6000_init_dwarf_reg_sizes_extra (tree);
984 static rtx rs6000_legitimize_address (rtx, rtx, enum machine_mode);
985 static rtx rs6000_debug_legitimize_address (rtx, rtx, enum machine_mode);
986 static rtx rs6000_legitimize_tls_address (rtx, enum tls_model);
987 static rtx rs6000_delegitimize_address (rtx);
988 static void rs6000_output_dwarf_dtprel (FILE *, int, rtx) ATTRIBUTE_UNUSED;
989 static rtx rs6000_tls_get_addr (void);
990 static rtx rs6000_got_sym (void);
991 static int rs6000_tls_symbol_ref_1 (rtx *, void *);
992 static const char *rs6000_get_some_local_dynamic_name (void);
993 static int rs6000_get_some_local_dynamic_name_1 (rtx *, void *);
994 static rtx rs6000_complex_function_value (enum machine_mode);
995 static rtx rs6000_spe_function_arg (CUMULATIVE_ARGS *,
996 enum machine_mode, tree);
997 static void rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS *,
998 HOST_WIDE_INT);
999 static void rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS *,
1000 tree, HOST_WIDE_INT);
1001 static void rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS *,
1002 HOST_WIDE_INT,
1003 rtx[], int *);
1004 static void rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *,
1005 const_tree, HOST_WIDE_INT,
1006 rtx[], int *);
1007 static rtx rs6000_darwin64_record_arg (CUMULATIVE_ARGS *, const_tree, int, bool);
1008 static rtx rs6000_mixed_function_arg (enum machine_mode, tree, int);
1009 static void rs6000_move_block_from_reg (int regno, rtx x, int nregs);
1010 static void setup_incoming_varargs (CUMULATIVE_ARGS *,
1011 enum machine_mode, tree,
1012 int *, int);
1013 static bool rs6000_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode,
1014 const_tree, bool);
1015 static int rs6000_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode,
1016 tree, bool);
1017 static const char *invalid_arg_for_unprototyped_fn (const_tree, const_tree, const_tree);
1018 #if TARGET_MACHO
1019 static void macho_branch_islands (void);
1020 static int no_previous_def (tree function_name);
1021 static tree get_prev_label (tree function_name);
1022 static void rs6000_darwin_file_start (void);
1023 #endif
1025 static tree rs6000_build_builtin_va_list (void);
1026 static void rs6000_va_start (tree, rtx);
1027 static tree rs6000_gimplify_va_arg (tree, tree, gimple_seq *, gimple_seq *);
1028 static bool rs6000_must_pass_in_stack (enum machine_mode, const_tree);
1029 static bool rs6000_scalar_mode_supported_p (enum machine_mode);
1030 static bool rs6000_vector_mode_supported_p (enum machine_mode);
1031 static rtx rs6000_emit_vector_compare_inner (enum rtx_code, rtx, rtx);
1032 static rtx rs6000_emit_vector_compare (enum rtx_code, rtx, rtx,
1033 enum machine_mode);
1034 static tree rs6000_stack_protect_fail (void);
1036 static rtx rs6000_legitimize_reload_address (rtx, enum machine_mode, int, int,
1037 int, int *);
1039 static rtx rs6000_debug_legitimize_reload_address (rtx, enum machine_mode, int,
1040 int, int, int *);
1042 rtx (*rs6000_legitimize_reload_address_ptr) (rtx, enum machine_mode, int, int,
1043 int, int *)
1044 = rs6000_legitimize_reload_address;
1046 static bool rs6000_mode_dependent_address (rtx);
1047 static bool rs6000_debug_mode_dependent_address (rtx);
1048 bool (*rs6000_mode_dependent_address_ptr) (rtx)
1049 = rs6000_mode_dependent_address;
1051 static enum reg_class rs6000_secondary_reload_class (enum reg_class,
1052 enum machine_mode, rtx);
1053 static enum reg_class rs6000_debug_secondary_reload_class (enum reg_class,
1054 enum machine_mode,
1055 rtx);
1056 enum reg_class (*rs6000_secondary_reload_class_ptr) (enum reg_class,
1057 enum machine_mode, rtx)
1058 = rs6000_secondary_reload_class;
1060 static enum reg_class rs6000_preferred_reload_class (rtx, enum reg_class);
1061 static enum reg_class rs6000_debug_preferred_reload_class (rtx,
1062 enum reg_class);
1063 enum reg_class (*rs6000_preferred_reload_class_ptr) (rtx, enum reg_class)
1064 = rs6000_preferred_reload_class;
1066 static bool rs6000_secondary_memory_needed (enum reg_class, enum reg_class,
1067 enum machine_mode);
1069 static bool rs6000_debug_secondary_memory_needed (enum reg_class,
1070 enum reg_class,
1071 enum machine_mode);
1073 bool (*rs6000_secondary_memory_needed_ptr) (enum reg_class, enum reg_class,
1074 enum machine_mode)
1075 = rs6000_secondary_memory_needed;
1077 static bool rs6000_cannot_change_mode_class (enum machine_mode,
1078 enum machine_mode,
1079 enum reg_class);
1080 static bool rs6000_debug_cannot_change_mode_class (enum machine_mode,
1081 enum machine_mode,
1082 enum reg_class);
1084 bool (*rs6000_cannot_change_mode_class_ptr) (enum machine_mode,
1085 enum machine_mode,
1086 enum reg_class)
1087 = rs6000_cannot_change_mode_class;
1089 static enum reg_class rs6000_secondary_reload (bool, rtx, enum reg_class,
1090 enum machine_mode,
1091 struct secondary_reload_info *);
1093 static const enum reg_class *rs6000_ira_cover_classes (void);
1095 const int INSN_NOT_AVAILABLE = -1;
1096 static enum machine_mode rs6000_eh_return_filter_mode (void);
1097 static bool rs6000_can_eliminate (const int, const int);
1098 static void rs6000_trampoline_init (rtx, tree, rtx);
1100 /* Hash table stuff for keeping track of TOC entries. */
1102 struct GTY(()) toc_hash_struct
1104 /* `key' will satisfy CONSTANT_P; in fact, it will satisfy
1105 ASM_OUTPUT_SPECIAL_POOL_ENTRY_P. */
1106 rtx key;
1107 enum machine_mode key_mode;
1108 int labelno;
1111 static GTY ((param_is (struct toc_hash_struct))) htab_t toc_hash_table;
1113 /* Hash table to keep track of the argument types for builtin functions. */
1115 struct GTY(()) builtin_hash_struct
1117 tree type;
1118 enum machine_mode mode[4]; /* return value + 3 arguments. */
1119 unsigned char uns_p[4]; /* and whether the types are unsigned. */
1122 static GTY ((param_is (struct builtin_hash_struct))) htab_t builtin_hash_table;
1124 /* Default register names. */
1125 char rs6000_reg_names[][8] =
1127 "0", "1", "2", "3", "4", "5", "6", "7",
1128 "8", "9", "10", "11", "12", "13", "14", "15",
1129 "16", "17", "18", "19", "20", "21", "22", "23",
1130 "24", "25", "26", "27", "28", "29", "30", "31",
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 "mq", "lr", "ctr","ap",
1136 "0", "1", "2", "3", "4", "5", "6", "7",
1137 "xer",
1138 /* AltiVec registers. */
1139 "0", "1", "2", "3", "4", "5", "6", "7",
1140 "8", "9", "10", "11", "12", "13", "14", "15",
1141 "16", "17", "18", "19", "20", "21", "22", "23",
1142 "24", "25", "26", "27", "28", "29", "30", "31",
1143 "vrsave", "vscr",
1144 /* SPE registers. */
1145 "spe_acc", "spefscr",
1146 /* Soft frame pointer. */
1147 "sfp"
1150 #ifdef TARGET_REGNAMES
1151 static const char alt_reg_names[][8] =
1153 "%r0", "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7",
1154 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15",
1155 "%r16", "%r17", "%r18", "%r19", "%r20", "%r21", "%r22", "%r23",
1156 "%r24", "%r25", "%r26", "%r27", "%r28", "%r29", "%r30", "%r31",
1157 "%f0", "%f1", "%f2", "%f3", "%f4", "%f5", "%f6", "%f7",
1158 "%f8", "%f9", "%f10", "%f11", "%f12", "%f13", "%f14", "%f15",
1159 "%f16", "%f17", "%f18", "%f19", "%f20", "%f21", "%f22", "%f23",
1160 "%f24", "%f25", "%f26", "%f27", "%f28", "%f29", "%f30", "%f31",
1161 "mq", "lr", "ctr", "ap",
1162 "%cr0", "%cr1", "%cr2", "%cr3", "%cr4", "%cr5", "%cr6", "%cr7",
1163 "xer",
1164 /* AltiVec registers. */
1165 "%v0", "%v1", "%v2", "%v3", "%v4", "%v5", "%v6", "%v7",
1166 "%v8", "%v9", "%v10", "%v11", "%v12", "%v13", "%v14", "%v15",
1167 "%v16", "%v17", "%v18", "%v19", "%v20", "%v21", "%v22", "%v23",
1168 "%v24", "%v25", "%v26", "%v27", "%v28", "%v29", "%v30", "%v31",
1169 "vrsave", "vscr",
1170 /* SPE registers. */
1171 "spe_acc", "spefscr",
1172 /* Soft frame pointer. */
1173 "sfp"
1175 #endif
1177 /* Table of valid machine attributes. */
1179 static const struct attribute_spec rs6000_attribute_table[] =
1181 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
1182 { "altivec", 1, 1, false, true, false, rs6000_handle_altivec_attribute },
1183 { "longcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute },
1184 { "shortcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute },
1185 { "ms_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute },
1186 { "gcc_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute },
1187 #ifdef SUBTARGET_ATTRIBUTE_TABLE
1188 SUBTARGET_ATTRIBUTE_TABLE,
1189 #endif
1190 { NULL, 0, 0, false, false, false, NULL }
1193 #ifndef MASK_STRICT_ALIGN
1194 #define MASK_STRICT_ALIGN 0
1195 #endif
1196 #ifndef TARGET_PROFILE_KERNEL
1197 #define TARGET_PROFILE_KERNEL 0
1198 #define SET_PROFILE_KERNEL(N)
1199 #else
1200 #define SET_PROFILE_KERNEL(N) TARGET_PROFILE_KERNEL = (N)
1201 #endif
1203 /* The VRSAVE bitmask puts bit %v0 as the most significant bit. */
1204 #define ALTIVEC_REG_BIT(REGNO) (0x80000000 >> ((REGNO) - FIRST_ALTIVEC_REGNO))
1206 /* Initialize the GCC target structure. */
1207 #undef TARGET_ATTRIBUTE_TABLE
1208 #define TARGET_ATTRIBUTE_TABLE rs6000_attribute_table
1209 #undef TARGET_SET_DEFAULT_TYPE_ATTRIBUTES
1210 #define TARGET_SET_DEFAULT_TYPE_ATTRIBUTES rs6000_set_default_type_attributes
1212 #undef TARGET_ASM_ALIGNED_DI_OP
1213 #define TARGET_ASM_ALIGNED_DI_OP DOUBLE_INT_ASM_OP
1215 /* Default unaligned ops are only provided for ELF. Find the ops needed
1216 for non-ELF systems. */
1217 #ifndef OBJECT_FORMAT_ELF
1218 #if TARGET_XCOFF
1219 /* For XCOFF. rs6000_assemble_integer will handle unaligned DIs on
1220 64-bit targets. */
1221 #undef TARGET_ASM_UNALIGNED_HI_OP
1222 #define TARGET_ASM_UNALIGNED_HI_OP "\t.vbyte\t2,"
1223 #undef TARGET_ASM_UNALIGNED_SI_OP
1224 #define TARGET_ASM_UNALIGNED_SI_OP "\t.vbyte\t4,"
1225 #undef TARGET_ASM_UNALIGNED_DI_OP
1226 #define TARGET_ASM_UNALIGNED_DI_OP "\t.vbyte\t8,"
1227 #else
1228 /* For Darwin. */
1229 #undef TARGET_ASM_UNALIGNED_HI_OP
1230 #define TARGET_ASM_UNALIGNED_HI_OP "\t.short\t"
1231 #undef TARGET_ASM_UNALIGNED_SI_OP
1232 #define TARGET_ASM_UNALIGNED_SI_OP "\t.long\t"
1233 #undef TARGET_ASM_UNALIGNED_DI_OP
1234 #define TARGET_ASM_UNALIGNED_DI_OP "\t.quad\t"
1235 #undef TARGET_ASM_ALIGNED_DI_OP
1236 #define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t"
1237 #endif
1238 #endif
1240 /* This hook deals with fixups for relocatable code and DI-mode objects
1241 in 64-bit code. */
1242 #undef TARGET_ASM_INTEGER
1243 #define TARGET_ASM_INTEGER rs6000_assemble_integer
1245 #ifdef HAVE_GAS_HIDDEN
1246 #undef TARGET_ASM_ASSEMBLE_VISIBILITY
1247 #define TARGET_ASM_ASSEMBLE_VISIBILITY rs6000_assemble_visibility
1248 #endif
1250 #undef TARGET_HAVE_TLS
1251 #define TARGET_HAVE_TLS HAVE_AS_TLS
1253 #undef TARGET_CANNOT_FORCE_CONST_MEM
1254 #define TARGET_CANNOT_FORCE_CONST_MEM rs6000_tls_referenced_p
1256 #undef TARGET_ASM_FUNCTION_PROLOGUE
1257 #define TARGET_ASM_FUNCTION_PROLOGUE rs6000_output_function_prologue
1258 #undef TARGET_ASM_FUNCTION_EPILOGUE
1259 #define TARGET_ASM_FUNCTION_EPILOGUE rs6000_output_function_epilogue
1261 #undef TARGET_LEGITIMIZE_ADDRESS
1262 #define TARGET_LEGITIMIZE_ADDRESS rs6000_legitimize_address
1264 #undef TARGET_SCHED_VARIABLE_ISSUE
1265 #define TARGET_SCHED_VARIABLE_ISSUE rs6000_variable_issue
1267 #undef TARGET_SCHED_ISSUE_RATE
1268 #define TARGET_SCHED_ISSUE_RATE rs6000_issue_rate
1269 #undef TARGET_SCHED_ADJUST_COST
1270 #define TARGET_SCHED_ADJUST_COST rs6000_adjust_cost
1271 #undef TARGET_SCHED_ADJUST_PRIORITY
1272 #define TARGET_SCHED_ADJUST_PRIORITY rs6000_adjust_priority
1273 #undef TARGET_SCHED_IS_COSTLY_DEPENDENCE
1274 #define TARGET_SCHED_IS_COSTLY_DEPENDENCE rs6000_is_costly_dependence
1275 #undef TARGET_SCHED_INIT
1276 #define TARGET_SCHED_INIT rs6000_sched_init
1277 #undef TARGET_SCHED_FINISH
1278 #define TARGET_SCHED_FINISH rs6000_sched_finish
1279 #undef TARGET_SCHED_REORDER
1280 #define TARGET_SCHED_REORDER rs6000_sched_reorder
1281 #undef TARGET_SCHED_REORDER2
1282 #define TARGET_SCHED_REORDER2 rs6000_sched_reorder2
1284 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
1285 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD rs6000_use_sched_lookahead
1287 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD
1288 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD rs6000_use_sched_lookahead_guard
1290 #undef TARGET_SCHED_ALLOC_SCHED_CONTEXT
1291 #define TARGET_SCHED_ALLOC_SCHED_CONTEXT rs6000_alloc_sched_context
1292 #undef TARGET_SCHED_INIT_SCHED_CONTEXT
1293 #define TARGET_SCHED_INIT_SCHED_CONTEXT rs6000_init_sched_context
1294 #undef TARGET_SCHED_SET_SCHED_CONTEXT
1295 #define TARGET_SCHED_SET_SCHED_CONTEXT rs6000_set_sched_context
1296 #undef TARGET_SCHED_FREE_SCHED_CONTEXT
1297 #define TARGET_SCHED_FREE_SCHED_CONTEXT rs6000_free_sched_context
1299 #undef TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD
1300 #define TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD rs6000_builtin_mask_for_load
1301 #undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN
1302 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN rs6000_builtin_mul_widen_even
1303 #undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD
1304 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD rs6000_builtin_mul_widen_odd
1305 #undef TARGET_VECTORIZE_BUILTIN_CONVERSION
1306 #define TARGET_VECTORIZE_BUILTIN_CONVERSION rs6000_builtin_conversion
1307 #undef TARGET_VECTORIZE_BUILTIN_VEC_PERM
1308 #define TARGET_VECTORIZE_BUILTIN_VEC_PERM rs6000_builtin_vec_perm
1309 #undef TARGET_SUPPORT_VECTOR_MISALIGNMENT
1310 #define TARGET_SUPPORT_VECTOR_MISALIGNMENT \
1311 rs6000_builtin_support_vector_misalignment
1312 #undef TARGET_VECTOR_ALIGNMENT_REACHABLE
1313 #define TARGET_VECTOR_ALIGNMENT_REACHABLE rs6000_vector_alignment_reachable
1315 #undef TARGET_INIT_BUILTINS
1316 #define TARGET_INIT_BUILTINS rs6000_init_builtins
1318 #undef TARGET_EXPAND_BUILTIN
1319 #define TARGET_EXPAND_BUILTIN rs6000_expand_builtin
1321 #undef TARGET_MANGLE_TYPE
1322 #define TARGET_MANGLE_TYPE rs6000_mangle_type
1324 #undef TARGET_INIT_LIBFUNCS
1325 #define TARGET_INIT_LIBFUNCS rs6000_init_libfuncs
1327 #if TARGET_MACHO
1328 #undef TARGET_BINDS_LOCAL_P
1329 #define TARGET_BINDS_LOCAL_P darwin_binds_local_p
1330 #endif
1332 #undef TARGET_MS_BITFIELD_LAYOUT_P
1333 #define TARGET_MS_BITFIELD_LAYOUT_P rs6000_ms_bitfield_layout_p
1335 #undef TARGET_ASM_OUTPUT_MI_THUNK
1336 #define TARGET_ASM_OUTPUT_MI_THUNK rs6000_output_mi_thunk
1338 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
1339 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true
1341 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
1342 #define TARGET_FUNCTION_OK_FOR_SIBCALL rs6000_function_ok_for_sibcall
1344 #undef TARGET_INVALID_WITHIN_DOLOOP
1345 #define TARGET_INVALID_WITHIN_DOLOOP rs6000_invalid_within_doloop
1347 #undef TARGET_RTX_COSTS
1348 #define TARGET_RTX_COSTS rs6000_rtx_costs
1349 #undef TARGET_ADDRESS_COST
1350 #define TARGET_ADDRESS_COST hook_int_rtx_bool_0
1352 #undef TARGET_DWARF_REGISTER_SPAN
1353 #define TARGET_DWARF_REGISTER_SPAN rs6000_dwarf_register_span
1355 #undef TARGET_INIT_DWARF_REG_SIZES_EXTRA
1356 #define TARGET_INIT_DWARF_REG_SIZES_EXTRA rs6000_init_dwarf_reg_sizes_extra
1358 /* On rs6000, function arguments are promoted, as are function return
1359 values. */
1360 #undef TARGET_PROMOTE_FUNCTION_MODE
1361 #define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote
1363 #undef TARGET_RETURN_IN_MEMORY
1364 #define TARGET_RETURN_IN_MEMORY rs6000_return_in_memory
1366 #undef TARGET_SETUP_INCOMING_VARARGS
1367 #define TARGET_SETUP_INCOMING_VARARGS setup_incoming_varargs
1369 /* Always strict argument naming on rs6000. */
1370 #undef TARGET_STRICT_ARGUMENT_NAMING
1371 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
1372 #undef TARGET_PRETEND_OUTGOING_VARARGS_NAMED
1373 #define TARGET_PRETEND_OUTGOING_VARARGS_NAMED hook_bool_CUMULATIVE_ARGS_true
1374 #undef TARGET_SPLIT_COMPLEX_ARG
1375 #define TARGET_SPLIT_COMPLEX_ARG hook_bool_const_tree_true
1376 #undef TARGET_MUST_PASS_IN_STACK
1377 #define TARGET_MUST_PASS_IN_STACK rs6000_must_pass_in_stack
1378 #undef TARGET_PASS_BY_REFERENCE
1379 #define TARGET_PASS_BY_REFERENCE rs6000_pass_by_reference
1380 #undef TARGET_ARG_PARTIAL_BYTES
1381 #define TARGET_ARG_PARTIAL_BYTES rs6000_arg_partial_bytes
1383 #undef TARGET_BUILD_BUILTIN_VA_LIST
1384 #define TARGET_BUILD_BUILTIN_VA_LIST rs6000_build_builtin_va_list
1386 #undef TARGET_EXPAND_BUILTIN_VA_START
1387 #define TARGET_EXPAND_BUILTIN_VA_START rs6000_va_start
1389 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
1390 #define TARGET_GIMPLIFY_VA_ARG_EXPR rs6000_gimplify_va_arg
1392 #undef TARGET_EH_RETURN_FILTER_MODE
1393 #define TARGET_EH_RETURN_FILTER_MODE rs6000_eh_return_filter_mode
1395 #undef TARGET_SCALAR_MODE_SUPPORTED_P
1396 #define TARGET_SCALAR_MODE_SUPPORTED_P rs6000_scalar_mode_supported_p
1398 #undef TARGET_VECTOR_MODE_SUPPORTED_P
1399 #define TARGET_VECTOR_MODE_SUPPORTED_P rs6000_vector_mode_supported_p
1401 #undef TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN
1402 #define TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN invalid_arg_for_unprototyped_fn
1404 #undef TARGET_HANDLE_OPTION
1405 #define TARGET_HANDLE_OPTION rs6000_handle_option
1407 #undef TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION
1408 #define TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION \
1409 rs6000_builtin_vectorized_function
1411 #undef TARGET_DEFAULT_TARGET_FLAGS
1412 #define TARGET_DEFAULT_TARGET_FLAGS \
1413 (TARGET_DEFAULT)
1415 #undef TARGET_STACK_PROTECT_FAIL
1416 #define TARGET_STACK_PROTECT_FAIL rs6000_stack_protect_fail
1418 /* MPC604EUM 3.5.2 Weak Consistency between Multiple Processors
1419 The PowerPC architecture requires only weak consistency among
1420 processors--that is, memory accesses between processors need not be
1421 sequentially consistent and memory accesses among processors can occur
1422 in any order. The ability to order memory accesses weakly provides
1423 opportunities for more efficient use of the system bus. Unless a
1424 dependency exists, the 604e allows read operations to precede store
1425 operations. */
1426 #undef TARGET_RELAXED_ORDERING
1427 #define TARGET_RELAXED_ORDERING true
1429 #ifdef HAVE_AS_TLS
1430 #undef TARGET_ASM_OUTPUT_DWARF_DTPREL
1431 #define TARGET_ASM_OUTPUT_DWARF_DTPREL rs6000_output_dwarf_dtprel
1432 #endif
1434 /* Use a 32-bit anchor range. This leads to sequences like:
1436 addis tmp,anchor,high
1437 add dest,tmp,low
1439 where tmp itself acts as an anchor, and can be shared between
1440 accesses to the same 64k page. */
1441 #undef TARGET_MIN_ANCHOR_OFFSET
1442 #define TARGET_MIN_ANCHOR_OFFSET -0x7fffffff - 1
1443 #undef TARGET_MAX_ANCHOR_OFFSET
1444 #define TARGET_MAX_ANCHOR_OFFSET 0x7fffffff
1445 #undef TARGET_USE_BLOCKS_FOR_CONSTANT_P
1446 #define TARGET_USE_BLOCKS_FOR_CONSTANT_P rs6000_use_blocks_for_constant_p
1448 #undef TARGET_DELEGITIMIZE_ADDRESS
1449 #define TARGET_DELEGITIMIZE_ADDRESS rs6000_delegitimize_address
1451 #undef TARGET_BUILTIN_RECIPROCAL
1452 #define TARGET_BUILTIN_RECIPROCAL rs6000_builtin_reciprocal
1454 #undef TARGET_EXPAND_TO_RTL_HOOK
1455 #define TARGET_EXPAND_TO_RTL_HOOK rs6000_alloc_sdmode_stack_slot
1457 #undef TARGET_INSTANTIATE_DECLS
1458 #define TARGET_INSTANTIATE_DECLS rs6000_instantiate_decls
1460 #undef TARGET_SECONDARY_RELOAD
1461 #define TARGET_SECONDARY_RELOAD rs6000_secondary_reload
1463 #undef TARGET_IRA_COVER_CLASSES
1464 #define TARGET_IRA_COVER_CLASSES rs6000_ira_cover_classes
1466 #undef TARGET_LEGITIMATE_ADDRESS_P
1467 #define TARGET_LEGITIMATE_ADDRESS_P rs6000_legitimate_address_p
1469 #undef TARGET_CAN_ELIMINATE
1470 #define TARGET_CAN_ELIMINATE rs6000_can_eliminate
1472 #undef TARGET_TRAMPOLINE_INIT
1473 #define TARGET_TRAMPOLINE_INIT rs6000_trampoline_init
1475 #undef TARGET_FUNCTION_VALUE
1476 #define TARGET_FUNCTION_VALUE rs6000_function_value
1478 struct gcc_target targetm = TARGET_INITIALIZER;
1480 /* Return number of consecutive hard regs needed starting at reg REGNO
1481 to hold something of mode MODE.
1482 This is ordinarily the length in words of a value of mode MODE
1483 but can be less for certain modes in special long registers.
1485 For the SPE, GPRs are 64 bits but only 32 bits are visible in
1486 scalar instructions. The upper 32 bits are only available to the
1487 SIMD instructions.
1489 POWER and PowerPC GPRs hold 32 bits worth;
1490 PowerPC64 GPRs and FPRs point register holds 64 bits worth. */
1492 static int
1493 rs6000_hard_regno_nregs_internal (int regno, enum machine_mode mode)
1495 unsigned HOST_WIDE_INT reg_size;
1497 if (FP_REGNO_P (regno))
1498 reg_size = (VECTOR_MEM_VSX_P (mode)
1499 ? UNITS_PER_VSX_WORD
1500 : UNITS_PER_FP_WORD);
1502 else if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode))
1503 reg_size = UNITS_PER_SPE_WORD;
1505 else if (ALTIVEC_REGNO_P (regno))
1506 reg_size = UNITS_PER_ALTIVEC_WORD;
1508 /* The value returned for SCmode in the E500 double case is 2 for
1509 ABI compatibility; storing an SCmode value in a single register
1510 would require function_arg and rs6000_spe_function_arg to handle
1511 SCmode so as to pass the value correctly in a pair of
1512 registers. */
1513 else if (TARGET_E500_DOUBLE && FLOAT_MODE_P (mode) && mode != SCmode
1514 && !DECIMAL_FLOAT_MODE_P (mode))
1515 reg_size = UNITS_PER_FP_WORD;
1517 else
1518 reg_size = UNITS_PER_WORD;
1520 return (GET_MODE_SIZE (mode) + reg_size - 1) / reg_size;
1523 /* Value is 1 if hard register REGNO can hold a value of machine-mode
1524 MODE. */
1525 static int
1526 rs6000_hard_regno_mode_ok (int regno, enum machine_mode mode)
1528 int last_regno = regno + rs6000_hard_regno_nregs[mode][regno] - 1;
1530 /* VSX registers that overlap the FPR registers are larger than for non-VSX
1531 implementations. Don't allow an item to be split between a FP register
1532 and an Altivec register. */
1533 if (VECTOR_MEM_VSX_P (mode))
1535 if (FP_REGNO_P (regno))
1536 return FP_REGNO_P (last_regno);
1538 if (ALTIVEC_REGNO_P (regno))
1539 return ALTIVEC_REGNO_P (last_regno);
1542 /* The GPRs can hold any mode, but values bigger than one register
1543 cannot go past R31. */
1544 if (INT_REGNO_P (regno))
1545 return INT_REGNO_P (last_regno);
1547 /* The float registers (except for VSX vector modes) can only hold floating
1548 modes and DImode. This excludes the 32-bit decimal float mode for
1549 now. */
1550 if (FP_REGNO_P (regno))
1552 if (SCALAR_FLOAT_MODE_P (mode)
1553 && (mode != TDmode || (regno % 2) == 0)
1554 && FP_REGNO_P (last_regno))
1555 return 1;
1557 if (GET_MODE_CLASS (mode) == MODE_INT
1558 && GET_MODE_SIZE (mode) == UNITS_PER_FP_WORD)
1559 return 1;
1561 if (PAIRED_SIMD_REGNO_P (regno) && TARGET_PAIRED_FLOAT
1562 && PAIRED_VECTOR_MODE (mode))
1563 return 1;
1565 return 0;
1568 /* The CR register can only hold CC modes. */
1569 if (CR_REGNO_P (regno))
1570 return GET_MODE_CLASS (mode) == MODE_CC;
1572 if (XER_REGNO_P (regno))
1573 return mode == PSImode;
1575 /* AltiVec only in AldyVec registers. */
1576 if (ALTIVEC_REGNO_P (regno))
1577 return VECTOR_MEM_ALTIVEC_OR_VSX_P (mode);
1579 /* ...but GPRs can hold SIMD data on the SPE in one register. */
1580 if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode))
1581 return 1;
1583 /* We cannot put TImode anywhere except general register and it must be able
1584 to fit within the register set. In the future, allow TImode in the
1585 Altivec or VSX registers. */
1587 return GET_MODE_SIZE (mode) <= UNITS_PER_WORD;
1590 /* Print interesting facts about registers. */
1591 static void
1592 rs6000_debug_reg_print (int first_regno, int last_regno, const char *reg_name)
1594 int r, m;
1596 for (r = first_regno; r <= last_regno; ++r)
1598 const char *comma = "";
1599 int len;
1601 if (first_regno == last_regno)
1602 fprintf (stderr, "%s:\t", reg_name);
1603 else
1604 fprintf (stderr, "%s%d:\t", reg_name, r - first_regno);
1606 len = 8;
1607 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1608 if (rs6000_hard_regno_mode_ok_p[m][r] && rs6000_hard_regno_nregs[m][r])
1610 if (len > 70)
1612 fprintf (stderr, ",\n\t");
1613 len = 8;
1614 comma = "";
1617 if (rs6000_hard_regno_nregs[m][r] > 1)
1618 len += fprintf (stderr, "%s%s/%d", comma, GET_MODE_NAME (m),
1619 rs6000_hard_regno_nregs[m][r]);
1620 else
1621 len += fprintf (stderr, "%s%s", comma, GET_MODE_NAME (m));
1623 comma = ", ";
1626 if (call_used_regs[r])
1628 if (len > 70)
1630 fprintf (stderr, ",\n\t");
1631 len = 8;
1632 comma = "";
1635 len += fprintf (stderr, "%s%s", comma, "call-used");
1636 comma = ", ";
1639 if (fixed_regs[r])
1641 if (len > 70)
1643 fprintf (stderr, ",\n\t");
1644 len = 8;
1645 comma = "";
1648 len += fprintf (stderr, "%s%s", comma, "fixed");
1649 comma = ", ";
1652 if (len > 70)
1654 fprintf (stderr, ",\n\t");
1655 comma = "";
1658 fprintf (stderr, "%sregno = %d\n", comma, r);
1662 /* Print various interesting information with -mdebug=reg. */
1663 static void
1664 rs6000_debug_reg_global (void)
1666 const char *nl = (const char *)0;
1667 int m;
1668 char costly_num[20];
1669 char nop_num[20];
1670 const char *costly_str;
1671 const char *nop_str;
1673 /* Map enum rs6000_vector to string. */
1674 static const char *rs6000_debug_vector_unit[] = {
1675 "none",
1676 "altivec",
1677 "vsx",
1678 "paired",
1679 "spe",
1680 "other"
1683 fprintf (stderr, "Register information: (last virtual reg = %d)\n",
1684 LAST_VIRTUAL_REGISTER);
1685 rs6000_debug_reg_print (0, 31, "gr");
1686 rs6000_debug_reg_print (32, 63, "fp");
1687 rs6000_debug_reg_print (FIRST_ALTIVEC_REGNO,
1688 LAST_ALTIVEC_REGNO,
1689 "vs");
1690 rs6000_debug_reg_print (LR_REGNO, LR_REGNO, "lr");
1691 rs6000_debug_reg_print (CTR_REGNO, CTR_REGNO, "ctr");
1692 rs6000_debug_reg_print (CR0_REGNO, CR7_REGNO, "cr");
1693 rs6000_debug_reg_print (MQ_REGNO, MQ_REGNO, "mq");
1694 rs6000_debug_reg_print (XER_REGNO, XER_REGNO, "xer");
1695 rs6000_debug_reg_print (VRSAVE_REGNO, VRSAVE_REGNO, "vrsave");
1696 rs6000_debug_reg_print (VSCR_REGNO, VSCR_REGNO, "vscr");
1697 rs6000_debug_reg_print (SPE_ACC_REGNO, SPE_ACC_REGNO, "spe_a");
1698 rs6000_debug_reg_print (SPEFSCR_REGNO, SPEFSCR_REGNO, "spe_f");
1700 fprintf (stderr,
1701 "\n"
1702 "d reg_class = %s\n"
1703 "f reg_class = %s\n"
1704 "v reg_class = %s\n"
1705 "wa reg_class = %s\n"
1706 "wd reg_class = %s\n"
1707 "wf reg_class = %s\n"
1708 "ws reg_class = %s\n\n",
1709 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_d]],
1710 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_f]],
1711 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_v]],
1712 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wa]],
1713 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wd]],
1714 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wf]],
1715 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_ws]]);
1717 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1718 if (rs6000_vector_unit[m] || rs6000_vector_mem[m])
1720 nl = "\n";
1721 fprintf (stderr, "Vector mode: %-5s arithmetic: %-8s move: %-8s\n",
1722 GET_MODE_NAME (m),
1723 rs6000_debug_vector_unit[ rs6000_vector_unit[m] ],
1724 rs6000_debug_vector_unit[ rs6000_vector_mem[m] ]);
1727 if (nl)
1728 fputs (nl, stderr);
1730 switch (rs6000_sched_costly_dep)
1732 case max_dep_latency:
1733 costly_str = "max_dep_latency";
1734 break;
1736 case no_dep_costly:
1737 costly_str = "no_dep_costly";
1738 break;
1740 case all_deps_costly:
1741 costly_str = "all_deps_costly";
1742 break;
1744 case true_store_to_load_dep_costly:
1745 costly_str = "true_store_to_load_dep_costly";
1746 break;
1748 case store_to_load_dep_costly:
1749 costly_str = "store_to_load_dep_costly";
1750 break;
1752 default:
1753 costly_str = costly_num;
1754 sprintf (costly_num, "%d", (int)rs6000_sched_costly_dep);
1755 break;
1758 switch (rs6000_sched_insert_nops)
1760 case sched_finish_regroup_exact:
1761 nop_str = "sched_finish_regroup_exact";
1762 break;
1764 case sched_finish_pad_groups:
1765 nop_str = "sched_finish_pad_groups";
1766 break;
1768 case sched_finish_none:
1769 nop_str = "sched_finish_none";
1770 break;
1772 default:
1773 nop_str = nop_num;
1774 sprintf (nop_num, "%d", (int)rs6000_sched_insert_nops);
1775 break;
1778 fprintf (stderr,
1779 "always_hint = %s\n"
1780 "align_branch_targets = %s\n"
1781 "sched_restricted_insns_priority = %d\n"
1782 "sched_costly_dep = %s\n"
1783 "sched_insert_nops = %s\n\n",
1784 rs6000_always_hint ? "true" : "false",
1785 rs6000_align_branch_targets ? "true" : "false",
1786 (int)rs6000_sched_restricted_insns_priority,
1787 costly_str, nop_str);
1790 /* Initialize the various global tables that are based on register size. */
1791 static void
1792 rs6000_init_hard_regno_mode_ok (void)
1794 int r, m, c;
1795 int align64;
1796 int align32;
1798 /* Precalculate REGNO_REG_CLASS. */
1799 rs6000_regno_regclass[0] = GENERAL_REGS;
1800 for (r = 1; r < 32; ++r)
1801 rs6000_regno_regclass[r] = BASE_REGS;
1803 for (r = 32; r < 64; ++r)
1804 rs6000_regno_regclass[r] = FLOAT_REGS;
1806 for (r = 64; r < FIRST_PSEUDO_REGISTER; ++r)
1807 rs6000_regno_regclass[r] = NO_REGS;
1809 for (r = FIRST_ALTIVEC_REGNO; r <= LAST_ALTIVEC_REGNO; ++r)
1810 rs6000_regno_regclass[r] = ALTIVEC_REGS;
1812 rs6000_regno_regclass[CR0_REGNO] = CR0_REGS;
1813 for (r = CR1_REGNO; r <= CR7_REGNO; ++r)
1814 rs6000_regno_regclass[r] = CR_REGS;
1816 rs6000_regno_regclass[MQ_REGNO] = MQ_REGS;
1817 rs6000_regno_regclass[LR_REGNO] = LINK_REGS;
1818 rs6000_regno_regclass[CTR_REGNO] = CTR_REGS;
1819 rs6000_regno_regclass[XER_REGNO] = XER_REGS;
1820 rs6000_regno_regclass[VRSAVE_REGNO] = VRSAVE_REGS;
1821 rs6000_regno_regclass[VSCR_REGNO] = VRSAVE_REGS;
1822 rs6000_regno_regclass[SPE_ACC_REGNO] = SPE_ACC_REGS;
1823 rs6000_regno_regclass[SPEFSCR_REGNO] = SPEFSCR_REGS;
1824 rs6000_regno_regclass[ARG_POINTER_REGNUM] = BASE_REGS;
1825 rs6000_regno_regclass[FRAME_POINTER_REGNUM] = BASE_REGS;
1827 /* Precalculate vector information, this must be set up before the
1828 rs6000_hard_regno_nregs_internal below. */
1829 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1831 rs6000_vector_unit[m] = rs6000_vector_mem[m] = VECTOR_NONE;
1832 rs6000_vector_reload[m][0] = CODE_FOR_nothing;
1833 rs6000_vector_reload[m][1] = CODE_FOR_nothing;
1836 for (c = 0; c < (int)(int)RS6000_CONSTRAINT_MAX; c++)
1837 rs6000_constraints[c] = NO_REGS;
1839 /* The VSX hardware allows native alignment for vectors, but control whether the compiler
1840 believes it can use native alignment or still uses 128-bit alignment. */
1841 if (TARGET_VSX && !TARGET_VSX_ALIGN_128)
1843 align64 = 64;
1844 align32 = 32;
1846 else
1848 align64 = 128;
1849 align32 = 128;
1852 /* V2DF mode, VSX only. */
1853 if (TARGET_VSX)
1855 rs6000_vector_unit[V2DFmode] = VECTOR_VSX;
1856 rs6000_vector_mem[V2DFmode] = VECTOR_VSX;
1857 rs6000_vector_align[V2DFmode] = align64;
1860 /* V4SF mode, either VSX or Altivec. */
1861 if (TARGET_VSX)
1863 rs6000_vector_unit[V4SFmode] = VECTOR_VSX;
1864 rs6000_vector_mem[V4SFmode] = VECTOR_VSX;
1865 rs6000_vector_align[V4SFmode] = align32;
1867 else if (TARGET_ALTIVEC)
1869 rs6000_vector_unit[V4SFmode] = VECTOR_ALTIVEC;
1870 rs6000_vector_mem[V4SFmode] = VECTOR_ALTIVEC;
1871 rs6000_vector_align[V4SFmode] = align32;
1874 /* V16QImode, V8HImode, V4SImode are Altivec only, but possibly do VSX loads
1875 and stores. */
1876 if (TARGET_ALTIVEC)
1878 rs6000_vector_unit[V4SImode] = VECTOR_ALTIVEC;
1879 rs6000_vector_unit[V8HImode] = VECTOR_ALTIVEC;
1880 rs6000_vector_unit[V16QImode] = VECTOR_ALTIVEC;
1881 rs6000_vector_align[V4SImode] = align32;
1882 rs6000_vector_align[V8HImode] = align32;
1883 rs6000_vector_align[V16QImode] = align32;
1885 if (TARGET_VSX)
1887 rs6000_vector_mem[V4SImode] = VECTOR_VSX;
1888 rs6000_vector_mem[V8HImode] = VECTOR_VSX;
1889 rs6000_vector_mem[V16QImode] = VECTOR_VSX;
1891 else
1893 rs6000_vector_mem[V4SImode] = VECTOR_ALTIVEC;
1894 rs6000_vector_mem[V8HImode] = VECTOR_ALTIVEC;
1895 rs6000_vector_mem[V16QImode] = VECTOR_ALTIVEC;
1899 /* V2DImode, only allow under VSX, which can do V2DI insert/splat/extract.
1900 Altivec doesn't have 64-bit support. */
1901 if (TARGET_VSX)
1903 rs6000_vector_mem[V2DImode] = VECTOR_VSX;
1904 rs6000_vector_unit[V2DImode] = VECTOR_NONE;
1905 rs6000_vector_align[V2DImode] = align64;
1908 /* DFmode, see if we want to use the VSX unit. */
1909 if (TARGET_VSX && TARGET_VSX_SCALAR_DOUBLE)
1911 rs6000_vector_unit[DFmode] = VECTOR_VSX;
1912 rs6000_vector_mem[DFmode]
1913 = (TARGET_VSX_SCALAR_MEMORY ? VECTOR_VSX : VECTOR_NONE);
1914 rs6000_vector_align[DFmode] = align64;
1917 /* TODO add SPE and paired floating point vector support. */
1919 /* Register class constaints for the constraints that depend on compile
1920 switches. */
1921 if (TARGET_HARD_FLOAT && TARGET_FPRS)
1922 rs6000_constraints[RS6000_CONSTRAINT_f] = FLOAT_REGS;
1924 if (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
1925 rs6000_constraints[RS6000_CONSTRAINT_d] = FLOAT_REGS;
1927 if (TARGET_VSX)
1929 /* At present, we just use VSX_REGS, but we have different constraints
1930 based on the use, in case we want to fine tune the default register
1931 class used. wa = any VSX register, wf = register class to use for
1932 V4SF, wd = register class to use for V2DF, and ws = register classs to
1933 use for DF scalars. */
1934 rs6000_constraints[RS6000_CONSTRAINT_wa] = VSX_REGS;
1935 rs6000_constraints[RS6000_CONSTRAINT_wf] = VSX_REGS;
1936 rs6000_constraints[RS6000_CONSTRAINT_wd] = VSX_REGS;
1937 if (TARGET_VSX_SCALAR_DOUBLE)
1938 rs6000_constraints[RS6000_CONSTRAINT_ws] = VSX_REGS;
1941 if (TARGET_ALTIVEC)
1942 rs6000_constraints[RS6000_CONSTRAINT_v] = ALTIVEC_REGS;
1944 /* Set up the reload helper functions. */
1945 if (TARGET_VSX || TARGET_ALTIVEC)
1947 if (TARGET_64BIT)
1949 rs6000_vector_reload[V16QImode][0] = CODE_FOR_reload_v16qi_di_store;
1950 rs6000_vector_reload[V16QImode][1] = CODE_FOR_reload_v16qi_di_load;
1951 rs6000_vector_reload[V8HImode][0] = CODE_FOR_reload_v8hi_di_store;
1952 rs6000_vector_reload[V8HImode][1] = CODE_FOR_reload_v8hi_di_load;
1953 rs6000_vector_reload[V4SImode][0] = CODE_FOR_reload_v4si_di_store;
1954 rs6000_vector_reload[V4SImode][1] = CODE_FOR_reload_v4si_di_load;
1955 rs6000_vector_reload[V2DImode][0] = CODE_FOR_reload_v2di_di_store;
1956 rs6000_vector_reload[V2DImode][1] = CODE_FOR_reload_v2di_di_load;
1957 rs6000_vector_reload[V4SFmode][0] = CODE_FOR_reload_v4sf_di_store;
1958 rs6000_vector_reload[V4SFmode][1] = CODE_FOR_reload_v4sf_di_load;
1959 rs6000_vector_reload[V2DFmode][0] = CODE_FOR_reload_v2df_di_store;
1960 rs6000_vector_reload[V2DFmode][1] = CODE_FOR_reload_v2df_di_load;
1962 else
1964 rs6000_vector_reload[V16QImode][0] = CODE_FOR_reload_v16qi_si_store;
1965 rs6000_vector_reload[V16QImode][1] = CODE_FOR_reload_v16qi_si_load;
1966 rs6000_vector_reload[V8HImode][0] = CODE_FOR_reload_v8hi_si_store;
1967 rs6000_vector_reload[V8HImode][1] = CODE_FOR_reload_v8hi_si_load;
1968 rs6000_vector_reload[V4SImode][0] = CODE_FOR_reload_v4si_si_store;
1969 rs6000_vector_reload[V4SImode][1] = CODE_FOR_reload_v4si_si_load;
1970 rs6000_vector_reload[V2DImode][0] = CODE_FOR_reload_v2di_si_store;
1971 rs6000_vector_reload[V2DImode][1] = CODE_FOR_reload_v2di_si_load;
1972 rs6000_vector_reload[V4SFmode][0] = CODE_FOR_reload_v4sf_si_store;
1973 rs6000_vector_reload[V4SFmode][1] = CODE_FOR_reload_v4sf_si_load;
1974 rs6000_vector_reload[V2DFmode][0] = CODE_FOR_reload_v2df_si_store;
1975 rs6000_vector_reload[V2DFmode][1] = CODE_FOR_reload_v2df_si_load;
1979 /* Precalculate HARD_REGNO_NREGS. */
1980 for (r = 0; r < FIRST_PSEUDO_REGISTER; ++r)
1981 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1982 rs6000_hard_regno_nregs[m][r]
1983 = rs6000_hard_regno_nregs_internal (r, (enum machine_mode)m);
1985 /* Precalculate HARD_REGNO_MODE_OK. */
1986 for (r = 0; r < FIRST_PSEUDO_REGISTER; ++r)
1987 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1988 if (rs6000_hard_regno_mode_ok (r, (enum machine_mode)m))
1989 rs6000_hard_regno_mode_ok_p[m][r] = true;
1991 /* Precalculate CLASS_MAX_NREGS sizes. */
1992 for (c = 0; c < LIM_REG_CLASSES; ++c)
1994 int reg_size;
1996 if (TARGET_VSX && VSX_REG_CLASS_P (c))
1997 reg_size = UNITS_PER_VSX_WORD;
1999 else if (c == ALTIVEC_REGS)
2000 reg_size = UNITS_PER_ALTIVEC_WORD;
2002 else if (c == FLOAT_REGS)
2003 reg_size = UNITS_PER_FP_WORD;
2005 else
2006 reg_size = UNITS_PER_WORD;
2008 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2009 rs6000_class_max_nregs[m][c]
2010 = (GET_MODE_SIZE (m) + reg_size - 1) / reg_size;
2013 if (TARGET_E500_DOUBLE)
2014 rs6000_class_max_nregs[DFmode][GENERAL_REGS] = 1;
2016 if (TARGET_DEBUG_REG)
2017 rs6000_debug_reg_global ();
2020 #if TARGET_MACHO
2021 /* The Darwin version of SUBTARGET_OVERRIDE_OPTIONS. */
2023 static void
2024 darwin_rs6000_override_options (void)
2026 /* The Darwin ABI always includes AltiVec, can't be (validly) turned
2027 off. */
2028 rs6000_altivec_abi = 1;
2029 TARGET_ALTIVEC_VRSAVE = 1;
2030 if (DEFAULT_ABI == ABI_DARWIN)
2032 if (MACHO_DYNAMIC_NO_PIC_P)
2034 if (flag_pic)
2035 warning (0, "-mdynamic-no-pic overrides -fpic or -fPIC");
2036 flag_pic = 0;
2038 else if (flag_pic == 1)
2040 flag_pic = 2;
2043 if (TARGET_64BIT && ! TARGET_POWERPC64)
2045 target_flags |= MASK_POWERPC64;
2046 warning (0, "-m64 requires PowerPC64 architecture, enabling");
2048 if (flag_mkernel)
2050 rs6000_default_long_calls = 1;
2051 target_flags |= MASK_SOFT_FLOAT;
2054 /* Make -m64 imply -maltivec. Darwin's 64-bit ABI includes
2055 Altivec. */
2056 if (!flag_mkernel && !flag_apple_kext
2057 && TARGET_64BIT
2058 && ! (target_flags_explicit & MASK_ALTIVEC))
2059 target_flags |= MASK_ALTIVEC;
2061 /* Unless the user (not the configurer) has explicitly overridden
2062 it with -mcpu=G3 or -mno-altivec, then 10.5+ targets default to
2063 G4 unless targetting the kernel. */
2064 if (!flag_mkernel
2065 && !flag_apple_kext
2066 && strverscmp (darwin_macosx_version_min, "10.5") >= 0
2067 && ! (target_flags_explicit & MASK_ALTIVEC)
2068 && ! rs6000_select[1].string)
2070 target_flags |= MASK_ALTIVEC;
2073 #endif
2075 /* If not otherwise specified by a target, make 'long double' equivalent to
2076 'double'. */
2078 #ifndef RS6000_DEFAULT_LONG_DOUBLE_SIZE
2079 #define RS6000_DEFAULT_LONG_DOUBLE_SIZE 64
2080 #endif
2082 /* Override command line options. Mostly we process the processor
2083 type and sometimes adjust other TARGET_ options. */
2085 void
2086 rs6000_override_options (const char *default_cpu)
2088 size_t i, j;
2089 struct rs6000_cpu_select *ptr;
2090 int set_masks;
2092 /* Simplifications for entries below. */
2094 enum {
2095 POWERPC_BASE_MASK = MASK_POWERPC | MASK_NEW_MNEMONICS,
2096 POWERPC_7400_MASK = POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_ALTIVEC
2099 /* This table occasionally claims that a processor does not support
2100 a particular feature even though it does, but the feature is slower
2101 than the alternative. Thus, it shouldn't be relied on as a
2102 complete description of the processor's support.
2104 Please keep this list in order, and don't forget to update the
2105 documentation in invoke.texi when adding a new processor or
2106 flag. */
2107 static struct ptt
2109 const char *const name; /* Canonical processor name. */
2110 const enum processor_type processor; /* Processor type enum value. */
2111 const int target_enable; /* Target flags to enable. */
2112 } const processor_target_table[]
2113 = {{"401", PROCESSOR_PPC403, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2114 {"403", PROCESSOR_PPC403,
2115 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_STRICT_ALIGN},
2116 {"405", PROCESSOR_PPC405,
2117 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
2118 {"405fp", PROCESSOR_PPC405,
2119 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
2120 {"440", PROCESSOR_PPC440,
2121 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
2122 {"440fp", PROCESSOR_PPC440,
2123 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
2124 {"464", PROCESSOR_PPC440,
2125 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
2126 {"464fp", PROCESSOR_PPC440,
2127 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
2128 {"505", PROCESSOR_MPCCORE, POWERPC_BASE_MASK},
2129 {"601", PROCESSOR_PPC601,
2130 MASK_POWER | POWERPC_BASE_MASK | MASK_MULTIPLE | MASK_STRING},
2131 {"602", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2132 {"603", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2133 {"603e", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2134 {"604", PROCESSOR_PPC604, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2135 {"604e", PROCESSOR_PPC604e, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2136 {"620", PROCESSOR_PPC620,
2137 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
2138 {"630", PROCESSOR_PPC630,
2139 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
2140 {"740", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2141 {"7400", PROCESSOR_PPC7400, POWERPC_7400_MASK},
2142 {"7450", PROCESSOR_PPC7450, POWERPC_7400_MASK},
2143 {"750", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2144 {"801", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2145 {"821", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2146 {"823", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2147 {"8540", PROCESSOR_PPC8540, POWERPC_BASE_MASK | MASK_STRICT_ALIGN
2148 | MASK_ISEL},
2149 /* 8548 has a dummy entry for now. */
2150 {"8548", PROCESSOR_PPC8540, POWERPC_BASE_MASK | MASK_STRICT_ALIGN
2151 | MASK_ISEL},
2152 {"e300c2", PROCESSOR_PPCE300C2, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2153 {"e300c3", PROCESSOR_PPCE300C3, POWERPC_BASE_MASK},
2154 {"e500mc", PROCESSOR_PPCE500MC, POWERPC_BASE_MASK | MASK_PPC_GFXOPT
2155 | MASK_ISEL},
2156 {"860", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2157 {"970", PROCESSOR_POWER4,
2158 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
2159 {"cell", PROCESSOR_CELL,
2160 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
2161 {"common", PROCESSOR_COMMON, MASK_NEW_MNEMONICS},
2162 {"ec603e", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2163 {"G3", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2164 {"G4", PROCESSOR_PPC7450, POWERPC_7400_MASK},
2165 {"G5", PROCESSOR_POWER4,
2166 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
2167 {"power", PROCESSOR_POWER, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2168 {"power2", PROCESSOR_POWER,
2169 MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING},
2170 {"power3", PROCESSOR_PPC630,
2171 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
2172 {"power4", PROCESSOR_POWER4,
2173 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2174 | MASK_MFCRF},
2175 {"power5", PROCESSOR_POWER5,
2176 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2177 | MASK_MFCRF | MASK_POPCNTB},
2178 {"power5+", PROCESSOR_POWER5,
2179 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2180 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND},
2181 {"power6", PROCESSOR_POWER6,
2182 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2183 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP},
2184 {"power6x", PROCESSOR_POWER6,
2185 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2186 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP
2187 | MASK_MFPGPR},
2188 {"power7", PROCESSOR_POWER7,
2189 POWERPC_7400_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_MFCRF
2190 | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP | MASK_POPCNTD
2191 | MASK_VSX}, /* Don't add MASK_ISEL by default */
2192 {"powerpc", PROCESSOR_POWERPC, POWERPC_BASE_MASK},
2193 {"powerpc64", PROCESSOR_POWERPC64,
2194 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
2195 {"rios", PROCESSOR_RIOS1, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2196 {"rios1", PROCESSOR_RIOS1, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2197 {"rios2", PROCESSOR_RIOS2,
2198 MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING},
2199 {"rsc", PROCESSOR_PPC601, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2200 {"rsc1", PROCESSOR_PPC601, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2201 {"rs64", PROCESSOR_RS64A,
2202 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64}
2205 const size_t ptt_size = ARRAY_SIZE (processor_target_table);
2207 /* Some OSs don't support saving the high part of 64-bit registers on
2208 context switch. Other OSs don't support saving Altivec registers.
2209 On those OSs, we don't touch the MASK_POWERPC64 or MASK_ALTIVEC
2210 settings; if the user wants either, the user must explicitly specify
2211 them and we won't interfere with the user's specification. */
2213 enum {
2214 POWER_MASKS = MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING,
2215 POWERPC_MASKS = (POWERPC_BASE_MASK | MASK_PPC_GPOPT | MASK_STRICT_ALIGN
2216 | MASK_PPC_GFXOPT | MASK_POWERPC64 | MASK_ALTIVEC
2217 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_MULHW
2218 | MASK_DLMZB | MASK_CMPB | MASK_MFPGPR | MASK_DFP
2219 | MASK_POPCNTD | MASK_VSX | MASK_ISEL)
2222 /* Set the pointer size. */
2223 if (TARGET_64BIT)
2225 rs6000_pmode = (int)DImode;
2226 rs6000_pointer_size = 64;
2228 else
2230 rs6000_pmode = (int)SImode;
2231 rs6000_pointer_size = 32;
2234 set_masks = POWER_MASKS | POWERPC_MASKS | MASK_SOFT_FLOAT;
2235 #ifdef OS_MISSING_POWERPC64
2236 if (OS_MISSING_POWERPC64)
2237 set_masks &= ~MASK_POWERPC64;
2238 #endif
2239 #ifdef OS_MISSING_ALTIVEC
2240 if (OS_MISSING_ALTIVEC)
2241 set_masks &= ~MASK_ALTIVEC;
2242 #endif
2244 /* Don't override by the processor default if given explicitly. */
2245 set_masks &= ~target_flags_explicit;
2247 /* Identify the processor type. */
2248 rs6000_select[0].string = default_cpu;
2249 rs6000_cpu = TARGET_POWERPC64 ? PROCESSOR_DEFAULT64 : PROCESSOR_DEFAULT;
2251 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
2253 ptr = &rs6000_select[i];
2254 if (ptr->string != (char *)0 && ptr->string[0] != '\0')
2256 for (j = 0; j < ptt_size; j++)
2257 if (! strcmp (ptr->string, processor_target_table[j].name))
2259 if (ptr->set_tune_p)
2260 rs6000_cpu = processor_target_table[j].processor;
2262 if (ptr->set_arch_p)
2264 target_flags &= ~set_masks;
2265 target_flags |= (processor_target_table[j].target_enable
2266 & set_masks);
2268 break;
2271 if (j == ptt_size)
2272 error ("bad value (%s) for %s switch", ptr->string, ptr->name);
2276 if (rs6000_cpu == PROCESSOR_PPCE300C2 || rs6000_cpu == PROCESSOR_PPCE300C3
2277 || rs6000_cpu == PROCESSOR_PPCE500MC)
2279 if (TARGET_ALTIVEC)
2280 error ("AltiVec not supported in this target");
2281 if (TARGET_SPE)
2282 error ("Spe not supported in this target");
2285 /* Disable Cell microcode if we are optimizing for the Cell
2286 and not optimizing for size. */
2287 if (rs6000_gen_cell_microcode == -1)
2288 rs6000_gen_cell_microcode = !(rs6000_cpu == PROCESSOR_CELL
2289 && !optimize_size);
2291 /* If we are optimizing big endian systems for space, use the load/store
2292 multiple and string instructions unless we are not generating
2293 Cell microcode. */
2294 if (BYTES_BIG_ENDIAN && optimize_size && !rs6000_gen_cell_microcode)
2295 target_flags |= ~target_flags_explicit & (MASK_MULTIPLE | MASK_STRING);
2297 /* Don't allow -mmultiple or -mstring on little endian systems
2298 unless the cpu is a 750, because the hardware doesn't support the
2299 instructions used in little endian mode, and causes an alignment
2300 trap. The 750 does not cause an alignment trap (except when the
2301 target is unaligned). */
2303 if (!BYTES_BIG_ENDIAN && rs6000_cpu != PROCESSOR_PPC750)
2305 if (TARGET_MULTIPLE)
2307 target_flags &= ~MASK_MULTIPLE;
2308 if ((target_flags_explicit & MASK_MULTIPLE) != 0)
2309 warning (0, "-mmultiple is not supported on little endian systems");
2312 if (TARGET_STRING)
2314 target_flags &= ~MASK_STRING;
2315 if ((target_flags_explicit & MASK_STRING) != 0)
2316 warning (0, "-mstring is not supported on little endian systems");
2320 /* Add some warnings for VSX. Enable -maltivec unless the user explicitly
2321 used -mno-altivec */
2322 if (TARGET_VSX)
2324 const char *msg = NULL;
2325 if (!TARGET_HARD_FLOAT || !TARGET_FPRS
2326 || !TARGET_SINGLE_FLOAT || !TARGET_DOUBLE_FLOAT)
2328 if (target_flags_explicit & MASK_VSX)
2329 msg = N_("-mvsx requires hardware floating point");
2330 else
2331 target_flags &= ~ MASK_VSX;
2333 else if (TARGET_PAIRED_FLOAT)
2334 msg = N_("-mvsx and -mpaired are incompatible");
2335 /* The hardware will allow VSX and little endian, but until we make sure
2336 things like vector select, etc. work don't allow VSX on little endian
2337 systems at this point. */
2338 else if (!BYTES_BIG_ENDIAN)
2339 msg = N_("-mvsx used with little endian code");
2340 else if (TARGET_AVOID_XFORM > 0)
2341 msg = N_("-mvsx needs indexed addressing");
2343 if (msg)
2345 warning (0, msg);
2346 target_flags &= ~ MASK_VSX;
2348 else if (TARGET_VSX && !TARGET_ALTIVEC
2349 && (target_flags_explicit & MASK_ALTIVEC) == 0)
2350 target_flags |= MASK_ALTIVEC;
2353 /* Set debug flags */
2354 if (rs6000_debug_name)
2356 if (! strcmp (rs6000_debug_name, "all"))
2357 rs6000_debug_stack = rs6000_debug_arg = rs6000_debug_reg
2358 = rs6000_debug_addr = rs6000_debug_cost = 1;
2359 else if (! strcmp (rs6000_debug_name, "stack"))
2360 rs6000_debug_stack = 1;
2361 else if (! strcmp (rs6000_debug_name, "arg"))
2362 rs6000_debug_arg = 1;
2363 else if (! strcmp (rs6000_debug_name, "reg"))
2364 rs6000_debug_reg = 1;
2365 else if (! strcmp (rs6000_debug_name, "addr"))
2366 rs6000_debug_addr = 1;
2367 else if (! strcmp (rs6000_debug_name, "cost"))
2368 rs6000_debug_cost = 1;
2369 else
2370 error ("unknown -mdebug-%s switch", rs6000_debug_name);
2372 /* If the appropriate debug option is enabled, replace the target hooks
2373 with debug versions that call the real version and then prints
2374 debugging information. */
2375 if (TARGET_DEBUG_COST)
2377 targetm.rtx_costs = rs6000_debug_rtx_costs;
2378 targetm.address_cost = rs6000_debug_address_cost;
2379 targetm.sched.adjust_cost = rs6000_debug_adjust_cost;
2382 if (TARGET_DEBUG_ADDR)
2384 targetm.legitimate_address_p = rs6000_debug_legitimate_address_p;
2385 targetm.legitimize_address = rs6000_debug_legitimize_address;
2386 rs6000_secondary_reload_class_ptr
2387 = rs6000_debug_secondary_reload_class;
2388 rs6000_secondary_memory_needed_ptr
2389 = rs6000_debug_secondary_memory_needed;
2390 rs6000_cannot_change_mode_class_ptr
2391 = rs6000_debug_cannot_change_mode_class;
2392 rs6000_preferred_reload_class_ptr
2393 = rs6000_debug_preferred_reload_class;
2394 rs6000_legitimize_reload_address_ptr
2395 = rs6000_debug_legitimize_reload_address;
2396 rs6000_mode_dependent_address_ptr
2397 = rs6000_debug_mode_dependent_address;
2401 if (rs6000_traceback_name)
2403 if (! strncmp (rs6000_traceback_name, "full", 4))
2404 rs6000_traceback = traceback_full;
2405 else if (! strncmp (rs6000_traceback_name, "part", 4))
2406 rs6000_traceback = traceback_part;
2407 else if (! strncmp (rs6000_traceback_name, "no", 2))
2408 rs6000_traceback = traceback_none;
2409 else
2410 error ("unknown -mtraceback arg %qs; expecting %<full%>, %<partial%> or %<none%>",
2411 rs6000_traceback_name);
2414 if (!rs6000_explicit_options.long_double)
2415 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
2417 #ifndef POWERPC_LINUX
2418 if (!rs6000_explicit_options.ieee)
2419 rs6000_ieeequad = 1;
2420 #endif
2422 /* Enable Altivec ABI for AIX -maltivec. */
2423 if (TARGET_XCOFF && (TARGET_ALTIVEC || TARGET_VSX))
2424 rs6000_altivec_abi = 1;
2426 /* The AltiVec ABI is the default for PowerPC-64 GNU/Linux. For
2427 PowerPC-32 GNU/Linux, -maltivec implies the AltiVec ABI. It can
2428 be explicitly overridden in either case. */
2429 if (TARGET_ELF)
2431 if (!rs6000_explicit_options.altivec_abi
2432 && (TARGET_64BIT || TARGET_ALTIVEC || TARGET_VSX))
2433 rs6000_altivec_abi = 1;
2435 /* Enable VRSAVE for AltiVec ABI, unless explicitly overridden. */
2436 if (!rs6000_explicit_options.vrsave)
2437 TARGET_ALTIVEC_VRSAVE = rs6000_altivec_abi;
2440 /* Set the Darwin64 ABI as default for 64-bit Darwin. */
2441 if (DEFAULT_ABI == ABI_DARWIN && TARGET_64BIT)
2443 rs6000_darwin64_abi = 1;
2444 #if TARGET_MACHO
2445 darwin_one_byte_bool = 1;
2446 #endif
2447 /* Default to natural alignment, for better performance. */
2448 rs6000_alignment_flags = MASK_ALIGN_NATURAL;
2451 /* Place FP constants in the constant pool instead of TOC
2452 if section anchors enabled. */
2453 if (flag_section_anchors)
2454 TARGET_NO_FP_IN_TOC = 1;
2456 /* Handle -mtls-size option. */
2457 rs6000_parse_tls_size_option ();
2459 #ifdef SUBTARGET_OVERRIDE_OPTIONS
2460 SUBTARGET_OVERRIDE_OPTIONS;
2461 #endif
2462 #ifdef SUBSUBTARGET_OVERRIDE_OPTIONS
2463 SUBSUBTARGET_OVERRIDE_OPTIONS;
2464 #endif
2465 #ifdef SUB3TARGET_OVERRIDE_OPTIONS
2466 SUB3TARGET_OVERRIDE_OPTIONS;
2467 #endif
2469 if (TARGET_E500 || rs6000_cpu == PROCESSOR_PPCE500MC)
2471 /* The e500 and e500mc do not have string instructions, and we set
2472 MASK_STRING above when optimizing for size. */
2473 if ((target_flags & MASK_STRING) != 0)
2474 target_flags = target_flags & ~MASK_STRING;
2476 else if (rs6000_select[1].string != NULL)
2478 /* For the powerpc-eabispe configuration, we set all these by
2479 default, so let's unset them if we manually set another
2480 CPU that is not the E500. */
2481 if (!rs6000_explicit_options.spe_abi)
2482 rs6000_spe_abi = 0;
2483 if (!rs6000_explicit_options.spe)
2484 rs6000_spe = 0;
2485 if (!rs6000_explicit_options.float_gprs)
2486 rs6000_float_gprs = 0;
2487 if (!(target_flags_explicit & MASK_ISEL))
2488 target_flags &= ~MASK_ISEL;
2491 /* Detect invalid option combinations with E500. */
2492 CHECK_E500_OPTIONS;
2494 rs6000_always_hint = (rs6000_cpu != PROCESSOR_POWER4
2495 && rs6000_cpu != PROCESSOR_POWER5
2496 && rs6000_cpu != PROCESSOR_POWER6
2497 && rs6000_cpu != PROCESSOR_POWER7
2498 && rs6000_cpu != PROCESSOR_CELL);
2499 rs6000_sched_groups = (rs6000_cpu == PROCESSOR_POWER4
2500 || rs6000_cpu == PROCESSOR_POWER5
2501 || rs6000_cpu == PROCESSOR_POWER7);
2502 rs6000_align_branch_targets = (rs6000_cpu == PROCESSOR_POWER4
2503 || rs6000_cpu == PROCESSOR_POWER5
2504 || rs6000_cpu == PROCESSOR_POWER6
2505 || rs6000_cpu == PROCESSOR_POWER7);
2507 /* Allow debug switches to override the above settings. */
2508 if (TARGET_ALWAYS_HINT > 0)
2509 rs6000_always_hint = TARGET_ALWAYS_HINT;
2511 if (TARGET_SCHED_GROUPS > 0)
2512 rs6000_sched_groups = TARGET_SCHED_GROUPS;
2514 if (TARGET_ALIGN_BRANCH_TARGETS > 0)
2515 rs6000_align_branch_targets = TARGET_ALIGN_BRANCH_TARGETS;
2517 rs6000_sched_restricted_insns_priority
2518 = (rs6000_sched_groups ? 1 : 0);
2520 /* Handle -msched-costly-dep option. */
2521 rs6000_sched_costly_dep
2522 = (rs6000_sched_groups ? store_to_load_dep_costly : no_dep_costly);
2524 if (rs6000_sched_costly_dep_str)
2526 if (! strcmp (rs6000_sched_costly_dep_str, "no"))
2527 rs6000_sched_costly_dep = no_dep_costly;
2528 else if (! strcmp (rs6000_sched_costly_dep_str, "all"))
2529 rs6000_sched_costly_dep = all_deps_costly;
2530 else if (! strcmp (rs6000_sched_costly_dep_str, "true_store_to_load"))
2531 rs6000_sched_costly_dep = true_store_to_load_dep_costly;
2532 else if (! strcmp (rs6000_sched_costly_dep_str, "store_to_load"))
2533 rs6000_sched_costly_dep = store_to_load_dep_costly;
2534 else
2535 rs6000_sched_costly_dep = ((enum rs6000_dependence_cost)
2536 atoi (rs6000_sched_costly_dep_str));
2539 /* Handle -minsert-sched-nops option. */
2540 rs6000_sched_insert_nops
2541 = (rs6000_sched_groups ? sched_finish_regroup_exact : sched_finish_none);
2543 if (rs6000_sched_insert_nops_str)
2545 if (! strcmp (rs6000_sched_insert_nops_str, "no"))
2546 rs6000_sched_insert_nops = sched_finish_none;
2547 else if (! strcmp (rs6000_sched_insert_nops_str, "pad"))
2548 rs6000_sched_insert_nops = sched_finish_pad_groups;
2549 else if (! strcmp (rs6000_sched_insert_nops_str, "regroup_exact"))
2550 rs6000_sched_insert_nops = sched_finish_regroup_exact;
2551 else
2552 rs6000_sched_insert_nops = ((enum rs6000_nop_insertion)
2553 atoi (rs6000_sched_insert_nops_str));
2556 #ifdef TARGET_REGNAMES
2557 /* If the user desires alternate register names, copy in the
2558 alternate names now. */
2559 if (TARGET_REGNAMES)
2560 memcpy (rs6000_reg_names, alt_reg_names, sizeof (rs6000_reg_names));
2561 #endif
2563 /* Set aix_struct_return last, after the ABI is determined.
2564 If -maix-struct-return or -msvr4-struct-return was explicitly
2565 used, don't override with the ABI default. */
2566 if (!rs6000_explicit_options.aix_struct_ret)
2567 aix_struct_return = (DEFAULT_ABI != ABI_V4 || DRAFT_V4_STRUCT_RET);
2569 if (TARGET_LONG_DOUBLE_128 && !TARGET_IEEEQUAD)
2570 REAL_MODE_FORMAT (TFmode) = &ibm_extended_format;
2572 if (TARGET_TOC)
2573 ASM_GENERATE_INTERNAL_LABEL (toc_label_name, "LCTOC", 1);
2575 /* We can only guarantee the availability of DI pseudo-ops when
2576 assembling for 64-bit targets. */
2577 if (!TARGET_64BIT)
2579 targetm.asm_out.aligned_op.di = NULL;
2580 targetm.asm_out.unaligned_op.di = NULL;
2583 /* Set branch target alignment, if not optimizing for size. */
2584 if (!optimize_size)
2586 /* Cell wants to be aligned 8byte for dual issue. */
2587 if (rs6000_cpu == PROCESSOR_CELL)
2589 if (align_functions <= 0)
2590 align_functions = 8;
2591 if (align_jumps <= 0)
2592 align_jumps = 8;
2593 if (align_loops <= 0)
2594 align_loops = 8;
2596 if (rs6000_align_branch_targets)
2598 if (align_functions <= 0)
2599 align_functions = 16;
2600 if (align_jumps <= 0)
2601 align_jumps = 16;
2602 if (align_loops <= 0)
2603 align_loops = 16;
2605 if (align_jumps_max_skip <= 0)
2606 align_jumps_max_skip = 15;
2607 if (align_loops_max_skip <= 0)
2608 align_loops_max_skip = 15;
2611 /* Arrange to save and restore machine status around nested functions. */
2612 init_machine_status = rs6000_init_machine_status;
2614 /* We should always be splitting complex arguments, but we can't break
2615 Linux and Darwin ABIs at the moment. For now, only AIX is fixed. */
2616 if (DEFAULT_ABI != ABI_AIX)
2617 targetm.calls.split_complex_arg = NULL;
2619 /* Initialize rs6000_cost with the appropriate target costs. */
2620 if (optimize_size)
2621 rs6000_cost = TARGET_POWERPC64 ? &size64_cost : &size32_cost;
2622 else
2623 switch (rs6000_cpu)
2625 case PROCESSOR_RIOS1:
2626 rs6000_cost = &rios1_cost;
2627 break;
2629 case PROCESSOR_RIOS2:
2630 rs6000_cost = &rios2_cost;
2631 break;
2633 case PROCESSOR_RS64A:
2634 rs6000_cost = &rs64a_cost;
2635 break;
2637 case PROCESSOR_MPCCORE:
2638 rs6000_cost = &mpccore_cost;
2639 break;
2641 case PROCESSOR_PPC403:
2642 rs6000_cost = &ppc403_cost;
2643 break;
2645 case PROCESSOR_PPC405:
2646 rs6000_cost = &ppc405_cost;
2647 break;
2649 case PROCESSOR_PPC440:
2650 rs6000_cost = &ppc440_cost;
2651 break;
2653 case PROCESSOR_PPC601:
2654 rs6000_cost = &ppc601_cost;
2655 break;
2657 case PROCESSOR_PPC603:
2658 rs6000_cost = &ppc603_cost;
2659 break;
2661 case PROCESSOR_PPC604:
2662 rs6000_cost = &ppc604_cost;
2663 break;
2665 case PROCESSOR_PPC604e:
2666 rs6000_cost = &ppc604e_cost;
2667 break;
2669 case PROCESSOR_PPC620:
2670 rs6000_cost = &ppc620_cost;
2671 break;
2673 case PROCESSOR_PPC630:
2674 rs6000_cost = &ppc630_cost;
2675 break;
2677 case PROCESSOR_CELL:
2678 rs6000_cost = &ppccell_cost;
2679 break;
2681 case PROCESSOR_PPC750:
2682 case PROCESSOR_PPC7400:
2683 rs6000_cost = &ppc750_cost;
2684 break;
2686 case PROCESSOR_PPC7450:
2687 rs6000_cost = &ppc7450_cost;
2688 break;
2690 case PROCESSOR_PPC8540:
2691 rs6000_cost = &ppc8540_cost;
2692 break;
2694 case PROCESSOR_PPCE300C2:
2695 case PROCESSOR_PPCE300C3:
2696 rs6000_cost = &ppce300c2c3_cost;
2697 break;
2699 case PROCESSOR_PPCE500MC:
2700 rs6000_cost = &ppce500mc_cost;
2701 break;
2703 case PROCESSOR_POWER4:
2704 case PROCESSOR_POWER5:
2705 rs6000_cost = &power4_cost;
2706 break;
2708 case PROCESSOR_POWER6:
2709 rs6000_cost = &power6_cost;
2710 break;
2712 case PROCESSOR_POWER7:
2713 rs6000_cost = &power7_cost;
2714 break;
2716 default:
2717 gcc_unreachable ();
2720 if (!PARAM_SET_P (PARAM_SIMULTANEOUS_PREFETCHES))
2721 set_param_value ("simultaneous-prefetches",
2722 rs6000_cost->simultaneous_prefetches);
2723 if (!PARAM_SET_P (PARAM_L1_CACHE_SIZE))
2724 set_param_value ("l1-cache-size", rs6000_cost->l1_cache_size);
2725 if (!PARAM_SET_P (PARAM_L1_CACHE_LINE_SIZE))
2726 set_param_value ("l1-cache-line-size", rs6000_cost->cache_line_size);
2727 if (!PARAM_SET_P (PARAM_L2_CACHE_SIZE))
2728 set_param_value ("l2-cache-size", rs6000_cost->l2_cache_size);
2730 /* If using typedef char *va_list, signal that __builtin_va_start (&ap, 0)
2731 can be optimized to ap = __builtin_next_arg (0). */
2732 if (DEFAULT_ABI != ABI_V4)
2733 targetm.expand_builtin_va_start = NULL;
2735 /* Set up single/double float flags.
2736 If TARGET_HARD_FLOAT is set, but neither single or double is set,
2737 then set both flags. */
2738 if (TARGET_HARD_FLOAT && TARGET_FPRS
2739 && rs6000_single_float == 0 && rs6000_double_float == 0)
2740 rs6000_single_float = rs6000_double_float = 1;
2742 /* Reset single and double FP flags if target is E500. */
2743 if (TARGET_E500)
2745 rs6000_single_float = rs6000_double_float = 0;
2746 if (TARGET_E500_SINGLE)
2747 rs6000_single_float = 1;
2748 if (TARGET_E500_DOUBLE)
2749 rs6000_single_float = rs6000_double_float = 1;
2752 /* If not explicitly specified via option, decide whether to generate indexed
2753 load/store instructions. */
2754 if (TARGET_AVOID_XFORM == -1)
2755 /* Avoid indexed addressing when targeting Power6 in order to avoid
2756 the DERAT mispredict penalty. */
2757 TARGET_AVOID_XFORM = (rs6000_cpu == PROCESSOR_POWER6 && TARGET_CMPB);
2759 rs6000_init_hard_regno_mode_ok ();
2762 /* Implement targetm.vectorize.builtin_mask_for_load. */
2763 static tree
2764 rs6000_builtin_mask_for_load (void)
2766 if (TARGET_ALTIVEC || TARGET_VSX)
2767 return altivec_builtin_mask_for_load;
2768 else
2769 return 0;
2772 /* Implement targetm.vectorize.builtin_conversion.
2773 Returns a decl of a function that implements conversion of an integer vector
2774 into a floating-point vector, or vice-versa. TYPE is the type of the integer
2775 side of the conversion.
2776 Return NULL_TREE if it is not available. */
2777 static tree
2778 rs6000_builtin_conversion (unsigned int tcode, tree type)
2780 enum tree_code code = (enum tree_code) tcode;
2782 switch (code)
2784 case FIX_TRUNC_EXPR:
2785 switch (TYPE_MODE (type))
2787 case V2DImode:
2788 if (!VECTOR_UNIT_VSX_P (V2DFmode))
2789 return NULL_TREE;
2791 return TYPE_UNSIGNED (type)
2792 ? rs6000_builtin_decls[VSX_BUILTIN_XVCVDPUXDS_UNS]
2793 : rs6000_builtin_decls[VSX_BUILTIN_XVCVDPSXDS];
2795 case V4SImode:
2796 if (VECTOR_UNIT_NONE_P (V4SImode) || VECTOR_UNIT_NONE_P (V4SFmode))
2797 return NULL_TREE;
2799 return TYPE_UNSIGNED (type)
2800 ? rs6000_builtin_decls[VECTOR_BUILTIN_FIXUNS_V4SF_V4SI]
2801 : rs6000_builtin_decls[VECTOR_BUILTIN_FIX_V4SF_V4SI];
2803 default:
2804 return NULL_TREE;
2807 case FLOAT_EXPR:
2808 switch (TYPE_MODE (type))
2810 case V2DImode:
2811 if (!VECTOR_UNIT_VSX_P (V2DFmode))
2812 return NULL_TREE;
2814 return TYPE_UNSIGNED (type)
2815 ? rs6000_builtin_decls[VSX_BUILTIN_XVCVUXDDP]
2816 : rs6000_builtin_decls[VSX_BUILTIN_XVCVSXDDP];
2818 case V4SImode:
2819 if (VECTOR_UNIT_NONE_P (V4SImode) || VECTOR_UNIT_NONE_P (V4SFmode))
2820 return NULL_TREE;
2822 return TYPE_UNSIGNED (type)
2823 ? rs6000_builtin_decls[VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF]
2824 : rs6000_builtin_decls[VECTOR_BUILTIN_FLOAT_V4SI_V4SF];
2826 default:
2827 return NULL_TREE;
2830 default:
2831 return NULL_TREE;
2835 /* Implement targetm.vectorize.builtin_mul_widen_even. */
2836 static tree
2837 rs6000_builtin_mul_widen_even (tree type)
2839 if (!TARGET_ALTIVEC)
2840 return NULL_TREE;
2842 switch (TYPE_MODE (type))
2844 case V8HImode:
2845 return TYPE_UNSIGNED (type)
2846 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULEUH_UNS]
2847 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULESH];
2849 case V16QImode:
2850 return TYPE_UNSIGNED (type)
2851 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULEUB_UNS]
2852 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULESB];
2853 default:
2854 return NULL_TREE;
2858 /* Implement targetm.vectorize.builtin_mul_widen_odd. */
2859 static tree
2860 rs6000_builtin_mul_widen_odd (tree type)
2862 if (!TARGET_ALTIVEC)
2863 return NULL_TREE;
2865 switch (TYPE_MODE (type))
2867 case V8HImode:
2868 return TYPE_UNSIGNED (type)
2869 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOUH_UNS]
2870 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOSH];
2872 case V16QImode:
2873 return TYPE_UNSIGNED (type)
2874 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOUB_UNS]
2875 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOSB];
2876 default:
2877 return NULL_TREE;
2882 /* Return true iff, data reference of TYPE can reach vector alignment (16)
2883 after applying N number of iterations. This routine does not determine
2884 how may iterations are required to reach desired alignment. */
2886 static bool
2887 rs6000_vector_alignment_reachable (const_tree type ATTRIBUTE_UNUSED, bool is_packed)
2889 if (is_packed)
2890 return false;
2892 if (TARGET_32BIT)
2894 if (rs6000_alignment_flags == MASK_ALIGN_NATURAL)
2895 return true;
2897 if (rs6000_alignment_flags == MASK_ALIGN_POWER)
2898 return true;
2900 return false;
2902 else
2904 if (TARGET_MACHO)
2905 return false;
2907 /* Assuming that all other types are naturally aligned. CHECKME! */
2908 return true;
2912 /* Return true if the vector misalignment factor is supported by the
2913 target. */
2914 bool
2915 rs6000_builtin_support_vector_misalignment (enum machine_mode mode,
2916 const_tree type,
2917 int misalignment,
2918 bool is_packed)
2920 if (TARGET_VSX)
2922 /* Return if movmisalign pattern is not supported for this mode. */
2923 if (optab_handler (movmisalign_optab, mode)->insn_code ==
2924 CODE_FOR_nothing)
2925 return false;
2927 if (misalignment == -1)
2929 /* misalignment factor is unknown at compile time but we know
2930 it's word aligned. */
2931 if (rs6000_vector_alignment_reachable (type, is_packed))
2932 return true;
2933 return false;
2935 /* VSX supports word-aligned vector. */
2936 if (misalignment % 4 == 0)
2937 return true;
2939 return false;
2942 /* Implement targetm.vectorize.builtin_vec_perm. */
2943 tree
2944 rs6000_builtin_vec_perm (tree type, tree *mask_element_type)
2946 tree inner_type = TREE_TYPE (type);
2947 bool uns_p = TYPE_UNSIGNED (inner_type);
2948 tree d;
2950 *mask_element_type = unsigned_char_type_node;
2952 switch (TYPE_MODE (type))
2954 case V16QImode:
2955 d = (uns_p
2956 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_16QI_UNS]
2957 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_16QI]);
2958 break;
2960 case V8HImode:
2961 d = (uns_p
2962 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_8HI_UNS]
2963 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_8HI]);
2964 break;
2966 case V4SImode:
2967 d = (uns_p
2968 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SI_UNS]
2969 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SI]);
2970 break;
2972 case V4SFmode:
2973 d = rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SF];
2974 break;
2976 case V2DFmode:
2977 if (!TARGET_ALLOW_DF_PERMUTE)
2978 return NULL_TREE;
2980 d = rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DF];
2981 break;
2983 case V2DImode:
2984 if (!TARGET_ALLOW_DF_PERMUTE)
2985 return NULL_TREE;
2987 d = (uns_p
2988 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DI_UNS]
2989 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DI]);
2990 break;
2992 default:
2993 return NULL_TREE;
2996 gcc_assert (d);
2997 return d;
3000 /* Handle generic options of the form -mfoo=yes/no.
3001 NAME is the option name.
3002 VALUE is the option value.
3003 FLAG is the pointer to the flag where to store a 1 or 0, depending on
3004 whether the option value is 'yes' or 'no' respectively. */
3005 static void
3006 rs6000_parse_yes_no_option (const char *name, const char *value, int *flag)
3008 if (value == 0)
3009 return;
3010 else if (!strcmp (value, "yes"))
3011 *flag = 1;
3012 else if (!strcmp (value, "no"))
3013 *flag = 0;
3014 else
3015 error ("unknown -m%s= option specified: '%s'", name, value);
3018 /* Validate and record the size specified with the -mtls-size option. */
3020 static void
3021 rs6000_parse_tls_size_option (void)
3023 if (rs6000_tls_size_string == 0)
3024 return;
3025 else if (strcmp (rs6000_tls_size_string, "16") == 0)
3026 rs6000_tls_size = 16;
3027 else if (strcmp (rs6000_tls_size_string, "32") == 0)
3028 rs6000_tls_size = 32;
3029 else if (strcmp (rs6000_tls_size_string, "64") == 0)
3030 rs6000_tls_size = 64;
3031 else
3032 error ("bad value %qs for -mtls-size switch", rs6000_tls_size_string);
3035 void
3036 optimization_options (int level ATTRIBUTE_UNUSED, int size ATTRIBUTE_UNUSED)
3038 if (DEFAULT_ABI == ABI_DARWIN)
3039 /* The Darwin libraries never set errno, so we might as well
3040 avoid calling them when that's the only reason we would. */
3041 flag_errno_math = 0;
3043 /* Double growth factor to counter reduced min jump length. */
3044 set_param_value ("max-grow-copy-bb-insns", 16);
3046 /* Enable section anchors by default.
3047 Skip section anchors for Objective C and Objective C++
3048 until front-ends fixed. */
3049 if (!TARGET_MACHO && lang_hooks.name[4] != 'O')
3050 flag_section_anchors = 2;
3053 static enum fpu_type_t
3054 rs6000_parse_fpu_option (const char *option)
3056 if (!strcmp("none", option)) return FPU_NONE;
3057 if (!strcmp("sp_lite", option)) return FPU_SF_LITE;
3058 if (!strcmp("dp_lite", option)) return FPU_DF_LITE;
3059 if (!strcmp("sp_full", option)) return FPU_SF_FULL;
3060 if (!strcmp("dp_full", option)) return FPU_DF_FULL;
3061 error("unknown value %s for -mfpu", option);
3062 return FPU_NONE;
3065 /* Returns a function decl for a vectorized version of the builtin function
3066 with builtin function code FN and the result vector type TYPE, or NULL_TREE
3067 if it is not available. */
3069 static tree
3070 rs6000_builtin_vectorized_function (unsigned int fn, tree type_out,
3071 tree type_in)
3073 enum machine_mode in_mode, out_mode;
3074 int in_n, out_n;
3076 if (TREE_CODE (type_out) != VECTOR_TYPE
3077 || TREE_CODE (type_in) != VECTOR_TYPE
3078 || !TARGET_VECTORIZE_BUILTINS)
3079 return NULL_TREE;
3081 out_mode = TYPE_MODE (TREE_TYPE (type_out));
3082 out_n = TYPE_VECTOR_SUBPARTS (type_out);
3083 in_mode = TYPE_MODE (TREE_TYPE (type_in));
3084 in_n = TYPE_VECTOR_SUBPARTS (type_in);
3086 switch (fn)
3088 case BUILT_IN_COPYSIGN:
3089 if (VECTOR_UNIT_VSX_P (V2DFmode)
3090 && out_mode == DFmode && out_n == 2
3091 && in_mode == DFmode && in_n == 2)
3092 return rs6000_builtin_decls[VSX_BUILTIN_CPSGNDP];
3093 break;
3094 case BUILT_IN_COPYSIGNF:
3095 if (out_mode != SFmode || out_n != 4
3096 || in_mode != SFmode || in_n != 4)
3097 break;
3098 if (VECTOR_UNIT_VSX_P (V4SFmode))
3099 return rs6000_builtin_decls[VSX_BUILTIN_CPSGNSP];
3100 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3101 return rs6000_builtin_decls[ALTIVEC_BUILTIN_COPYSIGN_V4SF];
3102 break;
3103 case BUILT_IN_SQRT:
3104 if (VECTOR_UNIT_VSX_P (V2DFmode)
3105 && out_mode == DFmode && out_n == 2
3106 && in_mode == DFmode && in_n == 2)
3107 return rs6000_builtin_decls[VSX_BUILTIN_XVSQRTDP];
3108 break;
3109 case BUILT_IN_SQRTF:
3110 if (VECTOR_UNIT_VSX_P (V4SFmode)
3111 && out_mode == SFmode && out_n == 4
3112 && in_mode == SFmode && in_n == 4)
3113 return rs6000_builtin_decls[VSX_BUILTIN_XVSQRTSP];
3114 break;
3115 case BUILT_IN_CEIL:
3116 if (VECTOR_UNIT_VSX_P (V2DFmode)
3117 && out_mode == DFmode && out_n == 2
3118 && in_mode == DFmode && in_n == 2)
3119 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIP];
3120 break;
3121 case BUILT_IN_CEILF:
3122 if (out_mode != SFmode || out_n != 4
3123 || in_mode != SFmode || in_n != 4)
3124 break;
3125 if (VECTOR_UNIT_VSX_P (V4SFmode))
3126 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIP];
3127 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3128 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIP];
3129 break;
3130 case BUILT_IN_FLOOR:
3131 if (VECTOR_UNIT_VSX_P (V2DFmode)
3132 && out_mode == DFmode && out_n == 2
3133 && in_mode == DFmode && in_n == 2)
3134 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIM];
3135 break;
3136 case BUILT_IN_FLOORF:
3137 if (out_mode != SFmode || out_n != 4
3138 || in_mode != SFmode || in_n != 4)
3139 break;
3140 if (VECTOR_UNIT_VSX_P (V4SFmode))
3141 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIM];
3142 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3143 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIM];
3144 break;
3145 case BUILT_IN_TRUNC:
3146 if (VECTOR_UNIT_VSX_P (V2DFmode)
3147 && out_mode == DFmode && out_n == 2
3148 && in_mode == DFmode && in_n == 2)
3149 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIZ];
3150 break;
3151 case BUILT_IN_TRUNCF:
3152 if (out_mode != SFmode || out_n != 4
3153 || in_mode != SFmode || in_n != 4)
3154 break;
3155 if (VECTOR_UNIT_VSX_P (V4SFmode))
3156 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIZ];
3157 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3158 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIZ];
3159 break;
3160 case BUILT_IN_NEARBYINT:
3161 if (VECTOR_UNIT_VSX_P (V2DFmode)
3162 && flag_unsafe_math_optimizations
3163 && out_mode == DFmode && out_n == 2
3164 && in_mode == DFmode && in_n == 2)
3165 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPI];
3166 break;
3167 case BUILT_IN_NEARBYINTF:
3168 if (VECTOR_UNIT_VSX_P (V4SFmode)
3169 && flag_unsafe_math_optimizations
3170 && out_mode == SFmode && out_n == 4
3171 && in_mode == SFmode && in_n == 4)
3172 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPI];
3173 break;
3174 case BUILT_IN_RINT:
3175 if (VECTOR_UNIT_VSX_P (V2DFmode)
3176 && !flag_trapping_math
3177 && out_mode == DFmode && out_n == 2
3178 && in_mode == DFmode && in_n == 2)
3179 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIC];
3180 break;
3181 case BUILT_IN_RINTF:
3182 if (VECTOR_UNIT_VSX_P (V4SFmode)
3183 && !flag_trapping_math
3184 && out_mode == SFmode && out_n == 4
3185 && in_mode == SFmode && in_n == 4)
3186 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIC];
3187 break;
3188 default:
3189 break;
3191 return NULL_TREE;
3195 /* Implement TARGET_HANDLE_OPTION. */
3197 static bool
3198 rs6000_handle_option (size_t code, const char *arg, int value)
3200 enum fpu_type_t fpu_type = FPU_NONE;
3201 int isel;
3203 switch (code)
3205 case OPT_mno_power:
3206 target_flags &= ~(MASK_POWER | MASK_POWER2
3207 | MASK_MULTIPLE | MASK_STRING);
3208 target_flags_explicit |= (MASK_POWER | MASK_POWER2
3209 | MASK_MULTIPLE | MASK_STRING);
3210 break;
3211 case OPT_mno_powerpc:
3212 target_flags &= ~(MASK_POWERPC | MASK_PPC_GPOPT
3213 | MASK_PPC_GFXOPT | MASK_POWERPC64);
3214 target_flags_explicit |= (MASK_POWERPC | MASK_PPC_GPOPT
3215 | MASK_PPC_GFXOPT | MASK_POWERPC64);
3216 break;
3217 case OPT_mfull_toc:
3218 target_flags &= ~MASK_MINIMAL_TOC;
3219 TARGET_NO_FP_IN_TOC = 0;
3220 TARGET_NO_SUM_IN_TOC = 0;
3221 target_flags_explicit |= MASK_MINIMAL_TOC;
3222 #ifdef TARGET_USES_SYSV4_OPT
3223 /* Note, V.4 no longer uses a normal TOC, so make -mfull-toc, be
3224 just the same as -mminimal-toc. */
3225 target_flags |= MASK_MINIMAL_TOC;
3226 target_flags_explicit |= MASK_MINIMAL_TOC;
3227 #endif
3228 break;
3230 #ifdef TARGET_USES_SYSV4_OPT
3231 case OPT_mtoc:
3232 /* Make -mtoc behave like -mminimal-toc. */
3233 target_flags |= MASK_MINIMAL_TOC;
3234 target_flags_explicit |= MASK_MINIMAL_TOC;
3235 break;
3236 #endif
3238 #ifdef TARGET_USES_AIX64_OPT
3239 case OPT_maix64:
3240 #else
3241 case OPT_m64:
3242 #endif
3243 target_flags |= MASK_POWERPC64 | MASK_POWERPC;
3244 target_flags |= ~target_flags_explicit & MASK_PPC_GFXOPT;
3245 target_flags_explicit |= MASK_POWERPC64 | MASK_POWERPC;
3246 break;
3248 #ifdef TARGET_USES_AIX64_OPT
3249 case OPT_maix32:
3250 #else
3251 case OPT_m32:
3252 #endif
3253 target_flags &= ~MASK_POWERPC64;
3254 target_flags_explicit |= MASK_POWERPC64;
3255 break;
3257 case OPT_minsert_sched_nops_:
3258 rs6000_sched_insert_nops_str = arg;
3259 break;
3261 case OPT_mminimal_toc:
3262 if (value == 1)
3264 TARGET_NO_FP_IN_TOC = 0;
3265 TARGET_NO_SUM_IN_TOC = 0;
3267 break;
3269 case OPT_mpower:
3270 if (value == 1)
3272 target_flags |= (MASK_MULTIPLE | MASK_STRING);
3273 target_flags_explicit |= (MASK_MULTIPLE | MASK_STRING);
3275 break;
3277 case OPT_mpower2:
3278 if (value == 1)
3280 target_flags |= (MASK_POWER | MASK_MULTIPLE | MASK_STRING);
3281 target_flags_explicit |= (MASK_POWER | MASK_MULTIPLE | MASK_STRING);
3283 break;
3285 case OPT_mpowerpc_gpopt:
3286 case OPT_mpowerpc_gfxopt:
3287 if (value == 1)
3289 target_flags |= MASK_POWERPC;
3290 target_flags_explicit |= MASK_POWERPC;
3292 break;
3294 case OPT_maix_struct_return:
3295 case OPT_msvr4_struct_return:
3296 rs6000_explicit_options.aix_struct_ret = true;
3297 break;
3299 case OPT_mvrsave:
3300 rs6000_explicit_options.vrsave = true;
3301 TARGET_ALTIVEC_VRSAVE = value;
3302 break;
3304 case OPT_mvrsave_:
3305 rs6000_explicit_options.vrsave = true;
3306 rs6000_parse_yes_no_option ("vrsave", arg, &(TARGET_ALTIVEC_VRSAVE));
3307 break;
3309 case OPT_misel_:
3310 target_flags_explicit |= MASK_ISEL;
3311 isel = 0;
3312 rs6000_parse_yes_no_option ("isel", arg, &isel);
3313 if (isel)
3314 target_flags |= MASK_ISEL;
3315 else
3316 target_flags &= ~MASK_ISEL;
3317 break;
3319 case OPT_mspe:
3320 rs6000_explicit_options.spe = true;
3321 rs6000_spe = value;
3322 break;
3324 case OPT_mspe_:
3325 rs6000_explicit_options.spe = true;
3326 rs6000_parse_yes_no_option ("spe", arg, &(rs6000_spe));
3327 break;
3329 case OPT_mdebug_:
3330 rs6000_debug_name = arg;
3331 break;
3333 #ifdef TARGET_USES_SYSV4_OPT
3334 case OPT_mcall_:
3335 rs6000_abi_name = arg;
3336 break;
3338 case OPT_msdata_:
3339 rs6000_sdata_name = arg;
3340 break;
3342 case OPT_mtls_size_:
3343 rs6000_tls_size_string = arg;
3344 break;
3346 case OPT_mrelocatable:
3347 if (value == 1)
3349 target_flags |= MASK_MINIMAL_TOC;
3350 target_flags_explicit |= MASK_MINIMAL_TOC;
3351 TARGET_NO_FP_IN_TOC = 1;
3353 break;
3355 case OPT_mrelocatable_lib:
3356 if (value == 1)
3358 target_flags |= MASK_RELOCATABLE | MASK_MINIMAL_TOC;
3359 target_flags_explicit |= MASK_RELOCATABLE | MASK_MINIMAL_TOC;
3360 TARGET_NO_FP_IN_TOC = 1;
3362 else
3364 target_flags &= ~MASK_RELOCATABLE;
3365 target_flags_explicit |= MASK_RELOCATABLE;
3367 break;
3368 #endif
3370 case OPT_mabi_:
3371 if (!strcmp (arg, "altivec"))
3373 rs6000_explicit_options.altivec_abi = true;
3374 rs6000_altivec_abi = 1;
3376 /* Enabling the AltiVec ABI turns off the SPE ABI. */
3377 rs6000_spe_abi = 0;
3379 else if (! strcmp (arg, "no-altivec"))
3381 rs6000_explicit_options.altivec_abi = true;
3382 rs6000_altivec_abi = 0;
3384 else if (! strcmp (arg, "spe"))
3386 rs6000_explicit_options.spe_abi = true;
3387 rs6000_spe_abi = 1;
3388 rs6000_altivec_abi = 0;
3389 if (!TARGET_SPE_ABI)
3390 error ("not configured for ABI: '%s'", arg);
3392 else if (! strcmp (arg, "no-spe"))
3394 rs6000_explicit_options.spe_abi = true;
3395 rs6000_spe_abi = 0;
3398 /* These are here for testing during development only, do not
3399 document in the manual please. */
3400 else if (! strcmp (arg, "d64"))
3402 rs6000_darwin64_abi = 1;
3403 warning (0, "Using darwin64 ABI");
3405 else if (! strcmp (arg, "d32"))
3407 rs6000_darwin64_abi = 0;
3408 warning (0, "Using old darwin ABI");
3411 else if (! strcmp (arg, "ibmlongdouble"))
3413 rs6000_explicit_options.ieee = true;
3414 rs6000_ieeequad = 0;
3415 warning (0, "Using IBM extended precision long double");
3417 else if (! strcmp (arg, "ieeelongdouble"))
3419 rs6000_explicit_options.ieee = true;
3420 rs6000_ieeequad = 1;
3421 warning (0, "Using IEEE extended precision long double");
3424 else
3426 error ("unknown ABI specified: '%s'", arg);
3427 return false;
3429 break;
3431 case OPT_mcpu_:
3432 rs6000_select[1].string = arg;
3433 break;
3435 case OPT_mtune_:
3436 rs6000_select[2].string = arg;
3437 break;
3439 case OPT_mtraceback_:
3440 rs6000_traceback_name = arg;
3441 break;
3443 case OPT_mfloat_gprs_:
3444 rs6000_explicit_options.float_gprs = true;
3445 if (! strcmp (arg, "yes") || ! strcmp (arg, "single"))
3446 rs6000_float_gprs = 1;
3447 else if (! strcmp (arg, "double"))
3448 rs6000_float_gprs = 2;
3449 else if (! strcmp (arg, "no"))
3450 rs6000_float_gprs = 0;
3451 else
3453 error ("invalid option for -mfloat-gprs: '%s'", arg);
3454 return false;
3456 break;
3458 case OPT_mlong_double_:
3459 rs6000_explicit_options.long_double = true;
3460 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
3461 if (value != 64 && value != 128)
3463 error ("Unknown switch -mlong-double-%s", arg);
3464 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
3465 return false;
3467 else
3468 rs6000_long_double_type_size = value;
3469 break;
3471 case OPT_msched_costly_dep_:
3472 rs6000_sched_costly_dep_str = arg;
3473 break;
3475 case OPT_malign_:
3476 rs6000_explicit_options.alignment = true;
3477 if (! strcmp (arg, "power"))
3479 /* On 64-bit Darwin, power alignment is ABI-incompatible with
3480 some C library functions, so warn about it. The flag may be
3481 useful for performance studies from time to time though, so
3482 don't disable it entirely. */
3483 if (DEFAULT_ABI == ABI_DARWIN && TARGET_64BIT)
3484 warning (0, "-malign-power is not supported for 64-bit Darwin;"
3485 " it is incompatible with the installed C and C++ libraries");
3486 rs6000_alignment_flags = MASK_ALIGN_POWER;
3488 else if (! strcmp (arg, "natural"))
3489 rs6000_alignment_flags = MASK_ALIGN_NATURAL;
3490 else
3492 error ("unknown -malign-XXXXX option specified: '%s'", arg);
3493 return false;
3495 break;
3497 case OPT_msingle_float:
3498 if (!TARGET_SINGLE_FPU)
3499 warning (0, "-msingle-float option equivalent to -mhard-float");
3500 /* -msingle-float implies -mno-double-float and TARGET_HARD_FLOAT. */
3501 rs6000_double_float = 0;
3502 target_flags &= ~MASK_SOFT_FLOAT;
3503 target_flags_explicit |= MASK_SOFT_FLOAT;
3504 break;
3506 case OPT_mdouble_float:
3507 /* -mdouble-float implies -msingle-float and TARGET_HARD_FLOAT. */
3508 rs6000_single_float = 1;
3509 target_flags &= ~MASK_SOFT_FLOAT;
3510 target_flags_explicit |= MASK_SOFT_FLOAT;
3511 break;
3513 case OPT_msimple_fpu:
3514 if (!TARGET_SINGLE_FPU)
3515 warning (0, "-msimple-fpu option ignored");
3516 break;
3518 case OPT_mhard_float:
3519 /* -mhard_float implies -msingle-float and -mdouble-float. */
3520 rs6000_single_float = rs6000_double_float = 1;
3521 break;
3523 case OPT_msoft_float:
3524 /* -msoft_float implies -mnosingle-float and -mnodouble-float. */
3525 rs6000_single_float = rs6000_double_float = 0;
3526 break;
3528 case OPT_mfpu_:
3529 fpu_type = rs6000_parse_fpu_option(arg);
3530 if (fpu_type != FPU_NONE)
3531 /* If -mfpu is not none, then turn off SOFT_FLOAT, turn on HARD_FLOAT. */
3533 target_flags &= ~MASK_SOFT_FLOAT;
3534 target_flags_explicit |= MASK_SOFT_FLOAT;
3535 rs6000_xilinx_fpu = 1;
3536 if (fpu_type == FPU_SF_LITE || fpu_type == FPU_SF_FULL)
3537 rs6000_single_float = 1;
3538 if (fpu_type == FPU_DF_LITE || fpu_type == FPU_DF_FULL)
3539 rs6000_single_float = rs6000_double_float = 1;
3540 if (fpu_type == FPU_SF_LITE || fpu_type == FPU_DF_LITE)
3541 rs6000_simple_fpu = 1;
3543 else
3545 /* -mfpu=none is equivalent to -msoft-float */
3546 target_flags |= MASK_SOFT_FLOAT;
3547 target_flags_explicit |= MASK_SOFT_FLOAT;
3548 rs6000_single_float = rs6000_double_float = 0;
3550 break;
3552 return true;
3555 /* Do anything needed at the start of the asm file. */
3557 static void
3558 rs6000_file_start (void)
3560 size_t i;
3561 char buffer[80];
3562 const char *start = buffer;
3563 struct rs6000_cpu_select *ptr;
3564 const char *default_cpu = TARGET_CPU_DEFAULT;
3565 FILE *file = asm_out_file;
3567 default_file_start ();
3569 #ifdef TARGET_BI_ARCH
3570 if ((TARGET_DEFAULT ^ target_flags) & MASK_64BIT)
3571 default_cpu = 0;
3572 #endif
3574 if (flag_verbose_asm)
3576 sprintf (buffer, "\n%s rs6000/powerpc options:", ASM_COMMENT_START);
3577 rs6000_select[0].string = default_cpu;
3579 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
3581 ptr = &rs6000_select[i];
3582 if (ptr->string != (char *)0 && ptr->string[0] != '\0')
3584 fprintf (file, "%s %s%s", start, ptr->name, ptr->string);
3585 start = "";
3589 if (PPC405_ERRATUM77)
3591 fprintf (file, "%s PPC405CR_ERRATUM77", start);
3592 start = "";
3595 #ifdef USING_ELFOS_H
3596 switch (rs6000_sdata)
3598 case SDATA_NONE: fprintf (file, "%s -msdata=none", start); start = ""; break;
3599 case SDATA_DATA: fprintf (file, "%s -msdata=data", start); start = ""; break;
3600 case SDATA_SYSV: fprintf (file, "%s -msdata=sysv", start); start = ""; break;
3601 case SDATA_EABI: fprintf (file, "%s -msdata=eabi", start); start = ""; break;
3604 if (rs6000_sdata && g_switch_value)
3606 fprintf (file, "%s -G " HOST_WIDE_INT_PRINT_UNSIGNED, start,
3607 g_switch_value);
3608 start = "";
3610 #endif
3612 if (*start == '\0')
3613 putc ('\n', file);
3616 #ifdef HAVE_AS_GNU_ATTRIBUTE
3617 if (TARGET_32BIT && DEFAULT_ABI == ABI_V4)
3619 fprintf (file, "\t.gnu_attribute 4, %d\n",
3620 ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT) ? 1
3621 : (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT) ? 3
3622 : 2));
3623 fprintf (file, "\t.gnu_attribute 8, %d\n",
3624 (TARGET_ALTIVEC_ABI ? 2
3625 : TARGET_SPE_ABI ? 3
3626 : 1));
3627 fprintf (file, "\t.gnu_attribute 12, %d\n",
3628 aix_struct_return ? 2 : 1);
3631 #endif
3633 if (DEFAULT_ABI == ABI_AIX || (TARGET_ELF && flag_pic == 2))
3635 switch_to_section (toc_section);
3636 switch_to_section (text_section);
3641 /* Return nonzero if this function is known to have a null epilogue. */
3644 direct_return (void)
3646 if (reload_completed)
3648 rs6000_stack_t *info = rs6000_stack_info ();
3650 if (info->first_gp_reg_save == 32
3651 && info->first_fp_reg_save == 64
3652 && info->first_altivec_reg_save == LAST_ALTIVEC_REGNO + 1
3653 && ! info->lr_save_p
3654 && ! info->cr_save_p
3655 && info->vrsave_mask == 0
3656 && ! info->push_p)
3657 return 1;
3660 return 0;
3663 /* Return the number of instructions it takes to form a constant in an
3664 integer register. */
3667 num_insns_constant_wide (HOST_WIDE_INT value)
3669 /* signed constant loadable with {cal|addi} */
3670 if ((unsigned HOST_WIDE_INT) (value + 0x8000) < 0x10000)
3671 return 1;
3673 /* constant loadable with {cau|addis} */
3674 else if ((value & 0xffff) == 0
3675 && (value >> 31 == -1 || value >> 31 == 0))
3676 return 1;
3678 #if HOST_BITS_PER_WIDE_INT == 64
3679 else if (TARGET_POWERPC64)
3681 HOST_WIDE_INT low = ((value & 0xffffffff) ^ 0x80000000) - 0x80000000;
3682 HOST_WIDE_INT high = value >> 31;
3684 if (high == 0 || high == -1)
3685 return 2;
3687 high >>= 1;
3689 if (low == 0)
3690 return num_insns_constant_wide (high) + 1;
3691 else
3692 return (num_insns_constant_wide (high)
3693 + num_insns_constant_wide (low) + 1);
3695 #endif
3697 else
3698 return 2;
3702 num_insns_constant (rtx op, enum machine_mode mode)
3704 HOST_WIDE_INT low, high;
3706 switch (GET_CODE (op))
3708 case CONST_INT:
3709 #if HOST_BITS_PER_WIDE_INT == 64
3710 if ((INTVAL (op) >> 31) != 0 && (INTVAL (op) >> 31) != -1
3711 && mask64_operand (op, mode))
3712 return 2;
3713 else
3714 #endif
3715 return num_insns_constant_wide (INTVAL (op));
3717 case CONST_DOUBLE:
3718 if (mode == SFmode || mode == SDmode)
3720 long l;
3721 REAL_VALUE_TYPE rv;
3723 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
3724 if (DECIMAL_FLOAT_MODE_P (mode))
3725 REAL_VALUE_TO_TARGET_DECIMAL32 (rv, l);
3726 else
3727 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
3728 return num_insns_constant_wide ((HOST_WIDE_INT) l);
3731 if (mode == VOIDmode || mode == DImode)
3733 high = CONST_DOUBLE_HIGH (op);
3734 low = CONST_DOUBLE_LOW (op);
3736 else
3738 long l[2];
3739 REAL_VALUE_TYPE rv;
3741 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
3742 if (DECIMAL_FLOAT_MODE_P (mode))
3743 REAL_VALUE_TO_TARGET_DECIMAL64 (rv, l);
3744 else
3745 REAL_VALUE_TO_TARGET_DOUBLE (rv, l);
3746 high = l[WORDS_BIG_ENDIAN == 0];
3747 low = l[WORDS_BIG_ENDIAN != 0];
3750 if (TARGET_32BIT)
3751 return (num_insns_constant_wide (low)
3752 + num_insns_constant_wide (high));
3753 else
3755 if ((high == 0 && low >= 0)
3756 || (high == -1 && low < 0))
3757 return num_insns_constant_wide (low);
3759 else if (mask64_operand (op, mode))
3760 return 2;
3762 else if (low == 0)
3763 return num_insns_constant_wide (high) + 1;
3765 else
3766 return (num_insns_constant_wide (high)
3767 + num_insns_constant_wide (low) + 1);
3770 default:
3771 gcc_unreachable ();
3775 /* Interpret element ELT of the CONST_VECTOR OP as an integer value.
3776 If the mode of OP is MODE_VECTOR_INT, this simply returns the
3777 corresponding element of the vector, but for V4SFmode and V2SFmode,
3778 the corresponding "float" is interpreted as an SImode integer. */
3780 HOST_WIDE_INT
3781 const_vector_elt_as_int (rtx op, unsigned int elt)
3783 rtx tmp = CONST_VECTOR_ELT (op, elt);
3784 if (GET_MODE (op) == V4SFmode
3785 || GET_MODE (op) == V2SFmode)
3786 tmp = gen_lowpart (SImode, tmp);
3787 return INTVAL (tmp);
3790 /* Return true if OP can be synthesized with a particular vspltisb, vspltish
3791 or vspltisw instruction. OP is a CONST_VECTOR. Which instruction is used
3792 depends on STEP and COPIES, one of which will be 1. If COPIES > 1,
3793 all items are set to the same value and contain COPIES replicas of the
3794 vsplt's operand; if STEP > 1, one in STEP elements is set to the vsplt's
3795 operand and the others are set to the value of the operand's msb. */
3797 static bool
3798 vspltis_constant (rtx op, unsigned step, unsigned copies)
3800 enum machine_mode mode = GET_MODE (op);
3801 enum machine_mode inner = GET_MODE_INNER (mode);
3803 unsigned i;
3804 unsigned nunits = GET_MODE_NUNITS (mode);
3805 unsigned bitsize = GET_MODE_BITSIZE (inner);
3806 unsigned mask = GET_MODE_MASK (inner);
3808 HOST_WIDE_INT val = const_vector_elt_as_int (op, nunits - 1);
3809 HOST_WIDE_INT splat_val = val;
3810 HOST_WIDE_INT msb_val = val > 0 ? 0 : -1;
3812 /* Construct the value to be splatted, if possible. If not, return 0. */
3813 for (i = 2; i <= copies; i *= 2)
3815 HOST_WIDE_INT small_val;
3816 bitsize /= 2;
3817 small_val = splat_val >> bitsize;
3818 mask >>= bitsize;
3819 if (splat_val != ((small_val << bitsize) | (small_val & mask)))
3820 return false;
3821 splat_val = small_val;
3824 /* Check if SPLAT_VAL can really be the operand of a vspltis[bhw]. */
3825 if (EASY_VECTOR_15 (splat_val))
3828 /* Also check if we can splat, and then add the result to itself. Do so if
3829 the value is positive, of if the splat instruction is using OP's mode;
3830 for splat_val < 0, the splat and the add should use the same mode. */
3831 else if (EASY_VECTOR_15_ADD_SELF (splat_val)
3832 && (splat_val >= 0 || (step == 1 && copies == 1)))
3835 /* Also check if are loading up the most significant bit which can be done by
3836 loading up -1 and shifting the value left by -1. */
3837 else if (EASY_VECTOR_MSB (splat_val, inner))
3840 else
3841 return false;
3843 /* Check if VAL is present in every STEP-th element, and the
3844 other elements are filled with its most significant bit. */
3845 for (i = 0; i < nunits - 1; ++i)
3847 HOST_WIDE_INT desired_val;
3848 if (((i + 1) & (step - 1)) == 0)
3849 desired_val = val;
3850 else
3851 desired_val = msb_val;
3853 if (desired_val != const_vector_elt_as_int (op, i))
3854 return false;
3857 return true;
3861 /* Return true if OP is of the given MODE and can be synthesized
3862 with a vspltisb, vspltish or vspltisw. */
3864 bool
3865 easy_altivec_constant (rtx op, enum machine_mode mode)
3867 unsigned step, copies;
3869 if (mode == VOIDmode)
3870 mode = GET_MODE (op);
3871 else if (mode != GET_MODE (op))
3872 return false;
3874 /* Start with a vspltisw. */
3875 step = GET_MODE_NUNITS (mode) / 4;
3876 copies = 1;
3878 if (vspltis_constant (op, step, copies))
3879 return true;
3881 /* Then try with a vspltish. */
3882 if (step == 1)
3883 copies <<= 1;
3884 else
3885 step >>= 1;
3887 if (vspltis_constant (op, step, copies))
3888 return true;
3890 /* And finally a vspltisb. */
3891 if (step == 1)
3892 copies <<= 1;
3893 else
3894 step >>= 1;
3896 if (vspltis_constant (op, step, copies))
3897 return true;
3899 return false;
3902 /* Generate a VEC_DUPLICATE representing a vspltis[bhw] instruction whose
3903 result is OP. Abort if it is not possible. */
3906 gen_easy_altivec_constant (rtx op)
3908 enum machine_mode mode = GET_MODE (op);
3909 int nunits = GET_MODE_NUNITS (mode);
3910 rtx last = CONST_VECTOR_ELT (op, nunits - 1);
3911 unsigned step = nunits / 4;
3912 unsigned copies = 1;
3914 /* Start with a vspltisw. */
3915 if (vspltis_constant (op, step, copies))
3916 return gen_rtx_VEC_DUPLICATE (V4SImode, gen_lowpart (SImode, last));
3918 /* Then try with a vspltish. */
3919 if (step == 1)
3920 copies <<= 1;
3921 else
3922 step >>= 1;
3924 if (vspltis_constant (op, step, copies))
3925 return gen_rtx_VEC_DUPLICATE (V8HImode, gen_lowpart (HImode, last));
3927 /* And finally a vspltisb. */
3928 if (step == 1)
3929 copies <<= 1;
3930 else
3931 step >>= 1;
3933 if (vspltis_constant (op, step, copies))
3934 return gen_rtx_VEC_DUPLICATE (V16QImode, gen_lowpart (QImode, last));
3936 gcc_unreachable ();
3939 const char *
3940 output_vec_const_move (rtx *operands)
3942 int cst, cst2;
3943 enum machine_mode mode;
3944 rtx dest, vec;
3946 dest = operands[0];
3947 vec = operands[1];
3948 mode = GET_MODE (dest);
3950 if (TARGET_VSX && zero_constant (vec, mode))
3951 return "xxlxor %x0,%x0,%x0";
3953 if (TARGET_ALTIVEC)
3955 rtx splat_vec;
3956 if (zero_constant (vec, mode))
3957 return "vxor %0,%0,%0";
3959 splat_vec = gen_easy_altivec_constant (vec);
3960 gcc_assert (GET_CODE (splat_vec) == VEC_DUPLICATE);
3961 operands[1] = XEXP (splat_vec, 0);
3962 if (!EASY_VECTOR_15 (INTVAL (operands[1])))
3963 return "#";
3965 switch (GET_MODE (splat_vec))
3967 case V4SImode:
3968 return "vspltisw %0,%1";
3970 case V8HImode:
3971 return "vspltish %0,%1";
3973 case V16QImode:
3974 return "vspltisb %0,%1";
3976 default:
3977 gcc_unreachable ();
3981 gcc_assert (TARGET_SPE);
3983 /* Vector constant 0 is handled as a splitter of V2SI, and in the
3984 pattern of V1DI, V4HI, and V2SF.
3986 FIXME: We should probably return # and add post reload
3987 splitters for these, but this way is so easy ;-). */
3988 cst = INTVAL (CONST_VECTOR_ELT (vec, 0));
3989 cst2 = INTVAL (CONST_VECTOR_ELT (vec, 1));
3990 operands[1] = CONST_VECTOR_ELT (vec, 0);
3991 operands[2] = CONST_VECTOR_ELT (vec, 1);
3992 if (cst == cst2)
3993 return "li %0,%1\n\tevmergelo %0,%0,%0";
3994 else
3995 return "li %0,%1\n\tevmergelo %0,%0,%0\n\tli %0,%2";
3998 /* Initialize TARGET of vector PAIRED to VALS. */
4000 void
4001 paired_expand_vector_init (rtx target, rtx vals)
4003 enum machine_mode mode = GET_MODE (target);
4004 int n_elts = GET_MODE_NUNITS (mode);
4005 int n_var = 0;
4006 rtx x, new_rtx, tmp, constant_op, op1, op2;
4007 int i;
4009 for (i = 0; i < n_elts; ++i)
4011 x = XVECEXP (vals, 0, i);
4012 if (!CONSTANT_P (x))
4013 ++n_var;
4015 if (n_var == 0)
4017 /* Load from constant pool. */
4018 emit_move_insn (target, gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0)));
4019 return;
4022 if (n_var == 2)
4024 /* The vector is initialized only with non-constants. */
4025 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, XVECEXP (vals, 0, 0),
4026 XVECEXP (vals, 0, 1));
4028 emit_move_insn (target, new_rtx);
4029 return;
4032 /* One field is non-constant and the other one is a constant. Load the
4033 constant from the constant pool and use ps_merge instruction to
4034 construct the whole vector. */
4035 op1 = XVECEXP (vals, 0, 0);
4036 op2 = XVECEXP (vals, 0, 1);
4038 constant_op = (CONSTANT_P (op1)) ? op1 : op2;
4040 tmp = gen_reg_rtx (GET_MODE (constant_op));
4041 emit_move_insn (tmp, constant_op);
4043 if (CONSTANT_P (op1))
4044 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, tmp, op2);
4045 else
4046 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, op1, tmp);
4048 emit_move_insn (target, new_rtx);
4051 void
4052 paired_expand_vector_move (rtx operands[])
4054 rtx op0 = operands[0], op1 = operands[1];
4056 emit_move_insn (op0, op1);
4059 /* Emit vector compare for code RCODE. DEST is destination, OP1 and
4060 OP2 are two VEC_COND_EXPR operands, CC_OP0 and CC_OP1 are the two
4061 operands for the relation operation COND. This is a recursive
4062 function. */
4064 static void
4065 paired_emit_vector_compare (enum rtx_code rcode,
4066 rtx dest, rtx op0, rtx op1,
4067 rtx cc_op0, rtx cc_op1)
4069 rtx tmp = gen_reg_rtx (V2SFmode);
4070 rtx tmp1, max, min, equal_zero;
4072 gcc_assert (TARGET_PAIRED_FLOAT);
4073 gcc_assert (GET_MODE (op0) == GET_MODE (op1));
4075 switch (rcode)
4077 case LT:
4078 case LTU:
4079 paired_emit_vector_compare (GE, dest, op1, op0, cc_op0, cc_op1);
4080 return;
4081 case GE:
4082 case GEU:
4083 emit_insn (gen_subv2sf3 (tmp, cc_op0, cc_op1));
4084 emit_insn (gen_selv2sf4 (dest, tmp, op0, op1, CONST0_RTX (SFmode)));
4085 return;
4086 case LE:
4087 case LEU:
4088 paired_emit_vector_compare (GE, dest, op0, op1, cc_op1, cc_op0);
4089 return;
4090 case GT:
4091 paired_emit_vector_compare (LE, dest, op1, op0, cc_op0, cc_op1);
4092 return;
4093 case EQ:
4094 tmp1 = gen_reg_rtx (V2SFmode);
4095 max = gen_reg_rtx (V2SFmode);
4096 min = gen_reg_rtx (V2SFmode);
4097 equal_zero = gen_reg_rtx (V2SFmode);
4099 emit_insn (gen_subv2sf3 (tmp, cc_op0, cc_op1));
4100 emit_insn (gen_selv2sf4
4101 (max, tmp, cc_op0, cc_op1, CONST0_RTX (SFmode)));
4102 emit_insn (gen_subv2sf3 (tmp, cc_op1, cc_op0));
4103 emit_insn (gen_selv2sf4
4104 (min, tmp, cc_op0, cc_op1, CONST0_RTX (SFmode)));
4105 emit_insn (gen_subv2sf3 (tmp1, min, max));
4106 emit_insn (gen_selv2sf4 (dest, tmp1, op0, op1, CONST0_RTX (SFmode)));
4107 return;
4108 case NE:
4109 paired_emit_vector_compare (EQ, dest, op1, op0, cc_op0, cc_op1);
4110 return;
4111 case UNLE:
4112 paired_emit_vector_compare (LE, dest, op1, op0, cc_op0, cc_op1);
4113 return;
4114 case UNLT:
4115 paired_emit_vector_compare (LT, dest, op1, op0, cc_op0, cc_op1);
4116 return;
4117 case UNGE:
4118 paired_emit_vector_compare (GE, dest, op1, op0, cc_op0, cc_op1);
4119 return;
4120 case UNGT:
4121 paired_emit_vector_compare (GT, dest, op1, op0, cc_op0, cc_op1);
4122 return;
4123 default:
4124 gcc_unreachable ();
4127 return;
4130 /* Emit vector conditional expression.
4131 DEST is destination. OP1 and OP2 are two VEC_COND_EXPR operands.
4132 CC_OP0 and CC_OP1 are the two operands for the relation operation COND. */
4135 paired_emit_vector_cond_expr (rtx dest, rtx op1, rtx op2,
4136 rtx cond, rtx cc_op0, rtx cc_op1)
4138 enum rtx_code rcode = GET_CODE (cond);
4140 if (!TARGET_PAIRED_FLOAT)
4141 return 0;
4143 paired_emit_vector_compare (rcode, dest, op1, op2, cc_op0, cc_op1);
4145 return 1;
4148 /* Initialize vector TARGET to VALS. */
4150 void
4151 rs6000_expand_vector_init (rtx target, rtx vals)
4153 enum machine_mode mode = GET_MODE (target);
4154 enum machine_mode inner_mode = GET_MODE_INNER (mode);
4155 int n_elts = GET_MODE_NUNITS (mode);
4156 int n_var = 0, one_var = -1;
4157 bool all_same = true, all_const_zero = true;
4158 rtx x, mem;
4159 int i;
4161 for (i = 0; i < n_elts; ++i)
4163 x = XVECEXP (vals, 0, i);
4164 if (!CONSTANT_P (x))
4165 ++n_var, one_var = i;
4166 else if (x != CONST0_RTX (inner_mode))
4167 all_const_zero = false;
4169 if (i > 0 && !rtx_equal_p (x, XVECEXP (vals, 0, 0)))
4170 all_same = false;
4173 if (n_var == 0)
4175 rtx const_vec = gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0));
4176 bool int_vector_p = (GET_MODE_CLASS (mode) == MODE_VECTOR_INT);
4177 if ((int_vector_p || TARGET_VSX) && all_const_zero)
4179 /* Zero register. */
4180 emit_insn (gen_rtx_SET (VOIDmode, target,
4181 gen_rtx_XOR (mode, target, target)));
4182 return;
4184 else if (int_vector_p && easy_vector_constant (const_vec, mode))
4186 /* Splat immediate. */
4187 emit_insn (gen_rtx_SET (VOIDmode, target, const_vec));
4188 return;
4190 else
4192 /* Load from constant pool. */
4193 emit_move_insn (target, const_vec);
4194 return;
4198 /* Double word values on VSX can use xxpermdi or lxvdsx. */
4199 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
4201 if (all_same)
4203 rtx element = XVECEXP (vals, 0, 0);
4204 if (mode == V2DFmode)
4205 emit_insn (gen_vsx_splat_v2df (target, element));
4206 else
4207 emit_insn (gen_vsx_splat_v2di (target, element));
4209 else
4211 rtx op0 = copy_to_reg (XVECEXP (vals, 0, 0));
4212 rtx op1 = copy_to_reg (XVECEXP (vals, 0, 1));
4213 if (mode == V2DFmode)
4214 emit_insn (gen_vsx_concat_v2df (target, op0, op1));
4215 else
4216 emit_insn (gen_vsx_concat_v2di (target, op0, op1));
4218 return;
4221 /* With single precision floating point on VSX, know that internally single
4222 precision is actually represented as a double, and either make 2 V2DF
4223 vectors, and convert these vectors to single precision, or do one
4224 conversion, and splat the result to the other elements. */
4225 if (mode == V4SFmode && VECTOR_MEM_VSX_P (mode))
4227 if (all_same)
4229 rtx freg = gen_reg_rtx (V4SFmode);
4230 rtx sreg = copy_to_reg (XVECEXP (vals, 0, 0));
4232 emit_insn (gen_vsx_xscvdpsp_scalar (freg, sreg));
4233 emit_insn (gen_vsx_xxspltw_v4sf (target, freg, const0_rtx));
4235 else
4237 rtx dbl_even = gen_reg_rtx (V2DFmode);
4238 rtx dbl_odd = gen_reg_rtx (V2DFmode);
4239 rtx flt_even = gen_reg_rtx (V4SFmode);
4240 rtx flt_odd = gen_reg_rtx (V4SFmode);
4242 emit_insn (gen_vsx_concat_v2sf (dbl_even,
4243 copy_to_reg (XVECEXP (vals, 0, 0)),
4244 copy_to_reg (XVECEXP (vals, 0, 1))));
4245 emit_insn (gen_vsx_concat_v2sf (dbl_odd,
4246 copy_to_reg (XVECEXP (vals, 0, 2)),
4247 copy_to_reg (XVECEXP (vals, 0, 3))));
4248 emit_insn (gen_vsx_xvcvdpsp (flt_even, dbl_even));
4249 emit_insn (gen_vsx_xvcvdpsp (flt_odd, dbl_odd));
4250 emit_insn (gen_vec_extract_evenv4sf (target, flt_even, flt_odd));
4252 return;
4255 /* Store value to stack temp. Load vector element. Splat. However, splat
4256 of 64-bit items is not supported on Altivec. */
4257 if (all_same && GET_MODE_SIZE (mode) <= 4)
4259 mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0);
4260 emit_move_insn (adjust_address_nv (mem, inner_mode, 0),
4261 XVECEXP (vals, 0, 0));
4262 x = gen_rtx_UNSPEC (VOIDmode,
4263 gen_rtvec (1, const0_rtx), UNSPEC_LVE);
4264 emit_insn (gen_rtx_PARALLEL (VOIDmode,
4265 gen_rtvec (2,
4266 gen_rtx_SET (VOIDmode,
4267 target, mem),
4268 x)));
4269 x = gen_rtx_VEC_SELECT (inner_mode, target,
4270 gen_rtx_PARALLEL (VOIDmode,
4271 gen_rtvec (1, const0_rtx)));
4272 emit_insn (gen_rtx_SET (VOIDmode, target,
4273 gen_rtx_VEC_DUPLICATE (mode, x)));
4274 return;
4277 /* One field is non-constant. Load constant then overwrite
4278 varying field. */
4279 if (n_var == 1)
4281 rtx copy = copy_rtx (vals);
4283 /* Load constant part of vector, substitute neighboring value for
4284 varying element. */
4285 XVECEXP (copy, 0, one_var) = XVECEXP (vals, 0, (one_var + 1) % n_elts);
4286 rs6000_expand_vector_init (target, copy);
4288 /* Insert variable. */
4289 rs6000_expand_vector_set (target, XVECEXP (vals, 0, one_var), one_var);
4290 return;
4293 /* Construct the vector in memory one field at a time
4294 and load the whole vector. */
4295 mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
4296 for (i = 0; i < n_elts; i++)
4297 emit_move_insn (adjust_address_nv (mem, inner_mode,
4298 i * GET_MODE_SIZE (inner_mode)),
4299 XVECEXP (vals, 0, i));
4300 emit_move_insn (target, mem);
4303 /* Set field ELT of TARGET to VAL. */
4305 void
4306 rs6000_expand_vector_set (rtx target, rtx val, int elt)
4308 enum machine_mode mode = GET_MODE (target);
4309 enum machine_mode inner_mode = GET_MODE_INNER (mode);
4310 rtx reg = gen_reg_rtx (mode);
4311 rtx mask, mem, x;
4312 int width = GET_MODE_SIZE (inner_mode);
4313 int i;
4315 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
4317 rtx (*set_func) (rtx, rtx, rtx, rtx)
4318 = ((mode == V2DFmode) ? gen_vsx_set_v2df : gen_vsx_set_v2di);
4319 emit_insn (set_func (target, target, val, GEN_INT (elt)));
4320 return;
4323 /* Load single variable value. */
4324 mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0);
4325 emit_move_insn (adjust_address_nv (mem, inner_mode, 0), val);
4326 x = gen_rtx_UNSPEC (VOIDmode,
4327 gen_rtvec (1, const0_rtx), UNSPEC_LVE);
4328 emit_insn (gen_rtx_PARALLEL (VOIDmode,
4329 gen_rtvec (2,
4330 gen_rtx_SET (VOIDmode,
4331 reg, mem),
4332 x)));
4334 /* Linear sequence. */
4335 mask = gen_rtx_PARALLEL (V16QImode, rtvec_alloc (16));
4336 for (i = 0; i < 16; ++i)
4337 XVECEXP (mask, 0, i) = GEN_INT (i);
4339 /* Set permute mask to insert element into target. */
4340 for (i = 0; i < width; ++i)
4341 XVECEXP (mask, 0, elt*width + i)
4342 = GEN_INT (i + 0x10);
4343 x = gen_rtx_CONST_VECTOR (V16QImode, XVEC (mask, 0));
4344 x = gen_rtx_UNSPEC (mode,
4345 gen_rtvec (3, target, reg,
4346 force_reg (V16QImode, x)),
4347 UNSPEC_VPERM);
4348 emit_insn (gen_rtx_SET (VOIDmode, target, x));
4351 /* Extract field ELT from VEC into TARGET. */
4353 void
4354 rs6000_expand_vector_extract (rtx target, rtx vec, int elt)
4356 enum machine_mode mode = GET_MODE (vec);
4357 enum machine_mode inner_mode = GET_MODE_INNER (mode);
4358 rtx mem, x;
4360 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
4362 rtx (*extract_func) (rtx, rtx, rtx)
4363 = ((mode == V2DFmode) ? gen_vsx_extract_v2df : gen_vsx_extract_v2di);
4364 emit_insn (extract_func (target, vec, GEN_INT (elt)));
4365 return;
4368 /* Allocate mode-sized buffer. */
4369 mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
4371 /* Add offset to field within buffer matching vector element. */
4372 mem = adjust_address_nv (mem, mode, elt * GET_MODE_SIZE (inner_mode));
4374 /* Store single field into mode-sized buffer. */
4375 x = gen_rtx_UNSPEC (VOIDmode,
4376 gen_rtvec (1, const0_rtx), UNSPEC_STVE);
4377 emit_insn (gen_rtx_PARALLEL (VOIDmode,
4378 gen_rtvec (2,
4379 gen_rtx_SET (VOIDmode,
4380 mem, vec),
4381 x)));
4382 emit_move_insn (target, adjust_address_nv (mem, inner_mode, 0));
4385 /* Generates shifts and masks for a pair of rldicl or rldicr insns to
4386 implement ANDing by the mask IN. */
4387 void
4388 build_mask64_2_operands (rtx in, rtx *out)
4390 #if HOST_BITS_PER_WIDE_INT >= 64
4391 unsigned HOST_WIDE_INT c, lsb, m1, m2;
4392 int shift;
4394 gcc_assert (GET_CODE (in) == CONST_INT);
4396 c = INTVAL (in);
4397 if (c & 1)
4399 /* Assume c initially something like 0x00fff000000fffff. The idea
4400 is to rotate the word so that the middle ^^^^^^ group of zeros
4401 is at the MS end and can be cleared with an rldicl mask. We then
4402 rotate back and clear off the MS ^^ group of zeros with a
4403 second rldicl. */
4404 c = ~c; /* c == 0xff000ffffff00000 */
4405 lsb = c & -c; /* lsb == 0x0000000000100000 */
4406 m1 = -lsb; /* m1 == 0xfffffffffff00000 */
4407 c = ~c; /* c == 0x00fff000000fffff */
4408 c &= -lsb; /* c == 0x00fff00000000000 */
4409 lsb = c & -c; /* lsb == 0x0000100000000000 */
4410 c = ~c; /* c == 0xff000fffffffffff */
4411 c &= -lsb; /* c == 0xff00000000000000 */
4412 shift = 0;
4413 while ((lsb >>= 1) != 0)
4414 shift++; /* shift == 44 on exit from loop */
4415 m1 <<= 64 - shift; /* m1 == 0xffffff0000000000 */
4416 m1 = ~m1; /* m1 == 0x000000ffffffffff */
4417 m2 = ~c; /* m2 == 0x00ffffffffffffff */
4419 else
4421 /* Assume c initially something like 0xff000f0000000000. The idea
4422 is to rotate the word so that the ^^^ middle group of zeros
4423 is at the LS end and can be cleared with an rldicr mask. We then
4424 rotate back and clear off the LS group of ^^^^^^^^^^ zeros with
4425 a second rldicr. */
4426 lsb = c & -c; /* lsb == 0x0000010000000000 */
4427 m2 = -lsb; /* m2 == 0xffffff0000000000 */
4428 c = ~c; /* c == 0x00fff0ffffffffff */
4429 c &= -lsb; /* c == 0x00fff00000000000 */
4430 lsb = c & -c; /* lsb == 0x0000100000000000 */
4431 c = ~c; /* c == 0xff000fffffffffff */
4432 c &= -lsb; /* c == 0xff00000000000000 */
4433 shift = 0;
4434 while ((lsb >>= 1) != 0)
4435 shift++; /* shift == 44 on exit from loop */
4436 m1 = ~c; /* m1 == 0x00ffffffffffffff */
4437 m1 >>= shift; /* m1 == 0x0000000000000fff */
4438 m1 = ~m1; /* m1 == 0xfffffffffffff000 */
4441 /* Note that when we only have two 0->1 and 1->0 transitions, one of the
4442 masks will be all 1's. We are guaranteed more than one transition. */
4443 out[0] = GEN_INT (64 - shift);
4444 out[1] = GEN_INT (m1);
4445 out[2] = GEN_INT (shift);
4446 out[3] = GEN_INT (m2);
4447 #else
4448 (void)in;
4449 (void)out;
4450 gcc_unreachable ();
4451 #endif
4454 /* Return TRUE if OP is an invalid SUBREG operation on the e500. */
4456 bool
4457 invalid_e500_subreg (rtx op, enum machine_mode mode)
4459 if (TARGET_E500_DOUBLE)
4461 /* Reject (subreg:SI (reg:DF)); likewise with subreg:DI or
4462 subreg:TI and reg:TF. Decimal float modes are like integer
4463 modes (only low part of each register used) for this
4464 purpose. */
4465 if (GET_CODE (op) == SUBREG
4466 && (mode == SImode || mode == DImode || mode == TImode
4467 || mode == DDmode || mode == TDmode)
4468 && REG_P (SUBREG_REG (op))
4469 && (GET_MODE (SUBREG_REG (op)) == DFmode
4470 || GET_MODE (SUBREG_REG (op)) == TFmode))
4471 return true;
4473 /* Reject (subreg:DF (reg:DI)); likewise with subreg:TF and
4474 reg:TI. */
4475 if (GET_CODE (op) == SUBREG
4476 && (mode == DFmode || mode == TFmode)
4477 && REG_P (SUBREG_REG (op))
4478 && (GET_MODE (SUBREG_REG (op)) == DImode
4479 || GET_MODE (SUBREG_REG (op)) == TImode
4480 || GET_MODE (SUBREG_REG (op)) == DDmode
4481 || GET_MODE (SUBREG_REG (op)) == TDmode))
4482 return true;
4485 if (TARGET_SPE
4486 && GET_CODE (op) == SUBREG
4487 && mode == SImode
4488 && REG_P (SUBREG_REG (op))
4489 && SPE_VECTOR_MODE (GET_MODE (SUBREG_REG (op))))
4490 return true;
4492 return false;
4495 /* AIX increases natural record alignment to doubleword if the first
4496 field is an FP double while the FP fields remain word aligned. */
4498 unsigned int
4499 rs6000_special_round_type_align (tree type, unsigned int computed,
4500 unsigned int specified)
4502 unsigned int align = MAX (computed, specified);
4503 tree field = TYPE_FIELDS (type);
4505 /* Skip all non field decls */
4506 while (field != NULL && TREE_CODE (field) != FIELD_DECL)
4507 field = TREE_CHAIN (field);
4509 if (field != NULL && field != type)
4511 type = TREE_TYPE (field);
4512 while (TREE_CODE (type) == ARRAY_TYPE)
4513 type = TREE_TYPE (type);
4515 if (type != error_mark_node && TYPE_MODE (type) == DFmode)
4516 align = MAX (align, 64);
4519 return align;
4522 /* Darwin increases record alignment to the natural alignment of
4523 the first field. */
4525 unsigned int
4526 darwin_rs6000_special_round_type_align (tree type, unsigned int computed,
4527 unsigned int specified)
4529 unsigned int align = MAX (computed, specified);
4531 if (TYPE_PACKED (type))
4532 return align;
4534 /* Find the first field, looking down into aggregates. */
4535 do {
4536 tree field = TYPE_FIELDS (type);
4537 /* Skip all non field decls */
4538 while (field != NULL && TREE_CODE (field) != FIELD_DECL)
4539 field = TREE_CHAIN (field);
4540 if (! field)
4541 break;
4542 type = TREE_TYPE (field);
4543 while (TREE_CODE (type) == ARRAY_TYPE)
4544 type = TREE_TYPE (type);
4545 } while (AGGREGATE_TYPE_P (type));
4547 if (! AGGREGATE_TYPE_P (type) && type != error_mark_node)
4548 align = MAX (align, TYPE_ALIGN (type));
4550 return align;
4553 /* Return 1 for an operand in small memory on V.4/eabi. */
4556 small_data_operand (rtx op ATTRIBUTE_UNUSED,
4557 enum machine_mode mode ATTRIBUTE_UNUSED)
4559 #if TARGET_ELF
4560 rtx sym_ref;
4562 if (rs6000_sdata == SDATA_NONE || rs6000_sdata == SDATA_DATA)
4563 return 0;
4565 if (DEFAULT_ABI != ABI_V4)
4566 return 0;
4568 /* Vector and float memory instructions have a limited offset on the
4569 SPE, so using a vector or float variable directly as an operand is
4570 not useful. */
4571 if (TARGET_SPE
4572 && (SPE_VECTOR_MODE (mode) || FLOAT_MODE_P (mode)))
4573 return 0;
4575 if (GET_CODE (op) == SYMBOL_REF)
4576 sym_ref = op;
4578 else if (GET_CODE (op) != CONST
4579 || GET_CODE (XEXP (op, 0)) != PLUS
4580 || GET_CODE (XEXP (XEXP (op, 0), 0)) != SYMBOL_REF
4581 || GET_CODE (XEXP (XEXP (op, 0), 1)) != CONST_INT)
4582 return 0;
4584 else
4586 rtx sum = XEXP (op, 0);
4587 HOST_WIDE_INT summand;
4589 /* We have to be careful here, because it is the referenced address
4590 that must be 32k from _SDA_BASE_, not just the symbol. */
4591 summand = INTVAL (XEXP (sum, 1));
4592 if (summand < 0 || (unsigned HOST_WIDE_INT) summand > g_switch_value)
4593 return 0;
4595 sym_ref = XEXP (sum, 0);
4598 return SYMBOL_REF_SMALL_P (sym_ref);
4599 #else
4600 return 0;
4601 #endif
4604 /* Return true if either operand is a general purpose register. */
4606 bool
4607 gpr_or_gpr_p (rtx op0, rtx op1)
4609 return ((REG_P (op0) && INT_REGNO_P (REGNO (op0)))
4610 || (REG_P (op1) && INT_REGNO_P (REGNO (op1))));
4614 /* Subroutines of rs6000_legitimize_address and rs6000_legitimate_address_p. */
4616 static bool
4617 reg_offset_addressing_ok_p (enum machine_mode mode)
4619 switch (mode)
4621 case V16QImode:
4622 case V8HImode:
4623 case V4SFmode:
4624 case V4SImode:
4625 case V2DFmode:
4626 case V2DImode:
4627 /* AltiVec/VSX vector modes. Only reg+reg addressing is valid. */
4628 if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode))
4629 return false;
4630 break;
4632 case V4HImode:
4633 case V2SImode:
4634 case V1DImode:
4635 case V2SFmode:
4636 /* Paired vector modes. Only reg+reg addressing is valid. */
4637 if (TARGET_PAIRED_FLOAT)
4638 return false;
4639 break;
4641 default:
4642 break;
4645 return true;
4648 static bool
4649 virtual_stack_registers_memory_p (rtx op)
4651 int regnum;
4653 if (GET_CODE (op) == REG)
4654 regnum = REGNO (op);
4656 else if (GET_CODE (op) == PLUS
4657 && GET_CODE (XEXP (op, 0)) == REG
4658 && GET_CODE (XEXP (op, 1)) == CONST_INT)
4659 regnum = REGNO (XEXP (op, 0));
4661 else
4662 return false;
4664 return (regnum >= FIRST_VIRTUAL_REGISTER
4665 && regnum <= LAST_VIRTUAL_REGISTER);
4668 static bool
4669 constant_pool_expr_p (rtx op)
4671 rtx base, offset;
4673 split_const (op, &base, &offset);
4674 return (GET_CODE (base) == SYMBOL_REF
4675 && CONSTANT_POOL_ADDRESS_P (base)
4676 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (base), Pmode));
4679 bool
4680 toc_relative_expr_p (rtx op)
4682 rtx base, offset;
4684 if (GET_CODE (op) != CONST)
4685 return false;
4687 split_const (op, &base, &offset);
4688 return (GET_CODE (base) == UNSPEC
4689 && XINT (base, 1) == UNSPEC_TOCREL);
4692 bool
4693 legitimate_constant_pool_address_p (rtx x)
4695 return (TARGET_TOC
4696 && GET_CODE (x) == PLUS
4697 && GET_CODE (XEXP (x, 0)) == REG
4698 && (TARGET_MINIMAL_TOC || REGNO (XEXP (x, 0)) == TOC_REGISTER)
4699 && toc_relative_expr_p (XEXP (x, 1)));
4702 static bool
4703 legitimate_small_data_p (enum machine_mode mode, rtx x)
4705 return (DEFAULT_ABI == ABI_V4
4706 && !flag_pic && !TARGET_TOC
4707 && (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST)
4708 && small_data_operand (x, mode));
4711 /* SPE offset addressing is limited to 5-bits worth of double words. */
4712 #define SPE_CONST_OFFSET_OK(x) (((x) & ~0xf8) == 0)
4714 bool
4715 rs6000_legitimate_offset_address_p (enum machine_mode mode, rtx x, int strict)
4717 unsigned HOST_WIDE_INT offset, extra;
4719 if (GET_CODE (x) != PLUS)
4720 return false;
4721 if (GET_CODE (XEXP (x, 0)) != REG)
4722 return false;
4723 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
4724 return false;
4725 if (!reg_offset_addressing_ok_p (mode))
4726 return virtual_stack_registers_memory_p (x);
4727 if (legitimate_constant_pool_address_p (x))
4728 return true;
4729 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
4730 return false;
4732 offset = INTVAL (XEXP (x, 1));
4733 extra = 0;
4734 switch (mode)
4736 case V4HImode:
4737 case V2SImode:
4738 case V1DImode:
4739 case V2SFmode:
4740 /* SPE vector modes. */
4741 return SPE_CONST_OFFSET_OK (offset);
4743 case DFmode:
4744 if (TARGET_E500_DOUBLE)
4745 return SPE_CONST_OFFSET_OK (offset);
4747 /* If we are using VSX scalar loads, restrict ourselves to reg+reg
4748 addressing. */
4749 if (VECTOR_MEM_VSX_P (DFmode))
4750 return false;
4752 case DDmode:
4753 case DImode:
4754 /* On e500v2, we may have:
4756 (subreg:DF (mem:DI (plus (reg) (const_int))) 0).
4758 Which gets addressed with evldd instructions. */
4759 if (TARGET_E500_DOUBLE)
4760 return SPE_CONST_OFFSET_OK (offset);
4762 if (mode == DFmode || mode == DDmode || !TARGET_POWERPC64)
4763 extra = 4;
4764 else if (offset & 3)
4765 return false;
4766 break;
4768 case TFmode:
4769 if (TARGET_E500_DOUBLE)
4770 return (SPE_CONST_OFFSET_OK (offset)
4771 && SPE_CONST_OFFSET_OK (offset + 8));
4773 case TDmode:
4774 case TImode:
4775 if (mode == TFmode || mode == TDmode || !TARGET_POWERPC64)
4776 extra = 12;
4777 else if (offset & 3)
4778 return false;
4779 else
4780 extra = 8;
4781 break;
4783 default:
4784 break;
4787 offset += 0x8000;
4788 return (offset < 0x10000) && (offset + extra < 0x10000);
4791 bool
4792 legitimate_indexed_address_p (rtx x, int strict)
4794 rtx op0, op1;
4796 if (GET_CODE (x) != PLUS)
4797 return false;
4799 op0 = XEXP (x, 0);
4800 op1 = XEXP (x, 1);
4802 /* Recognize the rtl generated by reload which we know will later be
4803 replaced with proper base and index regs. */
4804 if (!strict
4805 && reload_in_progress
4806 && (REG_P (op0) || GET_CODE (op0) == PLUS)
4807 && REG_P (op1))
4808 return true;
4810 return (REG_P (op0) && REG_P (op1)
4811 && ((INT_REG_OK_FOR_BASE_P (op0, strict)
4812 && INT_REG_OK_FOR_INDEX_P (op1, strict))
4813 || (INT_REG_OK_FOR_BASE_P (op1, strict)
4814 && INT_REG_OK_FOR_INDEX_P (op0, strict))));
4817 bool
4818 avoiding_indexed_address_p (enum machine_mode mode)
4820 /* Avoid indexed addressing for modes that have non-indexed
4821 load/store instruction forms. */
4822 return (TARGET_AVOID_XFORM && VECTOR_MEM_NONE_P (mode));
4825 inline bool
4826 legitimate_indirect_address_p (rtx x, int strict)
4828 return GET_CODE (x) == REG && INT_REG_OK_FOR_BASE_P (x, strict);
4831 bool
4832 macho_lo_sum_memory_operand (rtx x, enum machine_mode mode)
4834 if (!TARGET_MACHO || !flag_pic
4835 || mode != SImode || GET_CODE (x) != MEM)
4836 return false;
4837 x = XEXP (x, 0);
4839 if (GET_CODE (x) != LO_SUM)
4840 return false;
4841 if (GET_CODE (XEXP (x, 0)) != REG)
4842 return false;
4843 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 0))
4844 return false;
4845 x = XEXP (x, 1);
4847 return CONSTANT_P (x);
4850 static bool
4851 legitimate_lo_sum_address_p (enum machine_mode mode, rtx x, int strict)
4853 if (GET_CODE (x) != LO_SUM)
4854 return false;
4855 if (GET_CODE (XEXP (x, 0)) != REG)
4856 return false;
4857 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
4858 return false;
4859 /* Restrict addressing for DI because of our SUBREG hackery. */
4860 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
4861 || mode == DDmode || mode == TDmode
4862 || mode == DImode))
4863 return false;
4864 x = XEXP (x, 1);
4866 if (TARGET_ELF || TARGET_MACHO)
4868 if (DEFAULT_ABI != ABI_AIX && DEFAULT_ABI != ABI_DARWIN && flag_pic)
4869 return false;
4870 if (TARGET_TOC)
4871 return false;
4872 if (GET_MODE_NUNITS (mode) != 1)
4873 return false;
4874 if (GET_MODE_BITSIZE (mode) > 64
4875 || (GET_MODE_BITSIZE (mode) > 32 && !TARGET_POWERPC64
4876 && !(TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
4877 && (mode == DFmode || mode == DDmode))))
4878 return false;
4880 return CONSTANT_P (x);
4883 return false;
4887 /* Try machine-dependent ways of modifying an illegitimate address
4888 to be legitimate. If we find one, return the new, valid address.
4889 This is used from only one place: `memory_address' in explow.c.
4891 OLDX is the address as it was before break_out_memory_refs was
4892 called. In some cases it is useful to look at this to decide what
4893 needs to be done.
4895 It is always safe for this function to do nothing. It exists to
4896 recognize opportunities to optimize the output.
4898 On RS/6000, first check for the sum of a register with a constant
4899 integer that is out of range. If so, generate code to add the
4900 constant with the low-order 16 bits masked to the register and force
4901 this result into another register (this can be done with `cau').
4902 Then generate an address of REG+(CONST&0xffff), allowing for the
4903 possibility of bit 16 being a one.
4905 Then check for the sum of a register and something not constant, try to
4906 load the other things into a register and return the sum. */
4908 static rtx
4909 rs6000_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
4910 enum machine_mode mode)
4912 unsigned int extra = 0;
4914 if (!reg_offset_addressing_ok_p (mode))
4916 if (virtual_stack_registers_memory_p (x))
4917 return x;
4919 /* In theory we should not be seeing addresses of the form reg+0,
4920 but just in case it is generated, optimize it away. */
4921 if (GET_CODE (x) == PLUS && XEXP (x, 1) == const0_rtx)
4922 return force_reg (Pmode, XEXP (x, 0));
4924 /* Make sure both operands are registers. */
4925 else if (GET_CODE (x) == PLUS)
4926 return gen_rtx_PLUS (Pmode,
4927 force_reg (Pmode, XEXP (x, 0)),
4928 force_reg (Pmode, XEXP (x, 1)));
4929 else
4930 return force_reg (Pmode, x);
4932 if (GET_CODE (x) == SYMBOL_REF)
4934 enum tls_model model = SYMBOL_REF_TLS_MODEL (x);
4935 if (model != 0)
4936 return rs6000_legitimize_tls_address (x, model);
4939 switch (mode)
4941 case DFmode:
4942 case DDmode:
4943 extra = 4;
4944 break;
4945 case DImode:
4946 if (!TARGET_POWERPC64)
4947 extra = 4;
4948 break;
4949 case TFmode:
4950 case TDmode:
4951 extra = 12;
4952 break;
4953 case TImode:
4954 extra = TARGET_POWERPC64 ? 8 : 12;
4955 break;
4956 default:
4957 break;
4960 if (GET_CODE (x) == PLUS
4961 && GET_CODE (XEXP (x, 0)) == REG
4962 && GET_CODE (XEXP (x, 1)) == CONST_INT
4963 && ((unsigned HOST_WIDE_INT) (INTVAL (XEXP (x, 1)) + 0x8000)
4964 >= 0x10000 - extra)
4965 && !((TARGET_POWERPC64
4966 && (mode == DImode || mode == TImode)
4967 && (INTVAL (XEXP (x, 1)) & 3) != 0)
4968 || SPE_VECTOR_MODE (mode)
4969 || (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
4970 || mode == DImode || mode == DDmode
4971 || mode == TDmode))))
4973 HOST_WIDE_INT high_int, low_int;
4974 rtx sum;
4975 low_int = ((INTVAL (XEXP (x, 1)) & 0xffff) ^ 0x8000) - 0x8000;
4976 if (low_int >= 0x8000 - extra)
4977 low_int = 0;
4978 high_int = INTVAL (XEXP (x, 1)) - low_int;
4979 sum = force_operand (gen_rtx_PLUS (Pmode, XEXP (x, 0),
4980 GEN_INT (high_int)), 0);
4981 return plus_constant (sum, low_int);
4983 else if (GET_CODE (x) == PLUS
4984 && GET_CODE (XEXP (x, 0)) == REG
4985 && GET_CODE (XEXP (x, 1)) != CONST_INT
4986 && GET_MODE_NUNITS (mode) == 1
4987 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
4988 || TARGET_POWERPC64
4989 || ((mode != DImode && mode != DFmode && mode != DDmode)
4990 || (TARGET_E500_DOUBLE && mode != DDmode)))
4991 && (TARGET_POWERPC64 || mode != DImode)
4992 && !avoiding_indexed_address_p (mode)
4993 && mode != TImode
4994 && mode != TFmode
4995 && mode != TDmode)
4997 return gen_rtx_PLUS (Pmode, XEXP (x, 0),
4998 force_reg (Pmode, force_operand (XEXP (x, 1), 0)));
5000 else if (SPE_VECTOR_MODE (mode)
5001 || (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
5002 || mode == DDmode || mode == TDmode
5003 || mode == DImode)))
5005 if (mode == DImode)
5006 return x;
5007 /* We accept [reg + reg] and [reg + OFFSET]. */
5009 if (GET_CODE (x) == PLUS)
5011 rtx op1 = XEXP (x, 0);
5012 rtx op2 = XEXP (x, 1);
5013 rtx y;
5015 op1 = force_reg (Pmode, op1);
5017 if (GET_CODE (op2) != REG
5018 && (GET_CODE (op2) != CONST_INT
5019 || !SPE_CONST_OFFSET_OK (INTVAL (op2))
5020 || (GET_MODE_SIZE (mode) > 8
5021 && !SPE_CONST_OFFSET_OK (INTVAL (op2) + 8))))
5022 op2 = force_reg (Pmode, op2);
5024 /* We can't always do [reg + reg] for these, because [reg +
5025 reg + offset] is not a legitimate addressing mode. */
5026 y = gen_rtx_PLUS (Pmode, op1, op2);
5028 if ((GET_MODE_SIZE (mode) > 8 || mode == DDmode) && REG_P (op2))
5029 return force_reg (Pmode, y);
5030 else
5031 return y;
5034 return force_reg (Pmode, x);
5036 else if (TARGET_ELF
5037 && TARGET_32BIT
5038 && TARGET_NO_TOC
5039 && ! flag_pic
5040 && GET_CODE (x) != CONST_INT
5041 && GET_CODE (x) != CONST_DOUBLE
5042 && CONSTANT_P (x)
5043 && GET_MODE_NUNITS (mode) == 1
5044 && (GET_MODE_BITSIZE (mode) <= 32
5045 || ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5046 && (mode == DFmode || mode == DDmode))))
5048 rtx reg = gen_reg_rtx (Pmode);
5049 emit_insn (gen_elf_high (reg, x));
5050 return gen_rtx_LO_SUM (Pmode, reg, x);
5052 else if (TARGET_MACHO && TARGET_32BIT && TARGET_NO_TOC
5053 && ! flag_pic
5054 #if TARGET_MACHO
5055 && ! MACHO_DYNAMIC_NO_PIC_P
5056 #endif
5057 && GET_CODE (x) != CONST_INT
5058 && GET_CODE (x) != CONST_DOUBLE
5059 && CONSTANT_P (x)
5060 && GET_MODE_NUNITS (mode) == 1
5061 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5062 || (mode != DFmode && mode != DDmode))
5063 && mode != DImode
5064 && mode != TImode)
5066 rtx reg = gen_reg_rtx (Pmode);
5067 emit_insn (gen_macho_high (reg, x));
5068 return gen_rtx_LO_SUM (Pmode, reg, x);
5070 else if (TARGET_TOC
5071 && GET_CODE (x) == SYMBOL_REF
5072 && constant_pool_expr_p (x)
5073 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), Pmode))
5075 return create_TOC_reference (x);
5077 else
5078 return x;
5081 /* Debug version of rs6000_legitimize_address. */
5082 static rtx
5083 rs6000_debug_legitimize_address (rtx x, rtx oldx, enum machine_mode mode)
5085 rtx ret;
5086 rtx insns;
5088 start_sequence ();
5089 ret = rs6000_legitimize_address (x, oldx, mode);
5090 insns = get_insns ();
5091 end_sequence ();
5093 if (ret != x)
5095 fprintf (stderr,
5096 "\nrs6000_legitimize_address: mode %s, old code %s, "
5097 "new code %s, modified\n",
5098 GET_MODE_NAME (mode), GET_RTX_NAME (GET_CODE (x)),
5099 GET_RTX_NAME (GET_CODE (ret)));
5101 fprintf (stderr, "Original address:\n");
5102 debug_rtx (x);
5104 fprintf (stderr, "oldx:\n");
5105 debug_rtx (oldx);
5107 fprintf (stderr, "New address:\n");
5108 debug_rtx (ret);
5110 if (insns)
5112 fprintf (stderr, "Insns added:\n");
5113 debug_rtx_list (insns, 20);
5116 else
5118 fprintf (stderr,
5119 "\nrs6000_legitimize_address: mode %s, code %s, no change:\n",
5120 GET_MODE_NAME (mode), GET_RTX_NAME (GET_CODE (x)));
5122 debug_rtx (x);
5125 if (insns)
5126 emit_insn (insns);
5128 return ret;
5131 /* If ORIG_X is a constant pool reference, return its known value,
5132 otherwise ORIG_X. */
5134 static rtx
5135 rs6000_delegitimize_address (rtx x)
5137 rtx orig_x = delegitimize_mem_from_attrs (x);
5139 x = orig_x;
5141 if (!MEM_P (x))
5142 return orig_x;
5144 x = XEXP (x, 0);
5146 if (legitimate_constant_pool_address_p (x)
5147 && GET_CODE (XEXP (x, 1)) == CONST
5148 && GET_CODE (XEXP (XEXP (x, 1), 0)) == MINUS
5149 && GET_CODE (XEXP (XEXP (XEXP (x, 1), 0), 0)) == SYMBOL_REF
5150 && constant_pool_expr_p (XEXP (XEXP (XEXP (x, 1), 0), 0))
5151 && GET_CODE (XEXP (XEXP (XEXP (x, 1), 0), 1)) == SYMBOL_REF
5152 && toc_relative_expr_p (XEXP (XEXP (XEXP (x, 1), 0), 1)))
5153 return get_pool_constant (XEXP (XEXP (XEXP (x, 1), 0), 0));
5155 return orig_x;
5158 /* This is called from dwarf2out.c via TARGET_ASM_OUTPUT_DWARF_DTPREL.
5159 We need to emit DTP-relative relocations. */
5161 static void
5162 rs6000_output_dwarf_dtprel (FILE *file, int size, rtx x)
5164 switch (size)
5166 case 4:
5167 fputs ("\t.long\t", file);
5168 break;
5169 case 8:
5170 fputs (DOUBLE_INT_ASM_OP, file);
5171 break;
5172 default:
5173 gcc_unreachable ();
5175 output_addr_const (file, x);
5176 fputs ("@dtprel+0x8000", file);
5179 /* Construct the SYMBOL_REF for the tls_get_addr function. */
5181 static GTY(()) rtx rs6000_tls_symbol;
5182 static rtx
5183 rs6000_tls_get_addr (void)
5185 if (!rs6000_tls_symbol)
5186 rs6000_tls_symbol = init_one_libfunc ("__tls_get_addr");
5188 return rs6000_tls_symbol;
5191 /* Construct the SYMBOL_REF for TLS GOT references. */
5193 static GTY(()) rtx rs6000_got_symbol;
5194 static rtx
5195 rs6000_got_sym (void)
5197 if (!rs6000_got_symbol)
5199 rs6000_got_symbol = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
5200 SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_LOCAL;
5201 SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_EXTERNAL;
5204 return rs6000_got_symbol;
5207 /* ADDR contains a thread-local SYMBOL_REF. Generate code to compute
5208 this (thread-local) address. */
5210 static rtx
5211 rs6000_legitimize_tls_address (rtx addr, enum tls_model model)
5213 rtx dest, insn;
5215 dest = gen_reg_rtx (Pmode);
5216 if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 16)
5218 rtx tlsreg;
5220 if (TARGET_64BIT)
5222 tlsreg = gen_rtx_REG (Pmode, 13);
5223 insn = gen_tls_tprel_64 (dest, tlsreg, addr);
5225 else
5227 tlsreg = gen_rtx_REG (Pmode, 2);
5228 insn = gen_tls_tprel_32 (dest, tlsreg, addr);
5230 emit_insn (insn);
5232 else if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 32)
5234 rtx tlsreg, tmp;
5236 tmp = gen_reg_rtx (Pmode);
5237 if (TARGET_64BIT)
5239 tlsreg = gen_rtx_REG (Pmode, 13);
5240 insn = gen_tls_tprel_ha_64 (tmp, tlsreg, addr);
5242 else
5244 tlsreg = gen_rtx_REG (Pmode, 2);
5245 insn = gen_tls_tprel_ha_32 (tmp, tlsreg, addr);
5247 emit_insn (insn);
5248 if (TARGET_64BIT)
5249 insn = gen_tls_tprel_lo_64 (dest, tmp, addr);
5250 else
5251 insn = gen_tls_tprel_lo_32 (dest, tmp, addr);
5252 emit_insn (insn);
5254 else
5256 rtx r3, got, tga, tmp1, tmp2, eqv;
5258 /* We currently use relocations like @got@tlsgd for tls, which
5259 means the linker will handle allocation of tls entries, placing
5260 them in the .got section. So use a pointer to the .got section,
5261 not one to secondary TOC sections used by 64-bit -mminimal-toc,
5262 or to secondary GOT sections used by 32-bit -fPIC. */
5263 if (TARGET_64BIT)
5264 got = gen_rtx_REG (Pmode, 2);
5265 else
5267 if (flag_pic == 1)
5268 got = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
5269 else
5271 rtx gsym = rs6000_got_sym ();
5272 got = gen_reg_rtx (Pmode);
5273 if (flag_pic == 0)
5274 rs6000_emit_move (got, gsym, Pmode);
5275 else
5277 rtx tmp3, mem;
5278 rtx first, last;
5280 tmp1 = gen_reg_rtx (Pmode);
5281 tmp2 = gen_reg_rtx (Pmode);
5282 tmp3 = gen_reg_rtx (Pmode);
5283 mem = gen_const_mem (Pmode, tmp1);
5285 first = emit_insn (gen_load_toc_v4_PIC_1b (gsym));
5286 emit_move_insn (tmp1,
5287 gen_rtx_REG (Pmode, LR_REGNO));
5288 emit_move_insn (tmp2, mem);
5289 emit_insn (gen_addsi3 (tmp3, tmp1, tmp2));
5290 last = emit_move_insn (got, tmp3);
5291 set_unique_reg_note (last, REG_EQUAL, gsym);
5296 if (model == TLS_MODEL_GLOBAL_DYNAMIC)
5298 r3 = gen_rtx_REG (Pmode, 3);
5299 tga = rs6000_tls_get_addr ();
5301 if (DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
5302 insn = gen_tls_gd_aix64 (r3, got, addr, tga, const0_rtx);
5303 else if (DEFAULT_ABI == ABI_AIX && !TARGET_64BIT)
5304 insn = gen_tls_gd_aix32 (r3, got, addr, tga, const0_rtx);
5305 else if (DEFAULT_ABI == ABI_V4)
5306 insn = gen_tls_gd_sysvsi (r3, got, addr, tga, const0_rtx);
5307 else
5308 gcc_unreachable ();
5310 start_sequence ();
5311 insn = emit_call_insn (insn);
5312 RTL_CONST_CALL_P (insn) = 1;
5313 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), r3);
5314 if (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
5315 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), pic_offset_table_rtx);
5316 insn = get_insns ();
5317 end_sequence ();
5318 emit_libcall_block (insn, dest, r3, addr);
5320 else if (model == TLS_MODEL_LOCAL_DYNAMIC)
5322 r3 = gen_rtx_REG (Pmode, 3);
5323 tga = rs6000_tls_get_addr ();
5325 if (DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
5326 insn = gen_tls_ld_aix64 (r3, got, tga, const0_rtx);
5327 else if (DEFAULT_ABI == ABI_AIX && !TARGET_64BIT)
5328 insn = gen_tls_ld_aix32 (r3, got, tga, const0_rtx);
5329 else if (DEFAULT_ABI == ABI_V4)
5330 insn = gen_tls_ld_sysvsi (r3, got, tga, const0_rtx);
5331 else
5332 gcc_unreachable ();
5334 start_sequence ();
5335 insn = emit_call_insn (insn);
5336 RTL_CONST_CALL_P (insn) = 1;
5337 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), r3);
5338 if (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
5339 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), pic_offset_table_rtx);
5340 insn = get_insns ();
5341 end_sequence ();
5342 tmp1 = gen_reg_rtx (Pmode);
5343 eqv = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
5344 UNSPEC_TLSLD);
5345 emit_libcall_block (insn, tmp1, r3, eqv);
5346 if (rs6000_tls_size == 16)
5348 if (TARGET_64BIT)
5349 insn = gen_tls_dtprel_64 (dest, tmp1, addr);
5350 else
5351 insn = gen_tls_dtprel_32 (dest, tmp1, addr);
5353 else if (rs6000_tls_size == 32)
5355 tmp2 = gen_reg_rtx (Pmode);
5356 if (TARGET_64BIT)
5357 insn = gen_tls_dtprel_ha_64 (tmp2, tmp1, addr);
5358 else
5359 insn = gen_tls_dtprel_ha_32 (tmp2, tmp1, addr);
5360 emit_insn (insn);
5361 if (TARGET_64BIT)
5362 insn = gen_tls_dtprel_lo_64 (dest, tmp2, addr);
5363 else
5364 insn = gen_tls_dtprel_lo_32 (dest, tmp2, addr);
5366 else
5368 tmp2 = gen_reg_rtx (Pmode);
5369 if (TARGET_64BIT)
5370 insn = gen_tls_got_dtprel_64 (tmp2, got, addr);
5371 else
5372 insn = gen_tls_got_dtprel_32 (tmp2, got, addr);
5373 emit_insn (insn);
5374 insn = gen_rtx_SET (Pmode, dest,
5375 gen_rtx_PLUS (Pmode, tmp2, tmp1));
5377 emit_insn (insn);
5379 else
5381 /* IE, or 64-bit offset LE. */
5382 tmp2 = gen_reg_rtx (Pmode);
5383 if (TARGET_64BIT)
5384 insn = gen_tls_got_tprel_64 (tmp2, got, addr);
5385 else
5386 insn = gen_tls_got_tprel_32 (tmp2, got, addr);
5387 emit_insn (insn);
5388 if (TARGET_64BIT)
5389 insn = gen_tls_tls_64 (dest, tmp2, addr);
5390 else
5391 insn = gen_tls_tls_32 (dest, tmp2, addr);
5392 emit_insn (insn);
5396 return dest;
5399 /* Return 1 if X contains a thread-local symbol. */
5401 bool
5402 rs6000_tls_referenced_p (rtx x)
5404 if (! TARGET_HAVE_TLS)
5405 return false;
5407 return for_each_rtx (&x, &rs6000_tls_symbol_ref_1, 0);
5410 /* Return 1 if *X is a thread-local symbol. This is the same as
5411 rs6000_tls_symbol_ref except for the type of the unused argument. */
5413 static int
5414 rs6000_tls_symbol_ref_1 (rtx *x, void *data ATTRIBUTE_UNUSED)
5416 return RS6000_SYMBOL_REF_TLS_P (*x);
5419 /* Our implementation of LEGITIMIZE_RELOAD_ADDRESS. Returns a value to
5420 replace the input X, or the original X if no replacement is called for.
5421 The output parameter *WIN is 1 if the calling macro should goto WIN,
5422 0 if it should not.
5424 For RS/6000, we wish to handle large displacements off a base
5425 register by splitting the addend across an addiu/addis and the mem insn.
5426 This cuts number of extra insns needed from 3 to 1.
5428 On Darwin, we use this to generate code for floating point constants.
5429 A movsf_low is generated so we wind up with 2 instructions rather than 3.
5430 The Darwin code is inside #if TARGET_MACHO because only then are the
5431 machopic_* functions defined. */
5432 static rtx
5433 rs6000_legitimize_reload_address (rtx x, enum machine_mode mode,
5434 int opnum, int type,
5435 int ind_levels ATTRIBUTE_UNUSED, int *win)
5437 bool reg_offset_p = reg_offset_addressing_ok_p (mode);
5439 /* We must recognize output that we have already generated ourselves. */
5440 if (GET_CODE (x) == PLUS
5441 && GET_CODE (XEXP (x, 0)) == PLUS
5442 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
5443 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
5444 && GET_CODE (XEXP (x, 1)) == CONST_INT)
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 TARGET_MACHO
5454 if (DEFAULT_ABI == ABI_DARWIN && flag_pic
5455 && GET_CODE (x) == LO_SUM
5456 && GET_CODE (XEXP (x, 0)) == PLUS
5457 && XEXP (XEXP (x, 0), 0) == pic_offset_table_rtx
5458 && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH
5459 && XEXP (XEXP (XEXP (x, 0), 1), 0) == XEXP (x, 1)
5460 && machopic_operand_p (XEXP (x, 1)))
5462 /* Result of previous invocation of this function on Darwin
5463 floating point constant. */
5464 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
5465 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
5466 opnum, (enum reload_type)type);
5467 *win = 1;
5468 return x;
5470 #endif
5472 /* Force ld/std non-word aligned offset into base register by wrapping
5473 in offset 0. */
5474 if (GET_CODE (x) == PLUS
5475 && GET_CODE (XEXP (x, 0)) == REG
5476 && REGNO (XEXP (x, 0)) < 32
5477 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 1)
5478 && GET_CODE (XEXP (x, 1)) == CONST_INT
5479 && reg_offset_p
5480 && (INTVAL (XEXP (x, 1)) & 3) != 0
5481 && VECTOR_MEM_NONE_P (mode)
5482 && GET_MODE_SIZE (mode) >= UNITS_PER_WORD
5483 && TARGET_POWERPC64)
5485 x = gen_rtx_PLUS (GET_MODE (x), x, GEN_INT (0));
5486 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
5487 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
5488 opnum, (enum reload_type) type);
5489 *win = 1;
5490 return x;
5493 if (GET_CODE (x) == PLUS
5494 && GET_CODE (XEXP (x, 0)) == REG
5495 && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER
5496 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 1)
5497 && GET_CODE (XEXP (x, 1)) == CONST_INT
5498 && reg_offset_p
5499 && !SPE_VECTOR_MODE (mode)
5500 && !(TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
5501 || mode == DDmode || mode == TDmode
5502 || mode == DImode))
5503 && VECTOR_MEM_NONE_P (mode))
5505 HOST_WIDE_INT val = INTVAL (XEXP (x, 1));
5506 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
5507 HOST_WIDE_INT high
5508 = (((val - low) & 0xffffffff) ^ 0x80000000) - 0x80000000;
5510 /* Check for 32-bit overflow. */
5511 if (high + low != val)
5513 *win = 0;
5514 return x;
5517 /* Reload the high part into a base reg; leave the low part
5518 in the mem directly. */
5520 x = gen_rtx_PLUS (GET_MODE (x),
5521 gen_rtx_PLUS (GET_MODE (x), XEXP (x, 0),
5522 GEN_INT (high)),
5523 GEN_INT (low));
5525 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
5526 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
5527 opnum, (enum reload_type)type);
5528 *win = 1;
5529 return x;
5532 if (GET_CODE (x) == SYMBOL_REF
5533 && reg_offset_p
5534 && VECTOR_MEM_NONE_P (mode)
5535 && !SPE_VECTOR_MODE (mode)
5536 #if TARGET_MACHO
5537 && DEFAULT_ABI == ABI_DARWIN
5538 && (flag_pic || MACHO_DYNAMIC_NO_PIC_P)
5539 #else
5540 && DEFAULT_ABI == ABI_V4
5541 && !flag_pic
5542 #endif
5543 /* Don't do this for TFmode or TDmode, since the result isn't offsettable.
5544 The same goes for DImode without 64-bit gprs and DFmode and DDmode
5545 without fprs. */
5546 && mode != TFmode
5547 && mode != TDmode
5548 && (mode != DImode || TARGET_POWERPC64)
5549 && ((mode != DFmode && mode != DDmode) || TARGET_POWERPC64
5550 || (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)))
5552 #if TARGET_MACHO
5553 if (flag_pic)
5555 rtx offset = machopic_gen_offset (x);
5556 x = gen_rtx_LO_SUM (GET_MODE (x),
5557 gen_rtx_PLUS (Pmode, pic_offset_table_rtx,
5558 gen_rtx_HIGH (Pmode, offset)), offset);
5560 else
5561 #endif
5562 x = gen_rtx_LO_SUM (GET_MODE (x),
5563 gen_rtx_HIGH (Pmode, x), x);
5565 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
5566 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
5567 opnum, (enum reload_type)type);
5568 *win = 1;
5569 return x;
5572 /* Reload an offset address wrapped by an AND that represents the
5573 masking of the lower bits. Strip the outer AND and let reload
5574 convert the offset address into an indirect address. For VSX,
5575 force reload to create the address with an AND in a separate
5576 register, because we can't guarantee an altivec register will
5577 be used. */
5578 if (VECTOR_MEM_ALTIVEC_P (mode)
5579 && GET_CODE (x) == AND
5580 && GET_CODE (XEXP (x, 0)) == PLUS
5581 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
5582 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
5583 && GET_CODE (XEXP (x, 1)) == CONST_INT
5584 && INTVAL (XEXP (x, 1)) == -16)
5586 x = XEXP (x, 0);
5587 *win = 1;
5588 return x;
5591 if (TARGET_TOC
5592 && reg_offset_p
5593 && GET_CODE (x) == SYMBOL_REF
5594 && constant_pool_expr_p (x)
5595 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), mode))
5597 x = create_TOC_reference (x);
5598 *win = 1;
5599 return x;
5601 *win = 0;
5602 return x;
5605 /* Debug version of rs6000_legitimize_reload_address. */
5606 static rtx
5607 rs6000_debug_legitimize_reload_address (rtx x, enum machine_mode mode,
5608 int opnum, int type,
5609 int ind_levels, int *win)
5611 rtx ret = rs6000_legitimize_reload_address (x, mode, opnum, type,
5612 ind_levels, win);
5613 fprintf (stderr,
5614 "\nrs6000_legitimize_reload_address: mode = %s, opnum = %d, "
5615 "type = %d, ind_levels = %d, win = %d, original addr:\n",
5616 GET_MODE_NAME (mode), opnum, type, ind_levels, *win);
5617 debug_rtx (x);
5619 if (x == ret)
5620 fprintf (stderr, "Same address returned\n");
5621 else if (!ret)
5622 fprintf (stderr, "NULL returned\n");
5623 else
5625 fprintf (stderr, "New address:\n");
5626 debug_rtx (ret);
5629 return ret;
5632 /* TARGET_LEGITIMATE_ADDRESS_P recognizes an RTL expression
5633 that is a valid memory address for an instruction.
5634 The MODE argument is the machine mode for the MEM expression
5635 that wants to use this address.
5637 On the RS/6000, there are four valid address: a SYMBOL_REF that
5638 refers to a constant pool entry of an address (or the sum of it
5639 plus a constant), a short (16-bit signed) constant plus a register,
5640 the sum of two registers, or a register indirect, possibly with an
5641 auto-increment. For DFmode, DDmode and DImode with a constant plus
5642 register, we must ensure that both words are addressable or PowerPC64
5643 with offset word aligned.
5645 For modes spanning multiple registers (DFmode and DDmode in 32-bit GPRs,
5646 32-bit DImode, TImode, TFmode, TDmode), indexed addressing cannot be used
5647 because adjacent memory cells are accessed by adding word-sized offsets
5648 during assembly output. */
5649 bool
5650 rs6000_legitimate_address_p (enum machine_mode mode, rtx x, bool reg_ok_strict)
5652 bool reg_offset_p = reg_offset_addressing_ok_p (mode);
5654 /* If this is an unaligned stvx/ldvx type address, discard the outer AND. */
5655 if (VECTOR_MEM_ALTIVEC_P (mode)
5656 && GET_CODE (x) == AND
5657 && GET_CODE (XEXP (x, 1)) == CONST_INT
5658 && INTVAL (XEXP (x, 1)) == -16)
5659 x = XEXP (x, 0);
5661 if (RS6000_SYMBOL_REF_TLS_P (x))
5662 return 0;
5663 if (legitimate_indirect_address_p (x, reg_ok_strict))
5664 return 1;
5665 if ((GET_CODE (x) == PRE_INC || GET_CODE (x) == PRE_DEC)
5666 && !VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)
5667 && !SPE_VECTOR_MODE (mode)
5668 && mode != TFmode
5669 && mode != TDmode
5670 /* Restrict addressing for DI because of our SUBREG hackery. */
5671 && !(TARGET_E500_DOUBLE
5672 && (mode == DFmode || mode == DDmode || mode == DImode))
5673 && TARGET_UPDATE
5674 && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict))
5675 return 1;
5676 if (virtual_stack_registers_memory_p (x))
5677 return 1;
5678 if (reg_offset_p && legitimate_small_data_p (mode, x))
5679 return 1;
5680 if (reg_offset_p && legitimate_constant_pool_address_p (x))
5681 return 1;
5682 /* If not REG_OK_STRICT (before reload) let pass any stack offset. */
5683 if (! reg_ok_strict
5684 && reg_offset_p
5685 && GET_CODE (x) == PLUS
5686 && GET_CODE (XEXP (x, 0)) == REG
5687 && (XEXP (x, 0) == virtual_stack_vars_rtx
5688 || XEXP (x, 0) == arg_pointer_rtx)
5689 && GET_CODE (XEXP (x, 1)) == CONST_INT)
5690 return 1;
5691 if (rs6000_legitimate_offset_address_p (mode, x, reg_ok_strict))
5692 return 1;
5693 if (mode != TImode
5694 && mode != TFmode
5695 && mode != TDmode
5696 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5697 || TARGET_POWERPC64
5698 || (mode != DFmode && mode != DDmode)
5699 || (TARGET_E500_DOUBLE && mode != DDmode))
5700 && (TARGET_POWERPC64 || mode != DImode)
5701 && !avoiding_indexed_address_p (mode)
5702 && legitimate_indexed_address_p (x, reg_ok_strict))
5703 return 1;
5704 if (GET_CODE (x) == PRE_MODIFY
5705 && VECTOR_MEM_VSX_P (mode)
5706 && TARGET_UPDATE
5707 && legitimate_indexed_address_p (XEXP (x, 1), reg_ok_strict)
5708 && rtx_equal_p (XEXP (XEXP (x, 1), 0), XEXP (x, 0)))
5709 return 1;
5710 if (GET_CODE (x) == PRE_MODIFY
5711 && mode != TImode
5712 && mode != TFmode
5713 && mode != TDmode
5714 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5715 || TARGET_POWERPC64
5716 || ((mode != DFmode && mode != DDmode) || TARGET_E500_DOUBLE))
5717 && (TARGET_POWERPC64 || mode != DImode)
5718 && !VECTOR_MEM_ALTIVEC_P (mode)
5719 && !SPE_VECTOR_MODE (mode)
5720 /* Restrict addressing for DI because of our SUBREG hackery. */
5721 && !(TARGET_E500_DOUBLE
5722 && (mode == DFmode || mode == DDmode || mode == DImode))
5723 && TARGET_UPDATE
5724 && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict)
5725 && (rs6000_legitimate_offset_address_p (mode, XEXP (x, 1), reg_ok_strict)
5726 || (!avoiding_indexed_address_p (mode)
5727 && legitimate_indexed_address_p (XEXP (x, 1), reg_ok_strict)))
5728 && rtx_equal_p (XEXP (XEXP (x, 1), 0), XEXP (x, 0)))
5729 return 1;
5730 if (reg_offset_p && legitimate_lo_sum_address_p (mode, x, reg_ok_strict))
5731 return 1;
5732 return 0;
5735 /* Debug version of rs6000_legitimate_address_p. */
5736 static bool
5737 rs6000_debug_legitimate_address_p (enum machine_mode mode, rtx x,
5738 bool reg_ok_strict)
5740 bool ret = rs6000_legitimate_address_p (mode, x, reg_ok_strict);
5741 fprintf (stderr,
5742 "\nrs6000_legitimate_address_p: return = %s, mode = %s, "
5743 "strict = %d, code = %s\n",
5744 ret ? "true" : "false",
5745 GET_MODE_NAME (mode),
5746 reg_ok_strict,
5747 GET_RTX_NAME (GET_CODE (x)));
5748 debug_rtx (x);
5750 return ret;
5753 /* Go to LABEL if ADDR (a legitimate address expression)
5754 has an effect that depends on the machine mode it is used for.
5756 On the RS/6000 this is true of all integral offsets (since AltiVec
5757 and VSX modes don't allow them) or is a pre-increment or decrement.
5759 ??? Except that due to conceptual problems in offsettable_address_p
5760 we can't really report the problems of integral offsets. So leave
5761 this assuming that the adjustable offset must be valid for the
5762 sub-words of a TFmode operand, which is what we had before. */
5764 static bool
5765 rs6000_mode_dependent_address (rtx addr)
5767 switch (GET_CODE (addr))
5769 case PLUS:
5770 /* Any offset from virtual_stack_vars_rtx and arg_pointer_rtx
5771 is considered a legitimate address before reload, so there
5772 are no offset restrictions in that case. Note that this
5773 condition is safe in strict mode because any address involving
5774 virtual_stack_vars_rtx or arg_pointer_rtx would already have
5775 been rejected as illegitimate. */
5776 if (XEXP (addr, 0) != virtual_stack_vars_rtx
5777 && XEXP (addr, 0) != arg_pointer_rtx
5778 && GET_CODE (XEXP (addr, 1)) == CONST_INT)
5780 unsigned HOST_WIDE_INT val = INTVAL (XEXP (addr, 1));
5781 return val + 12 + 0x8000 >= 0x10000;
5783 break;
5785 case LO_SUM:
5786 return true;
5788 /* Auto-increment cases are now treated generically in recog.c. */
5789 case PRE_MODIFY:
5790 return TARGET_UPDATE;
5792 /* AND is only allowed in Altivec loads. */
5793 case AND:
5794 return true;
5796 default:
5797 break;
5800 return false;
5803 /* Debug version of rs6000_mode_dependent_address. */
5804 static bool
5805 rs6000_debug_mode_dependent_address (rtx addr)
5807 bool ret = rs6000_mode_dependent_address (addr);
5809 fprintf (stderr, "\nrs6000_mode_dependent_address: ret = %s\n",
5810 ret ? "true" : "false");
5811 debug_rtx (addr);
5813 return ret;
5816 /* Implement FIND_BASE_TERM. */
5819 rs6000_find_base_term (rtx op)
5821 rtx base, offset;
5823 split_const (op, &base, &offset);
5824 if (GET_CODE (base) == UNSPEC)
5825 switch (XINT (base, 1))
5827 case UNSPEC_TOCREL:
5828 case UNSPEC_MACHOPIC_OFFSET:
5829 /* OP represents SYM [+ OFFSET] - ANCHOR. SYM is the base term
5830 for aliasing purposes. */
5831 return XVECEXP (base, 0, 0);
5834 return op;
5837 /* More elaborate version of recog's offsettable_memref_p predicate
5838 that works around the ??? note of rs6000_mode_dependent_address.
5839 In particular it accepts
5841 (mem:DI (plus:SI (reg/f:SI 31 31) (const_int 32760 [0x7ff8])))
5843 in 32-bit mode, that the recog predicate rejects. */
5845 bool
5846 rs6000_offsettable_memref_p (rtx op)
5848 if (!MEM_P (op))
5849 return false;
5851 /* First mimic offsettable_memref_p. */
5852 if (offsettable_address_p (1, GET_MODE (op), XEXP (op, 0)))
5853 return true;
5855 /* offsettable_address_p invokes rs6000_mode_dependent_address, but
5856 the latter predicate knows nothing about the mode of the memory
5857 reference and, therefore, assumes that it is the largest supported
5858 mode (TFmode). As a consequence, legitimate offsettable memory
5859 references are rejected. rs6000_legitimate_offset_address_p contains
5860 the correct logic for the PLUS case of rs6000_mode_dependent_address. */
5861 return rs6000_legitimate_offset_address_p (GET_MODE (op), XEXP (op, 0), 1);
5864 /* Change register usage conditional on target flags. */
5865 void
5866 rs6000_conditional_register_usage (void)
5868 int i;
5870 /* Set MQ register fixed (already call_used) if not POWER
5871 architecture (RIOS1, RIOS2, RSC, and PPC601) so that it will not
5872 be allocated. */
5873 if (! TARGET_POWER)
5874 fixed_regs[64] = 1;
5876 /* 64-bit AIX and Linux reserve GPR13 for thread-private data. */
5877 if (TARGET_64BIT)
5878 fixed_regs[13] = call_used_regs[13]
5879 = call_really_used_regs[13] = 1;
5881 /* Conditionally disable FPRs. */
5882 if (TARGET_SOFT_FLOAT || !TARGET_FPRS)
5883 for (i = 32; i < 64; i++)
5884 fixed_regs[i] = call_used_regs[i]
5885 = call_really_used_regs[i] = 1;
5887 /* The TOC register is not killed across calls in a way that is
5888 visible to the compiler. */
5889 if (DEFAULT_ABI == ABI_AIX)
5890 call_really_used_regs[2] = 0;
5892 if (DEFAULT_ABI == ABI_V4
5893 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
5894 && flag_pic == 2)
5895 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
5897 if (DEFAULT_ABI == ABI_V4
5898 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
5899 && flag_pic == 1)
5900 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
5901 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
5902 = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
5904 if (DEFAULT_ABI == ABI_DARWIN
5905 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM)
5906 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
5907 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
5908 = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
5910 if (TARGET_TOC && TARGET_MINIMAL_TOC)
5911 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
5912 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
5914 if (TARGET_SPE)
5916 global_regs[SPEFSCR_REGNO] = 1;
5917 /* We used to use r14 as FIXED_SCRATCH to address SPE 64-bit
5918 registers in prologues and epilogues. We no longer use r14
5919 for FIXED_SCRATCH, but we're keeping r14 out of the allocation
5920 pool for link-compatibility with older versions of GCC. Once
5921 "old" code has died out, we can return r14 to the allocation
5922 pool. */
5923 fixed_regs[14]
5924 = call_used_regs[14]
5925 = call_really_used_regs[14] = 1;
5928 if (!TARGET_ALTIVEC && !TARGET_VSX)
5930 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
5931 fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1;
5932 call_really_used_regs[VRSAVE_REGNO] = 1;
5935 if (TARGET_ALTIVEC || TARGET_VSX)
5936 global_regs[VSCR_REGNO] = 1;
5938 if (TARGET_ALTIVEC_ABI)
5940 for (i = FIRST_ALTIVEC_REGNO; i < FIRST_ALTIVEC_REGNO + 20; ++i)
5941 call_used_regs[i] = call_really_used_regs[i] = 1;
5943 /* AIX reserves VR20:31 in non-extended ABI mode. */
5944 if (TARGET_XCOFF)
5945 for (i = FIRST_ALTIVEC_REGNO + 20; i < FIRST_ALTIVEC_REGNO + 32; ++i)
5946 fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1;
5950 /* Try to output insns to set TARGET equal to the constant C if it can
5951 be done in less than N insns. Do all computations in MODE.
5952 Returns the place where the output has been placed if it can be
5953 done and the insns have been emitted. If it would take more than N
5954 insns, zero is returned and no insns and emitted. */
5957 rs6000_emit_set_const (rtx dest, enum machine_mode mode,
5958 rtx source, int n ATTRIBUTE_UNUSED)
5960 rtx result, insn, set;
5961 HOST_WIDE_INT c0, c1;
5963 switch (mode)
5965 case QImode:
5966 case HImode:
5967 if (dest == NULL)
5968 dest = gen_reg_rtx (mode);
5969 emit_insn (gen_rtx_SET (VOIDmode, dest, source));
5970 return dest;
5972 case SImode:
5973 result = !can_create_pseudo_p () ? dest : gen_reg_rtx (SImode);
5975 emit_insn (gen_rtx_SET (VOIDmode, copy_rtx (result),
5976 GEN_INT (INTVAL (source)
5977 & (~ (HOST_WIDE_INT) 0xffff))));
5978 emit_insn (gen_rtx_SET (VOIDmode, dest,
5979 gen_rtx_IOR (SImode, copy_rtx (result),
5980 GEN_INT (INTVAL (source) & 0xffff))));
5981 result = dest;
5982 break;
5984 case DImode:
5985 switch (GET_CODE (source))
5987 case CONST_INT:
5988 c0 = INTVAL (source);
5989 c1 = -(c0 < 0);
5990 break;
5992 case CONST_DOUBLE:
5993 #if HOST_BITS_PER_WIDE_INT >= 64
5994 c0 = CONST_DOUBLE_LOW (source);
5995 c1 = -(c0 < 0);
5996 #else
5997 c0 = CONST_DOUBLE_LOW (source);
5998 c1 = CONST_DOUBLE_HIGH (source);
5999 #endif
6000 break;
6002 default:
6003 gcc_unreachable ();
6006 result = rs6000_emit_set_long_const (dest, c0, c1);
6007 break;
6009 default:
6010 gcc_unreachable ();
6013 insn = get_last_insn ();
6014 set = single_set (insn);
6015 if (! CONSTANT_P (SET_SRC (set)))
6016 set_unique_reg_note (insn, REG_EQUAL, source);
6018 return result;
6021 /* Having failed to find a 3 insn sequence in rs6000_emit_set_const,
6022 fall back to a straight forward decomposition. We do this to avoid
6023 exponential run times encountered when looking for longer sequences
6024 with rs6000_emit_set_const. */
6025 static rtx
6026 rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c1, HOST_WIDE_INT c2)
6028 if (!TARGET_POWERPC64)
6030 rtx operand1, operand2;
6032 operand1 = operand_subword_force (dest, WORDS_BIG_ENDIAN == 0,
6033 DImode);
6034 operand2 = operand_subword_force (copy_rtx (dest), WORDS_BIG_ENDIAN != 0,
6035 DImode);
6036 emit_move_insn (operand1, GEN_INT (c1));
6037 emit_move_insn (operand2, GEN_INT (c2));
6039 else
6041 HOST_WIDE_INT ud1, ud2, ud3, ud4;
6043 ud1 = c1 & 0xffff;
6044 ud2 = (c1 & 0xffff0000) >> 16;
6045 #if HOST_BITS_PER_WIDE_INT >= 64
6046 c2 = c1 >> 32;
6047 #endif
6048 ud3 = c2 & 0xffff;
6049 ud4 = (c2 & 0xffff0000) >> 16;
6051 if ((ud4 == 0xffff && ud3 == 0xffff && ud2 == 0xffff && (ud1 & 0x8000))
6052 || (ud4 == 0 && ud3 == 0 && ud2 == 0 && ! (ud1 & 0x8000)))
6054 if (ud1 & 0x8000)
6055 emit_move_insn (dest, GEN_INT (((ud1 ^ 0x8000) - 0x8000)));
6056 else
6057 emit_move_insn (dest, GEN_INT (ud1));
6060 else if ((ud4 == 0xffff && ud3 == 0xffff && (ud2 & 0x8000))
6061 || (ud4 == 0 && ud3 == 0 && ! (ud2 & 0x8000)))
6063 if (ud2 & 0x8000)
6064 emit_move_insn (dest, GEN_INT (((ud2 << 16) ^ 0x80000000)
6065 - 0x80000000));
6066 else
6067 emit_move_insn (dest, GEN_INT (ud2 << 16));
6068 if (ud1 != 0)
6069 emit_move_insn (copy_rtx (dest),
6070 gen_rtx_IOR (DImode, copy_rtx (dest),
6071 GEN_INT (ud1)));
6073 else if ((ud4 == 0xffff && (ud3 & 0x8000))
6074 || (ud4 == 0 && ! (ud3 & 0x8000)))
6076 if (ud3 & 0x8000)
6077 emit_move_insn (dest, GEN_INT (((ud3 << 16) ^ 0x80000000)
6078 - 0x80000000));
6079 else
6080 emit_move_insn (dest, GEN_INT (ud3 << 16));
6082 if (ud2 != 0)
6083 emit_move_insn (copy_rtx (dest),
6084 gen_rtx_IOR (DImode, copy_rtx (dest),
6085 GEN_INT (ud2)));
6086 emit_move_insn (copy_rtx (dest),
6087 gen_rtx_ASHIFT (DImode, copy_rtx (dest),
6088 GEN_INT (16)));
6089 if (ud1 != 0)
6090 emit_move_insn (copy_rtx (dest),
6091 gen_rtx_IOR (DImode, copy_rtx (dest),
6092 GEN_INT (ud1)));
6094 else
6096 if (ud4 & 0x8000)
6097 emit_move_insn (dest, GEN_INT (((ud4 << 16) ^ 0x80000000)
6098 - 0x80000000));
6099 else
6100 emit_move_insn (dest, GEN_INT (ud4 << 16));
6102 if (ud3 != 0)
6103 emit_move_insn (copy_rtx (dest),
6104 gen_rtx_IOR (DImode, copy_rtx (dest),
6105 GEN_INT (ud3)));
6107 emit_move_insn (copy_rtx (dest),
6108 gen_rtx_ASHIFT (DImode, copy_rtx (dest),
6109 GEN_INT (32)));
6110 if (ud2 != 0)
6111 emit_move_insn (copy_rtx (dest),
6112 gen_rtx_IOR (DImode, copy_rtx (dest),
6113 GEN_INT (ud2 << 16)));
6114 if (ud1 != 0)
6115 emit_move_insn (copy_rtx (dest),
6116 gen_rtx_IOR (DImode, copy_rtx (dest), GEN_INT (ud1)));
6119 return dest;
6122 /* Helper for the following. Get rid of [r+r] memory refs
6123 in cases where it won't work (TImode, TFmode, TDmode). */
6125 static void
6126 rs6000_eliminate_indexed_memrefs (rtx operands[2])
6128 if (GET_CODE (operands[0]) == MEM
6129 && GET_CODE (XEXP (operands[0], 0)) != REG
6130 && ! legitimate_constant_pool_address_p (XEXP (operands[0], 0))
6131 && ! reload_in_progress)
6132 operands[0]
6133 = replace_equiv_address (operands[0],
6134 copy_addr_to_reg (XEXP (operands[0], 0)));
6136 if (GET_CODE (operands[1]) == MEM
6137 && GET_CODE (XEXP (operands[1], 0)) != REG
6138 && ! legitimate_constant_pool_address_p (XEXP (operands[1], 0))
6139 && ! reload_in_progress)
6140 operands[1]
6141 = replace_equiv_address (operands[1],
6142 copy_addr_to_reg (XEXP (operands[1], 0)));
6145 /* Emit a move from SOURCE to DEST in mode MODE. */
6146 void
6147 rs6000_emit_move (rtx dest, rtx source, enum machine_mode mode)
6149 rtx operands[2];
6150 operands[0] = dest;
6151 operands[1] = source;
6153 if (TARGET_DEBUG_ADDR)
6155 fprintf (stderr,
6156 "\nrs6000_emit_move: mode = %s, reload_in_progress = %d, "
6157 "reload_completed = %d, can_create_pseudos = %d.\ndest:\n",
6158 GET_MODE_NAME (mode),
6159 reload_in_progress,
6160 reload_completed,
6161 can_create_pseudo_p ());
6162 debug_rtx (dest);
6163 fprintf (stderr, "source:\n");
6164 debug_rtx (source);
6167 /* Sanity checks. Check that we get CONST_DOUBLE only when we should. */
6168 if (GET_CODE (operands[1]) == CONST_DOUBLE
6169 && ! FLOAT_MODE_P (mode)
6170 && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
6172 /* FIXME. This should never happen. */
6173 /* Since it seems that it does, do the safe thing and convert
6174 to a CONST_INT. */
6175 operands[1] = gen_int_mode (CONST_DOUBLE_LOW (operands[1]), mode);
6177 gcc_assert (GET_CODE (operands[1]) != CONST_DOUBLE
6178 || FLOAT_MODE_P (mode)
6179 || ((CONST_DOUBLE_HIGH (operands[1]) != 0
6180 || CONST_DOUBLE_LOW (operands[1]) < 0)
6181 && (CONST_DOUBLE_HIGH (operands[1]) != -1
6182 || CONST_DOUBLE_LOW (operands[1]) >= 0)));
6184 /* Check if GCC is setting up a block move that will end up using FP
6185 registers as temporaries. We must make sure this is acceptable. */
6186 if (GET_CODE (operands[0]) == MEM
6187 && GET_CODE (operands[1]) == MEM
6188 && mode == DImode
6189 && (SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[0]))
6190 || SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[1])))
6191 && ! (SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[0]) > 32
6192 ? 32 : MEM_ALIGN (operands[0])))
6193 || SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[1]) > 32
6194 ? 32
6195 : MEM_ALIGN (operands[1]))))
6196 && ! MEM_VOLATILE_P (operands [0])
6197 && ! MEM_VOLATILE_P (operands [1]))
6199 emit_move_insn (adjust_address (operands[0], SImode, 0),
6200 adjust_address (operands[1], SImode, 0));
6201 emit_move_insn (adjust_address (copy_rtx (operands[0]), SImode, 4),
6202 adjust_address (copy_rtx (operands[1]), SImode, 4));
6203 return;
6206 /* Fix up invalid (const (plus (symbol_ref) (reg))) that seems to be created
6207 in the secondary_reload phase, which evidently overwrites the CONST_INT
6208 with a register. */
6209 if (GET_CODE (source) == CONST && GET_CODE (XEXP (source, 0)) == PLUS
6210 && mode == Pmode)
6212 rtx add_op0 = XEXP (XEXP (source, 0), 0);
6213 rtx add_op1 = XEXP (XEXP (source, 0), 1);
6215 if (GET_CODE (add_op0) == SYMBOL_REF && GET_CODE (add_op1) == REG)
6217 rtx tmp = (can_create_pseudo_p ()) ? gen_reg_rtx (Pmode) : dest;
6219 if (TARGET_DEBUG_ADDR)
6221 fprintf (stderr, "\nrs6000_emit_move: bad source\n");
6222 debug_rtx (source);
6225 rs6000_emit_move (tmp, add_op0, Pmode);
6226 emit_insn (gen_rtx_SET (VOIDmode, dest,
6227 gen_rtx_PLUS (Pmode, tmp, add_op1)));
6228 return;
6232 if (can_create_pseudo_p () && GET_CODE (operands[0]) == MEM
6233 && !gpc_reg_operand (operands[1], mode))
6234 operands[1] = force_reg (mode, operands[1]);
6236 if (mode == SFmode && ! TARGET_POWERPC
6237 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
6238 && GET_CODE (operands[0]) == MEM)
6240 int regnum;
6242 if (reload_in_progress || reload_completed)
6243 regnum = true_regnum (operands[1]);
6244 else if (GET_CODE (operands[1]) == REG)
6245 regnum = REGNO (operands[1]);
6246 else
6247 regnum = -1;
6249 /* If operands[1] is a register, on POWER it may have
6250 double-precision data in it, so truncate it to single
6251 precision. */
6252 if (FP_REGNO_P (regnum) || regnum >= FIRST_PSEUDO_REGISTER)
6254 rtx newreg;
6255 newreg = (!can_create_pseudo_p () ? copy_rtx (operands[1])
6256 : gen_reg_rtx (mode));
6257 emit_insn (gen_aux_truncdfsf2 (newreg, operands[1]));
6258 operands[1] = newreg;
6262 /* Recognize the case where operand[1] is a reference to thread-local
6263 data and load its address to a register. */
6264 if (rs6000_tls_referenced_p (operands[1]))
6266 enum tls_model model;
6267 rtx tmp = operands[1];
6268 rtx addend = NULL;
6270 if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
6272 addend = XEXP (XEXP (tmp, 0), 1);
6273 tmp = XEXP (XEXP (tmp, 0), 0);
6276 gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
6277 model = SYMBOL_REF_TLS_MODEL (tmp);
6278 gcc_assert (model != 0);
6280 tmp = rs6000_legitimize_tls_address (tmp, model);
6281 if (addend)
6283 tmp = gen_rtx_PLUS (mode, tmp, addend);
6284 tmp = force_operand (tmp, operands[0]);
6286 operands[1] = tmp;
6289 /* Handle the case where reload calls us with an invalid address. */
6290 if (reload_in_progress && mode == Pmode
6291 && (! general_operand (operands[1], mode)
6292 || ! nonimmediate_operand (operands[0], mode)))
6293 goto emit_set;
6295 /* 128-bit constant floating-point values on Darwin should really be
6296 loaded as two parts. */
6297 if (!TARGET_IEEEQUAD && TARGET_LONG_DOUBLE_128
6298 && mode == TFmode && GET_CODE (operands[1]) == CONST_DOUBLE)
6300 /* DImode is used, not DFmode, because simplify_gen_subreg doesn't
6301 know how to get a DFmode SUBREG of a TFmode. */
6302 enum machine_mode imode = (TARGET_E500_DOUBLE ? DFmode : DImode);
6303 rs6000_emit_move (simplify_gen_subreg (imode, operands[0], mode, 0),
6304 simplify_gen_subreg (imode, operands[1], mode, 0),
6305 imode);
6306 rs6000_emit_move (simplify_gen_subreg (imode, operands[0], mode,
6307 GET_MODE_SIZE (imode)),
6308 simplify_gen_subreg (imode, operands[1], mode,
6309 GET_MODE_SIZE (imode)),
6310 imode);
6311 return;
6314 if (reload_in_progress && cfun->machine->sdmode_stack_slot != NULL_RTX)
6315 cfun->machine->sdmode_stack_slot =
6316 eliminate_regs (cfun->machine->sdmode_stack_slot, VOIDmode, NULL_RTX);
6318 if (reload_in_progress
6319 && mode == SDmode
6320 && MEM_P (operands[0])
6321 && rtx_equal_p (operands[0], cfun->machine->sdmode_stack_slot)
6322 && REG_P (operands[1]))
6324 if (FP_REGNO_P (REGNO (operands[1])))
6326 rtx mem = adjust_address_nv (operands[0], DDmode, 0);
6327 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
6328 emit_insn (gen_movsd_store (mem, operands[1]));
6330 else if (INT_REGNO_P (REGNO (operands[1])))
6332 rtx mem = adjust_address_nv (operands[0], mode, 4);
6333 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
6334 emit_insn (gen_movsd_hardfloat (mem, operands[1]));
6336 else
6337 gcc_unreachable();
6338 return;
6340 if (reload_in_progress
6341 && mode == SDmode
6342 && REG_P (operands[0])
6343 && MEM_P (operands[1])
6344 && rtx_equal_p (operands[1], cfun->machine->sdmode_stack_slot))
6346 if (FP_REGNO_P (REGNO (operands[0])))
6348 rtx mem = adjust_address_nv (operands[1], DDmode, 0);
6349 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
6350 emit_insn (gen_movsd_load (operands[0], mem));
6352 else if (INT_REGNO_P (REGNO (operands[0])))
6354 rtx mem = adjust_address_nv (operands[1], mode, 4);
6355 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
6356 emit_insn (gen_movsd_hardfloat (operands[0], mem));
6358 else
6359 gcc_unreachable();
6360 return;
6363 /* FIXME: In the long term, this switch statement should go away
6364 and be replaced by a sequence of tests based on things like
6365 mode == Pmode. */
6366 switch (mode)
6368 case HImode:
6369 case QImode:
6370 if (CONSTANT_P (operands[1])
6371 && GET_CODE (operands[1]) != CONST_INT)
6372 operands[1] = force_const_mem (mode, operands[1]);
6373 break;
6375 case TFmode:
6376 case TDmode:
6377 rs6000_eliminate_indexed_memrefs (operands);
6378 /* fall through */
6380 case DFmode:
6381 case DDmode:
6382 case SFmode:
6383 case SDmode:
6384 if (CONSTANT_P (operands[1])
6385 && ! easy_fp_constant (operands[1], mode))
6386 operands[1] = force_const_mem (mode, operands[1]);
6387 break;
6389 case V16QImode:
6390 case V8HImode:
6391 case V4SFmode:
6392 case V4SImode:
6393 case V4HImode:
6394 case V2SFmode:
6395 case V2SImode:
6396 case V1DImode:
6397 case V2DFmode:
6398 case V2DImode:
6399 if (CONSTANT_P (operands[1])
6400 && !easy_vector_constant (operands[1], mode))
6401 operands[1] = force_const_mem (mode, operands[1]);
6402 break;
6404 case SImode:
6405 case DImode:
6406 /* Use default pattern for address of ELF small data */
6407 if (TARGET_ELF
6408 && mode == Pmode
6409 && DEFAULT_ABI == ABI_V4
6410 && (GET_CODE (operands[1]) == SYMBOL_REF
6411 || GET_CODE (operands[1]) == CONST)
6412 && small_data_operand (operands[1], mode))
6414 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
6415 return;
6418 if (DEFAULT_ABI == ABI_V4
6419 && mode == Pmode && mode == SImode
6420 && flag_pic == 1 && got_operand (operands[1], mode))
6422 emit_insn (gen_movsi_got (operands[0], operands[1]));
6423 return;
6426 if ((TARGET_ELF || DEFAULT_ABI == ABI_DARWIN)
6427 && TARGET_NO_TOC
6428 && ! flag_pic
6429 && mode == Pmode
6430 && CONSTANT_P (operands[1])
6431 && GET_CODE (operands[1]) != HIGH
6432 && GET_CODE (operands[1]) != CONST_INT)
6434 rtx target = (!can_create_pseudo_p ()
6435 ? operands[0]
6436 : gen_reg_rtx (mode));
6438 /* If this is a function address on -mcall-aixdesc,
6439 convert it to the address of the descriptor. */
6440 if (DEFAULT_ABI == ABI_AIX
6441 && GET_CODE (operands[1]) == SYMBOL_REF
6442 && XSTR (operands[1], 0)[0] == '.')
6444 const char *name = XSTR (operands[1], 0);
6445 rtx new_ref;
6446 while (*name == '.')
6447 name++;
6448 new_ref = gen_rtx_SYMBOL_REF (Pmode, name);
6449 CONSTANT_POOL_ADDRESS_P (new_ref)
6450 = CONSTANT_POOL_ADDRESS_P (operands[1]);
6451 SYMBOL_REF_FLAGS (new_ref) = SYMBOL_REF_FLAGS (operands[1]);
6452 SYMBOL_REF_USED (new_ref) = SYMBOL_REF_USED (operands[1]);
6453 SYMBOL_REF_DATA (new_ref) = SYMBOL_REF_DATA (operands[1]);
6454 operands[1] = new_ref;
6457 if (DEFAULT_ABI == ABI_DARWIN)
6459 #if TARGET_MACHO
6460 if (MACHO_DYNAMIC_NO_PIC_P)
6462 /* Take care of any required data indirection. */
6463 operands[1] = rs6000_machopic_legitimize_pic_address (
6464 operands[1], mode, operands[0]);
6465 if (operands[0] != operands[1])
6466 emit_insn (gen_rtx_SET (VOIDmode,
6467 operands[0], operands[1]));
6468 return;
6470 #endif
6471 emit_insn (gen_macho_high (target, operands[1]));
6472 emit_insn (gen_macho_low (operands[0], target, operands[1]));
6473 return;
6476 emit_insn (gen_elf_high (target, operands[1]));
6477 emit_insn (gen_elf_low (operands[0], target, operands[1]));
6478 return;
6481 /* If this is a SYMBOL_REF that refers to a constant pool entry,
6482 and we have put it in the TOC, we just need to make a TOC-relative
6483 reference to it. */
6484 if (TARGET_TOC
6485 && GET_CODE (operands[1]) == SYMBOL_REF
6486 && constant_pool_expr_p (operands[1])
6487 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (operands[1]),
6488 get_pool_mode (operands[1])))
6490 operands[1] = create_TOC_reference (operands[1]);
6492 else if (mode == Pmode
6493 && CONSTANT_P (operands[1])
6494 && ((GET_CODE (operands[1]) != CONST_INT
6495 && ! easy_fp_constant (operands[1], mode))
6496 || (GET_CODE (operands[1]) == CONST_INT
6497 && num_insns_constant (operands[1], mode) > 2)
6498 || (GET_CODE (operands[0]) == REG
6499 && FP_REGNO_P (REGNO (operands[0]))))
6500 && GET_CODE (operands[1]) != HIGH
6501 && ! legitimate_constant_pool_address_p (operands[1])
6502 && ! toc_relative_expr_p (operands[1]))
6505 #if TARGET_MACHO
6506 /* Darwin uses a special PIC legitimizer. */
6507 if (DEFAULT_ABI == ABI_DARWIN && MACHOPIC_INDIRECT)
6509 operands[1] =
6510 rs6000_machopic_legitimize_pic_address (operands[1], mode,
6511 operands[0]);
6512 if (operands[0] != operands[1])
6513 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
6514 return;
6516 #endif
6518 /* If we are to limit the number of things we put in the TOC and
6519 this is a symbol plus a constant we can add in one insn,
6520 just put the symbol in the TOC and add the constant. Don't do
6521 this if reload is in progress. */
6522 if (GET_CODE (operands[1]) == CONST
6523 && TARGET_NO_SUM_IN_TOC && ! reload_in_progress
6524 && GET_CODE (XEXP (operands[1], 0)) == PLUS
6525 && add_operand (XEXP (XEXP (operands[1], 0), 1), mode)
6526 && (GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == LABEL_REF
6527 || GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == SYMBOL_REF)
6528 && ! side_effects_p (operands[0]))
6530 rtx sym =
6531 force_const_mem (mode, XEXP (XEXP (operands[1], 0), 0));
6532 rtx other = XEXP (XEXP (operands[1], 0), 1);
6534 sym = force_reg (mode, sym);
6535 emit_insn (gen_add3_insn (operands[0], sym, other));
6536 return;
6539 operands[1] = force_const_mem (mode, operands[1]);
6541 if (TARGET_TOC
6542 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
6543 && constant_pool_expr_p (XEXP (operands[1], 0))
6544 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (
6545 get_pool_constant (XEXP (operands[1], 0)),
6546 get_pool_mode (XEXP (operands[1], 0))))
6548 operands[1]
6549 = gen_const_mem (mode,
6550 create_TOC_reference (XEXP (operands[1], 0)));
6551 set_mem_alias_set (operands[1], get_TOC_alias_set ());
6554 break;
6556 case TImode:
6557 rs6000_eliminate_indexed_memrefs (operands);
6559 if (TARGET_POWER)
6561 emit_insn (gen_rtx_PARALLEL (VOIDmode,
6562 gen_rtvec (2,
6563 gen_rtx_SET (VOIDmode,
6564 operands[0], operands[1]),
6565 gen_rtx_CLOBBER (VOIDmode,
6566 gen_rtx_SCRATCH (SImode)))));
6567 return;
6569 break;
6571 default:
6572 fatal_insn ("bad move", gen_rtx_SET (VOIDmode, dest, source));
6575 /* Above, we may have called force_const_mem which may have returned
6576 an invalid address. If we can, fix this up; otherwise, reload will
6577 have to deal with it. */
6578 if (GET_CODE (operands[1]) == MEM && ! reload_in_progress)
6579 operands[1] = validize_mem (operands[1]);
6581 emit_set:
6582 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
6585 /* Nonzero if we can use a floating-point register to pass this arg. */
6586 #define USE_FP_FOR_ARG_P(CUM,MODE,TYPE) \
6587 (SCALAR_FLOAT_MODE_P (MODE) \
6588 && (CUM)->fregno <= FP_ARG_MAX_REG \
6589 && TARGET_HARD_FLOAT && TARGET_FPRS)
6591 /* Nonzero if we can use an AltiVec register to pass this arg. */
6592 #define USE_ALTIVEC_FOR_ARG_P(CUM,MODE,TYPE,NAMED) \
6593 ((ALTIVEC_VECTOR_MODE (MODE) || VSX_VECTOR_MODE (MODE)) \
6594 && (CUM)->vregno <= ALTIVEC_ARG_MAX_REG \
6595 && TARGET_ALTIVEC_ABI \
6596 && (NAMED))
6598 /* Return a nonzero value to say to return the function value in
6599 memory, just as large structures are always returned. TYPE will be
6600 the data type of the value, and FNTYPE will be the type of the
6601 function doing the returning, or @code{NULL} for libcalls.
6603 The AIX ABI for the RS/6000 specifies that all structures are
6604 returned in memory. The Darwin ABI does the same. The SVR4 ABI
6605 specifies that structures <= 8 bytes are returned in r3/r4, but a
6606 draft put them in memory, and GCC used to implement the draft
6607 instead of the final standard. Therefore, aix_struct_return
6608 controls this instead of DEFAULT_ABI; V.4 targets needing backward
6609 compatibility can change DRAFT_V4_STRUCT_RET to override the
6610 default, and -m switches get the final word. See
6611 rs6000_override_options for more details.
6613 The PPC32 SVR4 ABI uses IEEE double extended for long double, if 128-bit
6614 long double support is enabled. These values are returned in memory.
6616 int_size_in_bytes returns -1 for variable size objects, which go in
6617 memory always. The cast to unsigned makes -1 > 8. */
6619 static bool
6620 rs6000_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
6622 /* In the darwin64 abi, try to use registers for larger structs
6623 if possible. */
6624 if (rs6000_darwin64_abi
6625 && TREE_CODE (type) == RECORD_TYPE
6626 && int_size_in_bytes (type) > 0)
6628 CUMULATIVE_ARGS valcum;
6629 rtx valret;
6631 valcum.words = 0;
6632 valcum.fregno = FP_ARG_MIN_REG;
6633 valcum.vregno = ALTIVEC_ARG_MIN_REG;
6634 /* Do a trial code generation as if this were going to be passed
6635 as an argument; if any part goes in memory, we return NULL. */
6636 valret = rs6000_darwin64_record_arg (&valcum, type, 1, true);
6637 if (valret)
6638 return false;
6639 /* Otherwise fall through to more conventional ABI rules. */
6642 if (AGGREGATE_TYPE_P (type)
6643 && (aix_struct_return
6644 || (unsigned HOST_WIDE_INT) int_size_in_bytes (type) > 8))
6645 return true;
6647 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
6648 modes only exist for GCC vector types if -maltivec. */
6649 if (TARGET_32BIT && !TARGET_ALTIVEC_ABI
6650 && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
6651 return false;
6653 /* Return synthetic vectors in memory. */
6654 if (TREE_CODE (type) == VECTOR_TYPE
6655 && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
6657 static bool warned_for_return_big_vectors = false;
6658 if (!warned_for_return_big_vectors)
6660 warning (0, "GCC vector returned by reference: "
6661 "non-standard ABI extension with no compatibility guarantee");
6662 warned_for_return_big_vectors = true;
6664 return true;
6667 if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && TYPE_MODE (type) == TFmode)
6668 return true;
6670 return false;
6673 /* Initialize a variable CUM of type CUMULATIVE_ARGS
6674 for a call to a function whose data type is FNTYPE.
6675 For a library call, FNTYPE is 0.
6677 For incoming args we set the number of arguments in the prototype large
6678 so we never return a PARALLEL. */
6680 void
6681 init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype,
6682 rtx libname ATTRIBUTE_UNUSED, int incoming,
6683 int libcall, int n_named_args)
6685 static CUMULATIVE_ARGS zero_cumulative;
6687 *cum = zero_cumulative;
6688 cum->words = 0;
6689 cum->fregno = FP_ARG_MIN_REG;
6690 cum->vregno = ALTIVEC_ARG_MIN_REG;
6691 cum->prototype = (fntype && TYPE_ARG_TYPES (fntype));
6692 cum->call_cookie = ((DEFAULT_ABI == ABI_V4 && libcall)
6693 ? CALL_LIBCALL : CALL_NORMAL);
6694 cum->sysv_gregno = GP_ARG_MIN_REG;
6695 cum->stdarg = fntype
6696 && (TYPE_ARG_TYPES (fntype) != 0
6697 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
6698 != void_type_node));
6700 cum->nargs_prototype = 0;
6701 if (incoming || cum->prototype)
6702 cum->nargs_prototype = n_named_args;
6704 /* Check for a longcall attribute. */
6705 if ((!fntype && rs6000_default_long_calls)
6706 || (fntype
6707 && lookup_attribute ("longcall", TYPE_ATTRIBUTES (fntype))
6708 && !lookup_attribute ("shortcall", TYPE_ATTRIBUTES (fntype))))
6709 cum->call_cookie |= CALL_LONG;
6711 if (TARGET_DEBUG_ARG)
6713 fprintf (stderr, "\ninit_cumulative_args:");
6714 if (fntype)
6716 tree ret_type = TREE_TYPE (fntype);
6717 fprintf (stderr, " ret code = %s,",
6718 tree_code_name[ (int)TREE_CODE (ret_type) ]);
6721 if (cum->call_cookie & CALL_LONG)
6722 fprintf (stderr, " longcall,");
6724 fprintf (stderr, " proto = %d, nargs = %d\n",
6725 cum->prototype, cum->nargs_prototype);
6728 if (fntype
6729 && !TARGET_ALTIVEC
6730 && TARGET_ALTIVEC_ABI
6731 && ALTIVEC_VECTOR_MODE (TYPE_MODE (TREE_TYPE (fntype))))
6733 error ("cannot return value in vector register because"
6734 " altivec instructions are disabled, use -maltivec"
6735 " to enable them");
6739 /* Return true if TYPE must be passed on the stack and not in registers. */
6741 static bool
6742 rs6000_must_pass_in_stack (enum machine_mode mode, const_tree type)
6744 if (DEFAULT_ABI == ABI_AIX || TARGET_64BIT)
6745 return must_pass_in_stack_var_size (mode, type);
6746 else
6747 return must_pass_in_stack_var_size_or_pad (mode, type);
6750 /* If defined, a C expression which determines whether, and in which
6751 direction, to pad out an argument with extra space. The value
6752 should be of type `enum direction': either `upward' to pad above
6753 the argument, `downward' to pad below, or `none' to inhibit
6754 padding.
6756 For the AIX ABI structs are always stored left shifted in their
6757 argument slot. */
6759 enum direction
6760 function_arg_padding (enum machine_mode mode, const_tree type)
6762 #ifndef AGGREGATE_PADDING_FIXED
6763 #define AGGREGATE_PADDING_FIXED 0
6764 #endif
6765 #ifndef AGGREGATES_PAD_UPWARD_ALWAYS
6766 #define AGGREGATES_PAD_UPWARD_ALWAYS 0
6767 #endif
6769 if (!AGGREGATE_PADDING_FIXED)
6771 /* GCC used to pass structures of the same size as integer types as
6772 if they were in fact integers, ignoring FUNCTION_ARG_PADDING.
6773 i.e. Structures of size 1 or 2 (or 4 when TARGET_64BIT) were
6774 passed padded downward, except that -mstrict-align further
6775 muddied the water in that multi-component structures of 2 and 4
6776 bytes in size were passed padded upward.
6778 The following arranges for best compatibility with previous
6779 versions of gcc, but removes the -mstrict-align dependency. */
6780 if (BYTES_BIG_ENDIAN)
6782 HOST_WIDE_INT size = 0;
6784 if (mode == BLKmode)
6786 if (type && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST)
6787 size = int_size_in_bytes (type);
6789 else
6790 size = GET_MODE_SIZE (mode);
6792 if (size == 1 || size == 2 || size == 4)
6793 return downward;
6795 return upward;
6798 if (AGGREGATES_PAD_UPWARD_ALWAYS)
6800 if (type != 0 && AGGREGATE_TYPE_P (type))
6801 return upward;
6804 /* Fall back to the default. */
6805 return DEFAULT_FUNCTION_ARG_PADDING (mode, type);
6808 /* If defined, a C expression that gives the alignment boundary, in bits,
6809 of an argument with the specified mode and type. If it is not defined,
6810 PARM_BOUNDARY is used for all arguments.
6812 V.4 wants long longs and doubles to be double word aligned. Just
6813 testing the mode size is a boneheaded way to do this as it means
6814 that other types such as complex int are also double word aligned.
6815 However, we're stuck with this because changing the ABI might break
6816 existing library interfaces.
6818 Doubleword align SPE vectors.
6819 Quadword align Altivec vectors.
6820 Quadword align large synthetic vector types. */
6823 function_arg_boundary (enum machine_mode mode, tree type)
6825 if (DEFAULT_ABI == ABI_V4
6826 && (GET_MODE_SIZE (mode) == 8
6827 || (TARGET_HARD_FLOAT
6828 && TARGET_FPRS
6829 && (mode == TFmode || mode == TDmode))))
6830 return 64;
6831 else if (SPE_VECTOR_MODE (mode)
6832 || (type && TREE_CODE (type) == VECTOR_TYPE
6833 && int_size_in_bytes (type) >= 8
6834 && int_size_in_bytes (type) < 16))
6835 return 64;
6836 else if ((ALTIVEC_VECTOR_MODE (mode) || VSX_VECTOR_MODE (mode))
6837 || (type && TREE_CODE (type) == VECTOR_TYPE
6838 && int_size_in_bytes (type) >= 16))
6839 return 128;
6840 else if (rs6000_darwin64_abi && mode == BLKmode
6841 && type && TYPE_ALIGN (type) > 64)
6842 return 128;
6843 else
6844 return PARM_BOUNDARY;
6847 /* For a function parm of MODE and TYPE, return the starting word in
6848 the parameter area. NWORDS of the parameter area are already used. */
6850 static unsigned int
6851 rs6000_parm_start (enum machine_mode mode, tree type, unsigned int nwords)
6853 unsigned int align;
6854 unsigned int parm_offset;
6856 align = function_arg_boundary (mode, type) / PARM_BOUNDARY - 1;
6857 parm_offset = DEFAULT_ABI == ABI_V4 ? 2 : 6;
6858 return nwords + (-(parm_offset + nwords) & align);
6861 /* Compute the size (in words) of a function argument. */
6863 static unsigned long
6864 rs6000_arg_size (enum machine_mode mode, tree type)
6866 unsigned long size;
6868 if (mode != BLKmode)
6869 size = GET_MODE_SIZE (mode);
6870 else
6871 size = int_size_in_bytes (type);
6873 if (TARGET_32BIT)
6874 return (size + 3) >> 2;
6875 else
6876 return (size + 7) >> 3;
6879 /* Use this to flush pending int fields. */
6881 static void
6882 rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS *cum,
6883 HOST_WIDE_INT bitpos)
6885 unsigned int startbit, endbit;
6886 int intregs, intoffset;
6887 enum machine_mode mode;
6889 if (cum->intoffset == -1)
6890 return;
6892 intoffset = cum->intoffset;
6893 cum->intoffset = -1;
6895 if (intoffset % BITS_PER_WORD != 0)
6897 mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD,
6898 MODE_INT, 0);
6899 if (mode == BLKmode)
6901 /* We couldn't find an appropriate mode, which happens,
6902 e.g., in packed structs when there are 3 bytes to load.
6903 Back intoffset back to the beginning of the word in this
6904 case. */
6905 intoffset = intoffset & -BITS_PER_WORD;
6909 startbit = intoffset & -BITS_PER_WORD;
6910 endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD;
6911 intregs = (endbit - startbit) / BITS_PER_WORD;
6912 cum->words += intregs;
6915 /* The darwin64 ABI calls for us to recurse down through structs,
6916 looking for elements passed in registers. Unfortunately, we have
6917 to track int register count here also because of misalignments
6918 in powerpc alignment mode. */
6920 static void
6921 rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS *cum,
6922 tree type,
6923 HOST_WIDE_INT startbitpos)
6925 tree f;
6927 for (f = TYPE_FIELDS (type); f ; f = TREE_CHAIN (f))
6928 if (TREE_CODE (f) == FIELD_DECL)
6930 HOST_WIDE_INT bitpos = startbitpos;
6931 tree ftype = TREE_TYPE (f);
6932 enum machine_mode mode;
6933 if (ftype == error_mark_node)
6934 continue;
6935 mode = TYPE_MODE (ftype);
6937 if (DECL_SIZE (f) != 0
6938 && host_integerp (bit_position (f), 1))
6939 bitpos += int_bit_position (f);
6941 /* ??? FIXME: else assume zero offset. */
6943 if (TREE_CODE (ftype) == RECORD_TYPE)
6944 rs6000_darwin64_record_arg_advance_recurse (cum, ftype, bitpos);
6945 else if (USE_FP_FOR_ARG_P (cum, mode, ftype))
6947 rs6000_darwin64_record_arg_advance_flush (cum, bitpos);
6948 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
6949 cum->words += (GET_MODE_SIZE (mode) + 7) >> 3;
6951 else if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, 1))
6953 rs6000_darwin64_record_arg_advance_flush (cum, bitpos);
6954 cum->vregno++;
6955 cum->words += 2;
6957 else if (cum->intoffset == -1)
6958 cum->intoffset = bitpos;
6962 /* Update the data in CUM to advance over an argument
6963 of mode MODE and data type TYPE.
6964 (TYPE is null for libcalls where that information may not be available.)
6966 Note that for args passed by reference, function_arg will be called
6967 with MODE and TYPE set to that of the pointer to the arg, not the arg
6968 itself. */
6970 void
6971 function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
6972 tree type, int named, int depth)
6974 int size;
6976 /* Only tick off an argument if we're not recursing. */
6977 if (depth == 0)
6978 cum->nargs_prototype--;
6980 if (TARGET_ALTIVEC_ABI
6981 && (ALTIVEC_VECTOR_MODE (mode)
6982 || VSX_VECTOR_MODE (mode)
6983 || (type && TREE_CODE (type) == VECTOR_TYPE
6984 && int_size_in_bytes (type) == 16)))
6986 bool stack = false;
6988 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
6990 cum->vregno++;
6991 if (!TARGET_ALTIVEC)
6992 error ("cannot pass argument in vector register because"
6993 " altivec instructions are disabled, use -maltivec"
6994 " to enable them");
6996 /* PowerPC64 Linux and AIX allocate GPRs for a vector argument
6997 even if it is going to be passed in a vector register.
6998 Darwin does the same for variable-argument functions. */
6999 if ((DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
7000 || (cum->stdarg && DEFAULT_ABI != ABI_V4))
7001 stack = true;
7003 else
7004 stack = true;
7006 if (stack)
7008 int align;
7010 /* Vector parameters must be 16-byte aligned. This places
7011 them at 2 mod 4 in terms of words in 32-bit mode, since
7012 the parameter save area starts at offset 24 from the
7013 stack. In 64-bit mode, they just have to start on an
7014 even word, since the parameter save area is 16-byte
7015 aligned. Space for GPRs is reserved even if the argument
7016 will be passed in memory. */
7017 if (TARGET_32BIT)
7018 align = (2 - cum->words) & 3;
7019 else
7020 align = cum->words & 1;
7021 cum->words += align + rs6000_arg_size (mode, type);
7023 if (TARGET_DEBUG_ARG)
7025 fprintf (stderr, "function_adv: words = %2d, align=%d, ",
7026 cum->words, align);
7027 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s\n",
7028 cum->nargs_prototype, cum->prototype,
7029 GET_MODE_NAME (mode));
7033 else if (TARGET_SPE_ABI && TARGET_SPE && SPE_VECTOR_MODE (mode)
7034 && !cum->stdarg
7035 && cum->sysv_gregno <= GP_ARG_MAX_REG)
7036 cum->sysv_gregno++;
7038 else if (rs6000_darwin64_abi
7039 && mode == BLKmode
7040 && TREE_CODE (type) == RECORD_TYPE
7041 && (size = int_size_in_bytes (type)) > 0)
7043 /* Variable sized types have size == -1 and are
7044 treated as if consisting entirely of ints.
7045 Pad to 16 byte boundary if needed. */
7046 if (TYPE_ALIGN (type) >= 2 * BITS_PER_WORD
7047 && (cum->words % 2) != 0)
7048 cum->words++;
7049 /* For varargs, we can just go up by the size of the struct. */
7050 if (!named)
7051 cum->words += (size + 7) / 8;
7052 else
7054 /* It is tempting to say int register count just goes up by
7055 sizeof(type)/8, but this is wrong in a case such as
7056 { int; double; int; } [powerpc alignment]. We have to
7057 grovel through the fields for these too. */
7058 cum->intoffset = 0;
7059 rs6000_darwin64_record_arg_advance_recurse (cum, type, 0);
7060 rs6000_darwin64_record_arg_advance_flush (cum,
7061 size * BITS_PER_UNIT);
7064 else if (DEFAULT_ABI == ABI_V4)
7066 if (TARGET_HARD_FLOAT && TARGET_FPRS
7067 && ((TARGET_SINGLE_FLOAT && mode == SFmode)
7068 || (TARGET_DOUBLE_FLOAT && mode == DFmode)
7069 || (mode == TFmode && !TARGET_IEEEQUAD)
7070 || mode == SDmode || mode == DDmode || mode == TDmode))
7072 /* _Decimal128 must use an even/odd register pair. This assumes
7073 that the register number is odd when fregno is odd. */
7074 if (mode == TDmode && (cum->fregno % 2) == 1)
7075 cum->fregno++;
7077 if (cum->fregno + (mode == TFmode || mode == TDmode ? 1 : 0)
7078 <= FP_ARG_V4_MAX_REG)
7079 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
7080 else
7082 cum->fregno = FP_ARG_V4_MAX_REG + 1;
7083 if (mode == DFmode || mode == TFmode
7084 || mode == DDmode || mode == TDmode)
7085 cum->words += cum->words & 1;
7086 cum->words += rs6000_arg_size (mode, type);
7089 else
7091 int n_words = rs6000_arg_size (mode, type);
7092 int gregno = cum->sysv_gregno;
7094 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
7095 (r7,r8) or (r9,r10). As does any other 2 word item such
7096 as complex int due to a historical mistake. */
7097 if (n_words == 2)
7098 gregno += (1 - gregno) & 1;
7100 /* Multi-reg args are not split between registers and stack. */
7101 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
7103 /* Long long and SPE vectors are aligned on the stack.
7104 So are other 2 word items such as complex int due to
7105 a historical mistake. */
7106 if (n_words == 2)
7107 cum->words += cum->words & 1;
7108 cum->words += n_words;
7111 /* Note: continuing to accumulate gregno past when we've started
7112 spilling to the stack indicates the fact that we've started
7113 spilling to the stack to expand_builtin_saveregs. */
7114 cum->sysv_gregno = gregno + n_words;
7117 if (TARGET_DEBUG_ARG)
7119 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
7120 cum->words, cum->fregno);
7121 fprintf (stderr, "gregno = %2d, nargs = %4d, proto = %d, ",
7122 cum->sysv_gregno, cum->nargs_prototype, cum->prototype);
7123 fprintf (stderr, "mode = %4s, named = %d\n",
7124 GET_MODE_NAME (mode), named);
7127 else
7129 int n_words = rs6000_arg_size (mode, type);
7130 int start_words = cum->words;
7131 int align_words = rs6000_parm_start (mode, type, start_words);
7133 cum->words = align_words + n_words;
7135 if (SCALAR_FLOAT_MODE_P (mode)
7136 && TARGET_HARD_FLOAT && TARGET_FPRS)
7138 /* _Decimal128 must be passed in an even/odd float register pair.
7139 This assumes that the register number is odd when fregno is
7140 odd. */
7141 if (mode == TDmode && (cum->fregno % 2) == 1)
7142 cum->fregno++;
7143 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
7146 if (TARGET_DEBUG_ARG)
7148 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
7149 cum->words, cum->fregno);
7150 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s, ",
7151 cum->nargs_prototype, cum->prototype, GET_MODE_NAME (mode));
7152 fprintf (stderr, "named = %d, align = %d, depth = %d\n",
7153 named, align_words - start_words, depth);
7158 static rtx
7159 spe_build_register_parallel (enum machine_mode mode, int gregno)
7161 rtx r1, r3, r5, r7;
7163 switch (mode)
7165 case DFmode:
7166 r1 = gen_rtx_REG (DImode, gregno);
7167 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
7168 return gen_rtx_PARALLEL (mode, gen_rtvec (1, r1));
7170 case DCmode:
7171 case TFmode:
7172 r1 = gen_rtx_REG (DImode, gregno);
7173 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
7174 r3 = gen_rtx_REG (DImode, gregno + 2);
7175 r3 = gen_rtx_EXPR_LIST (VOIDmode, r3, GEN_INT (8));
7176 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r3));
7178 case TCmode:
7179 r1 = gen_rtx_REG (DImode, gregno);
7180 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
7181 r3 = gen_rtx_REG (DImode, gregno + 2);
7182 r3 = gen_rtx_EXPR_LIST (VOIDmode, r3, GEN_INT (8));
7183 r5 = gen_rtx_REG (DImode, gregno + 4);
7184 r5 = gen_rtx_EXPR_LIST (VOIDmode, r5, GEN_INT (16));
7185 r7 = gen_rtx_REG (DImode, gregno + 6);
7186 r7 = gen_rtx_EXPR_LIST (VOIDmode, r7, GEN_INT (24));
7187 return gen_rtx_PARALLEL (mode, gen_rtvec (4, r1, r3, r5, r7));
7189 default:
7190 gcc_unreachable ();
7194 /* Determine where to put a SIMD argument on the SPE. */
7195 static rtx
7196 rs6000_spe_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
7197 tree type)
7199 int gregno = cum->sysv_gregno;
7201 /* On E500 v2, double arithmetic is done on the full 64-bit GPR, but
7202 are passed and returned in a pair of GPRs for ABI compatibility. */
7203 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
7204 || mode == DCmode || mode == TCmode))
7206 int n_words = rs6000_arg_size (mode, type);
7208 /* Doubles go in an odd/even register pair (r5/r6, etc). */
7209 if (mode == DFmode)
7210 gregno += (1 - gregno) & 1;
7212 /* Multi-reg args are not split between registers and stack. */
7213 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
7214 return NULL_RTX;
7216 return spe_build_register_parallel (mode, gregno);
7218 if (cum->stdarg)
7220 int n_words = rs6000_arg_size (mode, type);
7222 /* SPE vectors are put in odd registers. */
7223 if (n_words == 2 && (gregno & 1) == 0)
7224 gregno += 1;
7226 if (gregno + n_words - 1 <= GP_ARG_MAX_REG)
7228 rtx r1, r2;
7229 enum machine_mode m = SImode;
7231 r1 = gen_rtx_REG (m, gregno);
7232 r1 = gen_rtx_EXPR_LIST (m, r1, const0_rtx);
7233 r2 = gen_rtx_REG (m, gregno + 1);
7234 r2 = gen_rtx_EXPR_LIST (m, r2, GEN_INT (4));
7235 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
7237 else
7238 return NULL_RTX;
7240 else
7242 if (gregno <= GP_ARG_MAX_REG)
7243 return gen_rtx_REG (mode, gregno);
7244 else
7245 return NULL_RTX;
7249 /* A subroutine of rs6000_darwin64_record_arg. Assign the bits of the
7250 structure between cum->intoffset and bitpos to integer registers. */
7252 static void
7253 rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS *cum,
7254 HOST_WIDE_INT bitpos, rtx rvec[], int *k)
7256 enum machine_mode mode;
7257 unsigned int regno;
7258 unsigned int startbit, endbit;
7259 int this_regno, intregs, intoffset;
7260 rtx reg;
7262 if (cum->intoffset == -1)
7263 return;
7265 intoffset = cum->intoffset;
7266 cum->intoffset = -1;
7268 /* If this is the trailing part of a word, try to only load that
7269 much into the register. Otherwise load the whole register. Note
7270 that in the latter case we may pick up unwanted bits. It's not a
7271 problem at the moment but may wish to revisit. */
7273 if (intoffset % BITS_PER_WORD != 0)
7275 mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD,
7276 MODE_INT, 0);
7277 if (mode == BLKmode)
7279 /* We couldn't find an appropriate mode, which happens,
7280 e.g., in packed structs when there are 3 bytes to load.
7281 Back intoffset back to the beginning of the word in this
7282 case. */
7283 intoffset = intoffset & -BITS_PER_WORD;
7284 mode = word_mode;
7287 else
7288 mode = word_mode;
7290 startbit = intoffset & -BITS_PER_WORD;
7291 endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD;
7292 intregs = (endbit - startbit) / BITS_PER_WORD;
7293 this_regno = cum->words + intoffset / BITS_PER_WORD;
7295 if (intregs > 0 && intregs > GP_ARG_NUM_REG - this_regno)
7296 cum->use_stack = 1;
7298 intregs = MIN (intregs, GP_ARG_NUM_REG - this_regno);
7299 if (intregs <= 0)
7300 return;
7302 intoffset /= BITS_PER_UNIT;
7305 regno = GP_ARG_MIN_REG + this_regno;
7306 reg = gen_rtx_REG (mode, regno);
7307 rvec[(*k)++] =
7308 gen_rtx_EXPR_LIST (VOIDmode, reg, GEN_INT (intoffset));
7310 this_regno += 1;
7311 intoffset = (intoffset | (UNITS_PER_WORD-1)) + 1;
7312 mode = word_mode;
7313 intregs -= 1;
7315 while (intregs > 0);
7318 /* Recursive workhorse for the following. */
7320 static void
7321 rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *cum, const_tree type,
7322 HOST_WIDE_INT startbitpos, rtx rvec[],
7323 int *k)
7325 tree f;
7327 for (f = TYPE_FIELDS (type); f ; f = TREE_CHAIN (f))
7328 if (TREE_CODE (f) == FIELD_DECL)
7330 HOST_WIDE_INT bitpos = startbitpos;
7331 tree ftype = TREE_TYPE (f);
7332 enum machine_mode mode;
7333 if (ftype == error_mark_node)
7334 continue;
7335 mode = TYPE_MODE (ftype);
7337 if (DECL_SIZE (f) != 0
7338 && host_integerp (bit_position (f), 1))
7339 bitpos += int_bit_position (f);
7341 /* ??? FIXME: else assume zero offset. */
7343 if (TREE_CODE (ftype) == RECORD_TYPE)
7344 rs6000_darwin64_record_arg_recurse (cum, ftype, bitpos, rvec, k);
7345 else if (cum->named && USE_FP_FOR_ARG_P (cum, mode, ftype))
7347 #if 0
7348 switch (mode)
7350 case SCmode: mode = SFmode; break;
7351 case DCmode: mode = DFmode; break;
7352 case TCmode: mode = TFmode; break;
7353 default: break;
7355 #endif
7356 rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
7357 rvec[(*k)++]
7358 = gen_rtx_EXPR_LIST (VOIDmode,
7359 gen_rtx_REG (mode, cum->fregno++),
7360 GEN_INT (bitpos / BITS_PER_UNIT));
7361 if (mode == TFmode || mode == TDmode)
7362 cum->fregno++;
7364 else if (cum->named && USE_ALTIVEC_FOR_ARG_P (cum, mode, ftype, 1))
7366 rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
7367 rvec[(*k)++]
7368 = gen_rtx_EXPR_LIST (VOIDmode,
7369 gen_rtx_REG (mode, cum->vregno++),
7370 GEN_INT (bitpos / BITS_PER_UNIT));
7372 else if (cum->intoffset == -1)
7373 cum->intoffset = bitpos;
7377 /* For the darwin64 ABI, we want to construct a PARALLEL consisting of
7378 the register(s) to be used for each field and subfield of a struct
7379 being passed by value, along with the offset of where the
7380 register's value may be found in the block. FP fields go in FP
7381 register, vector fields go in vector registers, and everything
7382 else goes in int registers, packed as in memory.
7384 This code is also used for function return values. RETVAL indicates
7385 whether this is the case.
7387 Much of this is taken from the SPARC V9 port, which has a similar
7388 calling convention. */
7390 static rtx
7391 rs6000_darwin64_record_arg (CUMULATIVE_ARGS *orig_cum, const_tree type,
7392 int named, bool retval)
7394 rtx rvec[FIRST_PSEUDO_REGISTER];
7395 int k = 1, kbase = 1;
7396 HOST_WIDE_INT typesize = int_size_in_bytes (type);
7397 /* This is a copy; modifications are not visible to our caller. */
7398 CUMULATIVE_ARGS copy_cum = *orig_cum;
7399 CUMULATIVE_ARGS *cum = &copy_cum;
7401 /* Pad to 16 byte boundary if needed. */
7402 if (!retval && TYPE_ALIGN (type) >= 2 * BITS_PER_WORD
7403 && (cum->words % 2) != 0)
7404 cum->words++;
7406 cum->intoffset = 0;
7407 cum->use_stack = 0;
7408 cum->named = named;
7410 /* Put entries into rvec[] for individual FP and vector fields, and
7411 for the chunks of memory that go in int regs. Note we start at
7412 element 1; 0 is reserved for an indication of using memory, and
7413 may or may not be filled in below. */
7414 rs6000_darwin64_record_arg_recurse (cum, type, 0, rvec, &k);
7415 rs6000_darwin64_record_arg_flush (cum, typesize * BITS_PER_UNIT, rvec, &k);
7417 /* If any part of the struct went on the stack put all of it there.
7418 This hack is because the generic code for
7419 FUNCTION_ARG_PARTIAL_NREGS cannot handle cases where the register
7420 parts of the struct are not at the beginning. */
7421 if (cum->use_stack)
7423 if (retval)
7424 return NULL_RTX; /* doesn't go in registers at all */
7425 kbase = 0;
7426 rvec[0] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
7428 if (k > 1 || cum->use_stack)
7429 return gen_rtx_PARALLEL (BLKmode, gen_rtvec_v (k - kbase, &rvec[kbase]));
7430 else
7431 return NULL_RTX;
7434 /* Determine where to place an argument in 64-bit mode with 32-bit ABI. */
7436 static rtx
7437 rs6000_mixed_function_arg (enum machine_mode mode, tree type, int align_words)
7439 int n_units;
7440 int i, k;
7441 rtx rvec[GP_ARG_NUM_REG + 1];
7443 if (align_words >= GP_ARG_NUM_REG)
7444 return NULL_RTX;
7446 n_units = rs6000_arg_size (mode, type);
7448 /* Optimize the simple case where the arg fits in one gpr, except in
7449 the case of BLKmode due to assign_parms assuming that registers are
7450 BITS_PER_WORD wide. */
7451 if (n_units == 0
7452 || (n_units == 1 && mode != BLKmode))
7453 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
7455 k = 0;
7456 if (align_words + n_units > GP_ARG_NUM_REG)
7457 /* Not all of the arg fits in gprs. Say that it goes in memory too,
7458 using a magic NULL_RTX component.
7459 This is not strictly correct. Only some of the arg belongs in
7460 memory, not all of it. However, the normal scheme using
7461 function_arg_partial_nregs can result in unusual subregs, eg.
7462 (subreg:SI (reg:DF) 4), which are not handled well. The code to
7463 store the whole arg to memory is often more efficient than code
7464 to store pieces, and we know that space is available in the right
7465 place for the whole arg. */
7466 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
7468 i = 0;
7471 rtx r = gen_rtx_REG (SImode, GP_ARG_MIN_REG + align_words);
7472 rtx off = GEN_INT (i++ * 4);
7473 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
7475 while (++align_words < GP_ARG_NUM_REG && --n_units != 0);
7477 return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
7480 /* Determine where to put an argument to a function.
7481 Value is zero to push the argument on the stack,
7482 or a hard register in which to store the argument.
7484 MODE is the argument's machine mode.
7485 TYPE is the data type of the argument (as a tree).
7486 This is null for libcalls where that information may
7487 not be available.
7488 CUM is a variable of type CUMULATIVE_ARGS which gives info about
7489 the preceding args and about the function being called. It is
7490 not modified in this routine.
7491 NAMED is nonzero if this argument is a named parameter
7492 (otherwise it is an extra parameter matching an ellipsis).
7494 On RS/6000 the first eight words of non-FP are normally in registers
7495 and the rest are pushed. Under AIX, the first 13 FP args are in registers.
7496 Under V.4, the first 8 FP args are in registers.
7498 If this is floating-point and no prototype is specified, we use
7499 both an FP and integer register (or possibly FP reg and stack). Library
7500 functions (when CALL_LIBCALL is set) always have the proper types for args,
7501 so we can pass the FP value just in one register. emit_library_function
7502 doesn't support PARALLEL anyway.
7504 Note that for args passed by reference, function_arg will be called
7505 with MODE and TYPE set to that of the pointer to the arg, not the arg
7506 itself. */
7509 function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
7510 tree type, int named)
7512 enum rs6000_abi abi = DEFAULT_ABI;
7514 /* Return a marker to indicate whether CR1 needs to set or clear the
7515 bit that V.4 uses to say fp args were passed in registers.
7516 Assume that we don't need the marker for software floating point,
7517 or compiler generated library calls. */
7518 if (mode == VOIDmode)
7520 if (abi == ABI_V4
7521 && (cum->call_cookie & CALL_LIBCALL) == 0
7522 && (cum->stdarg
7523 || (cum->nargs_prototype < 0
7524 && (cum->prototype || TARGET_NO_PROTOTYPE))))
7526 /* For the SPE, we need to crxor CR6 always. */
7527 if (TARGET_SPE_ABI)
7528 return GEN_INT (cum->call_cookie | CALL_V4_SET_FP_ARGS);
7529 else if (TARGET_HARD_FLOAT && TARGET_FPRS)
7530 return GEN_INT (cum->call_cookie
7531 | ((cum->fregno == FP_ARG_MIN_REG)
7532 ? CALL_V4_SET_FP_ARGS
7533 : CALL_V4_CLEAR_FP_ARGS));
7536 return GEN_INT (cum->call_cookie);
7539 if (rs6000_darwin64_abi && mode == BLKmode
7540 && TREE_CODE (type) == RECORD_TYPE)
7542 rtx rslt = rs6000_darwin64_record_arg (cum, type, named, false);
7543 if (rslt != NULL_RTX)
7544 return rslt;
7545 /* Else fall through to usual handling. */
7548 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
7549 if (TARGET_64BIT && ! cum->prototype)
7551 /* Vector parameters get passed in vector register
7552 and also in GPRs or memory, in absence of prototype. */
7553 int align_words;
7554 rtx slot;
7555 align_words = (cum->words + 1) & ~1;
7557 if (align_words >= GP_ARG_NUM_REG)
7559 slot = NULL_RTX;
7561 else
7563 slot = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
7565 return gen_rtx_PARALLEL (mode,
7566 gen_rtvec (2,
7567 gen_rtx_EXPR_LIST (VOIDmode,
7568 slot, const0_rtx),
7569 gen_rtx_EXPR_LIST (VOIDmode,
7570 gen_rtx_REG (mode, cum->vregno),
7571 const0_rtx)));
7573 else
7574 return gen_rtx_REG (mode, cum->vregno);
7575 else if (TARGET_ALTIVEC_ABI
7576 && (ALTIVEC_VECTOR_MODE (mode)
7577 || VSX_VECTOR_MODE (mode)
7578 || (type && TREE_CODE (type) == VECTOR_TYPE
7579 && int_size_in_bytes (type) == 16)))
7581 if (named || abi == ABI_V4)
7582 return NULL_RTX;
7583 else
7585 /* Vector parameters to varargs functions under AIX or Darwin
7586 get passed in memory and possibly also in GPRs. */
7587 int align, align_words, n_words;
7588 enum machine_mode part_mode;
7590 /* Vector parameters must be 16-byte aligned. This places them at
7591 2 mod 4 in terms of words in 32-bit mode, since the parameter
7592 save area starts at offset 24 from the stack. In 64-bit mode,
7593 they just have to start on an even word, since the parameter
7594 save area is 16-byte aligned. */
7595 if (TARGET_32BIT)
7596 align = (2 - cum->words) & 3;
7597 else
7598 align = cum->words & 1;
7599 align_words = cum->words + align;
7601 /* Out of registers? Memory, then. */
7602 if (align_words >= GP_ARG_NUM_REG)
7603 return NULL_RTX;
7605 if (TARGET_32BIT && TARGET_POWERPC64)
7606 return rs6000_mixed_function_arg (mode, type, align_words);
7608 /* The vector value goes in GPRs. Only the part of the
7609 value in GPRs is reported here. */
7610 part_mode = mode;
7611 n_words = rs6000_arg_size (mode, type);
7612 if (align_words + n_words > GP_ARG_NUM_REG)
7613 /* Fortunately, there are only two possibilities, the value
7614 is either wholly in GPRs or half in GPRs and half not. */
7615 part_mode = DImode;
7617 return gen_rtx_REG (part_mode, GP_ARG_MIN_REG + align_words);
7620 else if (TARGET_SPE_ABI && TARGET_SPE
7621 && (SPE_VECTOR_MODE (mode)
7622 || (TARGET_E500_DOUBLE && (mode == DFmode
7623 || mode == DCmode
7624 || mode == TFmode
7625 || mode == TCmode))))
7626 return rs6000_spe_function_arg (cum, mode, type);
7628 else if (abi == ABI_V4)
7630 if (TARGET_HARD_FLOAT && TARGET_FPRS
7631 && ((TARGET_SINGLE_FLOAT && mode == SFmode)
7632 || (TARGET_DOUBLE_FLOAT && mode == DFmode)
7633 || (mode == TFmode && !TARGET_IEEEQUAD)
7634 || mode == SDmode || mode == DDmode || mode == TDmode))
7636 /* _Decimal128 must use an even/odd register pair. This assumes
7637 that the register number is odd when fregno is odd. */
7638 if (mode == TDmode && (cum->fregno % 2) == 1)
7639 cum->fregno++;
7641 if (cum->fregno + (mode == TFmode || mode == TDmode ? 1 : 0)
7642 <= FP_ARG_V4_MAX_REG)
7643 return gen_rtx_REG (mode, cum->fregno);
7644 else
7645 return NULL_RTX;
7647 else
7649 int n_words = rs6000_arg_size (mode, type);
7650 int gregno = cum->sysv_gregno;
7652 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
7653 (r7,r8) or (r9,r10). As does any other 2 word item such
7654 as complex int due to a historical mistake. */
7655 if (n_words == 2)
7656 gregno += (1 - gregno) & 1;
7658 /* Multi-reg args are not split between registers and stack. */
7659 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
7660 return NULL_RTX;
7662 if (TARGET_32BIT && TARGET_POWERPC64)
7663 return rs6000_mixed_function_arg (mode, type,
7664 gregno - GP_ARG_MIN_REG);
7665 return gen_rtx_REG (mode, gregno);
7668 else
7670 int align_words = rs6000_parm_start (mode, type, cum->words);
7672 /* _Decimal128 must be passed in an even/odd float register pair.
7673 This assumes that the register number is odd when fregno is odd. */
7674 if (mode == TDmode && (cum->fregno % 2) == 1)
7675 cum->fregno++;
7677 if (USE_FP_FOR_ARG_P (cum, mode, type))
7679 rtx rvec[GP_ARG_NUM_REG + 1];
7680 rtx r;
7681 int k;
7682 bool needs_psave;
7683 enum machine_mode fmode = mode;
7684 unsigned long n_fpreg = (GET_MODE_SIZE (mode) + 7) >> 3;
7686 if (cum->fregno + n_fpreg > FP_ARG_MAX_REG + 1)
7688 /* Currently, we only ever need one reg here because complex
7689 doubles are split. */
7690 gcc_assert (cum->fregno == FP_ARG_MAX_REG
7691 && (fmode == TFmode || fmode == TDmode));
7693 /* Long double or _Decimal128 split over regs and memory. */
7694 fmode = DECIMAL_FLOAT_MODE_P (fmode) ? DDmode : DFmode;
7697 /* Do we also need to pass this arg in the parameter save
7698 area? */
7699 needs_psave = (type
7700 && (cum->nargs_prototype <= 0
7701 || (DEFAULT_ABI == ABI_AIX
7702 && TARGET_XL_COMPAT
7703 && align_words >= GP_ARG_NUM_REG)));
7705 if (!needs_psave && mode == fmode)
7706 return gen_rtx_REG (fmode, cum->fregno);
7708 k = 0;
7709 if (needs_psave)
7711 /* Describe the part that goes in gprs or the stack.
7712 This piece must come first, before the fprs. */
7713 if (align_words < GP_ARG_NUM_REG)
7715 unsigned long n_words = rs6000_arg_size (mode, type);
7717 if (align_words + n_words > GP_ARG_NUM_REG
7718 || (TARGET_32BIT && TARGET_POWERPC64))
7720 /* If this is partially on the stack, then we only
7721 include the portion actually in registers here. */
7722 enum machine_mode rmode = TARGET_32BIT ? SImode : DImode;
7723 rtx off;
7724 int i = 0;
7725 if (align_words + n_words > GP_ARG_NUM_REG)
7726 /* Not all of the arg fits in gprs. Say that it
7727 goes in memory too, using a magic NULL_RTX
7728 component. Also see comment in
7729 rs6000_mixed_function_arg for why the normal
7730 function_arg_partial_nregs scheme doesn't work
7731 in this case. */
7732 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX,
7733 const0_rtx);
7736 r = gen_rtx_REG (rmode,
7737 GP_ARG_MIN_REG + align_words);
7738 off = GEN_INT (i++ * GET_MODE_SIZE (rmode));
7739 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
7741 while (++align_words < GP_ARG_NUM_REG && --n_words != 0);
7743 else
7745 /* The whole arg fits in gprs. */
7746 r = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
7747 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
7750 else
7751 /* It's entirely in memory. */
7752 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
7755 /* Describe where this piece goes in the fprs. */
7756 r = gen_rtx_REG (fmode, cum->fregno);
7757 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
7759 return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
7761 else if (align_words < GP_ARG_NUM_REG)
7763 if (TARGET_32BIT && TARGET_POWERPC64)
7764 return rs6000_mixed_function_arg (mode, type, align_words);
7766 if (mode == BLKmode)
7767 mode = Pmode;
7769 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
7771 else
7772 return NULL_RTX;
7776 /* For an arg passed partly in registers and partly in memory, this is
7777 the number of bytes passed in registers. For args passed entirely in
7778 registers or entirely in memory, zero. When an arg is described by a
7779 PARALLEL, perhaps using more than one register type, this function
7780 returns the number of bytes used by the first element of the PARALLEL. */
7782 static int
7783 rs6000_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode,
7784 tree type, bool named)
7786 int ret = 0;
7787 int align_words;
7789 if (DEFAULT_ABI == ABI_V4)
7790 return 0;
7792 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named)
7793 && cum->nargs_prototype >= 0)
7794 return 0;
7796 /* In this complicated case we just disable the partial_nregs code. */
7797 if (rs6000_darwin64_abi && mode == BLKmode
7798 && TREE_CODE (type) == RECORD_TYPE
7799 && int_size_in_bytes (type) > 0)
7800 return 0;
7802 align_words = rs6000_parm_start (mode, type, cum->words);
7804 if (USE_FP_FOR_ARG_P (cum, mode, type))
7806 /* If we are passing this arg in the fixed parameter save area
7807 (gprs or memory) as well as fprs, then this function should
7808 return the number of partial bytes passed in the parameter
7809 save area rather than partial bytes passed in fprs. */
7810 if (type
7811 && (cum->nargs_prototype <= 0
7812 || (DEFAULT_ABI == ABI_AIX
7813 && TARGET_XL_COMPAT
7814 && align_words >= GP_ARG_NUM_REG)))
7815 return 0;
7816 else if (cum->fregno + ((GET_MODE_SIZE (mode) + 7) >> 3)
7817 > FP_ARG_MAX_REG + 1)
7818 ret = (FP_ARG_MAX_REG + 1 - cum->fregno) * 8;
7819 else if (cum->nargs_prototype >= 0)
7820 return 0;
7823 if (align_words < GP_ARG_NUM_REG
7824 && GP_ARG_NUM_REG < align_words + rs6000_arg_size (mode, type))
7825 ret = (GP_ARG_NUM_REG - align_words) * (TARGET_32BIT ? 4 : 8);
7827 if (ret != 0 && TARGET_DEBUG_ARG)
7828 fprintf (stderr, "rs6000_arg_partial_bytes: %d\n", ret);
7830 return ret;
7833 /* A C expression that indicates when an argument must be passed by
7834 reference. If nonzero for an argument, a copy of that argument is
7835 made in memory and a pointer to the argument is passed instead of
7836 the argument itself. The pointer is passed in whatever way is
7837 appropriate for passing a pointer to that type.
7839 Under V.4, aggregates and long double are passed by reference.
7841 As an extension to all 32-bit ABIs, AltiVec vectors are passed by
7842 reference unless the AltiVec vector extension ABI is in force.
7844 As an extension to all ABIs, variable sized types are passed by
7845 reference. */
7847 static bool
7848 rs6000_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
7849 enum machine_mode mode, const_tree type,
7850 bool named ATTRIBUTE_UNUSED)
7852 if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && mode == TFmode)
7854 if (TARGET_DEBUG_ARG)
7855 fprintf (stderr, "function_arg_pass_by_reference: V4 long double\n");
7856 return 1;
7859 if (!type)
7860 return 0;
7862 if (DEFAULT_ABI == ABI_V4 && AGGREGATE_TYPE_P (type))
7864 if (TARGET_DEBUG_ARG)
7865 fprintf (stderr, "function_arg_pass_by_reference: V4 aggregate\n");
7866 return 1;
7869 if (int_size_in_bytes (type) < 0)
7871 if (TARGET_DEBUG_ARG)
7872 fprintf (stderr, "function_arg_pass_by_reference: variable size\n");
7873 return 1;
7876 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
7877 modes only exist for GCC vector types if -maltivec. */
7878 if (TARGET_32BIT && !TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
7880 if (TARGET_DEBUG_ARG)
7881 fprintf (stderr, "function_arg_pass_by_reference: AltiVec\n");
7882 return 1;
7885 /* Pass synthetic vectors in memory. */
7886 if (TREE_CODE (type) == VECTOR_TYPE
7887 && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
7889 static bool warned_for_pass_big_vectors = false;
7890 if (TARGET_DEBUG_ARG)
7891 fprintf (stderr, "function_arg_pass_by_reference: synthetic vector\n");
7892 if (!warned_for_pass_big_vectors)
7894 warning (0, "GCC vector passed by reference: "
7895 "non-standard ABI extension with no compatibility guarantee");
7896 warned_for_pass_big_vectors = true;
7898 return 1;
7901 return 0;
7904 static void
7905 rs6000_move_block_from_reg (int regno, rtx x, int nregs)
7907 int i;
7908 enum machine_mode reg_mode = TARGET_32BIT ? SImode : DImode;
7910 if (nregs == 0)
7911 return;
7913 for (i = 0; i < nregs; i++)
7915 rtx tem = adjust_address_nv (x, reg_mode, i * GET_MODE_SIZE (reg_mode));
7916 if (reload_completed)
7918 if (! strict_memory_address_p (reg_mode, XEXP (tem, 0)))
7919 tem = NULL_RTX;
7920 else
7921 tem = simplify_gen_subreg (reg_mode, x, BLKmode,
7922 i * GET_MODE_SIZE (reg_mode));
7924 else
7925 tem = replace_equiv_address (tem, XEXP (tem, 0));
7927 gcc_assert (tem);
7929 emit_move_insn (tem, gen_rtx_REG (reg_mode, regno + i));
7933 /* Perform any needed actions needed for a function that is receiving a
7934 variable number of arguments.
7936 CUM is as above.
7938 MODE and TYPE are the mode and type of the current parameter.
7940 PRETEND_SIZE is a variable that should be set to the amount of stack
7941 that must be pushed by the prolog to pretend that our caller pushed
7944 Normally, this macro will push all remaining incoming registers on the
7945 stack and set PRETEND_SIZE to the length of the registers pushed. */
7947 static void
7948 setup_incoming_varargs (CUMULATIVE_ARGS *cum, enum machine_mode mode,
7949 tree type, int *pretend_size ATTRIBUTE_UNUSED,
7950 int no_rtl)
7952 CUMULATIVE_ARGS next_cum;
7953 int reg_size = TARGET_32BIT ? 4 : 8;
7954 rtx save_area = NULL_RTX, mem;
7955 int first_reg_offset;
7956 alias_set_type set;
7958 /* Skip the last named argument. */
7959 next_cum = *cum;
7960 function_arg_advance (&next_cum, mode, type, 1, 0);
7962 if (DEFAULT_ABI == ABI_V4)
7964 first_reg_offset = next_cum.sysv_gregno - GP_ARG_MIN_REG;
7966 if (! no_rtl)
7968 int gpr_reg_num = 0, gpr_size = 0, fpr_size = 0;
7969 HOST_WIDE_INT offset = 0;
7971 /* Try to optimize the size of the varargs save area.
7972 The ABI requires that ap.reg_save_area is doubleword
7973 aligned, but we don't need to allocate space for all
7974 the bytes, only those to which we actually will save
7975 anything. */
7976 if (cfun->va_list_gpr_size && first_reg_offset < GP_ARG_NUM_REG)
7977 gpr_reg_num = GP_ARG_NUM_REG - first_reg_offset;
7978 if (TARGET_HARD_FLOAT && TARGET_FPRS
7979 && next_cum.fregno <= FP_ARG_V4_MAX_REG
7980 && cfun->va_list_fpr_size)
7982 if (gpr_reg_num)
7983 fpr_size = (next_cum.fregno - FP_ARG_MIN_REG)
7984 * UNITS_PER_FP_WORD;
7985 if (cfun->va_list_fpr_size
7986 < FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
7987 fpr_size += cfun->va_list_fpr_size * UNITS_PER_FP_WORD;
7988 else
7989 fpr_size += (FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
7990 * UNITS_PER_FP_WORD;
7992 if (gpr_reg_num)
7994 offset = -((first_reg_offset * reg_size) & ~7);
7995 if (!fpr_size && gpr_reg_num > cfun->va_list_gpr_size)
7997 gpr_reg_num = cfun->va_list_gpr_size;
7998 if (reg_size == 4 && (first_reg_offset & 1))
7999 gpr_reg_num++;
8001 gpr_size = (gpr_reg_num * reg_size + 7) & ~7;
8003 else if (fpr_size)
8004 offset = - (int) (next_cum.fregno - FP_ARG_MIN_REG)
8005 * UNITS_PER_FP_WORD
8006 - (int) (GP_ARG_NUM_REG * reg_size);
8008 if (gpr_size + fpr_size)
8010 rtx reg_save_area
8011 = assign_stack_local (BLKmode, gpr_size + fpr_size, 64);
8012 gcc_assert (GET_CODE (reg_save_area) == MEM);
8013 reg_save_area = XEXP (reg_save_area, 0);
8014 if (GET_CODE (reg_save_area) == PLUS)
8016 gcc_assert (XEXP (reg_save_area, 0)
8017 == virtual_stack_vars_rtx);
8018 gcc_assert (GET_CODE (XEXP (reg_save_area, 1)) == CONST_INT);
8019 offset += INTVAL (XEXP (reg_save_area, 1));
8021 else
8022 gcc_assert (reg_save_area == virtual_stack_vars_rtx);
8025 cfun->machine->varargs_save_offset = offset;
8026 save_area = plus_constant (virtual_stack_vars_rtx, offset);
8029 else
8031 first_reg_offset = next_cum.words;
8032 save_area = virtual_incoming_args_rtx;
8034 if (targetm.calls.must_pass_in_stack (mode, type))
8035 first_reg_offset += rs6000_arg_size (TYPE_MODE (type), type);
8038 set = get_varargs_alias_set ();
8039 if (! no_rtl && first_reg_offset < GP_ARG_NUM_REG
8040 && cfun->va_list_gpr_size)
8042 int nregs = GP_ARG_NUM_REG - first_reg_offset;
8044 if (va_list_gpr_counter_field)
8046 /* V4 va_list_gpr_size counts number of registers needed. */
8047 if (nregs > cfun->va_list_gpr_size)
8048 nregs = cfun->va_list_gpr_size;
8050 else
8052 /* char * va_list instead counts number of bytes needed. */
8053 if (nregs > cfun->va_list_gpr_size / reg_size)
8054 nregs = cfun->va_list_gpr_size / reg_size;
8057 mem = gen_rtx_MEM (BLKmode,
8058 plus_constant (save_area,
8059 first_reg_offset * reg_size));
8060 MEM_NOTRAP_P (mem) = 1;
8061 set_mem_alias_set (mem, set);
8062 set_mem_align (mem, BITS_PER_WORD);
8064 rs6000_move_block_from_reg (GP_ARG_MIN_REG + first_reg_offset, mem,
8065 nregs);
8068 /* Save FP registers if needed. */
8069 if (DEFAULT_ABI == ABI_V4
8070 && TARGET_HARD_FLOAT && TARGET_FPRS
8071 && ! no_rtl
8072 && next_cum.fregno <= FP_ARG_V4_MAX_REG
8073 && cfun->va_list_fpr_size)
8075 int fregno = next_cum.fregno, nregs;
8076 rtx cr1 = gen_rtx_REG (CCmode, CR1_REGNO);
8077 rtx lab = gen_label_rtx ();
8078 int off = (GP_ARG_NUM_REG * reg_size) + ((fregno - FP_ARG_MIN_REG)
8079 * UNITS_PER_FP_WORD);
8081 emit_jump_insn
8082 (gen_rtx_SET (VOIDmode,
8083 pc_rtx,
8084 gen_rtx_IF_THEN_ELSE (VOIDmode,
8085 gen_rtx_NE (VOIDmode, cr1,
8086 const0_rtx),
8087 gen_rtx_LABEL_REF (VOIDmode, lab),
8088 pc_rtx)));
8090 for (nregs = 0;
8091 fregno <= FP_ARG_V4_MAX_REG && nregs < cfun->va_list_fpr_size;
8092 fregno++, off += UNITS_PER_FP_WORD, nregs++)
8094 mem = gen_rtx_MEM ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
8095 ? DFmode : SFmode,
8096 plus_constant (save_area, off));
8097 MEM_NOTRAP_P (mem) = 1;
8098 set_mem_alias_set (mem, set);
8099 set_mem_align (mem, GET_MODE_ALIGNMENT (
8100 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
8101 ? DFmode : SFmode));
8102 emit_move_insn (mem, gen_rtx_REG (
8103 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
8104 ? DFmode : SFmode, fregno));
8107 emit_label (lab);
8111 /* Create the va_list data type. */
8113 static tree
8114 rs6000_build_builtin_va_list (void)
8116 tree f_gpr, f_fpr, f_res, f_ovf, f_sav, record, type_decl;
8118 /* For AIX, prefer 'char *' because that's what the system
8119 header files like. */
8120 if (DEFAULT_ABI != ABI_V4)
8121 return build_pointer_type (char_type_node);
8123 record = (*lang_hooks.types.make_type) (RECORD_TYPE);
8124 type_decl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
8125 get_identifier ("__va_list_tag"), record);
8127 f_gpr = build_decl (BUILTINS_LOCATION, FIELD_DECL, get_identifier ("gpr"),
8128 unsigned_char_type_node);
8129 f_fpr = build_decl (BUILTINS_LOCATION, FIELD_DECL, get_identifier ("fpr"),
8130 unsigned_char_type_node);
8131 /* Give the two bytes of padding a name, so that -Wpadded won't warn on
8132 every user file. */
8133 f_res = build_decl (BUILTINS_LOCATION, FIELD_DECL,
8134 get_identifier ("reserved"), short_unsigned_type_node);
8135 f_ovf = build_decl (BUILTINS_LOCATION, FIELD_DECL,
8136 get_identifier ("overflow_arg_area"),
8137 ptr_type_node);
8138 f_sav = build_decl (BUILTINS_LOCATION, FIELD_DECL,
8139 get_identifier ("reg_save_area"),
8140 ptr_type_node);
8142 va_list_gpr_counter_field = f_gpr;
8143 va_list_fpr_counter_field = f_fpr;
8145 DECL_FIELD_CONTEXT (f_gpr) = record;
8146 DECL_FIELD_CONTEXT (f_fpr) = record;
8147 DECL_FIELD_CONTEXT (f_res) = record;
8148 DECL_FIELD_CONTEXT (f_ovf) = record;
8149 DECL_FIELD_CONTEXT (f_sav) = record;
8151 TREE_CHAIN (record) = type_decl;
8152 TYPE_NAME (record) = type_decl;
8153 TYPE_FIELDS (record) = f_gpr;
8154 TREE_CHAIN (f_gpr) = f_fpr;
8155 TREE_CHAIN (f_fpr) = f_res;
8156 TREE_CHAIN (f_res) = f_ovf;
8157 TREE_CHAIN (f_ovf) = f_sav;
8159 layout_type (record);
8161 /* The correct type is an array type of one element. */
8162 return build_array_type (record, build_index_type (size_zero_node));
8165 /* Implement va_start. */
8167 static void
8168 rs6000_va_start (tree valist, rtx nextarg)
8170 HOST_WIDE_INT words, n_gpr, n_fpr;
8171 tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
8172 tree gpr, fpr, ovf, sav, t;
8174 /* Only SVR4 needs something special. */
8175 if (DEFAULT_ABI != ABI_V4)
8177 std_expand_builtin_va_start (valist, nextarg);
8178 return;
8181 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
8182 f_fpr = TREE_CHAIN (f_gpr);
8183 f_res = TREE_CHAIN (f_fpr);
8184 f_ovf = TREE_CHAIN (f_res);
8185 f_sav = TREE_CHAIN (f_ovf);
8187 valist = build_va_arg_indirect_ref (valist);
8188 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
8189 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), unshare_expr (valist),
8190 f_fpr, NULL_TREE);
8191 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), unshare_expr (valist),
8192 f_ovf, NULL_TREE);
8193 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), unshare_expr (valist),
8194 f_sav, NULL_TREE);
8196 /* Count number of gp and fp argument registers used. */
8197 words = crtl->args.info.words;
8198 n_gpr = MIN (crtl->args.info.sysv_gregno - GP_ARG_MIN_REG,
8199 GP_ARG_NUM_REG);
8200 n_fpr = MIN (crtl->args.info.fregno - FP_ARG_MIN_REG,
8201 FP_ARG_NUM_REG);
8203 if (TARGET_DEBUG_ARG)
8204 fprintf (stderr, "va_start: words = "HOST_WIDE_INT_PRINT_DEC", n_gpr = "
8205 HOST_WIDE_INT_PRINT_DEC", n_fpr = "HOST_WIDE_INT_PRINT_DEC"\n",
8206 words, n_gpr, n_fpr);
8208 if (cfun->va_list_gpr_size)
8210 t = build2 (MODIFY_EXPR, TREE_TYPE (gpr), gpr,
8211 build_int_cst (NULL_TREE, n_gpr));
8212 TREE_SIDE_EFFECTS (t) = 1;
8213 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
8216 if (cfun->va_list_fpr_size)
8218 t = build2 (MODIFY_EXPR, TREE_TYPE (fpr), fpr,
8219 build_int_cst (NULL_TREE, n_fpr));
8220 TREE_SIDE_EFFECTS (t) = 1;
8221 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
8224 /* Find the overflow area. */
8225 t = make_tree (TREE_TYPE (ovf), virtual_incoming_args_rtx);
8226 if (words != 0)
8227 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (ovf), t,
8228 size_int (words * UNITS_PER_WORD));
8229 t = build2 (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
8230 TREE_SIDE_EFFECTS (t) = 1;
8231 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
8233 /* If there were no va_arg invocations, don't set up the register
8234 save area. */
8235 if (!cfun->va_list_gpr_size
8236 && !cfun->va_list_fpr_size
8237 && n_gpr < GP_ARG_NUM_REG
8238 && n_fpr < FP_ARG_V4_MAX_REG)
8239 return;
8241 /* Find the register save area. */
8242 t = make_tree (TREE_TYPE (sav), virtual_stack_vars_rtx);
8243 if (cfun->machine->varargs_save_offset)
8244 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (sav), t,
8245 size_int (cfun->machine->varargs_save_offset));
8246 t = build2 (MODIFY_EXPR, TREE_TYPE (sav), sav, t);
8247 TREE_SIDE_EFFECTS (t) = 1;
8248 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
8251 /* Implement va_arg. */
8253 tree
8254 rs6000_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
8255 gimple_seq *post_p)
8257 tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
8258 tree gpr, fpr, ovf, sav, reg, t, u;
8259 int size, rsize, n_reg, sav_ofs, sav_scale;
8260 tree lab_false, lab_over, addr;
8261 int align;
8262 tree ptrtype = build_pointer_type_for_mode (type, ptr_mode, true);
8263 int regalign = 0;
8264 gimple stmt;
8266 if (pass_by_reference (NULL, TYPE_MODE (type), type, false))
8268 t = rs6000_gimplify_va_arg (valist, ptrtype, pre_p, post_p);
8269 return build_va_arg_indirect_ref (t);
8272 if (DEFAULT_ABI != ABI_V4)
8274 if (targetm.calls.split_complex_arg && TREE_CODE (type) == COMPLEX_TYPE)
8276 tree elem_type = TREE_TYPE (type);
8277 enum machine_mode elem_mode = TYPE_MODE (elem_type);
8278 int elem_size = GET_MODE_SIZE (elem_mode);
8280 if (elem_size < UNITS_PER_WORD)
8282 tree real_part, imag_part;
8283 gimple_seq post = NULL;
8285 real_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
8286 &post);
8287 /* Copy the value into a temporary, lest the formal temporary
8288 be reused out from under us. */
8289 real_part = get_initialized_tmp_var (real_part, pre_p, &post);
8290 gimple_seq_add_seq (pre_p, post);
8292 imag_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
8293 post_p);
8295 return build2 (COMPLEX_EXPR, type, real_part, imag_part);
8299 return std_gimplify_va_arg_expr (valist, type, pre_p, post_p);
8302 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
8303 f_fpr = TREE_CHAIN (f_gpr);
8304 f_res = TREE_CHAIN (f_fpr);
8305 f_ovf = TREE_CHAIN (f_res);
8306 f_sav = TREE_CHAIN (f_ovf);
8308 valist = build_va_arg_indirect_ref (valist);
8309 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
8310 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), unshare_expr (valist),
8311 f_fpr, NULL_TREE);
8312 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), unshare_expr (valist),
8313 f_ovf, NULL_TREE);
8314 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), unshare_expr (valist),
8315 f_sav, NULL_TREE);
8317 size = int_size_in_bytes (type);
8318 rsize = (size + 3) / 4;
8319 align = 1;
8321 if (TARGET_HARD_FLOAT && TARGET_FPRS
8322 && ((TARGET_SINGLE_FLOAT && TYPE_MODE (type) == SFmode)
8323 || (TARGET_DOUBLE_FLOAT
8324 && (TYPE_MODE (type) == DFmode
8325 || TYPE_MODE (type) == TFmode
8326 || TYPE_MODE (type) == SDmode
8327 || TYPE_MODE (type) == DDmode
8328 || TYPE_MODE (type) == TDmode))))
8330 /* FP args go in FP registers, if present. */
8331 reg = fpr;
8332 n_reg = (size + 7) / 8;
8333 sav_ofs = ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? 8 : 4) * 4;
8334 sav_scale = ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? 8 : 4);
8335 if (TYPE_MODE (type) != SFmode && TYPE_MODE (type) != SDmode)
8336 align = 8;
8338 else
8340 /* Otherwise into GP registers. */
8341 reg = gpr;
8342 n_reg = rsize;
8343 sav_ofs = 0;
8344 sav_scale = 4;
8345 if (n_reg == 2)
8346 align = 8;
8349 /* Pull the value out of the saved registers.... */
8351 lab_over = NULL;
8352 addr = create_tmp_var (ptr_type_node, "addr");
8354 /* AltiVec vectors never go in registers when -mabi=altivec. */
8355 if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
8356 align = 16;
8357 else
8359 lab_false = create_artificial_label (input_location);
8360 lab_over = create_artificial_label (input_location);
8362 /* Long long and SPE vectors are aligned in the registers.
8363 As are any other 2 gpr item such as complex int due to a
8364 historical mistake. */
8365 u = reg;
8366 if (n_reg == 2 && reg == gpr)
8368 regalign = 1;
8369 u = build2 (BIT_AND_EXPR, TREE_TYPE (reg), unshare_expr (reg),
8370 build_int_cst (TREE_TYPE (reg), n_reg - 1));
8371 u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg),
8372 unshare_expr (reg), u);
8374 /* _Decimal128 is passed in even/odd fpr pairs; the stored
8375 reg number is 0 for f1, so we want to make it odd. */
8376 else if (reg == fpr && TYPE_MODE (type) == TDmode)
8378 t = build2 (BIT_IOR_EXPR, TREE_TYPE (reg), unshare_expr (reg),
8379 build_int_cst (TREE_TYPE (reg), 1));
8380 u = build2 (MODIFY_EXPR, void_type_node, unshare_expr (reg), t);
8383 t = fold_convert (TREE_TYPE (reg), size_int (8 - n_reg + 1));
8384 t = build2 (GE_EXPR, boolean_type_node, u, t);
8385 u = build1 (GOTO_EXPR, void_type_node, lab_false);
8386 t = build3 (COND_EXPR, void_type_node, t, u, NULL_TREE);
8387 gimplify_and_add (t, pre_p);
8389 t = sav;
8390 if (sav_ofs)
8391 t = build2 (POINTER_PLUS_EXPR, ptr_type_node, sav, size_int (sav_ofs));
8393 u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg), unshare_expr (reg),
8394 build_int_cst (TREE_TYPE (reg), n_reg));
8395 u = fold_convert (sizetype, u);
8396 u = build2 (MULT_EXPR, sizetype, u, size_int (sav_scale));
8397 t = build2 (POINTER_PLUS_EXPR, ptr_type_node, t, u);
8399 /* _Decimal32 varargs are located in the second word of the 64-bit
8400 FP register for 32-bit binaries. */
8401 if (!TARGET_POWERPC64
8402 && TARGET_HARD_FLOAT && TARGET_FPRS
8403 && TYPE_MODE (type) == SDmode)
8404 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (size));
8406 gimplify_assign (addr, t, pre_p);
8408 gimple_seq_add_stmt (pre_p, gimple_build_goto (lab_over));
8410 stmt = gimple_build_label (lab_false);
8411 gimple_seq_add_stmt (pre_p, stmt);
8413 if ((n_reg == 2 && !regalign) || n_reg > 2)
8415 /* Ensure that we don't find any more args in regs.
8416 Alignment has taken care of for special cases. */
8417 gimplify_assign (reg, build_int_cst (TREE_TYPE (reg), 8), pre_p);
8421 /* ... otherwise out of the overflow area. */
8423 /* Care for on-stack alignment if needed. */
8424 t = ovf;
8425 if (align != 1)
8427 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (align - 1));
8428 t = fold_convert (sizetype, t);
8429 t = build2 (BIT_AND_EXPR, TREE_TYPE (t), t,
8430 size_int (-align));
8431 t = fold_convert (TREE_TYPE (ovf), t);
8433 gimplify_expr (&t, pre_p, NULL, is_gimple_val, fb_rvalue);
8435 gimplify_assign (unshare_expr (addr), t, pre_p);
8437 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (size));
8438 gimplify_assign (unshare_expr (ovf), t, pre_p);
8440 if (lab_over)
8442 stmt = gimple_build_label (lab_over);
8443 gimple_seq_add_stmt (pre_p, stmt);
8446 if (STRICT_ALIGNMENT
8447 && (TYPE_ALIGN (type)
8448 > (unsigned) BITS_PER_UNIT * (align < 4 ? 4 : align)))
8450 /* The value (of type complex double, for example) may not be
8451 aligned in memory in the saved registers, so copy via a
8452 temporary. (This is the same code as used for SPARC.) */
8453 tree tmp = create_tmp_var (type, "va_arg_tmp");
8454 tree dest_addr = build_fold_addr_expr (tmp);
8456 tree copy = build_call_expr (implicit_built_in_decls[BUILT_IN_MEMCPY],
8457 3, dest_addr, addr, size_int (rsize * 4));
8459 gimplify_and_add (copy, pre_p);
8460 addr = dest_addr;
8463 addr = fold_convert (ptrtype, addr);
8464 return build_va_arg_indirect_ref (addr);
8467 /* Builtins. */
8469 static void
8470 def_builtin (int mask, const char *name, tree type, int code)
8472 if ((mask & target_flags) || TARGET_PAIRED_FLOAT)
8474 if (rs6000_builtin_decls[code])
8475 fatal_error ("internal error: builtin function to %s already processed.",
8476 name);
8478 rs6000_builtin_decls[code] =
8479 add_builtin_function (name, type, code, BUILT_IN_MD,
8480 NULL, NULL_TREE);
8484 /* Simple ternary operations: VECd = foo (VECa, VECb, VECc). */
8486 static const struct builtin_description bdesc_3arg[] =
8488 { MASK_ALTIVEC, CODE_FOR_altivec_vmaddfp, "__builtin_altivec_vmaddfp", ALTIVEC_BUILTIN_VMADDFP },
8489 { MASK_ALTIVEC, CODE_FOR_altivec_vmhaddshs, "__builtin_altivec_vmhaddshs", ALTIVEC_BUILTIN_VMHADDSHS },
8490 { MASK_ALTIVEC, CODE_FOR_altivec_vmhraddshs, "__builtin_altivec_vmhraddshs", ALTIVEC_BUILTIN_VMHRADDSHS },
8491 { MASK_ALTIVEC, CODE_FOR_altivec_vmladduhm, "__builtin_altivec_vmladduhm", ALTIVEC_BUILTIN_VMLADDUHM},
8492 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumubm, "__builtin_altivec_vmsumubm", ALTIVEC_BUILTIN_VMSUMUBM },
8493 { MASK_ALTIVEC, CODE_FOR_altivec_vmsummbm, "__builtin_altivec_vmsummbm", ALTIVEC_BUILTIN_VMSUMMBM },
8494 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhm, "__builtin_altivec_vmsumuhm", ALTIVEC_BUILTIN_VMSUMUHM },
8495 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshm, "__builtin_altivec_vmsumshm", ALTIVEC_BUILTIN_VMSUMSHM },
8496 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhs, "__builtin_altivec_vmsumuhs", ALTIVEC_BUILTIN_VMSUMUHS },
8497 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshs, "__builtin_altivec_vmsumshs", ALTIVEC_BUILTIN_VMSUMSHS },
8498 { MASK_ALTIVEC, CODE_FOR_altivec_vnmsubfp, "__builtin_altivec_vnmsubfp", ALTIVEC_BUILTIN_VNMSUBFP },
8499 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2df, "__builtin_altivec_vperm_2df", ALTIVEC_BUILTIN_VPERM_2DF },
8500 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2di, "__builtin_altivec_vperm_2di", ALTIVEC_BUILTIN_VPERM_2DI },
8501 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4sf, "__builtin_altivec_vperm_4sf", ALTIVEC_BUILTIN_VPERM_4SF },
8502 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4si, "__builtin_altivec_vperm_4si", ALTIVEC_BUILTIN_VPERM_4SI },
8503 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v8hi, "__builtin_altivec_vperm_8hi", ALTIVEC_BUILTIN_VPERM_8HI },
8504 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_altivec_vperm_16qi", ALTIVEC_BUILTIN_VPERM_16QI },
8505 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2di_uns, "__builtin_altivec_vperm_2di_uns", ALTIVEC_BUILTIN_VPERM_2DI_UNS },
8506 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4si_uns, "__builtin_altivec_vperm_4si_uns", ALTIVEC_BUILTIN_VPERM_4SI_UNS },
8507 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v8hi_uns, "__builtin_altivec_vperm_8hi_uns", ALTIVEC_BUILTIN_VPERM_8HI_UNS },
8508 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_altivec_vperm_16qi_uns", ALTIVEC_BUILTIN_VPERM_16QI_UNS },
8509 { MASK_ALTIVEC, CODE_FOR_vector_select_v4sf, "__builtin_altivec_vsel_4sf", ALTIVEC_BUILTIN_VSEL_4SF },
8510 { MASK_ALTIVEC, CODE_FOR_vector_select_v4si, "__builtin_altivec_vsel_4si", ALTIVEC_BUILTIN_VSEL_4SI },
8511 { MASK_ALTIVEC, CODE_FOR_vector_select_v8hi, "__builtin_altivec_vsel_8hi", ALTIVEC_BUILTIN_VSEL_8HI },
8512 { MASK_ALTIVEC, CODE_FOR_vector_select_v16qi, "__builtin_altivec_vsel_16qi", ALTIVEC_BUILTIN_VSEL_16QI },
8513 { MASK_ALTIVEC, CODE_FOR_vector_select_v2df, "__builtin_altivec_vsel_2df", ALTIVEC_BUILTIN_VSEL_2DF },
8514 { MASK_ALTIVEC, CODE_FOR_vector_select_v2di, "__builtin_altivec_vsel_2di", ALTIVEC_BUILTIN_VSEL_2DI },
8515 { MASK_ALTIVEC, CODE_FOR_vector_select_v4si_uns, "__builtin_altivec_vsel_4si_uns", ALTIVEC_BUILTIN_VSEL_4SI_UNS },
8516 { MASK_ALTIVEC, CODE_FOR_vector_select_v8hi_uns, "__builtin_altivec_vsel_8hi_uns", ALTIVEC_BUILTIN_VSEL_8HI_UNS },
8517 { MASK_ALTIVEC, CODE_FOR_vector_select_v16qi_uns, "__builtin_altivec_vsel_16qi_uns", ALTIVEC_BUILTIN_VSEL_16QI_UNS },
8518 { MASK_ALTIVEC, CODE_FOR_vector_select_v2di_uns, "__builtin_altivec_vsel_2di_uns", ALTIVEC_BUILTIN_VSEL_2DI_UNS },
8519 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v16qi, "__builtin_altivec_vsldoi_16qi", ALTIVEC_BUILTIN_VSLDOI_16QI },
8520 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v8hi, "__builtin_altivec_vsldoi_8hi", ALTIVEC_BUILTIN_VSLDOI_8HI },
8521 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v4si, "__builtin_altivec_vsldoi_4si", ALTIVEC_BUILTIN_VSLDOI_4SI },
8522 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v4sf, "__builtin_altivec_vsldoi_4sf", ALTIVEC_BUILTIN_VSLDOI_4SF },
8524 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_madd", ALTIVEC_BUILTIN_VEC_MADD },
8525 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_madds", ALTIVEC_BUILTIN_VEC_MADDS },
8526 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mladd", ALTIVEC_BUILTIN_VEC_MLADD },
8527 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mradds", ALTIVEC_BUILTIN_VEC_MRADDS },
8528 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msum", ALTIVEC_BUILTIN_VEC_MSUM },
8529 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumshm", ALTIVEC_BUILTIN_VEC_VMSUMSHM },
8530 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumuhm", ALTIVEC_BUILTIN_VEC_VMSUMUHM },
8531 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsummbm", ALTIVEC_BUILTIN_VEC_VMSUMMBM },
8532 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumubm", ALTIVEC_BUILTIN_VEC_VMSUMUBM },
8533 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msums", ALTIVEC_BUILTIN_VEC_MSUMS },
8534 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumshs", ALTIVEC_BUILTIN_VEC_VMSUMSHS },
8535 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumuhs", ALTIVEC_BUILTIN_VEC_VMSUMUHS },
8536 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nmsub", ALTIVEC_BUILTIN_VEC_NMSUB },
8537 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_perm", ALTIVEC_BUILTIN_VEC_PERM },
8538 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sel", ALTIVEC_BUILTIN_VEC_SEL },
8540 { MASK_VSX, CODE_FOR_vsx_fmaddv2df4, "__builtin_vsx_xvmadddp", VSX_BUILTIN_XVMADDDP },
8541 { MASK_VSX, CODE_FOR_vsx_fmsubv2df4, "__builtin_vsx_xvmsubdp", VSX_BUILTIN_XVMSUBDP },
8542 { MASK_VSX, CODE_FOR_vsx_fnmaddv2df4, "__builtin_vsx_xvnmadddp", VSX_BUILTIN_XVNMADDDP },
8543 { MASK_VSX, CODE_FOR_vsx_fnmsubv2df4, "__builtin_vsx_xvnmsubdp", VSX_BUILTIN_XVNMSUBDP },
8545 { MASK_VSX, CODE_FOR_vsx_fmaddv4sf4, "__builtin_vsx_xvmaddsp", VSX_BUILTIN_XVMADDSP },
8546 { MASK_VSX, CODE_FOR_vsx_fmsubv4sf4, "__builtin_vsx_xvmsubsp", VSX_BUILTIN_XVMSUBSP },
8547 { MASK_VSX, CODE_FOR_vsx_fnmaddv4sf4, "__builtin_vsx_xvnmaddsp", VSX_BUILTIN_XVNMADDSP },
8548 { MASK_VSX, CODE_FOR_vsx_fnmsubv4sf4, "__builtin_vsx_xvnmsubsp", VSX_BUILTIN_XVNMSUBSP },
8550 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msub", VSX_BUILTIN_VEC_MSUB },
8551 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nmadd", VSX_BUILTIN_VEC_NMADD },
8553 { MASK_VSX, CODE_FOR_vector_select_v2di, "__builtin_vsx_xxsel_2di", VSX_BUILTIN_XXSEL_2DI },
8554 { MASK_VSX, CODE_FOR_vector_select_v2df, "__builtin_vsx_xxsel_2df", VSX_BUILTIN_XXSEL_2DF },
8555 { MASK_VSX, CODE_FOR_vector_select_v4sf, "__builtin_vsx_xxsel_4sf", VSX_BUILTIN_XXSEL_4SF },
8556 { MASK_VSX, CODE_FOR_vector_select_v4si, "__builtin_vsx_xxsel_4si", VSX_BUILTIN_XXSEL_4SI },
8557 { MASK_VSX, CODE_FOR_vector_select_v8hi, "__builtin_vsx_xxsel_8hi", VSX_BUILTIN_XXSEL_8HI },
8558 { MASK_VSX, CODE_FOR_vector_select_v16qi, "__builtin_vsx_xxsel_16qi", VSX_BUILTIN_XXSEL_16QI },
8559 { MASK_VSX, CODE_FOR_vector_select_v2di_uns, "__builtin_vsx_xxsel_2di_uns", VSX_BUILTIN_XXSEL_2DI_UNS },
8560 { MASK_VSX, CODE_FOR_vector_select_v4si_uns, "__builtin_vsx_xxsel_4si_uns", VSX_BUILTIN_XXSEL_4SI_UNS },
8561 { MASK_VSX, CODE_FOR_vector_select_v8hi_uns, "__builtin_vsx_xxsel_8hi_uns", VSX_BUILTIN_XXSEL_8HI_UNS },
8562 { MASK_VSX, CODE_FOR_vector_select_v16qi_uns, "__builtin_vsx_xxsel_16qi_uns", VSX_BUILTIN_XXSEL_16QI_UNS },
8564 { MASK_VSX, CODE_FOR_altivec_vperm_v2di, "__builtin_vsx_vperm_2di", VSX_BUILTIN_VPERM_2DI },
8565 { MASK_VSX, CODE_FOR_altivec_vperm_v2df, "__builtin_vsx_vperm_2df", VSX_BUILTIN_VPERM_2DF },
8566 { MASK_VSX, CODE_FOR_altivec_vperm_v4sf, "__builtin_vsx_vperm_4sf", VSX_BUILTIN_VPERM_4SF },
8567 { MASK_VSX, CODE_FOR_altivec_vperm_v4si, "__builtin_vsx_vperm_4si", VSX_BUILTIN_VPERM_4SI },
8568 { MASK_VSX, CODE_FOR_altivec_vperm_v8hi, "__builtin_vsx_vperm_8hi", VSX_BUILTIN_VPERM_8HI },
8569 { MASK_VSX, CODE_FOR_altivec_vperm_v16qi, "__builtin_vsx_vperm_16qi", VSX_BUILTIN_VPERM_16QI },
8570 { MASK_VSX, CODE_FOR_altivec_vperm_v2di_uns, "__builtin_vsx_vperm_2di_uns", VSX_BUILTIN_VPERM_2DI_UNS },
8571 { MASK_VSX, CODE_FOR_altivec_vperm_v4si_uns, "__builtin_vsx_vperm_4si_uns", VSX_BUILTIN_VPERM_4SI_UNS },
8572 { MASK_VSX, CODE_FOR_altivec_vperm_v8hi_uns, "__builtin_vsx_vperm_8hi_uns", VSX_BUILTIN_VPERM_8HI_UNS },
8573 { MASK_VSX, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_vsx_vperm_16qi_uns", VSX_BUILTIN_VPERM_16QI_UNS },
8575 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v2df, "__builtin_vsx_xxpermdi_2df", VSX_BUILTIN_XXPERMDI_2DF },
8576 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v2di, "__builtin_vsx_xxpermdi_2di", VSX_BUILTIN_XXPERMDI_2DI },
8577 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v4sf, "__builtin_vsx_xxpermdi_4sf", VSX_BUILTIN_XXPERMDI_4SF },
8578 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v4si, "__builtin_vsx_xxpermdi_4si", VSX_BUILTIN_XXPERMDI_4SI },
8579 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v8hi, "__builtin_vsx_xxpermdi_8hi", VSX_BUILTIN_XXPERMDI_8HI },
8580 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v16qi, "__builtin_vsx_xxpermdi_16qi", VSX_BUILTIN_XXPERMDI_16QI },
8581 { MASK_VSX, CODE_FOR_nothing, "__builtin_vsx_xxpermdi", VSX_BUILTIN_VEC_XXPERMDI },
8582 { MASK_VSX, CODE_FOR_vsx_set_v2df, "__builtin_vsx_set_2df", VSX_BUILTIN_SET_2DF },
8583 { MASK_VSX, CODE_FOR_vsx_set_v2di, "__builtin_vsx_set_2di", VSX_BUILTIN_SET_2DI },
8585 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v2di, "__builtin_vsx_xxsldwi_2di", VSX_BUILTIN_XXSLDWI_2DI },
8586 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v2df, "__builtin_vsx_xxsldwi_2df", VSX_BUILTIN_XXSLDWI_2DF },
8587 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v4sf, "__builtin_vsx_xxsldwi_4sf", VSX_BUILTIN_XXSLDWI_4SF },
8588 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v4si, "__builtin_vsx_xxsldwi_4si", VSX_BUILTIN_XXSLDWI_4SI },
8589 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v8hi, "__builtin_vsx_xxsldwi_8hi", VSX_BUILTIN_XXSLDWI_8HI },
8590 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v16qi, "__builtin_vsx_xxsldwi_16qi", VSX_BUILTIN_XXSLDWI_16QI },
8591 { MASK_VSX, CODE_FOR_nothing, "__builtin_vsx_xxsldwi", VSX_BUILTIN_VEC_XXSLDWI },
8593 { 0, CODE_FOR_paired_msub, "__builtin_paired_msub", PAIRED_BUILTIN_MSUB },
8594 { 0, CODE_FOR_paired_madd, "__builtin_paired_madd", PAIRED_BUILTIN_MADD },
8595 { 0, CODE_FOR_paired_madds0, "__builtin_paired_madds0", PAIRED_BUILTIN_MADDS0 },
8596 { 0, CODE_FOR_paired_madds1, "__builtin_paired_madds1", PAIRED_BUILTIN_MADDS1 },
8597 { 0, CODE_FOR_paired_nmsub, "__builtin_paired_nmsub", PAIRED_BUILTIN_NMSUB },
8598 { 0, CODE_FOR_paired_nmadd, "__builtin_paired_nmadd", PAIRED_BUILTIN_NMADD },
8599 { 0, CODE_FOR_paired_sum0, "__builtin_paired_sum0", PAIRED_BUILTIN_SUM0 },
8600 { 0, CODE_FOR_paired_sum1, "__builtin_paired_sum1", PAIRED_BUILTIN_SUM1 },
8601 { 0, CODE_FOR_selv2sf4, "__builtin_paired_selv2sf4", PAIRED_BUILTIN_SELV2SF4 },
8604 /* DST operations: void foo (void *, const int, const char). */
8606 static const struct builtin_description bdesc_dst[] =
8608 { MASK_ALTIVEC, CODE_FOR_altivec_dst, "__builtin_altivec_dst", ALTIVEC_BUILTIN_DST },
8609 { MASK_ALTIVEC, CODE_FOR_altivec_dstt, "__builtin_altivec_dstt", ALTIVEC_BUILTIN_DSTT },
8610 { MASK_ALTIVEC, CODE_FOR_altivec_dstst, "__builtin_altivec_dstst", ALTIVEC_BUILTIN_DSTST },
8611 { MASK_ALTIVEC, CODE_FOR_altivec_dststt, "__builtin_altivec_dststt", ALTIVEC_BUILTIN_DSTSTT },
8613 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dst", ALTIVEC_BUILTIN_VEC_DST },
8614 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dstt", ALTIVEC_BUILTIN_VEC_DSTT },
8615 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dstst", ALTIVEC_BUILTIN_VEC_DSTST },
8616 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dststt", ALTIVEC_BUILTIN_VEC_DSTSTT }
8619 /* Simple binary operations: VECc = foo (VECa, VECb). */
8621 static struct builtin_description bdesc_2arg[] =
8623 { MASK_ALTIVEC, CODE_FOR_addv16qi3, "__builtin_altivec_vaddubm", ALTIVEC_BUILTIN_VADDUBM },
8624 { MASK_ALTIVEC, CODE_FOR_addv8hi3, "__builtin_altivec_vadduhm", ALTIVEC_BUILTIN_VADDUHM },
8625 { MASK_ALTIVEC, CODE_FOR_addv4si3, "__builtin_altivec_vadduwm", ALTIVEC_BUILTIN_VADDUWM },
8626 { MASK_ALTIVEC, CODE_FOR_addv4sf3, "__builtin_altivec_vaddfp", ALTIVEC_BUILTIN_VADDFP },
8627 { MASK_ALTIVEC, CODE_FOR_altivec_vaddcuw, "__builtin_altivec_vaddcuw", ALTIVEC_BUILTIN_VADDCUW },
8628 { MASK_ALTIVEC, CODE_FOR_altivec_vaddubs, "__builtin_altivec_vaddubs", ALTIVEC_BUILTIN_VADDUBS },
8629 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsbs, "__builtin_altivec_vaddsbs", ALTIVEC_BUILTIN_VADDSBS },
8630 { MASK_ALTIVEC, CODE_FOR_altivec_vadduhs, "__builtin_altivec_vadduhs", ALTIVEC_BUILTIN_VADDUHS },
8631 { MASK_ALTIVEC, CODE_FOR_altivec_vaddshs, "__builtin_altivec_vaddshs", ALTIVEC_BUILTIN_VADDSHS },
8632 { MASK_ALTIVEC, CODE_FOR_altivec_vadduws, "__builtin_altivec_vadduws", ALTIVEC_BUILTIN_VADDUWS },
8633 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsws, "__builtin_altivec_vaddsws", ALTIVEC_BUILTIN_VADDSWS },
8634 { MASK_ALTIVEC, CODE_FOR_andv4si3, "__builtin_altivec_vand", ALTIVEC_BUILTIN_VAND },
8635 { MASK_ALTIVEC, CODE_FOR_andcv4si3, "__builtin_altivec_vandc", ALTIVEC_BUILTIN_VANDC },
8636 { MASK_ALTIVEC, CODE_FOR_altivec_vavgub, "__builtin_altivec_vavgub", ALTIVEC_BUILTIN_VAVGUB },
8637 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsb, "__builtin_altivec_vavgsb", ALTIVEC_BUILTIN_VAVGSB },
8638 { MASK_ALTIVEC, CODE_FOR_altivec_vavguh, "__builtin_altivec_vavguh", ALTIVEC_BUILTIN_VAVGUH },
8639 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsh, "__builtin_altivec_vavgsh", ALTIVEC_BUILTIN_VAVGSH },
8640 { MASK_ALTIVEC, CODE_FOR_altivec_vavguw, "__builtin_altivec_vavguw", ALTIVEC_BUILTIN_VAVGUW },
8641 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsw, "__builtin_altivec_vavgsw", ALTIVEC_BUILTIN_VAVGSW },
8642 { MASK_ALTIVEC, CODE_FOR_altivec_vcfux, "__builtin_altivec_vcfux", ALTIVEC_BUILTIN_VCFUX },
8643 { MASK_ALTIVEC, CODE_FOR_altivec_vcfsx, "__builtin_altivec_vcfsx", ALTIVEC_BUILTIN_VCFSX },
8644 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpbfp, "__builtin_altivec_vcmpbfp", ALTIVEC_BUILTIN_VCMPBFP },
8645 { MASK_ALTIVEC, CODE_FOR_vector_eqv16qi, "__builtin_altivec_vcmpequb", ALTIVEC_BUILTIN_VCMPEQUB },
8646 { MASK_ALTIVEC, CODE_FOR_vector_eqv8hi, "__builtin_altivec_vcmpequh", ALTIVEC_BUILTIN_VCMPEQUH },
8647 { MASK_ALTIVEC, CODE_FOR_vector_eqv4si, "__builtin_altivec_vcmpequw", ALTIVEC_BUILTIN_VCMPEQUW },
8648 { MASK_ALTIVEC, CODE_FOR_vector_eqv4sf, "__builtin_altivec_vcmpeqfp", ALTIVEC_BUILTIN_VCMPEQFP },
8649 { MASK_ALTIVEC, CODE_FOR_vector_gev4sf, "__builtin_altivec_vcmpgefp", ALTIVEC_BUILTIN_VCMPGEFP },
8650 { MASK_ALTIVEC, CODE_FOR_vector_gtuv16qi, "__builtin_altivec_vcmpgtub", ALTIVEC_BUILTIN_VCMPGTUB },
8651 { MASK_ALTIVEC, CODE_FOR_vector_gtv16qi, "__builtin_altivec_vcmpgtsb", ALTIVEC_BUILTIN_VCMPGTSB },
8652 { MASK_ALTIVEC, CODE_FOR_vector_gtuv8hi, "__builtin_altivec_vcmpgtuh", ALTIVEC_BUILTIN_VCMPGTUH },
8653 { MASK_ALTIVEC, CODE_FOR_vector_gtv8hi, "__builtin_altivec_vcmpgtsh", ALTIVEC_BUILTIN_VCMPGTSH },
8654 { MASK_ALTIVEC, CODE_FOR_vector_gtuv4si, "__builtin_altivec_vcmpgtuw", ALTIVEC_BUILTIN_VCMPGTUW },
8655 { MASK_ALTIVEC, CODE_FOR_vector_gtv4si, "__builtin_altivec_vcmpgtsw", ALTIVEC_BUILTIN_VCMPGTSW },
8656 { MASK_ALTIVEC, CODE_FOR_vector_gtv4sf, "__builtin_altivec_vcmpgtfp", ALTIVEC_BUILTIN_VCMPGTFP },
8657 { MASK_ALTIVEC, CODE_FOR_altivec_vctsxs, "__builtin_altivec_vctsxs", ALTIVEC_BUILTIN_VCTSXS },
8658 { MASK_ALTIVEC, CODE_FOR_altivec_vctuxs, "__builtin_altivec_vctuxs", ALTIVEC_BUILTIN_VCTUXS },
8659 { MASK_ALTIVEC, CODE_FOR_umaxv16qi3, "__builtin_altivec_vmaxub", ALTIVEC_BUILTIN_VMAXUB },
8660 { MASK_ALTIVEC, CODE_FOR_smaxv16qi3, "__builtin_altivec_vmaxsb", ALTIVEC_BUILTIN_VMAXSB },
8661 { MASK_ALTIVEC, CODE_FOR_umaxv8hi3, "__builtin_altivec_vmaxuh", ALTIVEC_BUILTIN_VMAXUH },
8662 { MASK_ALTIVEC, CODE_FOR_smaxv8hi3, "__builtin_altivec_vmaxsh", ALTIVEC_BUILTIN_VMAXSH },
8663 { MASK_ALTIVEC, CODE_FOR_umaxv4si3, "__builtin_altivec_vmaxuw", ALTIVEC_BUILTIN_VMAXUW },
8664 { MASK_ALTIVEC, CODE_FOR_smaxv4si3, "__builtin_altivec_vmaxsw", ALTIVEC_BUILTIN_VMAXSW },
8665 { MASK_ALTIVEC, CODE_FOR_smaxv4sf3, "__builtin_altivec_vmaxfp", ALTIVEC_BUILTIN_VMAXFP },
8666 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghb, "__builtin_altivec_vmrghb", ALTIVEC_BUILTIN_VMRGHB },
8667 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghh, "__builtin_altivec_vmrghh", ALTIVEC_BUILTIN_VMRGHH },
8668 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghw, "__builtin_altivec_vmrghw", ALTIVEC_BUILTIN_VMRGHW },
8669 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglb, "__builtin_altivec_vmrglb", ALTIVEC_BUILTIN_VMRGLB },
8670 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglh, "__builtin_altivec_vmrglh", ALTIVEC_BUILTIN_VMRGLH },
8671 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglw, "__builtin_altivec_vmrglw", ALTIVEC_BUILTIN_VMRGLW },
8672 { MASK_ALTIVEC, CODE_FOR_uminv16qi3, "__builtin_altivec_vminub", ALTIVEC_BUILTIN_VMINUB },
8673 { MASK_ALTIVEC, CODE_FOR_sminv16qi3, "__builtin_altivec_vminsb", ALTIVEC_BUILTIN_VMINSB },
8674 { MASK_ALTIVEC, CODE_FOR_uminv8hi3, "__builtin_altivec_vminuh", ALTIVEC_BUILTIN_VMINUH },
8675 { MASK_ALTIVEC, CODE_FOR_sminv8hi3, "__builtin_altivec_vminsh", ALTIVEC_BUILTIN_VMINSH },
8676 { MASK_ALTIVEC, CODE_FOR_uminv4si3, "__builtin_altivec_vminuw", ALTIVEC_BUILTIN_VMINUW },
8677 { MASK_ALTIVEC, CODE_FOR_sminv4si3, "__builtin_altivec_vminsw", ALTIVEC_BUILTIN_VMINSW },
8678 { MASK_ALTIVEC, CODE_FOR_sminv4sf3, "__builtin_altivec_vminfp", ALTIVEC_BUILTIN_VMINFP },
8679 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleub, "__builtin_altivec_vmuleub", ALTIVEC_BUILTIN_VMULEUB },
8680 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleub, "__builtin_altivec_vmuleub_uns", ALTIVEC_BUILTIN_VMULEUB_UNS },
8681 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesb, "__builtin_altivec_vmulesb", ALTIVEC_BUILTIN_VMULESB },
8682 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleuh, "__builtin_altivec_vmuleuh", ALTIVEC_BUILTIN_VMULEUH },
8683 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleuh, "__builtin_altivec_vmuleuh_uns", ALTIVEC_BUILTIN_VMULEUH_UNS },
8684 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesh, "__builtin_altivec_vmulesh", ALTIVEC_BUILTIN_VMULESH },
8685 { MASK_ALTIVEC, CODE_FOR_altivec_vmuloub, "__builtin_altivec_vmuloub", ALTIVEC_BUILTIN_VMULOUB },
8686 { MASK_ALTIVEC, CODE_FOR_altivec_vmuloub, "__builtin_altivec_vmuloub_uns", ALTIVEC_BUILTIN_VMULOUB_UNS },
8687 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosb, "__builtin_altivec_vmulosb", ALTIVEC_BUILTIN_VMULOSB },
8688 { MASK_ALTIVEC, CODE_FOR_altivec_vmulouh, "__builtin_altivec_vmulouh", ALTIVEC_BUILTIN_VMULOUH },
8689 { MASK_ALTIVEC, CODE_FOR_altivec_vmulouh, "__builtin_altivec_vmulouh_uns", ALTIVEC_BUILTIN_VMULOUH_UNS },
8690 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosh, "__builtin_altivec_vmulosh", ALTIVEC_BUILTIN_VMULOSH },
8691 { MASK_ALTIVEC, CODE_FOR_norv4si3, "__builtin_altivec_vnor", ALTIVEC_BUILTIN_VNOR },
8692 { MASK_ALTIVEC, CODE_FOR_iorv4si3, "__builtin_altivec_vor", ALTIVEC_BUILTIN_VOR },
8693 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhum, "__builtin_altivec_vpkuhum", ALTIVEC_BUILTIN_VPKUHUM },
8694 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwum, "__builtin_altivec_vpkuwum", ALTIVEC_BUILTIN_VPKUWUM },
8695 { MASK_ALTIVEC, CODE_FOR_altivec_vpkpx, "__builtin_altivec_vpkpx", ALTIVEC_BUILTIN_VPKPX },
8696 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshss, "__builtin_altivec_vpkshss", ALTIVEC_BUILTIN_VPKSHSS },
8697 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswss, "__builtin_altivec_vpkswss", ALTIVEC_BUILTIN_VPKSWSS },
8698 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhus, "__builtin_altivec_vpkuhus", ALTIVEC_BUILTIN_VPKUHUS },
8699 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshus, "__builtin_altivec_vpkshus", ALTIVEC_BUILTIN_VPKSHUS },
8700 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwus, "__builtin_altivec_vpkuwus", ALTIVEC_BUILTIN_VPKUWUS },
8701 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswus, "__builtin_altivec_vpkswus", ALTIVEC_BUILTIN_VPKSWUS },
8702 { MASK_ALTIVEC, CODE_FOR_vrotlv16qi3, "__builtin_altivec_vrlb", ALTIVEC_BUILTIN_VRLB },
8703 { MASK_ALTIVEC, CODE_FOR_vrotlv8hi3, "__builtin_altivec_vrlh", ALTIVEC_BUILTIN_VRLH },
8704 { MASK_ALTIVEC, CODE_FOR_vrotlv4si3, "__builtin_altivec_vrlw", ALTIVEC_BUILTIN_VRLW },
8705 { MASK_ALTIVEC, CODE_FOR_vashlv16qi3, "__builtin_altivec_vslb", ALTIVEC_BUILTIN_VSLB },
8706 { MASK_ALTIVEC, CODE_FOR_vashlv8hi3, "__builtin_altivec_vslh", ALTIVEC_BUILTIN_VSLH },
8707 { MASK_ALTIVEC, CODE_FOR_vashlv4si3, "__builtin_altivec_vslw", ALTIVEC_BUILTIN_VSLW },
8708 { MASK_ALTIVEC, CODE_FOR_altivec_vsl, "__builtin_altivec_vsl", ALTIVEC_BUILTIN_VSL },
8709 { MASK_ALTIVEC, CODE_FOR_altivec_vslo, "__builtin_altivec_vslo", ALTIVEC_BUILTIN_VSLO },
8710 { MASK_ALTIVEC, CODE_FOR_altivec_vspltb, "__builtin_altivec_vspltb", ALTIVEC_BUILTIN_VSPLTB },
8711 { MASK_ALTIVEC, CODE_FOR_altivec_vsplth, "__builtin_altivec_vsplth", ALTIVEC_BUILTIN_VSPLTH },
8712 { MASK_ALTIVEC, CODE_FOR_altivec_vspltw, "__builtin_altivec_vspltw", ALTIVEC_BUILTIN_VSPLTW },
8713 { MASK_ALTIVEC, CODE_FOR_vlshrv16qi3, "__builtin_altivec_vsrb", ALTIVEC_BUILTIN_VSRB },
8714 { MASK_ALTIVEC, CODE_FOR_vlshrv8hi3, "__builtin_altivec_vsrh", ALTIVEC_BUILTIN_VSRH },
8715 { MASK_ALTIVEC, CODE_FOR_vlshrv4si3, "__builtin_altivec_vsrw", ALTIVEC_BUILTIN_VSRW },
8716 { MASK_ALTIVEC, CODE_FOR_vashrv16qi3, "__builtin_altivec_vsrab", ALTIVEC_BUILTIN_VSRAB },
8717 { MASK_ALTIVEC, CODE_FOR_vashrv8hi3, "__builtin_altivec_vsrah", ALTIVEC_BUILTIN_VSRAH },
8718 { MASK_ALTIVEC, CODE_FOR_vashrv4si3, "__builtin_altivec_vsraw", ALTIVEC_BUILTIN_VSRAW },
8719 { MASK_ALTIVEC, CODE_FOR_altivec_vsr, "__builtin_altivec_vsr", ALTIVEC_BUILTIN_VSR },
8720 { MASK_ALTIVEC, CODE_FOR_altivec_vsro, "__builtin_altivec_vsro", ALTIVEC_BUILTIN_VSRO },
8721 { MASK_ALTIVEC, CODE_FOR_subv16qi3, "__builtin_altivec_vsububm", ALTIVEC_BUILTIN_VSUBUBM },
8722 { MASK_ALTIVEC, CODE_FOR_subv8hi3, "__builtin_altivec_vsubuhm", ALTIVEC_BUILTIN_VSUBUHM },
8723 { MASK_ALTIVEC, CODE_FOR_subv4si3, "__builtin_altivec_vsubuwm", ALTIVEC_BUILTIN_VSUBUWM },
8724 { MASK_ALTIVEC, CODE_FOR_subv4sf3, "__builtin_altivec_vsubfp", ALTIVEC_BUILTIN_VSUBFP },
8725 { MASK_ALTIVEC, CODE_FOR_altivec_vsubcuw, "__builtin_altivec_vsubcuw", ALTIVEC_BUILTIN_VSUBCUW },
8726 { MASK_ALTIVEC, CODE_FOR_altivec_vsububs, "__builtin_altivec_vsububs", ALTIVEC_BUILTIN_VSUBUBS },
8727 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsbs, "__builtin_altivec_vsubsbs", ALTIVEC_BUILTIN_VSUBSBS },
8728 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuhs, "__builtin_altivec_vsubuhs", ALTIVEC_BUILTIN_VSUBUHS },
8729 { MASK_ALTIVEC, CODE_FOR_altivec_vsubshs, "__builtin_altivec_vsubshs", ALTIVEC_BUILTIN_VSUBSHS },
8730 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuws, "__builtin_altivec_vsubuws", ALTIVEC_BUILTIN_VSUBUWS },
8731 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsws, "__builtin_altivec_vsubsws", ALTIVEC_BUILTIN_VSUBSWS },
8732 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4ubs, "__builtin_altivec_vsum4ubs", ALTIVEC_BUILTIN_VSUM4UBS },
8733 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4sbs, "__builtin_altivec_vsum4sbs", ALTIVEC_BUILTIN_VSUM4SBS },
8734 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4shs, "__builtin_altivec_vsum4shs", ALTIVEC_BUILTIN_VSUM4SHS },
8735 { MASK_ALTIVEC, CODE_FOR_altivec_vsum2sws, "__builtin_altivec_vsum2sws", ALTIVEC_BUILTIN_VSUM2SWS },
8736 { MASK_ALTIVEC, CODE_FOR_altivec_vsumsws, "__builtin_altivec_vsumsws", ALTIVEC_BUILTIN_VSUMSWS },
8737 { MASK_ALTIVEC, CODE_FOR_xorv4si3, "__builtin_altivec_vxor", ALTIVEC_BUILTIN_VXOR },
8738 { MASK_ALTIVEC, CODE_FOR_vector_copysignv4sf3, "__builtin_altivec_copysignfp", ALTIVEC_BUILTIN_COPYSIGN_V4SF },
8740 { MASK_VSX, CODE_FOR_addv2df3, "__builtin_vsx_xvadddp", VSX_BUILTIN_XVADDDP },
8741 { MASK_VSX, CODE_FOR_subv2df3, "__builtin_vsx_xvsubdp", VSX_BUILTIN_XVSUBDP },
8742 { MASK_VSX, CODE_FOR_mulv2df3, "__builtin_vsx_xvmuldp", VSX_BUILTIN_XVMULDP },
8743 { MASK_VSX, CODE_FOR_divv2df3, "__builtin_vsx_xvdivdp", VSX_BUILTIN_XVDIVDP },
8744 { MASK_VSX, CODE_FOR_sminv2df3, "__builtin_vsx_xvmindp", VSX_BUILTIN_XVMINDP },
8745 { MASK_VSX, CODE_FOR_smaxv2df3, "__builtin_vsx_xvmaxdp", VSX_BUILTIN_XVMAXDP },
8746 { MASK_VSX, CODE_FOR_vsx_tdivv2df3_fe, "__builtin_vsx_xvtdivdp_fe", VSX_BUILTIN_XVTDIVDP_FE },
8747 { MASK_VSX, CODE_FOR_vsx_tdivv2df3_fg, "__builtin_vsx_xvtdivdp_fg", VSX_BUILTIN_XVTDIVDP_FG },
8748 { MASK_VSX, CODE_FOR_vector_eqv2df, "__builtin_vsx_xvcmpeqdp", VSX_BUILTIN_XVCMPEQDP },
8749 { MASK_VSX, CODE_FOR_vector_gtv2df, "__builtin_vsx_xvcmpgtdp", VSX_BUILTIN_XVCMPGTDP },
8750 { MASK_VSX, CODE_FOR_vector_gev2df, "__builtin_vsx_xvcmpgedp", VSX_BUILTIN_XVCMPGEDP },
8752 { MASK_VSX, CODE_FOR_addv4sf3, "__builtin_vsx_xvaddsp", VSX_BUILTIN_XVADDSP },
8753 { MASK_VSX, CODE_FOR_subv4sf3, "__builtin_vsx_xvsubsp", VSX_BUILTIN_XVSUBSP },
8754 { MASK_VSX, CODE_FOR_mulv4sf3, "__builtin_vsx_xvmulsp", VSX_BUILTIN_XVMULSP },
8755 { MASK_VSX, CODE_FOR_divv4sf3, "__builtin_vsx_xvdivsp", VSX_BUILTIN_XVDIVSP },
8756 { MASK_VSX, CODE_FOR_sminv4sf3, "__builtin_vsx_xvminsp", VSX_BUILTIN_XVMINSP },
8757 { MASK_VSX, CODE_FOR_smaxv4sf3, "__builtin_vsx_xvmaxsp", VSX_BUILTIN_XVMAXSP },
8758 { MASK_VSX, CODE_FOR_vsx_tdivv4sf3_fe, "__builtin_vsx_xvtdivsp_fe", VSX_BUILTIN_XVTDIVSP_FE },
8759 { MASK_VSX, CODE_FOR_vsx_tdivv4sf3_fg, "__builtin_vsx_xvtdivsp_fg", VSX_BUILTIN_XVTDIVSP_FG },
8760 { MASK_VSX, CODE_FOR_vector_eqv4sf, "__builtin_vsx_xvcmpeqsp", VSX_BUILTIN_XVCMPEQSP },
8761 { MASK_VSX, CODE_FOR_vector_gtv4sf, "__builtin_vsx_xvcmpgtsp", VSX_BUILTIN_XVCMPGTSP },
8762 { MASK_VSX, CODE_FOR_vector_gev4sf, "__builtin_vsx_xvcmpgesp", VSX_BUILTIN_XVCMPGESP },
8764 { MASK_VSX, CODE_FOR_smindf3, "__builtin_vsx_xsmindp", VSX_BUILTIN_XSMINDP },
8765 { MASK_VSX, CODE_FOR_smaxdf3, "__builtin_vsx_xsmaxdp", VSX_BUILTIN_XSMAXDP },
8766 { MASK_VSX, CODE_FOR_vsx_tdivdf3_fe, "__builtin_vsx_xstdivdp_fe", VSX_BUILTIN_XSTDIVDP_FE },
8767 { MASK_VSX, CODE_FOR_vsx_tdivdf3_fg, "__builtin_vsx_xstdivdp_fg", VSX_BUILTIN_XSTDIVDP_FG },
8768 { MASK_VSX, CODE_FOR_vector_copysignv2df3, "__builtin_vsx_cpsgndp", VSX_BUILTIN_CPSGNDP },
8769 { MASK_VSX, CODE_FOR_vector_copysignv4sf3, "__builtin_vsx_cpsgnsp", VSX_BUILTIN_CPSGNSP },
8771 { MASK_VSX, CODE_FOR_vsx_concat_v2df, "__builtin_vsx_concat_2df", VSX_BUILTIN_CONCAT_2DF },
8772 { MASK_VSX, CODE_FOR_vsx_concat_v2di, "__builtin_vsx_concat_2di", VSX_BUILTIN_CONCAT_2DI },
8773 { MASK_VSX, CODE_FOR_vsx_splat_v2df, "__builtin_vsx_splat_2df", VSX_BUILTIN_SPLAT_2DF },
8774 { MASK_VSX, CODE_FOR_vsx_splat_v2di, "__builtin_vsx_splat_2di", VSX_BUILTIN_SPLAT_2DI },
8775 { MASK_VSX, CODE_FOR_vsx_xxmrghw_v4sf, "__builtin_vsx_xxmrghw", VSX_BUILTIN_XXMRGHW_4SF },
8776 { MASK_VSX, CODE_FOR_vsx_xxmrghw_v4si, "__builtin_vsx_xxmrghw_4si", VSX_BUILTIN_XXMRGHW_4SI },
8777 { MASK_VSX, CODE_FOR_vsx_xxmrglw_v4sf, "__builtin_vsx_xxmrglw", VSX_BUILTIN_XXMRGLW_4SF },
8778 { MASK_VSX, CODE_FOR_vsx_xxmrglw_v4si, "__builtin_vsx_xxmrglw_4si", VSX_BUILTIN_XXMRGLW_4SI },
8780 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_add", ALTIVEC_BUILTIN_VEC_ADD },
8781 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vaddfp", ALTIVEC_BUILTIN_VEC_VADDFP },
8782 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduwm", ALTIVEC_BUILTIN_VEC_VADDUWM },
8783 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhm", ALTIVEC_BUILTIN_VEC_VADDUHM },
8784 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubm", ALTIVEC_BUILTIN_VEC_VADDUBM },
8785 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_addc", ALTIVEC_BUILTIN_VEC_ADDC },
8786 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_adds", ALTIVEC_BUILTIN_VEC_ADDS },
8787 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddsws", ALTIVEC_BUILTIN_VEC_VADDSWS },
8788 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduws", ALTIVEC_BUILTIN_VEC_VADDUWS },
8789 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddshs", ALTIVEC_BUILTIN_VEC_VADDSHS },
8790 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhs", ALTIVEC_BUILTIN_VEC_VADDUHS },
8791 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddsbs", ALTIVEC_BUILTIN_VEC_VADDSBS },
8792 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubs", ALTIVEC_BUILTIN_VEC_VADDUBS },
8793 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_and", ALTIVEC_BUILTIN_VEC_AND },
8794 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_andc", ALTIVEC_BUILTIN_VEC_ANDC },
8795 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_avg", ALTIVEC_BUILTIN_VEC_AVG },
8796 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsw", ALTIVEC_BUILTIN_VEC_VAVGSW },
8797 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavguw", ALTIVEC_BUILTIN_VEC_VAVGUW },
8798 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsh", ALTIVEC_BUILTIN_VEC_VAVGSH },
8799 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavguh", ALTIVEC_BUILTIN_VEC_VAVGUH },
8800 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsb", ALTIVEC_BUILTIN_VEC_VAVGSB },
8801 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgub", ALTIVEC_BUILTIN_VEC_VAVGUB },
8802 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpb", ALTIVEC_BUILTIN_VEC_CMPB },
8803 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpeq", ALTIVEC_BUILTIN_VEC_CMPEQ },
8804 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpeqfp", ALTIVEC_BUILTIN_VEC_VCMPEQFP },
8805 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequw", ALTIVEC_BUILTIN_VEC_VCMPEQUW },
8806 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequh", ALTIVEC_BUILTIN_VEC_VCMPEQUH },
8807 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequb", ALTIVEC_BUILTIN_VEC_VCMPEQUB },
8808 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpge", ALTIVEC_BUILTIN_VEC_CMPGE },
8809 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpgt", ALTIVEC_BUILTIN_VEC_CMPGT },
8810 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtfp", ALTIVEC_BUILTIN_VEC_VCMPGTFP },
8811 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsw", ALTIVEC_BUILTIN_VEC_VCMPGTSW },
8812 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtuw", ALTIVEC_BUILTIN_VEC_VCMPGTUW },
8813 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsh", ALTIVEC_BUILTIN_VEC_VCMPGTSH },
8814 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtuh", ALTIVEC_BUILTIN_VEC_VCMPGTUH },
8815 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsb", ALTIVEC_BUILTIN_VEC_VCMPGTSB },
8816 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtub", ALTIVEC_BUILTIN_VEC_VCMPGTUB },
8817 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmple", ALTIVEC_BUILTIN_VEC_CMPLE },
8818 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmplt", ALTIVEC_BUILTIN_VEC_CMPLT },
8819 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_copysign", ALTIVEC_BUILTIN_VEC_COPYSIGN },
8820 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_max", ALTIVEC_BUILTIN_VEC_MAX },
8821 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vmaxfp", ALTIVEC_BUILTIN_VEC_VMAXFP },
8822 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsw", ALTIVEC_BUILTIN_VEC_VMAXSW },
8823 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxuw", ALTIVEC_BUILTIN_VEC_VMAXUW },
8824 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsh", ALTIVEC_BUILTIN_VEC_VMAXSH },
8825 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxuh", ALTIVEC_BUILTIN_VEC_VMAXUH },
8826 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsb", ALTIVEC_BUILTIN_VEC_VMAXSB },
8827 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxub", ALTIVEC_BUILTIN_VEC_VMAXUB },
8828 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mergeh", ALTIVEC_BUILTIN_VEC_MERGEH },
8829 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghw", ALTIVEC_BUILTIN_VEC_VMRGHW },
8830 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghh", ALTIVEC_BUILTIN_VEC_VMRGHH },
8831 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghb", ALTIVEC_BUILTIN_VEC_VMRGHB },
8832 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mergel", ALTIVEC_BUILTIN_VEC_MERGEL },
8833 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglw", ALTIVEC_BUILTIN_VEC_VMRGLW },
8834 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglh", ALTIVEC_BUILTIN_VEC_VMRGLH },
8835 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglb", ALTIVEC_BUILTIN_VEC_VMRGLB },
8836 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_min", ALTIVEC_BUILTIN_VEC_MIN },
8837 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vminfp", ALTIVEC_BUILTIN_VEC_VMINFP },
8838 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsw", ALTIVEC_BUILTIN_VEC_VMINSW },
8839 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminuw", ALTIVEC_BUILTIN_VEC_VMINUW },
8840 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsh", ALTIVEC_BUILTIN_VEC_VMINSH },
8841 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminuh", ALTIVEC_BUILTIN_VEC_VMINUH },
8842 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsb", ALTIVEC_BUILTIN_VEC_VMINSB },
8843 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminub", ALTIVEC_BUILTIN_VEC_VMINUB },
8844 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mule", ALTIVEC_BUILTIN_VEC_MULE },
8845 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuleub", ALTIVEC_BUILTIN_VEC_VMULEUB },
8846 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulesb", ALTIVEC_BUILTIN_VEC_VMULESB },
8847 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuleuh", ALTIVEC_BUILTIN_VEC_VMULEUH },
8848 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulesh", ALTIVEC_BUILTIN_VEC_VMULESH },
8849 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mulo", ALTIVEC_BUILTIN_VEC_MULO },
8850 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulosh", ALTIVEC_BUILTIN_VEC_VMULOSH },
8851 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulouh", ALTIVEC_BUILTIN_VEC_VMULOUH },
8852 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulosb", ALTIVEC_BUILTIN_VEC_VMULOSB },
8853 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuloub", ALTIVEC_BUILTIN_VEC_VMULOUB },
8854 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_nor", ALTIVEC_BUILTIN_VEC_NOR },
8855 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_or", ALTIVEC_BUILTIN_VEC_OR },
8856 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_pack", ALTIVEC_BUILTIN_VEC_PACK },
8857 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuwum", ALTIVEC_BUILTIN_VEC_VPKUWUM },
8858 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuhum", ALTIVEC_BUILTIN_VEC_VPKUHUM },
8859 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packpx", ALTIVEC_BUILTIN_VEC_PACKPX },
8860 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packs", ALTIVEC_BUILTIN_VEC_PACKS },
8861 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkswss", ALTIVEC_BUILTIN_VEC_VPKSWSS },
8862 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuwus", ALTIVEC_BUILTIN_VEC_VPKUWUS },
8863 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkshss", ALTIVEC_BUILTIN_VEC_VPKSHSS },
8864 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuhus", ALTIVEC_BUILTIN_VEC_VPKUHUS },
8865 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packsu", ALTIVEC_BUILTIN_VEC_PACKSU },
8866 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkswus", ALTIVEC_BUILTIN_VEC_VPKSWUS },
8867 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkshus", ALTIVEC_BUILTIN_VEC_VPKSHUS },
8868 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rl", ALTIVEC_BUILTIN_VEC_RL },
8869 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlw", ALTIVEC_BUILTIN_VEC_VRLW },
8870 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlh", ALTIVEC_BUILTIN_VEC_VRLH },
8871 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlb", ALTIVEC_BUILTIN_VEC_VRLB },
8872 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sl", ALTIVEC_BUILTIN_VEC_SL },
8873 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslw", ALTIVEC_BUILTIN_VEC_VSLW },
8874 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslh", ALTIVEC_BUILTIN_VEC_VSLH },
8875 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslb", ALTIVEC_BUILTIN_VEC_VSLB },
8876 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sll", ALTIVEC_BUILTIN_VEC_SLL },
8877 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_slo", ALTIVEC_BUILTIN_VEC_SLO },
8878 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sr", ALTIVEC_BUILTIN_VEC_SR },
8879 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrw", ALTIVEC_BUILTIN_VEC_VSRW },
8880 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrh", ALTIVEC_BUILTIN_VEC_VSRH },
8881 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrb", ALTIVEC_BUILTIN_VEC_VSRB },
8882 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sra", ALTIVEC_BUILTIN_VEC_SRA },
8883 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsraw", ALTIVEC_BUILTIN_VEC_VSRAW },
8884 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrah", ALTIVEC_BUILTIN_VEC_VSRAH },
8885 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrab", ALTIVEC_BUILTIN_VEC_VSRAB },
8886 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_srl", ALTIVEC_BUILTIN_VEC_SRL },
8887 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sro", ALTIVEC_BUILTIN_VEC_SRO },
8888 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_sub", ALTIVEC_BUILTIN_VEC_SUB },
8889 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vsubfp", ALTIVEC_BUILTIN_VEC_VSUBFP },
8890 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuwm", ALTIVEC_BUILTIN_VEC_VSUBUWM },
8891 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuhm", ALTIVEC_BUILTIN_VEC_VSUBUHM },
8892 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsububm", ALTIVEC_BUILTIN_VEC_VSUBUBM },
8893 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_subc", ALTIVEC_BUILTIN_VEC_SUBC },
8894 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_subs", ALTIVEC_BUILTIN_VEC_SUBS },
8895 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubsws", ALTIVEC_BUILTIN_VEC_VSUBSWS },
8896 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuws", ALTIVEC_BUILTIN_VEC_VSUBUWS },
8897 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubshs", ALTIVEC_BUILTIN_VEC_VSUBSHS },
8898 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuhs", ALTIVEC_BUILTIN_VEC_VSUBUHS },
8899 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubsbs", ALTIVEC_BUILTIN_VEC_VSUBSBS },
8900 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsububs", ALTIVEC_BUILTIN_VEC_VSUBUBS },
8901 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sum4s", ALTIVEC_BUILTIN_VEC_SUM4S },
8902 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4shs", ALTIVEC_BUILTIN_VEC_VSUM4SHS },
8903 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4sbs", ALTIVEC_BUILTIN_VEC_VSUM4SBS },
8904 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4ubs", ALTIVEC_BUILTIN_VEC_VSUM4UBS },
8905 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sum2s", ALTIVEC_BUILTIN_VEC_SUM2S },
8906 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sums", ALTIVEC_BUILTIN_VEC_SUMS },
8907 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_xor", ALTIVEC_BUILTIN_VEC_XOR },
8909 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_mul", VSX_BUILTIN_VEC_MUL },
8910 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_div", VSX_BUILTIN_VEC_DIV },
8912 { 0, CODE_FOR_divv2sf3, "__builtin_paired_divv2sf3", PAIRED_BUILTIN_DIVV2SF3 },
8913 { 0, CODE_FOR_addv2sf3, "__builtin_paired_addv2sf3", PAIRED_BUILTIN_ADDV2SF3 },
8914 { 0, CODE_FOR_subv2sf3, "__builtin_paired_subv2sf3", PAIRED_BUILTIN_SUBV2SF3 },
8915 { 0, CODE_FOR_mulv2sf3, "__builtin_paired_mulv2sf3", PAIRED_BUILTIN_MULV2SF3 },
8916 { 0, CODE_FOR_paired_muls0, "__builtin_paired_muls0", PAIRED_BUILTIN_MULS0 },
8917 { 0, CODE_FOR_paired_muls1, "__builtin_paired_muls1", PAIRED_BUILTIN_MULS1 },
8918 { 0, CODE_FOR_paired_merge00, "__builtin_paired_merge00", PAIRED_BUILTIN_MERGE00 },
8919 { 0, CODE_FOR_paired_merge01, "__builtin_paired_merge01", PAIRED_BUILTIN_MERGE01 },
8920 { 0, CODE_FOR_paired_merge10, "__builtin_paired_merge10", PAIRED_BUILTIN_MERGE10 },
8921 { 0, CODE_FOR_paired_merge11, "__builtin_paired_merge11", PAIRED_BUILTIN_MERGE11 },
8923 /* Place holder, leave as first spe builtin. */
8924 { 0, CODE_FOR_spe_evaddw, "__builtin_spe_evaddw", SPE_BUILTIN_EVADDW },
8925 { 0, CODE_FOR_spe_evand, "__builtin_spe_evand", SPE_BUILTIN_EVAND },
8926 { 0, CODE_FOR_spe_evandc, "__builtin_spe_evandc", SPE_BUILTIN_EVANDC },
8927 { 0, CODE_FOR_spe_evdivws, "__builtin_spe_evdivws", SPE_BUILTIN_EVDIVWS },
8928 { 0, CODE_FOR_spe_evdivwu, "__builtin_spe_evdivwu", SPE_BUILTIN_EVDIVWU },
8929 { 0, CODE_FOR_spe_eveqv, "__builtin_spe_eveqv", SPE_BUILTIN_EVEQV },
8930 { 0, CODE_FOR_spe_evfsadd, "__builtin_spe_evfsadd", SPE_BUILTIN_EVFSADD },
8931 { 0, CODE_FOR_spe_evfsdiv, "__builtin_spe_evfsdiv", SPE_BUILTIN_EVFSDIV },
8932 { 0, CODE_FOR_spe_evfsmul, "__builtin_spe_evfsmul", SPE_BUILTIN_EVFSMUL },
8933 { 0, CODE_FOR_spe_evfssub, "__builtin_spe_evfssub", SPE_BUILTIN_EVFSSUB },
8934 { 0, CODE_FOR_spe_evmergehi, "__builtin_spe_evmergehi", SPE_BUILTIN_EVMERGEHI },
8935 { 0, CODE_FOR_spe_evmergehilo, "__builtin_spe_evmergehilo", SPE_BUILTIN_EVMERGEHILO },
8936 { 0, CODE_FOR_spe_evmergelo, "__builtin_spe_evmergelo", SPE_BUILTIN_EVMERGELO },
8937 { 0, CODE_FOR_spe_evmergelohi, "__builtin_spe_evmergelohi", SPE_BUILTIN_EVMERGELOHI },
8938 { 0, CODE_FOR_spe_evmhegsmfaa, "__builtin_spe_evmhegsmfaa", SPE_BUILTIN_EVMHEGSMFAA },
8939 { 0, CODE_FOR_spe_evmhegsmfan, "__builtin_spe_evmhegsmfan", SPE_BUILTIN_EVMHEGSMFAN },
8940 { 0, CODE_FOR_spe_evmhegsmiaa, "__builtin_spe_evmhegsmiaa", SPE_BUILTIN_EVMHEGSMIAA },
8941 { 0, CODE_FOR_spe_evmhegsmian, "__builtin_spe_evmhegsmian", SPE_BUILTIN_EVMHEGSMIAN },
8942 { 0, CODE_FOR_spe_evmhegumiaa, "__builtin_spe_evmhegumiaa", SPE_BUILTIN_EVMHEGUMIAA },
8943 { 0, CODE_FOR_spe_evmhegumian, "__builtin_spe_evmhegumian", SPE_BUILTIN_EVMHEGUMIAN },
8944 { 0, CODE_FOR_spe_evmhesmf, "__builtin_spe_evmhesmf", SPE_BUILTIN_EVMHESMF },
8945 { 0, CODE_FOR_spe_evmhesmfa, "__builtin_spe_evmhesmfa", SPE_BUILTIN_EVMHESMFA },
8946 { 0, CODE_FOR_spe_evmhesmfaaw, "__builtin_spe_evmhesmfaaw", SPE_BUILTIN_EVMHESMFAAW },
8947 { 0, CODE_FOR_spe_evmhesmfanw, "__builtin_spe_evmhesmfanw", SPE_BUILTIN_EVMHESMFANW },
8948 { 0, CODE_FOR_spe_evmhesmi, "__builtin_spe_evmhesmi", SPE_BUILTIN_EVMHESMI },
8949 { 0, CODE_FOR_spe_evmhesmia, "__builtin_spe_evmhesmia", SPE_BUILTIN_EVMHESMIA },
8950 { 0, CODE_FOR_spe_evmhesmiaaw, "__builtin_spe_evmhesmiaaw", SPE_BUILTIN_EVMHESMIAAW },
8951 { 0, CODE_FOR_spe_evmhesmianw, "__builtin_spe_evmhesmianw", SPE_BUILTIN_EVMHESMIANW },
8952 { 0, CODE_FOR_spe_evmhessf, "__builtin_spe_evmhessf", SPE_BUILTIN_EVMHESSF },
8953 { 0, CODE_FOR_spe_evmhessfa, "__builtin_spe_evmhessfa", SPE_BUILTIN_EVMHESSFA },
8954 { 0, CODE_FOR_spe_evmhessfaaw, "__builtin_spe_evmhessfaaw", SPE_BUILTIN_EVMHESSFAAW },
8955 { 0, CODE_FOR_spe_evmhessfanw, "__builtin_spe_evmhessfanw", SPE_BUILTIN_EVMHESSFANW },
8956 { 0, CODE_FOR_spe_evmhessiaaw, "__builtin_spe_evmhessiaaw", SPE_BUILTIN_EVMHESSIAAW },
8957 { 0, CODE_FOR_spe_evmhessianw, "__builtin_spe_evmhessianw", SPE_BUILTIN_EVMHESSIANW },
8958 { 0, CODE_FOR_spe_evmheumi, "__builtin_spe_evmheumi", SPE_BUILTIN_EVMHEUMI },
8959 { 0, CODE_FOR_spe_evmheumia, "__builtin_spe_evmheumia", SPE_BUILTIN_EVMHEUMIA },
8960 { 0, CODE_FOR_spe_evmheumiaaw, "__builtin_spe_evmheumiaaw", SPE_BUILTIN_EVMHEUMIAAW },
8961 { 0, CODE_FOR_spe_evmheumianw, "__builtin_spe_evmheumianw", SPE_BUILTIN_EVMHEUMIANW },
8962 { 0, CODE_FOR_spe_evmheusiaaw, "__builtin_spe_evmheusiaaw", SPE_BUILTIN_EVMHEUSIAAW },
8963 { 0, CODE_FOR_spe_evmheusianw, "__builtin_spe_evmheusianw", SPE_BUILTIN_EVMHEUSIANW },
8964 { 0, CODE_FOR_spe_evmhogsmfaa, "__builtin_spe_evmhogsmfaa", SPE_BUILTIN_EVMHOGSMFAA },
8965 { 0, CODE_FOR_spe_evmhogsmfan, "__builtin_spe_evmhogsmfan", SPE_BUILTIN_EVMHOGSMFAN },
8966 { 0, CODE_FOR_spe_evmhogsmiaa, "__builtin_spe_evmhogsmiaa", SPE_BUILTIN_EVMHOGSMIAA },
8967 { 0, CODE_FOR_spe_evmhogsmian, "__builtin_spe_evmhogsmian", SPE_BUILTIN_EVMHOGSMIAN },
8968 { 0, CODE_FOR_spe_evmhogumiaa, "__builtin_spe_evmhogumiaa", SPE_BUILTIN_EVMHOGUMIAA },
8969 { 0, CODE_FOR_spe_evmhogumian, "__builtin_spe_evmhogumian", SPE_BUILTIN_EVMHOGUMIAN },
8970 { 0, CODE_FOR_spe_evmhosmf, "__builtin_spe_evmhosmf", SPE_BUILTIN_EVMHOSMF },
8971 { 0, CODE_FOR_spe_evmhosmfa, "__builtin_spe_evmhosmfa", SPE_BUILTIN_EVMHOSMFA },
8972 { 0, CODE_FOR_spe_evmhosmfaaw, "__builtin_spe_evmhosmfaaw", SPE_BUILTIN_EVMHOSMFAAW },
8973 { 0, CODE_FOR_spe_evmhosmfanw, "__builtin_spe_evmhosmfanw", SPE_BUILTIN_EVMHOSMFANW },
8974 { 0, CODE_FOR_spe_evmhosmi, "__builtin_spe_evmhosmi", SPE_BUILTIN_EVMHOSMI },
8975 { 0, CODE_FOR_spe_evmhosmia, "__builtin_spe_evmhosmia", SPE_BUILTIN_EVMHOSMIA },
8976 { 0, CODE_FOR_spe_evmhosmiaaw, "__builtin_spe_evmhosmiaaw", SPE_BUILTIN_EVMHOSMIAAW },
8977 { 0, CODE_FOR_spe_evmhosmianw, "__builtin_spe_evmhosmianw", SPE_BUILTIN_EVMHOSMIANW },
8978 { 0, CODE_FOR_spe_evmhossf, "__builtin_spe_evmhossf", SPE_BUILTIN_EVMHOSSF },
8979 { 0, CODE_FOR_spe_evmhossfa, "__builtin_spe_evmhossfa", SPE_BUILTIN_EVMHOSSFA },
8980 { 0, CODE_FOR_spe_evmhossfaaw, "__builtin_spe_evmhossfaaw", SPE_BUILTIN_EVMHOSSFAAW },
8981 { 0, CODE_FOR_spe_evmhossfanw, "__builtin_spe_evmhossfanw", SPE_BUILTIN_EVMHOSSFANW },
8982 { 0, CODE_FOR_spe_evmhossiaaw, "__builtin_spe_evmhossiaaw", SPE_BUILTIN_EVMHOSSIAAW },
8983 { 0, CODE_FOR_spe_evmhossianw, "__builtin_spe_evmhossianw", SPE_BUILTIN_EVMHOSSIANW },
8984 { 0, CODE_FOR_spe_evmhoumi, "__builtin_spe_evmhoumi", SPE_BUILTIN_EVMHOUMI },
8985 { 0, CODE_FOR_spe_evmhoumia, "__builtin_spe_evmhoumia", SPE_BUILTIN_EVMHOUMIA },
8986 { 0, CODE_FOR_spe_evmhoumiaaw, "__builtin_spe_evmhoumiaaw", SPE_BUILTIN_EVMHOUMIAAW },
8987 { 0, CODE_FOR_spe_evmhoumianw, "__builtin_spe_evmhoumianw", SPE_BUILTIN_EVMHOUMIANW },
8988 { 0, CODE_FOR_spe_evmhousiaaw, "__builtin_spe_evmhousiaaw", SPE_BUILTIN_EVMHOUSIAAW },
8989 { 0, CODE_FOR_spe_evmhousianw, "__builtin_spe_evmhousianw", SPE_BUILTIN_EVMHOUSIANW },
8990 { 0, CODE_FOR_spe_evmwhsmf, "__builtin_spe_evmwhsmf", SPE_BUILTIN_EVMWHSMF },
8991 { 0, CODE_FOR_spe_evmwhsmfa, "__builtin_spe_evmwhsmfa", SPE_BUILTIN_EVMWHSMFA },
8992 { 0, CODE_FOR_spe_evmwhsmi, "__builtin_spe_evmwhsmi", SPE_BUILTIN_EVMWHSMI },
8993 { 0, CODE_FOR_spe_evmwhsmia, "__builtin_spe_evmwhsmia", SPE_BUILTIN_EVMWHSMIA },
8994 { 0, CODE_FOR_spe_evmwhssf, "__builtin_spe_evmwhssf", SPE_BUILTIN_EVMWHSSF },
8995 { 0, CODE_FOR_spe_evmwhssfa, "__builtin_spe_evmwhssfa", SPE_BUILTIN_EVMWHSSFA },
8996 { 0, CODE_FOR_spe_evmwhumi, "__builtin_spe_evmwhumi", SPE_BUILTIN_EVMWHUMI },
8997 { 0, CODE_FOR_spe_evmwhumia, "__builtin_spe_evmwhumia", SPE_BUILTIN_EVMWHUMIA },
8998 { 0, CODE_FOR_spe_evmwlsmiaaw, "__builtin_spe_evmwlsmiaaw", SPE_BUILTIN_EVMWLSMIAAW },
8999 { 0, CODE_FOR_spe_evmwlsmianw, "__builtin_spe_evmwlsmianw", SPE_BUILTIN_EVMWLSMIANW },
9000 { 0, CODE_FOR_spe_evmwlssiaaw, "__builtin_spe_evmwlssiaaw", SPE_BUILTIN_EVMWLSSIAAW },
9001 { 0, CODE_FOR_spe_evmwlssianw, "__builtin_spe_evmwlssianw", SPE_BUILTIN_EVMWLSSIANW },
9002 { 0, CODE_FOR_spe_evmwlumi, "__builtin_spe_evmwlumi", SPE_BUILTIN_EVMWLUMI },
9003 { 0, CODE_FOR_spe_evmwlumia, "__builtin_spe_evmwlumia", SPE_BUILTIN_EVMWLUMIA },
9004 { 0, CODE_FOR_spe_evmwlumiaaw, "__builtin_spe_evmwlumiaaw", SPE_BUILTIN_EVMWLUMIAAW },
9005 { 0, CODE_FOR_spe_evmwlumianw, "__builtin_spe_evmwlumianw", SPE_BUILTIN_EVMWLUMIANW },
9006 { 0, CODE_FOR_spe_evmwlusiaaw, "__builtin_spe_evmwlusiaaw", SPE_BUILTIN_EVMWLUSIAAW },
9007 { 0, CODE_FOR_spe_evmwlusianw, "__builtin_spe_evmwlusianw", SPE_BUILTIN_EVMWLUSIANW },
9008 { 0, CODE_FOR_spe_evmwsmf, "__builtin_spe_evmwsmf", SPE_BUILTIN_EVMWSMF },
9009 { 0, CODE_FOR_spe_evmwsmfa, "__builtin_spe_evmwsmfa", SPE_BUILTIN_EVMWSMFA },
9010 { 0, CODE_FOR_spe_evmwsmfaa, "__builtin_spe_evmwsmfaa", SPE_BUILTIN_EVMWSMFAA },
9011 { 0, CODE_FOR_spe_evmwsmfan, "__builtin_spe_evmwsmfan", SPE_BUILTIN_EVMWSMFAN },
9012 { 0, CODE_FOR_spe_evmwsmi, "__builtin_spe_evmwsmi", SPE_BUILTIN_EVMWSMI },
9013 { 0, CODE_FOR_spe_evmwsmia, "__builtin_spe_evmwsmia", SPE_BUILTIN_EVMWSMIA },
9014 { 0, CODE_FOR_spe_evmwsmiaa, "__builtin_spe_evmwsmiaa", SPE_BUILTIN_EVMWSMIAA },
9015 { 0, CODE_FOR_spe_evmwsmian, "__builtin_spe_evmwsmian", SPE_BUILTIN_EVMWSMIAN },
9016 { 0, CODE_FOR_spe_evmwssf, "__builtin_spe_evmwssf", SPE_BUILTIN_EVMWSSF },
9017 { 0, CODE_FOR_spe_evmwssfa, "__builtin_spe_evmwssfa", SPE_BUILTIN_EVMWSSFA },
9018 { 0, CODE_FOR_spe_evmwssfaa, "__builtin_spe_evmwssfaa", SPE_BUILTIN_EVMWSSFAA },
9019 { 0, CODE_FOR_spe_evmwssfan, "__builtin_spe_evmwssfan", SPE_BUILTIN_EVMWSSFAN },
9020 { 0, CODE_FOR_spe_evmwumi, "__builtin_spe_evmwumi", SPE_BUILTIN_EVMWUMI },
9021 { 0, CODE_FOR_spe_evmwumia, "__builtin_spe_evmwumia", SPE_BUILTIN_EVMWUMIA },
9022 { 0, CODE_FOR_spe_evmwumiaa, "__builtin_spe_evmwumiaa", SPE_BUILTIN_EVMWUMIAA },
9023 { 0, CODE_FOR_spe_evmwumian, "__builtin_spe_evmwumian", SPE_BUILTIN_EVMWUMIAN },
9024 { 0, CODE_FOR_spe_evnand, "__builtin_spe_evnand", SPE_BUILTIN_EVNAND },
9025 { 0, CODE_FOR_spe_evnor, "__builtin_spe_evnor", SPE_BUILTIN_EVNOR },
9026 { 0, CODE_FOR_spe_evor, "__builtin_spe_evor", SPE_BUILTIN_EVOR },
9027 { 0, CODE_FOR_spe_evorc, "__builtin_spe_evorc", SPE_BUILTIN_EVORC },
9028 { 0, CODE_FOR_spe_evrlw, "__builtin_spe_evrlw", SPE_BUILTIN_EVRLW },
9029 { 0, CODE_FOR_spe_evslw, "__builtin_spe_evslw", SPE_BUILTIN_EVSLW },
9030 { 0, CODE_FOR_spe_evsrws, "__builtin_spe_evsrws", SPE_BUILTIN_EVSRWS },
9031 { 0, CODE_FOR_spe_evsrwu, "__builtin_spe_evsrwu", SPE_BUILTIN_EVSRWU },
9032 { 0, CODE_FOR_spe_evsubfw, "__builtin_spe_evsubfw", SPE_BUILTIN_EVSUBFW },
9034 /* SPE binary operations expecting a 5-bit unsigned literal. */
9035 { 0, CODE_FOR_spe_evaddiw, "__builtin_spe_evaddiw", SPE_BUILTIN_EVADDIW },
9037 { 0, CODE_FOR_spe_evrlwi, "__builtin_spe_evrlwi", SPE_BUILTIN_EVRLWI },
9038 { 0, CODE_FOR_spe_evslwi, "__builtin_spe_evslwi", SPE_BUILTIN_EVSLWI },
9039 { 0, CODE_FOR_spe_evsrwis, "__builtin_spe_evsrwis", SPE_BUILTIN_EVSRWIS },
9040 { 0, CODE_FOR_spe_evsrwiu, "__builtin_spe_evsrwiu", SPE_BUILTIN_EVSRWIU },
9041 { 0, CODE_FOR_spe_evsubifw, "__builtin_spe_evsubifw", SPE_BUILTIN_EVSUBIFW },
9042 { 0, CODE_FOR_spe_evmwhssfaa, "__builtin_spe_evmwhssfaa", SPE_BUILTIN_EVMWHSSFAA },
9043 { 0, CODE_FOR_spe_evmwhssmaa, "__builtin_spe_evmwhssmaa", SPE_BUILTIN_EVMWHSSMAA },
9044 { 0, CODE_FOR_spe_evmwhsmfaa, "__builtin_spe_evmwhsmfaa", SPE_BUILTIN_EVMWHSMFAA },
9045 { 0, CODE_FOR_spe_evmwhsmiaa, "__builtin_spe_evmwhsmiaa", SPE_BUILTIN_EVMWHSMIAA },
9046 { 0, CODE_FOR_spe_evmwhusiaa, "__builtin_spe_evmwhusiaa", SPE_BUILTIN_EVMWHUSIAA },
9047 { 0, CODE_FOR_spe_evmwhumiaa, "__builtin_spe_evmwhumiaa", SPE_BUILTIN_EVMWHUMIAA },
9048 { 0, CODE_FOR_spe_evmwhssfan, "__builtin_spe_evmwhssfan", SPE_BUILTIN_EVMWHSSFAN },
9049 { 0, CODE_FOR_spe_evmwhssian, "__builtin_spe_evmwhssian", SPE_BUILTIN_EVMWHSSIAN },
9050 { 0, CODE_FOR_spe_evmwhsmfan, "__builtin_spe_evmwhsmfan", SPE_BUILTIN_EVMWHSMFAN },
9051 { 0, CODE_FOR_spe_evmwhsmian, "__builtin_spe_evmwhsmian", SPE_BUILTIN_EVMWHSMIAN },
9052 { 0, CODE_FOR_spe_evmwhusian, "__builtin_spe_evmwhusian", SPE_BUILTIN_EVMWHUSIAN },
9053 { 0, CODE_FOR_spe_evmwhumian, "__builtin_spe_evmwhumian", SPE_BUILTIN_EVMWHUMIAN },
9054 { 0, CODE_FOR_spe_evmwhgssfaa, "__builtin_spe_evmwhgssfaa", SPE_BUILTIN_EVMWHGSSFAA },
9055 { 0, CODE_FOR_spe_evmwhgsmfaa, "__builtin_spe_evmwhgsmfaa", SPE_BUILTIN_EVMWHGSMFAA },
9056 { 0, CODE_FOR_spe_evmwhgsmiaa, "__builtin_spe_evmwhgsmiaa", SPE_BUILTIN_EVMWHGSMIAA },
9057 { 0, CODE_FOR_spe_evmwhgumiaa, "__builtin_spe_evmwhgumiaa", SPE_BUILTIN_EVMWHGUMIAA },
9058 { 0, CODE_FOR_spe_evmwhgssfan, "__builtin_spe_evmwhgssfan", SPE_BUILTIN_EVMWHGSSFAN },
9059 { 0, CODE_FOR_spe_evmwhgsmfan, "__builtin_spe_evmwhgsmfan", SPE_BUILTIN_EVMWHGSMFAN },
9060 { 0, CODE_FOR_spe_evmwhgsmian, "__builtin_spe_evmwhgsmian", SPE_BUILTIN_EVMWHGSMIAN },
9061 { 0, CODE_FOR_spe_evmwhgumian, "__builtin_spe_evmwhgumian", SPE_BUILTIN_EVMWHGUMIAN },
9062 { 0, CODE_FOR_spe_brinc, "__builtin_spe_brinc", SPE_BUILTIN_BRINC },
9064 /* Place-holder. Leave as last binary SPE builtin. */
9065 { 0, CODE_FOR_xorv2si3, "__builtin_spe_evxor", SPE_BUILTIN_EVXOR }
9068 /* AltiVec predicates. */
9070 struct builtin_description_predicates
9072 const unsigned int mask;
9073 const enum insn_code icode;
9074 const char *const name;
9075 const enum rs6000_builtins code;
9078 static const struct builtin_description_predicates bdesc_altivec_preds[] =
9080 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpbfp_p, "__builtin_altivec_vcmpbfp_p",
9081 ALTIVEC_BUILTIN_VCMPBFP_P },
9082 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_eq_v4sf_p,
9083 "__builtin_altivec_vcmpeqfp_p", ALTIVEC_BUILTIN_VCMPEQFP_P },
9084 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_ge_v4sf_p,
9085 "__builtin_altivec_vcmpgefp_p", ALTIVEC_BUILTIN_VCMPGEFP_P },
9086 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_gt_v4sf_p,
9087 "__builtin_altivec_vcmpgtfp_p", ALTIVEC_BUILTIN_VCMPGTFP_P },
9088 { MASK_ALTIVEC, CODE_FOR_vector_eq_v4si_p, "__builtin_altivec_vcmpequw_p",
9089 ALTIVEC_BUILTIN_VCMPEQUW_P },
9090 { MASK_ALTIVEC, CODE_FOR_vector_gt_v4si_p, "__builtin_altivec_vcmpgtsw_p",
9091 ALTIVEC_BUILTIN_VCMPGTSW_P },
9092 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v4si_p, "__builtin_altivec_vcmpgtuw_p",
9093 ALTIVEC_BUILTIN_VCMPGTUW_P },
9094 { MASK_ALTIVEC, CODE_FOR_vector_eq_v8hi_p, "__builtin_altivec_vcmpequh_p",
9095 ALTIVEC_BUILTIN_VCMPEQUH_P },
9096 { MASK_ALTIVEC, CODE_FOR_vector_gt_v8hi_p, "__builtin_altivec_vcmpgtsh_p",
9097 ALTIVEC_BUILTIN_VCMPGTSH_P },
9098 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v8hi_p, "__builtin_altivec_vcmpgtuh_p",
9099 ALTIVEC_BUILTIN_VCMPGTUH_P },
9100 { MASK_ALTIVEC, CODE_FOR_vector_eq_v16qi_p, "__builtin_altivec_vcmpequb_p",
9101 ALTIVEC_BUILTIN_VCMPEQUB_P },
9102 { MASK_ALTIVEC, CODE_FOR_vector_gt_v16qi_p, "__builtin_altivec_vcmpgtsb_p",
9103 ALTIVEC_BUILTIN_VCMPGTSB_P },
9104 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v16qi_p, "__builtin_altivec_vcmpgtub_p",
9105 ALTIVEC_BUILTIN_VCMPGTUB_P },
9107 { MASK_VSX, CODE_FOR_vector_eq_v4sf_p, "__builtin_vsx_xvcmpeqsp_p",
9108 VSX_BUILTIN_XVCMPEQSP_P },
9109 { MASK_VSX, CODE_FOR_vector_ge_v4sf_p, "__builtin_vsx_xvcmpgesp_p",
9110 VSX_BUILTIN_XVCMPGESP_P },
9111 { MASK_VSX, CODE_FOR_vector_gt_v4sf_p, "__builtin_vsx_xvcmpgtsp_p",
9112 VSX_BUILTIN_XVCMPGTSP_P },
9113 { MASK_VSX, CODE_FOR_vector_eq_v2df_p, "__builtin_vsx_xvcmpeqdp_p",
9114 VSX_BUILTIN_XVCMPEQDP_P },
9115 { MASK_VSX, CODE_FOR_vector_ge_v2df_p, "__builtin_vsx_xvcmpgedp_p",
9116 VSX_BUILTIN_XVCMPGEDP_P },
9117 { MASK_VSX, CODE_FOR_vector_gt_v2df_p, "__builtin_vsx_xvcmpgtdp_p",
9118 VSX_BUILTIN_XVCMPGTDP_P },
9120 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpeq_p",
9121 ALTIVEC_BUILTIN_VCMPEQ_P },
9122 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpgt_p",
9123 ALTIVEC_BUILTIN_VCMPGT_P },
9124 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpge_p",
9125 ALTIVEC_BUILTIN_VCMPGE_P }
9128 /* SPE predicates. */
9129 static struct builtin_description bdesc_spe_predicates[] =
9131 /* Place-holder. Leave as first. */
9132 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evcmpeq", SPE_BUILTIN_EVCMPEQ },
9133 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evcmpgts", SPE_BUILTIN_EVCMPGTS },
9134 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evcmpgtu", SPE_BUILTIN_EVCMPGTU },
9135 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evcmplts", SPE_BUILTIN_EVCMPLTS },
9136 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evcmpltu", SPE_BUILTIN_EVCMPLTU },
9137 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evfscmpeq", SPE_BUILTIN_EVFSCMPEQ },
9138 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evfscmpgt", SPE_BUILTIN_EVFSCMPGT },
9139 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evfscmplt", SPE_BUILTIN_EVFSCMPLT },
9140 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evfststeq", SPE_BUILTIN_EVFSTSTEQ },
9141 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evfststgt", SPE_BUILTIN_EVFSTSTGT },
9142 /* Place-holder. Leave as last. */
9143 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evfststlt", SPE_BUILTIN_EVFSTSTLT },
9146 /* SPE evsel predicates. */
9147 static struct builtin_description bdesc_spe_evsel[] =
9149 /* Place-holder. Leave as first. */
9150 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evsel_gts", SPE_BUILTIN_EVSEL_CMPGTS },
9151 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evsel_gtu", SPE_BUILTIN_EVSEL_CMPGTU },
9152 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evsel_lts", SPE_BUILTIN_EVSEL_CMPLTS },
9153 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evsel_ltu", SPE_BUILTIN_EVSEL_CMPLTU },
9154 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evsel_eq", SPE_BUILTIN_EVSEL_CMPEQ },
9155 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evsel_fsgt", SPE_BUILTIN_EVSEL_FSCMPGT },
9156 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evsel_fslt", SPE_BUILTIN_EVSEL_FSCMPLT },
9157 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evsel_fseq", SPE_BUILTIN_EVSEL_FSCMPEQ },
9158 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evsel_fststgt", SPE_BUILTIN_EVSEL_FSTSTGT },
9159 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evsel_fststlt", SPE_BUILTIN_EVSEL_FSTSTLT },
9160 /* Place-holder. Leave as last. */
9161 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evsel_fststeq", SPE_BUILTIN_EVSEL_FSTSTEQ },
9164 /* PAIRED predicates. */
9165 static const struct builtin_description bdesc_paired_preds[] =
9167 /* Place-holder. Leave as first. */
9168 { 0, CODE_FOR_paired_cmpu0, "__builtin_paired_cmpu0", PAIRED_BUILTIN_CMPU0 },
9169 /* Place-holder. Leave as last. */
9170 { 0, CODE_FOR_paired_cmpu1, "__builtin_paired_cmpu1", PAIRED_BUILTIN_CMPU1 },
9173 /* ABS* operations. */
9175 static const struct builtin_description bdesc_abs[] =
9177 { MASK_ALTIVEC, CODE_FOR_absv4si2, "__builtin_altivec_abs_v4si", ALTIVEC_BUILTIN_ABS_V4SI },
9178 { MASK_ALTIVEC, CODE_FOR_absv8hi2, "__builtin_altivec_abs_v8hi", ALTIVEC_BUILTIN_ABS_V8HI },
9179 { MASK_ALTIVEC, CODE_FOR_absv4sf2, "__builtin_altivec_abs_v4sf", ALTIVEC_BUILTIN_ABS_V4SF },
9180 { MASK_ALTIVEC, CODE_FOR_absv16qi2, "__builtin_altivec_abs_v16qi", ALTIVEC_BUILTIN_ABS_V16QI },
9181 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v4si, "__builtin_altivec_abss_v4si", ALTIVEC_BUILTIN_ABSS_V4SI },
9182 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v8hi, "__builtin_altivec_abss_v8hi", ALTIVEC_BUILTIN_ABSS_V8HI },
9183 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v16qi, "__builtin_altivec_abss_v16qi", ALTIVEC_BUILTIN_ABSS_V16QI },
9184 { MASK_VSX, CODE_FOR_absv2df2, "__builtin_vsx_xvabsdp", VSX_BUILTIN_XVABSDP },
9185 { MASK_VSX, CODE_FOR_vsx_nabsv2df2, "__builtin_vsx_xvnabsdp", VSX_BUILTIN_XVNABSDP },
9186 { MASK_VSX, CODE_FOR_absv4sf2, "__builtin_vsx_xvabssp", VSX_BUILTIN_XVABSSP },
9187 { MASK_VSX, CODE_FOR_vsx_nabsv4sf2, "__builtin_vsx_xvnabssp", VSX_BUILTIN_XVNABSSP },
9190 /* Simple unary operations: VECb = foo (unsigned literal) or VECb =
9191 foo (VECa). */
9193 static struct builtin_description bdesc_1arg[] =
9195 { MASK_ALTIVEC, CODE_FOR_altivec_vexptefp, "__builtin_altivec_vexptefp", ALTIVEC_BUILTIN_VEXPTEFP },
9196 { MASK_ALTIVEC, CODE_FOR_altivec_vlogefp, "__builtin_altivec_vlogefp", ALTIVEC_BUILTIN_VLOGEFP },
9197 { MASK_ALTIVEC, CODE_FOR_altivec_vrefp, "__builtin_altivec_vrefp", ALTIVEC_BUILTIN_VREFP },
9198 { MASK_ALTIVEC, CODE_FOR_vector_floorv4sf2, "__builtin_altivec_vrfim", ALTIVEC_BUILTIN_VRFIM },
9199 { MASK_ALTIVEC, CODE_FOR_altivec_vrfin, "__builtin_altivec_vrfin", ALTIVEC_BUILTIN_VRFIN },
9200 { MASK_ALTIVEC, CODE_FOR_vector_ceilv4sf2, "__builtin_altivec_vrfip", ALTIVEC_BUILTIN_VRFIP },
9201 { MASK_ALTIVEC, CODE_FOR_vector_btruncv4sf2, "__builtin_altivec_vrfiz", ALTIVEC_BUILTIN_VRFIZ },
9202 { MASK_ALTIVEC, CODE_FOR_altivec_vrsqrtefp, "__builtin_altivec_vrsqrtefp", ALTIVEC_BUILTIN_VRSQRTEFP },
9203 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisb, "__builtin_altivec_vspltisb", ALTIVEC_BUILTIN_VSPLTISB },
9204 { MASK_ALTIVEC, CODE_FOR_altivec_vspltish, "__builtin_altivec_vspltish", ALTIVEC_BUILTIN_VSPLTISH },
9205 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisw, "__builtin_altivec_vspltisw", ALTIVEC_BUILTIN_VSPLTISW },
9206 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsb, "__builtin_altivec_vupkhsb", ALTIVEC_BUILTIN_VUPKHSB },
9207 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhpx, "__builtin_altivec_vupkhpx", ALTIVEC_BUILTIN_VUPKHPX },
9208 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsh, "__builtin_altivec_vupkhsh", ALTIVEC_BUILTIN_VUPKHSH },
9209 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsb, "__builtin_altivec_vupklsb", ALTIVEC_BUILTIN_VUPKLSB },
9210 { MASK_ALTIVEC, CODE_FOR_altivec_vupklpx, "__builtin_altivec_vupklpx", ALTIVEC_BUILTIN_VUPKLPX },
9211 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsh, "__builtin_altivec_vupklsh", ALTIVEC_BUILTIN_VUPKLSH },
9213 { MASK_VSX, CODE_FOR_negv2df2, "__builtin_vsx_xvnegdp", VSX_BUILTIN_XVNEGDP },
9214 { MASK_VSX, CODE_FOR_sqrtv2df2, "__builtin_vsx_xvsqrtdp", VSX_BUILTIN_XVSQRTDP },
9215 { MASK_VSX, CODE_FOR_vsx_rsqrtev2df2, "__builtin_vsx_xvrsqrtedp", VSX_BUILTIN_XVRSQRTEDP },
9216 { MASK_VSX, CODE_FOR_vsx_tsqrtv2df2_fe, "__builtin_vsx_xvtsqrtdp_fe", VSX_BUILTIN_XVTSQRTDP_FE },
9217 { MASK_VSX, CODE_FOR_vsx_tsqrtv2df2_fg, "__builtin_vsx_xvtsqrtdp_fg", VSX_BUILTIN_XVTSQRTDP_FG },
9218 { MASK_VSX, CODE_FOR_vsx_frev2df2, "__builtin_vsx_xvredp", VSX_BUILTIN_XVREDP },
9220 { MASK_VSX, CODE_FOR_negv4sf2, "__builtin_vsx_xvnegsp", VSX_BUILTIN_XVNEGSP },
9221 { MASK_VSX, CODE_FOR_sqrtv4sf2, "__builtin_vsx_xvsqrtsp", VSX_BUILTIN_XVSQRTSP },
9222 { MASK_VSX, CODE_FOR_vsx_rsqrtev4sf2, "__builtin_vsx_xvrsqrtesp", VSX_BUILTIN_XVRSQRTESP },
9223 { MASK_VSX, CODE_FOR_vsx_tsqrtv4sf2_fe, "__builtin_vsx_xvtsqrtsp_fe", VSX_BUILTIN_XVTSQRTSP_FE },
9224 { MASK_VSX, CODE_FOR_vsx_tsqrtv4sf2_fg, "__builtin_vsx_xvtsqrtsp_fg", VSX_BUILTIN_XVTSQRTSP_FG },
9225 { MASK_VSX, CODE_FOR_vsx_frev4sf2, "__builtin_vsx_xvresp", VSX_BUILTIN_XVRESP },
9227 { MASK_VSX, CODE_FOR_vsx_xscvdpsp, "__builtin_vsx_xscvdpsp", VSX_BUILTIN_XSCVDPSP },
9228 { MASK_VSX, CODE_FOR_vsx_xscvdpsp, "__builtin_vsx_xscvspdp", VSX_BUILTIN_XSCVSPDP },
9229 { MASK_VSX, CODE_FOR_vsx_xvcvdpsp, "__builtin_vsx_xvcvdpsp", VSX_BUILTIN_XVCVDPSP },
9230 { MASK_VSX, CODE_FOR_vsx_xvcvspdp, "__builtin_vsx_xvcvspdp", VSX_BUILTIN_XVCVSPDP },
9231 { MASK_VSX, CODE_FOR_vsx_tsqrtdf2_fe, "__builtin_vsx_xstsqrtdp_fe", VSX_BUILTIN_XSTSQRTDP_FE },
9232 { MASK_VSX, CODE_FOR_vsx_tsqrtdf2_fg, "__builtin_vsx_xstsqrtdp_fg", VSX_BUILTIN_XSTSQRTDP_FG },
9234 { MASK_VSX, CODE_FOR_vsx_fix_truncv2dfv2di2, "__builtin_vsx_xvcvdpsxds", VSX_BUILTIN_XVCVDPSXDS },
9235 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv2dfv2di2, "__builtin_vsx_xvcvdpuxds", VSX_BUILTIN_XVCVDPUXDS },
9236 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv2dfv2di2, "__builtin_vsx_xvcvdpuxds_uns", VSX_BUILTIN_XVCVDPUXDS_UNS },
9237 { MASK_VSX, CODE_FOR_vsx_floatv2div2df2, "__builtin_vsx_xvcvsxddp", VSX_BUILTIN_XVCVSXDDP },
9238 { MASK_VSX, CODE_FOR_vsx_floatunsv2div2df2, "__builtin_vsx_xvcvuxddp", VSX_BUILTIN_XVCVUXDDP },
9239 { MASK_VSX, CODE_FOR_vsx_floatunsv2div2df2, "__builtin_vsx_xvcvuxddp_uns", VSX_BUILTIN_XVCVUXDDP_UNS },
9241 { MASK_VSX, CODE_FOR_vsx_fix_truncv4sfv4si2, "__builtin_vsx_xvcvspsxws", VSX_BUILTIN_XVCVSPSXWS },
9242 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv4sfv4si2, "__builtin_vsx_xvcvspuxws", VSX_BUILTIN_XVCVSPUXWS },
9243 { MASK_VSX, CODE_FOR_vsx_floatv4siv4sf2, "__builtin_vsx_xvcvsxwsp", VSX_BUILTIN_XVCVSXWSP },
9244 { MASK_VSX, CODE_FOR_vsx_floatunsv4siv4sf2, "__builtin_vsx_xvcvuxwsp", VSX_BUILTIN_XVCVUXWSP },
9246 { MASK_VSX, CODE_FOR_vsx_xvcvdpsxws, "__builtin_vsx_xvcvdpsxws", VSX_BUILTIN_XVCVDPSXWS },
9247 { MASK_VSX, CODE_FOR_vsx_xvcvdpuxws, "__builtin_vsx_xvcvdpuxws", VSX_BUILTIN_XVCVDPUXWS },
9248 { MASK_VSX, CODE_FOR_vsx_xvcvsxwdp, "__builtin_vsx_xvcvsxwdp", VSX_BUILTIN_XVCVSXWDP },
9249 { MASK_VSX, CODE_FOR_vsx_xvcvuxwdp, "__builtin_vsx_xvcvuxwdp", VSX_BUILTIN_XVCVUXWDP },
9250 { MASK_VSX, CODE_FOR_vsx_xvrdpi, "__builtin_vsx_xvrdpi", VSX_BUILTIN_XVRDPI },
9251 { MASK_VSX, CODE_FOR_vsx_xvrdpic, "__builtin_vsx_xvrdpic", VSX_BUILTIN_XVRDPIC },
9252 { MASK_VSX, CODE_FOR_vsx_floorv2df2, "__builtin_vsx_xvrdpim", VSX_BUILTIN_XVRDPIM },
9253 { MASK_VSX, CODE_FOR_vsx_ceilv2df2, "__builtin_vsx_xvrdpip", VSX_BUILTIN_XVRDPIP },
9254 { MASK_VSX, CODE_FOR_vsx_btruncv2df2, "__builtin_vsx_xvrdpiz", VSX_BUILTIN_XVRDPIZ },
9256 { MASK_VSX, CODE_FOR_vsx_xvcvspsxds, "__builtin_vsx_xvcvspsxds", VSX_BUILTIN_XVCVSPSXDS },
9257 { MASK_VSX, CODE_FOR_vsx_xvcvspuxds, "__builtin_vsx_xvcvspuxds", VSX_BUILTIN_XVCVSPUXDS },
9258 { MASK_VSX, CODE_FOR_vsx_xvcvsxdsp, "__builtin_vsx_xvcvsxdsp", VSX_BUILTIN_XVCVSXDSP },
9259 { MASK_VSX, CODE_FOR_vsx_xvcvuxdsp, "__builtin_vsx_xvcvuxdsp", VSX_BUILTIN_XVCVUXDSP },
9260 { MASK_VSX, CODE_FOR_vsx_xvrspi, "__builtin_vsx_xvrspi", VSX_BUILTIN_XVRSPI },
9261 { MASK_VSX, CODE_FOR_vsx_xvrspic, "__builtin_vsx_xvrspic", VSX_BUILTIN_XVRSPIC },
9262 { MASK_VSX, CODE_FOR_vsx_floorv4sf2, "__builtin_vsx_xvrspim", VSX_BUILTIN_XVRSPIM },
9263 { MASK_VSX, CODE_FOR_vsx_ceilv4sf2, "__builtin_vsx_xvrspip", VSX_BUILTIN_XVRSPIP },
9264 { MASK_VSX, CODE_FOR_vsx_btruncv4sf2, "__builtin_vsx_xvrspiz", VSX_BUILTIN_XVRSPIZ },
9266 { MASK_VSX, CODE_FOR_vsx_xsrdpi, "__builtin_vsx_xsrdpi", VSX_BUILTIN_XSRDPI },
9267 { MASK_VSX, CODE_FOR_vsx_xsrdpic, "__builtin_vsx_xsrdpic", VSX_BUILTIN_XSRDPIC },
9268 { MASK_VSX, CODE_FOR_vsx_floordf2, "__builtin_vsx_xsrdpim", VSX_BUILTIN_XSRDPIM },
9269 { MASK_VSX, CODE_FOR_vsx_ceildf2, "__builtin_vsx_xsrdpip", VSX_BUILTIN_XSRDPIP },
9270 { MASK_VSX, CODE_FOR_vsx_btruncdf2, "__builtin_vsx_xsrdpiz", VSX_BUILTIN_XSRDPIZ },
9272 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abs", ALTIVEC_BUILTIN_VEC_ABS },
9273 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abss", ALTIVEC_BUILTIN_VEC_ABSS },
9274 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_ceil", ALTIVEC_BUILTIN_VEC_CEIL },
9275 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_expte", ALTIVEC_BUILTIN_VEC_EXPTE },
9276 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_floor", ALTIVEC_BUILTIN_VEC_FLOOR },
9277 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_loge", ALTIVEC_BUILTIN_VEC_LOGE },
9278 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mtvscr", ALTIVEC_BUILTIN_VEC_MTVSCR },
9279 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_re", ALTIVEC_BUILTIN_VEC_RE },
9280 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_round", ALTIVEC_BUILTIN_VEC_ROUND },
9281 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rsqrte", ALTIVEC_BUILTIN_VEC_RSQRTE },
9282 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_trunc", ALTIVEC_BUILTIN_VEC_TRUNC },
9283 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_unpackh", ALTIVEC_BUILTIN_VEC_UNPACKH },
9284 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhsh", ALTIVEC_BUILTIN_VEC_VUPKHSH },
9285 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhpx", ALTIVEC_BUILTIN_VEC_VUPKHPX },
9286 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhsb", ALTIVEC_BUILTIN_VEC_VUPKHSB },
9287 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_unpackl", ALTIVEC_BUILTIN_VEC_UNPACKL },
9288 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklpx", ALTIVEC_BUILTIN_VEC_VUPKLPX },
9289 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsh", ALTIVEC_BUILTIN_VEC_VUPKLSH },
9290 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsb", ALTIVEC_BUILTIN_VEC_VUPKLSB },
9292 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_nearbyint", ALTIVEC_BUILTIN_VEC_NEARBYINT },
9293 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_rint", ALTIVEC_BUILTIN_VEC_RINT },
9294 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_sqrt", ALTIVEC_BUILTIN_VEC_SQRT },
9296 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_floatv4siv4sf2, "__builtin_vec_float_sisf", VECTOR_BUILTIN_FLOAT_V4SI_V4SF },
9297 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_unsigned_floatv4siv4sf2, "__builtin_vec_uns_float_sisf", VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF },
9298 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_fix_truncv4sfv4si2, "__builtin_vec_fix_sfsi", VECTOR_BUILTIN_FIX_V4SF_V4SI },
9299 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_fixuns_truncv4sfv4si2, "__builtin_vec_fixuns_sfsi", VECTOR_BUILTIN_FIXUNS_V4SF_V4SI },
9301 /* The SPE unary builtins must start with SPE_BUILTIN_EVABS and
9302 end with SPE_BUILTIN_EVSUBFUSIAAW. */
9303 { 0, CODE_FOR_spe_evabs, "__builtin_spe_evabs", SPE_BUILTIN_EVABS },
9304 { 0, CODE_FOR_spe_evaddsmiaaw, "__builtin_spe_evaddsmiaaw", SPE_BUILTIN_EVADDSMIAAW },
9305 { 0, CODE_FOR_spe_evaddssiaaw, "__builtin_spe_evaddssiaaw", SPE_BUILTIN_EVADDSSIAAW },
9306 { 0, CODE_FOR_spe_evaddumiaaw, "__builtin_spe_evaddumiaaw", SPE_BUILTIN_EVADDUMIAAW },
9307 { 0, CODE_FOR_spe_evaddusiaaw, "__builtin_spe_evaddusiaaw", SPE_BUILTIN_EVADDUSIAAW },
9308 { 0, CODE_FOR_spe_evcntlsw, "__builtin_spe_evcntlsw", SPE_BUILTIN_EVCNTLSW },
9309 { 0, CODE_FOR_spe_evcntlzw, "__builtin_spe_evcntlzw", SPE_BUILTIN_EVCNTLZW },
9310 { 0, CODE_FOR_spe_evextsb, "__builtin_spe_evextsb", SPE_BUILTIN_EVEXTSB },
9311 { 0, CODE_FOR_spe_evextsh, "__builtin_spe_evextsh", SPE_BUILTIN_EVEXTSH },
9312 { 0, CODE_FOR_spe_evfsabs, "__builtin_spe_evfsabs", SPE_BUILTIN_EVFSABS },
9313 { 0, CODE_FOR_spe_evfscfsf, "__builtin_spe_evfscfsf", SPE_BUILTIN_EVFSCFSF },
9314 { 0, CODE_FOR_spe_evfscfsi, "__builtin_spe_evfscfsi", SPE_BUILTIN_EVFSCFSI },
9315 { 0, CODE_FOR_spe_evfscfuf, "__builtin_spe_evfscfuf", SPE_BUILTIN_EVFSCFUF },
9316 { 0, CODE_FOR_spe_evfscfui, "__builtin_spe_evfscfui", SPE_BUILTIN_EVFSCFUI },
9317 { 0, CODE_FOR_spe_evfsctsf, "__builtin_spe_evfsctsf", SPE_BUILTIN_EVFSCTSF },
9318 { 0, CODE_FOR_spe_evfsctsi, "__builtin_spe_evfsctsi", SPE_BUILTIN_EVFSCTSI },
9319 { 0, CODE_FOR_spe_evfsctsiz, "__builtin_spe_evfsctsiz", SPE_BUILTIN_EVFSCTSIZ },
9320 { 0, CODE_FOR_spe_evfsctuf, "__builtin_spe_evfsctuf", SPE_BUILTIN_EVFSCTUF },
9321 { 0, CODE_FOR_spe_evfsctui, "__builtin_spe_evfsctui", SPE_BUILTIN_EVFSCTUI },
9322 { 0, CODE_FOR_spe_evfsctuiz, "__builtin_spe_evfsctuiz", SPE_BUILTIN_EVFSCTUIZ },
9323 { 0, CODE_FOR_spe_evfsnabs, "__builtin_spe_evfsnabs", SPE_BUILTIN_EVFSNABS },
9324 { 0, CODE_FOR_spe_evfsneg, "__builtin_spe_evfsneg", SPE_BUILTIN_EVFSNEG },
9325 { 0, CODE_FOR_spe_evmra, "__builtin_spe_evmra", SPE_BUILTIN_EVMRA },
9326 { 0, CODE_FOR_negv2si2, "__builtin_spe_evneg", SPE_BUILTIN_EVNEG },
9327 { 0, CODE_FOR_spe_evrndw, "__builtin_spe_evrndw", SPE_BUILTIN_EVRNDW },
9328 { 0, CODE_FOR_spe_evsubfsmiaaw, "__builtin_spe_evsubfsmiaaw", SPE_BUILTIN_EVSUBFSMIAAW },
9329 { 0, CODE_FOR_spe_evsubfssiaaw, "__builtin_spe_evsubfssiaaw", SPE_BUILTIN_EVSUBFSSIAAW },
9330 { 0, CODE_FOR_spe_evsubfumiaaw, "__builtin_spe_evsubfumiaaw", SPE_BUILTIN_EVSUBFUMIAAW },
9332 /* Place-holder. Leave as last unary SPE builtin. */
9333 { 0, CODE_FOR_spe_evsubfusiaaw, "__builtin_spe_evsubfusiaaw", SPE_BUILTIN_EVSUBFUSIAAW },
9335 { 0, CODE_FOR_absv2sf2, "__builtin_paired_absv2sf2", PAIRED_BUILTIN_ABSV2SF2 },
9336 { 0, CODE_FOR_nabsv2sf2, "__builtin_paired_nabsv2sf2", PAIRED_BUILTIN_NABSV2SF2 },
9337 { 0, CODE_FOR_negv2sf2, "__builtin_paired_negv2sf2", PAIRED_BUILTIN_NEGV2SF2 },
9338 { 0, CODE_FOR_sqrtv2sf2, "__builtin_paired_sqrtv2sf2", PAIRED_BUILTIN_SQRTV2SF2 },
9339 { 0, CODE_FOR_resv2sf2, "__builtin_paired_resv2sf2", PAIRED_BUILTIN_RESV2SF2 }
9342 static rtx
9343 rs6000_expand_unop_builtin (enum insn_code icode, tree exp, rtx target)
9345 rtx pat;
9346 tree arg0 = CALL_EXPR_ARG (exp, 0);
9347 rtx op0 = expand_normal (arg0);
9348 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9349 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
9351 if (icode == CODE_FOR_nothing)
9352 /* Builtin not supported on this processor. */
9353 return 0;
9355 /* If we got invalid arguments bail out before generating bad rtl. */
9356 if (arg0 == error_mark_node)
9357 return const0_rtx;
9359 if (icode == CODE_FOR_altivec_vspltisb
9360 || icode == CODE_FOR_altivec_vspltish
9361 || icode == CODE_FOR_altivec_vspltisw
9362 || icode == CODE_FOR_spe_evsplatfi
9363 || icode == CODE_FOR_spe_evsplati)
9365 /* Only allow 5-bit *signed* literals. */
9366 if (GET_CODE (op0) != CONST_INT
9367 || INTVAL (op0) > 15
9368 || INTVAL (op0) < -16)
9370 error ("argument 1 must be a 5-bit signed literal");
9371 return const0_rtx;
9375 if (target == 0
9376 || GET_MODE (target) != tmode
9377 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
9378 target = gen_reg_rtx (tmode);
9380 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
9381 op0 = copy_to_mode_reg (mode0, op0);
9383 pat = GEN_FCN (icode) (target, op0);
9384 if (! pat)
9385 return 0;
9386 emit_insn (pat);
9388 return target;
9391 static rtx
9392 altivec_expand_abs_builtin (enum insn_code icode, tree exp, rtx target)
9394 rtx pat, scratch1, scratch2;
9395 tree arg0 = CALL_EXPR_ARG (exp, 0);
9396 rtx op0 = expand_normal (arg0);
9397 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9398 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
9400 /* If we have invalid arguments, bail out before generating bad rtl. */
9401 if (arg0 == error_mark_node)
9402 return const0_rtx;
9404 if (target == 0
9405 || GET_MODE (target) != tmode
9406 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
9407 target = gen_reg_rtx (tmode);
9409 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
9410 op0 = copy_to_mode_reg (mode0, op0);
9412 scratch1 = gen_reg_rtx (mode0);
9413 scratch2 = gen_reg_rtx (mode0);
9415 pat = GEN_FCN (icode) (target, op0, scratch1, scratch2);
9416 if (! pat)
9417 return 0;
9418 emit_insn (pat);
9420 return target;
9423 static rtx
9424 rs6000_expand_binop_builtin (enum insn_code icode, tree exp, rtx target)
9426 rtx pat;
9427 tree arg0 = CALL_EXPR_ARG (exp, 0);
9428 tree arg1 = CALL_EXPR_ARG (exp, 1);
9429 rtx op0 = expand_normal (arg0);
9430 rtx op1 = expand_normal (arg1);
9431 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9432 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
9433 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
9435 if (icode == CODE_FOR_nothing)
9436 /* Builtin not supported on this processor. */
9437 return 0;
9439 /* If we got invalid arguments bail out before generating bad rtl. */
9440 if (arg0 == error_mark_node || arg1 == error_mark_node)
9441 return const0_rtx;
9443 if (icode == CODE_FOR_altivec_vcfux
9444 || icode == CODE_FOR_altivec_vcfsx
9445 || icode == CODE_FOR_altivec_vctsxs
9446 || icode == CODE_FOR_altivec_vctuxs
9447 || icode == CODE_FOR_altivec_vspltb
9448 || icode == CODE_FOR_altivec_vsplth
9449 || icode == CODE_FOR_altivec_vspltw
9450 || icode == CODE_FOR_spe_evaddiw
9451 || icode == CODE_FOR_spe_evldd
9452 || icode == CODE_FOR_spe_evldh
9453 || icode == CODE_FOR_spe_evldw
9454 || icode == CODE_FOR_spe_evlhhesplat
9455 || icode == CODE_FOR_spe_evlhhossplat
9456 || icode == CODE_FOR_spe_evlhhousplat
9457 || icode == CODE_FOR_spe_evlwhe
9458 || icode == CODE_FOR_spe_evlwhos
9459 || icode == CODE_FOR_spe_evlwhou
9460 || icode == CODE_FOR_spe_evlwhsplat
9461 || icode == CODE_FOR_spe_evlwwsplat
9462 || icode == CODE_FOR_spe_evrlwi
9463 || icode == CODE_FOR_spe_evslwi
9464 || icode == CODE_FOR_spe_evsrwis
9465 || icode == CODE_FOR_spe_evsubifw
9466 || icode == CODE_FOR_spe_evsrwiu)
9468 /* Only allow 5-bit unsigned literals. */
9469 STRIP_NOPS (arg1);
9470 if (TREE_CODE (arg1) != INTEGER_CST
9471 || TREE_INT_CST_LOW (arg1) & ~0x1f)
9473 error ("argument 2 must be a 5-bit unsigned literal");
9474 return const0_rtx;
9478 if (target == 0
9479 || GET_MODE (target) != tmode
9480 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
9481 target = gen_reg_rtx (tmode);
9483 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
9484 op0 = copy_to_mode_reg (mode0, op0);
9485 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
9486 op1 = copy_to_mode_reg (mode1, op1);
9488 pat = GEN_FCN (icode) (target, op0, op1);
9489 if (! pat)
9490 return 0;
9491 emit_insn (pat);
9493 return target;
9496 static rtx
9497 altivec_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
9499 rtx pat, scratch;
9500 tree cr6_form = CALL_EXPR_ARG (exp, 0);
9501 tree arg0 = CALL_EXPR_ARG (exp, 1);
9502 tree arg1 = CALL_EXPR_ARG (exp, 2);
9503 rtx op0 = expand_normal (arg0);
9504 rtx op1 = expand_normal (arg1);
9505 enum machine_mode tmode = SImode;
9506 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
9507 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
9508 int cr6_form_int;
9510 if (TREE_CODE (cr6_form) != INTEGER_CST)
9512 error ("argument 1 of __builtin_altivec_predicate must be a constant");
9513 return const0_rtx;
9515 else
9516 cr6_form_int = TREE_INT_CST_LOW (cr6_form);
9518 gcc_assert (mode0 == mode1);
9520 /* If we have invalid arguments, bail out before generating bad rtl. */
9521 if (arg0 == error_mark_node || arg1 == error_mark_node)
9522 return const0_rtx;
9524 if (target == 0
9525 || GET_MODE (target) != tmode
9526 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
9527 target = gen_reg_rtx (tmode);
9529 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
9530 op0 = copy_to_mode_reg (mode0, op0);
9531 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
9532 op1 = copy_to_mode_reg (mode1, op1);
9534 scratch = gen_reg_rtx (mode0);
9536 pat = GEN_FCN (icode) (scratch, op0, op1);
9537 if (! pat)
9538 return 0;
9539 emit_insn (pat);
9541 /* The vec_any* and vec_all* predicates use the same opcodes for two
9542 different operations, but the bits in CR6 will be different
9543 depending on what information we want. So we have to play tricks
9544 with CR6 to get the right bits out.
9546 If you think this is disgusting, look at the specs for the
9547 AltiVec predicates. */
9549 switch (cr6_form_int)
9551 case 0:
9552 emit_insn (gen_cr6_test_for_zero (target));
9553 break;
9554 case 1:
9555 emit_insn (gen_cr6_test_for_zero_reverse (target));
9556 break;
9557 case 2:
9558 emit_insn (gen_cr6_test_for_lt (target));
9559 break;
9560 case 3:
9561 emit_insn (gen_cr6_test_for_lt_reverse (target));
9562 break;
9563 default:
9564 error ("argument 1 of __builtin_altivec_predicate is out of range");
9565 break;
9568 return target;
9571 static rtx
9572 paired_expand_lv_builtin (enum insn_code icode, tree exp, rtx target)
9574 rtx pat, addr;
9575 tree arg0 = CALL_EXPR_ARG (exp, 0);
9576 tree arg1 = CALL_EXPR_ARG (exp, 1);
9577 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9578 enum machine_mode mode0 = Pmode;
9579 enum machine_mode mode1 = Pmode;
9580 rtx op0 = expand_normal (arg0);
9581 rtx op1 = expand_normal (arg1);
9583 if (icode == CODE_FOR_nothing)
9584 /* Builtin not supported on this processor. */
9585 return 0;
9587 /* If we got invalid arguments bail out before generating bad rtl. */
9588 if (arg0 == error_mark_node || arg1 == error_mark_node)
9589 return const0_rtx;
9591 if (target == 0
9592 || GET_MODE (target) != tmode
9593 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
9594 target = gen_reg_rtx (tmode);
9596 op1 = copy_to_mode_reg (mode1, op1);
9598 if (op0 == const0_rtx)
9600 addr = gen_rtx_MEM (tmode, op1);
9602 else
9604 op0 = copy_to_mode_reg (mode0, op0);
9605 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op0, op1));
9608 pat = GEN_FCN (icode) (target, addr);
9610 if (! pat)
9611 return 0;
9612 emit_insn (pat);
9614 return target;
9617 static rtx
9618 altivec_expand_lv_builtin (enum insn_code icode, tree exp, rtx target, bool blk)
9620 rtx pat, addr;
9621 tree arg0 = CALL_EXPR_ARG (exp, 0);
9622 tree arg1 = CALL_EXPR_ARG (exp, 1);
9623 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9624 enum machine_mode mode0 = Pmode;
9625 enum machine_mode mode1 = Pmode;
9626 rtx op0 = expand_normal (arg0);
9627 rtx op1 = expand_normal (arg1);
9629 if (icode == CODE_FOR_nothing)
9630 /* Builtin not supported on this processor. */
9631 return 0;
9633 /* If we got invalid arguments bail out before generating bad rtl. */
9634 if (arg0 == error_mark_node || arg1 == error_mark_node)
9635 return const0_rtx;
9637 if (target == 0
9638 || GET_MODE (target) != tmode
9639 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
9640 target = gen_reg_rtx (tmode);
9642 op1 = copy_to_mode_reg (mode1, op1);
9644 if (op0 == const0_rtx)
9646 addr = gen_rtx_MEM (blk ? BLKmode : tmode, op1);
9648 else
9650 op0 = copy_to_mode_reg (mode0, op0);
9651 addr = gen_rtx_MEM (blk ? BLKmode : tmode, gen_rtx_PLUS (Pmode, op0, op1));
9654 pat = GEN_FCN (icode) (target, addr);
9656 if (! pat)
9657 return 0;
9658 emit_insn (pat);
9660 return target;
9663 static rtx
9664 spe_expand_stv_builtin (enum insn_code icode, tree exp)
9666 tree arg0 = CALL_EXPR_ARG (exp, 0);
9667 tree arg1 = CALL_EXPR_ARG (exp, 1);
9668 tree arg2 = CALL_EXPR_ARG (exp, 2);
9669 rtx op0 = expand_normal (arg0);
9670 rtx op1 = expand_normal (arg1);
9671 rtx op2 = expand_normal (arg2);
9672 rtx pat;
9673 enum machine_mode mode0 = insn_data[icode].operand[0].mode;
9674 enum machine_mode mode1 = insn_data[icode].operand[1].mode;
9675 enum machine_mode mode2 = insn_data[icode].operand[2].mode;
9677 /* Invalid arguments. Bail before doing anything stoopid! */
9678 if (arg0 == error_mark_node
9679 || arg1 == error_mark_node
9680 || arg2 == error_mark_node)
9681 return const0_rtx;
9683 if (! (*insn_data[icode].operand[2].predicate) (op0, mode2))
9684 op0 = copy_to_mode_reg (mode2, op0);
9685 if (! (*insn_data[icode].operand[0].predicate) (op1, mode0))
9686 op1 = copy_to_mode_reg (mode0, op1);
9687 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
9688 op2 = copy_to_mode_reg (mode1, op2);
9690 pat = GEN_FCN (icode) (op1, op2, op0);
9691 if (pat)
9692 emit_insn (pat);
9693 return NULL_RTX;
9696 static rtx
9697 paired_expand_stv_builtin (enum insn_code icode, tree exp)
9699 tree arg0 = CALL_EXPR_ARG (exp, 0);
9700 tree arg1 = CALL_EXPR_ARG (exp, 1);
9701 tree arg2 = CALL_EXPR_ARG (exp, 2);
9702 rtx op0 = expand_normal (arg0);
9703 rtx op1 = expand_normal (arg1);
9704 rtx op2 = expand_normal (arg2);
9705 rtx pat, addr;
9706 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9707 enum machine_mode mode1 = Pmode;
9708 enum machine_mode mode2 = Pmode;
9710 /* Invalid arguments. Bail before doing anything stoopid! */
9711 if (arg0 == error_mark_node
9712 || arg1 == error_mark_node
9713 || arg2 == error_mark_node)
9714 return const0_rtx;
9716 if (! (*insn_data[icode].operand[1].predicate) (op0, tmode))
9717 op0 = copy_to_mode_reg (tmode, op0);
9719 op2 = copy_to_mode_reg (mode2, op2);
9721 if (op1 == const0_rtx)
9723 addr = gen_rtx_MEM (tmode, op2);
9725 else
9727 op1 = copy_to_mode_reg (mode1, op1);
9728 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op1, op2));
9731 pat = GEN_FCN (icode) (addr, op0);
9732 if (pat)
9733 emit_insn (pat);
9734 return NULL_RTX;
9737 static rtx
9738 altivec_expand_stv_builtin (enum insn_code icode, tree exp)
9740 tree arg0 = CALL_EXPR_ARG (exp, 0);
9741 tree arg1 = CALL_EXPR_ARG (exp, 1);
9742 tree arg2 = CALL_EXPR_ARG (exp, 2);
9743 rtx op0 = expand_normal (arg0);
9744 rtx op1 = expand_normal (arg1);
9745 rtx op2 = expand_normal (arg2);
9746 rtx pat, addr;
9747 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9748 enum machine_mode mode1 = Pmode;
9749 enum machine_mode mode2 = Pmode;
9751 /* Invalid arguments. Bail before doing anything stoopid! */
9752 if (arg0 == error_mark_node
9753 || arg1 == error_mark_node
9754 || arg2 == error_mark_node)
9755 return const0_rtx;
9757 if (! (*insn_data[icode].operand[1].predicate) (op0, tmode))
9758 op0 = copy_to_mode_reg (tmode, op0);
9760 op2 = copy_to_mode_reg (mode2, op2);
9762 if (op1 == const0_rtx)
9764 addr = gen_rtx_MEM (tmode, op2);
9766 else
9768 op1 = copy_to_mode_reg (mode1, op1);
9769 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op1, op2));
9772 pat = GEN_FCN (icode) (addr, op0);
9773 if (pat)
9774 emit_insn (pat);
9775 return NULL_RTX;
9778 static rtx
9779 rs6000_expand_ternop_builtin (enum insn_code icode, tree exp, rtx target)
9781 rtx pat;
9782 tree arg0 = CALL_EXPR_ARG (exp, 0);
9783 tree arg1 = CALL_EXPR_ARG (exp, 1);
9784 tree arg2 = CALL_EXPR_ARG (exp, 2);
9785 rtx op0 = expand_normal (arg0);
9786 rtx op1 = expand_normal (arg1);
9787 rtx op2 = expand_normal (arg2);
9788 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9789 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
9790 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
9791 enum machine_mode mode2 = insn_data[icode].operand[3].mode;
9793 if (icode == CODE_FOR_nothing)
9794 /* Builtin not supported on this processor. */
9795 return 0;
9797 /* If we got invalid arguments bail out before generating bad rtl. */
9798 if (arg0 == error_mark_node
9799 || arg1 == error_mark_node
9800 || arg2 == error_mark_node)
9801 return const0_rtx;
9803 switch (icode)
9805 case CODE_FOR_altivec_vsldoi_v4sf:
9806 case CODE_FOR_altivec_vsldoi_v4si:
9807 case CODE_FOR_altivec_vsldoi_v8hi:
9808 case CODE_FOR_altivec_vsldoi_v16qi:
9809 /* Only allow 4-bit unsigned literals. */
9810 STRIP_NOPS (arg2);
9811 if (TREE_CODE (arg2) != INTEGER_CST
9812 || TREE_INT_CST_LOW (arg2) & ~0xf)
9814 error ("argument 3 must be a 4-bit unsigned literal");
9815 return const0_rtx;
9817 break;
9819 case CODE_FOR_vsx_xxpermdi_v2df:
9820 case CODE_FOR_vsx_xxpermdi_v2di:
9821 case CODE_FOR_vsx_xxsldwi_v16qi:
9822 case CODE_FOR_vsx_xxsldwi_v8hi:
9823 case CODE_FOR_vsx_xxsldwi_v4si:
9824 case CODE_FOR_vsx_xxsldwi_v4sf:
9825 case CODE_FOR_vsx_xxsldwi_v2di:
9826 case CODE_FOR_vsx_xxsldwi_v2df:
9827 /* Only allow 2-bit unsigned literals. */
9828 STRIP_NOPS (arg2);
9829 if (TREE_CODE (arg2) != INTEGER_CST
9830 || TREE_INT_CST_LOW (arg2) & ~0x3)
9832 error ("argument 3 must be a 2-bit unsigned literal");
9833 return const0_rtx;
9835 break;
9837 case CODE_FOR_vsx_set_v2df:
9838 case CODE_FOR_vsx_set_v2di:
9839 /* Only allow 1-bit unsigned literals. */
9840 STRIP_NOPS (arg2);
9841 if (TREE_CODE (arg2) != INTEGER_CST
9842 || TREE_INT_CST_LOW (arg2) & ~0x1)
9844 error ("argument 3 must be a 1-bit unsigned literal");
9845 return const0_rtx;
9847 break;
9849 default:
9850 break;
9853 if (target == 0
9854 || GET_MODE (target) != tmode
9855 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
9856 target = gen_reg_rtx (tmode);
9858 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
9859 op0 = copy_to_mode_reg (mode0, op0);
9860 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
9861 op1 = copy_to_mode_reg (mode1, op1);
9862 if (! (*insn_data[icode].operand[3].predicate) (op2, mode2))
9863 op2 = copy_to_mode_reg (mode2, op2);
9865 if (TARGET_PAIRED_FLOAT && icode == CODE_FOR_selv2sf4)
9866 pat = GEN_FCN (icode) (target, op0, op1, op2, CONST0_RTX (SFmode));
9867 else
9868 pat = GEN_FCN (icode) (target, op0, op1, op2);
9869 if (! pat)
9870 return 0;
9871 emit_insn (pat);
9873 return target;
9876 /* Expand the lvx builtins. */
9877 static rtx
9878 altivec_expand_ld_builtin (tree exp, rtx target, bool *expandedp)
9880 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
9881 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
9882 tree arg0;
9883 enum machine_mode tmode, mode0;
9884 rtx pat, op0;
9885 enum insn_code icode;
9887 switch (fcode)
9889 case ALTIVEC_BUILTIN_LD_INTERNAL_16qi:
9890 icode = CODE_FOR_vector_load_v16qi;
9891 break;
9892 case ALTIVEC_BUILTIN_LD_INTERNAL_8hi:
9893 icode = CODE_FOR_vector_load_v8hi;
9894 break;
9895 case ALTIVEC_BUILTIN_LD_INTERNAL_4si:
9896 icode = CODE_FOR_vector_load_v4si;
9897 break;
9898 case ALTIVEC_BUILTIN_LD_INTERNAL_4sf:
9899 icode = CODE_FOR_vector_load_v4sf;
9900 break;
9901 default:
9902 *expandedp = false;
9903 return NULL_RTX;
9906 *expandedp = true;
9908 arg0 = CALL_EXPR_ARG (exp, 0);
9909 op0 = expand_normal (arg0);
9910 tmode = insn_data[icode].operand[0].mode;
9911 mode0 = insn_data[icode].operand[1].mode;
9913 if (target == 0
9914 || GET_MODE (target) != tmode
9915 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
9916 target = gen_reg_rtx (tmode);
9918 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
9919 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
9921 pat = GEN_FCN (icode) (target, op0);
9922 if (! pat)
9923 return 0;
9924 emit_insn (pat);
9925 return target;
9928 /* Expand the stvx builtins. */
9929 static rtx
9930 altivec_expand_st_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
9931 bool *expandedp)
9933 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
9934 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
9935 tree arg0, arg1;
9936 enum machine_mode mode0, mode1;
9937 rtx pat, op0, op1;
9938 enum insn_code icode;
9940 switch (fcode)
9942 case ALTIVEC_BUILTIN_ST_INTERNAL_16qi:
9943 icode = CODE_FOR_vector_store_v16qi;
9944 break;
9945 case ALTIVEC_BUILTIN_ST_INTERNAL_8hi:
9946 icode = CODE_FOR_vector_store_v8hi;
9947 break;
9948 case ALTIVEC_BUILTIN_ST_INTERNAL_4si:
9949 icode = CODE_FOR_vector_store_v4si;
9950 break;
9951 case ALTIVEC_BUILTIN_ST_INTERNAL_4sf:
9952 icode = CODE_FOR_vector_store_v4sf;
9953 break;
9954 default:
9955 *expandedp = false;
9956 return NULL_RTX;
9959 arg0 = CALL_EXPR_ARG (exp, 0);
9960 arg1 = CALL_EXPR_ARG (exp, 1);
9961 op0 = expand_normal (arg0);
9962 op1 = expand_normal (arg1);
9963 mode0 = insn_data[icode].operand[0].mode;
9964 mode1 = insn_data[icode].operand[1].mode;
9966 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
9967 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
9968 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
9969 op1 = copy_to_mode_reg (mode1, op1);
9971 pat = GEN_FCN (icode) (op0, op1);
9972 if (pat)
9973 emit_insn (pat);
9975 *expandedp = true;
9976 return NULL_RTX;
9979 /* Expand the dst builtins. */
9980 static rtx
9981 altivec_expand_dst_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
9982 bool *expandedp)
9984 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
9985 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
9986 tree arg0, arg1, arg2;
9987 enum machine_mode mode0, mode1, mode2;
9988 rtx pat, op0, op1, op2;
9989 const struct builtin_description *d;
9990 size_t i;
9992 *expandedp = false;
9994 /* Handle DST variants. */
9995 d = bdesc_dst;
9996 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
9997 if (d->code == fcode)
9999 arg0 = CALL_EXPR_ARG (exp, 0);
10000 arg1 = CALL_EXPR_ARG (exp, 1);
10001 arg2 = CALL_EXPR_ARG (exp, 2);
10002 op0 = expand_normal (arg0);
10003 op1 = expand_normal (arg1);
10004 op2 = expand_normal (arg2);
10005 mode0 = insn_data[d->icode].operand[0].mode;
10006 mode1 = insn_data[d->icode].operand[1].mode;
10007 mode2 = insn_data[d->icode].operand[2].mode;
10009 /* Invalid arguments, bail out before generating bad rtl. */
10010 if (arg0 == error_mark_node
10011 || arg1 == error_mark_node
10012 || arg2 == error_mark_node)
10013 return const0_rtx;
10015 *expandedp = true;
10016 STRIP_NOPS (arg2);
10017 if (TREE_CODE (arg2) != INTEGER_CST
10018 || TREE_INT_CST_LOW (arg2) & ~0x3)
10020 error ("argument to %qs must be a 2-bit unsigned literal", d->name);
10021 return const0_rtx;
10024 if (! (*insn_data[d->icode].operand[0].predicate) (op0, mode0))
10025 op0 = copy_to_mode_reg (Pmode, op0);
10026 if (! (*insn_data[d->icode].operand[1].predicate) (op1, mode1))
10027 op1 = copy_to_mode_reg (mode1, op1);
10029 pat = GEN_FCN (d->icode) (op0, op1, op2);
10030 if (pat != 0)
10031 emit_insn (pat);
10033 return NULL_RTX;
10036 return NULL_RTX;
10039 /* Expand vec_init builtin. */
10040 static rtx
10041 altivec_expand_vec_init_builtin (tree type, tree exp, rtx target)
10043 enum machine_mode tmode = TYPE_MODE (type);
10044 enum machine_mode inner_mode = GET_MODE_INNER (tmode);
10045 int i, n_elt = GET_MODE_NUNITS (tmode);
10046 rtvec v = rtvec_alloc (n_elt);
10048 gcc_assert (VECTOR_MODE_P (tmode));
10049 gcc_assert (n_elt == call_expr_nargs (exp));
10051 for (i = 0; i < n_elt; ++i)
10053 rtx x = expand_normal (CALL_EXPR_ARG (exp, i));
10054 RTVEC_ELT (v, i) = gen_lowpart (inner_mode, x);
10057 if (!target || !register_operand (target, tmode))
10058 target = gen_reg_rtx (tmode);
10060 rs6000_expand_vector_init (target, gen_rtx_PARALLEL (tmode, v));
10061 return target;
10064 /* Return the integer constant in ARG. Constrain it to be in the range
10065 of the subparts of VEC_TYPE; issue an error if not. */
10067 static int
10068 get_element_number (tree vec_type, tree arg)
10070 unsigned HOST_WIDE_INT elt, max = TYPE_VECTOR_SUBPARTS (vec_type) - 1;
10072 if (!host_integerp (arg, 1)
10073 || (elt = tree_low_cst (arg, 1), elt > max))
10075 error ("selector must be an integer constant in the range 0..%wi", max);
10076 return 0;
10079 return elt;
10082 /* Expand vec_set builtin. */
10083 static rtx
10084 altivec_expand_vec_set_builtin (tree exp)
10086 enum machine_mode tmode, mode1;
10087 tree arg0, arg1, arg2;
10088 int elt;
10089 rtx op0, op1;
10091 arg0 = CALL_EXPR_ARG (exp, 0);
10092 arg1 = CALL_EXPR_ARG (exp, 1);
10093 arg2 = CALL_EXPR_ARG (exp, 2);
10095 tmode = TYPE_MODE (TREE_TYPE (arg0));
10096 mode1 = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
10097 gcc_assert (VECTOR_MODE_P (tmode));
10099 op0 = expand_expr (arg0, NULL_RTX, tmode, EXPAND_NORMAL);
10100 op1 = expand_expr (arg1, NULL_RTX, mode1, EXPAND_NORMAL);
10101 elt = get_element_number (TREE_TYPE (arg0), arg2);
10103 if (GET_MODE (op1) != mode1 && GET_MODE (op1) != VOIDmode)
10104 op1 = convert_modes (mode1, GET_MODE (op1), op1, true);
10106 op0 = force_reg (tmode, op0);
10107 op1 = force_reg (mode1, op1);
10109 rs6000_expand_vector_set (op0, op1, elt);
10111 return op0;
10114 /* Expand vec_ext builtin. */
10115 static rtx
10116 altivec_expand_vec_ext_builtin (tree exp, rtx target)
10118 enum machine_mode tmode, mode0;
10119 tree arg0, arg1;
10120 int elt;
10121 rtx op0;
10123 arg0 = CALL_EXPR_ARG (exp, 0);
10124 arg1 = CALL_EXPR_ARG (exp, 1);
10126 op0 = expand_normal (arg0);
10127 elt = get_element_number (TREE_TYPE (arg0), arg1);
10129 tmode = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
10130 mode0 = TYPE_MODE (TREE_TYPE (arg0));
10131 gcc_assert (VECTOR_MODE_P (mode0));
10133 op0 = force_reg (mode0, op0);
10135 if (optimize || !target || !register_operand (target, tmode))
10136 target = gen_reg_rtx (tmode);
10138 rs6000_expand_vector_extract (target, op0, elt);
10140 return target;
10143 /* Expand the builtin in EXP and store the result in TARGET. Store
10144 true in *EXPANDEDP if we found a builtin to expand. */
10145 static rtx
10146 altivec_expand_builtin (tree exp, rtx target, bool *expandedp)
10148 const struct builtin_description *d;
10149 const struct builtin_description_predicates *dp;
10150 size_t i;
10151 enum insn_code icode;
10152 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10153 tree arg0;
10154 rtx op0, pat;
10155 enum machine_mode tmode, mode0;
10156 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10158 if ((fcode >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
10159 && fcode <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
10160 || (fcode >= VSX_BUILTIN_OVERLOADED_FIRST
10161 && fcode <= VSX_BUILTIN_OVERLOADED_LAST))
10163 *expandedp = true;
10164 error ("unresolved overload for Altivec builtin %qF", fndecl);
10165 return const0_rtx;
10168 target = altivec_expand_ld_builtin (exp, target, expandedp);
10169 if (*expandedp)
10170 return target;
10172 target = altivec_expand_st_builtin (exp, target, expandedp);
10173 if (*expandedp)
10174 return target;
10176 target = altivec_expand_dst_builtin (exp, target, expandedp);
10177 if (*expandedp)
10178 return target;
10180 *expandedp = true;
10182 switch (fcode)
10184 case ALTIVEC_BUILTIN_STVX:
10185 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx, exp);
10186 case ALTIVEC_BUILTIN_STVEBX:
10187 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvebx, exp);
10188 case ALTIVEC_BUILTIN_STVEHX:
10189 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvehx, exp);
10190 case ALTIVEC_BUILTIN_STVEWX:
10191 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvewx, exp);
10192 case ALTIVEC_BUILTIN_STVXL:
10193 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvxl, exp);
10195 case ALTIVEC_BUILTIN_STVLX:
10196 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlx, exp);
10197 case ALTIVEC_BUILTIN_STVLXL:
10198 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlxl, exp);
10199 case ALTIVEC_BUILTIN_STVRX:
10200 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrx, exp);
10201 case ALTIVEC_BUILTIN_STVRXL:
10202 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrxl, exp);
10204 case ALTIVEC_BUILTIN_MFVSCR:
10205 icode = CODE_FOR_altivec_mfvscr;
10206 tmode = insn_data[icode].operand[0].mode;
10208 if (target == 0
10209 || GET_MODE (target) != tmode
10210 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10211 target = gen_reg_rtx (tmode);
10213 pat = GEN_FCN (icode) (target);
10214 if (! pat)
10215 return 0;
10216 emit_insn (pat);
10217 return target;
10219 case ALTIVEC_BUILTIN_MTVSCR:
10220 icode = CODE_FOR_altivec_mtvscr;
10221 arg0 = CALL_EXPR_ARG (exp, 0);
10222 op0 = expand_normal (arg0);
10223 mode0 = insn_data[icode].operand[0].mode;
10225 /* If we got invalid arguments bail out before generating bad rtl. */
10226 if (arg0 == error_mark_node)
10227 return const0_rtx;
10229 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
10230 op0 = copy_to_mode_reg (mode0, op0);
10232 pat = GEN_FCN (icode) (op0);
10233 if (pat)
10234 emit_insn (pat);
10235 return NULL_RTX;
10237 case ALTIVEC_BUILTIN_DSSALL:
10238 emit_insn (gen_altivec_dssall ());
10239 return NULL_RTX;
10241 case ALTIVEC_BUILTIN_DSS:
10242 icode = CODE_FOR_altivec_dss;
10243 arg0 = CALL_EXPR_ARG (exp, 0);
10244 STRIP_NOPS (arg0);
10245 op0 = expand_normal (arg0);
10246 mode0 = insn_data[icode].operand[0].mode;
10248 /* If we got invalid arguments bail out before generating bad rtl. */
10249 if (arg0 == error_mark_node)
10250 return const0_rtx;
10252 if (TREE_CODE (arg0) != INTEGER_CST
10253 || TREE_INT_CST_LOW (arg0) & ~0x3)
10255 error ("argument to dss must be a 2-bit unsigned literal");
10256 return const0_rtx;
10259 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
10260 op0 = copy_to_mode_reg (mode0, op0);
10262 emit_insn (gen_altivec_dss (op0));
10263 return NULL_RTX;
10265 case ALTIVEC_BUILTIN_VEC_INIT_V4SI:
10266 case ALTIVEC_BUILTIN_VEC_INIT_V8HI:
10267 case ALTIVEC_BUILTIN_VEC_INIT_V16QI:
10268 case ALTIVEC_BUILTIN_VEC_INIT_V4SF:
10269 case VSX_BUILTIN_VEC_INIT_V2DF:
10270 case VSX_BUILTIN_VEC_INIT_V2DI:
10271 return altivec_expand_vec_init_builtin (TREE_TYPE (exp), exp, target);
10273 case ALTIVEC_BUILTIN_VEC_SET_V4SI:
10274 case ALTIVEC_BUILTIN_VEC_SET_V8HI:
10275 case ALTIVEC_BUILTIN_VEC_SET_V16QI:
10276 case ALTIVEC_BUILTIN_VEC_SET_V4SF:
10277 case VSX_BUILTIN_VEC_SET_V2DF:
10278 case VSX_BUILTIN_VEC_SET_V2DI:
10279 return altivec_expand_vec_set_builtin (exp);
10281 case ALTIVEC_BUILTIN_VEC_EXT_V4SI:
10282 case ALTIVEC_BUILTIN_VEC_EXT_V8HI:
10283 case ALTIVEC_BUILTIN_VEC_EXT_V16QI:
10284 case ALTIVEC_BUILTIN_VEC_EXT_V4SF:
10285 case VSX_BUILTIN_VEC_EXT_V2DF:
10286 case VSX_BUILTIN_VEC_EXT_V2DI:
10287 return altivec_expand_vec_ext_builtin (exp, target);
10289 default:
10290 break;
10291 /* Fall through. */
10294 /* Expand abs* operations. */
10295 d = bdesc_abs;
10296 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
10297 if (d->code == fcode)
10298 return altivec_expand_abs_builtin (d->icode, exp, target);
10300 /* Expand the AltiVec predicates. */
10301 dp = bdesc_altivec_preds;
10302 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
10303 if (dp->code == fcode)
10304 return altivec_expand_predicate_builtin (dp->icode, exp, target);
10306 /* LV* are funky. We initialized them differently. */
10307 switch (fcode)
10309 case ALTIVEC_BUILTIN_LVSL:
10310 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsl,
10311 exp, target, false);
10312 case ALTIVEC_BUILTIN_LVSR:
10313 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsr,
10314 exp, target, false);
10315 case ALTIVEC_BUILTIN_LVEBX:
10316 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvebx,
10317 exp, target, false);
10318 case ALTIVEC_BUILTIN_LVEHX:
10319 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvehx,
10320 exp, target, false);
10321 case ALTIVEC_BUILTIN_LVEWX:
10322 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvewx,
10323 exp, target, false);
10324 case ALTIVEC_BUILTIN_LVXL:
10325 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvxl,
10326 exp, target, false);
10327 case ALTIVEC_BUILTIN_LVX:
10328 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx,
10329 exp, target, false);
10330 case ALTIVEC_BUILTIN_LVLX:
10331 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlx,
10332 exp, target, true);
10333 case ALTIVEC_BUILTIN_LVLXL:
10334 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlxl,
10335 exp, target, true);
10336 case ALTIVEC_BUILTIN_LVRX:
10337 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrx,
10338 exp, target, true);
10339 case ALTIVEC_BUILTIN_LVRXL:
10340 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrxl,
10341 exp, target, true);
10342 default:
10343 break;
10344 /* Fall through. */
10347 *expandedp = false;
10348 return NULL_RTX;
10351 /* Expand the builtin in EXP and store the result in TARGET. Store
10352 true in *EXPANDEDP if we found a builtin to expand. */
10353 static rtx
10354 paired_expand_builtin (tree exp, rtx target, bool * expandedp)
10356 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10357 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10358 const struct builtin_description *d;
10359 size_t i;
10361 *expandedp = true;
10363 switch (fcode)
10365 case PAIRED_BUILTIN_STX:
10366 return paired_expand_stv_builtin (CODE_FOR_paired_stx, exp);
10367 case PAIRED_BUILTIN_LX:
10368 return paired_expand_lv_builtin (CODE_FOR_paired_lx, exp, target);
10369 default:
10370 break;
10371 /* Fall through. */
10374 /* Expand the paired predicates. */
10375 d = bdesc_paired_preds;
10376 for (i = 0; i < ARRAY_SIZE (bdesc_paired_preds); i++, d++)
10377 if (d->code == fcode)
10378 return paired_expand_predicate_builtin (d->icode, exp, target);
10380 *expandedp = false;
10381 return NULL_RTX;
10384 /* Binops that need to be initialized manually, but can be expanded
10385 automagically by rs6000_expand_binop_builtin. */
10386 static struct builtin_description bdesc_2arg_spe[] =
10388 { 0, CODE_FOR_spe_evlddx, "__builtin_spe_evlddx", SPE_BUILTIN_EVLDDX },
10389 { 0, CODE_FOR_spe_evldwx, "__builtin_spe_evldwx", SPE_BUILTIN_EVLDWX },
10390 { 0, CODE_FOR_spe_evldhx, "__builtin_spe_evldhx", SPE_BUILTIN_EVLDHX },
10391 { 0, CODE_FOR_spe_evlwhex, "__builtin_spe_evlwhex", SPE_BUILTIN_EVLWHEX },
10392 { 0, CODE_FOR_spe_evlwhoux, "__builtin_spe_evlwhoux", SPE_BUILTIN_EVLWHOUX },
10393 { 0, CODE_FOR_spe_evlwhosx, "__builtin_spe_evlwhosx", SPE_BUILTIN_EVLWHOSX },
10394 { 0, CODE_FOR_spe_evlwwsplatx, "__builtin_spe_evlwwsplatx", SPE_BUILTIN_EVLWWSPLATX },
10395 { 0, CODE_FOR_spe_evlwhsplatx, "__builtin_spe_evlwhsplatx", SPE_BUILTIN_EVLWHSPLATX },
10396 { 0, CODE_FOR_spe_evlhhesplatx, "__builtin_spe_evlhhesplatx", SPE_BUILTIN_EVLHHESPLATX },
10397 { 0, CODE_FOR_spe_evlhhousplatx, "__builtin_spe_evlhhousplatx", SPE_BUILTIN_EVLHHOUSPLATX },
10398 { 0, CODE_FOR_spe_evlhhossplatx, "__builtin_spe_evlhhossplatx", SPE_BUILTIN_EVLHHOSSPLATX },
10399 { 0, CODE_FOR_spe_evldd, "__builtin_spe_evldd", SPE_BUILTIN_EVLDD },
10400 { 0, CODE_FOR_spe_evldw, "__builtin_spe_evldw", SPE_BUILTIN_EVLDW },
10401 { 0, CODE_FOR_spe_evldh, "__builtin_spe_evldh", SPE_BUILTIN_EVLDH },
10402 { 0, CODE_FOR_spe_evlwhe, "__builtin_spe_evlwhe", SPE_BUILTIN_EVLWHE },
10403 { 0, CODE_FOR_spe_evlwhou, "__builtin_spe_evlwhou", SPE_BUILTIN_EVLWHOU },
10404 { 0, CODE_FOR_spe_evlwhos, "__builtin_spe_evlwhos", SPE_BUILTIN_EVLWHOS },
10405 { 0, CODE_FOR_spe_evlwwsplat, "__builtin_spe_evlwwsplat", SPE_BUILTIN_EVLWWSPLAT },
10406 { 0, CODE_FOR_spe_evlwhsplat, "__builtin_spe_evlwhsplat", SPE_BUILTIN_EVLWHSPLAT },
10407 { 0, CODE_FOR_spe_evlhhesplat, "__builtin_spe_evlhhesplat", SPE_BUILTIN_EVLHHESPLAT },
10408 { 0, CODE_FOR_spe_evlhhousplat, "__builtin_spe_evlhhousplat", SPE_BUILTIN_EVLHHOUSPLAT },
10409 { 0, CODE_FOR_spe_evlhhossplat, "__builtin_spe_evlhhossplat", SPE_BUILTIN_EVLHHOSSPLAT }
10412 /* Expand the builtin in EXP and store the result in TARGET. Store
10413 true in *EXPANDEDP if we found a builtin to expand.
10415 This expands the SPE builtins that are not simple unary and binary
10416 operations. */
10417 static rtx
10418 spe_expand_builtin (tree exp, rtx target, bool *expandedp)
10420 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10421 tree arg1, arg0;
10422 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10423 enum insn_code icode;
10424 enum machine_mode tmode, mode0;
10425 rtx pat, op0;
10426 struct builtin_description *d;
10427 size_t i;
10429 *expandedp = true;
10431 /* Syntax check for a 5-bit unsigned immediate. */
10432 switch (fcode)
10434 case SPE_BUILTIN_EVSTDD:
10435 case SPE_BUILTIN_EVSTDH:
10436 case SPE_BUILTIN_EVSTDW:
10437 case SPE_BUILTIN_EVSTWHE:
10438 case SPE_BUILTIN_EVSTWHO:
10439 case SPE_BUILTIN_EVSTWWE:
10440 case SPE_BUILTIN_EVSTWWO:
10441 arg1 = CALL_EXPR_ARG (exp, 2);
10442 if (TREE_CODE (arg1) != INTEGER_CST
10443 || TREE_INT_CST_LOW (arg1) & ~0x1f)
10445 error ("argument 2 must be a 5-bit unsigned literal");
10446 return const0_rtx;
10448 break;
10449 default:
10450 break;
10453 /* The evsplat*i instructions are not quite generic. */
10454 switch (fcode)
10456 case SPE_BUILTIN_EVSPLATFI:
10457 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplatfi,
10458 exp, target);
10459 case SPE_BUILTIN_EVSPLATI:
10460 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplati,
10461 exp, target);
10462 default:
10463 break;
10466 d = (struct builtin_description *) bdesc_2arg_spe;
10467 for (i = 0; i < ARRAY_SIZE (bdesc_2arg_spe); ++i, ++d)
10468 if (d->code == fcode)
10469 return rs6000_expand_binop_builtin (d->icode, exp, target);
10471 d = (struct builtin_description *) bdesc_spe_predicates;
10472 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, ++d)
10473 if (d->code == fcode)
10474 return spe_expand_predicate_builtin (d->icode, exp, target);
10476 d = (struct builtin_description *) bdesc_spe_evsel;
10477 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, ++d)
10478 if (d->code == fcode)
10479 return spe_expand_evsel_builtin (d->icode, exp, target);
10481 switch (fcode)
10483 case SPE_BUILTIN_EVSTDDX:
10484 return spe_expand_stv_builtin (CODE_FOR_spe_evstddx, exp);
10485 case SPE_BUILTIN_EVSTDHX:
10486 return spe_expand_stv_builtin (CODE_FOR_spe_evstdhx, exp);
10487 case SPE_BUILTIN_EVSTDWX:
10488 return spe_expand_stv_builtin (CODE_FOR_spe_evstdwx, exp);
10489 case SPE_BUILTIN_EVSTWHEX:
10490 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhex, exp);
10491 case SPE_BUILTIN_EVSTWHOX:
10492 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhox, exp);
10493 case SPE_BUILTIN_EVSTWWEX:
10494 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwex, exp);
10495 case SPE_BUILTIN_EVSTWWOX:
10496 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwox, exp);
10497 case SPE_BUILTIN_EVSTDD:
10498 return spe_expand_stv_builtin (CODE_FOR_spe_evstdd, exp);
10499 case SPE_BUILTIN_EVSTDH:
10500 return spe_expand_stv_builtin (CODE_FOR_spe_evstdh, exp);
10501 case SPE_BUILTIN_EVSTDW:
10502 return spe_expand_stv_builtin (CODE_FOR_spe_evstdw, exp);
10503 case SPE_BUILTIN_EVSTWHE:
10504 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhe, exp);
10505 case SPE_BUILTIN_EVSTWHO:
10506 return spe_expand_stv_builtin (CODE_FOR_spe_evstwho, exp);
10507 case SPE_BUILTIN_EVSTWWE:
10508 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwe, exp);
10509 case SPE_BUILTIN_EVSTWWO:
10510 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwo, exp);
10511 case SPE_BUILTIN_MFSPEFSCR:
10512 icode = CODE_FOR_spe_mfspefscr;
10513 tmode = insn_data[icode].operand[0].mode;
10515 if (target == 0
10516 || GET_MODE (target) != tmode
10517 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10518 target = gen_reg_rtx (tmode);
10520 pat = GEN_FCN (icode) (target);
10521 if (! pat)
10522 return 0;
10523 emit_insn (pat);
10524 return target;
10525 case SPE_BUILTIN_MTSPEFSCR:
10526 icode = CODE_FOR_spe_mtspefscr;
10527 arg0 = CALL_EXPR_ARG (exp, 0);
10528 op0 = expand_normal (arg0);
10529 mode0 = insn_data[icode].operand[0].mode;
10531 if (arg0 == error_mark_node)
10532 return const0_rtx;
10534 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
10535 op0 = copy_to_mode_reg (mode0, op0);
10537 pat = GEN_FCN (icode) (op0);
10538 if (pat)
10539 emit_insn (pat);
10540 return NULL_RTX;
10541 default:
10542 break;
10545 *expandedp = false;
10546 return NULL_RTX;
10549 static rtx
10550 paired_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
10552 rtx pat, scratch, tmp;
10553 tree form = CALL_EXPR_ARG (exp, 0);
10554 tree arg0 = CALL_EXPR_ARG (exp, 1);
10555 tree arg1 = CALL_EXPR_ARG (exp, 2);
10556 rtx op0 = expand_normal (arg0);
10557 rtx op1 = expand_normal (arg1);
10558 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10559 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
10560 int form_int;
10561 enum rtx_code code;
10563 if (TREE_CODE (form) != INTEGER_CST)
10565 error ("argument 1 of __builtin_paired_predicate must be a constant");
10566 return const0_rtx;
10568 else
10569 form_int = TREE_INT_CST_LOW (form);
10571 gcc_assert (mode0 == mode1);
10573 if (arg0 == error_mark_node || arg1 == error_mark_node)
10574 return const0_rtx;
10576 if (target == 0
10577 || GET_MODE (target) != SImode
10578 || !(*insn_data[icode].operand[0].predicate) (target, SImode))
10579 target = gen_reg_rtx (SImode);
10580 if (!(*insn_data[icode].operand[1].predicate) (op0, mode0))
10581 op0 = copy_to_mode_reg (mode0, op0);
10582 if (!(*insn_data[icode].operand[2].predicate) (op1, mode1))
10583 op1 = copy_to_mode_reg (mode1, op1);
10585 scratch = gen_reg_rtx (CCFPmode);
10587 pat = GEN_FCN (icode) (scratch, op0, op1);
10588 if (!pat)
10589 return const0_rtx;
10591 emit_insn (pat);
10593 switch (form_int)
10595 /* LT bit. */
10596 case 0:
10597 code = LT;
10598 break;
10599 /* GT bit. */
10600 case 1:
10601 code = GT;
10602 break;
10603 /* EQ bit. */
10604 case 2:
10605 code = EQ;
10606 break;
10607 /* UN bit. */
10608 case 3:
10609 emit_insn (gen_move_from_CR_ov_bit (target, scratch));
10610 return target;
10611 default:
10612 error ("argument 1 of __builtin_paired_predicate is out of range");
10613 return const0_rtx;
10616 tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx);
10617 emit_move_insn (target, tmp);
10618 return target;
10621 static rtx
10622 spe_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
10624 rtx pat, scratch, tmp;
10625 tree form = CALL_EXPR_ARG (exp, 0);
10626 tree arg0 = CALL_EXPR_ARG (exp, 1);
10627 tree arg1 = CALL_EXPR_ARG (exp, 2);
10628 rtx op0 = expand_normal (arg0);
10629 rtx op1 = expand_normal (arg1);
10630 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10631 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
10632 int form_int;
10633 enum rtx_code code;
10635 if (TREE_CODE (form) != INTEGER_CST)
10637 error ("argument 1 of __builtin_spe_predicate must be a constant");
10638 return const0_rtx;
10640 else
10641 form_int = TREE_INT_CST_LOW (form);
10643 gcc_assert (mode0 == mode1);
10645 if (arg0 == error_mark_node || arg1 == error_mark_node)
10646 return const0_rtx;
10648 if (target == 0
10649 || GET_MODE (target) != SImode
10650 || ! (*insn_data[icode].operand[0].predicate) (target, SImode))
10651 target = gen_reg_rtx (SImode);
10653 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10654 op0 = copy_to_mode_reg (mode0, op0);
10655 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
10656 op1 = copy_to_mode_reg (mode1, op1);
10658 scratch = gen_reg_rtx (CCmode);
10660 pat = GEN_FCN (icode) (scratch, op0, op1);
10661 if (! pat)
10662 return const0_rtx;
10663 emit_insn (pat);
10665 /* There are 4 variants for each predicate: _any_, _all_, _upper_,
10666 _lower_. We use one compare, but look in different bits of the
10667 CR for each variant.
10669 There are 2 elements in each SPE simd type (upper/lower). The CR
10670 bits are set as follows:
10672 BIT0 | BIT 1 | BIT 2 | BIT 3
10673 U | L | (U | L) | (U & L)
10675 So, for an "all" relationship, BIT 3 would be set.
10676 For an "any" relationship, BIT 2 would be set. Etc.
10678 Following traditional nomenclature, these bits map to:
10680 BIT0 | BIT 1 | BIT 2 | BIT 3
10681 LT | GT | EQ | OV
10683 Later, we will generate rtl to look in the LT/EQ/EQ/OV bits.
10686 switch (form_int)
10688 /* All variant. OV bit. */
10689 case 0:
10690 /* We need to get to the OV bit, which is the ORDERED bit. We
10691 could generate (ordered:SI (reg:CC xx) (const_int 0)), but
10692 that's ugly and will make validate_condition_mode die.
10693 So let's just use another pattern. */
10694 emit_insn (gen_move_from_CR_ov_bit (target, scratch));
10695 return target;
10696 /* Any variant. EQ bit. */
10697 case 1:
10698 code = EQ;
10699 break;
10700 /* Upper variant. LT bit. */
10701 case 2:
10702 code = LT;
10703 break;
10704 /* Lower variant. GT bit. */
10705 case 3:
10706 code = GT;
10707 break;
10708 default:
10709 error ("argument 1 of __builtin_spe_predicate is out of range");
10710 return const0_rtx;
10713 tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx);
10714 emit_move_insn (target, tmp);
10716 return target;
10719 /* The evsel builtins look like this:
10721 e = __builtin_spe_evsel_OP (a, b, c, d);
10723 and work like this:
10725 e[upper] = a[upper] *OP* b[upper] ? c[upper] : d[upper];
10726 e[lower] = a[lower] *OP* b[lower] ? c[lower] : d[lower];
10729 static rtx
10730 spe_expand_evsel_builtin (enum insn_code icode, tree exp, rtx target)
10732 rtx pat, scratch;
10733 tree arg0 = CALL_EXPR_ARG (exp, 0);
10734 tree arg1 = CALL_EXPR_ARG (exp, 1);
10735 tree arg2 = CALL_EXPR_ARG (exp, 2);
10736 tree arg3 = CALL_EXPR_ARG (exp, 3);
10737 rtx op0 = expand_normal (arg0);
10738 rtx op1 = expand_normal (arg1);
10739 rtx op2 = expand_normal (arg2);
10740 rtx op3 = expand_normal (arg3);
10741 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10742 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
10744 gcc_assert (mode0 == mode1);
10746 if (arg0 == error_mark_node || arg1 == error_mark_node
10747 || arg2 == error_mark_node || arg3 == error_mark_node)
10748 return const0_rtx;
10750 if (target == 0
10751 || GET_MODE (target) != mode0
10752 || ! (*insn_data[icode].operand[0].predicate) (target, mode0))
10753 target = gen_reg_rtx (mode0);
10755 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10756 op0 = copy_to_mode_reg (mode0, op0);
10757 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
10758 op1 = copy_to_mode_reg (mode0, op1);
10759 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
10760 op2 = copy_to_mode_reg (mode0, op2);
10761 if (! (*insn_data[icode].operand[1].predicate) (op3, mode1))
10762 op3 = copy_to_mode_reg (mode0, op3);
10764 /* Generate the compare. */
10765 scratch = gen_reg_rtx (CCmode);
10766 pat = GEN_FCN (icode) (scratch, op0, op1);
10767 if (! pat)
10768 return const0_rtx;
10769 emit_insn (pat);
10771 if (mode0 == V2SImode)
10772 emit_insn (gen_spe_evsel (target, op2, op3, scratch));
10773 else
10774 emit_insn (gen_spe_evsel_fs (target, op2, op3, scratch));
10776 return target;
10779 /* Expand an expression EXP that calls a built-in function,
10780 with result going to TARGET if that's convenient
10781 (and in mode MODE if that's convenient).
10782 SUBTARGET may be used as the target for computing one of EXP's operands.
10783 IGNORE is nonzero if the value is to be ignored. */
10785 static rtx
10786 rs6000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
10787 enum machine_mode mode ATTRIBUTE_UNUSED,
10788 int ignore ATTRIBUTE_UNUSED)
10790 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10791 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10792 const struct builtin_description *d;
10793 size_t i;
10794 rtx ret;
10795 bool success;
10797 if (fcode == RS6000_BUILTIN_RECIP)
10798 return rs6000_expand_binop_builtin (CODE_FOR_recipdf3, exp, target);
10800 if (fcode == RS6000_BUILTIN_RECIPF)
10801 return rs6000_expand_binop_builtin (CODE_FOR_recipsf3, exp, target);
10803 if (fcode == RS6000_BUILTIN_RSQRTF)
10804 return rs6000_expand_unop_builtin (CODE_FOR_rsqrtsf2, exp, target);
10806 if (fcode == RS6000_BUILTIN_BSWAP_HI)
10807 return rs6000_expand_unop_builtin (CODE_FOR_bswaphi2, exp, target);
10809 if (fcode == POWER7_BUILTIN_BPERMD)
10810 return rs6000_expand_binop_builtin (((TARGET_64BIT)
10811 ? CODE_FOR_bpermd_di
10812 : CODE_FOR_bpermd_si), exp, target);
10814 if (fcode == ALTIVEC_BUILTIN_MASK_FOR_LOAD
10815 || fcode == ALTIVEC_BUILTIN_MASK_FOR_STORE)
10817 int icode = (int) CODE_FOR_altivec_lvsr;
10818 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10819 enum machine_mode mode = insn_data[icode].operand[1].mode;
10820 tree arg;
10821 rtx op, addr, pat;
10823 gcc_assert (TARGET_ALTIVEC);
10825 arg = CALL_EXPR_ARG (exp, 0);
10826 gcc_assert (TREE_CODE (TREE_TYPE (arg)) == POINTER_TYPE);
10827 op = expand_expr (arg, NULL_RTX, Pmode, EXPAND_NORMAL);
10828 addr = memory_address (mode, op);
10829 if (fcode == ALTIVEC_BUILTIN_MASK_FOR_STORE)
10830 op = addr;
10831 else
10833 /* For the load case need to negate the address. */
10834 op = gen_reg_rtx (GET_MODE (addr));
10835 emit_insn (gen_rtx_SET (VOIDmode, op,
10836 gen_rtx_NEG (GET_MODE (addr), addr)));
10838 op = gen_rtx_MEM (mode, op);
10840 if (target == 0
10841 || GET_MODE (target) != tmode
10842 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10843 target = gen_reg_rtx (tmode);
10845 /*pat = gen_altivec_lvsr (target, op);*/
10846 pat = GEN_FCN (icode) (target, op);
10847 if (!pat)
10848 return 0;
10849 emit_insn (pat);
10851 return target;
10854 /* FIXME: There's got to be a nicer way to handle this case than
10855 constructing a new CALL_EXPR. */
10856 if (fcode == ALTIVEC_BUILTIN_VCFUX
10857 || fcode == ALTIVEC_BUILTIN_VCFSX
10858 || fcode == ALTIVEC_BUILTIN_VCTUXS
10859 || fcode == ALTIVEC_BUILTIN_VCTSXS)
10861 if (call_expr_nargs (exp) == 1)
10862 exp = build_call_nary (TREE_TYPE (exp), CALL_EXPR_FN (exp),
10863 2, CALL_EXPR_ARG (exp, 0), integer_zero_node);
10866 if (TARGET_ALTIVEC)
10868 ret = altivec_expand_builtin (exp, target, &success);
10870 if (success)
10871 return ret;
10873 if (TARGET_SPE)
10875 ret = spe_expand_builtin (exp, target, &success);
10877 if (success)
10878 return ret;
10880 if (TARGET_PAIRED_FLOAT)
10882 ret = paired_expand_builtin (exp, target, &success);
10884 if (success)
10885 return ret;
10888 gcc_assert (TARGET_ALTIVEC || TARGET_VSX || TARGET_SPE || TARGET_PAIRED_FLOAT);
10890 /* Handle simple unary operations. */
10891 d = (struct builtin_description *) bdesc_1arg;
10892 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
10893 if (d->code == fcode)
10894 return rs6000_expand_unop_builtin (d->icode, exp, target);
10896 /* Handle simple binary operations. */
10897 d = (struct builtin_description *) bdesc_2arg;
10898 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
10899 if (d->code == fcode)
10900 return rs6000_expand_binop_builtin (d->icode, exp, target);
10902 /* Handle simple ternary operations. */
10903 d = bdesc_3arg;
10904 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
10905 if (d->code == fcode)
10906 return rs6000_expand_ternop_builtin (d->icode, exp, target);
10908 gcc_unreachable ();
10911 static void
10912 rs6000_init_builtins (void)
10914 tree tdecl;
10916 V2SI_type_node = build_vector_type (intSI_type_node, 2);
10917 V2SF_type_node = build_vector_type (float_type_node, 2);
10918 V2DI_type_node = build_vector_type (intDI_type_node, 2);
10919 V2DF_type_node = build_vector_type (double_type_node, 2);
10920 V4HI_type_node = build_vector_type (intHI_type_node, 4);
10921 V4SI_type_node = build_vector_type (intSI_type_node, 4);
10922 V4SF_type_node = build_vector_type (float_type_node, 4);
10923 V8HI_type_node = build_vector_type (intHI_type_node, 8);
10924 V16QI_type_node = build_vector_type (intQI_type_node, 16);
10926 unsigned_V16QI_type_node = build_vector_type (unsigned_intQI_type_node, 16);
10927 unsigned_V8HI_type_node = build_vector_type (unsigned_intHI_type_node, 8);
10928 unsigned_V4SI_type_node = build_vector_type (unsigned_intSI_type_node, 4);
10929 unsigned_V2DI_type_node = build_vector_type (unsigned_intDI_type_node, 2);
10931 opaque_V2SF_type_node = build_opaque_vector_type (float_type_node, 2);
10932 opaque_V2SI_type_node = build_opaque_vector_type (intSI_type_node, 2);
10933 opaque_p_V2SI_type_node = build_pointer_type (opaque_V2SI_type_node);
10934 opaque_V4SI_type_node = build_opaque_vector_type (intSI_type_node, 4);
10936 /* The 'vector bool ...' types must be kept distinct from 'vector unsigned ...'
10937 types, especially in C++ land. Similarly, 'vector pixel' is distinct from
10938 'vector unsigned short'. */
10940 bool_char_type_node = build_distinct_type_copy (unsigned_intQI_type_node);
10941 bool_short_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
10942 bool_int_type_node = build_distinct_type_copy (unsigned_intSI_type_node);
10943 bool_long_type_node = build_distinct_type_copy (unsigned_intDI_type_node);
10944 pixel_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
10946 long_integer_type_internal_node = long_integer_type_node;
10947 long_unsigned_type_internal_node = long_unsigned_type_node;
10948 intQI_type_internal_node = intQI_type_node;
10949 uintQI_type_internal_node = unsigned_intQI_type_node;
10950 intHI_type_internal_node = intHI_type_node;
10951 uintHI_type_internal_node = unsigned_intHI_type_node;
10952 intSI_type_internal_node = intSI_type_node;
10953 uintSI_type_internal_node = unsigned_intSI_type_node;
10954 intDI_type_internal_node = intDI_type_node;
10955 uintDI_type_internal_node = unsigned_intDI_type_node;
10956 float_type_internal_node = float_type_node;
10957 double_type_internal_node = float_type_node;
10958 void_type_internal_node = void_type_node;
10960 /* Initialize the modes for builtin_function_type, mapping a machine mode to
10961 tree type node. */
10962 builtin_mode_to_type[QImode][0] = integer_type_node;
10963 builtin_mode_to_type[HImode][0] = integer_type_node;
10964 builtin_mode_to_type[SImode][0] = intSI_type_node;
10965 builtin_mode_to_type[SImode][1] = unsigned_intSI_type_node;
10966 builtin_mode_to_type[DImode][0] = intDI_type_node;
10967 builtin_mode_to_type[DImode][1] = unsigned_intDI_type_node;
10968 builtin_mode_to_type[SFmode][0] = float_type_node;
10969 builtin_mode_to_type[DFmode][0] = double_type_node;
10970 builtin_mode_to_type[V2SImode][0] = V2SI_type_node;
10971 builtin_mode_to_type[V2SFmode][0] = V2SF_type_node;
10972 builtin_mode_to_type[V2DImode][0] = V2DI_type_node;
10973 builtin_mode_to_type[V2DImode][1] = unsigned_V2DI_type_node;
10974 builtin_mode_to_type[V2DFmode][0] = V2DF_type_node;
10975 builtin_mode_to_type[V4HImode][0] = V4HI_type_node;
10976 builtin_mode_to_type[V4SImode][0] = V4SI_type_node;
10977 builtin_mode_to_type[V4SImode][1] = unsigned_V4SI_type_node;
10978 builtin_mode_to_type[V4SFmode][0] = V4SF_type_node;
10979 builtin_mode_to_type[V8HImode][0] = V8HI_type_node;
10980 builtin_mode_to_type[V8HImode][1] = unsigned_V8HI_type_node;
10981 builtin_mode_to_type[V16QImode][0] = V16QI_type_node;
10982 builtin_mode_to_type[V16QImode][1] = unsigned_V16QI_type_node;
10984 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
10985 get_identifier ("__bool char"),
10986 bool_char_type_node);
10987 TYPE_NAME (bool_char_type_node) = tdecl;
10988 (*lang_hooks.decls.pushdecl) (tdecl);
10989 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
10990 get_identifier ("__bool short"),
10991 bool_short_type_node);
10992 TYPE_NAME (bool_short_type_node) = tdecl;
10993 (*lang_hooks.decls.pushdecl) (tdecl);
10994 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
10995 get_identifier ("__bool int"),
10996 bool_int_type_node);
10997 TYPE_NAME (bool_int_type_node) = tdecl;
10998 (*lang_hooks.decls.pushdecl) (tdecl);
10999 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL, get_identifier ("__pixel"),
11000 pixel_type_node);
11001 TYPE_NAME (pixel_type_node) = tdecl;
11002 (*lang_hooks.decls.pushdecl) (tdecl);
11004 bool_V16QI_type_node = build_vector_type (bool_char_type_node, 16);
11005 bool_V8HI_type_node = build_vector_type (bool_short_type_node, 8);
11006 bool_V4SI_type_node = build_vector_type (bool_int_type_node, 4);
11007 bool_V2DI_type_node = build_vector_type (bool_long_type_node, 2);
11008 pixel_V8HI_type_node = build_vector_type (pixel_type_node, 8);
11010 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
11011 get_identifier ("__vector unsigned char"),
11012 unsigned_V16QI_type_node);
11013 TYPE_NAME (unsigned_V16QI_type_node) = tdecl;
11014 (*lang_hooks.decls.pushdecl) (tdecl);
11015 tdecl = build_decl (BUILTINS_LOCATION,
11016 TYPE_DECL, get_identifier ("__vector signed char"),
11017 V16QI_type_node);
11018 TYPE_NAME (V16QI_type_node) = tdecl;
11019 (*lang_hooks.decls.pushdecl) (tdecl);
11020 tdecl = build_decl (BUILTINS_LOCATION,
11021 TYPE_DECL, get_identifier ("__vector __bool char"),
11022 bool_V16QI_type_node);
11023 TYPE_NAME ( bool_V16QI_type_node) = tdecl;
11024 (*lang_hooks.decls.pushdecl) (tdecl);
11026 tdecl = build_decl (BUILTINS_LOCATION,
11027 TYPE_DECL, get_identifier ("__vector unsigned short"),
11028 unsigned_V8HI_type_node);
11029 TYPE_NAME (unsigned_V8HI_type_node) = tdecl;
11030 (*lang_hooks.decls.pushdecl) (tdecl);
11031 tdecl = build_decl (BUILTINS_LOCATION,
11032 TYPE_DECL, get_identifier ("__vector signed short"),
11033 V8HI_type_node);
11034 TYPE_NAME (V8HI_type_node) = tdecl;
11035 (*lang_hooks.decls.pushdecl) (tdecl);
11036 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
11037 get_identifier ("__vector __bool short"),
11038 bool_V8HI_type_node);
11039 TYPE_NAME (bool_V8HI_type_node) = tdecl;
11040 (*lang_hooks.decls.pushdecl) (tdecl);
11042 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
11043 get_identifier ("__vector unsigned int"),
11044 unsigned_V4SI_type_node);
11045 TYPE_NAME (unsigned_V4SI_type_node) = tdecl;
11046 (*lang_hooks.decls.pushdecl) (tdecl);
11047 tdecl = build_decl (BUILTINS_LOCATION,
11048 TYPE_DECL, get_identifier ("__vector signed int"),
11049 V4SI_type_node);
11050 TYPE_NAME (V4SI_type_node) = tdecl;
11051 (*lang_hooks.decls.pushdecl) (tdecl);
11052 tdecl = build_decl (BUILTINS_LOCATION,
11053 TYPE_DECL, get_identifier ("__vector __bool int"),
11054 bool_V4SI_type_node);
11055 TYPE_NAME (bool_V4SI_type_node) = tdecl;
11056 (*lang_hooks.decls.pushdecl) (tdecl);
11058 tdecl = build_decl (BUILTINS_LOCATION,
11059 TYPE_DECL, get_identifier ("__vector float"),
11060 V4SF_type_node);
11061 TYPE_NAME (V4SF_type_node) = tdecl;
11062 (*lang_hooks.decls.pushdecl) (tdecl);
11063 tdecl = build_decl (BUILTINS_LOCATION,
11064 TYPE_DECL, get_identifier ("__vector __pixel"),
11065 pixel_V8HI_type_node);
11066 TYPE_NAME (pixel_V8HI_type_node) = tdecl;
11067 (*lang_hooks.decls.pushdecl) (tdecl);
11069 if (TARGET_VSX)
11071 tdecl = build_decl (BUILTINS_LOCATION,
11072 TYPE_DECL, get_identifier ("__vector double"),
11073 V2DF_type_node);
11074 TYPE_NAME (V2DF_type_node) = tdecl;
11075 (*lang_hooks.decls.pushdecl) (tdecl);
11077 tdecl = build_decl (BUILTINS_LOCATION,
11078 TYPE_DECL, get_identifier ("__vector long"),
11079 V2DI_type_node);
11080 TYPE_NAME (V2DI_type_node) = tdecl;
11081 (*lang_hooks.decls.pushdecl) (tdecl);
11083 tdecl = build_decl (BUILTINS_LOCATION,
11084 TYPE_DECL, get_identifier ("__vector unsigned long"),
11085 unsigned_V2DI_type_node);
11086 TYPE_NAME (unsigned_V2DI_type_node) = tdecl;
11087 (*lang_hooks.decls.pushdecl) (tdecl);
11089 tdecl = build_decl (BUILTINS_LOCATION,
11090 TYPE_DECL, get_identifier ("__vector __bool long"),
11091 bool_V2DI_type_node);
11092 TYPE_NAME (bool_V2DI_type_node) = tdecl;
11093 (*lang_hooks.decls.pushdecl) (tdecl);
11096 if (TARGET_PAIRED_FLOAT)
11097 paired_init_builtins ();
11098 if (TARGET_SPE)
11099 spe_init_builtins ();
11100 if (TARGET_ALTIVEC)
11101 altivec_init_builtins ();
11102 if (TARGET_ALTIVEC || TARGET_SPE || TARGET_PAIRED_FLOAT || TARGET_VSX)
11103 rs6000_common_init_builtins ();
11104 if (TARGET_PPC_GFXOPT)
11106 tree ftype = builtin_function_type (SFmode, SFmode, SFmode, VOIDmode,
11107 RS6000_BUILTIN_RECIPF,
11108 "__builtin_recipdivf");
11109 def_builtin (MASK_PPC_GFXOPT, "__builtin_recipdivf", ftype,
11110 RS6000_BUILTIN_RECIPF);
11112 ftype = builtin_function_type (SFmode, SFmode, VOIDmode, VOIDmode,
11113 RS6000_BUILTIN_RSQRTF,
11114 "__builtin_rsqrtf");
11115 def_builtin (MASK_PPC_GFXOPT, "__builtin_rsqrtf", ftype,
11116 RS6000_BUILTIN_RSQRTF);
11118 if (TARGET_POPCNTB)
11120 tree ftype = builtin_function_type (DFmode, DFmode, DFmode, VOIDmode,
11121 RS6000_BUILTIN_RECIP,
11122 "__builtin_recipdiv");
11123 def_builtin (MASK_POPCNTB, "__builtin_recipdiv", ftype,
11124 RS6000_BUILTIN_RECIP);
11127 if (TARGET_POPCNTD)
11129 enum machine_mode mode = (TARGET_64BIT) ? DImode : SImode;
11130 tree ftype = builtin_function_type (mode, mode, mode, VOIDmode,
11131 POWER7_BUILTIN_BPERMD,
11132 "__builtin_bpermd");
11133 def_builtin (MASK_POPCNTD, "__builtin_bpermd", ftype,
11134 POWER7_BUILTIN_BPERMD);
11136 if (TARGET_POWERPC)
11138 /* Don't use builtin_function_type here, as it maps HI/QI to SI. */
11139 tree ftype = build_function_type_list (unsigned_intHI_type_node,
11140 unsigned_intHI_type_node,
11141 NULL_TREE);
11142 def_builtin (MASK_POWERPC, "__builtin_bswap16", ftype,
11143 RS6000_BUILTIN_BSWAP_HI);
11146 #if TARGET_XCOFF
11147 /* AIX libm provides clog as __clog. */
11148 if (built_in_decls [BUILT_IN_CLOG])
11149 set_user_assembler_name (built_in_decls [BUILT_IN_CLOG], "__clog");
11150 #endif
11152 #ifdef SUBTARGET_INIT_BUILTINS
11153 SUBTARGET_INIT_BUILTINS;
11154 #endif
11157 /* Search through a set of builtins and enable the mask bits.
11158 DESC is an array of builtins.
11159 SIZE is the total number of builtins.
11160 START is the builtin enum at which to start.
11161 END is the builtin enum at which to end. */
11162 static void
11163 enable_mask_for_builtins (struct builtin_description *desc, int size,
11164 enum rs6000_builtins start,
11165 enum rs6000_builtins end)
11167 int i;
11169 for (i = 0; i < size; ++i)
11170 if (desc[i].code == start)
11171 break;
11173 if (i == size)
11174 return;
11176 for (; i < size; ++i)
11178 /* Flip all the bits on. */
11179 desc[i].mask = target_flags;
11180 if (desc[i].code == end)
11181 break;
11185 static void
11186 spe_init_builtins (void)
11188 tree endlink = void_list_node;
11189 tree puint_type_node = build_pointer_type (unsigned_type_node);
11190 tree pushort_type_node = build_pointer_type (short_unsigned_type_node);
11191 struct builtin_description *d;
11192 size_t i;
11194 tree v2si_ftype_4_v2si
11195 = build_function_type
11196 (opaque_V2SI_type_node,
11197 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11198 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11199 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11200 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11201 endlink)))));
11203 tree v2sf_ftype_4_v2sf
11204 = build_function_type
11205 (opaque_V2SF_type_node,
11206 tree_cons (NULL_TREE, opaque_V2SF_type_node,
11207 tree_cons (NULL_TREE, opaque_V2SF_type_node,
11208 tree_cons (NULL_TREE, opaque_V2SF_type_node,
11209 tree_cons (NULL_TREE, opaque_V2SF_type_node,
11210 endlink)))));
11212 tree int_ftype_int_v2si_v2si
11213 = build_function_type
11214 (integer_type_node,
11215 tree_cons (NULL_TREE, integer_type_node,
11216 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11217 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11218 endlink))));
11220 tree int_ftype_int_v2sf_v2sf
11221 = build_function_type
11222 (integer_type_node,
11223 tree_cons (NULL_TREE, integer_type_node,
11224 tree_cons (NULL_TREE, opaque_V2SF_type_node,
11225 tree_cons (NULL_TREE, opaque_V2SF_type_node,
11226 endlink))));
11228 tree void_ftype_v2si_puint_int
11229 = build_function_type (void_type_node,
11230 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11231 tree_cons (NULL_TREE, puint_type_node,
11232 tree_cons (NULL_TREE,
11233 integer_type_node,
11234 endlink))));
11236 tree void_ftype_v2si_puint_char
11237 = build_function_type (void_type_node,
11238 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11239 tree_cons (NULL_TREE, puint_type_node,
11240 tree_cons (NULL_TREE,
11241 char_type_node,
11242 endlink))));
11244 tree void_ftype_v2si_pv2si_int
11245 = build_function_type (void_type_node,
11246 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11247 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
11248 tree_cons (NULL_TREE,
11249 integer_type_node,
11250 endlink))));
11252 tree void_ftype_v2si_pv2si_char
11253 = build_function_type (void_type_node,
11254 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11255 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
11256 tree_cons (NULL_TREE,
11257 char_type_node,
11258 endlink))));
11260 tree void_ftype_int
11261 = build_function_type (void_type_node,
11262 tree_cons (NULL_TREE, integer_type_node, endlink));
11264 tree int_ftype_void
11265 = build_function_type (integer_type_node, endlink);
11267 tree v2si_ftype_pv2si_int
11268 = build_function_type (opaque_V2SI_type_node,
11269 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
11270 tree_cons (NULL_TREE, integer_type_node,
11271 endlink)));
11273 tree v2si_ftype_puint_int
11274 = build_function_type (opaque_V2SI_type_node,
11275 tree_cons (NULL_TREE, puint_type_node,
11276 tree_cons (NULL_TREE, integer_type_node,
11277 endlink)));
11279 tree v2si_ftype_pushort_int
11280 = build_function_type (opaque_V2SI_type_node,
11281 tree_cons (NULL_TREE, pushort_type_node,
11282 tree_cons (NULL_TREE, integer_type_node,
11283 endlink)));
11285 tree v2si_ftype_signed_char
11286 = build_function_type (opaque_V2SI_type_node,
11287 tree_cons (NULL_TREE, signed_char_type_node,
11288 endlink));
11290 /* The initialization of the simple binary and unary builtins is
11291 done in rs6000_common_init_builtins, but we have to enable the
11292 mask bits here manually because we have run out of `target_flags'
11293 bits. We really need to redesign this mask business. */
11295 enable_mask_for_builtins ((struct builtin_description *) bdesc_2arg,
11296 ARRAY_SIZE (bdesc_2arg),
11297 SPE_BUILTIN_EVADDW,
11298 SPE_BUILTIN_EVXOR);
11299 enable_mask_for_builtins ((struct builtin_description *) bdesc_1arg,
11300 ARRAY_SIZE (bdesc_1arg),
11301 SPE_BUILTIN_EVABS,
11302 SPE_BUILTIN_EVSUBFUSIAAW);
11303 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_predicates,
11304 ARRAY_SIZE (bdesc_spe_predicates),
11305 SPE_BUILTIN_EVCMPEQ,
11306 SPE_BUILTIN_EVFSTSTLT);
11307 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_evsel,
11308 ARRAY_SIZE (bdesc_spe_evsel),
11309 SPE_BUILTIN_EVSEL_CMPGTS,
11310 SPE_BUILTIN_EVSEL_FSTSTEQ);
11312 (*lang_hooks.decls.pushdecl)
11313 (build_decl (BUILTINS_LOCATION, TYPE_DECL,
11314 get_identifier ("__ev64_opaque__"),
11315 opaque_V2SI_type_node));
11317 /* Initialize irregular SPE builtins. */
11319 def_builtin (target_flags, "__builtin_spe_mtspefscr", void_ftype_int, SPE_BUILTIN_MTSPEFSCR);
11320 def_builtin (target_flags, "__builtin_spe_mfspefscr", int_ftype_void, SPE_BUILTIN_MFSPEFSCR);
11321 def_builtin (target_flags, "__builtin_spe_evstddx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDDX);
11322 def_builtin (target_flags, "__builtin_spe_evstdhx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDHX);
11323 def_builtin (target_flags, "__builtin_spe_evstdwx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDWX);
11324 def_builtin (target_flags, "__builtin_spe_evstwhex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHEX);
11325 def_builtin (target_flags, "__builtin_spe_evstwhox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHOX);
11326 def_builtin (target_flags, "__builtin_spe_evstwwex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWEX);
11327 def_builtin (target_flags, "__builtin_spe_evstwwox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWOX);
11328 def_builtin (target_flags, "__builtin_spe_evstdd", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDD);
11329 def_builtin (target_flags, "__builtin_spe_evstdh", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDH);
11330 def_builtin (target_flags, "__builtin_spe_evstdw", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDW);
11331 def_builtin (target_flags, "__builtin_spe_evstwhe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHE);
11332 def_builtin (target_flags, "__builtin_spe_evstwho", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHO);
11333 def_builtin (target_flags, "__builtin_spe_evstwwe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWE);
11334 def_builtin (target_flags, "__builtin_spe_evstwwo", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWO);
11335 def_builtin (target_flags, "__builtin_spe_evsplatfi", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATFI);
11336 def_builtin (target_flags, "__builtin_spe_evsplati", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATI);
11338 /* Loads. */
11339 def_builtin (target_flags, "__builtin_spe_evlddx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDDX);
11340 def_builtin (target_flags, "__builtin_spe_evldwx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDWX);
11341 def_builtin (target_flags, "__builtin_spe_evldhx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDHX);
11342 def_builtin (target_flags, "__builtin_spe_evlwhex", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHEX);
11343 def_builtin (target_flags, "__builtin_spe_evlwhoux", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOUX);
11344 def_builtin (target_flags, "__builtin_spe_evlwhosx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOSX);
11345 def_builtin (target_flags, "__builtin_spe_evlwwsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLATX);
11346 def_builtin (target_flags, "__builtin_spe_evlwhsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLATX);
11347 def_builtin (target_flags, "__builtin_spe_evlhhesplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLATX);
11348 def_builtin (target_flags, "__builtin_spe_evlhhousplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLATX);
11349 def_builtin (target_flags, "__builtin_spe_evlhhossplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLATX);
11350 def_builtin (target_flags, "__builtin_spe_evldd", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDD);
11351 def_builtin (target_flags, "__builtin_spe_evldw", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDW);
11352 def_builtin (target_flags, "__builtin_spe_evldh", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDH);
11353 def_builtin (target_flags, "__builtin_spe_evlhhesplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLAT);
11354 def_builtin (target_flags, "__builtin_spe_evlhhossplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLAT);
11355 def_builtin (target_flags, "__builtin_spe_evlhhousplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLAT);
11356 def_builtin (target_flags, "__builtin_spe_evlwhe", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHE);
11357 def_builtin (target_flags, "__builtin_spe_evlwhos", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOS);
11358 def_builtin (target_flags, "__builtin_spe_evlwhou", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOU);
11359 def_builtin (target_flags, "__builtin_spe_evlwhsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLAT);
11360 def_builtin (target_flags, "__builtin_spe_evlwwsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLAT);
11362 /* Predicates. */
11363 d = (struct builtin_description *) bdesc_spe_predicates;
11364 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, d++)
11366 tree type;
11368 switch (insn_data[d->icode].operand[1].mode)
11370 case V2SImode:
11371 type = int_ftype_int_v2si_v2si;
11372 break;
11373 case V2SFmode:
11374 type = int_ftype_int_v2sf_v2sf;
11375 break;
11376 default:
11377 gcc_unreachable ();
11380 def_builtin (d->mask, d->name, type, d->code);
11383 /* Evsel predicates. */
11384 d = (struct builtin_description *) bdesc_spe_evsel;
11385 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, d++)
11387 tree type;
11389 switch (insn_data[d->icode].operand[1].mode)
11391 case V2SImode:
11392 type = v2si_ftype_4_v2si;
11393 break;
11394 case V2SFmode:
11395 type = v2sf_ftype_4_v2sf;
11396 break;
11397 default:
11398 gcc_unreachable ();
11401 def_builtin (d->mask, d->name, type, d->code);
11405 static void
11406 paired_init_builtins (void)
11408 const struct builtin_description *d;
11409 size_t i;
11410 tree endlink = void_list_node;
11412 tree int_ftype_int_v2sf_v2sf
11413 = build_function_type
11414 (integer_type_node,
11415 tree_cons (NULL_TREE, integer_type_node,
11416 tree_cons (NULL_TREE, V2SF_type_node,
11417 tree_cons (NULL_TREE, V2SF_type_node,
11418 endlink))));
11419 tree pcfloat_type_node =
11420 build_pointer_type (build_qualified_type
11421 (float_type_node, TYPE_QUAL_CONST));
11423 tree v2sf_ftype_long_pcfloat = build_function_type_list (V2SF_type_node,
11424 long_integer_type_node,
11425 pcfloat_type_node,
11426 NULL_TREE);
11427 tree void_ftype_v2sf_long_pcfloat =
11428 build_function_type_list (void_type_node,
11429 V2SF_type_node,
11430 long_integer_type_node,
11431 pcfloat_type_node,
11432 NULL_TREE);
11435 def_builtin (0, "__builtin_paired_lx", v2sf_ftype_long_pcfloat,
11436 PAIRED_BUILTIN_LX);
11439 def_builtin (0, "__builtin_paired_stx", void_ftype_v2sf_long_pcfloat,
11440 PAIRED_BUILTIN_STX);
11442 /* Predicates. */
11443 d = bdesc_paired_preds;
11444 for (i = 0; i < ARRAY_SIZE (bdesc_paired_preds); ++i, d++)
11446 tree type;
11448 switch (insn_data[d->icode].operand[1].mode)
11450 case V2SFmode:
11451 type = int_ftype_int_v2sf_v2sf;
11452 break;
11453 default:
11454 gcc_unreachable ();
11457 def_builtin (d->mask, d->name, type, d->code);
11461 static void
11462 altivec_init_builtins (void)
11464 const struct builtin_description *d;
11465 const struct builtin_description_predicates *dp;
11466 size_t i;
11467 tree ftype;
11469 tree pfloat_type_node = build_pointer_type (float_type_node);
11470 tree pint_type_node = build_pointer_type (integer_type_node);
11471 tree pshort_type_node = build_pointer_type (short_integer_type_node);
11472 tree pchar_type_node = build_pointer_type (char_type_node);
11474 tree pvoid_type_node = build_pointer_type (void_type_node);
11476 tree pcfloat_type_node = build_pointer_type (build_qualified_type (float_type_node, TYPE_QUAL_CONST));
11477 tree pcint_type_node = build_pointer_type (build_qualified_type (integer_type_node, TYPE_QUAL_CONST));
11478 tree pcshort_type_node = build_pointer_type (build_qualified_type (short_integer_type_node, TYPE_QUAL_CONST));
11479 tree pcchar_type_node = build_pointer_type (build_qualified_type (char_type_node, TYPE_QUAL_CONST));
11481 tree pcvoid_type_node = build_pointer_type (build_qualified_type (void_type_node, TYPE_QUAL_CONST));
11483 tree int_ftype_opaque
11484 = build_function_type_list (integer_type_node,
11485 opaque_V4SI_type_node, NULL_TREE);
11486 tree opaque_ftype_opaque
11487 = build_function_type (integer_type_node,
11488 NULL_TREE);
11489 tree opaque_ftype_opaque_int
11490 = build_function_type_list (opaque_V4SI_type_node,
11491 opaque_V4SI_type_node, integer_type_node, NULL_TREE);
11492 tree opaque_ftype_opaque_opaque_int
11493 = build_function_type_list (opaque_V4SI_type_node,
11494 opaque_V4SI_type_node, opaque_V4SI_type_node,
11495 integer_type_node, NULL_TREE);
11496 tree int_ftype_int_opaque_opaque
11497 = build_function_type_list (integer_type_node,
11498 integer_type_node, opaque_V4SI_type_node,
11499 opaque_V4SI_type_node, NULL_TREE);
11500 tree int_ftype_int_v4si_v4si
11501 = build_function_type_list (integer_type_node,
11502 integer_type_node, V4SI_type_node,
11503 V4SI_type_node, NULL_TREE);
11504 tree v4sf_ftype_pcfloat
11505 = build_function_type_list (V4SF_type_node, pcfloat_type_node, NULL_TREE);
11506 tree void_ftype_pfloat_v4sf
11507 = build_function_type_list (void_type_node,
11508 pfloat_type_node, V4SF_type_node, NULL_TREE);
11509 tree v4si_ftype_pcint
11510 = build_function_type_list (V4SI_type_node, pcint_type_node, NULL_TREE);
11511 tree void_ftype_pint_v4si
11512 = build_function_type_list (void_type_node,
11513 pint_type_node, V4SI_type_node, NULL_TREE);
11514 tree v8hi_ftype_pcshort
11515 = build_function_type_list (V8HI_type_node, pcshort_type_node, NULL_TREE);
11516 tree void_ftype_pshort_v8hi
11517 = build_function_type_list (void_type_node,
11518 pshort_type_node, V8HI_type_node, NULL_TREE);
11519 tree v16qi_ftype_pcchar
11520 = build_function_type_list (V16QI_type_node, pcchar_type_node, NULL_TREE);
11521 tree void_ftype_pchar_v16qi
11522 = build_function_type_list (void_type_node,
11523 pchar_type_node, V16QI_type_node, NULL_TREE);
11524 tree void_ftype_v4si
11525 = build_function_type_list (void_type_node, V4SI_type_node, NULL_TREE);
11526 tree v8hi_ftype_void
11527 = build_function_type (V8HI_type_node, void_list_node);
11528 tree void_ftype_void
11529 = build_function_type (void_type_node, void_list_node);
11530 tree void_ftype_int
11531 = build_function_type_list (void_type_node, integer_type_node, NULL_TREE);
11533 tree opaque_ftype_long_pcvoid
11534 = build_function_type_list (opaque_V4SI_type_node,
11535 long_integer_type_node, pcvoid_type_node, NULL_TREE);
11536 tree v16qi_ftype_long_pcvoid
11537 = build_function_type_list (V16QI_type_node,
11538 long_integer_type_node, pcvoid_type_node, NULL_TREE);
11539 tree v8hi_ftype_long_pcvoid
11540 = build_function_type_list (V8HI_type_node,
11541 long_integer_type_node, pcvoid_type_node, NULL_TREE);
11542 tree v4si_ftype_long_pcvoid
11543 = build_function_type_list (V4SI_type_node,
11544 long_integer_type_node, pcvoid_type_node, NULL_TREE);
11546 tree void_ftype_opaque_long_pvoid
11547 = build_function_type_list (void_type_node,
11548 opaque_V4SI_type_node, long_integer_type_node,
11549 pvoid_type_node, NULL_TREE);
11550 tree void_ftype_v4si_long_pvoid
11551 = build_function_type_list (void_type_node,
11552 V4SI_type_node, long_integer_type_node,
11553 pvoid_type_node, NULL_TREE);
11554 tree void_ftype_v16qi_long_pvoid
11555 = build_function_type_list (void_type_node,
11556 V16QI_type_node, long_integer_type_node,
11557 pvoid_type_node, NULL_TREE);
11558 tree void_ftype_v8hi_long_pvoid
11559 = build_function_type_list (void_type_node,
11560 V8HI_type_node, long_integer_type_node,
11561 pvoid_type_node, NULL_TREE);
11562 tree int_ftype_int_v8hi_v8hi
11563 = build_function_type_list (integer_type_node,
11564 integer_type_node, V8HI_type_node,
11565 V8HI_type_node, NULL_TREE);
11566 tree int_ftype_int_v16qi_v16qi
11567 = build_function_type_list (integer_type_node,
11568 integer_type_node, V16QI_type_node,
11569 V16QI_type_node, NULL_TREE);
11570 tree int_ftype_int_v4sf_v4sf
11571 = build_function_type_list (integer_type_node,
11572 integer_type_node, V4SF_type_node,
11573 V4SF_type_node, NULL_TREE);
11574 tree int_ftype_int_v2df_v2df
11575 = build_function_type_list (integer_type_node,
11576 integer_type_node, V2DF_type_node,
11577 V2DF_type_node, NULL_TREE);
11578 tree v4si_ftype_v4si
11579 = build_function_type_list (V4SI_type_node, V4SI_type_node, NULL_TREE);
11580 tree v8hi_ftype_v8hi
11581 = build_function_type_list (V8HI_type_node, V8HI_type_node, NULL_TREE);
11582 tree v16qi_ftype_v16qi
11583 = build_function_type_list (V16QI_type_node, V16QI_type_node, NULL_TREE);
11584 tree v4sf_ftype_v4sf
11585 = build_function_type_list (V4SF_type_node, V4SF_type_node, NULL_TREE);
11586 tree v2df_ftype_v2df
11587 = build_function_type_list (V2DF_type_node, V2DF_type_node, NULL_TREE);
11588 tree void_ftype_pcvoid_int_int
11589 = build_function_type_list (void_type_node,
11590 pcvoid_type_node, integer_type_node,
11591 integer_type_node, NULL_TREE);
11593 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_4sf", v4sf_ftype_pcfloat,
11594 ALTIVEC_BUILTIN_LD_INTERNAL_4sf);
11595 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_4sf", void_ftype_pfloat_v4sf,
11596 ALTIVEC_BUILTIN_ST_INTERNAL_4sf);
11597 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_4si", v4si_ftype_pcint,
11598 ALTIVEC_BUILTIN_LD_INTERNAL_4si);
11599 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_4si", void_ftype_pint_v4si,
11600 ALTIVEC_BUILTIN_ST_INTERNAL_4si);
11601 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_8hi", v8hi_ftype_pcshort,
11602 ALTIVEC_BUILTIN_LD_INTERNAL_8hi);
11603 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_8hi", void_ftype_pshort_v8hi,
11604 ALTIVEC_BUILTIN_ST_INTERNAL_8hi);
11605 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_16qi", v16qi_ftype_pcchar,
11606 ALTIVEC_BUILTIN_LD_INTERNAL_16qi);
11607 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_16qi", void_ftype_pchar_v16qi,
11608 ALTIVEC_BUILTIN_ST_INTERNAL_16qi);
11609 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mtvscr", void_ftype_v4si, ALTIVEC_BUILTIN_MTVSCR);
11610 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mfvscr", v8hi_ftype_void, ALTIVEC_BUILTIN_MFVSCR);
11611 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dssall", void_ftype_void, ALTIVEC_BUILTIN_DSSALL);
11612 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dss", void_ftype_int, ALTIVEC_BUILTIN_DSS);
11613 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSL);
11614 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSR);
11615 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEBX);
11616 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEHX);
11617 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEWX);
11618 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvxl", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVXL);
11619 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVX);
11620 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVX);
11621 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvewx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVEWX);
11622 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvxl", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVXL);
11623 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvebx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVEBX);
11624 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvehx", void_ftype_v8hi_long_pvoid, ALTIVEC_BUILTIN_STVEHX);
11625 def_builtin (MASK_ALTIVEC, "__builtin_vec_ld", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LD);
11626 def_builtin (MASK_ALTIVEC, "__builtin_vec_lde", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDE);
11627 def_builtin (MASK_ALTIVEC, "__builtin_vec_ldl", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDL);
11628 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSL);
11629 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSR);
11630 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEBX);
11631 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEHX);
11632 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEWX);
11633 def_builtin (MASK_ALTIVEC, "__builtin_vec_st", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_ST);
11634 def_builtin (MASK_ALTIVEC, "__builtin_vec_ste", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STE);
11635 def_builtin (MASK_ALTIVEC, "__builtin_vec_stl", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STL);
11636 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvewx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEWX);
11637 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvebx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEBX);
11638 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvehx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEHX);
11640 if (rs6000_cpu == PROCESSOR_CELL)
11642 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvlx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVLX);
11643 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvlxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVLXL);
11644 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvrx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVRX);
11645 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvrxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVRXL);
11647 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvlx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVLX);
11648 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvlxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVLXL);
11649 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvrx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVRX);
11650 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvrxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVRXL);
11652 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvlx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVLX);
11653 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvlxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVLXL);
11654 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvrx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVRX);
11655 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvrxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVRXL);
11657 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvlx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVLX);
11658 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvlxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVLXL);
11659 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvrx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVRX);
11660 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvrxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVRXL);
11662 def_builtin (MASK_ALTIVEC, "__builtin_vec_step", int_ftype_opaque, ALTIVEC_BUILTIN_VEC_STEP);
11663 def_builtin (MASK_ALTIVEC, "__builtin_vec_splats", opaque_ftype_opaque, ALTIVEC_BUILTIN_VEC_SPLATS);
11664 def_builtin (MASK_ALTIVEC, "__builtin_vec_promote", opaque_ftype_opaque, ALTIVEC_BUILTIN_VEC_PROMOTE);
11666 def_builtin (MASK_ALTIVEC, "__builtin_vec_sld", opaque_ftype_opaque_opaque_int, ALTIVEC_BUILTIN_VEC_SLD);
11667 def_builtin (MASK_ALTIVEC, "__builtin_vec_splat", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_SPLAT);
11668 def_builtin (MASK_ALTIVEC, "__builtin_vec_extract", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_EXTRACT);
11669 def_builtin (MASK_ALTIVEC, "__builtin_vec_insert", opaque_ftype_opaque_opaque_int, ALTIVEC_BUILTIN_VEC_INSERT);
11670 def_builtin (MASK_ALTIVEC, "__builtin_vec_vspltw", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTW);
11671 def_builtin (MASK_ALTIVEC, "__builtin_vec_vsplth", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTH);
11672 def_builtin (MASK_ALTIVEC, "__builtin_vec_vspltb", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTB);
11673 def_builtin (MASK_ALTIVEC, "__builtin_vec_ctf", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTF);
11674 def_builtin (MASK_ALTIVEC, "__builtin_vec_vcfsx", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFSX);
11675 def_builtin (MASK_ALTIVEC, "__builtin_vec_vcfux", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFUX);
11676 def_builtin (MASK_ALTIVEC, "__builtin_vec_cts", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTS);
11677 def_builtin (MASK_ALTIVEC, "__builtin_vec_ctu", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTU);
11679 /* Add the DST variants. */
11680 d = bdesc_dst;
11681 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
11682 def_builtin (d->mask, d->name, void_ftype_pcvoid_int_int, d->code);
11684 /* Initialize the predicates. */
11685 dp = bdesc_altivec_preds;
11686 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
11688 enum machine_mode mode1;
11689 tree type;
11690 bool is_overloaded = ((dp->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
11691 && dp->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
11692 || (dp->code >= VSX_BUILTIN_OVERLOADED_FIRST
11693 && dp->code <= VSX_BUILTIN_OVERLOADED_LAST));
11695 if (is_overloaded)
11696 mode1 = VOIDmode;
11697 else
11698 mode1 = insn_data[dp->icode].operand[1].mode;
11700 switch (mode1)
11702 case VOIDmode:
11703 type = int_ftype_int_opaque_opaque;
11704 break;
11705 case V4SImode:
11706 type = int_ftype_int_v4si_v4si;
11707 break;
11708 case V8HImode:
11709 type = int_ftype_int_v8hi_v8hi;
11710 break;
11711 case V16QImode:
11712 type = int_ftype_int_v16qi_v16qi;
11713 break;
11714 case V4SFmode:
11715 type = int_ftype_int_v4sf_v4sf;
11716 break;
11717 case V2DFmode:
11718 type = int_ftype_int_v2df_v2df;
11719 break;
11720 default:
11721 gcc_unreachable ();
11724 def_builtin (dp->mask, dp->name, type, dp->code);
11727 /* Initialize the abs* operators. */
11728 d = bdesc_abs;
11729 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
11731 enum machine_mode mode0;
11732 tree type;
11734 mode0 = insn_data[d->icode].operand[0].mode;
11736 switch (mode0)
11738 case V4SImode:
11739 type = v4si_ftype_v4si;
11740 break;
11741 case V8HImode:
11742 type = v8hi_ftype_v8hi;
11743 break;
11744 case V16QImode:
11745 type = v16qi_ftype_v16qi;
11746 break;
11747 case V4SFmode:
11748 type = v4sf_ftype_v4sf;
11749 break;
11750 case V2DFmode:
11751 type = v2df_ftype_v2df;
11752 break;
11753 default:
11754 gcc_unreachable ();
11757 def_builtin (d->mask, d->name, type, d->code);
11760 if (TARGET_ALTIVEC)
11762 tree decl;
11764 /* Initialize target builtin that implements
11765 targetm.vectorize.builtin_mask_for_load. */
11767 decl = add_builtin_function ("__builtin_altivec_mask_for_load",
11768 v16qi_ftype_long_pcvoid,
11769 ALTIVEC_BUILTIN_MASK_FOR_LOAD,
11770 BUILT_IN_MD, NULL, NULL_TREE);
11771 TREE_READONLY (decl) = 1;
11772 /* Record the decl. Will be used by rs6000_builtin_mask_for_load. */
11773 altivec_builtin_mask_for_load = decl;
11776 /* Access to the vec_init patterns. */
11777 ftype = build_function_type_list (V4SI_type_node, integer_type_node,
11778 integer_type_node, integer_type_node,
11779 integer_type_node, NULL_TREE);
11780 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v4si", ftype,
11781 ALTIVEC_BUILTIN_VEC_INIT_V4SI);
11783 ftype = build_function_type_list (V8HI_type_node, short_integer_type_node,
11784 short_integer_type_node,
11785 short_integer_type_node,
11786 short_integer_type_node,
11787 short_integer_type_node,
11788 short_integer_type_node,
11789 short_integer_type_node,
11790 short_integer_type_node, NULL_TREE);
11791 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v8hi", ftype,
11792 ALTIVEC_BUILTIN_VEC_INIT_V8HI);
11794 ftype = build_function_type_list (V16QI_type_node, char_type_node,
11795 char_type_node, char_type_node,
11796 char_type_node, char_type_node,
11797 char_type_node, char_type_node,
11798 char_type_node, char_type_node,
11799 char_type_node, char_type_node,
11800 char_type_node, char_type_node,
11801 char_type_node, char_type_node,
11802 char_type_node, NULL_TREE);
11803 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v16qi", ftype,
11804 ALTIVEC_BUILTIN_VEC_INIT_V16QI);
11806 ftype = build_function_type_list (V4SF_type_node, float_type_node,
11807 float_type_node, float_type_node,
11808 float_type_node, NULL_TREE);
11809 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v4sf", ftype,
11810 ALTIVEC_BUILTIN_VEC_INIT_V4SF);
11812 if (TARGET_VSX)
11814 ftype = build_function_type_list (V2DF_type_node, double_type_node,
11815 double_type_node, NULL_TREE);
11816 def_builtin (MASK_VSX, "__builtin_vec_init_v2df", ftype,
11817 VSX_BUILTIN_VEC_INIT_V2DF);
11819 ftype = build_function_type_list (V2DI_type_node, intDI_type_node,
11820 intDI_type_node, NULL_TREE);
11821 def_builtin (MASK_VSX, "__builtin_vec_init_v2di", ftype,
11822 VSX_BUILTIN_VEC_INIT_V2DI);
11825 /* Access to the vec_set patterns. */
11826 ftype = build_function_type_list (V4SI_type_node, V4SI_type_node,
11827 intSI_type_node,
11828 integer_type_node, NULL_TREE);
11829 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v4si", ftype,
11830 ALTIVEC_BUILTIN_VEC_SET_V4SI);
11832 ftype = build_function_type_list (V8HI_type_node, V8HI_type_node,
11833 intHI_type_node,
11834 integer_type_node, NULL_TREE);
11835 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v8hi", ftype,
11836 ALTIVEC_BUILTIN_VEC_SET_V8HI);
11838 ftype = build_function_type_list (V16QI_type_node, V16QI_type_node,
11839 intQI_type_node,
11840 integer_type_node, NULL_TREE);
11841 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v16qi", ftype,
11842 ALTIVEC_BUILTIN_VEC_SET_V16QI);
11844 ftype = build_function_type_list (V4SF_type_node, V4SF_type_node,
11845 float_type_node,
11846 integer_type_node, NULL_TREE);
11847 def_builtin (MASK_ALTIVEC|MASK_VSX, "__builtin_vec_set_v4sf", ftype,
11848 ALTIVEC_BUILTIN_VEC_SET_V4SF);
11850 if (TARGET_VSX)
11852 ftype = build_function_type_list (V2DF_type_node, V2DF_type_node,
11853 double_type_node,
11854 integer_type_node, NULL_TREE);
11855 def_builtin (MASK_VSX, "__builtin_vec_set_v2df", ftype,
11856 VSX_BUILTIN_VEC_SET_V2DF);
11858 ftype = build_function_type_list (V2DI_type_node, V2DI_type_node,
11859 intDI_type_node,
11860 integer_type_node, NULL_TREE);
11861 def_builtin (MASK_VSX, "__builtin_vec_set_v2di", ftype,
11862 VSX_BUILTIN_VEC_SET_V2DI);
11865 /* Access to the vec_extract patterns. */
11866 ftype = build_function_type_list (intSI_type_node, V4SI_type_node,
11867 integer_type_node, NULL_TREE);
11868 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v4si", ftype,
11869 ALTIVEC_BUILTIN_VEC_EXT_V4SI);
11871 ftype = build_function_type_list (intHI_type_node, V8HI_type_node,
11872 integer_type_node, NULL_TREE);
11873 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v8hi", ftype,
11874 ALTIVEC_BUILTIN_VEC_EXT_V8HI);
11876 ftype = build_function_type_list (intQI_type_node, V16QI_type_node,
11877 integer_type_node, NULL_TREE);
11878 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v16qi", ftype,
11879 ALTIVEC_BUILTIN_VEC_EXT_V16QI);
11881 ftype = build_function_type_list (float_type_node, V4SF_type_node,
11882 integer_type_node, NULL_TREE);
11883 def_builtin (MASK_ALTIVEC|MASK_VSX, "__builtin_vec_ext_v4sf", ftype,
11884 ALTIVEC_BUILTIN_VEC_EXT_V4SF);
11886 if (TARGET_VSX)
11888 ftype = build_function_type_list (double_type_node, V2DF_type_node,
11889 integer_type_node, NULL_TREE);
11890 def_builtin (MASK_VSX, "__builtin_vec_ext_v2df", ftype,
11891 VSX_BUILTIN_VEC_EXT_V2DF);
11893 ftype = build_function_type_list (intDI_type_node, V2DI_type_node,
11894 integer_type_node, NULL_TREE);
11895 def_builtin (MASK_VSX, "__builtin_vec_ext_v2di", ftype,
11896 VSX_BUILTIN_VEC_EXT_V2DI);
11900 /* Hash function for builtin functions with up to 3 arguments and a return
11901 type. */
11902 static unsigned
11903 builtin_hash_function (const void *hash_entry)
11905 unsigned ret = 0;
11906 int i;
11907 const struct builtin_hash_struct *bh =
11908 (const struct builtin_hash_struct *) hash_entry;
11910 for (i = 0; i < 4; i++)
11912 ret = (ret * (unsigned)MAX_MACHINE_MODE) + ((unsigned)bh->mode[i]);
11913 ret = (ret * 2) + bh->uns_p[i];
11916 return ret;
11919 /* Compare builtin hash entries H1 and H2 for equivalence. */
11920 static int
11921 builtin_hash_eq (const void *h1, const void *h2)
11923 const struct builtin_hash_struct *p1 = (const struct builtin_hash_struct *) h1;
11924 const struct builtin_hash_struct *p2 = (const struct builtin_hash_struct *) h2;
11926 return ((p1->mode[0] == p2->mode[0])
11927 && (p1->mode[1] == p2->mode[1])
11928 && (p1->mode[2] == p2->mode[2])
11929 && (p1->mode[3] == p2->mode[3])
11930 && (p1->uns_p[0] == p2->uns_p[0])
11931 && (p1->uns_p[1] == p2->uns_p[1])
11932 && (p1->uns_p[2] == p2->uns_p[2])
11933 && (p1->uns_p[3] == p2->uns_p[3]));
11936 /* Map types for builtin functions with an explicit return type and up to 3
11937 arguments. Functions with fewer than 3 arguments use VOIDmode as the type
11938 of the argument. */
11939 static tree
11940 builtin_function_type (enum machine_mode mode_ret, enum machine_mode mode_arg0,
11941 enum machine_mode mode_arg1, enum machine_mode mode_arg2,
11942 enum rs6000_builtins builtin, const char *name)
11944 struct builtin_hash_struct h;
11945 struct builtin_hash_struct *h2;
11946 void **found;
11947 int num_args = 3;
11948 int i;
11949 tree ret_type = NULL_TREE;
11950 tree arg_type[3] = { NULL_TREE, NULL_TREE, NULL_TREE };
11951 tree args;
11953 /* Create builtin_hash_table. */
11954 if (builtin_hash_table == NULL)
11955 builtin_hash_table = htab_create_ggc (1500, builtin_hash_function,
11956 builtin_hash_eq, NULL);
11958 h.type = NULL_TREE;
11959 h.mode[0] = mode_ret;
11960 h.mode[1] = mode_arg0;
11961 h.mode[2] = mode_arg1;
11962 h.mode[3] = mode_arg2;
11963 h.uns_p[0] = 0;
11964 h.uns_p[1] = 0;
11965 h.uns_p[2] = 0;
11966 h.uns_p[3] = 0;
11968 /* If the builtin is a type that produces unsigned results or takes unsigned
11969 arguments, and it is returned as a decl for the vectorizer (such as
11970 widening multiplies, permute), make sure the arguments and return value
11971 are type correct. */
11972 switch (builtin)
11974 /* unsigned 2 argument functions. */
11975 case ALTIVEC_BUILTIN_VMULEUB_UNS:
11976 case ALTIVEC_BUILTIN_VMULEUH_UNS:
11977 case ALTIVEC_BUILTIN_VMULOUB_UNS:
11978 case ALTIVEC_BUILTIN_VMULOUH_UNS:
11979 h.uns_p[0] = 1;
11980 h.uns_p[1] = 1;
11981 h.uns_p[2] = 1;
11982 break;
11984 /* unsigned 3 argument functions. */
11985 case ALTIVEC_BUILTIN_VPERM_16QI_UNS:
11986 case ALTIVEC_BUILTIN_VPERM_8HI_UNS:
11987 case ALTIVEC_BUILTIN_VPERM_4SI_UNS:
11988 case ALTIVEC_BUILTIN_VPERM_2DI_UNS:
11989 case ALTIVEC_BUILTIN_VSEL_16QI_UNS:
11990 case ALTIVEC_BUILTIN_VSEL_8HI_UNS:
11991 case ALTIVEC_BUILTIN_VSEL_4SI_UNS:
11992 case ALTIVEC_BUILTIN_VSEL_2DI_UNS:
11993 case VSX_BUILTIN_VPERM_16QI_UNS:
11994 case VSX_BUILTIN_VPERM_8HI_UNS:
11995 case VSX_BUILTIN_VPERM_4SI_UNS:
11996 case VSX_BUILTIN_VPERM_2DI_UNS:
11997 case VSX_BUILTIN_XXSEL_16QI_UNS:
11998 case VSX_BUILTIN_XXSEL_8HI_UNS:
11999 case VSX_BUILTIN_XXSEL_4SI_UNS:
12000 case VSX_BUILTIN_XXSEL_2DI_UNS:
12001 h.uns_p[0] = 1;
12002 h.uns_p[1] = 1;
12003 h.uns_p[2] = 1;
12004 h.uns_p[3] = 1;
12005 break;
12007 /* signed permute functions with unsigned char mask. */
12008 case ALTIVEC_BUILTIN_VPERM_16QI:
12009 case ALTIVEC_BUILTIN_VPERM_8HI:
12010 case ALTIVEC_BUILTIN_VPERM_4SI:
12011 case ALTIVEC_BUILTIN_VPERM_4SF:
12012 case ALTIVEC_BUILTIN_VPERM_2DI:
12013 case ALTIVEC_BUILTIN_VPERM_2DF:
12014 case VSX_BUILTIN_VPERM_16QI:
12015 case VSX_BUILTIN_VPERM_8HI:
12016 case VSX_BUILTIN_VPERM_4SI:
12017 case VSX_BUILTIN_VPERM_4SF:
12018 case VSX_BUILTIN_VPERM_2DI:
12019 case VSX_BUILTIN_VPERM_2DF:
12020 h.uns_p[3] = 1;
12021 break;
12023 /* unsigned args, signed return. */
12024 case VSX_BUILTIN_XVCVUXDDP_UNS:
12025 case VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF:
12026 h.uns_p[1] = 1;
12027 break;
12029 /* signed args, unsigned return. */
12030 case VSX_BUILTIN_XVCVDPUXDS_UNS:
12031 case VECTOR_BUILTIN_FIXUNS_V4SF_V4SI:
12032 h.uns_p[0] = 1;
12033 break;
12035 default:
12036 break;
12039 /* Figure out how many args are present. */
12040 while (num_args > 0 && h.mode[num_args] == VOIDmode)
12041 num_args--;
12043 if (num_args == 0)
12044 fatal_error ("internal error: builtin function %s had no type", name);
12046 ret_type = builtin_mode_to_type[h.mode[0]][h.uns_p[0]];
12047 if (!ret_type && h.uns_p[0])
12048 ret_type = builtin_mode_to_type[h.mode[0]][0];
12050 if (!ret_type)
12051 fatal_error ("internal error: builtin function %s had an unexpected "
12052 "return type %s", name, GET_MODE_NAME (h.mode[0]));
12054 for (i = 0; i < num_args; i++)
12056 int m = (int) h.mode[i+1];
12057 int uns_p = h.uns_p[i+1];
12059 arg_type[i] = builtin_mode_to_type[m][uns_p];
12060 if (!arg_type[i] && uns_p)
12061 arg_type[i] = builtin_mode_to_type[m][0];
12063 if (!arg_type[i])
12064 fatal_error ("internal error: builtin function %s, argument %d "
12065 "had unexpected argument type %s", name, i,
12066 GET_MODE_NAME (m));
12069 found = htab_find_slot (builtin_hash_table, &h, INSERT);
12070 if (*found == NULL)
12072 h2 = GGC_NEW (struct builtin_hash_struct);
12073 *h2 = h;
12074 *found = (void *)h2;
12075 args = void_list_node;
12077 for (i = num_args - 1; i >= 0; i--)
12078 args = tree_cons (NULL_TREE, arg_type[i], args);
12080 h2->type = build_function_type (ret_type, args);
12083 return ((struct builtin_hash_struct *)(*found))->type;
12086 static void
12087 rs6000_common_init_builtins (void)
12089 const struct builtin_description *d;
12090 size_t i;
12092 tree opaque_ftype_opaque = NULL_TREE;
12093 tree opaque_ftype_opaque_opaque = NULL_TREE;
12094 tree opaque_ftype_opaque_opaque_opaque = NULL_TREE;
12095 tree v2si_ftype_qi = NULL_TREE;
12096 tree v2si_ftype_v2si_qi = NULL_TREE;
12097 tree v2si_ftype_int_qi = NULL_TREE;
12099 if (!TARGET_PAIRED_FLOAT)
12101 builtin_mode_to_type[V2SImode][0] = opaque_V2SI_type_node;
12102 builtin_mode_to_type[V2SFmode][0] = opaque_V2SF_type_node;
12105 /* Add the ternary operators. */
12106 d = bdesc_3arg;
12107 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
12109 tree type;
12110 int mask = d->mask;
12112 if ((mask != 0 && (mask & target_flags) == 0)
12113 || (mask == 0 && !TARGET_PAIRED_FLOAT))
12114 continue;
12116 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
12117 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
12118 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
12119 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
12121 if (! (type = opaque_ftype_opaque_opaque_opaque))
12122 type = opaque_ftype_opaque_opaque_opaque
12123 = build_function_type_list (opaque_V4SI_type_node,
12124 opaque_V4SI_type_node,
12125 opaque_V4SI_type_node,
12126 opaque_V4SI_type_node,
12127 NULL_TREE);
12129 else
12131 enum insn_code icode = d->icode;
12132 if (d->name == 0 || icode == CODE_FOR_nothing)
12133 continue;
12135 type = builtin_function_type (insn_data[icode].operand[0].mode,
12136 insn_data[icode].operand[1].mode,
12137 insn_data[icode].operand[2].mode,
12138 insn_data[icode].operand[3].mode,
12139 d->code, d->name);
12142 def_builtin (d->mask, d->name, type, d->code);
12145 /* Add the binary operators. */
12146 d = bdesc_2arg;
12147 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
12149 enum machine_mode mode0, mode1, mode2;
12150 tree type;
12151 int mask = d->mask;
12153 if ((mask != 0 && (mask & target_flags) == 0)
12154 || (mask == 0 && !TARGET_PAIRED_FLOAT))
12155 continue;
12157 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
12158 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
12159 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
12160 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
12162 if (! (type = opaque_ftype_opaque_opaque))
12163 type = opaque_ftype_opaque_opaque
12164 = build_function_type_list (opaque_V4SI_type_node,
12165 opaque_V4SI_type_node,
12166 opaque_V4SI_type_node,
12167 NULL_TREE);
12169 else
12171 enum insn_code icode = d->icode;
12172 if (d->name == 0 || icode == CODE_FOR_nothing)
12173 continue;
12175 mode0 = insn_data[icode].operand[0].mode;
12176 mode1 = insn_data[icode].operand[1].mode;
12177 mode2 = insn_data[icode].operand[2].mode;
12179 if (mode0 == V2SImode && mode1 == V2SImode && mode2 == QImode)
12181 if (! (type = v2si_ftype_v2si_qi))
12182 type = v2si_ftype_v2si_qi
12183 = build_function_type_list (opaque_V2SI_type_node,
12184 opaque_V2SI_type_node,
12185 char_type_node,
12186 NULL_TREE);
12189 else if (mode0 == V2SImode && GET_MODE_CLASS (mode1) == MODE_INT
12190 && mode2 == QImode)
12192 if (! (type = v2si_ftype_int_qi))
12193 type = v2si_ftype_int_qi
12194 = build_function_type_list (opaque_V2SI_type_node,
12195 integer_type_node,
12196 char_type_node,
12197 NULL_TREE);
12200 else
12201 type = builtin_function_type (mode0, mode1, mode2, VOIDmode,
12202 d->code, d->name);
12205 def_builtin (d->mask, d->name, type, d->code);
12208 /* Add the simple unary operators. */
12209 d = (struct builtin_description *) bdesc_1arg;
12210 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
12212 enum machine_mode mode0, mode1;
12213 tree type;
12214 int mask = d->mask;
12216 if ((mask != 0 && (mask & target_flags) == 0)
12217 || (mask == 0 && !TARGET_PAIRED_FLOAT))
12218 continue;
12220 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
12221 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
12222 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
12223 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
12225 if (! (type = opaque_ftype_opaque))
12226 type = opaque_ftype_opaque
12227 = build_function_type_list (opaque_V4SI_type_node,
12228 opaque_V4SI_type_node,
12229 NULL_TREE);
12231 else
12233 enum insn_code icode = d->icode;
12234 if (d->name == 0 || icode == CODE_FOR_nothing)
12235 continue;
12237 mode0 = insn_data[icode].operand[0].mode;
12238 mode1 = insn_data[icode].operand[1].mode;
12240 if (mode0 == V2SImode && mode1 == QImode)
12242 if (! (type = v2si_ftype_qi))
12243 type = v2si_ftype_qi
12244 = build_function_type_list (opaque_V2SI_type_node,
12245 char_type_node,
12246 NULL_TREE);
12249 else
12250 type = builtin_function_type (mode0, mode1, VOIDmode, VOIDmode,
12251 d->code, d->name);
12254 def_builtin (d->mask, d->name, type, d->code);
12258 static void
12259 rs6000_init_libfuncs (void)
12261 if (DEFAULT_ABI != ABI_V4 && TARGET_XCOFF
12262 && !TARGET_POWER2 && !TARGET_POWERPC)
12264 /* AIX library routines for float->int conversion. */
12265 set_conv_libfunc (sfix_optab, SImode, DFmode, "__itrunc");
12266 set_conv_libfunc (ufix_optab, SImode, DFmode, "__uitrunc");
12267 set_conv_libfunc (sfix_optab, SImode, TFmode, "_qitrunc");
12268 set_conv_libfunc (ufix_optab, SImode, TFmode, "_quitrunc");
12271 if (!TARGET_IEEEQUAD)
12272 /* AIX/Darwin/64-bit Linux quad floating point routines. */
12273 if (!TARGET_XL_COMPAT)
12275 set_optab_libfunc (add_optab, TFmode, "__gcc_qadd");
12276 set_optab_libfunc (sub_optab, TFmode, "__gcc_qsub");
12277 set_optab_libfunc (smul_optab, TFmode, "__gcc_qmul");
12278 set_optab_libfunc (sdiv_optab, TFmode, "__gcc_qdiv");
12280 if (!(TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)))
12282 set_optab_libfunc (neg_optab, TFmode, "__gcc_qneg");
12283 set_optab_libfunc (eq_optab, TFmode, "__gcc_qeq");
12284 set_optab_libfunc (ne_optab, TFmode, "__gcc_qne");
12285 set_optab_libfunc (gt_optab, TFmode, "__gcc_qgt");
12286 set_optab_libfunc (ge_optab, TFmode, "__gcc_qge");
12287 set_optab_libfunc (lt_optab, TFmode, "__gcc_qlt");
12288 set_optab_libfunc (le_optab, TFmode, "__gcc_qle");
12290 set_conv_libfunc (sext_optab, TFmode, SFmode, "__gcc_stoq");
12291 set_conv_libfunc (sext_optab, TFmode, DFmode, "__gcc_dtoq");
12292 set_conv_libfunc (trunc_optab, SFmode, TFmode, "__gcc_qtos");
12293 set_conv_libfunc (trunc_optab, DFmode, TFmode, "__gcc_qtod");
12294 set_conv_libfunc (sfix_optab, SImode, TFmode, "__gcc_qtoi");
12295 set_conv_libfunc (ufix_optab, SImode, TFmode, "__gcc_qtou");
12296 set_conv_libfunc (sfloat_optab, TFmode, SImode, "__gcc_itoq");
12297 set_conv_libfunc (ufloat_optab, TFmode, SImode, "__gcc_utoq");
12300 if (!(TARGET_HARD_FLOAT && TARGET_FPRS))
12301 set_optab_libfunc (unord_optab, TFmode, "__gcc_qunord");
12303 else
12305 set_optab_libfunc (add_optab, TFmode, "_xlqadd");
12306 set_optab_libfunc (sub_optab, TFmode, "_xlqsub");
12307 set_optab_libfunc (smul_optab, TFmode, "_xlqmul");
12308 set_optab_libfunc (sdiv_optab, TFmode, "_xlqdiv");
12310 else
12312 /* 32-bit SVR4 quad floating point routines. */
12314 set_optab_libfunc (add_optab, TFmode, "_q_add");
12315 set_optab_libfunc (sub_optab, TFmode, "_q_sub");
12316 set_optab_libfunc (neg_optab, TFmode, "_q_neg");
12317 set_optab_libfunc (smul_optab, TFmode, "_q_mul");
12318 set_optab_libfunc (sdiv_optab, TFmode, "_q_div");
12319 if (TARGET_PPC_GPOPT || TARGET_POWER2)
12320 set_optab_libfunc (sqrt_optab, TFmode, "_q_sqrt");
12322 set_optab_libfunc (eq_optab, TFmode, "_q_feq");
12323 set_optab_libfunc (ne_optab, TFmode, "_q_fne");
12324 set_optab_libfunc (gt_optab, TFmode, "_q_fgt");
12325 set_optab_libfunc (ge_optab, TFmode, "_q_fge");
12326 set_optab_libfunc (lt_optab, TFmode, "_q_flt");
12327 set_optab_libfunc (le_optab, TFmode, "_q_fle");
12329 set_conv_libfunc (sext_optab, TFmode, SFmode, "_q_stoq");
12330 set_conv_libfunc (sext_optab, TFmode, DFmode, "_q_dtoq");
12331 set_conv_libfunc (trunc_optab, SFmode, TFmode, "_q_qtos");
12332 set_conv_libfunc (trunc_optab, DFmode, TFmode, "_q_qtod");
12333 set_conv_libfunc (sfix_optab, SImode, TFmode, "_q_qtoi");
12334 set_conv_libfunc (ufix_optab, SImode, TFmode, "_q_qtou");
12335 set_conv_libfunc (sfloat_optab, TFmode, SImode, "_q_itoq");
12336 set_conv_libfunc (ufloat_optab, TFmode, SImode, "_q_utoq");
12341 /* Expand a block clear operation, and return 1 if successful. Return 0
12342 if we should let the compiler generate normal code.
12344 operands[0] is the destination
12345 operands[1] is the length
12346 operands[3] is the alignment */
12349 expand_block_clear (rtx operands[])
12351 rtx orig_dest = operands[0];
12352 rtx bytes_rtx = operands[1];
12353 rtx align_rtx = operands[3];
12354 bool constp = (GET_CODE (bytes_rtx) == CONST_INT);
12355 HOST_WIDE_INT align;
12356 HOST_WIDE_INT bytes;
12357 int offset;
12358 int clear_bytes;
12359 int clear_step;
12361 /* If this is not a fixed size move, just call memcpy */
12362 if (! constp)
12363 return 0;
12365 /* This must be a fixed size alignment */
12366 gcc_assert (GET_CODE (align_rtx) == CONST_INT);
12367 align = INTVAL (align_rtx) * BITS_PER_UNIT;
12369 /* Anything to clear? */
12370 bytes = INTVAL (bytes_rtx);
12371 if (bytes <= 0)
12372 return 1;
12374 /* Use the builtin memset after a point, to avoid huge code bloat.
12375 When optimize_size, avoid any significant code bloat; calling
12376 memset is about 4 instructions, so allow for one instruction to
12377 load zero and three to do clearing. */
12378 if (TARGET_ALTIVEC && align >= 128)
12379 clear_step = 16;
12380 else if (TARGET_POWERPC64 && align >= 32)
12381 clear_step = 8;
12382 else if (TARGET_SPE && align >= 64)
12383 clear_step = 8;
12384 else
12385 clear_step = 4;
12387 if (optimize_size && bytes > 3 * clear_step)
12388 return 0;
12389 if (! optimize_size && bytes > 8 * clear_step)
12390 return 0;
12392 for (offset = 0; bytes > 0; offset += clear_bytes, bytes -= clear_bytes)
12394 enum machine_mode mode = BLKmode;
12395 rtx dest;
12397 if (bytes >= 16 && TARGET_ALTIVEC && align >= 128)
12399 clear_bytes = 16;
12400 mode = V4SImode;
12402 else if (bytes >= 8 && TARGET_SPE && align >= 64)
12404 clear_bytes = 8;
12405 mode = V2SImode;
12407 else if (bytes >= 8 && TARGET_POWERPC64
12408 /* 64-bit loads and stores require word-aligned
12409 displacements. */
12410 && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
12412 clear_bytes = 8;
12413 mode = DImode;
12415 else if (bytes >= 4 && (align >= 32 || !STRICT_ALIGNMENT))
12416 { /* move 4 bytes */
12417 clear_bytes = 4;
12418 mode = SImode;
12420 else if (bytes >= 2 && (align >= 16 || !STRICT_ALIGNMENT))
12421 { /* move 2 bytes */
12422 clear_bytes = 2;
12423 mode = HImode;
12425 else /* move 1 byte at a time */
12427 clear_bytes = 1;
12428 mode = QImode;
12431 dest = adjust_address (orig_dest, mode, offset);
12433 emit_move_insn (dest, CONST0_RTX (mode));
12436 return 1;
12440 /* Expand a block move operation, and return 1 if successful. Return 0
12441 if we should let the compiler generate normal code.
12443 operands[0] is the destination
12444 operands[1] is the source
12445 operands[2] is the length
12446 operands[3] is the alignment */
12448 #define MAX_MOVE_REG 4
12451 expand_block_move (rtx operands[])
12453 rtx orig_dest = operands[0];
12454 rtx orig_src = operands[1];
12455 rtx bytes_rtx = operands[2];
12456 rtx align_rtx = operands[3];
12457 int constp = (GET_CODE (bytes_rtx) == CONST_INT);
12458 int align;
12459 int bytes;
12460 int offset;
12461 int move_bytes;
12462 rtx stores[MAX_MOVE_REG];
12463 int num_reg = 0;
12465 /* If this is not a fixed size move, just call memcpy */
12466 if (! constp)
12467 return 0;
12469 /* This must be a fixed size alignment */
12470 gcc_assert (GET_CODE (align_rtx) == CONST_INT);
12471 align = INTVAL (align_rtx) * BITS_PER_UNIT;
12473 /* Anything to move? */
12474 bytes = INTVAL (bytes_rtx);
12475 if (bytes <= 0)
12476 return 1;
12478 /* store_one_arg depends on expand_block_move to handle at least the size of
12479 reg_parm_stack_space. */
12480 if (bytes > (TARGET_POWERPC64 ? 64 : 32))
12481 return 0;
12483 for (offset = 0; bytes > 0; offset += move_bytes, bytes -= move_bytes)
12485 union {
12486 rtx (*movmemsi) (rtx, rtx, rtx, rtx);
12487 rtx (*mov) (rtx, rtx);
12488 } gen_func;
12489 enum machine_mode mode = BLKmode;
12490 rtx src, dest;
12492 /* Altivec first, since it will be faster than a string move
12493 when it applies, and usually not significantly larger. */
12494 if (TARGET_ALTIVEC && bytes >= 16 && align >= 128)
12496 move_bytes = 16;
12497 mode = V4SImode;
12498 gen_func.mov = gen_movv4si;
12500 else if (TARGET_SPE && bytes >= 8 && align >= 64)
12502 move_bytes = 8;
12503 mode = V2SImode;
12504 gen_func.mov = gen_movv2si;
12506 else if (TARGET_STRING
12507 && bytes > 24 /* move up to 32 bytes at a time */
12508 && ! fixed_regs[5]
12509 && ! fixed_regs[6]
12510 && ! fixed_regs[7]
12511 && ! fixed_regs[8]
12512 && ! fixed_regs[9]
12513 && ! fixed_regs[10]
12514 && ! fixed_regs[11]
12515 && ! fixed_regs[12])
12517 move_bytes = (bytes > 32) ? 32 : bytes;
12518 gen_func.movmemsi = gen_movmemsi_8reg;
12520 else if (TARGET_STRING
12521 && bytes > 16 /* move up to 24 bytes at a time */
12522 && ! fixed_regs[5]
12523 && ! fixed_regs[6]
12524 && ! fixed_regs[7]
12525 && ! fixed_regs[8]
12526 && ! fixed_regs[9]
12527 && ! fixed_regs[10])
12529 move_bytes = (bytes > 24) ? 24 : bytes;
12530 gen_func.movmemsi = gen_movmemsi_6reg;
12532 else if (TARGET_STRING
12533 && bytes > 8 /* move up to 16 bytes at a time */
12534 && ! fixed_regs[5]
12535 && ! fixed_regs[6]
12536 && ! fixed_regs[7]
12537 && ! fixed_regs[8])
12539 move_bytes = (bytes > 16) ? 16 : bytes;
12540 gen_func.movmemsi = gen_movmemsi_4reg;
12542 else if (bytes >= 8 && TARGET_POWERPC64
12543 /* 64-bit loads and stores require word-aligned
12544 displacements. */
12545 && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
12547 move_bytes = 8;
12548 mode = DImode;
12549 gen_func.mov = gen_movdi;
12551 else if (TARGET_STRING && bytes > 4 && !TARGET_POWERPC64)
12552 { /* move up to 8 bytes at a time */
12553 move_bytes = (bytes > 8) ? 8 : bytes;
12554 gen_func.movmemsi = gen_movmemsi_2reg;
12556 else if (bytes >= 4 && (align >= 32 || !STRICT_ALIGNMENT))
12557 { /* move 4 bytes */
12558 move_bytes = 4;
12559 mode = SImode;
12560 gen_func.mov = gen_movsi;
12562 else if (bytes >= 2 && (align >= 16 || !STRICT_ALIGNMENT))
12563 { /* move 2 bytes */
12564 move_bytes = 2;
12565 mode = HImode;
12566 gen_func.mov = gen_movhi;
12568 else if (TARGET_STRING && bytes > 1)
12569 { /* move up to 4 bytes at a time */
12570 move_bytes = (bytes > 4) ? 4 : bytes;
12571 gen_func.movmemsi = gen_movmemsi_1reg;
12573 else /* move 1 byte at a time */
12575 move_bytes = 1;
12576 mode = QImode;
12577 gen_func.mov = gen_movqi;
12580 src = adjust_address (orig_src, mode, offset);
12581 dest = adjust_address (orig_dest, mode, offset);
12583 if (mode != BLKmode)
12585 rtx tmp_reg = gen_reg_rtx (mode);
12587 emit_insn ((*gen_func.mov) (tmp_reg, src));
12588 stores[num_reg++] = (*gen_func.mov) (dest, tmp_reg);
12591 if (mode == BLKmode || num_reg >= MAX_MOVE_REG || bytes == move_bytes)
12593 int i;
12594 for (i = 0; i < num_reg; i++)
12595 emit_insn (stores[i]);
12596 num_reg = 0;
12599 if (mode == BLKmode)
12601 /* Move the address into scratch registers. The movmemsi
12602 patterns require zero offset. */
12603 if (!REG_P (XEXP (src, 0)))
12605 rtx src_reg = copy_addr_to_reg (XEXP (src, 0));
12606 src = replace_equiv_address (src, src_reg);
12608 set_mem_size (src, GEN_INT (move_bytes));
12610 if (!REG_P (XEXP (dest, 0)))
12612 rtx dest_reg = copy_addr_to_reg (XEXP (dest, 0));
12613 dest = replace_equiv_address (dest, dest_reg);
12615 set_mem_size (dest, GEN_INT (move_bytes));
12617 emit_insn ((*gen_func.movmemsi) (dest, src,
12618 GEN_INT (move_bytes & 31),
12619 align_rtx));
12623 return 1;
12627 /* Return a string to perform a load_multiple operation.
12628 operands[0] is the vector.
12629 operands[1] is the source address.
12630 operands[2] is the first destination register. */
12632 const char *
12633 rs6000_output_load_multiple (rtx operands[3])
12635 /* We have to handle the case where the pseudo used to contain the address
12636 is assigned to one of the output registers. */
12637 int i, j;
12638 int words = XVECLEN (operands[0], 0);
12639 rtx xop[10];
12641 if (XVECLEN (operands[0], 0) == 1)
12642 return "{l|lwz} %2,0(%1)";
12644 for (i = 0; i < words; i++)
12645 if (refers_to_regno_p (REGNO (operands[2]) + i,
12646 REGNO (operands[2]) + i + 1, operands[1], 0))
12648 if (i == words-1)
12650 xop[0] = GEN_INT (4 * (words-1));
12651 xop[1] = operands[1];
12652 xop[2] = operands[2];
12653 output_asm_insn ("{lsi|lswi} %2,%1,%0\n\t{l|lwz} %1,%0(%1)", xop);
12654 return "";
12656 else if (i == 0)
12658 xop[0] = GEN_INT (4 * (words-1));
12659 xop[1] = operands[1];
12660 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + 1);
12661 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);
12662 return "";
12664 else
12666 for (j = 0; j < words; j++)
12667 if (j != i)
12669 xop[0] = GEN_INT (j * 4);
12670 xop[1] = operands[1];
12671 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + j);
12672 output_asm_insn ("{l|lwz} %2,%0(%1)", xop);
12674 xop[0] = GEN_INT (i * 4);
12675 xop[1] = operands[1];
12676 output_asm_insn ("{l|lwz} %1,%0(%1)", xop);
12677 return "";
12681 return "{lsi|lswi} %2,%1,%N0";
12685 /* A validation routine: say whether CODE, a condition code, and MODE
12686 match. The other alternatives either don't make sense or should
12687 never be generated. */
12689 void
12690 validate_condition_mode (enum rtx_code code, enum machine_mode mode)
12692 gcc_assert ((GET_RTX_CLASS (code) == RTX_COMPARE
12693 || GET_RTX_CLASS (code) == RTX_COMM_COMPARE)
12694 && GET_MODE_CLASS (mode) == MODE_CC);
12696 /* These don't make sense. */
12697 gcc_assert ((code != GT && code != LT && code != GE && code != LE)
12698 || mode != CCUNSmode);
12700 gcc_assert ((code != GTU && code != LTU && code != GEU && code != LEU)
12701 || mode == CCUNSmode);
12703 gcc_assert (mode == CCFPmode
12704 || (code != ORDERED && code != UNORDERED
12705 && code != UNEQ && code != LTGT
12706 && code != UNGT && code != UNLT
12707 && code != UNGE && code != UNLE));
12709 /* These should never be generated except for
12710 flag_finite_math_only. */
12711 gcc_assert (mode != CCFPmode
12712 || flag_finite_math_only
12713 || (code != LE && code != GE
12714 && code != UNEQ && code != LTGT
12715 && code != UNGT && code != UNLT));
12717 /* These are invalid; the information is not there. */
12718 gcc_assert (mode != CCEQmode || code == EQ || code == NE);
12722 /* Return 1 if ANDOP is a mask that has no bits on that are not in the
12723 mask required to convert the result of a rotate insn into a shift
12724 left insn of SHIFTOP bits. Both are known to be SImode CONST_INT. */
12727 includes_lshift_p (rtx shiftop, rtx andop)
12729 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
12731 shift_mask <<= INTVAL (shiftop);
12733 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
12736 /* Similar, but for right shift. */
12739 includes_rshift_p (rtx shiftop, rtx andop)
12741 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
12743 shift_mask >>= INTVAL (shiftop);
12745 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
12748 /* Return 1 if ANDOP is a mask suitable for use with an rldic insn
12749 to perform a left shift. It must have exactly SHIFTOP least
12750 significant 0's, then one or more 1's, then zero or more 0's. */
12753 includes_rldic_lshift_p (rtx shiftop, rtx andop)
12755 if (GET_CODE (andop) == CONST_INT)
12757 HOST_WIDE_INT c, lsb, shift_mask;
12759 c = INTVAL (andop);
12760 if (c == 0 || c == ~0)
12761 return 0;
12763 shift_mask = ~0;
12764 shift_mask <<= INTVAL (shiftop);
12766 /* Find the least significant one bit. */
12767 lsb = c & -c;
12769 /* It must coincide with the LSB of the shift mask. */
12770 if (-lsb != shift_mask)
12771 return 0;
12773 /* Invert to look for the next transition (if any). */
12774 c = ~c;
12776 /* Remove the low group of ones (originally low group of zeros). */
12777 c &= -lsb;
12779 /* Again find the lsb, and check we have all 1's above. */
12780 lsb = c & -c;
12781 return c == -lsb;
12783 else if (GET_CODE (andop) == CONST_DOUBLE
12784 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
12786 HOST_WIDE_INT low, high, lsb;
12787 HOST_WIDE_INT shift_mask_low, shift_mask_high;
12789 low = CONST_DOUBLE_LOW (andop);
12790 if (HOST_BITS_PER_WIDE_INT < 64)
12791 high = CONST_DOUBLE_HIGH (andop);
12793 if ((low == 0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == 0))
12794 || (low == ~0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0)))
12795 return 0;
12797 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
12799 shift_mask_high = ~0;
12800 if (INTVAL (shiftop) > 32)
12801 shift_mask_high <<= INTVAL (shiftop) - 32;
12803 lsb = high & -high;
12805 if (-lsb != shift_mask_high || INTVAL (shiftop) < 32)
12806 return 0;
12808 high = ~high;
12809 high &= -lsb;
12811 lsb = high & -high;
12812 return high == -lsb;
12815 shift_mask_low = ~0;
12816 shift_mask_low <<= INTVAL (shiftop);
12818 lsb = low & -low;
12820 if (-lsb != shift_mask_low)
12821 return 0;
12823 if (HOST_BITS_PER_WIDE_INT < 64)
12824 high = ~high;
12825 low = ~low;
12826 low &= -lsb;
12828 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
12830 lsb = high & -high;
12831 return high == -lsb;
12834 lsb = low & -low;
12835 return low == -lsb && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0);
12837 else
12838 return 0;
12841 /* Return 1 if ANDOP is a mask suitable for use with an rldicr insn
12842 to perform a left shift. It must have SHIFTOP or more least
12843 significant 0's, with the remainder of the word 1's. */
12846 includes_rldicr_lshift_p (rtx shiftop, rtx andop)
12848 if (GET_CODE (andop) == CONST_INT)
12850 HOST_WIDE_INT c, lsb, shift_mask;
12852 shift_mask = ~0;
12853 shift_mask <<= INTVAL (shiftop);
12854 c = INTVAL (andop);
12856 /* Find the least significant one bit. */
12857 lsb = c & -c;
12859 /* It must be covered by the shift mask.
12860 This test also rejects c == 0. */
12861 if ((lsb & shift_mask) == 0)
12862 return 0;
12864 /* Check we have all 1's above the transition, and reject all 1's. */
12865 return c == -lsb && lsb != 1;
12867 else if (GET_CODE (andop) == CONST_DOUBLE
12868 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
12870 HOST_WIDE_INT low, lsb, shift_mask_low;
12872 low = CONST_DOUBLE_LOW (andop);
12874 if (HOST_BITS_PER_WIDE_INT < 64)
12876 HOST_WIDE_INT high, shift_mask_high;
12878 high = CONST_DOUBLE_HIGH (andop);
12880 if (low == 0)
12882 shift_mask_high = ~0;
12883 if (INTVAL (shiftop) > 32)
12884 shift_mask_high <<= INTVAL (shiftop) - 32;
12886 lsb = high & -high;
12888 if ((lsb & shift_mask_high) == 0)
12889 return 0;
12891 return high == -lsb;
12893 if (high != ~0)
12894 return 0;
12897 shift_mask_low = ~0;
12898 shift_mask_low <<= INTVAL (shiftop);
12900 lsb = low & -low;
12902 if ((lsb & shift_mask_low) == 0)
12903 return 0;
12905 return low == -lsb && lsb != 1;
12907 else
12908 return 0;
12911 /* Return 1 if operands will generate a valid arguments to rlwimi
12912 instruction for insert with right shift in 64-bit mode. The mask may
12913 not start on the first bit or stop on the last bit because wrap-around
12914 effects of instruction do not correspond to semantics of RTL insn. */
12917 insvdi_rshift_rlwimi_p (rtx sizeop, rtx startop, rtx shiftop)
12919 if (INTVAL (startop) > 32
12920 && INTVAL (startop) < 64
12921 && INTVAL (sizeop) > 1
12922 && INTVAL (sizeop) + INTVAL (startop) < 64
12923 && INTVAL (shiftop) > 0
12924 && INTVAL (sizeop) + INTVAL (shiftop) < 32
12925 && (64 - (INTVAL (shiftop) & 63)) >= INTVAL (sizeop))
12926 return 1;
12928 return 0;
12931 /* Return 1 if REGNO (reg1) == REGNO (reg2) - 1 making them candidates
12932 for lfq and stfq insns iff the registers are hard registers. */
12935 registers_ok_for_quad_peep (rtx reg1, rtx reg2)
12937 /* We might have been passed a SUBREG. */
12938 if (GET_CODE (reg1) != REG || GET_CODE (reg2) != REG)
12939 return 0;
12941 /* We might have been passed non floating point registers. */
12942 if (!FP_REGNO_P (REGNO (reg1))
12943 || !FP_REGNO_P (REGNO (reg2)))
12944 return 0;
12946 return (REGNO (reg1) == REGNO (reg2) - 1);
12949 /* Return 1 if addr1 and addr2 are suitable for lfq or stfq insn.
12950 addr1 and addr2 must be in consecutive memory locations
12951 (addr2 == addr1 + 8). */
12954 mems_ok_for_quad_peep (rtx mem1, rtx mem2)
12956 rtx addr1, addr2;
12957 unsigned int reg1, reg2;
12958 int offset1, offset2;
12960 /* The mems cannot be volatile. */
12961 if (MEM_VOLATILE_P (mem1) || MEM_VOLATILE_P (mem2))
12962 return 0;
12964 addr1 = XEXP (mem1, 0);
12965 addr2 = XEXP (mem2, 0);
12967 /* Extract an offset (if used) from the first addr. */
12968 if (GET_CODE (addr1) == PLUS)
12970 /* If not a REG, return zero. */
12971 if (GET_CODE (XEXP (addr1, 0)) != REG)
12972 return 0;
12973 else
12975 reg1 = REGNO (XEXP (addr1, 0));
12976 /* The offset must be constant! */
12977 if (GET_CODE (XEXP (addr1, 1)) != CONST_INT)
12978 return 0;
12979 offset1 = INTVAL (XEXP (addr1, 1));
12982 else if (GET_CODE (addr1) != REG)
12983 return 0;
12984 else
12986 reg1 = REGNO (addr1);
12987 /* This was a simple (mem (reg)) expression. Offset is 0. */
12988 offset1 = 0;
12991 /* And now for the second addr. */
12992 if (GET_CODE (addr2) == PLUS)
12994 /* If not a REG, return zero. */
12995 if (GET_CODE (XEXP (addr2, 0)) != REG)
12996 return 0;
12997 else
12999 reg2 = REGNO (XEXP (addr2, 0));
13000 /* The offset must be constant. */
13001 if (GET_CODE (XEXP (addr2, 1)) != CONST_INT)
13002 return 0;
13003 offset2 = INTVAL (XEXP (addr2, 1));
13006 else if (GET_CODE (addr2) != REG)
13007 return 0;
13008 else
13010 reg2 = REGNO (addr2);
13011 /* This was a simple (mem (reg)) expression. Offset is 0. */
13012 offset2 = 0;
13015 /* Both of these must have the same base register. */
13016 if (reg1 != reg2)
13017 return 0;
13019 /* The offset for the second addr must be 8 more than the first addr. */
13020 if (offset2 != offset1 + 8)
13021 return 0;
13023 /* All the tests passed. addr1 and addr2 are valid for lfq or stfq
13024 instructions. */
13025 return 1;
13030 rs6000_secondary_memory_needed_rtx (enum machine_mode mode)
13032 static bool eliminated = false;
13033 rtx ret;
13035 if (mode != SDmode)
13036 ret = assign_stack_local (mode, GET_MODE_SIZE (mode), 0);
13037 else
13039 rtx mem = cfun->machine->sdmode_stack_slot;
13040 gcc_assert (mem != NULL_RTX);
13042 if (!eliminated)
13044 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
13045 cfun->machine->sdmode_stack_slot = mem;
13046 eliminated = true;
13048 ret = mem;
13051 if (TARGET_DEBUG_ADDR)
13053 fprintf (stderr, "\nrs6000_secondary_memory_needed_rtx, mode %s, rtx:\n",
13054 GET_MODE_NAME (mode));
13055 if (!ret)
13056 fprintf (stderr, "\tNULL_RTX\n");
13057 else
13058 debug_rtx (ret);
13061 return ret;
13064 static tree
13065 rs6000_check_sdmode (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
13067 /* Don't walk into types. */
13068 if (*tp == NULL_TREE || *tp == error_mark_node || TYPE_P (*tp))
13070 *walk_subtrees = 0;
13071 return NULL_TREE;
13074 switch (TREE_CODE (*tp))
13076 case VAR_DECL:
13077 case PARM_DECL:
13078 case FIELD_DECL:
13079 case RESULT_DECL:
13080 case SSA_NAME:
13081 case REAL_CST:
13082 case INDIRECT_REF:
13083 case ALIGN_INDIRECT_REF:
13084 case MISALIGNED_INDIRECT_REF:
13085 case VIEW_CONVERT_EXPR:
13086 if (TYPE_MODE (TREE_TYPE (*tp)) == SDmode)
13087 return *tp;
13088 break;
13089 default:
13090 break;
13093 return NULL_TREE;
13096 enum reload_reg_type {
13097 GPR_REGISTER_TYPE,
13098 VECTOR_REGISTER_TYPE,
13099 OTHER_REGISTER_TYPE
13102 static enum reload_reg_type
13103 rs6000_reload_register_type (enum reg_class rclass)
13105 switch (rclass)
13107 case GENERAL_REGS:
13108 case BASE_REGS:
13109 return GPR_REGISTER_TYPE;
13111 case FLOAT_REGS:
13112 case ALTIVEC_REGS:
13113 case VSX_REGS:
13114 return VECTOR_REGISTER_TYPE;
13116 default:
13117 return OTHER_REGISTER_TYPE;
13121 /* Inform reload about cases where moving X with a mode MODE to a register in
13122 RCLASS requires an extra scratch or immediate register. Return the class
13123 needed for the immediate register.
13125 For VSX and Altivec, we may need a register to convert sp+offset into
13126 reg+sp. */
13128 static enum reg_class
13129 rs6000_secondary_reload (bool in_p,
13130 rtx x,
13131 enum reg_class rclass,
13132 enum machine_mode mode,
13133 secondary_reload_info *sri)
13135 enum reg_class ret = ALL_REGS;
13136 enum insn_code icode;
13137 bool default_p = false;
13139 sri->icode = CODE_FOR_nothing;
13141 /* Convert vector loads and stores into gprs to use an additional base
13142 register. */
13143 icode = rs6000_vector_reload[mode][in_p != false];
13144 if (icode != CODE_FOR_nothing)
13146 ret = NO_REGS;
13147 sri->icode = CODE_FOR_nothing;
13148 sri->extra_cost = 0;
13150 if (GET_CODE (x) == MEM)
13152 rtx addr = XEXP (x, 0);
13154 /* Loads to and stores from gprs can do reg+offset, and wouldn't need
13155 an extra register in that case, but it would need an extra
13156 register if the addressing is reg+reg or (reg+reg)&(-16). */
13157 if (rclass == GENERAL_REGS || rclass == BASE_REGS)
13159 if (!legitimate_indirect_address_p (addr, false)
13160 && !rs6000_legitimate_offset_address_p (TImode, addr, false))
13162 sri->icode = icode;
13163 /* account for splitting the loads, and converting the
13164 address from reg+reg to reg. */
13165 sri->extra_cost = (((TARGET_64BIT) ? 3 : 5)
13166 + ((GET_CODE (addr) == AND) ? 1 : 0));
13169 /* Loads to and stores from vector registers can only do reg+reg
13170 addressing. Altivec registers can also do (reg+reg)&(-16). */
13171 else if (rclass == VSX_REGS || rclass == ALTIVEC_REGS
13172 || rclass == FLOAT_REGS || rclass == NO_REGS)
13174 if (!VECTOR_MEM_ALTIVEC_P (mode)
13175 && GET_CODE (addr) == AND
13176 && GET_CODE (XEXP (addr, 1)) == CONST_INT
13177 && INTVAL (XEXP (addr, 1)) == -16
13178 && (legitimate_indirect_address_p (XEXP (addr, 0), false)
13179 || legitimate_indexed_address_p (XEXP (addr, 0), false)))
13181 sri->icode = icode;
13182 sri->extra_cost = ((GET_CODE (XEXP (addr, 0)) == PLUS)
13183 ? 2 : 1);
13185 else if (!legitimate_indirect_address_p (addr, false)
13186 && (rclass == NO_REGS
13187 || !legitimate_indexed_address_p (addr, false)))
13189 sri->icode = icode;
13190 sri->extra_cost = 1;
13192 else
13193 icode = CODE_FOR_nothing;
13195 /* Any other loads, including to pseudo registers which haven't been
13196 assigned to a register yet, default to require a scratch
13197 register. */
13198 else
13200 sri->icode = icode;
13201 sri->extra_cost = 2;
13204 else if (REG_P (x))
13206 int regno = true_regnum (x);
13208 icode = CODE_FOR_nothing;
13209 if (regno < 0 || regno >= FIRST_PSEUDO_REGISTER)
13210 default_p = true;
13211 else
13213 enum reg_class xclass = REGNO_REG_CLASS (regno);
13214 enum reload_reg_type rtype1 = rs6000_reload_register_type (rclass);
13215 enum reload_reg_type rtype2 = rs6000_reload_register_type (xclass);
13217 /* If memory is needed, use default_secondary_reload to create the
13218 stack slot. */
13219 if (rtype1 != rtype2 || rtype1 == OTHER_REGISTER_TYPE)
13220 default_p = true;
13221 else
13222 ret = NO_REGS;
13225 else
13226 default_p = true;
13228 else
13229 default_p = true;
13231 if (default_p)
13232 ret = default_secondary_reload (in_p, x, rclass, mode, sri);
13234 gcc_assert (ret != ALL_REGS);
13236 if (TARGET_DEBUG_ADDR)
13238 fprintf (stderr,
13239 "\nrs6000_secondary_reload, return %s, in_p = %s, rclass = %s, "
13240 "mode = %s",
13241 reg_class_names[ret],
13242 in_p ? "true" : "false",
13243 reg_class_names[rclass],
13244 GET_MODE_NAME (mode));
13246 if (default_p)
13247 fprintf (stderr, ", default secondary reload");
13249 if (sri->icode != CODE_FOR_nothing)
13250 fprintf (stderr, ", reload func = %s, extra cost = %d\n",
13251 insn_data[sri->icode].name, sri->extra_cost);
13252 else
13253 fprintf (stderr, "\n");
13255 debug_rtx (x);
13258 return ret;
13261 /* Fixup reload addresses for Altivec or VSX loads/stores to change SP+offset
13262 to SP+reg addressing. */
13264 void
13265 rs6000_secondary_reload_inner (rtx reg, rtx mem, rtx scratch, bool store_p)
13267 int regno = true_regnum (reg);
13268 enum machine_mode mode = GET_MODE (reg);
13269 enum reg_class rclass;
13270 rtx addr;
13271 rtx and_op2 = NULL_RTX;
13272 rtx addr_op1;
13273 rtx addr_op2;
13274 rtx scratch_or_premodify = scratch;
13275 rtx and_rtx;
13276 rtx cc_clobber;
13278 if (TARGET_DEBUG_ADDR)
13280 fprintf (stderr, "\nrs6000_secondary_reload_inner, type = %s\n",
13281 store_p ? "store" : "load");
13282 fprintf (stderr, "reg:\n");
13283 debug_rtx (reg);
13284 fprintf (stderr, "mem:\n");
13285 debug_rtx (mem);
13286 fprintf (stderr, "scratch:\n");
13287 debug_rtx (scratch);
13290 gcc_assert (regno >= 0 && regno < FIRST_PSEUDO_REGISTER);
13291 gcc_assert (GET_CODE (mem) == MEM);
13292 rclass = REGNO_REG_CLASS (regno);
13293 addr = XEXP (mem, 0);
13295 switch (rclass)
13297 /* GPRs can handle reg + small constant, all other addresses need to use
13298 the scratch register. */
13299 case GENERAL_REGS:
13300 case BASE_REGS:
13301 if (GET_CODE (addr) == AND)
13303 and_op2 = XEXP (addr, 1);
13304 addr = XEXP (addr, 0);
13307 if (GET_CODE (addr) == PRE_MODIFY)
13309 scratch_or_premodify = XEXP (addr, 0);
13310 gcc_assert (REG_P (scratch_or_premodify));
13311 gcc_assert (GET_CODE (XEXP (addr, 1)) == PLUS);
13312 addr = XEXP (addr, 1);
13315 if (GET_CODE (addr) == PLUS
13316 && (!rs6000_legitimate_offset_address_p (TImode, addr, false)
13317 || and_op2 != NULL_RTX))
13319 addr_op1 = XEXP (addr, 0);
13320 addr_op2 = XEXP (addr, 1);
13321 gcc_assert (legitimate_indirect_address_p (addr_op1, false));
13323 if (!REG_P (addr_op2)
13324 && (GET_CODE (addr_op2) != CONST_INT
13325 || !satisfies_constraint_I (addr_op2)))
13327 if (TARGET_DEBUG_ADDR)
13329 fprintf (stderr,
13330 "\nMove plus addr to register %s, mode = %s: ",
13331 rs6000_reg_names[REGNO (scratch)],
13332 GET_MODE_NAME (mode));
13333 debug_rtx (addr_op2);
13335 rs6000_emit_move (scratch, addr_op2, Pmode);
13336 addr_op2 = scratch;
13339 emit_insn (gen_rtx_SET (VOIDmode,
13340 scratch_or_premodify,
13341 gen_rtx_PLUS (Pmode,
13342 addr_op1,
13343 addr_op2)));
13345 addr = scratch_or_premodify;
13346 scratch_or_premodify = scratch;
13348 else if (!legitimate_indirect_address_p (addr, false)
13349 && !rs6000_legitimate_offset_address_p (TImode, addr, false))
13351 if (TARGET_DEBUG_ADDR)
13353 fprintf (stderr, "\nMove addr to register %s, mode = %s: ",
13354 rs6000_reg_names[REGNO (scratch_or_premodify)],
13355 GET_MODE_NAME (mode));
13356 debug_rtx (addr);
13358 rs6000_emit_move (scratch_or_premodify, addr, Pmode);
13359 addr = scratch_or_premodify;
13360 scratch_or_premodify = scratch;
13362 break;
13364 /* Float/Altivec registers can only handle reg+reg addressing. Move
13365 other addresses into a scratch register. */
13366 case FLOAT_REGS:
13367 case VSX_REGS:
13368 case ALTIVEC_REGS:
13370 /* With float regs, we need to handle the AND ourselves, since we can't
13371 use the Altivec instruction with an implicit AND -16. Allow scalar
13372 loads to float registers to use reg+offset even if VSX. */
13373 if (GET_CODE (addr) == AND
13374 && (rclass != ALTIVEC_REGS || GET_MODE_SIZE (mode) != 16
13375 || GET_CODE (XEXP (addr, 1)) != CONST_INT
13376 || INTVAL (XEXP (addr, 1)) != -16
13377 || !VECTOR_MEM_ALTIVEC_P (mode)))
13379 and_op2 = XEXP (addr, 1);
13380 addr = XEXP (addr, 0);
13383 /* If we aren't using a VSX load, save the PRE_MODIFY register and use it
13384 as the address later. */
13385 if (GET_CODE (addr) == PRE_MODIFY
13386 && (!VECTOR_MEM_VSX_P (mode)
13387 || and_op2 != NULL_RTX
13388 || !legitimate_indexed_address_p (XEXP (addr, 1), false)))
13390 scratch_or_premodify = XEXP (addr, 0);
13391 gcc_assert (legitimate_indirect_address_p (scratch_or_premodify,
13392 false));
13393 gcc_assert (GET_CODE (XEXP (addr, 1)) == PLUS);
13394 addr = XEXP (addr, 1);
13397 if (legitimate_indirect_address_p (addr, false) /* reg */
13398 || legitimate_indexed_address_p (addr, false) /* reg+reg */
13399 || GET_CODE (addr) == PRE_MODIFY /* VSX pre-modify */
13400 || (GET_CODE (addr) == AND /* Altivec memory */
13401 && GET_CODE (XEXP (addr, 1)) == CONST_INT
13402 && INTVAL (XEXP (addr, 1)) == -16
13403 && VECTOR_MEM_ALTIVEC_P (mode))
13404 || (rclass == FLOAT_REGS /* legacy float mem */
13405 && GET_MODE_SIZE (mode) == 8
13406 && and_op2 == NULL_RTX
13407 && scratch_or_premodify == scratch
13408 && rs6000_legitimate_offset_address_p (mode, addr, false)))
13411 else if (GET_CODE (addr) == PLUS)
13413 addr_op1 = XEXP (addr, 0);
13414 addr_op2 = XEXP (addr, 1);
13415 gcc_assert (REG_P (addr_op1));
13417 if (TARGET_DEBUG_ADDR)
13419 fprintf (stderr, "\nMove plus addr to register %s, mode = %s: ",
13420 rs6000_reg_names[REGNO (scratch)], GET_MODE_NAME (mode));
13421 debug_rtx (addr_op2);
13423 rs6000_emit_move (scratch, addr_op2, Pmode);
13424 emit_insn (gen_rtx_SET (VOIDmode,
13425 scratch_or_premodify,
13426 gen_rtx_PLUS (Pmode,
13427 addr_op1,
13428 scratch)));
13429 addr = scratch_or_premodify;
13430 scratch_or_premodify = scratch;
13433 else if (GET_CODE (addr) == SYMBOL_REF || GET_CODE (addr) == CONST
13434 || GET_CODE (addr) == CONST_INT || REG_P (addr))
13436 if (TARGET_DEBUG_ADDR)
13438 fprintf (stderr, "\nMove addr to register %s, mode = %s: ",
13439 rs6000_reg_names[REGNO (scratch_or_premodify)],
13440 GET_MODE_NAME (mode));
13441 debug_rtx (addr);
13444 rs6000_emit_move (scratch_or_premodify, addr, Pmode);
13445 addr = scratch_or_premodify;
13446 scratch_or_premodify = scratch;
13449 else
13450 gcc_unreachable ();
13452 break;
13454 default:
13455 gcc_unreachable ();
13458 /* If the original address involved a pre-modify that we couldn't use the VSX
13459 memory instruction with update, and we haven't taken care of already,
13460 store the address in the pre-modify register and use that as the
13461 address. */
13462 if (scratch_or_premodify != scratch && scratch_or_premodify != addr)
13464 emit_insn (gen_rtx_SET (VOIDmode, scratch_or_premodify, addr));
13465 addr = scratch_or_premodify;
13468 /* If the original address involved an AND -16 and we couldn't use an ALTIVEC
13469 memory instruction, recreate the AND now, including the clobber which is
13470 generated by the general ANDSI3/ANDDI3 patterns for the
13471 andi. instruction. */
13472 if (and_op2 != NULL_RTX)
13474 if (! legitimate_indirect_address_p (addr, false))
13476 emit_insn (gen_rtx_SET (VOIDmode, scratch, addr));
13477 addr = scratch;
13480 if (TARGET_DEBUG_ADDR)
13482 fprintf (stderr, "\nAnd addr to register %s, mode = %s: ",
13483 rs6000_reg_names[REGNO (scratch)], GET_MODE_NAME (mode));
13484 debug_rtx (and_op2);
13487 and_rtx = gen_rtx_SET (VOIDmode,
13488 scratch,
13489 gen_rtx_AND (Pmode,
13490 addr,
13491 and_op2));
13493 cc_clobber = gen_rtx_CLOBBER (CCmode, gen_rtx_SCRATCH (CCmode));
13494 emit_insn (gen_rtx_PARALLEL (VOIDmode,
13495 gen_rtvec (2, and_rtx, cc_clobber)));
13496 addr = scratch;
13499 /* Adjust the address if it changed. */
13500 if (addr != XEXP (mem, 0))
13502 mem = change_address (mem, mode, addr);
13503 if (TARGET_DEBUG_ADDR)
13504 fprintf (stderr, "\nrs6000_secondary_reload_inner, mem adjusted.\n");
13507 /* Now create the move. */
13508 if (store_p)
13509 emit_insn (gen_rtx_SET (VOIDmode, mem, reg));
13510 else
13511 emit_insn (gen_rtx_SET (VOIDmode, reg, mem));
13513 return;
13516 /* Target hook to return the cover classes for Integrated Register Allocator.
13517 Cover classes is a set of non-intersected register classes covering all hard
13518 registers used for register allocation purpose. Any move between two
13519 registers of a cover class should be cheaper than load or store of the
13520 registers. The value is array of register classes with LIM_REG_CLASSES used
13521 as the end marker.
13523 We need two IRA_COVER_CLASSES, one for pre-VSX, and the other for VSX to
13524 account for the Altivec and Floating registers being subsets of the VSX
13525 register set under VSX, but distinct register sets on pre-VSX machines. */
13527 static const enum reg_class *
13528 rs6000_ira_cover_classes (void)
13530 static const enum reg_class cover_pre_vsx[] = IRA_COVER_CLASSES_PRE_VSX;
13531 static const enum reg_class cover_vsx[] = IRA_COVER_CLASSES_VSX;
13533 return (TARGET_VSX) ? cover_vsx : cover_pre_vsx;
13536 /* Allocate a 64-bit stack slot to be used for copying SDmode
13537 values through if this function has any SDmode references. */
13539 static void
13540 rs6000_alloc_sdmode_stack_slot (void)
13542 tree t;
13543 basic_block bb;
13544 gimple_stmt_iterator gsi;
13546 gcc_assert (cfun->machine->sdmode_stack_slot == NULL_RTX);
13548 FOR_EACH_BB (bb)
13549 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
13551 tree ret = walk_gimple_op (gsi_stmt (gsi), rs6000_check_sdmode, NULL);
13552 if (ret)
13554 rtx stack = assign_stack_local (DDmode, GET_MODE_SIZE (DDmode), 0);
13555 cfun->machine->sdmode_stack_slot = adjust_address_nv (stack,
13556 SDmode, 0);
13557 return;
13561 /* Check for any SDmode parameters of the function. */
13562 for (t = DECL_ARGUMENTS (cfun->decl); t; t = TREE_CHAIN (t))
13564 if (TREE_TYPE (t) == error_mark_node)
13565 continue;
13567 if (TYPE_MODE (TREE_TYPE (t)) == SDmode
13568 || TYPE_MODE (DECL_ARG_TYPE (t)) == SDmode)
13570 rtx stack = assign_stack_local (DDmode, GET_MODE_SIZE (DDmode), 0);
13571 cfun->machine->sdmode_stack_slot = adjust_address_nv (stack,
13572 SDmode, 0);
13573 return;
13578 static void
13579 rs6000_instantiate_decls (void)
13581 if (cfun->machine->sdmode_stack_slot != NULL_RTX)
13582 instantiate_decl_rtl (cfun->machine->sdmode_stack_slot);
13585 /* Given an rtx X being reloaded into a reg required to be
13586 in class CLASS, return the class of reg to actually use.
13587 In general this is just CLASS; but on some machines
13588 in some cases it is preferable to use a more restrictive class.
13590 On the RS/6000, we have to return NO_REGS when we want to reload a
13591 floating-point CONST_DOUBLE to force it to be copied to memory.
13593 We also don't want to reload integer values into floating-point
13594 registers if we can at all help it. In fact, this can
13595 cause reload to die, if it tries to generate a reload of CTR
13596 into a FP register and discovers it doesn't have the memory location
13597 required.
13599 ??? Would it be a good idea to have reload do the converse, that is
13600 try to reload floating modes into FP registers if possible?
13603 static enum reg_class
13604 rs6000_preferred_reload_class (rtx x, enum reg_class rclass)
13606 enum machine_mode mode = GET_MODE (x);
13608 if (VECTOR_UNIT_VSX_P (mode)
13609 && x == CONST0_RTX (mode) && VSX_REG_CLASS_P (rclass))
13610 return rclass;
13612 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode)
13613 && (rclass == ALTIVEC_REGS || rclass == VSX_REGS)
13614 && easy_vector_constant (x, mode))
13615 return ALTIVEC_REGS;
13617 if (CONSTANT_P (x) && reg_classes_intersect_p (rclass, FLOAT_REGS))
13618 return NO_REGS;
13620 if (GET_MODE_CLASS (mode) == MODE_INT && rclass == NON_SPECIAL_REGS)
13621 return GENERAL_REGS;
13623 /* For VSX, prefer the traditional registers for DF if the address is of the
13624 form reg+offset because we can use the non-VSX loads. Prefer the Altivec
13625 registers if Altivec is handling the vector operations (i.e. V16QI, V8HI,
13626 and V4SI). */
13627 if (rclass == VSX_REGS && VECTOR_MEM_VSX_P (mode))
13629 if (mode == DFmode && GET_CODE (x) == MEM)
13631 rtx addr = XEXP (x, 0);
13633 if (legitimate_indirect_address_p (addr, false)) /* reg */
13634 return VSX_REGS;
13636 if (legitimate_indexed_address_p (addr, false)) /* reg+reg */
13637 return VSX_REGS;
13639 if (GET_CODE (addr) == PRE_MODIFY
13640 && legitimate_indexed_address_p (XEXP (addr, 0), false))
13641 return VSX_REGS;
13643 return FLOAT_REGS;
13646 if (VECTOR_UNIT_ALTIVEC_P (mode))
13647 return ALTIVEC_REGS;
13649 return rclass;
13652 return rclass;
13655 /* Debug version of rs6000_preferred_reload_class. */
13656 static enum reg_class
13657 rs6000_debug_preferred_reload_class (rtx x, enum reg_class rclass)
13659 enum reg_class ret = rs6000_preferred_reload_class (x, rclass);
13661 fprintf (stderr,
13662 "\nrs6000_preferred_reload_class, return %s, rclass = %s, "
13663 "mode = %s, x:\n",
13664 reg_class_names[ret], reg_class_names[rclass],
13665 GET_MODE_NAME (GET_MODE (x)));
13666 debug_rtx (x);
13668 return ret;
13671 /* If we are copying between FP or AltiVec registers and anything else, we need
13672 a memory location. The exception is when we are targeting ppc64 and the
13673 move to/from fpr to gpr instructions are available. Also, under VSX, you
13674 can copy vector registers from the FP register set to the Altivec register
13675 set and vice versa. */
13677 static bool
13678 rs6000_secondary_memory_needed (enum reg_class class1,
13679 enum reg_class class2,
13680 enum machine_mode mode)
13682 if (class1 == class2)
13683 return false;
13685 /* Under VSX, there are 3 register classes that values could be in (VSX_REGS,
13686 ALTIVEC_REGS, and FLOAT_REGS). We don't need to use memory to copy
13687 between these classes. But we need memory for other things that can go in
13688 FLOAT_REGS like SFmode. */
13689 if (TARGET_VSX
13690 && (VECTOR_MEM_VSX_P (mode) || VECTOR_UNIT_VSX_P (mode))
13691 && (class1 == VSX_REGS || class1 == ALTIVEC_REGS
13692 || class1 == FLOAT_REGS))
13693 return (class2 != VSX_REGS && class2 != ALTIVEC_REGS
13694 && class2 != FLOAT_REGS);
13696 if (class1 == VSX_REGS || class2 == VSX_REGS)
13697 return true;
13699 if (class1 == FLOAT_REGS
13700 && (!TARGET_MFPGPR || !TARGET_POWERPC64
13701 || ((mode != DFmode)
13702 && (mode != DDmode)
13703 && (mode != DImode))))
13704 return true;
13706 if (class2 == FLOAT_REGS
13707 && (!TARGET_MFPGPR || !TARGET_POWERPC64
13708 || ((mode != DFmode)
13709 && (mode != DDmode)
13710 && (mode != DImode))))
13711 return true;
13713 if (class1 == ALTIVEC_REGS || class2 == ALTIVEC_REGS)
13714 return true;
13716 return false;
13719 /* Debug version of rs6000_secondary_memory_needed. */
13720 static bool
13721 rs6000_debug_secondary_memory_needed (enum reg_class class1,
13722 enum reg_class class2,
13723 enum machine_mode mode)
13725 bool ret = rs6000_secondary_memory_needed (class1, class2, mode);
13727 fprintf (stderr,
13728 "rs6000_secondary_memory_needed, return: %s, class1 = %s, "
13729 "class2 = %s, mode = %s\n",
13730 ret ? "true" : "false", reg_class_names[class1],
13731 reg_class_names[class2], GET_MODE_NAME (mode));
13733 return ret;
13736 /* Return the register class of a scratch register needed to copy IN into
13737 or out of a register in RCLASS in MODE. If it can be done directly,
13738 NO_REGS is returned. */
13740 static enum reg_class
13741 rs6000_secondary_reload_class (enum reg_class rclass, enum machine_mode mode,
13742 rtx in)
13744 int regno;
13746 if (TARGET_ELF || (DEFAULT_ABI == ABI_DARWIN
13747 #if TARGET_MACHO
13748 && MACHOPIC_INDIRECT
13749 #endif
13752 /* We cannot copy a symbolic operand directly into anything
13753 other than BASE_REGS for TARGET_ELF. So indicate that a
13754 register from BASE_REGS is needed as an intermediate
13755 register.
13757 On Darwin, pic addresses require a load from memory, which
13758 needs a base register. */
13759 if (rclass != BASE_REGS
13760 && (GET_CODE (in) == SYMBOL_REF
13761 || GET_CODE (in) == HIGH
13762 || GET_CODE (in) == LABEL_REF
13763 || GET_CODE (in) == CONST))
13764 return BASE_REGS;
13767 if (GET_CODE (in) == REG)
13769 regno = REGNO (in);
13770 if (regno >= FIRST_PSEUDO_REGISTER)
13772 regno = true_regnum (in);
13773 if (regno >= FIRST_PSEUDO_REGISTER)
13774 regno = -1;
13777 else if (GET_CODE (in) == SUBREG)
13779 regno = true_regnum (in);
13780 if (regno >= FIRST_PSEUDO_REGISTER)
13781 regno = -1;
13783 else
13784 regno = -1;
13786 /* We can place anything into GENERAL_REGS and can put GENERAL_REGS
13787 into anything. */
13788 if (rclass == GENERAL_REGS || rclass == BASE_REGS
13789 || (regno >= 0 && INT_REGNO_P (regno)))
13790 return NO_REGS;
13792 /* Constants, memory, and FP registers can go into FP registers. */
13793 if ((regno == -1 || FP_REGNO_P (regno))
13794 && (rclass == FLOAT_REGS || rclass == NON_SPECIAL_REGS))
13795 return (mode != SDmode) ? NO_REGS : GENERAL_REGS;
13797 /* Memory, and FP/altivec registers can go into fp/altivec registers under
13798 VSX. */
13799 if (TARGET_VSX
13800 && (regno == -1 || VSX_REGNO_P (regno))
13801 && VSX_REG_CLASS_P (rclass))
13802 return NO_REGS;
13804 /* Memory, and AltiVec registers can go into AltiVec registers. */
13805 if ((regno == -1 || ALTIVEC_REGNO_P (regno))
13806 && rclass == ALTIVEC_REGS)
13807 return NO_REGS;
13809 /* We can copy among the CR registers. */
13810 if ((rclass == CR_REGS || rclass == CR0_REGS)
13811 && regno >= 0 && CR_REGNO_P (regno))
13812 return NO_REGS;
13814 /* Otherwise, we need GENERAL_REGS. */
13815 return GENERAL_REGS;
13818 /* Debug version of rs6000_secondary_reload_class. */
13819 static enum reg_class
13820 rs6000_debug_secondary_reload_class (enum reg_class rclass,
13821 enum machine_mode mode, rtx in)
13823 enum reg_class ret = rs6000_secondary_reload_class (rclass, mode, in);
13824 fprintf (stderr,
13825 "\nrs6000_secondary_reload_class, return %s, rclass = %s, "
13826 "mode = %s, input rtx:\n",
13827 reg_class_names[ret], reg_class_names[rclass],
13828 GET_MODE_NAME (mode));
13829 debug_rtx (in);
13831 return ret;
13834 /* Return nonzero if for CLASS a mode change from FROM to TO is invalid. */
13836 static bool
13837 rs6000_cannot_change_mode_class (enum machine_mode from,
13838 enum machine_mode to,
13839 enum reg_class rclass)
13841 unsigned from_size = GET_MODE_SIZE (from);
13842 unsigned to_size = GET_MODE_SIZE (to);
13844 if (from_size != to_size)
13846 enum reg_class xclass = (TARGET_VSX) ? VSX_REGS : FLOAT_REGS;
13847 return ((from_size < 8 || to_size < 8 || TARGET_IEEEQUAD)
13848 && reg_classes_intersect_p (xclass, rclass));
13851 if (TARGET_E500_DOUBLE
13852 && ((((to) == DFmode) + ((from) == DFmode)) == 1
13853 || (((to) == TFmode) + ((from) == TFmode)) == 1
13854 || (((to) == DDmode) + ((from) == DDmode)) == 1
13855 || (((to) == TDmode) + ((from) == TDmode)) == 1
13856 || (((to) == DImode) + ((from) == DImode)) == 1))
13857 return true;
13859 /* Since the VSX register set includes traditional floating point registers
13860 and altivec registers, just check for the size being different instead of
13861 trying to check whether the modes are vector modes. Otherwise it won't
13862 allow say DF and DI to change classes. */
13863 if (TARGET_VSX && VSX_REG_CLASS_P (rclass))
13864 return (from_size != 8 && from_size != 16);
13866 if (TARGET_ALTIVEC && rclass == ALTIVEC_REGS
13867 && (ALTIVEC_VECTOR_MODE (from) + ALTIVEC_VECTOR_MODE (to)) == 1)
13868 return true;
13870 if (TARGET_SPE && (SPE_VECTOR_MODE (from) + SPE_VECTOR_MODE (to)) == 1
13871 && reg_classes_intersect_p (GENERAL_REGS, rclass))
13872 return true;
13874 return false;
13877 /* Debug version of rs6000_cannot_change_mode_class. */
13878 static bool
13879 rs6000_debug_cannot_change_mode_class (enum machine_mode from,
13880 enum machine_mode to,
13881 enum reg_class rclass)
13883 bool ret = rs6000_cannot_change_mode_class (from, to, rclass);
13885 fprintf (stderr,
13886 "rs6000_cannot_change_mode_class, return %s, from = %s, "
13887 "to = %s, rclass = %s\n",
13888 ret ? "true" : "false",
13889 GET_MODE_NAME (from), GET_MODE_NAME (to),
13890 reg_class_names[rclass]);
13892 return ret;
13895 /* Given a comparison operation, return the bit number in CCR to test. We
13896 know this is a valid comparison.
13898 SCC_P is 1 if this is for an scc. That means that %D will have been
13899 used instead of %C, so the bits will be in different places.
13901 Return -1 if OP isn't a valid comparison for some reason. */
13904 ccr_bit (rtx op, int scc_p)
13906 enum rtx_code code = GET_CODE (op);
13907 enum machine_mode cc_mode;
13908 int cc_regnum;
13909 int base_bit;
13910 rtx reg;
13912 if (!COMPARISON_P (op))
13913 return -1;
13915 reg = XEXP (op, 0);
13917 gcc_assert (GET_CODE (reg) == REG && CR_REGNO_P (REGNO (reg)));
13919 cc_mode = GET_MODE (reg);
13920 cc_regnum = REGNO (reg);
13921 base_bit = 4 * (cc_regnum - CR0_REGNO);
13923 validate_condition_mode (code, cc_mode);
13925 /* When generating a sCOND operation, only positive conditions are
13926 allowed. */
13927 gcc_assert (!scc_p
13928 || code == EQ || code == GT || code == LT || code == UNORDERED
13929 || code == GTU || code == LTU);
13931 switch (code)
13933 case NE:
13934 return scc_p ? base_bit + 3 : base_bit + 2;
13935 case EQ:
13936 return base_bit + 2;
13937 case GT: case GTU: case UNLE:
13938 return base_bit + 1;
13939 case LT: case LTU: case UNGE:
13940 return base_bit;
13941 case ORDERED: case UNORDERED:
13942 return base_bit + 3;
13944 case GE: case GEU:
13945 /* If scc, we will have done a cror to put the bit in the
13946 unordered position. So test that bit. For integer, this is ! LT
13947 unless this is an scc insn. */
13948 return scc_p ? base_bit + 3 : base_bit;
13950 case LE: case LEU:
13951 return scc_p ? base_bit + 3 : base_bit + 1;
13953 default:
13954 gcc_unreachable ();
13958 /* Return the GOT register. */
13961 rs6000_got_register (rtx value ATTRIBUTE_UNUSED)
13963 /* The second flow pass currently (June 1999) can't update
13964 regs_ever_live without disturbing other parts of the compiler, so
13965 update it here to make the prolog/epilogue code happy. */
13966 if (!can_create_pseudo_p ()
13967 && !df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM))
13968 df_set_regs_ever_live (RS6000_PIC_OFFSET_TABLE_REGNUM, true);
13970 crtl->uses_pic_offset_table = 1;
13972 return pic_offset_table_rtx;
13975 /* Function to init struct machine_function.
13976 This will be called, via a pointer variable,
13977 from push_function_context. */
13979 static struct machine_function *
13980 rs6000_init_machine_status (void)
13982 return GGC_CNEW (machine_function);
13985 /* These macros test for integers and extract the low-order bits. */
13986 #define INT_P(X) \
13987 ((GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST_DOUBLE) \
13988 && GET_MODE (X) == VOIDmode)
13990 #define INT_LOWPART(X) \
13991 (GET_CODE (X) == CONST_INT ? INTVAL (X) : CONST_DOUBLE_LOW (X))
13994 extract_MB (rtx op)
13996 int i;
13997 unsigned long val = INT_LOWPART (op);
13999 /* If the high bit is zero, the value is the first 1 bit we find
14000 from the left. */
14001 if ((val & 0x80000000) == 0)
14003 gcc_assert (val & 0xffffffff);
14005 i = 1;
14006 while (((val <<= 1) & 0x80000000) == 0)
14007 ++i;
14008 return i;
14011 /* If the high bit is set and the low bit is not, or the mask is all
14012 1's, the value is zero. */
14013 if ((val & 1) == 0 || (val & 0xffffffff) == 0xffffffff)
14014 return 0;
14016 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
14017 from the right. */
14018 i = 31;
14019 while (((val >>= 1) & 1) != 0)
14020 --i;
14022 return i;
14026 extract_ME (rtx op)
14028 int i;
14029 unsigned long val = INT_LOWPART (op);
14031 /* If the low bit is zero, the value is the first 1 bit we find from
14032 the right. */
14033 if ((val & 1) == 0)
14035 gcc_assert (val & 0xffffffff);
14037 i = 30;
14038 while (((val >>= 1) & 1) == 0)
14039 --i;
14041 return i;
14044 /* If the low bit is set and the high bit is not, or the mask is all
14045 1's, the value is 31. */
14046 if ((val & 0x80000000) == 0 || (val & 0xffffffff) == 0xffffffff)
14047 return 31;
14049 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
14050 from the left. */
14051 i = 0;
14052 while (((val <<= 1) & 0x80000000) != 0)
14053 ++i;
14055 return i;
14058 /* Locate some local-dynamic symbol still in use by this function
14059 so that we can print its name in some tls_ld pattern. */
14061 static const char *
14062 rs6000_get_some_local_dynamic_name (void)
14064 rtx insn;
14066 if (cfun->machine->some_ld_name)
14067 return cfun->machine->some_ld_name;
14069 for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
14070 if (INSN_P (insn)
14071 && for_each_rtx (&PATTERN (insn),
14072 rs6000_get_some_local_dynamic_name_1, 0))
14073 return cfun->machine->some_ld_name;
14075 gcc_unreachable ();
14078 /* Helper function for rs6000_get_some_local_dynamic_name. */
14080 static int
14081 rs6000_get_some_local_dynamic_name_1 (rtx *px, void *data ATTRIBUTE_UNUSED)
14083 rtx x = *px;
14085 if (GET_CODE (x) == SYMBOL_REF)
14087 const char *str = XSTR (x, 0);
14088 if (SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_DYNAMIC)
14090 cfun->machine->some_ld_name = str;
14091 return 1;
14095 return 0;
14098 /* Write out a function code label. */
14100 void
14101 rs6000_output_function_entry (FILE *file, const char *fname)
14103 if (fname[0] != '.')
14105 switch (DEFAULT_ABI)
14107 default:
14108 gcc_unreachable ();
14110 case ABI_AIX:
14111 if (DOT_SYMBOLS)
14112 putc ('.', file);
14113 else
14114 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "L.");
14115 break;
14117 case ABI_V4:
14118 case ABI_DARWIN:
14119 break;
14122 if (TARGET_AIX)
14123 RS6000_OUTPUT_BASENAME (file, fname);
14124 else
14125 assemble_name (file, fname);
14128 /* Print an operand. Recognize special options, documented below. */
14130 #if TARGET_ELF
14131 #define SMALL_DATA_RELOC ((rs6000_sdata == SDATA_EABI) ? "sda21" : "sdarel")
14132 #define SMALL_DATA_REG ((rs6000_sdata == SDATA_EABI) ? 0 : 13)
14133 #else
14134 #define SMALL_DATA_RELOC "sda21"
14135 #define SMALL_DATA_REG 0
14136 #endif
14138 void
14139 print_operand (FILE *file, rtx x, int code)
14141 int i;
14142 HOST_WIDE_INT val;
14143 unsigned HOST_WIDE_INT uval;
14145 switch (code)
14147 case '.':
14148 /* Write out an instruction after the call which may be replaced
14149 with glue code by the loader. This depends on the AIX version. */
14150 asm_fprintf (file, RS6000_CALL_GLUE);
14151 return;
14153 /* %a is output_address. */
14155 case 'A':
14156 /* If X is a constant integer whose low-order 5 bits are zero,
14157 write 'l'. Otherwise, write 'r'. This is a kludge to fix a bug
14158 in the AIX assembler where "sri" with a zero shift count
14159 writes a trash instruction. */
14160 if (GET_CODE (x) == CONST_INT && (INTVAL (x) & 31) == 0)
14161 putc ('l', file);
14162 else
14163 putc ('r', file);
14164 return;
14166 case 'b':
14167 /* If constant, low-order 16 bits of constant, unsigned.
14168 Otherwise, write normally. */
14169 if (INT_P (x))
14170 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 0xffff);
14171 else
14172 print_operand (file, x, 0);
14173 return;
14175 case 'B':
14176 /* If the low-order bit is zero, write 'r'; otherwise, write 'l'
14177 for 64-bit mask direction. */
14178 putc (((INT_LOWPART (x) & 1) == 0 ? 'r' : 'l'), file);
14179 return;
14181 /* %c is output_addr_const if a CONSTANT_ADDRESS_P, otherwise
14182 output_operand. */
14184 case 'c':
14185 /* X is a CR register. Print the number of the GT bit of the CR. */
14186 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
14187 output_operand_lossage ("invalid %%c value");
14188 else
14189 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 1);
14190 return;
14192 case 'D':
14193 /* Like 'J' but get to the GT bit only. */
14194 gcc_assert (GET_CODE (x) == REG);
14196 /* Bit 1 is GT bit. */
14197 i = 4 * (REGNO (x) - CR0_REGNO) + 1;
14199 /* Add one for shift count in rlinm for scc. */
14200 fprintf (file, "%d", i + 1);
14201 return;
14203 case 'E':
14204 /* X is a CR register. Print the number of the EQ bit of the CR */
14205 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
14206 output_operand_lossage ("invalid %%E value");
14207 else
14208 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 2);
14209 return;
14211 case 'f':
14212 /* X is a CR register. Print the shift count needed to move it
14213 to the high-order four bits. */
14214 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
14215 output_operand_lossage ("invalid %%f value");
14216 else
14217 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO));
14218 return;
14220 case 'F':
14221 /* Similar, but print the count for the rotate in the opposite
14222 direction. */
14223 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
14224 output_operand_lossage ("invalid %%F value");
14225 else
14226 fprintf (file, "%d", 32 - 4 * (REGNO (x) - CR0_REGNO));
14227 return;
14229 case 'G':
14230 /* X is a constant integer. If it is negative, print "m",
14231 otherwise print "z". This is to make an aze or ame insn. */
14232 if (GET_CODE (x) != CONST_INT)
14233 output_operand_lossage ("invalid %%G value");
14234 else if (INTVAL (x) >= 0)
14235 putc ('z', file);
14236 else
14237 putc ('m', file);
14238 return;
14240 case 'h':
14241 /* If constant, output low-order five bits. Otherwise, write
14242 normally. */
14243 if (INT_P (x))
14244 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 31);
14245 else
14246 print_operand (file, x, 0);
14247 return;
14249 case 'H':
14250 /* If constant, output low-order six bits. Otherwise, write
14251 normally. */
14252 if (INT_P (x))
14253 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 63);
14254 else
14255 print_operand (file, x, 0);
14256 return;
14258 case 'I':
14259 /* Print `i' if this is a constant, else nothing. */
14260 if (INT_P (x))
14261 putc ('i', file);
14262 return;
14264 case 'j':
14265 /* Write the bit number in CCR for jump. */
14266 i = ccr_bit (x, 0);
14267 if (i == -1)
14268 output_operand_lossage ("invalid %%j code");
14269 else
14270 fprintf (file, "%d", i);
14271 return;
14273 case 'J':
14274 /* Similar, but add one for shift count in rlinm for scc and pass
14275 scc flag to `ccr_bit'. */
14276 i = ccr_bit (x, 1);
14277 if (i == -1)
14278 output_operand_lossage ("invalid %%J code");
14279 else
14280 /* If we want bit 31, write a shift count of zero, not 32. */
14281 fprintf (file, "%d", i == 31 ? 0 : i + 1);
14282 return;
14284 case 'k':
14285 /* X must be a constant. Write the 1's complement of the
14286 constant. */
14287 if (! INT_P (x))
14288 output_operand_lossage ("invalid %%k value");
14289 else
14290 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ~ INT_LOWPART (x));
14291 return;
14293 case 'K':
14294 /* X must be a symbolic constant on ELF. Write an
14295 expression suitable for an 'addi' that adds in the low 16
14296 bits of the MEM. */
14297 if (GET_CODE (x) != CONST)
14299 print_operand_address (file, x);
14300 fputs ("@l", file);
14302 else
14304 if (GET_CODE (XEXP (x, 0)) != PLUS
14305 || (GET_CODE (XEXP (XEXP (x, 0), 0)) != SYMBOL_REF
14306 && GET_CODE (XEXP (XEXP (x, 0), 0)) != LABEL_REF)
14307 || GET_CODE (XEXP (XEXP (x, 0), 1)) != CONST_INT)
14308 output_operand_lossage ("invalid %%K value");
14309 print_operand_address (file, XEXP (XEXP (x, 0), 0));
14310 fputs ("@l", file);
14311 /* For GNU as, there must be a non-alphanumeric character
14312 between 'l' and the number. The '-' is added by
14313 print_operand() already. */
14314 if (INTVAL (XEXP (XEXP (x, 0), 1)) >= 0)
14315 fputs ("+", file);
14316 print_operand (file, XEXP (XEXP (x, 0), 1), 0);
14318 return;
14320 /* %l is output_asm_label. */
14322 case 'L':
14323 /* Write second word of DImode or DFmode reference. Works on register
14324 or non-indexed memory only. */
14325 if (GET_CODE (x) == REG)
14326 fputs (reg_names[REGNO (x) + 1], file);
14327 else if (GET_CODE (x) == MEM)
14329 /* Handle possible auto-increment. Since it is pre-increment and
14330 we have already done it, we can just use an offset of word. */
14331 if (GET_CODE (XEXP (x, 0)) == PRE_INC
14332 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
14333 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
14334 UNITS_PER_WORD));
14335 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
14336 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
14337 UNITS_PER_WORD));
14338 else
14339 output_address (XEXP (adjust_address_nv (x, SImode,
14340 UNITS_PER_WORD),
14341 0));
14343 if (small_data_operand (x, GET_MODE (x)))
14344 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
14345 reg_names[SMALL_DATA_REG]);
14347 return;
14349 case 'm':
14350 /* MB value for a mask operand. */
14351 if (! mask_operand (x, SImode))
14352 output_operand_lossage ("invalid %%m value");
14354 fprintf (file, "%d", extract_MB (x));
14355 return;
14357 case 'M':
14358 /* ME value for a mask operand. */
14359 if (! mask_operand (x, SImode))
14360 output_operand_lossage ("invalid %%M value");
14362 fprintf (file, "%d", extract_ME (x));
14363 return;
14365 /* %n outputs the negative of its operand. */
14367 case 'N':
14368 /* Write the number of elements in the vector times 4. */
14369 if (GET_CODE (x) != PARALLEL)
14370 output_operand_lossage ("invalid %%N value");
14371 else
14372 fprintf (file, "%d", XVECLEN (x, 0) * 4);
14373 return;
14375 case 'O':
14376 /* Similar, but subtract 1 first. */
14377 if (GET_CODE (x) != PARALLEL)
14378 output_operand_lossage ("invalid %%O value");
14379 else
14380 fprintf (file, "%d", (XVECLEN (x, 0) - 1) * 4);
14381 return;
14383 case 'p':
14384 /* X is a CONST_INT that is a power of two. Output the logarithm. */
14385 if (! INT_P (x)
14386 || INT_LOWPART (x) < 0
14387 || (i = exact_log2 (INT_LOWPART (x))) < 0)
14388 output_operand_lossage ("invalid %%p value");
14389 else
14390 fprintf (file, "%d", i);
14391 return;
14393 case 'P':
14394 /* The operand must be an indirect memory reference. The result
14395 is the register name. */
14396 if (GET_CODE (x) != MEM || GET_CODE (XEXP (x, 0)) != REG
14397 || REGNO (XEXP (x, 0)) >= 32)
14398 output_operand_lossage ("invalid %%P value");
14399 else
14400 fputs (reg_names[REGNO (XEXP (x, 0))], file);
14401 return;
14403 case 'q':
14404 /* This outputs the logical code corresponding to a boolean
14405 expression. The expression may have one or both operands
14406 negated (if one, only the first one). For condition register
14407 logical operations, it will also treat the negated
14408 CR codes as NOTs, but not handle NOTs of them. */
14410 const char *const *t = 0;
14411 const char *s;
14412 enum rtx_code code = GET_CODE (x);
14413 static const char * const tbl[3][3] = {
14414 { "and", "andc", "nor" },
14415 { "or", "orc", "nand" },
14416 { "xor", "eqv", "xor" } };
14418 if (code == AND)
14419 t = tbl[0];
14420 else if (code == IOR)
14421 t = tbl[1];
14422 else if (code == XOR)
14423 t = tbl[2];
14424 else
14425 output_operand_lossage ("invalid %%q value");
14427 if (GET_CODE (XEXP (x, 0)) != NOT)
14428 s = t[0];
14429 else
14431 if (GET_CODE (XEXP (x, 1)) == NOT)
14432 s = t[2];
14433 else
14434 s = t[1];
14437 fputs (s, file);
14439 return;
14441 case 'Q':
14442 if (TARGET_MFCRF)
14443 fputc (',', file);
14444 /* FALLTHRU */
14445 else
14446 return;
14448 case 'R':
14449 /* X is a CR register. Print the mask for `mtcrf'. */
14450 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
14451 output_operand_lossage ("invalid %%R value");
14452 else
14453 fprintf (file, "%d", 128 >> (REGNO (x) - CR0_REGNO));
14454 return;
14456 case 's':
14457 /* Low 5 bits of 32 - value */
14458 if (! INT_P (x))
14459 output_operand_lossage ("invalid %%s value");
14460 else
14461 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (32 - INT_LOWPART (x)) & 31);
14462 return;
14464 case 'S':
14465 /* PowerPC64 mask position. All 0's is excluded.
14466 CONST_INT 32-bit mask is considered sign-extended so any
14467 transition must occur within the CONST_INT, not on the boundary. */
14468 if (! mask64_operand (x, DImode))
14469 output_operand_lossage ("invalid %%S value");
14471 uval = INT_LOWPART (x);
14473 if (uval & 1) /* Clear Left */
14475 #if HOST_BITS_PER_WIDE_INT > 64
14476 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
14477 #endif
14478 i = 64;
14480 else /* Clear Right */
14482 uval = ~uval;
14483 #if HOST_BITS_PER_WIDE_INT > 64
14484 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
14485 #endif
14486 i = 63;
14488 while (uval != 0)
14489 --i, uval >>= 1;
14490 gcc_assert (i >= 0);
14491 fprintf (file, "%d", i);
14492 return;
14494 case 't':
14495 /* Like 'J' but get to the OVERFLOW/UNORDERED bit. */
14496 gcc_assert (GET_CODE (x) == REG && GET_MODE (x) == CCmode);
14498 /* Bit 3 is OV bit. */
14499 i = 4 * (REGNO (x) - CR0_REGNO) + 3;
14501 /* If we want bit 31, write a shift count of zero, not 32. */
14502 fprintf (file, "%d", i == 31 ? 0 : i + 1);
14503 return;
14505 case 'T':
14506 /* Print the symbolic name of a branch target register. */
14507 if (GET_CODE (x) != REG || (REGNO (x) != LR_REGNO
14508 && REGNO (x) != CTR_REGNO))
14509 output_operand_lossage ("invalid %%T value");
14510 else if (REGNO (x) == LR_REGNO)
14511 fputs (TARGET_NEW_MNEMONICS ? "lr" : "r", file);
14512 else
14513 fputs ("ctr", file);
14514 return;
14516 case 'u':
14517 /* High-order 16 bits of constant for use in unsigned operand. */
14518 if (! INT_P (x))
14519 output_operand_lossage ("invalid %%u value");
14520 else
14521 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
14522 (INT_LOWPART (x) >> 16) & 0xffff);
14523 return;
14525 case 'v':
14526 /* High-order 16 bits of constant for use in signed operand. */
14527 if (! INT_P (x))
14528 output_operand_lossage ("invalid %%v value");
14529 else
14530 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
14531 (INT_LOWPART (x) >> 16) & 0xffff);
14532 return;
14534 case 'U':
14535 /* Print `u' if this has an auto-increment or auto-decrement. */
14536 if (GET_CODE (x) == MEM
14537 && (GET_CODE (XEXP (x, 0)) == PRE_INC
14538 || GET_CODE (XEXP (x, 0)) == PRE_DEC
14539 || GET_CODE (XEXP (x, 0)) == PRE_MODIFY))
14540 putc ('u', file);
14541 return;
14543 case 'V':
14544 /* Print the trap code for this operand. */
14545 switch (GET_CODE (x))
14547 case EQ:
14548 fputs ("eq", file); /* 4 */
14549 break;
14550 case NE:
14551 fputs ("ne", file); /* 24 */
14552 break;
14553 case LT:
14554 fputs ("lt", file); /* 16 */
14555 break;
14556 case LE:
14557 fputs ("le", file); /* 20 */
14558 break;
14559 case GT:
14560 fputs ("gt", file); /* 8 */
14561 break;
14562 case GE:
14563 fputs ("ge", file); /* 12 */
14564 break;
14565 case LTU:
14566 fputs ("llt", file); /* 2 */
14567 break;
14568 case LEU:
14569 fputs ("lle", file); /* 6 */
14570 break;
14571 case GTU:
14572 fputs ("lgt", file); /* 1 */
14573 break;
14574 case GEU:
14575 fputs ("lge", file); /* 5 */
14576 break;
14577 default:
14578 gcc_unreachable ();
14580 break;
14582 case 'w':
14583 /* If constant, low-order 16 bits of constant, signed. Otherwise, write
14584 normally. */
14585 if (INT_P (x))
14586 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
14587 ((INT_LOWPART (x) & 0xffff) ^ 0x8000) - 0x8000);
14588 else
14589 print_operand (file, x, 0);
14590 return;
14592 case 'W':
14593 /* MB value for a PowerPC64 rldic operand. */
14594 val = (GET_CODE (x) == CONST_INT
14595 ? INTVAL (x) : CONST_DOUBLE_HIGH (x));
14597 if (val < 0)
14598 i = -1;
14599 else
14600 for (i = 0; i < HOST_BITS_PER_WIDE_INT; i++)
14601 if ((val <<= 1) < 0)
14602 break;
14604 #if HOST_BITS_PER_WIDE_INT == 32
14605 if (GET_CODE (x) == CONST_INT && i >= 0)
14606 i += 32; /* zero-extend high-part was all 0's */
14607 else if (GET_CODE (x) == CONST_DOUBLE && i == 32)
14609 val = CONST_DOUBLE_LOW (x);
14611 gcc_assert (val);
14612 if (val < 0)
14613 --i;
14614 else
14615 for ( ; i < 64; i++)
14616 if ((val <<= 1) < 0)
14617 break;
14619 #endif
14621 fprintf (file, "%d", i + 1);
14622 return;
14624 case 'x':
14625 /* X is a FPR or Altivec register used in a VSX context. */
14626 if (GET_CODE (x) != REG || !VSX_REGNO_P (REGNO (x)))
14627 output_operand_lossage ("invalid %%x value");
14628 else
14630 int reg = REGNO (x);
14631 int vsx_reg = (FP_REGNO_P (reg)
14632 ? reg - 32
14633 : reg - FIRST_ALTIVEC_REGNO + 32);
14635 #ifdef TARGET_REGNAMES
14636 if (TARGET_REGNAMES)
14637 fprintf (file, "%%vs%d", vsx_reg);
14638 else
14639 #endif
14640 fprintf (file, "%d", vsx_reg);
14642 return;
14644 case 'X':
14645 if (GET_CODE (x) == MEM
14646 && (legitimate_indexed_address_p (XEXP (x, 0), 0)
14647 || (GET_CODE (XEXP (x, 0)) == PRE_MODIFY
14648 && legitimate_indexed_address_p (XEXP (XEXP (x, 0), 1), 0))))
14649 putc ('x', file);
14650 return;
14652 case 'Y':
14653 /* Like 'L', for third word of TImode */
14654 if (GET_CODE (x) == REG)
14655 fputs (reg_names[REGNO (x) + 2], file);
14656 else if (GET_CODE (x) == MEM)
14658 if (GET_CODE (XEXP (x, 0)) == PRE_INC
14659 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
14660 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
14661 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
14662 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
14663 else
14664 output_address (XEXP (adjust_address_nv (x, SImode, 8), 0));
14665 if (small_data_operand (x, GET_MODE (x)))
14666 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
14667 reg_names[SMALL_DATA_REG]);
14669 return;
14671 case 'z':
14672 /* X is a SYMBOL_REF. Write out the name preceded by a
14673 period and without any trailing data in brackets. Used for function
14674 names. If we are configured for System V (or the embedded ABI) on
14675 the PowerPC, do not emit the period, since those systems do not use
14676 TOCs and the like. */
14677 gcc_assert (GET_CODE (x) == SYMBOL_REF);
14679 /* Mark the decl as referenced so that cgraph will output the
14680 function. */
14681 if (SYMBOL_REF_DECL (x))
14682 mark_decl_referenced (SYMBOL_REF_DECL (x));
14684 /* For macho, check to see if we need a stub. */
14685 if (TARGET_MACHO)
14687 const char *name = XSTR (x, 0);
14688 #if TARGET_MACHO
14689 if (MACHOPIC_INDIRECT
14690 && machopic_classify_symbol (x) == MACHOPIC_UNDEFINED_FUNCTION)
14691 name = machopic_indirection_name (x, /*stub_p=*/true);
14692 #endif
14693 assemble_name (file, name);
14695 else if (!DOT_SYMBOLS)
14696 assemble_name (file, XSTR (x, 0));
14697 else
14698 rs6000_output_function_entry (file, XSTR (x, 0));
14699 return;
14701 case 'Z':
14702 /* Like 'L', for last word of TImode. */
14703 if (GET_CODE (x) == REG)
14704 fputs (reg_names[REGNO (x) + 3], file);
14705 else if (GET_CODE (x) == MEM)
14707 if (GET_CODE (XEXP (x, 0)) == PRE_INC
14708 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
14709 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
14710 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
14711 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
14712 else
14713 output_address (XEXP (adjust_address_nv (x, SImode, 12), 0));
14714 if (small_data_operand (x, GET_MODE (x)))
14715 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
14716 reg_names[SMALL_DATA_REG]);
14718 return;
14720 /* Print AltiVec or SPE memory operand. */
14721 case 'y':
14723 rtx tmp;
14725 gcc_assert (GET_CODE (x) == MEM);
14727 tmp = XEXP (x, 0);
14729 /* Ugly hack because %y is overloaded. */
14730 if ((TARGET_SPE || TARGET_E500_DOUBLE)
14731 && (GET_MODE_SIZE (GET_MODE (x)) == 8
14732 || GET_MODE (x) == TFmode
14733 || GET_MODE (x) == TImode))
14735 /* Handle [reg]. */
14736 if (GET_CODE (tmp) == REG)
14738 fprintf (file, "0(%s)", reg_names[REGNO (tmp)]);
14739 break;
14741 /* Handle [reg+UIMM]. */
14742 else if (GET_CODE (tmp) == PLUS &&
14743 GET_CODE (XEXP (tmp, 1)) == CONST_INT)
14745 int x;
14747 gcc_assert (GET_CODE (XEXP (tmp, 0)) == REG);
14749 x = INTVAL (XEXP (tmp, 1));
14750 fprintf (file, "%d(%s)", x, reg_names[REGNO (XEXP (tmp, 0))]);
14751 break;
14754 /* Fall through. Must be [reg+reg]. */
14756 if (VECTOR_MEM_ALTIVEC_P (GET_MODE (x))
14757 && GET_CODE (tmp) == AND
14758 && GET_CODE (XEXP (tmp, 1)) == CONST_INT
14759 && INTVAL (XEXP (tmp, 1)) == -16)
14760 tmp = XEXP (tmp, 0);
14761 else if (VECTOR_MEM_VSX_P (GET_MODE (x))
14762 && GET_CODE (tmp) == PRE_MODIFY)
14763 tmp = XEXP (tmp, 1);
14764 if (GET_CODE (tmp) == REG)
14765 fprintf (file, "0,%s", reg_names[REGNO (tmp)]);
14766 else
14768 if (!GET_CODE (tmp) == PLUS
14769 || !REG_P (XEXP (tmp, 0))
14770 || !REG_P (XEXP (tmp, 1)))
14772 output_operand_lossage ("invalid %%y value, try using the 'Z' constraint");
14773 break;
14776 if (REGNO (XEXP (tmp, 0)) == 0)
14777 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 1)) ],
14778 reg_names[ REGNO (XEXP (tmp, 0)) ]);
14779 else
14780 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 0)) ],
14781 reg_names[ REGNO (XEXP (tmp, 1)) ]);
14783 break;
14786 case 0:
14787 if (GET_CODE (x) == REG)
14788 fprintf (file, "%s", reg_names[REGNO (x)]);
14789 else if (GET_CODE (x) == MEM)
14791 /* We need to handle PRE_INC and PRE_DEC here, since we need to
14792 know the width from the mode. */
14793 if (GET_CODE (XEXP (x, 0)) == PRE_INC)
14794 fprintf (file, "%d(%s)", GET_MODE_SIZE (GET_MODE (x)),
14795 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
14796 else if (GET_CODE (XEXP (x, 0)) == PRE_DEC)
14797 fprintf (file, "%d(%s)", - GET_MODE_SIZE (GET_MODE (x)),
14798 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
14799 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
14800 output_address (XEXP (XEXP (x, 0), 1));
14801 else
14802 output_address (XEXP (x, 0));
14804 else
14805 output_addr_const (file, x);
14806 return;
14808 case '&':
14809 assemble_name (file, rs6000_get_some_local_dynamic_name ());
14810 return;
14812 default:
14813 output_operand_lossage ("invalid %%xn code");
14817 /* Print the address of an operand. */
14819 void
14820 print_operand_address (FILE *file, rtx x)
14822 if (GET_CODE (x) == REG)
14823 fprintf (file, "0(%s)", reg_names[ REGNO (x) ]);
14824 else if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST
14825 || GET_CODE (x) == LABEL_REF)
14827 output_addr_const (file, x);
14828 if (small_data_operand (x, GET_MODE (x)))
14829 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
14830 reg_names[SMALL_DATA_REG]);
14831 else
14832 gcc_assert (!TARGET_TOC);
14834 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == REG)
14836 gcc_assert (REG_P (XEXP (x, 0)));
14837 if (REGNO (XEXP (x, 0)) == 0)
14838 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 1)) ],
14839 reg_names[ REGNO (XEXP (x, 0)) ]);
14840 else
14841 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 0)) ],
14842 reg_names[ REGNO (XEXP (x, 1)) ]);
14844 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == CONST_INT)
14845 fprintf (file, HOST_WIDE_INT_PRINT_DEC "(%s)",
14846 INTVAL (XEXP (x, 1)), reg_names[ REGNO (XEXP (x, 0)) ]);
14847 #if TARGET_ELF
14848 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
14849 && CONSTANT_P (XEXP (x, 1)))
14851 output_addr_const (file, XEXP (x, 1));
14852 fprintf (file, "@l(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
14854 #endif
14855 #if TARGET_MACHO
14856 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
14857 && CONSTANT_P (XEXP (x, 1)))
14859 fprintf (file, "lo16(");
14860 output_addr_const (file, XEXP (x, 1));
14861 fprintf (file, ")(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
14863 #endif
14864 else if (legitimate_constant_pool_address_p (x))
14866 output_addr_const (file, XEXP (x, 1));
14867 fprintf (file, "(%s)", reg_names[REGNO (XEXP (x, 0))]);
14869 else
14870 gcc_unreachable ();
14873 /* Implement OUTPUT_ADDR_CONST_EXTRA for address X. */
14875 bool
14876 rs6000_output_addr_const_extra (FILE *file, rtx x)
14878 if (GET_CODE (x) == UNSPEC)
14879 switch (XINT (x, 1))
14881 case UNSPEC_TOCREL:
14882 x = XVECEXP (x, 0, 0);
14883 gcc_assert (GET_CODE (x) == SYMBOL_REF);
14884 output_addr_const (file, x);
14885 if (!TARGET_AIX || (TARGET_ELF && TARGET_MINIMAL_TOC))
14887 putc ('-', file);
14888 assemble_name (file, toc_label_name);
14890 else if (TARGET_ELF)
14891 fputs ("@toc", file);
14892 return true;
14894 #if TARGET_MACHO
14895 case UNSPEC_MACHOPIC_OFFSET:
14896 output_addr_const (file, XVECEXP (x, 0, 0));
14897 putc ('-', file);
14898 machopic_output_function_base_name (file);
14899 return true;
14900 #endif
14902 return false;
14905 /* Target hook for assembling integer objects. The PowerPC version has
14906 to handle fixup entries for relocatable code if RELOCATABLE_NEEDS_FIXUP
14907 is defined. It also needs to handle DI-mode objects on 64-bit
14908 targets. */
14910 static bool
14911 rs6000_assemble_integer (rtx x, unsigned int size, int aligned_p)
14913 #ifdef RELOCATABLE_NEEDS_FIXUP
14914 /* Special handling for SI values. */
14915 if (RELOCATABLE_NEEDS_FIXUP && size == 4 && aligned_p)
14917 static int recurse = 0;
14919 /* For -mrelocatable, we mark all addresses that need to be fixed up
14920 in the .fixup section. */
14921 if (TARGET_RELOCATABLE
14922 && in_section != toc_section
14923 && in_section != text_section
14924 && !unlikely_text_section_p (in_section)
14925 && !recurse
14926 && GET_CODE (x) != CONST_INT
14927 && GET_CODE (x) != CONST_DOUBLE
14928 && CONSTANT_P (x))
14930 char buf[256];
14932 recurse = 1;
14933 ASM_GENERATE_INTERNAL_LABEL (buf, "LCP", fixuplabelno);
14934 fixuplabelno++;
14935 ASM_OUTPUT_LABEL (asm_out_file, buf);
14936 fprintf (asm_out_file, "\t.long\t(");
14937 output_addr_const (asm_out_file, x);
14938 fprintf (asm_out_file, ")@fixup\n");
14939 fprintf (asm_out_file, "\t.section\t\".fixup\",\"aw\"\n");
14940 ASM_OUTPUT_ALIGN (asm_out_file, 2);
14941 fprintf (asm_out_file, "\t.long\t");
14942 assemble_name (asm_out_file, buf);
14943 fprintf (asm_out_file, "\n\t.previous\n");
14944 recurse = 0;
14945 return true;
14947 /* Remove initial .'s to turn a -mcall-aixdesc function
14948 address into the address of the descriptor, not the function
14949 itself. */
14950 else if (GET_CODE (x) == SYMBOL_REF
14951 && XSTR (x, 0)[0] == '.'
14952 && DEFAULT_ABI == ABI_AIX)
14954 const char *name = XSTR (x, 0);
14955 while (*name == '.')
14956 name++;
14958 fprintf (asm_out_file, "\t.long\t%s\n", name);
14959 return true;
14962 #endif /* RELOCATABLE_NEEDS_FIXUP */
14963 return default_assemble_integer (x, size, aligned_p);
14966 #ifdef HAVE_GAS_HIDDEN
14967 /* Emit an assembler directive to set symbol visibility for DECL to
14968 VISIBILITY_TYPE. */
14970 static void
14971 rs6000_assemble_visibility (tree decl, int vis)
14973 /* Functions need to have their entry point symbol visibility set as
14974 well as their descriptor symbol visibility. */
14975 if (DEFAULT_ABI == ABI_AIX
14976 && DOT_SYMBOLS
14977 && TREE_CODE (decl) == FUNCTION_DECL)
14979 static const char * const visibility_types[] = {
14980 NULL, "internal", "hidden", "protected"
14983 const char *name, *type;
14985 name = ((* targetm.strip_name_encoding)
14986 (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))));
14987 type = visibility_types[vis];
14989 fprintf (asm_out_file, "\t.%s\t%s\n", type, name);
14990 fprintf (asm_out_file, "\t.%s\t.%s\n", type, name);
14992 else
14993 default_assemble_visibility (decl, vis);
14995 #endif
14997 enum rtx_code
14998 rs6000_reverse_condition (enum machine_mode mode, enum rtx_code code)
15000 /* Reversal of FP compares takes care -- an ordered compare
15001 becomes an unordered compare and vice versa. */
15002 if (mode == CCFPmode
15003 && (!flag_finite_math_only
15004 || code == UNLT || code == UNLE || code == UNGT || code == UNGE
15005 || code == UNEQ || code == LTGT))
15006 return reverse_condition_maybe_unordered (code);
15007 else
15008 return reverse_condition (code);
15011 /* Generate a compare for CODE. Return a brand-new rtx that
15012 represents the result of the compare. */
15014 static rtx
15015 rs6000_generate_compare (rtx cmp, enum machine_mode mode)
15017 enum machine_mode comp_mode;
15018 rtx compare_result;
15019 enum rtx_code code = GET_CODE (cmp);
15020 rtx op0 = XEXP (cmp, 0);
15021 rtx op1 = XEXP (cmp, 1);
15023 if (FLOAT_MODE_P (mode))
15024 comp_mode = CCFPmode;
15025 else if (code == GTU || code == LTU
15026 || code == GEU || code == LEU)
15027 comp_mode = CCUNSmode;
15028 else if ((code == EQ || code == NE)
15029 && GET_CODE (op0) == SUBREG
15030 && GET_CODE (op1) == SUBREG
15031 && SUBREG_PROMOTED_UNSIGNED_P (op0)
15032 && SUBREG_PROMOTED_UNSIGNED_P (op1))
15033 /* These are unsigned values, perhaps there will be a later
15034 ordering compare that can be shared with this one.
15035 Unfortunately we cannot detect the signedness of the operands
15036 for non-subregs. */
15037 comp_mode = CCUNSmode;
15038 else
15039 comp_mode = CCmode;
15041 /* First, the compare. */
15042 compare_result = gen_reg_rtx (comp_mode);
15044 /* E500 FP compare instructions on the GPRs. Yuck! */
15045 if ((!TARGET_FPRS && TARGET_HARD_FLOAT)
15046 && FLOAT_MODE_P (mode))
15048 rtx cmp, or_result, compare_result2;
15049 enum machine_mode op_mode = GET_MODE (op0);
15051 if (op_mode == VOIDmode)
15052 op_mode = GET_MODE (op1);
15054 /* The E500 FP compare instructions toggle the GT bit (CR bit 1) only.
15055 This explains the following mess. */
15057 switch (code)
15059 case EQ: case UNEQ: case NE: case LTGT:
15060 switch (op_mode)
15062 case SFmode:
15063 cmp = (flag_finite_math_only && !flag_trapping_math)
15064 ? gen_tstsfeq_gpr (compare_result, op0, op1)
15065 : gen_cmpsfeq_gpr (compare_result, op0, op1);
15066 break;
15068 case DFmode:
15069 cmp = (flag_finite_math_only && !flag_trapping_math)
15070 ? gen_tstdfeq_gpr (compare_result, op0, op1)
15071 : gen_cmpdfeq_gpr (compare_result, op0, op1);
15072 break;
15074 case TFmode:
15075 cmp = (flag_finite_math_only && !flag_trapping_math)
15076 ? gen_tsttfeq_gpr (compare_result, op0, op1)
15077 : gen_cmptfeq_gpr (compare_result, op0, op1);
15078 break;
15080 default:
15081 gcc_unreachable ();
15083 break;
15085 case GT: case GTU: case UNGT: case UNGE: case GE: case GEU:
15086 switch (op_mode)
15088 case SFmode:
15089 cmp = (flag_finite_math_only && !flag_trapping_math)
15090 ? gen_tstsfgt_gpr (compare_result, op0, op1)
15091 : gen_cmpsfgt_gpr (compare_result, op0, op1);
15092 break;
15094 case DFmode:
15095 cmp = (flag_finite_math_only && !flag_trapping_math)
15096 ? gen_tstdfgt_gpr (compare_result, op0, op1)
15097 : gen_cmpdfgt_gpr (compare_result, op0, op1);
15098 break;
15100 case TFmode:
15101 cmp = (flag_finite_math_only && !flag_trapping_math)
15102 ? gen_tsttfgt_gpr (compare_result, op0, op1)
15103 : gen_cmptfgt_gpr (compare_result, op0, op1);
15104 break;
15106 default:
15107 gcc_unreachable ();
15109 break;
15111 case LT: case LTU: case UNLT: case UNLE: case LE: case LEU:
15112 switch (op_mode)
15114 case SFmode:
15115 cmp = (flag_finite_math_only && !flag_trapping_math)
15116 ? gen_tstsflt_gpr (compare_result, op0, op1)
15117 : gen_cmpsflt_gpr (compare_result, op0, op1);
15118 break;
15120 case DFmode:
15121 cmp = (flag_finite_math_only && !flag_trapping_math)
15122 ? gen_tstdflt_gpr (compare_result, op0, op1)
15123 : gen_cmpdflt_gpr (compare_result, op0, op1);
15124 break;
15126 case TFmode:
15127 cmp = (flag_finite_math_only && !flag_trapping_math)
15128 ? gen_tsttflt_gpr (compare_result, op0, op1)
15129 : gen_cmptflt_gpr (compare_result, op0, op1);
15130 break;
15132 default:
15133 gcc_unreachable ();
15135 break;
15136 default:
15137 gcc_unreachable ();
15140 /* Synthesize LE and GE from LT/GT || EQ. */
15141 if (code == LE || code == GE || code == LEU || code == GEU)
15143 emit_insn (cmp);
15145 switch (code)
15147 case LE: code = LT; break;
15148 case GE: code = GT; break;
15149 case LEU: code = LT; break;
15150 case GEU: code = GT; break;
15151 default: gcc_unreachable ();
15154 compare_result2 = gen_reg_rtx (CCFPmode);
15156 /* Do the EQ. */
15157 switch (op_mode)
15159 case SFmode:
15160 cmp = (flag_finite_math_only && !flag_trapping_math)
15161 ? gen_tstsfeq_gpr (compare_result2, op0, op1)
15162 : gen_cmpsfeq_gpr (compare_result2, op0, op1);
15163 break;
15165 case DFmode:
15166 cmp = (flag_finite_math_only && !flag_trapping_math)
15167 ? gen_tstdfeq_gpr (compare_result2, op0, op1)
15168 : gen_cmpdfeq_gpr (compare_result2, op0, op1);
15169 break;
15171 case TFmode:
15172 cmp = (flag_finite_math_only && !flag_trapping_math)
15173 ? gen_tsttfeq_gpr (compare_result2, op0, op1)
15174 : gen_cmptfeq_gpr (compare_result2, op0, op1);
15175 break;
15177 default:
15178 gcc_unreachable ();
15180 emit_insn (cmp);
15182 /* OR them together. */
15183 or_result = gen_reg_rtx (CCFPmode);
15184 cmp = gen_e500_cr_ior_compare (or_result, compare_result,
15185 compare_result2);
15186 compare_result = or_result;
15187 code = EQ;
15189 else
15191 if (code == NE || code == LTGT)
15192 code = NE;
15193 else
15194 code = EQ;
15197 emit_insn (cmp);
15199 else
15201 /* Generate XLC-compatible TFmode compare as PARALLEL with extra
15202 CLOBBERs to match cmptf_internal2 pattern. */
15203 if (comp_mode == CCFPmode && TARGET_XL_COMPAT
15204 && GET_MODE (op0) == TFmode
15205 && !TARGET_IEEEQUAD
15206 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128)
15207 emit_insn (gen_rtx_PARALLEL (VOIDmode,
15208 gen_rtvec (9,
15209 gen_rtx_SET (VOIDmode,
15210 compare_result,
15211 gen_rtx_COMPARE (comp_mode, op0, op1)),
15212 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15213 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15214 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15215 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15216 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15217 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15218 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15219 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)))));
15220 else if (GET_CODE (op1) == UNSPEC
15221 && XINT (op1, 1) == UNSPEC_SP_TEST)
15223 rtx op1b = XVECEXP (op1, 0, 0);
15224 comp_mode = CCEQmode;
15225 compare_result = gen_reg_rtx (CCEQmode);
15226 if (TARGET_64BIT)
15227 emit_insn (gen_stack_protect_testdi (compare_result, op0, op1b));
15228 else
15229 emit_insn (gen_stack_protect_testsi (compare_result, op0, op1b));
15231 else
15232 emit_insn (gen_rtx_SET (VOIDmode, compare_result,
15233 gen_rtx_COMPARE (comp_mode, op0, op1)));
15236 /* Some kinds of FP comparisons need an OR operation;
15237 under flag_finite_math_only we don't bother. */
15238 if (FLOAT_MODE_P (mode)
15239 && !flag_finite_math_only
15240 && !(TARGET_HARD_FLOAT && !TARGET_FPRS)
15241 && (code == LE || code == GE
15242 || code == UNEQ || code == LTGT
15243 || code == UNGT || code == UNLT))
15245 enum rtx_code or1, or2;
15246 rtx or1_rtx, or2_rtx, compare2_rtx;
15247 rtx or_result = gen_reg_rtx (CCEQmode);
15249 switch (code)
15251 case LE: or1 = LT; or2 = EQ; break;
15252 case GE: or1 = GT; or2 = EQ; break;
15253 case UNEQ: or1 = UNORDERED; or2 = EQ; break;
15254 case LTGT: or1 = LT; or2 = GT; break;
15255 case UNGT: or1 = UNORDERED; or2 = GT; break;
15256 case UNLT: or1 = UNORDERED; or2 = LT; break;
15257 default: gcc_unreachable ();
15259 validate_condition_mode (or1, comp_mode);
15260 validate_condition_mode (or2, comp_mode);
15261 or1_rtx = gen_rtx_fmt_ee (or1, SImode, compare_result, const0_rtx);
15262 or2_rtx = gen_rtx_fmt_ee (or2, SImode, compare_result, const0_rtx);
15263 compare2_rtx = gen_rtx_COMPARE (CCEQmode,
15264 gen_rtx_IOR (SImode, or1_rtx, or2_rtx),
15265 const_true_rtx);
15266 emit_insn (gen_rtx_SET (VOIDmode, or_result, compare2_rtx));
15268 compare_result = or_result;
15269 code = EQ;
15272 validate_condition_mode (code, GET_MODE (compare_result));
15274 return gen_rtx_fmt_ee (code, VOIDmode, compare_result, const0_rtx);
15278 /* Emit the RTL for an sCOND pattern. */
15280 void
15281 rs6000_emit_sCOND (enum machine_mode mode, rtx operands[])
15283 rtx condition_rtx;
15284 enum machine_mode op_mode;
15285 enum rtx_code cond_code;
15286 rtx result = operands[0];
15288 condition_rtx = rs6000_generate_compare (operands[1], mode);
15289 cond_code = GET_CODE (condition_rtx);
15291 if (FLOAT_MODE_P (mode)
15292 && !TARGET_FPRS && TARGET_HARD_FLOAT)
15294 rtx t;
15296 PUT_MODE (condition_rtx, SImode);
15297 t = XEXP (condition_rtx, 0);
15299 gcc_assert (cond_code == NE || cond_code == EQ);
15301 if (cond_code == NE)
15302 emit_insn (gen_e500_flip_gt_bit (t, t));
15304 emit_insn (gen_move_from_CR_gt_bit (result, t));
15305 return;
15308 if (cond_code == NE
15309 || cond_code == GE || cond_code == LE
15310 || cond_code == GEU || cond_code == LEU
15311 || cond_code == ORDERED || cond_code == UNGE || cond_code == UNLE)
15313 rtx not_result = gen_reg_rtx (CCEQmode);
15314 rtx not_op, rev_cond_rtx;
15315 enum machine_mode cc_mode;
15317 cc_mode = GET_MODE (XEXP (condition_rtx, 0));
15319 rev_cond_rtx = gen_rtx_fmt_ee (rs6000_reverse_condition (cc_mode, cond_code),
15320 SImode, XEXP (condition_rtx, 0), const0_rtx);
15321 not_op = gen_rtx_COMPARE (CCEQmode, rev_cond_rtx, const0_rtx);
15322 emit_insn (gen_rtx_SET (VOIDmode, not_result, not_op));
15323 condition_rtx = gen_rtx_EQ (VOIDmode, not_result, const0_rtx);
15326 op_mode = GET_MODE (XEXP (operands[1], 0));
15327 if (op_mode == VOIDmode)
15328 op_mode = GET_MODE (XEXP (operands[1], 1));
15330 if (TARGET_POWERPC64 && (op_mode == DImode || FLOAT_MODE_P (mode)))
15332 PUT_MODE (condition_rtx, DImode);
15333 convert_move (result, condition_rtx, 0);
15335 else
15337 PUT_MODE (condition_rtx, SImode);
15338 emit_insn (gen_rtx_SET (VOIDmode, result, condition_rtx));
15342 /* Emit a branch of kind CODE to location LOC. */
15344 void
15345 rs6000_emit_cbranch (enum machine_mode mode, rtx operands[])
15347 rtx condition_rtx, loc_ref;
15349 condition_rtx = rs6000_generate_compare (operands[0], mode);
15350 loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands[3]);
15351 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
15352 gen_rtx_IF_THEN_ELSE (VOIDmode, condition_rtx,
15353 loc_ref, pc_rtx)));
15356 /* Return the string to output a conditional branch to LABEL, which is
15357 the operand number of the label, or -1 if the branch is really a
15358 conditional return.
15360 OP is the conditional expression. XEXP (OP, 0) is assumed to be a
15361 condition code register and its mode specifies what kind of
15362 comparison we made.
15364 REVERSED is nonzero if we should reverse the sense of the comparison.
15366 INSN is the insn. */
15368 char *
15369 output_cbranch (rtx op, const char *label, int reversed, rtx insn)
15371 static char string[64];
15372 enum rtx_code code = GET_CODE (op);
15373 rtx cc_reg = XEXP (op, 0);
15374 enum machine_mode mode = GET_MODE (cc_reg);
15375 int cc_regno = REGNO (cc_reg) - CR0_REGNO;
15376 int need_longbranch = label != NULL && get_attr_length (insn) == 8;
15377 int really_reversed = reversed ^ need_longbranch;
15378 char *s = string;
15379 const char *ccode;
15380 const char *pred;
15381 rtx note;
15383 validate_condition_mode (code, mode);
15385 /* Work out which way this really branches. We could use
15386 reverse_condition_maybe_unordered here always but this
15387 makes the resulting assembler clearer. */
15388 if (really_reversed)
15390 /* Reversal of FP compares takes care -- an ordered compare
15391 becomes an unordered compare and vice versa. */
15392 if (mode == CCFPmode)
15393 code = reverse_condition_maybe_unordered (code);
15394 else
15395 code = reverse_condition (code);
15398 if ((!TARGET_FPRS && TARGET_HARD_FLOAT) && mode == CCFPmode)
15400 /* The efscmp/tst* instructions twiddle bit 2, which maps nicely
15401 to the GT bit. */
15402 switch (code)
15404 case EQ:
15405 /* Opposite of GT. */
15406 code = GT;
15407 break;
15409 case NE:
15410 code = UNLE;
15411 break;
15413 default:
15414 gcc_unreachable ();
15418 switch (code)
15420 /* Not all of these are actually distinct opcodes, but
15421 we distinguish them for clarity of the resulting assembler. */
15422 case NE: case LTGT:
15423 ccode = "ne"; break;
15424 case EQ: case UNEQ:
15425 ccode = "eq"; break;
15426 case GE: case GEU:
15427 ccode = "ge"; break;
15428 case GT: case GTU: case UNGT:
15429 ccode = "gt"; break;
15430 case LE: case LEU:
15431 ccode = "le"; break;
15432 case LT: case LTU: case UNLT:
15433 ccode = "lt"; break;
15434 case UNORDERED: ccode = "un"; break;
15435 case ORDERED: ccode = "nu"; break;
15436 case UNGE: ccode = "nl"; break;
15437 case UNLE: ccode = "ng"; break;
15438 default:
15439 gcc_unreachable ();
15442 /* Maybe we have a guess as to how likely the branch is.
15443 The old mnemonics don't have a way to specify this information. */
15444 pred = "";
15445 note = find_reg_note (insn, REG_BR_PROB, NULL_RTX);
15446 if (note != NULL_RTX)
15448 /* PROB is the difference from 50%. */
15449 int prob = INTVAL (XEXP (note, 0)) - REG_BR_PROB_BASE / 2;
15451 /* Only hint for highly probable/improbable branches on newer
15452 cpus as static prediction overrides processor dynamic
15453 prediction. For older cpus we may as well always hint, but
15454 assume not taken for branches that are very close to 50% as a
15455 mispredicted taken branch is more expensive than a
15456 mispredicted not-taken branch. */
15457 if (rs6000_always_hint
15458 || (abs (prob) > REG_BR_PROB_BASE / 100 * 48
15459 && br_prob_note_reliable_p (note)))
15461 if (abs (prob) > REG_BR_PROB_BASE / 20
15462 && ((prob > 0) ^ need_longbranch))
15463 pred = "+";
15464 else
15465 pred = "-";
15469 if (label == NULL)
15470 s += sprintf (s, "{b%sr|b%slr%s} ", ccode, ccode, pred);
15471 else
15472 s += sprintf (s, "{b%s|b%s%s} ", ccode, ccode, pred);
15474 /* We need to escape any '%' characters in the reg_names string.
15475 Assume they'd only be the first character.... */
15476 if (reg_names[cc_regno + CR0_REGNO][0] == '%')
15477 *s++ = '%';
15478 s += sprintf (s, "%s", reg_names[cc_regno + CR0_REGNO]);
15480 if (label != NULL)
15482 /* If the branch distance was too far, we may have to use an
15483 unconditional branch to go the distance. */
15484 if (need_longbranch)
15485 s += sprintf (s, ",$+8\n\tb %s", label);
15486 else
15487 s += sprintf (s, ",%s", label);
15490 return string;
15493 /* Return the string to flip the GT bit on a CR. */
15494 char *
15495 output_e500_flip_gt_bit (rtx dst, rtx src)
15497 static char string[64];
15498 int a, b;
15500 gcc_assert (GET_CODE (dst) == REG && CR_REGNO_P (REGNO (dst))
15501 && GET_CODE (src) == REG && CR_REGNO_P (REGNO (src)));
15503 /* GT bit. */
15504 a = 4 * (REGNO (dst) - CR0_REGNO) + 1;
15505 b = 4 * (REGNO (src) - CR0_REGNO) + 1;
15507 sprintf (string, "crnot %d,%d", a, b);
15508 return string;
15511 /* Return insn for VSX or Altivec comparisons. */
15513 static rtx
15514 rs6000_emit_vector_compare_inner (enum rtx_code code, rtx op0, rtx op1)
15516 rtx mask;
15517 enum machine_mode mode = GET_MODE (op0);
15519 switch (code)
15521 default:
15522 break;
15524 case GE:
15525 if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
15526 return NULL_RTX;
15528 case EQ:
15529 case GT:
15530 case GTU:
15531 mask = gen_reg_rtx (mode);
15532 emit_insn (gen_rtx_SET (VOIDmode,
15533 mask,
15534 gen_rtx_fmt_ee (code, mode, op0, op1)));
15535 return mask;
15538 return NULL_RTX;
15541 /* Emit vector compare for operands OP0 and OP1 using code RCODE.
15542 DMODE is expected destination mode. This is a recursive function. */
15544 static rtx
15545 rs6000_emit_vector_compare (enum rtx_code rcode,
15546 rtx op0, rtx op1,
15547 enum machine_mode dmode)
15549 rtx mask;
15550 bool swap_operands = false;
15551 bool try_again = false;
15553 gcc_assert (VECTOR_UNIT_ALTIVEC_OR_VSX_P (dmode));
15554 gcc_assert (GET_MODE (op0) == GET_MODE (op1));
15556 /* See if the comparison works as is. */
15557 mask = rs6000_emit_vector_compare_inner (rcode, op0, op1);
15558 if (mask)
15559 return mask;
15561 switch (rcode)
15563 case LT:
15564 rcode = GT;
15565 swap_operands = true;
15566 try_again = true;
15567 break;
15568 case LTU:
15569 rcode = GTU;
15570 swap_operands = true;
15571 try_again = true;
15572 break;
15573 case NE:
15574 case UNLE:
15575 case UNLT:
15576 case UNGE:
15577 case UNGT:
15578 /* Invert condition and try again.
15579 e.g., A != B becomes ~(A==B). */
15581 enum rtx_code rev_code;
15582 enum insn_code nor_code;
15583 rtx mask2;
15585 rev_code = reverse_condition_maybe_unordered (rcode);
15586 if (rev_code == UNKNOWN)
15587 return NULL_RTX;
15589 nor_code = optab_handler (one_cmpl_optab, (int)dmode)->insn_code;
15590 if (nor_code == CODE_FOR_nothing)
15591 return NULL_RTX;
15593 mask2 = rs6000_emit_vector_compare (rev_code, op0, op1, dmode);
15594 if (!mask2)
15595 return NULL_RTX;
15597 mask = gen_reg_rtx (dmode);
15598 emit_insn (GEN_FCN (nor_code) (mask, mask2));
15599 return mask;
15601 break;
15602 case GE:
15603 case GEU:
15604 case LE:
15605 case LEU:
15606 /* Try GT/GTU/LT/LTU OR EQ */
15608 rtx c_rtx, eq_rtx;
15609 enum insn_code ior_code;
15610 enum rtx_code new_code;
15612 switch (rcode)
15614 case GE:
15615 new_code = GT;
15616 break;
15618 case GEU:
15619 new_code = GTU;
15620 break;
15622 case LE:
15623 new_code = LT;
15624 break;
15626 case LEU:
15627 new_code = LTU;
15628 break;
15630 default:
15631 gcc_unreachable ();
15634 ior_code = optab_handler (ior_optab, (int)dmode)->insn_code;
15635 if (ior_code == CODE_FOR_nothing)
15636 return NULL_RTX;
15638 c_rtx = rs6000_emit_vector_compare (new_code, op0, op1, dmode);
15639 if (!c_rtx)
15640 return NULL_RTX;
15642 eq_rtx = rs6000_emit_vector_compare (EQ, op0, op1, dmode);
15643 if (!eq_rtx)
15644 return NULL_RTX;
15646 mask = gen_reg_rtx (dmode);
15647 emit_insn (GEN_FCN (ior_code) (mask, c_rtx, eq_rtx));
15648 return mask;
15650 break;
15651 default:
15652 return NULL_RTX;
15655 if (try_again)
15657 if (swap_operands)
15659 rtx tmp;
15660 tmp = op0;
15661 op0 = op1;
15662 op1 = tmp;
15665 mask = rs6000_emit_vector_compare_inner (rcode, op0, op1);
15666 if (mask)
15667 return mask;
15670 /* You only get two chances. */
15671 return NULL_RTX;
15674 /* Emit vector conditional expression. DEST is destination. OP_TRUE and
15675 OP_FALSE are two VEC_COND_EXPR operands. CC_OP0 and CC_OP1 are the two
15676 operands for the relation operation COND. */
15679 rs6000_emit_vector_cond_expr (rtx dest, rtx op_true, rtx op_false,
15680 rtx cond, rtx cc_op0, rtx cc_op1)
15682 enum machine_mode dest_mode = GET_MODE (dest);
15683 enum rtx_code rcode = GET_CODE (cond);
15684 enum machine_mode cc_mode = CCmode;
15685 rtx mask;
15686 rtx cond2;
15687 rtx tmp;
15688 bool invert_move = false;
15690 if (VECTOR_UNIT_NONE_P (dest_mode))
15691 return 0;
15693 switch (rcode)
15695 /* Swap operands if we can, and fall back to doing the operation as
15696 specified, and doing a NOR to invert the test. */
15697 case NE:
15698 case UNLE:
15699 case UNLT:
15700 case UNGE:
15701 case UNGT:
15702 /* Invert condition and try again.
15703 e.g., A = (B != C) ? D : E becomes A = (B == C) ? E : D. */
15704 invert_move = true;
15705 rcode = reverse_condition_maybe_unordered (rcode);
15706 if (rcode == UNKNOWN)
15707 return 0;
15708 break;
15710 /* Mark unsigned tests with CCUNSmode. */
15711 case GTU:
15712 case GEU:
15713 case LTU:
15714 case LEU:
15715 cc_mode = CCUNSmode;
15716 break;
15718 default:
15719 break;
15722 /* Get the vector mask for the given relational operations. */
15723 mask = rs6000_emit_vector_compare (rcode, cc_op0, cc_op1, dest_mode);
15725 if (!mask)
15726 return 0;
15728 if (invert_move)
15730 tmp = op_true;
15731 op_true = op_false;
15732 op_false = tmp;
15735 cond2 = gen_rtx_fmt_ee (NE, cc_mode, mask, const0_rtx);
15736 emit_insn (gen_rtx_SET (VOIDmode,
15737 dest,
15738 gen_rtx_IF_THEN_ELSE (dest_mode,
15739 cond2,
15740 op_true,
15741 op_false)));
15742 return 1;
15745 /* Emit a conditional move: move TRUE_COND to DEST if OP of the
15746 operands of the last comparison is nonzero/true, FALSE_COND if it
15747 is zero/false. Return 0 if the hardware has no such operation. */
15750 rs6000_emit_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
15752 enum rtx_code code = GET_CODE (op);
15753 rtx op0 = XEXP (op, 0);
15754 rtx op1 = XEXP (op, 1);
15755 REAL_VALUE_TYPE c1;
15756 enum machine_mode compare_mode = GET_MODE (op0);
15757 enum machine_mode result_mode = GET_MODE (dest);
15758 rtx temp;
15759 bool is_against_zero;
15761 /* These modes should always match. */
15762 if (GET_MODE (op1) != compare_mode
15763 /* In the isel case however, we can use a compare immediate, so
15764 op1 may be a small constant. */
15765 && (!TARGET_ISEL || !short_cint_operand (op1, VOIDmode)))
15766 return 0;
15767 if (GET_MODE (true_cond) != result_mode)
15768 return 0;
15769 if (GET_MODE (false_cond) != result_mode)
15770 return 0;
15772 /* First, work out if the hardware can do this at all, or
15773 if it's too slow.... */
15774 if (!FLOAT_MODE_P (compare_mode))
15776 if (TARGET_ISEL)
15777 return rs6000_emit_int_cmove (dest, op, true_cond, false_cond);
15778 return 0;
15780 else if (TARGET_HARD_FLOAT && !TARGET_FPRS
15781 && SCALAR_FLOAT_MODE_P (compare_mode))
15782 return 0;
15784 is_against_zero = op1 == CONST0_RTX (compare_mode);
15786 /* A floating-point subtract might overflow, underflow, or produce
15787 an inexact result, thus changing the floating-point flags, so it
15788 can't be generated if we care about that. It's safe if one side
15789 of the construct is zero, since then no subtract will be
15790 generated. */
15791 if (SCALAR_FLOAT_MODE_P (compare_mode)
15792 && flag_trapping_math && ! is_against_zero)
15793 return 0;
15795 /* Eliminate half of the comparisons by switching operands, this
15796 makes the remaining code simpler. */
15797 if (code == UNLT || code == UNGT || code == UNORDERED || code == NE
15798 || code == LTGT || code == LT || code == UNLE)
15800 code = reverse_condition_maybe_unordered (code);
15801 temp = true_cond;
15802 true_cond = false_cond;
15803 false_cond = temp;
15806 /* UNEQ and LTGT take four instructions for a comparison with zero,
15807 it'll probably be faster to use a branch here too. */
15808 if (code == UNEQ && HONOR_NANS (compare_mode))
15809 return 0;
15811 if (GET_CODE (op1) == CONST_DOUBLE)
15812 REAL_VALUE_FROM_CONST_DOUBLE (c1, op1);
15814 /* We're going to try to implement comparisons by performing
15815 a subtract, then comparing against zero. Unfortunately,
15816 Inf - Inf is NaN which is not zero, and so if we don't
15817 know that the operand is finite and the comparison
15818 would treat EQ different to UNORDERED, we can't do it. */
15819 if (HONOR_INFINITIES (compare_mode)
15820 && code != GT && code != UNGE
15821 && (GET_CODE (op1) != CONST_DOUBLE || real_isinf (&c1))
15822 /* Constructs of the form (a OP b ? a : b) are safe. */
15823 && ((! rtx_equal_p (op0, false_cond) && ! rtx_equal_p (op1, false_cond))
15824 || (! rtx_equal_p (op0, true_cond)
15825 && ! rtx_equal_p (op1, true_cond))))
15826 return 0;
15828 /* At this point we know we can use fsel. */
15830 /* Reduce the comparison to a comparison against zero. */
15831 if (! is_against_zero)
15833 temp = gen_reg_rtx (compare_mode);
15834 emit_insn (gen_rtx_SET (VOIDmode, temp,
15835 gen_rtx_MINUS (compare_mode, op0, op1)));
15836 op0 = temp;
15837 op1 = CONST0_RTX (compare_mode);
15840 /* If we don't care about NaNs we can reduce some of the comparisons
15841 down to faster ones. */
15842 if (! HONOR_NANS (compare_mode))
15843 switch (code)
15845 case GT:
15846 code = LE;
15847 temp = true_cond;
15848 true_cond = false_cond;
15849 false_cond = temp;
15850 break;
15851 case UNGE:
15852 code = GE;
15853 break;
15854 case UNEQ:
15855 code = EQ;
15856 break;
15857 default:
15858 break;
15861 /* Now, reduce everything down to a GE. */
15862 switch (code)
15864 case GE:
15865 break;
15867 case LE:
15868 temp = gen_reg_rtx (compare_mode);
15869 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
15870 op0 = temp;
15871 break;
15873 case ORDERED:
15874 temp = gen_reg_rtx (compare_mode);
15875 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_ABS (compare_mode, op0)));
15876 op0 = temp;
15877 break;
15879 case EQ:
15880 temp = gen_reg_rtx (compare_mode);
15881 emit_insn (gen_rtx_SET (VOIDmode, temp,
15882 gen_rtx_NEG (compare_mode,
15883 gen_rtx_ABS (compare_mode, op0))));
15884 op0 = temp;
15885 break;
15887 case UNGE:
15888 /* a UNGE 0 <-> (a GE 0 || -a UNLT 0) */
15889 temp = gen_reg_rtx (result_mode);
15890 emit_insn (gen_rtx_SET (VOIDmode, temp,
15891 gen_rtx_IF_THEN_ELSE (result_mode,
15892 gen_rtx_GE (VOIDmode,
15893 op0, op1),
15894 true_cond, false_cond)));
15895 false_cond = true_cond;
15896 true_cond = temp;
15898 temp = gen_reg_rtx (compare_mode);
15899 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
15900 op0 = temp;
15901 break;
15903 case GT:
15904 /* a GT 0 <-> (a GE 0 && -a UNLT 0) */
15905 temp = gen_reg_rtx (result_mode);
15906 emit_insn (gen_rtx_SET (VOIDmode, temp,
15907 gen_rtx_IF_THEN_ELSE (result_mode,
15908 gen_rtx_GE (VOIDmode,
15909 op0, op1),
15910 true_cond, false_cond)));
15911 true_cond = false_cond;
15912 false_cond = temp;
15914 temp = gen_reg_rtx (compare_mode);
15915 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
15916 op0 = temp;
15917 break;
15919 default:
15920 gcc_unreachable ();
15923 emit_insn (gen_rtx_SET (VOIDmode, dest,
15924 gen_rtx_IF_THEN_ELSE (result_mode,
15925 gen_rtx_GE (VOIDmode,
15926 op0, op1),
15927 true_cond, false_cond)));
15928 return 1;
15931 /* Same as above, but for ints (isel). */
15933 static int
15934 rs6000_emit_int_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
15936 rtx condition_rtx, cr;
15937 enum machine_mode mode = GET_MODE (XEXP (op, 0));
15939 if (mode != SImode && (!TARGET_POWERPC64 || mode != DImode))
15940 return 0;
15942 /* We still have to do the compare, because isel doesn't do a
15943 compare, it just looks at the CRx bits set by a previous compare
15944 instruction. */
15945 condition_rtx = rs6000_generate_compare (op, SImode);
15946 cr = XEXP (condition_rtx, 0);
15948 if (mode == SImode)
15950 if (GET_MODE (cr) == CCmode)
15951 emit_insn (gen_isel_signed_si (dest, condition_rtx,
15952 true_cond, false_cond, cr));
15953 else
15954 emit_insn (gen_isel_unsigned_si (dest, condition_rtx,
15955 true_cond, false_cond, cr));
15957 else
15959 if (GET_MODE (cr) == CCmode)
15960 emit_insn (gen_isel_signed_di (dest, condition_rtx,
15961 true_cond, false_cond, cr));
15962 else
15963 emit_insn (gen_isel_unsigned_di (dest, condition_rtx,
15964 true_cond, false_cond, cr));
15967 return 1;
15970 const char *
15971 output_isel (rtx *operands)
15973 enum rtx_code code;
15975 code = GET_CODE (operands[1]);
15976 if (code == GE || code == GEU || code == LE || code == LEU || code == NE)
15978 PUT_CODE (operands[1], reverse_condition (code));
15979 return "isel %0,%3,%2,%j1";
15981 else
15982 return "isel %0,%2,%3,%j1";
15985 void
15986 rs6000_emit_minmax (rtx dest, enum rtx_code code, rtx op0, rtx op1)
15988 enum machine_mode mode = GET_MODE (op0);
15989 enum rtx_code c;
15990 rtx target;
15992 /* VSX/altivec have direct min/max insns. */
15993 if ((code == SMAX || code == SMIN) && VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode))
15995 emit_insn (gen_rtx_SET (VOIDmode,
15996 dest,
15997 gen_rtx_fmt_ee (code, mode, op0, op1)));
15998 return;
16001 if (code == SMAX || code == SMIN)
16002 c = GE;
16003 else
16004 c = GEU;
16006 if (code == SMAX || code == UMAX)
16007 target = emit_conditional_move (dest, c, op0, op1, mode,
16008 op0, op1, mode, 0);
16009 else
16010 target = emit_conditional_move (dest, c, op0, op1, mode,
16011 op1, op0, mode, 0);
16012 gcc_assert (target);
16013 if (target != dest)
16014 emit_move_insn (dest, target);
16017 /* Emit instructions to perform a load-reserved/store-conditional operation.
16018 The operation performed is an atomic
16019 (set M (CODE:MODE M OP))
16020 If not NULL, BEFORE is atomically set to M before the operation, and
16021 AFTER is set to M after the operation (that is, (CODE:MODE M OP)).
16022 If SYNC_P then a memory barrier is emitted before the operation.
16023 Either OP or M may be wrapped in a NOT operation. */
16025 void
16026 rs6000_emit_sync (enum rtx_code code, enum machine_mode mode,
16027 rtx m, rtx op, rtx before_param, rtx after_param,
16028 bool sync_p)
16030 enum machine_mode used_mode;
16031 rtx the_op, set_before, set_after, set_atomic, cc_scratch, before, after;
16032 rtx used_m;
16033 rtvec vec;
16034 HOST_WIDE_INT imask = GET_MODE_MASK (mode);
16035 rtx shift = NULL_RTX;
16037 if (sync_p)
16038 emit_insn (gen_lwsync ());
16040 used_m = m;
16042 /* If this is smaller than SImode, we'll have to use SImode with
16043 adjustments. */
16044 if (mode == QImode || mode == HImode)
16046 rtx newop, oldop;
16048 if (MEM_ALIGN (used_m) >= 32)
16050 int ishift = 0;
16051 if (BYTES_BIG_ENDIAN)
16052 ishift = GET_MODE_BITSIZE (SImode) - GET_MODE_BITSIZE (mode);
16054 shift = GEN_INT (ishift);
16055 used_m = change_address (used_m, SImode, 0);
16057 else
16059 rtx addrSI, aligned_addr;
16060 int shift_mask = mode == QImode ? 0x18 : 0x10;
16062 addrSI = gen_lowpart_common (SImode,
16063 force_reg (Pmode, XEXP (used_m, 0)));
16064 addrSI = force_reg (SImode, addrSI);
16065 shift = gen_reg_rtx (SImode);
16067 emit_insn (gen_rlwinm (shift, addrSI, GEN_INT (3),
16068 GEN_INT (shift_mask)));
16069 emit_insn (gen_xorsi3 (shift, shift, GEN_INT (shift_mask)));
16071 aligned_addr = expand_binop (Pmode, and_optab,
16072 XEXP (used_m, 0),
16073 GEN_INT (-4), NULL_RTX,
16074 1, OPTAB_LIB_WIDEN);
16075 used_m = change_address (used_m, SImode, aligned_addr);
16076 set_mem_align (used_m, 32);
16078 /* It's safe to keep the old alias set of USED_M, because
16079 the operation is atomic and only affects the original
16080 USED_M. */
16081 m = used_m;
16083 if (GET_CODE (op) == NOT)
16085 oldop = lowpart_subreg (SImode, XEXP (op, 0), mode);
16086 oldop = gen_rtx_NOT (SImode, oldop);
16088 else
16089 oldop = lowpart_subreg (SImode, op, mode);
16091 switch (code)
16093 case IOR:
16094 case XOR:
16095 newop = expand_binop (SImode, and_optab,
16096 oldop, GEN_INT (imask), NULL_RTX,
16097 1, OPTAB_LIB_WIDEN);
16098 emit_insn (gen_ashlsi3 (newop, newop, shift));
16099 break;
16101 case NOT: /* NAND */
16102 newop = expand_binop (SImode, ior_optab,
16103 oldop, GEN_INT (~imask), NULL_RTX,
16104 1, OPTAB_LIB_WIDEN);
16105 emit_insn (gen_rotlsi3 (newop, newop, shift));
16106 break;
16108 case AND:
16109 newop = expand_binop (SImode, ior_optab,
16110 oldop, GEN_INT (~imask), NULL_RTX,
16111 1, OPTAB_LIB_WIDEN);
16112 emit_insn (gen_rotlsi3 (newop, newop, shift));
16113 break;
16115 case PLUS:
16116 case MINUS:
16118 rtx mask;
16120 newop = expand_binop (SImode, and_optab,
16121 oldop, GEN_INT (imask), NULL_RTX,
16122 1, OPTAB_LIB_WIDEN);
16123 emit_insn (gen_ashlsi3 (newop, newop, shift));
16125 mask = gen_reg_rtx (SImode);
16126 emit_move_insn (mask, GEN_INT (imask));
16127 emit_insn (gen_ashlsi3 (mask, mask, shift));
16129 if (code == PLUS)
16130 newop = gen_rtx_PLUS (SImode, m, newop);
16131 else
16132 newop = gen_rtx_MINUS (SImode, m, newop);
16133 newop = gen_rtx_AND (SImode, newop, mask);
16134 newop = gen_rtx_IOR (SImode, newop,
16135 gen_rtx_AND (SImode,
16136 gen_rtx_NOT (SImode, mask),
16137 m));
16138 break;
16141 default:
16142 gcc_unreachable ();
16145 op = newop;
16146 used_mode = SImode;
16147 before = gen_reg_rtx (used_mode);
16148 after = gen_reg_rtx (used_mode);
16150 else
16152 used_mode = mode;
16153 before = before_param;
16154 after = after_param;
16156 if (before == NULL_RTX)
16157 before = gen_reg_rtx (used_mode);
16158 if (after == NULL_RTX)
16159 after = gen_reg_rtx (used_mode);
16162 if ((code == PLUS || code == MINUS)
16163 && used_mode != mode)
16164 the_op = op; /* Computed above. */
16165 else if (GET_CODE (op) == NOT && GET_CODE (m) != NOT)
16166 the_op = gen_rtx_fmt_ee (code, used_mode, op, m);
16167 else if (code == NOT)
16168 the_op = gen_rtx_fmt_ee (IOR, used_mode,
16169 gen_rtx_NOT (used_mode, m),
16170 gen_rtx_NOT (used_mode, op));
16171 else
16172 the_op = gen_rtx_fmt_ee (code, used_mode, m, op);
16174 set_after = gen_rtx_SET (VOIDmode, after, the_op);
16175 set_before = gen_rtx_SET (VOIDmode, before, used_m);
16176 set_atomic = gen_rtx_SET (VOIDmode, used_m,
16177 gen_rtx_UNSPEC (used_mode,
16178 gen_rtvec (1, the_op),
16179 UNSPEC_SYNC_OP));
16180 cc_scratch = gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (CCmode));
16182 if ((code == PLUS || code == MINUS) && used_mode != mode)
16183 vec = gen_rtvec (5, set_after, set_before, set_atomic, cc_scratch,
16184 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (SImode)));
16185 else
16186 vec = gen_rtvec (4, set_after, set_before, set_atomic, cc_scratch);
16187 emit_insn (gen_rtx_PARALLEL (VOIDmode, vec));
16189 /* Shift and mask the return values properly. */
16190 if (used_mode != mode && before_param)
16192 emit_insn (gen_lshrsi3 (before, before, shift));
16193 convert_move (before_param, before, 1);
16196 if (used_mode != mode && after_param)
16198 emit_insn (gen_lshrsi3 (after, after, shift));
16199 convert_move (after_param, after, 1);
16202 /* The previous sequence will end with a branch that's dependent on
16203 the conditional store, so placing an isync will ensure that no
16204 other instructions (especially, no load or store instructions)
16205 can start before the atomic operation completes. */
16206 if (sync_p)
16207 emit_insn (gen_isync ());
16210 /* A subroutine of the atomic operation splitters. Jump to LABEL if
16211 COND is true. Mark the jump as unlikely to be taken. */
16213 static void
16214 emit_unlikely_jump (rtx cond, rtx label)
16216 rtx very_unlikely = GEN_INT (REG_BR_PROB_BASE / 100 - 1);
16217 rtx x;
16219 x = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, label, pc_rtx);
16220 x = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, x));
16221 add_reg_note (x, REG_BR_PROB, very_unlikely);
16224 /* A subroutine of the atomic operation splitters. Emit a load-locked
16225 instruction in MODE. */
16227 static void
16228 emit_load_locked (enum machine_mode mode, rtx reg, rtx mem)
16230 rtx (*fn) (rtx, rtx) = NULL;
16231 if (mode == SImode)
16232 fn = gen_load_locked_si;
16233 else if (mode == DImode)
16234 fn = gen_load_locked_di;
16235 emit_insn (fn (reg, mem));
16238 /* A subroutine of the atomic operation splitters. Emit a store-conditional
16239 instruction in MODE. */
16241 static void
16242 emit_store_conditional (enum machine_mode mode, rtx res, rtx mem, rtx val)
16244 rtx (*fn) (rtx, rtx, rtx) = NULL;
16245 if (mode == SImode)
16246 fn = gen_store_conditional_si;
16247 else if (mode == DImode)
16248 fn = gen_store_conditional_di;
16250 /* Emit sync before stwcx. to address PPC405 Erratum. */
16251 if (PPC405_ERRATUM77)
16252 emit_insn (gen_memory_barrier ());
16254 emit_insn (fn (res, mem, val));
16257 /* Expand an atomic fetch-and-operate pattern. CODE is the binary operation
16258 to perform. MEM is the memory on which to operate. VAL is the second
16259 operand of the binary operator. BEFORE and AFTER are optional locations to
16260 return the value of MEM either before of after the operation. SCRATCH is
16261 a scratch register. */
16263 void
16264 rs6000_split_atomic_op (enum rtx_code code, rtx mem, rtx val,
16265 rtx before, rtx after, rtx scratch)
16267 enum machine_mode mode = GET_MODE (mem);
16268 rtx label, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
16270 emit_insn (gen_lwsync ());
16272 label = gen_label_rtx ();
16273 emit_label (label);
16274 label = gen_rtx_LABEL_REF (VOIDmode, label);
16276 if (before == NULL_RTX)
16277 before = scratch;
16278 emit_load_locked (mode, before, mem);
16280 if (code == NOT)
16281 x = gen_rtx_IOR (mode,
16282 gen_rtx_NOT (mode, before),
16283 gen_rtx_NOT (mode, val));
16284 else if (code == AND)
16285 x = gen_rtx_UNSPEC (mode, gen_rtvec (2, before, val), UNSPEC_AND);
16286 else
16287 x = gen_rtx_fmt_ee (code, mode, before, val);
16289 if (after != NULL_RTX)
16290 emit_insn (gen_rtx_SET (VOIDmode, after, copy_rtx (x)));
16291 emit_insn (gen_rtx_SET (VOIDmode, scratch, x));
16293 emit_store_conditional (mode, cond, mem, scratch);
16295 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
16296 emit_unlikely_jump (x, label);
16298 emit_insn (gen_isync ());
16301 /* Expand an atomic compare and swap operation. MEM is the memory on which
16302 to operate. OLDVAL is the old value to be compared. NEWVAL is the new
16303 value to be stored. SCRATCH is a scratch GPR. */
16305 void
16306 rs6000_split_compare_and_swap (rtx retval, rtx mem, rtx oldval, rtx newval,
16307 rtx scratch)
16309 enum machine_mode mode = GET_MODE (mem);
16310 rtx label1, label2, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
16312 emit_insn (gen_lwsync ());
16314 label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
16315 label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
16316 emit_label (XEXP (label1, 0));
16318 emit_load_locked (mode, retval, mem);
16320 x = gen_rtx_COMPARE (CCmode, retval, oldval);
16321 emit_insn (gen_rtx_SET (VOIDmode, cond, x));
16323 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
16324 emit_unlikely_jump (x, label2);
16326 emit_move_insn (scratch, newval);
16327 emit_store_conditional (mode, cond, mem, scratch);
16329 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
16330 emit_unlikely_jump (x, label1);
16332 emit_insn (gen_isync ());
16333 emit_label (XEXP (label2, 0));
16336 /* Expand an atomic test and set operation. MEM is the memory on which
16337 to operate. VAL is the value set. SCRATCH is a scratch GPR. */
16339 void
16340 rs6000_split_lock_test_and_set (rtx retval, rtx mem, rtx val, rtx scratch)
16342 enum machine_mode mode = GET_MODE (mem);
16343 rtx label, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
16345 label = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
16346 emit_label (XEXP (label, 0));
16348 emit_load_locked (mode, retval, mem);
16349 emit_move_insn (scratch, val);
16350 emit_store_conditional (mode, cond, mem, scratch);
16352 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
16353 emit_unlikely_jump (x, label);
16355 emit_insn (gen_isync ());
16358 void
16359 rs6000_expand_compare_and_swapqhi (rtx dst, rtx mem, rtx oldval, rtx newval)
16361 enum machine_mode mode = GET_MODE (mem);
16362 rtx addrSI, align, wdst, shift, mask;
16363 HOST_WIDE_INT shift_mask = mode == QImode ? 0x18 : 0x10;
16364 HOST_WIDE_INT imask = GET_MODE_MASK (mode);
16366 /* Shift amount for subword relative to aligned word. */
16367 addrSI = force_reg (GET_MODE (XEXP (mem, 0)), XEXP (mem, 0));
16368 addrSI = force_reg (SImode, gen_lowpart_common (SImode, addrSI));
16369 shift = gen_reg_rtx (SImode);
16370 emit_insn (gen_rlwinm (shift, addrSI, GEN_INT (3),
16371 GEN_INT (shift_mask)));
16372 emit_insn (gen_xorsi3 (shift, shift, GEN_INT (shift_mask)));
16374 /* Shift and mask old value into position within word. */
16375 oldval = convert_modes (SImode, mode, oldval, 1);
16376 oldval = expand_binop (SImode, and_optab,
16377 oldval, GEN_INT (imask), NULL_RTX,
16378 1, OPTAB_LIB_WIDEN);
16379 emit_insn (gen_ashlsi3 (oldval, oldval, shift));
16381 /* Shift and mask new value into position within word. */
16382 newval = convert_modes (SImode, mode, newval, 1);
16383 newval = expand_binop (SImode, and_optab,
16384 newval, GEN_INT (imask), NULL_RTX,
16385 1, OPTAB_LIB_WIDEN);
16386 emit_insn (gen_ashlsi3 (newval, newval, shift));
16388 /* Mask for insertion. */
16389 mask = gen_reg_rtx (SImode);
16390 emit_move_insn (mask, GEN_INT (imask));
16391 emit_insn (gen_ashlsi3 (mask, mask, shift));
16393 /* Address of aligned word containing subword. */
16394 align = expand_binop (Pmode, and_optab, XEXP (mem, 0), GEN_INT (-4),
16395 NULL_RTX, 1, OPTAB_LIB_WIDEN);
16396 mem = change_address (mem, SImode, align);
16397 set_mem_align (mem, 32);
16398 MEM_VOLATILE_P (mem) = 1;
16400 wdst = gen_reg_rtx (SImode);
16401 emit_insn (gen_sync_compare_and_swapqhi_internal (wdst, mask,
16402 oldval, newval, mem));
16404 /* Shift the result back. */
16405 emit_insn (gen_lshrsi3 (wdst, wdst, shift));
16407 emit_move_insn (dst, gen_lowpart (mode, wdst));
16410 void
16411 rs6000_split_compare_and_swapqhi (rtx dest, rtx mask,
16412 rtx oldval, rtx newval, rtx mem,
16413 rtx scratch)
16415 rtx label1, label2, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
16417 emit_insn (gen_lwsync ());
16418 label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
16419 label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
16420 emit_label (XEXP (label1, 0));
16422 emit_load_locked (SImode, scratch, mem);
16424 /* Mask subword within loaded value for comparison with oldval.
16425 Use UNSPEC_AND to avoid clobber.*/
16426 emit_insn (gen_rtx_SET (SImode, dest,
16427 gen_rtx_UNSPEC (SImode,
16428 gen_rtvec (2, scratch, mask),
16429 UNSPEC_AND)));
16431 x = gen_rtx_COMPARE (CCmode, dest, oldval);
16432 emit_insn (gen_rtx_SET (VOIDmode, cond, x));
16434 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
16435 emit_unlikely_jump (x, label2);
16437 /* Clear subword within loaded value for insertion of new value. */
16438 emit_insn (gen_rtx_SET (SImode, scratch,
16439 gen_rtx_AND (SImode,
16440 gen_rtx_NOT (SImode, mask), scratch)));
16441 emit_insn (gen_iorsi3 (scratch, scratch, newval));
16442 emit_store_conditional (SImode, cond, mem, scratch);
16444 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
16445 emit_unlikely_jump (x, label1);
16447 emit_insn (gen_isync ());
16448 emit_label (XEXP (label2, 0));
16452 /* Emit instructions to move SRC to DST. Called by splitters for
16453 multi-register moves. It will emit at most one instruction for
16454 each register that is accessed; that is, it won't emit li/lis pairs
16455 (or equivalent for 64-bit code). One of SRC or DST must be a hard
16456 register. */
16458 void
16459 rs6000_split_multireg_move (rtx dst, rtx src)
16461 /* The register number of the first register being moved. */
16462 int reg;
16463 /* The mode that is to be moved. */
16464 enum machine_mode mode;
16465 /* The mode that the move is being done in, and its size. */
16466 enum machine_mode reg_mode;
16467 int reg_mode_size;
16468 /* The number of registers that will be moved. */
16469 int nregs;
16471 reg = REG_P (dst) ? REGNO (dst) : REGNO (src);
16472 mode = GET_MODE (dst);
16473 nregs = hard_regno_nregs[reg][mode];
16474 if (FP_REGNO_P (reg))
16475 reg_mode = DECIMAL_FLOAT_MODE_P (mode) ? DDmode :
16476 ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? DFmode : SFmode);
16477 else if (ALTIVEC_REGNO_P (reg))
16478 reg_mode = V16QImode;
16479 else if (TARGET_E500_DOUBLE && mode == TFmode)
16480 reg_mode = DFmode;
16481 else
16482 reg_mode = word_mode;
16483 reg_mode_size = GET_MODE_SIZE (reg_mode);
16485 gcc_assert (reg_mode_size * nregs == GET_MODE_SIZE (mode));
16487 if (REG_P (src) && REG_P (dst) && (REGNO (src) < REGNO (dst)))
16489 /* Move register range backwards, if we might have destructive
16490 overlap. */
16491 int i;
16492 for (i = nregs - 1; i >= 0; i--)
16493 emit_insn (gen_rtx_SET (VOIDmode,
16494 simplify_gen_subreg (reg_mode, dst, mode,
16495 i * reg_mode_size),
16496 simplify_gen_subreg (reg_mode, src, mode,
16497 i * reg_mode_size)));
16499 else
16501 int i;
16502 int j = -1;
16503 bool used_update = false;
16505 if (MEM_P (src) && INT_REGNO_P (reg))
16507 rtx breg;
16509 if (GET_CODE (XEXP (src, 0)) == PRE_INC
16510 || GET_CODE (XEXP (src, 0)) == PRE_DEC)
16512 rtx delta_rtx;
16513 breg = XEXP (XEXP (src, 0), 0);
16514 delta_rtx = (GET_CODE (XEXP (src, 0)) == PRE_INC
16515 ? GEN_INT (GET_MODE_SIZE (GET_MODE (src)))
16516 : GEN_INT (-GET_MODE_SIZE (GET_MODE (src))));
16517 emit_insn (gen_add3_insn (breg, breg, delta_rtx));
16518 src = replace_equiv_address (src, breg);
16520 else if (! rs6000_offsettable_memref_p (src))
16522 rtx basereg;
16523 basereg = gen_rtx_REG (Pmode, reg);
16524 emit_insn (gen_rtx_SET (VOIDmode, basereg, XEXP (src, 0)));
16525 src = replace_equiv_address (src, basereg);
16528 breg = XEXP (src, 0);
16529 if (GET_CODE (breg) == PLUS || GET_CODE (breg) == LO_SUM)
16530 breg = XEXP (breg, 0);
16532 /* If the base register we are using to address memory is
16533 also a destination reg, then change that register last. */
16534 if (REG_P (breg)
16535 && REGNO (breg) >= REGNO (dst)
16536 && REGNO (breg) < REGNO (dst) + nregs)
16537 j = REGNO (breg) - REGNO (dst);
16540 if (GET_CODE (dst) == MEM && INT_REGNO_P (reg))
16542 rtx breg;
16544 if (GET_CODE (XEXP (dst, 0)) == PRE_INC
16545 || GET_CODE (XEXP (dst, 0)) == PRE_DEC)
16547 rtx delta_rtx;
16548 breg = XEXP (XEXP (dst, 0), 0);
16549 delta_rtx = (GET_CODE (XEXP (dst, 0)) == PRE_INC
16550 ? GEN_INT (GET_MODE_SIZE (GET_MODE (dst)))
16551 : GEN_INT (-GET_MODE_SIZE (GET_MODE (dst))));
16553 /* We have to update the breg before doing the store.
16554 Use store with update, if available. */
16556 if (TARGET_UPDATE)
16558 rtx nsrc = simplify_gen_subreg (reg_mode, src, mode, 0);
16559 emit_insn (TARGET_32BIT
16560 ? (TARGET_POWERPC64
16561 ? gen_movdi_si_update (breg, breg, delta_rtx, nsrc)
16562 : gen_movsi_update (breg, breg, delta_rtx, nsrc))
16563 : gen_movdi_di_update (breg, breg, delta_rtx, nsrc));
16564 used_update = true;
16566 else
16567 emit_insn (gen_add3_insn (breg, breg, delta_rtx));
16568 dst = replace_equiv_address (dst, breg);
16570 else
16571 gcc_assert (rs6000_offsettable_memref_p (dst));
16574 for (i = 0; i < nregs; i++)
16576 /* Calculate index to next subword. */
16577 ++j;
16578 if (j == nregs)
16579 j = 0;
16581 /* If compiler already emitted move of first word by
16582 store with update, no need to do anything. */
16583 if (j == 0 && used_update)
16584 continue;
16586 emit_insn (gen_rtx_SET (VOIDmode,
16587 simplify_gen_subreg (reg_mode, dst, mode,
16588 j * reg_mode_size),
16589 simplify_gen_subreg (reg_mode, src, mode,
16590 j * reg_mode_size)));
16596 /* This page contains routines that are used to determine what the
16597 function prologue and epilogue code will do and write them out. */
16599 /* Return the first fixed-point register that is required to be
16600 saved. 32 if none. */
16603 first_reg_to_save (void)
16605 int first_reg;
16607 /* Find lowest numbered live register. */
16608 for (first_reg = 13; first_reg <= 31; first_reg++)
16609 if (df_regs_ever_live_p (first_reg)
16610 && (! call_used_regs[first_reg]
16611 || (first_reg == RS6000_PIC_OFFSET_TABLE_REGNUM
16612 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
16613 || (DEFAULT_ABI == ABI_DARWIN && flag_pic)
16614 || (TARGET_TOC && TARGET_MINIMAL_TOC)))))
16615 break;
16617 #if TARGET_MACHO
16618 if (flag_pic
16619 && crtl->uses_pic_offset_table
16620 && first_reg > RS6000_PIC_OFFSET_TABLE_REGNUM)
16621 return RS6000_PIC_OFFSET_TABLE_REGNUM;
16622 #endif
16624 return first_reg;
16627 /* Similar, for FP regs. */
16630 first_fp_reg_to_save (void)
16632 int first_reg;
16634 /* Find lowest numbered live register. */
16635 for (first_reg = 14 + 32; first_reg <= 63; first_reg++)
16636 if (df_regs_ever_live_p (first_reg))
16637 break;
16639 return first_reg;
16642 /* Similar, for AltiVec regs. */
16644 static int
16645 first_altivec_reg_to_save (void)
16647 int i;
16649 /* Stack frame remains as is unless we are in AltiVec ABI. */
16650 if (! TARGET_ALTIVEC_ABI)
16651 return LAST_ALTIVEC_REGNO + 1;
16653 /* On Darwin, the unwind routines are compiled without
16654 TARGET_ALTIVEC, and use save_world to save/restore the
16655 altivec registers when necessary. */
16656 if (DEFAULT_ABI == ABI_DARWIN && crtl->calls_eh_return
16657 && ! TARGET_ALTIVEC)
16658 return FIRST_ALTIVEC_REGNO + 20;
16660 /* Find lowest numbered live register. */
16661 for (i = FIRST_ALTIVEC_REGNO + 20; i <= LAST_ALTIVEC_REGNO; ++i)
16662 if (df_regs_ever_live_p (i))
16663 break;
16665 return i;
16668 /* Return a 32-bit mask of the AltiVec registers we need to set in
16669 VRSAVE. Bit n of the return value is 1 if Vn is live. The MSB in
16670 the 32-bit word is 0. */
16672 static unsigned int
16673 compute_vrsave_mask (void)
16675 unsigned int i, mask = 0;
16677 /* On Darwin, the unwind routines are compiled without
16678 TARGET_ALTIVEC, and use save_world to save/restore the
16679 call-saved altivec registers when necessary. */
16680 if (DEFAULT_ABI == ABI_DARWIN && crtl->calls_eh_return
16681 && ! TARGET_ALTIVEC)
16682 mask |= 0xFFF;
16684 /* First, find out if we use _any_ altivec registers. */
16685 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
16686 if (df_regs_ever_live_p (i))
16687 mask |= ALTIVEC_REG_BIT (i);
16689 if (mask == 0)
16690 return mask;
16692 /* Next, remove the argument registers from the set. These must
16693 be in the VRSAVE mask set by the caller, so we don't need to add
16694 them in again. More importantly, the mask we compute here is
16695 used to generate CLOBBERs in the set_vrsave insn, and we do not
16696 wish the argument registers to die. */
16697 for (i = crtl->args.info.vregno - 1; i >= ALTIVEC_ARG_MIN_REG; --i)
16698 mask &= ~ALTIVEC_REG_BIT (i);
16700 /* Similarly, remove the return value from the set. */
16702 bool yes = false;
16703 diddle_return_value (is_altivec_return_reg, &yes);
16704 if (yes)
16705 mask &= ~ALTIVEC_REG_BIT (ALTIVEC_ARG_RETURN);
16708 return mask;
16711 /* For a very restricted set of circumstances, we can cut down the
16712 size of prologues/epilogues by calling our own save/restore-the-world
16713 routines. */
16715 static void
16716 compute_save_world_info (rs6000_stack_t *info_ptr)
16718 info_ptr->world_save_p = 1;
16719 info_ptr->world_save_p
16720 = (WORLD_SAVE_P (info_ptr)
16721 && DEFAULT_ABI == ABI_DARWIN
16722 && ! (cfun->calls_setjmp && flag_exceptions)
16723 && info_ptr->first_fp_reg_save == FIRST_SAVED_FP_REGNO
16724 && info_ptr->first_gp_reg_save == FIRST_SAVED_GP_REGNO
16725 && info_ptr->first_altivec_reg_save == FIRST_SAVED_ALTIVEC_REGNO
16726 && info_ptr->cr_save_p);
16728 /* This will not work in conjunction with sibcalls. Make sure there
16729 are none. (This check is expensive, but seldom executed.) */
16730 if (WORLD_SAVE_P (info_ptr))
16732 rtx insn;
16733 for ( insn = get_last_insn_anywhere (); insn; insn = PREV_INSN (insn))
16734 if ( GET_CODE (insn) == CALL_INSN
16735 && SIBLING_CALL_P (insn))
16737 info_ptr->world_save_p = 0;
16738 break;
16742 if (WORLD_SAVE_P (info_ptr))
16744 /* Even if we're not touching VRsave, make sure there's room on the
16745 stack for it, if it looks like we're calling SAVE_WORLD, which
16746 will attempt to save it. */
16747 info_ptr->vrsave_size = 4;
16749 /* If we are going to save the world, we need to save the link register too. */
16750 info_ptr->lr_save_p = 1;
16752 /* "Save" the VRsave register too if we're saving the world. */
16753 if (info_ptr->vrsave_mask == 0)
16754 info_ptr->vrsave_mask = compute_vrsave_mask ();
16756 /* Because the Darwin register save/restore routines only handle
16757 F14 .. F31 and V20 .. V31 as per the ABI, perform a consistency
16758 check. */
16759 gcc_assert (info_ptr->first_fp_reg_save >= FIRST_SAVED_FP_REGNO
16760 && (info_ptr->first_altivec_reg_save
16761 >= FIRST_SAVED_ALTIVEC_REGNO));
16763 return;
16767 static void
16768 is_altivec_return_reg (rtx reg, void *xyes)
16770 bool *yes = (bool *) xyes;
16771 if (REGNO (reg) == ALTIVEC_ARG_RETURN)
16772 *yes = true;
16776 /* Calculate the stack information for the current function. This is
16777 complicated by having two separate calling sequences, the AIX calling
16778 sequence and the V.4 calling sequence.
16780 AIX (and Darwin/Mac OS X) stack frames look like:
16781 32-bit 64-bit
16782 SP----> +---------------------------------------+
16783 | back chain to caller | 0 0
16784 +---------------------------------------+
16785 | saved CR | 4 8 (8-11)
16786 +---------------------------------------+
16787 | saved LR | 8 16
16788 +---------------------------------------+
16789 | reserved for compilers | 12 24
16790 +---------------------------------------+
16791 | reserved for binders | 16 32
16792 +---------------------------------------+
16793 | saved TOC pointer | 20 40
16794 +---------------------------------------+
16795 | Parameter save area (P) | 24 48
16796 +---------------------------------------+
16797 | Alloca space (A) | 24+P etc.
16798 +---------------------------------------+
16799 | Local variable space (L) | 24+P+A
16800 +---------------------------------------+
16801 | Float/int conversion temporary (X) | 24+P+A+L
16802 +---------------------------------------+
16803 | Save area for AltiVec registers (W) | 24+P+A+L+X
16804 +---------------------------------------+
16805 | AltiVec alignment padding (Y) | 24+P+A+L+X+W
16806 +---------------------------------------+
16807 | Save area for VRSAVE register (Z) | 24+P+A+L+X+W+Y
16808 +---------------------------------------+
16809 | Save area for GP registers (G) | 24+P+A+X+L+X+W+Y+Z
16810 +---------------------------------------+
16811 | Save area for FP registers (F) | 24+P+A+X+L+X+W+Y+Z+G
16812 +---------------------------------------+
16813 old SP->| back chain to caller's caller |
16814 +---------------------------------------+
16816 The required alignment for AIX configurations is two words (i.e., 8
16817 or 16 bytes).
16820 V.4 stack frames look like:
16822 SP----> +---------------------------------------+
16823 | back chain to caller | 0
16824 +---------------------------------------+
16825 | caller's saved LR | 4
16826 +---------------------------------------+
16827 | Parameter save area (P) | 8
16828 +---------------------------------------+
16829 | Alloca space (A) | 8+P
16830 +---------------------------------------+
16831 | Varargs save area (V) | 8+P+A
16832 +---------------------------------------+
16833 | Local variable space (L) | 8+P+A+V
16834 +---------------------------------------+
16835 | Float/int conversion temporary (X) | 8+P+A+V+L
16836 +---------------------------------------+
16837 | Save area for AltiVec registers (W) | 8+P+A+V+L+X
16838 +---------------------------------------+
16839 | AltiVec alignment padding (Y) | 8+P+A+V+L+X+W
16840 +---------------------------------------+
16841 | Save area for VRSAVE register (Z) | 8+P+A+V+L+X+W+Y
16842 +---------------------------------------+
16843 | SPE: area for 64-bit GP registers |
16844 +---------------------------------------+
16845 | SPE alignment padding |
16846 +---------------------------------------+
16847 | saved CR (C) | 8+P+A+V+L+X+W+Y+Z
16848 +---------------------------------------+
16849 | Save area for GP registers (G) | 8+P+A+V+L+X+W+Y+Z+C
16850 +---------------------------------------+
16851 | Save area for FP registers (F) | 8+P+A+V+L+X+W+Y+Z+C+G
16852 +---------------------------------------+
16853 old SP->| back chain to caller's caller |
16854 +---------------------------------------+
16856 The required alignment for V.4 is 16 bytes, or 8 bytes if -meabi is
16857 given. (But note below and in sysv4.h that we require only 8 and
16858 may round up the size of our stack frame anyways. The historical
16859 reason is early versions of powerpc-linux which didn't properly
16860 align the stack at program startup. A happy side-effect is that
16861 -mno-eabi libraries can be used with -meabi programs.)
16863 The EABI configuration defaults to the V.4 layout. However,
16864 the stack alignment requirements may differ. If -mno-eabi is not
16865 given, the required stack alignment is 8 bytes; if -mno-eabi is
16866 given, the required alignment is 16 bytes. (But see V.4 comment
16867 above.) */
16869 #ifndef ABI_STACK_BOUNDARY
16870 #define ABI_STACK_BOUNDARY STACK_BOUNDARY
16871 #endif
16873 static rs6000_stack_t *
16874 rs6000_stack_info (void)
16876 static rs6000_stack_t info;
16877 rs6000_stack_t *info_ptr = &info;
16878 int reg_size = TARGET_32BIT ? 4 : 8;
16879 int ehrd_size;
16880 int save_align;
16881 int first_gp;
16882 HOST_WIDE_INT non_fixed_size;
16884 memset (&info, 0, sizeof (info));
16886 if (TARGET_SPE)
16888 /* Cache value so we don't rescan instruction chain over and over. */
16889 if (cfun->machine->insn_chain_scanned_p == 0)
16890 cfun->machine->insn_chain_scanned_p
16891 = spe_func_has_64bit_regs_p () + 1;
16892 info_ptr->spe_64bit_regs_used = cfun->machine->insn_chain_scanned_p - 1;
16895 /* Select which calling sequence. */
16896 info_ptr->abi = DEFAULT_ABI;
16898 /* Calculate which registers need to be saved & save area size. */
16899 info_ptr->first_gp_reg_save = first_reg_to_save ();
16900 /* Assume that we will have to save RS6000_PIC_OFFSET_TABLE_REGNUM,
16901 even if it currently looks like we won't. Reload may need it to
16902 get at a constant; if so, it will have already created a constant
16903 pool entry for it. */
16904 if (((TARGET_TOC && TARGET_MINIMAL_TOC)
16905 || (flag_pic == 1 && DEFAULT_ABI == ABI_V4)
16906 || (flag_pic && DEFAULT_ABI == ABI_DARWIN))
16907 && crtl->uses_const_pool
16908 && info_ptr->first_gp_reg_save > RS6000_PIC_OFFSET_TABLE_REGNUM)
16909 first_gp = RS6000_PIC_OFFSET_TABLE_REGNUM;
16910 else
16911 first_gp = info_ptr->first_gp_reg_save;
16913 info_ptr->gp_size = reg_size * (32 - first_gp);
16915 /* For the SPE, we have an additional upper 32-bits on each GPR.
16916 Ideally we should save the entire 64-bits only when the upper
16917 half is used in SIMD instructions. Since we only record
16918 registers live (not the size they are used in), this proves
16919 difficult because we'd have to traverse the instruction chain at
16920 the right time, taking reload into account. This is a real pain,
16921 so we opt to save the GPRs in 64-bits always if but one register
16922 gets used in 64-bits. Otherwise, all the registers in the frame
16923 get saved in 32-bits.
16925 So... since when we save all GPRs (except the SP) in 64-bits, the
16926 traditional GP save area will be empty. */
16927 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
16928 info_ptr->gp_size = 0;
16930 info_ptr->first_fp_reg_save = first_fp_reg_to_save ();
16931 info_ptr->fp_size = 8 * (64 - info_ptr->first_fp_reg_save);
16933 info_ptr->first_altivec_reg_save = first_altivec_reg_to_save ();
16934 info_ptr->altivec_size = 16 * (LAST_ALTIVEC_REGNO + 1
16935 - info_ptr->first_altivec_reg_save);
16937 /* Does this function call anything? */
16938 info_ptr->calls_p = (! current_function_is_leaf
16939 || cfun->machine->ra_needs_full_frame);
16941 /* Determine if we need to save the link register. */
16942 if ((DEFAULT_ABI == ABI_AIX
16943 && crtl->profile
16944 && !TARGET_PROFILE_KERNEL)
16945 #ifdef TARGET_RELOCATABLE
16946 || (TARGET_RELOCATABLE && (get_pool_size () != 0))
16947 #endif
16948 || (info_ptr->first_fp_reg_save != 64
16949 && !FP_SAVE_INLINE (info_ptr->first_fp_reg_save))
16950 || (DEFAULT_ABI == ABI_V4 && cfun->calls_alloca)
16951 || info_ptr->calls_p
16952 || rs6000_ra_ever_killed ())
16954 info_ptr->lr_save_p = 1;
16955 df_set_regs_ever_live (LR_REGNO, true);
16958 /* Determine if we need to save the condition code registers. */
16959 if (df_regs_ever_live_p (CR2_REGNO)
16960 || df_regs_ever_live_p (CR3_REGNO)
16961 || df_regs_ever_live_p (CR4_REGNO))
16963 info_ptr->cr_save_p = 1;
16964 if (DEFAULT_ABI == ABI_V4)
16965 info_ptr->cr_size = reg_size;
16968 /* If the current function calls __builtin_eh_return, then we need
16969 to allocate stack space for registers that will hold data for
16970 the exception handler. */
16971 if (crtl->calls_eh_return)
16973 unsigned int i;
16974 for (i = 0; EH_RETURN_DATA_REGNO (i) != INVALID_REGNUM; ++i)
16975 continue;
16977 /* SPE saves EH registers in 64-bits. */
16978 ehrd_size = i * (TARGET_SPE_ABI
16979 && info_ptr->spe_64bit_regs_used != 0
16980 ? UNITS_PER_SPE_WORD : UNITS_PER_WORD);
16982 else
16983 ehrd_size = 0;
16985 /* Determine various sizes. */
16986 info_ptr->reg_size = reg_size;
16987 info_ptr->fixed_size = RS6000_SAVE_AREA;
16988 info_ptr->vars_size = RS6000_ALIGN (get_frame_size (), 8);
16989 info_ptr->parm_size = RS6000_ALIGN (crtl->outgoing_args_size,
16990 TARGET_ALTIVEC ? 16 : 8);
16991 if (FRAME_GROWS_DOWNWARD)
16992 info_ptr->vars_size
16993 += RS6000_ALIGN (info_ptr->fixed_size + info_ptr->vars_size
16994 + info_ptr->parm_size,
16995 ABI_STACK_BOUNDARY / BITS_PER_UNIT)
16996 - (info_ptr->fixed_size + info_ptr->vars_size
16997 + info_ptr->parm_size);
16999 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
17000 info_ptr->spe_gp_size = 8 * (32 - first_gp);
17001 else
17002 info_ptr->spe_gp_size = 0;
17004 if (TARGET_ALTIVEC_ABI)
17005 info_ptr->vrsave_mask = compute_vrsave_mask ();
17006 else
17007 info_ptr->vrsave_mask = 0;
17009 if (TARGET_ALTIVEC_VRSAVE && info_ptr->vrsave_mask)
17010 info_ptr->vrsave_size = 4;
17011 else
17012 info_ptr->vrsave_size = 0;
17014 compute_save_world_info (info_ptr);
17016 /* Calculate the offsets. */
17017 switch (DEFAULT_ABI)
17019 case ABI_NONE:
17020 default:
17021 gcc_unreachable ();
17023 case ABI_AIX:
17024 case ABI_DARWIN:
17025 info_ptr->fp_save_offset = - info_ptr->fp_size;
17026 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
17028 if (TARGET_ALTIVEC_ABI)
17030 info_ptr->vrsave_save_offset
17031 = info_ptr->gp_save_offset - info_ptr->vrsave_size;
17033 /* Align stack so vector save area is on a quadword boundary.
17034 The padding goes above the vectors. */
17035 if (info_ptr->altivec_size != 0)
17036 info_ptr->altivec_padding_size
17037 = info_ptr->vrsave_save_offset & 0xF;
17038 else
17039 info_ptr->altivec_padding_size = 0;
17041 info_ptr->altivec_save_offset
17042 = info_ptr->vrsave_save_offset
17043 - info_ptr->altivec_padding_size
17044 - info_ptr->altivec_size;
17045 gcc_assert (info_ptr->altivec_size == 0
17046 || info_ptr->altivec_save_offset % 16 == 0);
17048 /* Adjust for AltiVec case. */
17049 info_ptr->ehrd_offset = info_ptr->altivec_save_offset - ehrd_size;
17051 else
17052 info_ptr->ehrd_offset = info_ptr->gp_save_offset - ehrd_size;
17053 info_ptr->cr_save_offset = reg_size; /* first word when 64-bit. */
17054 info_ptr->lr_save_offset = 2*reg_size;
17055 break;
17057 case ABI_V4:
17058 info_ptr->fp_save_offset = - info_ptr->fp_size;
17059 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
17060 info_ptr->cr_save_offset = info_ptr->gp_save_offset - info_ptr->cr_size;
17062 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
17064 /* Align stack so SPE GPR save area is aligned on a
17065 double-word boundary. */
17066 if (info_ptr->spe_gp_size != 0 && info_ptr->cr_save_offset != 0)
17067 info_ptr->spe_padding_size
17068 = 8 - (-info_ptr->cr_save_offset % 8);
17069 else
17070 info_ptr->spe_padding_size = 0;
17072 info_ptr->spe_gp_save_offset
17073 = info_ptr->cr_save_offset
17074 - info_ptr->spe_padding_size
17075 - info_ptr->spe_gp_size;
17077 /* Adjust for SPE case. */
17078 info_ptr->ehrd_offset = info_ptr->spe_gp_save_offset;
17080 else if (TARGET_ALTIVEC_ABI)
17082 info_ptr->vrsave_save_offset
17083 = info_ptr->cr_save_offset - info_ptr->vrsave_size;
17085 /* Align stack so vector save area is on a quadword boundary. */
17086 if (info_ptr->altivec_size != 0)
17087 info_ptr->altivec_padding_size
17088 = 16 - (-info_ptr->vrsave_save_offset % 16);
17089 else
17090 info_ptr->altivec_padding_size = 0;
17092 info_ptr->altivec_save_offset
17093 = info_ptr->vrsave_save_offset
17094 - info_ptr->altivec_padding_size
17095 - info_ptr->altivec_size;
17097 /* Adjust for AltiVec case. */
17098 info_ptr->ehrd_offset = info_ptr->altivec_save_offset;
17100 else
17101 info_ptr->ehrd_offset = info_ptr->cr_save_offset;
17102 info_ptr->ehrd_offset -= ehrd_size;
17103 info_ptr->lr_save_offset = reg_size;
17104 break;
17107 save_align = (TARGET_ALTIVEC_ABI || DEFAULT_ABI == ABI_DARWIN) ? 16 : 8;
17108 info_ptr->save_size = RS6000_ALIGN (info_ptr->fp_size
17109 + info_ptr->gp_size
17110 + info_ptr->altivec_size
17111 + info_ptr->altivec_padding_size
17112 + info_ptr->spe_gp_size
17113 + info_ptr->spe_padding_size
17114 + ehrd_size
17115 + info_ptr->cr_size
17116 + info_ptr->vrsave_size,
17117 save_align);
17119 non_fixed_size = (info_ptr->vars_size
17120 + info_ptr->parm_size
17121 + info_ptr->save_size);
17123 info_ptr->total_size = RS6000_ALIGN (non_fixed_size + info_ptr->fixed_size,
17124 ABI_STACK_BOUNDARY / BITS_PER_UNIT);
17126 /* Determine if we need to allocate any stack frame:
17128 For AIX we need to push the stack if a frame pointer is needed
17129 (because the stack might be dynamically adjusted), if we are
17130 debugging, if we make calls, or if the sum of fp_save, gp_save,
17131 and local variables are more than the space needed to save all
17132 non-volatile registers: 32-bit: 18*8 + 19*4 = 220 or 64-bit: 18*8
17133 + 18*8 = 288 (GPR13 reserved).
17135 For V.4 we don't have the stack cushion that AIX uses, but assume
17136 that the debugger can handle stackless frames. */
17138 if (info_ptr->calls_p)
17139 info_ptr->push_p = 1;
17141 else if (DEFAULT_ABI == ABI_V4)
17142 info_ptr->push_p = non_fixed_size != 0;
17144 else if (frame_pointer_needed)
17145 info_ptr->push_p = 1;
17147 else if (TARGET_XCOFF && write_symbols != NO_DEBUG)
17148 info_ptr->push_p = 1;
17150 else
17151 info_ptr->push_p = non_fixed_size > (TARGET_32BIT ? 220 : 288);
17153 /* Zero offsets if we're not saving those registers. */
17154 if (info_ptr->fp_size == 0)
17155 info_ptr->fp_save_offset = 0;
17157 if (info_ptr->gp_size == 0)
17158 info_ptr->gp_save_offset = 0;
17160 if (! TARGET_ALTIVEC_ABI || info_ptr->altivec_size == 0)
17161 info_ptr->altivec_save_offset = 0;
17163 if (! TARGET_ALTIVEC_ABI || info_ptr->vrsave_mask == 0)
17164 info_ptr->vrsave_save_offset = 0;
17166 if (! TARGET_SPE_ABI
17167 || info_ptr->spe_64bit_regs_used == 0
17168 || info_ptr->spe_gp_size == 0)
17169 info_ptr->spe_gp_save_offset = 0;
17171 if (! info_ptr->lr_save_p)
17172 info_ptr->lr_save_offset = 0;
17174 if (! info_ptr->cr_save_p)
17175 info_ptr->cr_save_offset = 0;
17177 return info_ptr;
17180 /* Return true if the current function uses any GPRs in 64-bit SIMD
17181 mode. */
17183 static bool
17184 spe_func_has_64bit_regs_p (void)
17186 rtx insns, insn;
17188 /* Functions that save and restore all the call-saved registers will
17189 need to save/restore the registers in 64-bits. */
17190 if (crtl->calls_eh_return
17191 || cfun->calls_setjmp
17192 || crtl->has_nonlocal_goto)
17193 return true;
17195 insns = get_insns ();
17197 for (insn = NEXT_INSN (insns); insn != NULL_RTX; insn = NEXT_INSN (insn))
17199 if (INSN_P (insn))
17201 rtx i;
17203 /* FIXME: This should be implemented with attributes...
17205 (set_attr "spe64" "true")....then,
17206 if (get_spe64(insn)) return true;
17208 It's the only reliable way to do the stuff below. */
17210 i = PATTERN (insn);
17211 if (GET_CODE (i) == SET)
17213 enum machine_mode mode = GET_MODE (SET_SRC (i));
17215 if (SPE_VECTOR_MODE (mode))
17216 return true;
17217 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode))
17218 return true;
17223 return false;
17226 static void
17227 debug_stack_info (rs6000_stack_t *info)
17229 const char *abi_string;
17231 if (! info)
17232 info = rs6000_stack_info ();
17234 fprintf (stderr, "\nStack information for function %s:\n",
17235 ((current_function_decl && DECL_NAME (current_function_decl))
17236 ? IDENTIFIER_POINTER (DECL_NAME (current_function_decl))
17237 : "<unknown>"));
17239 switch (info->abi)
17241 default: abi_string = "Unknown"; break;
17242 case ABI_NONE: abi_string = "NONE"; break;
17243 case ABI_AIX: abi_string = "AIX"; break;
17244 case ABI_DARWIN: abi_string = "Darwin"; break;
17245 case ABI_V4: abi_string = "V.4"; break;
17248 fprintf (stderr, "\tABI = %5s\n", abi_string);
17250 if (TARGET_ALTIVEC_ABI)
17251 fprintf (stderr, "\tALTIVEC ABI extensions enabled.\n");
17253 if (TARGET_SPE_ABI)
17254 fprintf (stderr, "\tSPE ABI extensions enabled.\n");
17256 if (info->first_gp_reg_save != 32)
17257 fprintf (stderr, "\tfirst_gp_reg_save = %5d\n", info->first_gp_reg_save);
17259 if (info->first_fp_reg_save != 64)
17260 fprintf (stderr, "\tfirst_fp_reg_save = %5d\n", info->first_fp_reg_save);
17262 if (info->first_altivec_reg_save <= LAST_ALTIVEC_REGNO)
17263 fprintf (stderr, "\tfirst_altivec_reg_save = %5d\n",
17264 info->first_altivec_reg_save);
17266 if (info->lr_save_p)
17267 fprintf (stderr, "\tlr_save_p = %5d\n", info->lr_save_p);
17269 if (info->cr_save_p)
17270 fprintf (stderr, "\tcr_save_p = %5d\n", info->cr_save_p);
17272 if (info->vrsave_mask)
17273 fprintf (stderr, "\tvrsave_mask = 0x%x\n", info->vrsave_mask);
17275 if (info->push_p)
17276 fprintf (stderr, "\tpush_p = %5d\n", info->push_p);
17278 if (info->calls_p)
17279 fprintf (stderr, "\tcalls_p = %5d\n", info->calls_p);
17281 if (info->gp_save_offset)
17282 fprintf (stderr, "\tgp_save_offset = %5d\n", info->gp_save_offset);
17284 if (info->fp_save_offset)
17285 fprintf (stderr, "\tfp_save_offset = %5d\n", info->fp_save_offset);
17287 if (info->altivec_save_offset)
17288 fprintf (stderr, "\taltivec_save_offset = %5d\n",
17289 info->altivec_save_offset);
17291 if (info->spe_gp_save_offset)
17292 fprintf (stderr, "\tspe_gp_save_offset = %5d\n",
17293 info->spe_gp_save_offset);
17295 if (info->vrsave_save_offset)
17296 fprintf (stderr, "\tvrsave_save_offset = %5d\n",
17297 info->vrsave_save_offset);
17299 if (info->lr_save_offset)
17300 fprintf (stderr, "\tlr_save_offset = %5d\n", info->lr_save_offset);
17302 if (info->cr_save_offset)
17303 fprintf (stderr, "\tcr_save_offset = %5d\n", info->cr_save_offset);
17305 if (info->varargs_save_offset)
17306 fprintf (stderr, "\tvarargs_save_offset = %5d\n", info->varargs_save_offset);
17308 if (info->total_size)
17309 fprintf (stderr, "\ttotal_size = "HOST_WIDE_INT_PRINT_DEC"\n",
17310 info->total_size);
17312 if (info->vars_size)
17313 fprintf (stderr, "\tvars_size = "HOST_WIDE_INT_PRINT_DEC"\n",
17314 info->vars_size);
17316 if (info->parm_size)
17317 fprintf (stderr, "\tparm_size = %5d\n", info->parm_size);
17319 if (info->fixed_size)
17320 fprintf (stderr, "\tfixed_size = %5d\n", info->fixed_size);
17322 if (info->gp_size)
17323 fprintf (stderr, "\tgp_size = %5d\n", info->gp_size);
17325 if (info->spe_gp_size)
17326 fprintf (stderr, "\tspe_gp_size = %5d\n", info->spe_gp_size);
17328 if (info->fp_size)
17329 fprintf (stderr, "\tfp_size = %5d\n", info->fp_size);
17331 if (info->altivec_size)
17332 fprintf (stderr, "\taltivec_size = %5d\n", info->altivec_size);
17334 if (info->vrsave_size)
17335 fprintf (stderr, "\tvrsave_size = %5d\n", info->vrsave_size);
17337 if (info->altivec_padding_size)
17338 fprintf (stderr, "\taltivec_padding_size= %5d\n",
17339 info->altivec_padding_size);
17341 if (info->spe_padding_size)
17342 fprintf (stderr, "\tspe_padding_size = %5d\n",
17343 info->spe_padding_size);
17345 if (info->cr_size)
17346 fprintf (stderr, "\tcr_size = %5d\n", info->cr_size);
17348 if (info->save_size)
17349 fprintf (stderr, "\tsave_size = %5d\n", info->save_size);
17351 if (info->reg_size != 4)
17352 fprintf (stderr, "\treg_size = %5d\n", info->reg_size);
17354 fprintf (stderr, "\n");
17358 rs6000_return_addr (int count, rtx frame)
17360 /* Currently we don't optimize very well between prolog and body
17361 code and for PIC code the code can be actually quite bad, so
17362 don't try to be too clever here. */
17363 if (count != 0 || (DEFAULT_ABI != ABI_AIX && flag_pic))
17365 cfun->machine->ra_needs_full_frame = 1;
17367 return
17368 gen_rtx_MEM
17369 (Pmode,
17370 memory_address
17371 (Pmode,
17372 plus_constant (copy_to_reg
17373 (gen_rtx_MEM (Pmode,
17374 memory_address (Pmode, frame))),
17375 RETURN_ADDRESS_OFFSET)));
17378 cfun->machine->ra_need_lr = 1;
17379 return get_hard_reg_initial_val (Pmode, LR_REGNO);
17382 /* Say whether a function is a candidate for sibcall handling or not.
17383 We do not allow indirect calls to be optimized into sibling calls.
17384 Also, we can't do it if there are any vector parameters; there's
17385 nowhere to put the VRsave code so it works; note that functions with
17386 vector parameters are required to have a prototype, so the argument
17387 type info must be available here. (The tail recursion case can work
17388 with vector parameters, but there's no way to distinguish here.) */
17389 static bool
17390 rs6000_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED)
17392 tree type;
17393 if (decl)
17395 if (TARGET_ALTIVEC_VRSAVE)
17397 for (type = TYPE_ARG_TYPES (TREE_TYPE (decl));
17398 type; type = TREE_CHAIN (type))
17400 if (TREE_CODE (TREE_VALUE (type)) == VECTOR_TYPE)
17401 return false;
17404 if (DEFAULT_ABI == ABI_DARWIN
17405 || ((*targetm.binds_local_p) (decl)
17406 && (DEFAULT_ABI != ABI_AIX || !DECL_EXTERNAL (decl))))
17408 tree attr_list = TYPE_ATTRIBUTES (TREE_TYPE (decl));
17410 if (!lookup_attribute ("longcall", attr_list)
17411 || lookup_attribute ("shortcall", attr_list))
17412 return true;
17415 return false;
17418 /* NULL if INSN insn is valid within a low-overhead loop.
17419 Otherwise return why doloop cannot be applied.
17420 PowerPC uses the COUNT register for branch on table instructions. */
17422 static const char *
17423 rs6000_invalid_within_doloop (const_rtx insn)
17425 if (CALL_P (insn))
17426 return "Function call in the loop.";
17428 if (JUMP_P (insn)
17429 && (GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC
17430 || GET_CODE (PATTERN (insn)) == ADDR_VEC))
17431 return "Computed branch in the loop.";
17433 return NULL;
17436 static int
17437 rs6000_ra_ever_killed (void)
17439 rtx top;
17440 rtx reg;
17441 rtx insn;
17443 if (cfun->is_thunk)
17444 return 0;
17446 /* regs_ever_live has LR marked as used if any sibcalls are present,
17447 but this should not force saving and restoring in the
17448 pro/epilogue. Likewise, reg_set_between_p thinks a sibcall
17449 clobbers LR, so that is inappropriate. */
17451 /* Also, the prologue can generate a store into LR that
17452 doesn't really count, like this:
17454 move LR->R0
17455 bcl to set PIC register
17456 move LR->R31
17457 move R0->LR
17459 When we're called from the epilogue, we need to avoid counting
17460 this as a store. */
17462 push_topmost_sequence ();
17463 top = get_insns ();
17464 pop_topmost_sequence ();
17465 reg = gen_rtx_REG (Pmode, LR_REGNO);
17467 for (insn = NEXT_INSN (top); insn != NULL_RTX; insn = NEXT_INSN (insn))
17469 if (INSN_P (insn))
17471 if (CALL_P (insn))
17473 if (!SIBLING_CALL_P (insn))
17474 return 1;
17476 else if (find_regno_note (insn, REG_INC, LR_REGNO))
17477 return 1;
17478 else if (set_of (reg, insn) != NULL_RTX
17479 && !prologue_epilogue_contains (insn))
17480 return 1;
17483 return 0;
17486 /* Emit instructions needed to load the TOC register.
17487 This is only needed when TARGET_TOC, TARGET_MINIMAL_TOC, and there is
17488 a constant pool; or for SVR4 -fpic. */
17490 void
17491 rs6000_emit_load_toc_table (int fromprolog)
17493 rtx dest;
17494 dest = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
17496 if (TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI != ABI_AIX && flag_pic)
17498 char buf[30];
17499 rtx lab, tmp1, tmp2, got;
17501 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
17502 lab = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
17503 if (flag_pic == 2)
17504 got = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
17505 else
17506 got = rs6000_got_sym ();
17507 tmp1 = tmp2 = dest;
17508 if (!fromprolog)
17510 tmp1 = gen_reg_rtx (Pmode);
17511 tmp2 = gen_reg_rtx (Pmode);
17513 emit_insn (gen_load_toc_v4_PIC_1 (lab));
17514 emit_move_insn (tmp1,
17515 gen_rtx_REG (Pmode, LR_REGNO));
17516 emit_insn (gen_load_toc_v4_PIC_3b (tmp2, tmp1, got, lab));
17517 emit_insn (gen_load_toc_v4_PIC_3c (dest, tmp2, got, lab));
17519 else if (TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 1)
17521 emit_insn (gen_load_toc_v4_pic_si ());
17522 emit_move_insn (dest, gen_rtx_REG (Pmode, LR_REGNO));
17524 else if (TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2)
17526 char buf[30];
17527 rtx temp0 = (fromprolog
17528 ? gen_rtx_REG (Pmode, 0)
17529 : gen_reg_rtx (Pmode));
17531 if (fromprolog)
17533 rtx symF, symL;
17535 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
17536 symF = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
17538 ASM_GENERATE_INTERNAL_LABEL (buf, "LCL", rs6000_pic_labelno);
17539 symL = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
17541 emit_insn (gen_load_toc_v4_PIC_1 (symF));
17542 emit_move_insn (dest,
17543 gen_rtx_REG (Pmode, LR_REGNO));
17544 emit_insn (gen_load_toc_v4_PIC_2 (temp0, dest, symL, symF));
17546 else
17548 rtx tocsym;
17550 tocsym = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
17551 emit_insn (gen_load_toc_v4_PIC_1b (tocsym));
17552 emit_move_insn (dest,
17553 gen_rtx_REG (Pmode, LR_REGNO));
17554 emit_move_insn (temp0, gen_rtx_MEM (Pmode, dest));
17556 emit_insn (gen_addsi3 (dest, temp0, dest));
17558 else if (TARGET_ELF && !TARGET_AIX && flag_pic == 0 && TARGET_MINIMAL_TOC)
17560 /* This is for AIX code running in non-PIC ELF32. */
17561 char buf[30];
17562 rtx realsym;
17563 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
17564 realsym = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
17566 emit_insn (gen_elf_high (dest, realsym));
17567 emit_insn (gen_elf_low (dest, dest, realsym));
17569 else
17571 gcc_assert (DEFAULT_ABI == ABI_AIX);
17573 if (TARGET_32BIT)
17574 emit_insn (gen_load_toc_aix_si (dest));
17575 else
17576 emit_insn (gen_load_toc_aix_di (dest));
17580 /* Emit instructions to restore the link register after determining where
17581 its value has been stored. */
17583 void
17584 rs6000_emit_eh_reg_restore (rtx source, rtx scratch)
17586 rs6000_stack_t *info = rs6000_stack_info ();
17587 rtx operands[2];
17589 operands[0] = source;
17590 operands[1] = scratch;
17592 if (info->lr_save_p)
17594 rtx frame_rtx = stack_pointer_rtx;
17595 HOST_WIDE_INT sp_offset = 0;
17596 rtx tmp;
17598 if (frame_pointer_needed
17599 || cfun->calls_alloca
17600 || info->total_size > 32767)
17602 tmp = gen_frame_mem (Pmode, frame_rtx);
17603 emit_move_insn (operands[1], tmp);
17604 frame_rtx = operands[1];
17606 else if (info->push_p)
17607 sp_offset = info->total_size;
17609 tmp = plus_constant (frame_rtx, info->lr_save_offset + sp_offset);
17610 tmp = gen_frame_mem (Pmode, tmp);
17611 emit_move_insn (tmp, operands[0]);
17613 else
17614 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO), operands[0]);
17617 static GTY(()) alias_set_type set = -1;
17619 alias_set_type
17620 get_TOC_alias_set (void)
17622 if (set == -1)
17623 set = new_alias_set ();
17624 return set;
17627 /* This returns nonzero if the current function uses the TOC. This is
17628 determined by the presence of (use (unspec ... UNSPEC_TOC)), which
17629 is generated by the ABI_V4 load_toc_* patterns. */
17630 #if TARGET_ELF
17631 static int
17632 uses_TOC (void)
17634 rtx insn;
17636 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
17637 if (INSN_P (insn))
17639 rtx pat = PATTERN (insn);
17640 int i;
17642 if (GET_CODE (pat) == PARALLEL)
17643 for (i = 0; i < XVECLEN (pat, 0); i++)
17645 rtx sub = XVECEXP (pat, 0, i);
17646 if (GET_CODE (sub) == USE)
17648 sub = XEXP (sub, 0);
17649 if (GET_CODE (sub) == UNSPEC
17650 && XINT (sub, 1) == UNSPEC_TOC)
17651 return 1;
17655 return 0;
17657 #endif
17660 create_TOC_reference (rtx symbol)
17662 if (TARGET_DEBUG_ADDR)
17664 if (GET_CODE (symbol) == SYMBOL_REF)
17665 fprintf (stderr, "\ncreate_TOC_reference, (symbol_ref %s)\n",
17666 XSTR (symbol, 0));
17667 else
17669 fprintf (stderr, "\ncreate_TOC_reference, code %s:\n",
17670 GET_RTX_NAME (GET_CODE (symbol)));
17671 debug_rtx (symbol);
17675 if (!can_create_pseudo_p ())
17676 df_set_regs_ever_live (TOC_REGISTER, true);
17677 return gen_rtx_PLUS (Pmode,
17678 gen_rtx_REG (Pmode, TOC_REGISTER),
17679 gen_rtx_CONST (Pmode,
17680 gen_rtx_UNSPEC (Pmode, gen_rtvec (1, symbol), UNSPEC_TOCREL)));
17683 /* Issue assembly directives that create a reference to the given DWARF
17684 FRAME_TABLE_LABEL from the current function section. */
17685 void
17686 rs6000_aix_asm_output_dwarf_table_ref (char * frame_table_label)
17688 fprintf (asm_out_file, "\t.ref %s\n",
17689 TARGET_STRIP_NAME_ENCODING (frame_table_label));
17692 /* If _Unwind_* has been called from within the same module,
17693 toc register is not guaranteed to be saved to 40(1) on function
17694 entry. Save it there in that case. */
17696 void
17697 rs6000_aix_emit_builtin_unwind_init (void)
17699 rtx mem;
17700 rtx stack_top = gen_reg_rtx (Pmode);
17701 rtx opcode_addr = gen_reg_rtx (Pmode);
17702 rtx opcode = gen_reg_rtx (SImode);
17703 rtx tocompare = gen_reg_rtx (SImode);
17704 rtx no_toc_save_needed = gen_label_rtx ();
17706 mem = gen_frame_mem (Pmode, hard_frame_pointer_rtx);
17707 emit_move_insn (stack_top, mem);
17709 mem = gen_frame_mem (Pmode,
17710 gen_rtx_PLUS (Pmode, stack_top,
17711 GEN_INT (2 * GET_MODE_SIZE (Pmode))));
17712 emit_move_insn (opcode_addr, mem);
17713 emit_move_insn (opcode, gen_rtx_MEM (SImode, opcode_addr));
17714 emit_move_insn (tocompare, gen_int_mode (TARGET_32BIT ? 0x80410014
17715 : 0xE8410028, SImode));
17717 do_compare_rtx_and_jump (opcode, tocompare, EQ, 1,
17718 SImode, NULL_RTX, NULL_RTX,
17719 no_toc_save_needed);
17721 mem = gen_frame_mem (Pmode,
17722 gen_rtx_PLUS (Pmode, stack_top,
17723 GEN_INT (5 * GET_MODE_SIZE (Pmode))));
17724 emit_move_insn (mem, gen_rtx_REG (Pmode, 2));
17725 emit_label (no_toc_save_needed);
17728 /* This ties together stack memory (MEM with an alias set of frame_alias_set)
17729 and the change to the stack pointer. */
17731 static void
17732 rs6000_emit_stack_tie (void)
17734 rtx mem = gen_frame_mem (BLKmode,
17735 gen_rtx_REG (Pmode, STACK_POINTER_REGNUM));
17737 emit_insn (gen_stack_tie (mem));
17740 /* Emit the correct code for allocating stack space, as insns.
17741 If COPY_R12, make sure a copy of the old frame is left in r12.
17742 If COPY_R11, make sure a copy of the old frame is left in r11,
17743 in preference to r12 if COPY_R12.
17744 The generated code may use hard register 0 as a temporary. */
17746 static void
17747 rs6000_emit_allocate_stack (HOST_WIDE_INT size, int copy_r12, int copy_r11)
17749 rtx insn;
17750 rtx stack_reg = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
17751 rtx tmp_reg = gen_rtx_REG (Pmode, 0);
17752 rtx todec = gen_int_mode (-size, Pmode);
17753 rtx par, set, mem;
17755 if (INTVAL (todec) != -size)
17757 warning (0, "stack frame too large");
17758 emit_insn (gen_trap ());
17759 return;
17762 if (crtl->limit_stack)
17764 if (REG_P (stack_limit_rtx)
17765 && REGNO (stack_limit_rtx) > 1
17766 && REGNO (stack_limit_rtx) <= 31)
17768 emit_insn (gen_add3_insn (tmp_reg, stack_limit_rtx, GEN_INT (size)));
17769 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
17770 const0_rtx));
17772 else if (GET_CODE (stack_limit_rtx) == SYMBOL_REF
17773 && TARGET_32BIT
17774 && DEFAULT_ABI == ABI_V4)
17776 rtx toload = gen_rtx_CONST (VOIDmode,
17777 gen_rtx_PLUS (Pmode,
17778 stack_limit_rtx,
17779 GEN_INT (size)));
17781 emit_insn (gen_elf_high (tmp_reg, toload));
17782 emit_insn (gen_elf_low (tmp_reg, tmp_reg, toload));
17783 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
17784 const0_rtx));
17786 else
17787 warning (0, "stack limit expression is not supported");
17790 if (copy_r12 || copy_r11)
17791 emit_move_insn (copy_r11
17792 ? gen_rtx_REG (Pmode, 11)
17793 : gen_rtx_REG (Pmode, 12),
17794 stack_reg);
17796 if (size > 32767)
17798 /* Need a note here so that try_split doesn't get confused. */
17799 if (get_last_insn () == NULL_RTX)
17800 emit_note (NOTE_INSN_DELETED);
17801 insn = emit_move_insn (tmp_reg, todec);
17802 try_split (PATTERN (insn), insn, 0);
17803 todec = tmp_reg;
17806 insn = emit_insn (TARGET_32BIT
17807 ? gen_movsi_update_stack (stack_reg, stack_reg,
17808 todec, stack_reg)
17809 : gen_movdi_di_update_stack (stack_reg, stack_reg,
17810 todec, stack_reg));
17811 /* Since we didn't use gen_frame_mem to generate the MEM, grab
17812 it now and set the alias set/attributes. The above gen_*_update
17813 calls will generate a PARALLEL with the MEM set being the first
17814 operation. */
17815 par = PATTERN (insn);
17816 gcc_assert (GET_CODE (par) == PARALLEL);
17817 set = XVECEXP (par, 0, 0);
17818 gcc_assert (GET_CODE (set) == SET);
17819 mem = SET_DEST (set);
17820 gcc_assert (MEM_P (mem));
17821 MEM_NOTRAP_P (mem) = 1;
17822 set_mem_alias_set (mem, get_frame_alias_set ());
17824 RTX_FRAME_RELATED_P (insn) = 1;
17825 add_reg_note (insn, REG_FRAME_RELATED_EXPR,
17826 gen_rtx_SET (VOIDmode, stack_reg,
17827 gen_rtx_PLUS (Pmode, stack_reg,
17828 GEN_INT (-size))));
17831 /* Add to 'insn' a note which is PATTERN (INSN) but with REG replaced
17832 with (plus:P (reg 1) VAL), and with REG2 replaced with RREG if REG2
17833 is not NULL. It would be nice if dwarf2out_frame_debug_expr could
17834 deduce these equivalences by itself so it wasn't necessary to hold
17835 its hand so much. */
17837 static void
17838 rs6000_frame_related (rtx insn, rtx reg, HOST_WIDE_INT val,
17839 rtx reg2, rtx rreg)
17841 rtx real, temp;
17843 /* copy_rtx will not make unique copies of registers, so we need to
17844 ensure we don't have unwanted sharing here. */
17845 if (reg == reg2)
17846 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
17848 if (reg == rreg)
17849 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
17851 real = copy_rtx (PATTERN (insn));
17853 if (reg2 != NULL_RTX)
17854 real = replace_rtx (real, reg2, rreg);
17856 real = replace_rtx (real, reg,
17857 gen_rtx_PLUS (Pmode, gen_rtx_REG (Pmode,
17858 STACK_POINTER_REGNUM),
17859 GEN_INT (val)));
17861 /* We expect that 'real' is either a SET or a PARALLEL containing
17862 SETs (and possibly other stuff). In a PARALLEL, all the SETs
17863 are important so they all have to be marked RTX_FRAME_RELATED_P. */
17865 if (GET_CODE (real) == SET)
17867 rtx set = real;
17869 temp = simplify_rtx (SET_SRC (set));
17870 if (temp)
17871 SET_SRC (set) = temp;
17872 temp = simplify_rtx (SET_DEST (set));
17873 if (temp)
17874 SET_DEST (set) = temp;
17875 if (GET_CODE (SET_DEST (set)) == MEM)
17877 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
17878 if (temp)
17879 XEXP (SET_DEST (set), 0) = temp;
17882 else
17884 int i;
17886 gcc_assert (GET_CODE (real) == PARALLEL);
17887 for (i = 0; i < XVECLEN (real, 0); i++)
17888 if (GET_CODE (XVECEXP (real, 0, i)) == SET)
17890 rtx set = XVECEXP (real, 0, i);
17892 temp = simplify_rtx (SET_SRC (set));
17893 if (temp)
17894 SET_SRC (set) = temp;
17895 temp = simplify_rtx (SET_DEST (set));
17896 if (temp)
17897 SET_DEST (set) = temp;
17898 if (GET_CODE (SET_DEST (set)) == MEM)
17900 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
17901 if (temp)
17902 XEXP (SET_DEST (set), 0) = temp;
17904 RTX_FRAME_RELATED_P (set) = 1;
17908 RTX_FRAME_RELATED_P (insn) = 1;
17909 add_reg_note (insn, REG_FRAME_RELATED_EXPR, real);
17912 /* Returns an insn that has a vrsave set operation with the
17913 appropriate CLOBBERs. */
17915 static rtx
17916 generate_set_vrsave (rtx reg, rs6000_stack_t *info, int epiloguep)
17918 int nclobs, i;
17919 rtx insn, clobs[TOTAL_ALTIVEC_REGS + 1];
17920 rtx vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
17922 clobs[0]
17923 = gen_rtx_SET (VOIDmode,
17924 vrsave,
17925 gen_rtx_UNSPEC_VOLATILE (SImode,
17926 gen_rtvec (2, reg, vrsave),
17927 UNSPECV_SET_VRSAVE));
17929 nclobs = 1;
17931 /* We need to clobber the registers in the mask so the scheduler
17932 does not move sets to VRSAVE before sets of AltiVec registers.
17934 However, if the function receives nonlocal gotos, reload will set
17935 all call saved registers live. We will end up with:
17937 (set (reg 999) (mem))
17938 (parallel [ (set (reg vrsave) (unspec blah))
17939 (clobber (reg 999))])
17941 The clobber will cause the store into reg 999 to be dead, and
17942 flow will attempt to delete an epilogue insn. In this case, we
17943 need an unspec use/set of the register. */
17945 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
17946 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
17948 if (!epiloguep || call_used_regs [i])
17949 clobs[nclobs++] = gen_rtx_CLOBBER (VOIDmode,
17950 gen_rtx_REG (V4SImode, i));
17951 else
17953 rtx reg = gen_rtx_REG (V4SImode, i);
17955 clobs[nclobs++]
17956 = gen_rtx_SET (VOIDmode,
17957 reg,
17958 gen_rtx_UNSPEC (V4SImode,
17959 gen_rtvec (1, reg), 27));
17963 insn = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (nclobs));
17965 for (i = 0; i < nclobs; ++i)
17966 XVECEXP (insn, 0, i) = clobs[i];
17968 return insn;
17971 /* Save a register into the frame, and emit RTX_FRAME_RELATED_P notes.
17972 Save REGNO into [FRAME_REG + OFFSET] in mode MODE. */
17974 static void
17975 emit_frame_save (rtx frame_reg, rtx frame_ptr, enum machine_mode mode,
17976 unsigned int regno, int offset, HOST_WIDE_INT total_size)
17978 rtx reg, offset_rtx, insn, mem, addr, int_rtx;
17979 rtx replacea, replaceb;
17981 int_rtx = GEN_INT (offset);
17983 /* Some cases that need register indexed addressing. */
17984 if ((TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
17985 || (TARGET_VSX && VSX_VECTOR_MODE (mode))
17986 || (TARGET_E500_DOUBLE && mode == DFmode)
17987 || (TARGET_SPE_ABI
17988 && SPE_VECTOR_MODE (mode)
17989 && !SPE_CONST_OFFSET_OK (offset)))
17991 /* Whomever calls us must make sure r11 is available in the
17992 flow path of instructions in the prologue. */
17993 offset_rtx = gen_rtx_REG (Pmode, 11);
17994 emit_move_insn (offset_rtx, int_rtx);
17996 replacea = offset_rtx;
17997 replaceb = int_rtx;
17999 else
18001 offset_rtx = int_rtx;
18002 replacea = NULL_RTX;
18003 replaceb = NULL_RTX;
18006 reg = gen_rtx_REG (mode, regno);
18007 addr = gen_rtx_PLUS (Pmode, frame_reg, offset_rtx);
18008 mem = gen_frame_mem (mode, addr);
18010 insn = emit_move_insn (mem, reg);
18012 rs6000_frame_related (insn, frame_ptr, total_size, replacea, replaceb);
18015 /* Emit an offset memory reference suitable for a frame store, while
18016 converting to a valid addressing mode. */
18018 static rtx
18019 gen_frame_mem_offset (enum machine_mode mode, rtx reg, int offset)
18021 rtx int_rtx, offset_rtx;
18023 int_rtx = GEN_INT (offset);
18025 if ((TARGET_SPE_ABI && SPE_VECTOR_MODE (mode))
18026 || (TARGET_E500_DOUBLE && mode == DFmode))
18028 offset_rtx = gen_rtx_REG (Pmode, FIXED_SCRATCH);
18029 emit_move_insn (offset_rtx, int_rtx);
18031 else
18032 offset_rtx = int_rtx;
18034 return gen_frame_mem (mode, gen_rtx_PLUS (Pmode, reg, offset_rtx));
18037 /* Look for user-defined global regs. We should not save and restore these,
18038 and cannot use stmw/lmw if there are any in its range. */
18040 static bool
18041 no_global_regs_above (int first, bool gpr)
18043 int i;
18044 int last = gpr ? 32 : 64;
18045 for (i = first; i < last; i++)
18046 if (global_regs[i])
18047 return false;
18048 return true;
18051 #ifndef TARGET_FIX_AND_CONTINUE
18052 #define TARGET_FIX_AND_CONTINUE 0
18053 #endif
18055 /* It's really GPR 13 and FPR 14, but we need the smaller of the two. */
18056 #define FIRST_SAVRES_REGISTER FIRST_SAVED_GP_REGNO
18057 #define LAST_SAVRES_REGISTER 31
18058 #define N_SAVRES_REGISTERS (LAST_SAVRES_REGISTER - FIRST_SAVRES_REGISTER + 1)
18060 static GTY(()) rtx savres_routine_syms[N_SAVRES_REGISTERS][8];
18062 /* Temporary holding space for an out-of-line register save/restore
18063 routine name. */
18064 static char savres_routine_name[30];
18066 /* Return the name for an out-of-line register save/restore routine.
18067 We are saving/restoring GPRs if GPR is true. */
18069 static char *
18070 rs6000_savres_routine_name (rs6000_stack_t *info, int regno,
18071 bool savep, bool gpr, bool lr)
18073 const char *prefix = "";
18074 const char *suffix = "";
18076 /* Different targets are supposed to define
18077 {SAVE,RESTORE}_FP_{PREFIX,SUFFIX} with the idea that the needed
18078 routine name could be defined with:
18080 sprintf (name, "%s%d%s", SAVE_FP_PREFIX, regno, SAVE_FP_SUFFIX)
18082 This is a nice idea in practice, but in reality, things are
18083 complicated in several ways:
18085 - ELF targets have save/restore routines for GPRs.
18087 - SPE targets use different prefixes for 32/64-bit registers, and
18088 neither of them fit neatly in the FOO_{PREFIX,SUFFIX} regimen.
18090 - PPC64 ELF targets have routines for save/restore of GPRs that
18091 differ in what they do with the link register, so having a set
18092 prefix doesn't work. (We only use one of the save routines at
18093 the moment, though.)
18095 - PPC32 elf targets have "exit" versions of the restore routines
18096 that restore the link register and can save some extra space.
18097 These require an extra suffix. (There are also "tail" versions
18098 of the restore routines and "GOT" versions of the save routines,
18099 but we don't generate those at present. Same problems apply,
18100 though.)
18102 We deal with all this by synthesizing our own prefix/suffix and
18103 using that for the simple sprintf call shown above. */
18104 if (TARGET_SPE)
18106 /* No floating point saves on the SPE. */
18107 gcc_assert (gpr);
18109 if (savep)
18110 prefix = info->spe_64bit_regs_used ? "_save64gpr_" : "_save32gpr_";
18111 else
18112 prefix = info->spe_64bit_regs_used ? "_rest64gpr_" : "_rest32gpr_";
18114 if (lr)
18115 suffix = "_x";
18117 else if (DEFAULT_ABI == ABI_V4)
18119 if (TARGET_64BIT)
18120 goto aix_names;
18122 if (gpr)
18123 prefix = savep ? "_savegpr_" : "_restgpr_";
18124 else
18125 prefix = savep ? "_savefpr_" : "_restfpr_";
18127 if (lr)
18128 suffix = "_x";
18130 else if (DEFAULT_ABI == ABI_AIX)
18132 #ifndef POWERPC_LINUX
18133 /* No out-of-line save/restore routines for GPRs on AIX. */
18134 gcc_assert (!TARGET_AIX || !gpr);
18135 #endif
18137 aix_names:
18138 if (gpr)
18139 prefix = (savep
18140 ? (lr ? "_savegpr0_" : "_savegpr1_")
18141 : (lr ? "_restgpr0_" : "_restgpr1_"));
18142 #ifdef POWERPC_LINUX
18143 else if (lr)
18144 prefix = (savep ? "_savefpr_" : "_restfpr_");
18145 #endif
18146 else
18148 prefix = savep ? SAVE_FP_PREFIX : RESTORE_FP_PREFIX;
18149 suffix = savep ? SAVE_FP_SUFFIX : RESTORE_FP_SUFFIX;
18152 else if (DEFAULT_ABI == ABI_DARWIN)
18153 sorry ("Out-of-line save/restore routines not supported on Darwin");
18155 sprintf (savres_routine_name, "%s%d%s", prefix, regno, suffix);
18157 return savres_routine_name;
18160 /* Return an RTL SYMBOL_REF for an out-of-line register save/restore routine.
18161 We are saving/restoring GPRs if GPR is true. */
18163 static rtx
18164 rs6000_savres_routine_sym (rs6000_stack_t *info, bool savep,
18165 bool gpr, bool lr)
18167 int regno = gpr ? info->first_gp_reg_save : (info->first_fp_reg_save - 32);
18168 rtx sym;
18169 int select = ((savep ? 1 : 0) << 2
18170 | ((TARGET_SPE_ABI
18171 /* On the SPE, we never have any FPRs, but we do have
18172 32/64-bit versions of the routines. */
18173 ? (info->spe_64bit_regs_used ? 1 : 0)
18174 : (gpr ? 1 : 0)) << 1)
18175 | (lr ? 1: 0));
18177 /* Don't generate bogus routine names. */
18178 gcc_assert (FIRST_SAVRES_REGISTER <= regno
18179 && regno <= LAST_SAVRES_REGISTER);
18181 sym = savres_routine_syms[regno-FIRST_SAVRES_REGISTER][select];
18183 if (sym == NULL)
18185 char *name;
18187 name = rs6000_savres_routine_name (info, regno, savep, gpr, lr);
18189 sym = savres_routine_syms[regno-FIRST_SAVRES_REGISTER][select]
18190 = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (name));
18191 SYMBOL_REF_FLAGS (sym) |= SYMBOL_FLAG_FUNCTION;
18194 return sym;
18197 /* Emit a sequence of insns, including a stack tie if needed, for
18198 resetting the stack pointer. If SAVRES is true, then don't reset the
18199 stack pointer, but move the base of the frame into r11 for use by
18200 out-of-line register restore routines. */
18202 static rtx
18203 rs6000_emit_stack_reset (rs6000_stack_t *info,
18204 rtx sp_reg_rtx, rtx frame_reg_rtx,
18205 int sp_offset, bool savres)
18207 /* This blockage is needed so that sched doesn't decide to move
18208 the sp change before the register restores. */
18209 if (frame_reg_rtx != sp_reg_rtx
18210 || (TARGET_SPE_ABI
18211 && info->spe_64bit_regs_used != 0
18212 && info->first_gp_reg_save != 32))
18213 rs6000_emit_stack_tie ();
18215 if (frame_reg_rtx != sp_reg_rtx)
18217 if (sp_offset != 0)
18219 rtx dest_reg = savres ? gen_rtx_REG (Pmode, 11) : sp_reg_rtx;
18220 return emit_insn (gen_add3_insn (dest_reg, frame_reg_rtx,
18221 GEN_INT (sp_offset)));
18223 else if (!savres)
18224 return emit_move_insn (sp_reg_rtx, frame_reg_rtx);
18226 else if (sp_offset != 0)
18228 /* If we are restoring registers out-of-line, we will be using the
18229 "exit" variants of the restore routines, which will reset the
18230 stack for us. But we do need to point r11 into the right place
18231 for those routines. */
18232 rtx dest_reg = (savres
18233 ? gen_rtx_REG (Pmode, 11)
18234 : sp_reg_rtx);
18236 rtx insn = emit_insn (gen_add3_insn (dest_reg, sp_reg_rtx,
18237 GEN_INT (sp_offset)));
18238 if (!savres)
18239 return insn;
18241 return NULL_RTX;
18244 /* Construct a parallel rtx describing the effect of a call to an
18245 out-of-line register save/restore routine. */
18247 static rtx
18248 rs6000_make_savres_rtx (rs6000_stack_t *info,
18249 rtx frame_reg_rtx, int save_area_offset,
18250 enum machine_mode reg_mode,
18251 bool savep, bool gpr, bool lr)
18253 int i;
18254 int offset, start_reg, end_reg, n_regs;
18255 int reg_size = GET_MODE_SIZE (reg_mode);
18256 rtx sym;
18257 rtvec p;
18259 offset = 0;
18260 start_reg = (gpr
18261 ? info->first_gp_reg_save
18262 : info->first_fp_reg_save);
18263 end_reg = gpr ? 32 : 64;
18264 n_regs = end_reg - start_reg;
18265 p = rtvec_alloc ((lr ? 4 : 3) + n_regs);
18267 if (!savep && lr)
18268 RTVEC_ELT (p, offset++) = gen_rtx_RETURN (VOIDmode);
18270 RTVEC_ELT (p, offset++)
18271 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 65));
18273 sym = rs6000_savres_routine_sym (info, savep, gpr, lr);
18274 RTVEC_ELT (p, offset++) = gen_rtx_USE (VOIDmode, sym);
18275 RTVEC_ELT (p, offset++)
18276 = gen_rtx_USE (VOIDmode,
18277 gen_rtx_REG (Pmode, DEFAULT_ABI != ABI_AIX ? 11
18278 : gpr && !lr ? 12
18279 : 1));
18281 for (i = 0; i < end_reg - start_reg; i++)
18283 rtx addr, reg, mem;
18284 reg = gen_rtx_REG (reg_mode, start_reg + i);
18285 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18286 GEN_INT (save_area_offset + reg_size*i));
18287 mem = gen_frame_mem (reg_mode, addr);
18289 RTVEC_ELT (p, i + offset) = gen_rtx_SET (VOIDmode,
18290 savep ? mem : reg,
18291 savep ? reg : mem);
18294 if (savep && lr)
18296 rtx addr, reg, mem;
18297 reg = gen_rtx_REG (Pmode, 0);
18298 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18299 GEN_INT (info->lr_save_offset));
18300 mem = gen_frame_mem (Pmode, addr);
18301 RTVEC_ELT (p, i + offset) = gen_rtx_SET (VOIDmode, mem, reg);
18304 return gen_rtx_PARALLEL (VOIDmode, p);
18307 /* Determine whether the gp REG is really used. */
18309 static bool
18310 rs6000_reg_live_or_pic_offset_p (int reg)
18312 return ((df_regs_ever_live_p (reg)
18313 && (!call_used_regs[reg]
18314 || (reg == RS6000_PIC_OFFSET_TABLE_REGNUM
18315 && TARGET_TOC && TARGET_MINIMAL_TOC)))
18316 || (reg == RS6000_PIC_OFFSET_TABLE_REGNUM
18317 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
18318 || (DEFAULT_ABI == ABI_DARWIN && flag_pic))));
18321 enum {
18322 SAVRES_MULTIPLE = 0x1,
18323 SAVRES_INLINE_FPRS = 0x2,
18324 SAVRES_INLINE_GPRS = 0x4,
18325 SAVRES_NOINLINE_GPRS_SAVES_LR = 0x8,
18326 SAVRES_NOINLINE_FPRS_SAVES_LR = 0x10,
18327 SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR = 0x20
18330 /* Determine the strategy for savings/restoring registers. */
18332 static int
18333 rs6000_savres_strategy (rs6000_stack_t *info, bool savep,
18334 int using_static_chain_p, int sibcall)
18336 bool using_multiple_p;
18337 bool common;
18338 bool savres_fprs_inline;
18339 bool savres_gprs_inline;
18340 bool noclobber_global_gprs
18341 = no_global_regs_above (info->first_gp_reg_save, /*gpr=*/true);
18342 int strategy;
18344 using_multiple_p = (TARGET_MULTIPLE && ! TARGET_POWERPC64
18345 && (!TARGET_SPE_ABI
18346 || info->spe_64bit_regs_used == 0)
18347 && info->first_gp_reg_save < 31
18348 && noclobber_global_gprs);
18349 /* Don't bother to try to save things out-of-line if r11 is occupied
18350 by the static chain. It would require too much fiddling and the
18351 static chain is rarely used anyway. */
18352 common = (using_static_chain_p
18353 || sibcall
18354 || crtl->calls_eh_return
18355 || !info->lr_save_p
18356 || cfun->machine->ra_need_lr
18357 || info->total_size > 32767);
18358 savres_fprs_inline = (common
18359 || info->first_fp_reg_save == 64
18360 || !no_global_regs_above (info->first_fp_reg_save,
18361 /*gpr=*/false)
18362 /* The out-of-line FP routines use
18363 double-precision stores; we can't use those
18364 routines if we don't have such stores. */
18365 || (TARGET_HARD_FLOAT && !TARGET_DOUBLE_FLOAT)
18366 || FP_SAVE_INLINE (info->first_fp_reg_save));
18367 savres_gprs_inline = (common
18368 /* Saving CR interferes with the exit routines
18369 used on the SPE, so just punt here. */
18370 || (!savep
18371 && TARGET_SPE_ABI
18372 && info->spe_64bit_regs_used != 0
18373 && info->cr_save_p != 0)
18374 || info->first_gp_reg_save == 32
18375 || !noclobber_global_gprs
18376 || GP_SAVE_INLINE (info->first_gp_reg_save));
18378 if (savep)
18379 /* If we are going to use store multiple, then don't even bother
18380 with the out-of-line routines, since the store-multiple instruction
18381 will always be smaller. */
18382 savres_gprs_inline = savres_gprs_inline || using_multiple_p;
18383 else
18385 /* The situation is more complicated with load multiple. We'd
18386 prefer to use the out-of-line routines for restores, since the
18387 "exit" out-of-line routines can handle the restore of LR and
18388 the frame teardown. But we can only use the out-of-line
18389 routines if we know that we've used store multiple or
18390 out-of-line routines in the prologue, i.e. if we've saved all
18391 the registers from first_gp_reg_save. Otherwise, we risk
18392 loading garbage from the stack. Furthermore, we can only use
18393 the "exit" out-of-line gpr restore if we haven't saved any
18394 fprs. */
18395 bool saved_all = !savres_gprs_inline || using_multiple_p;
18397 if (saved_all && info->first_fp_reg_save != 64)
18398 /* We can't use the exit routine; use load multiple if it's
18399 available. */
18400 savres_gprs_inline = savres_gprs_inline || using_multiple_p;
18403 strategy = (using_multiple_p
18404 | (savres_fprs_inline << 1)
18405 | (savres_gprs_inline << 2));
18406 #ifdef POWERPC_LINUX
18407 if (TARGET_64BIT)
18409 if (!savres_fprs_inline)
18410 strategy |= SAVRES_NOINLINE_FPRS_SAVES_LR;
18411 else if (!savres_gprs_inline && info->first_fp_reg_save == 64)
18412 strategy |= SAVRES_NOINLINE_GPRS_SAVES_LR;
18414 #else
18415 if (TARGET_AIX && !savres_fprs_inline)
18416 strategy |= SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR;
18417 #endif
18418 return strategy;
18421 /* Emit function prologue as insns. */
18423 void
18424 rs6000_emit_prologue (void)
18426 rs6000_stack_t *info = rs6000_stack_info ();
18427 enum machine_mode reg_mode = Pmode;
18428 int reg_size = TARGET_32BIT ? 4 : 8;
18429 rtx sp_reg_rtx = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
18430 rtx frame_ptr_rtx = gen_rtx_REG (Pmode, 12);
18431 rtx frame_reg_rtx = sp_reg_rtx;
18432 rtx cr_save_rtx = NULL_RTX;
18433 rtx insn;
18434 int strategy;
18435 int saving_FPRs_inline;
18436 int saving_GPRs_inline;
18437 int using_store_multiple;
18438 int using_static_chain_p = (cfun->static_chain_decl != NULL_TREE
18439 && df_regs_ever_live_p (STATIC_CHAIN_REGNUM)
18440 && call_used_regs[STATIC_CHAIN_REGNUM]);
18441 HOST_WIDE_INT sp_offset = 0;
18443 if (TARGET_FIX_AND_CONTINUE)
18445 /* gdb on darwin arranges to forward a function from the old
18446 address by modifying the first 5 instructions of the function
18447 to branch to the overriding function. This is necessary to
18448 permit function pointers that point to the old function to
18449 actually forward to the new function. */
18450 emit_insn (gen_nop ());
18451 emit_insn (gen_nop ());
18452 emit_insn (gen_nop ());
18453 emit_insn (gen_nop ());
18454 emit_insn (gen_nop ());
18457 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
18459 reg_mode = V2SImode;
18460 reg_size = 8;
18463 strategy = rs6000_savres_strategy (info, /*savep=*/true,
18464 /*static_chain_p=*/using_static_chain_p,
18465 /*sibcall=*/0);
18466 using_store_multiple = strategy & SAVRES_MULTIPLE;
18467 saving_FPRs_inline = strategy & SAVRES_INLINE_FPRS;
18468 saving_GPRs_inline = strategy & SAVRES_INLINE_GPRS;
18470 /* For V.4, update stack before we do any saving and set back pointer. */
18471 if (! WORLD_SAVE_P (info)
18472 && info->push_p
18473 && (DEFAULT_ABI == ABI_V4
18474 || crtl->calls_eh_return))
18476 bool need_r11 = (TARGET_SPE
18477 ? (!saving_GPRs_inline
18478 && info->spe_64bit_regs_used == 0)
18479 : (!saving_FPRs_inline || !saving_GPRs_inline));
18480 if (info->total_size < 32767)
18481 sp_offset = info->total_size;
18482 else
18483 frame_reg_rtx = (need_r11
18484 ? gen_rtx_REG (Pmode, 11)
18485 : frame_ptr_rtx);
18486 rs6000_emit_allocate_stack (info->total_size,
18487 (frame_reg_rtx != sp_reg_rtx
18488 && (info->cr_save_p
18489 || info->lr_save_p
18490 || info->first_fp_reg_save < 64
18491 || info->first_gp_reg_save < 32
18493 need_r11);
18494 if (frame_reg_rtx != sp_reg_rtx)
18495 rs6000_emit_stack_tie ();
18498 /* Handle world saves specially here. */
18499 if (WORLD_SAVE_P (info))
18501 int i, j, sz;
18502 rtx treg;
18503 rtvec p;
18504 rtx reg0;
18506 /* save_world expects lr in r0. */
18507 reg0 = gen_rtx_REG (Pmode, 0);
18508 if (info->lr_save_p)
18510 insn = emit_move_insn (reg0,
18511 gen_rtx_REG (Pmode, LR_REGNO));
18512 RTX_FRAME_RELATED_P (insn) = 1;
18515 /* The SAVE_WORLD and RESTORE_WORLD routines make a number of
18516 assumptions about the offsets of various bits of the stack
18517 frame. */
18518 gcc_assert (info->gp_save_offset == -220
18519 && info->fp_save_offset == -144
18520 && info->lr_save_offset == 8
18521 && info->cr_save_offset == 4
18522 && info->push_p
18523 && info->lr_save_p
18524 && (!crtl->calls_eh_return
18525 || info->ehrd_offset == -432)
18526 && info->vrsave_save_offset == -224
18527 && info->altivec_save_offset == -416);
18529 treg = gen_rtx_REG (SImode, 11);
18530 emit_move_insn (treg, GEN_INT (-info->total_size));
18532 /* SAVE_WORLD takes the caller's LR in R0 and the frame size
18533 in R11. It also clobbers R12, so beware! */
18535 /* Preserve CR2 for save_world prologues */
18536 sz = 5;
18537 sz += 32 - info->first_gp_reg_save;
18538 sz += 64 - info->first_fp_reg_save;
18539 sz += LAST_ALTIVEC_REGNO - info->first_altivec_reg_save + 1;
18540 p = rtvec_alloc (sz);
18541 j = 0;
18542 RTVEC_ELT (p, j++) = gen_rtx_CLOBBER (VOIDmode,
18543 gen_rtx_REG (SImode,
18544 LR_REGNO));
18545 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
18546 gen_rtx_SYMBOL_REF (Pmode,
18547 "*save_world"));
18548 /* We do floats first so that the instruction pattern matches
18549 properly. */
18550 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
18552 rtx reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
18553 ? DFmode : SFmode),
18554 info->first_fp_reg_save + i);
18555 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18556 GEN_INT (info->fp_save_offset
18557 + sp_offset + 8 * i));
18558 rtx mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
18559 ? DFmode : SFmode), addr);
18561 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
18563 for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++)
18565 rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i);
18566 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18567 GEN_INT (info->altivec_save_offset
18568 + sp_offset + 16 * i));
18569 rtx mem = gen_frame_mem (V4SImode, addr);
18571 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
18573 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
18575 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
18576 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18577 GEN_INT (info->gp_save_offset
18578 + sp_offset + reg_size * i));
18579 rtx mem = gen_frame_mem (reg_mode, addr);
18581 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
18585 /* CR register traditionally saved as CR2. */
18586 rtx reg = gen_rtx_REG (reg_mode, CR2_REGNO);
18587 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18588 GEN_INT (info->cr_save_offset
18589 + sp_offset));
18590 rtx mem = gen_frame_mem (reg_mode, addr);
18592 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
18594 /* Explain about use of R0. */
18595 if (info->lr_save_p)
18597 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18598 GEN_INT (info->lr_save_offset
18599 + sp_offset));
18600 rtx mem = gen_frame_mem (reg_mode, addr);
18602 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg0);
18604 /* Explain what happens to the stack pointer. */
18606 rtx newval = gen_rtx_PLUS (Pmode, sp_reg_rtx, treg);
18607 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, sp_reg_rtx, newval);
18610 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
18611 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
18612 treg, GEN_INT (-info->total_size));
18613 sp_offset = info->total_size;
18616 /* If we use the link register, get it into r0. */
18617 if (!WORLD_SAVE_P (info) && info->lr_save_p)
18619 rtx addr, reg, mem;
18621 insn = emit_move_insn (gen_rtx_REG (Pmode, 0),
18622 gen_rtx_REG (Pmode, LR_REGNO));
18623 RTX_FRAME_RELATED_P (insn) = 1;
18625 if (!(strategy & (SAVRES_NOINLINE_GPRS_SAVES_LR
18626 | SAVRES_NOINLINE_FPRS_SAVES_LR)))
18628 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18629 GEN_INT (info->lr_save_offset + sp_offset));
18630 reg = gen_rtx_REG (Pmode, 0);
18631 mem = gen_rtx_MEM (Pmode, addr);
18632 /* This should not be of rs6000_sr_alias_set, because of
18633 __builtin_return_address. */
18635 insn = emit_move_insn (mem, reg);
18636 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
18637 NULL_RTX, NULL_RTX);
18641 /* If we need to save CR, put it into r12 or r11. */
18642 if (!WORLD_SAVE_P (info) && info->cr_save_p && frame_reg_rtx != frame_ptr_rtx)
18644 rtx set;
18646 cr_save_rtx
18647 = gen_rtx_REG (SImode, DEFAULT_ABI == ABI_AIX && !saving_GPRs_inline
18648 ? 11 : 12);
18649 insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
18650 RTX_FRAME_RELATED_P (insn) = 1;
18651 /* Now, there's no way that dwarf2out_frame_debug_expr is going
18652 to understand '(unspec:SI [(reg:CC 68) ...] UNSPEC_MOVESI_FROM_CR)'.
18653 But that's OK. All we have to do is specify that _one_ condition
18654 code register is saved in this stack slot. The thrower's epilogue
18655 will then restore all the call-saved registers.
18656 We use CR2_REGNO (70) to be compatible with gcc-2.95 on Linux. */
18657 set = gen_rtx_SET (VOIDmode, cr_save_rtx,
18658 gen_rtx_REG (SImode, CR2_REGNO));
18659 add_reg_note (insn, REG_FRAME_RELATED_EXPR, set);
18662 /* Do any required saving of fpr's. If only one or two to save, do
18663 it ourselves. Otherwise, call function. */
18664 if (!WORLD_SAVE_P (info) && saving_FPRs_inline)
18666 int i;
18667 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
18668 if ((df_regs_ever_live_p (info->first_fp_reg_save+i)
18669 && ! call_used_regs[info->first_fp_reg_save+i]))
18670 emit_frame_save (frame_reg_rtx, frame_ptr_rtx,
18671 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
18672 ? DFmode : SFmode,
18673 info->first_fp_reg_save + i,
18674 info->fp_save_offset + sp_offset + 8 * i,
18675 info->total_size);
18677 else if (!WORLD_SAVE_P (info) && info->first_fp_reg_save != 64)
18679 rtx par;
18681 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
18682 info->fp_save_offset + sp_offset,
18683 DFmode,
18684 /*savep=*/true, /*gpr=*/false,
18685 /*lr=*/(strategy
18686 & SAVRES_NOINLINE_FPRS_SAVES_LR)
18687 != 0);
18688 insn = emit_insn (par);
18689 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
18690 NULL_RTX, NULL_RTX);
18693 /* Save GPRs. This is done as a PARALLEL if we are using
18694 the store-multiple instructions. */
18695 if (!WORLD_SAVE_P (info)
18696 && TARGET_SPE_ABI
18697 && info->spe_64bit_regs_used != 0
18698 && info->first_gp_reg_save != 32)
18700 int i;
18701 rtx spe_save_area_ptr;
18703 /* Determine whether we can address all of the registers that need
18704 to be saved with an offset from the stack pointer that fits in
18705 the small const field for SPE memory instructions. */
18706 int spe_regs_addressable_via_sp
18707 = (SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset
18708 + (32 - info->first_gp_reg_save - 1) * reg_size)
18709 && saving_GPRs_inline);
18710 int spe_offset;
18712 if (spe_regs_addressable_via_sp)
18714 spe_save_area_ptr = frame_reg_rtx;
18715 spe_offset = info->spe_gp_save_offset + sp_offset;
18717 else
18719 /* Make r11 point to the start of the SPE save area. We need
18720 to be careful here if r11 is holding the static chain. If
18721 it is, then temporarily save it in r0. We would use r0 as
18722 our base register here, but using r0 as a base register in
18723 loads and stores means something different from what we
18724 would like. */
18725 int ool_adjust = (saving_GPRs_inline
18727 : (info->first_gp_reg_save
18728 - (FIRST_SAVRES_REGISTER+1))*8);
18729 HOST_WIDE_INT offset = (info->spe_gp_save_offset
18730 + sp_offset - ool_adjust);
18732 if (using_static_chain_p)
18734 rtx r0 = gen_rtx_REG (Pmode, 0);
18735 gcc_assert (info->first_gp_reg_save > 11);
18737 emit_move_insn (r0, gen_rtx_REG (Pmode, 11));
18740 spe_save_area_ptr = gen_rtx_REG (Pmode, 11);
18741 insn = emit_insn (gen_addsi3 (spe_save_area_ptr,
18742 frame_reg_rtx,
18743 GEN_INT (offset)));
18744 /* We need to make sure the move to r11 gets noted for
18745 properly outputting unwind information. */
18746 if (!saving_GPRs_inline)
18747 rs6000_frame_related (insn, frame_reg_rtx, offset,
18748 NULL_RTX, NULL_RTX);
18749 spe_offset = 0;
18752 if (saving_GPRs_inline)
18754 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
18755 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
18757 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
18758 rtx offset, addr, mem;
18760 /* We're doing all this to ensure that the offset fits into
18761 the immediate offset of 'evstdd'. */
18762 gcc_assert (SPE_CONST_OFFSET_OK (reg_size * i + spe_offset));
18764 offset = GEN_INT (reg_size * i + spe_offset);
18765 addr = gen_rtx_PLUS (Pmode, spe_save_area_ptr, offset);
18766 mem = gen_rtx_MEM (V2SImode, addr);
18768 insn = emit_move_insn (mem, reg);
18770 rs6000_frame_related (insn, spe_save_area_ptr,
18771 info->spe_gp_save_offset
18772 + sp_offset + reg_size * i,
18773 offset, const0_rtx);
18776 else
18778 rtx par;
18780 par = rs6000_make_savres_rtx (info, gen_rtx_REG (Pmode, 11),
18781 0, reg_mode,
18782 /*savep=*/true, /*gpr=*/true,
18783 /*lr=*/false);
18784 insn = emit_insn (par);
18785 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
18786 NULL_RTX, NULL_RTX);
18790 /* Move the static chain pointer back. */
18791 if (using_static_chain_p && !spe_regs_addressable_via_sp)
18792 emit_move_insn (gen_rtx_REG (Pmode, 11), gen_rtx_REG (Pmode, 0));
18794 else if (!WORLD_SAVE_P (info) && !saving_GPRs_inline)
18796 rtx par;
18798 /* Need to adjust r11 (r12) if we saved any FPRs. */
18799 if (info->first_fp_reg_save != 64)
18801 rtx dest_reg = gen_rtx_REG (reg_mode, DEFAULT_ABI == ABI_AIX
18802 ? 12 : 11);
18803 rtx offset = GEN_INT (sp_offset
18804 + (-8 * (64-info->first_fp_reg_save)));
18805 emit_insn (gen_add3_insn (dest_reg, frame_reg_rtx, offset));
18808 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
18809 info->gp_save_offset + sp_offset,
18810 reg_mode,
18811 /*savep=*/true, /*gpr=*/true,
18812 /*lr=*/(strategy
18813 & SAVRES_NOINLINE_GPRS_SAVES_LR)
18814 != 0);
18815 insn = emit_insn (par);
18816 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
18817 NULL_RTX, NULL_RTX);
18819 else if (!WORLD_SAVE_P (info) && using_store_multiple)
18821 rtvec p;
18822 int i;
18823 p = rtvec_alloc (32 - info->first_gp_reg_save);
18824 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
18826 rtx addr, reg, mem;
18827 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
18828 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18829 GEN_INT (info->gp_save_offset
18830 + sp_offset
18831 + reg_size * i));
18832 mem = gen_frame_mem (reg_mode, addr);
18834 RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, mem, reg);
18836 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
18837 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
18838 NULL_RTX, NULL_RTX);
18840 else if (!WORLD_SAVE_P (info))
18842 int i;
18843 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
18844 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
18846 rtx addr, reg, mem;
18847 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
18849 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18850 GEN_INT (info->gp_save_offset
18851 + sp_offset
18852 + reg_size * i));
18853 mem = gen_frame_mem (reg_mode, addr);
18855 insn = emit_move_insn (mem, reg);
18856 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
18857 NULL_RTX, NULL_RTX);
18861 /* ??? There's no need to emit actual instructions here, but it's the
18862 easiest way to get the frame unwind information emitted. */
18863 if (crtl->calls_eh_return)
18865 unsigned int i, regno;
18867 /* In AIX ABI we need to pretend we save r2 here. */
18868 if (TARGET_AIX)
18870 rtx addr, reg, mem;
18872 reg = gen_rtx_REG (reg_mode, 2);
18873 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18874 GEN_INT (sp_offset + 5 * reg_size));
18875 mem = gen_frame_mem (reg_mode, addr);
18877 insn = emit_move_insn (mem, reg);
18878 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
18879 NULL_RTX, NULL_RTX);
18880 PATTERN (insn) = gen_blockage ();
18883 for (i = 0; ; ++i)
18885 regno = EH_RETURN_DATA_REGNO (i);
18886 if (regno == INVALID_REGNUM)
18887 break;
18889 emit_frame_save (frame_reg_rtx, frame_ptr_rtx, reg_mode, regno,
18890 info->ehrd_offset + sp_offset
18891 + reg_size * (int) i,
18892 info->total_size);
18896 /* Save CR if we use any that must be preserved. */
18897 if (!WORLD_SAVE_P (info) && info->cr_save_p)
18899 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18900 GEN_INT (info->cr_save_offset + sp_offset));
18901 rtx mem = gen_frame_mem (SImode, addr);
18902 /* See the large comment above about why CR2_REGNO is used. */
18903 rtx magic_eh_cr_reg = gen_rtx_REG (SImode, CR2_REGNO);
18905 /* If r12 was used to hold the original sp, copy cr into r0 now
18906 that it's free. */
18907 if (REGNO (frame_reg_rtx) == 12)
18909 rtx set;
18911 cr_save_rtx = gen_rtx_REG (SImode, 0);
18912 insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
18913 RTX_FRAME_RELATED_P (insn) = 1;
18914 set = gen_rtx_SET (VOIDmode, cr_save_rtx, magic_eh_cr_reg);
18915 add_reg_note (insn, REG_FRAME_RELATED_EXPR, set);
18917 insn = emit_move_insn (mem, cr_save_rtx);
18919 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
18920 NULL_RTX, NULL_RTX);
18923 /* Update stack and set back pointer unless this is V.4,
18924 for which it was done previously. */
18925 if (!WORLD_SAVE_P (info) && info->push_p
18926 && !(DEFAULT_ABI == ABI_V4 || crtl->calls_eh_return))
18928 if (info->total_size < 32767)
18929 sp_offset = info->total_size;
18930 else
18931 frame_reg_rtx = frame_ptr_rtx;
18932 rs6000_emit_allocate_stack (info->total_size,
18933 (frame_reg_rtx != sp_reg_rtx
18934 && ((info->altivec_size != 0)
18935 || (info->vrsave_mask != 0)
18937 FALSE);
18938 if (frame_reg_rtx != sp_reg_rtx)
18939 rs6000_emit_stack_tie ();
18942 /* Set frame pointer, if needed. */
18943 if (frame_pointer_needed)
18945 insn = emit_move_insn (gen_rtx_REG (Pmode, HARD_FRAME_POINTER_REGNUM),
18946 sp_reg_rtx);
18947 RTX_FRAME_RELATED_P (insn) = 1;
18950 /* Save AltiVec registers if needed. Save here because the red zone does
18951 not include AltiVec registers. */
18952 if (!WORLD_SAVE_P (info) && TARGET_ALTIVEC_ABI && info->altivec_size != 0)
18954 int i;
18956 /* There should be a non inline version of this, for when we
18957 are saving lots of vector registers. */
18958 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
18959 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
18961 rtx areg, savereg, mem;
18962 int offset;
18964 offset = info->altivec_save_offset + sp_offset
18965 + 16 * (i - info->first_altivec_reg_save);
18967 savereg = gen_rtx_REG (V4SImode, i);
18969 areg = gen_rtx_REG (Pmode, 0);
18970 emit_move_insn (areg, GEN_INT (offset));
18972 /* AltiVec addressing mode is [reg+reg]. */
18973 mem = gen_frame_mem (V4SImode,
18974 gen_rtx_PLUS (Pmode, frame_reg_rtx, areg));
18976 insn = emit_move_insn (mem, savereg);
18978 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
18979 areg, GEN_INT (offset));
18983 /* VRSAVE is a bit vector representing which AltiVec registers
18984 are used. The OS uses this to determine which vector
18985 registers to save on a context switch. We need to save
18986 VRSAVE on the stack frame, add whatever AltiVec registers we
18987 used in this function, and do the corresponding magic in the
18988 epilogue. */
18990 if (TARGET_ALTIVEC && TARGET_ALTIVEC_VRSAVE
18991 && info->vrsave_mask != 0)
18993 rtx reg, mem, vrsave;
18994 int offset;
18996 /* Get VRSAVE onto a GPR. Note that ABI_V4 might be using r12
18997 as frame_reg_rtx and r11 as the static chain pointer for
18998 nested functions. */
18999 reg = gen_rtx_REG (SImode, 0);
19000 vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
19001 if (TARGET_MACHO)
19002 emit_insn (gen_get_vrsave_internal (reg));
19003 else
19004 emit_insn (gen_rtx_SET (VOIDmode, reg, vrsave));
19006 if (!WORLD_SAVE_P (info))
19008 /* Save VRSAVE. */
19009 offset = info->vrsave_save_offset + sp_offset;
19010 mem = gen_frame_mem (SImode,
19011 gen_rtx_PLUS (Pmode, frame_reg_rtx,
19012 GEN_INT (offset)));
19013 insn = emit_move_insn (mem, reg);
19016 /* Include the registers in the mask. */
19017 emit_insn (gen_iorsi3 (reg, reg, GEN_INT ((int) info->vrsave_mask)));
19019 insn = emit_insn (generate_set_vrsave (reg, info, 0));
19022 /* If we are using RS6000_PIC_OFFSET_TABLE_REGNUM, we need to set it up. */
19023 if ((TARGET_TOC && TARGET_MINIMAL_TOC && get_pool_size () != 0)
19024 || (DEFAULT_ABI == ABI_V4
19025 && (flag_pic == 1 || (flag_pic && TARGET_SECURE_PLT))
19026 && df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM)))
19028 /* If emit_load_toc_table will use the link register, we need to save
19029 it. We use R12 for this purpose because emit_load_toc_table
19030 can use register 0. This allows us to use a plain 'blr' to return
19031 from the procedure more often. */
19032 int save_LR_around_toc_setup = (TARGET_ELF
19033 && DEFAULT_ABI != ABI_AIX
19034 && flag_pic
19035 && ! info->lr_save_p
19036 && EDGE_COUNT (EXIT_BLOCK_PTR->preds) > 0);
19037 if (save_LR_around_toc_setup)
19039 rtx lr = gen_rtx_REG (Pmode, LR_REGNO);
19041 insn = emit_move_insn (frame_ptr_rtx, lr);
19042 RTX_FRAME_RELATED_P (insn) = 1;
19044 rs6000_emit_load_toc_table (TRUE);
19046 insn = emit_move_insn (lr, frame_ptr_rtx);
19047 RTX_FRAME_RELATED_P (insn) = 1;
19049 else
19050 rs6000_emit_load_toc_table (TRUE);
19053 #if TARGET_MACHO
19054 if (DEFAULT_ABI == ABI_DARWIN
19055 && flag_pic && crtl->uses_pic_offset_table)
19057 rtx lr = gen_rtx_REG (Pmode, LR_REGNO);
19058 rtx src = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
19060 /* Save and restore LR locally around this call (in R0). */
19061 if (!info->lr_save_p)
19062 emit_move_insn (gen_rtx_REG (Pmode, 0), lr);
19064 emit_insn (gen_load_macho_picbase (src));
19066 emit_move_insn (gen_rtx_REG (Pmode,
19067 RS6000_PIC_OFFSET_TABLE_REGNUM),
19068 lr);
19070 if (!info->lr_save_p)
19071 emit_move_insn (lr, gen_rtx_REG (Pmode, 0));
19073 #endif
19076 /* Write function prologue. */
19078 static void
19079 rs6000_output_function_prologue (FILE *file,
19080 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
19082 rs6000_stack_t *info = rs6000_stack_info ();
19084 if (TARGET_DEBUG_STACK)
19085 debug_stack_info (info);
19087 /* Write .extern for any function we will call to save and restore
19088 fp values. */
19089 if (info->first_fp_reg_save < 64
19090 && !FP_SAVE_INLINE (info->first_fp_reg_save))
19092 char *name;
19093 int regno = info->first_fp_reg_save - 32;
19095 name = rs6000_savres_routine_name (info, regno, /*savep=*/true,
19096 /*gpr=*/false, /*lr=*/false);
19097 fprintf (file, "\t.extern %s\n", name);
19099 name = rs6000_savres_routine_name (info, regno, /*savep=*/false,
19100 /*gpr=*/false, /*lr=*/true);
19101 fprintf (file, "\t.extern %s\n", name);
19104 /* Write .extern for AIX common mode routines, if needed. */
19105 if (! TARGET_POWER && ! TARGET_POWERPC && ! common_mode_defined)
19107 fputs ("\t.extern __mulh\n", file);
19108 fputs ("\t.extern __mull\n", file);
19109 fputs ("\t.extern __divss\n", file);
19110 fputs ("\t.extern __divus\n", file);
19111 fputs ("\t.extern __quoss\n", file);
19112 fputs ("\t.extern __quous\n", file);
19113 common_mode_defined = 1;
19116 if (! HAVE_prologue)
19118 rtx prologue;
19120 start_sequence ();
19122 /* A NOTE_INSN_DELETED is supposed to be at the start and end of
19123 the "toplevel" insn chain. */
19124 emit_note (NOTE_INSN_DELETED);
19125 rs6000_emit_prologue ();
19126 emit_note (NOTE_INSN_DELETED);
19128 /* Expand INSN_ADDRESSES so final() doesn't crash. */
19130 rtx insn;
19131 unsigned addr = 0;
19132 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
19134 INSN_ADDRESSES_NEW (insn, addr);
19135 addr += 4;
19139 prologue = get_insns ();
19140 end_sequence ();
19142 if (TARGET_DEBUG_STACK)
19143 debug_rtx_list (prologue, 100);
19145 emit_insn_before_noloc (prologue, BB_HEAD (ENTRY_BLOCK_PTR->next_bb),
19146 ENTRY_BLOCK_PTR);
19149 rs6000_pic_labelno++;
19152 /* Non-zero if vmx regs are restored before the frame pop, zero if
19153 we restore after the pop when possible. */
19154 #define ALWAYS_RESTORE_ALTIVEC_BEFORE_POP 0
19156 /* Reload CR from REG. */
19158 static void
19159 rs6000_restore_saved_cr (rtx reg, int using_mfcr_multiple)
19161 int count = 0;
19162 int i;
19164 if (using_mfcr_multiple)
19166 for (i = 0; i < 8; i++)
19167 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
19168 count++;
19169 gcc_assert (count);
19172 if (using_mfcr_multiple && count > 1)
19174 rtvec p;
19175 int ndx;
19177 p = rtvec_alloc (count);
19179 ndx = 0;
19180 for (i = 0; i < 8; i++)
19181 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
19183 rtvec r = rtvec_alloc (2);
19184 RTVEC_ELT (r, 0) = reg;
19185 RTVEC_ELT (r, 1) = GEN_INT (1 << (7-i));
19186 RTVEC_ELT (p, ndx) =
19187 gen_rtx_SET (VOIDmode, gen_rtx_REG (CCmode, CR0_REGNO+i),
19188 gen_rtx_UNSPEC (CCmode, r, UNSPEC_MOVESI_TO_CR));
19189 ndx++;
19191 emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
19192 gcc_assert (ndx == count);
19194 else
19195 for (i = 0; i < 8; i++)
19196 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
19198 emit_insn (gen_movsi_to_cr_one (gen_rtx_REG (CCmode,
19199 CR0_REGNO+i),
19200 reg));
19204 /* Return true if OFFSET from stack pointer can be clobbered by signals.
19205 V.4 doesn't have any stack cushion, AIX ABIs have 220 or 288 bytes
19206 below stack pointer not cloberred by signals. */
19208 static inline bool
19209 offset_below_red_zone_p (HOST_WIDE_INT offset)
19211 return offset < (DEFAULT_ABI == ABI_V4
19213 : TARGET_32BIT ? -220 : -288);
19216 /* Emit function epilogue as insns. */
19218 void
19219 rs6000_emit_epilogue (int sibcall)
19221 rs6000_stack_t *info;
19222 int restoring_GPRs_inline;
19223 int restoring_FPRs_inline;
19224 int using_load_multiple;
19225 int using_mtcr_multiple;
19226 int use_backchain_to_restore_sp;
19227 int restore_lr;
19228 int strategy;
19229 int sp_offset = 0;
19230 rtx sp_reg_rtx = gen_rtx_REG (Pmode, 1);
19231 rtx frame_reg_rtx = sp_reg_rtx;
19232 rtx cfa_restores = NULL_RTX;
19233 rtx insn;
19234 rtx cr_save_reg = NULL_RTX;
19235 enum machine_mode reg_mode = Pmode;
19236 int reg_size = TARGET_32BIT ? 4 : 8;
19237 int i;
19239 info = rs6000_stack_info ();
19241 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
19243 reg_mode = V2SImode;
19244 reg_size = 8;
19247 strategy = rs6000_savres_strategy (info, /*savep=*/false,
19248 /*static_chain_p=*/0, sibcall);
19249 using_load_multiple = strategy & SAVRES_MULTIPLE;
19250 restoring_FPRs_inline = strategy & SAVRES_INLINE_FPRS;
19251 restoring_GPRs_inline = strategy & SAVRES_INLINE_GPRS;
19252 using_mtcr_multiple = (rs6000_cpu == PROCESSOR_PPC601
19253 || rs6000_cpu == PROCESSOR_PPC603
19254 || rs6000_cpu == PROCESSOR_PPC750
19255 || optimize_size);
19256 /* Restore via the backchain when we have a large frame, since this
19257 is more efficient than an addis, addi pair. The second condition
19258 here will not trigger at the moment; We don't actually need a
19259 frame pointer for alloca, but the generic parts of the compiler
19260 give us one anyway. */
19261 use_backchain_to_restore_sp = (info->total_size > 32767
19262 || info->total_size
19263 + (info->lr_save_p ? info->lr_save_offset : 0)
19264 > 32767
19265 || (cfun->calls_alloca
19266 && !frame_pointer_needed));
19267 restore_lr = (info->lr_save_p
19268 && (restoring_FPRs_inline
19269 || (strategy & SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR))
19270 && (restoring_GPRs_inline
19271 || info->first_fp_reg_save < 64));
19273 if (WORLD_SAVE_P (info))
19275 int i, j;
19276 char rname[30];
19277 const char *alloc_rname;
19278 rtvec p;
19280 /* eh_rest_world_r10 will return to the location saved in the LR
19281 stack slot (which is not likely to be our caller.)
19282 Input: R10 -- stack adjustment. Clobbers R0, R11, R12, R7, R8.
19283 rest_world is similar, except any R10 parameter is ignored.
19284 The exception-handling stuff that was here in 2.95 is no
19285 longer necessary. */
19287 p = rtvec_alloc (9
19289 + 32 - info->first_gp_reg_save
19290 + LAST_ALTIVEC_REGNO + 1 - info->first_altivec_reg_save
19291 + 63 + 1 - info->first_fp_reg_save);
19293 strcpy (rname, ((crtl->calls_eh_return) ?
19294 "*eh_rest_world_r10" : "*rest_world"));
19295 alloc_rname = ggc_strdup (rname);
19297 j = 0;
19298 RTVEC_ELT (p, j++) = gen_rtx_RETURN (VOIDmode);
19299 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
19300 gen_rtx_REG (Pmode,
19301 LR_REGNO));
19302 RTVEC_ELT (p, j++)
19303 = gen_rtx_USE (VOIDmode, gen_rtx_SYMBOL_REF (Pmode, alloc_rname));
19304 /* The instruction pattern requires a clobber here;
19305 it is shared with the restVEC helper. */
19306 RTVEC_ELT (p, j++)
19307 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 11));
19310 /* CR register traditionally saved as CR2. */
19311 rtx reg = gen_rtx_REG (reg_mode, CR2_REGNO);
19312 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19313 GEN_INT (info->cr_save_offset));
19314 rtx mem = gen_frame_mem (reg_mode, addr);
19316 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
19319 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
19321 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
19322 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19323 GEN_INT (info->gp_save_offset
19324 + reg_size * i));
19325 rtx mem = gen_frame_mem (reg_mode, addr);
19327 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
19329 for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++)
19331 rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i);
19332 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19333 GEN_INT (info->altivec_save_offset
19334 + 16 * i));
19335 rtx mem = gen_frame_mem (V4SImode, addr);
19337 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
19339 for (i = 0; info->first_fp_reg_save + i <= 63; i++)
19341 rtx reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
19342 ? DFmode : SFmode),
19343 info->first_fp_reg_save + i);
19344 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19345 GEN_INT (info->fp_save_offset
19346 + 8 * i));
19347 rtx mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
19348 ? DFmode : SFmode), addr);
19350 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
19352 RTVEC_ELT (p, j++)
19353 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 0));
19354 RTVEC_ELT (p, j++)
19355 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 12));
19356 RTVEC_ELT (p, j++)
19357 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 7));
19358 RTVEC_ELT (p, j++)
19359 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 8));
19360 RTVEC_ELT (p, j++)
19361 = gen_rtx_USE (VOIDmode, gen_rtx_REG (SImode, 10));
19362 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
19364 return;
19367 /* frame_reg_rtx + sp_offset points to the top of this stack frame. */
19368 if (info->push_p)
19369 sp_offset = info->total_size;
19371 /* Restore AltiVec registers if we must do so before adjusting the
19372 stack. */
19373 if (TARGET_ALTIVEC_ABI
19374 && info->altivec_size != 0
19375 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
19376 || (DEFAULT_ABI != ABI_V4
19377 && offset_below_red_zone_p (info->altivec_save_offset))))
19379 int i;
19381 if (use_backchain_to_restore_sp)
19383 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
19384 emit_move_insn (frame_reg_rtx,
19385 gen_rtx_MEM (Pmode, sp_reg_rtx));
19386 sp_offset = 0;
19388 else if (frame_pointer_needed)
19389 frame_reg_rtx = hard_frame_pointer_rtx;
19391 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
19392 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
19394 rtx addr, areg, mem, reg;
19396 areg = gen_rtx_REG (Pmode, 0);
19397 emit_move_insn
19398 (areg, GEN_INT (info->altivec_save_offset
19399 + sp_offset
19400 + 16 * (i - info->first_altivec_reg_save)));
19402 /* AltiVec addressing mode is [reg+reg]. */
19403 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
19404 mem = gen_frame_mem (V4SImode, addr);
19406 reg = gen_rtx_REG (V4SImode, i);
19407 emit_move_insn (reg, mem);
19408 if (offset_below_red_zone_p (info->altivec_save_offset
19409 + (i - info->first_altivec_reg_save)
19410 * 16))
19411 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
19412 cfa_restores);
19416 /* Restore VRSAVE if we must do so before adjusting the stack. */
19417 if (TARGET_ALTIVEC
19418 && TARGET_ALTIVEC_VRSAVE
19419 && info->vrsave_mask != 0
19420 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
19421 || (DEFAULT_ABI != ABI_V4
19422 && offset_below_red_zone_p (info->vrsave_save_offset))))
19424 rtx addr, mem, reg;
19426 if (frame_reg_rtx == sp_reg_rtx)
19428 if (use_backchain_to_restore_sp)
19430 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
19431 emit_move_insn (frame_reg_rtx,
19432 gen_rtx_MEM (Pmode, sp_reg_rtx));
19433 sp_offset = 0;
19435 else if (frame_pointer_needed)
19436 frame_reg_rtx = hard_frame_pointer_rtx;
19439 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19440 GEN_INT (info->vrsave_save_offset + sp_offset));
19441 mem = gen_frame_mem (SImode, addr);
19442 reg = gen_rtx_REG (SImode, 12);
19443 emit_move_insn (reg, mem);
19445 emit_insn (generate_set_vrsave (reg, info, 1));
19448 insn = NULL_RTX;
19449 /* If we have a large stack frame, restore the old stack pointer
19450 using the backchain. */
19451 if (use_backchain_to_restore_sp)
19453 if (frame_reg_rtx == sp_reg_rtx)
19455 /* Under V.4, don't reset the stack pointer until after we're done
19456 loading the saved registers. */
19457 if (DEFAULT_ABI == ABI_V4)
19458 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
19460 insn = emit_move_insn (frame_reg_rtx,
19461 gen_rtx_MEM (Pmode, sp_reg_rtx));
19462 sp_offset = 0;
19464 else if (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
19465 && DEFAULT_ABI == ABI_V4)
19466 /* frame_reg_rtx has been set up by the altivec restore. */
19468 else
19470 insn = emit_move_insn (sp_reg_rtx, frame_reg_rtx);
19471 frame_reg_rtx = sp_reg_rtx;
19474 /* If we have a frame pointer, we can restore the old stack pointer
19475 from it. */
19476 else if (frame_pointer_needed)
19478 frame_reg_rtx = sp_reg_rtx;
19479 if (DEFAULT_ABI == ABI_V4)
19480 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
19482 insn = emit_insn (gen_add3_insn (frame_reg_rtx, hard_frame_pointer_rtx,
19483 GEN_INT (info->total_size)));
19484 sp_offset = 0;
19486 else if (info->push_p
19487 && DEFAULT_ABI != ABI_V4
19488 && !crtl->calls_eh_return)
19490 insn = emit_insn (gen_add3_insn (sp_reg_rtx, sp_reg_rtx,
19491 GEN_INT (info->total_size)));
19492 sp_offset = 0;
19494 if (insn && frame_reg_rtx == sp_reg_rtx)
19496 if (cfa_restores)
19498 REG_NOTES (insn) = cfa_restores;
19499 cfa_restores = NULL_RTX;
19501 add_reg_note (insn, REG_CFA_DEF_CFA, sp_reg_rtx);
19502 RTX_FRAME_RELATED_P (insn) = 1;
19505 /* Restore AltiVec registers if we have not done so already. */
19506 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
19507 && TARGET_ALTIVEC_ABI
19508 && info->altivec_size != 0
19509 && (DEFAULT_ABI == ABI_V4
19510 || !offset_below_red_zone_p (info->altivec_save_offset)))
19512 int i;
19514 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
19515 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
19517 rtx addr, areg, mem, reg;
19519 areg = gen_rtx_REG (Pmode, 0);
19520 emit_move_insn
19521 (areg, GEN_INT (info->altivec_save_offset
19522 + sp_offset
19523 + 16 * (i - info->first_altivec_reg_save)));
19525 /* AltiVec addressing mode is [reg+reg]. */
19526 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
19527 mem = gen_frame_mem (V4SImode, addr);
19529 reg = gen_rtx_REG (V4SImode, i);
19530 emit_move_insn (reg, mem);
19531 if (DEFAULT_ABI == ABI_V4)
19532 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
19533 cfa_restores);
19537 /* Restore VRSAVE if we have not done so already. */
19538 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
19539 && TARGET_ALTIVEC
19540 && TARGET_ALTIVEC_VRSAVE
19541 && info->vrsave_mask != 0
19542 && (DEFAULT_ABI == ABI_V4
19543 || !offset_below_red_zone_p (info->vrsave_save_offset)))
19545 rtx addr, mem, reg;
19547 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19548 GEN_INT (info->vrsave_save_offset + sp_offset));
19549 mem = gen_frame_mem (SImode, addr);
19550 reg = gen_rtx_REG (SImode, 12);
19551 emit_move_insn (reg, mem);
19553 emit_insn (generate_set_vrsave (reg, info, 1));
19556 /* Get the old lr if we saved it. If we are restoring registers
19557 out-of-line, then the out-of-line routines can do this for us. */
19558 if (restore_lr && restoring_GPRs_inline)
19560 rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
19561 info->lr_save_offset + sp_offset);
19563 emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
19566 /* Get the old cr if we saved it. */
19567 if (info->cr_save_p)
19569 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19570 GEN_INT (info->cr_save_offset + sp_offset));
19571 rtx mem = gen_frame_mem (SImode, addr);
19573 cr_save_reg = gen_rtx_REG (SImode,
19574 DEFAULT_ABI == ABI_AIX
19575 && !restoring_GPRs_inline
19576 && info->first_fp_reg_save < 64
19577 ? 11 : 12);
19578 emit_move_insn (cr_save_reg, mem);
19581 /* Set LR here to try to overlap restores below. LR is always saved
19582 above incoming stack, so it never needs REG_CFA_RESTORE. */
19583 if (restore_lr && restoring_GPRs_inline)
19584 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO),
19585 gen_rtx_REG (Pmode, 0));
19587 /* Load exception handler data registers, if needed. */
19588 if (crtl->calls_eh_return)
19590 unsigned int i, regno;
19592 if (TARGET_AIX)
19594 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19595 GEN_INT (sp_offset + 5 * reg_size));
19596 rtx mem = gen_frame_mem (reg_mode, addr);
19598 emit_move_insn (gen_rtx_REG (reg_mode, 2), mem);
19601 for (i = 0; ; ++i)
19603 rtx mem;
19605 regno = EH_RETURN_DATA_REGNO (i);
19606 if (regno == INVALID_REGNUM)
19607 break;
19609 mem = gen_frame_mem_offset (reg_mode, frame_reg_rtx,
19610 info->ehrd_offset + sp_offset
19611 + reg_size * (int) i);
19613 emit_move_insn (gen_rtx_REG (reg_mode, regno), mem);
19617 /* Restore GPRs. This is done as a PARALLEL if we are using
19618 the load-multiple instructions. */
19619 if (TARGET_SPE_ABI
19620 && info->spe_64bit_regs_used != 0
19621 && info->first_gp_reg_save != 32)
19623 /* Determine whether we can address all of the registers that need
19624 to be saved with an offset from the stack pointer that fits in
19625 the small const field for SPE memory instructions. */
19626 int spe_regs_addressable_via_sp
19627 = (SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset
19628 + (32 - info->first_gp_reg_save - 1) * reg_size)
19629 && restoring_GPRs_inline);
19630 int spe_offset;
19632 if (spe_regs_addressable_via_sp)
19633 spe_offset = info->spe_gp_save_offset + sp_offset;
19634 else
19636 rtx old_frame_reg_rtx = frame_reg_rtx;
19637 /* Make r11 point to the start of the SPE save area. We worried about
19638 not clobbering it when we were saving registers in the prologue.
19639 There's no need to worry here because the static chain is passed
19640 anew to every function. */
19641 int ool_adjust = (restoring_GPRs_inline
19643 : (info->first_gp_reg_save
19644 - (FIRST_SAVRES_REGISTER+1))*8);
19646 if (frame_reg_rtx == sp_reg_rtx)
19647 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
19648 emit_insn (gen_addsi3 (frame_reg_rtx, old_frame_reg_rtx,
19649 GEN_INT (info->spe_gp_save_offset
19650 + sp_offset
19651 - ool_adjust)));
19652 /* Keep the invariant that frame_reg_rtx + sp_offset points
19653 at the top of the stack frame. */
19654 sp_offset = -info->spe_gp_save_offset;
19656 spe_offset = 0;
19659 if (restoring_GPRs_inline)
19661 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
19662 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
19664 rtx offset, addr, mem, reg;
19666 /* We're doing all this to ensure that the immediate offset
19667 fits into the immediate field of 'evldd'. */
19668 gcc_assert (SPE_CONST_OFFSET_OK (spe_offset + reg_size * i));
19670 offset = GEN_INT (spe_offset + reg_size * i);
19671 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, offset);
19672 mem = gen_rtx_MEM (V2SImode, addr);
19673 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
19675 insn = emit_move_insn (reg, mem);
19676 if (DEFAULT_ABI == ABI_V4)
19678 if (frame_pointer_needed
19679 && info->first_gp_reg_save + i
19680 == HARD_FRAME_POINTER_REGNUM)
19682 add_reg_note (insn, REG_CFA_DEF_CFA,
19683 plus_constant (frame_reg_rtx,
19684 sp_offset));
19685 RTX_FRAME_RELATED_P (insn) = 1;
19688 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
19689 cfa_restores);
19693 else
19695 rtx par;
19697 par = rs6000_make_savres_rtx (info, gen_rtx_REG (Pmode, 11),
19698 0, reg_mode,
19699 /*savep=*/false, /*gpr=*/true,
19700 /*lr=*/true);
19701 emit_jump_insn (par);
19702 /* We don't want anybody else emitting things after we jumped
19703 back. */
19704 return;
19707 else if (!restoring_GPRs_inline)
19709 /* We are jumping to an out-of-line function. */
19710 bool can_use_exit = info->first_fp_reg_save == 64;
19711 rtx par;
19713 /* Emit stack reset code if we need it. */
19714 if (can_use_exit)
19715 rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx,
19716 sp_offset, can_use_exit);
19717 else
19719 emit_insn (gen_add3_insn (gen_rtx_REG (Pmode, DEFAULT_ABI == ABI_AIX
19720 ? 12 : 11),
19721 frame_reg_rtx,
19722 GEN_INT (sp_offset - info->fp_size)));
19723 if (REGNO (frame_reg_rtx) == 11)
19724 sp_offset += info->fp_size;
19727 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
19728 info->gp_save_offset, reg_mode,
19729 /*savep=*/false, /*gpr=*/true,
19730 /*lr=*/can_use_exit);
19732 if (can_use_exit)
19734 if (info->cr_save_p)
19736 rs6000_restore_saved_cr (cr_save_reg, using_mtcr_multiple);
19737 if (DEFAULT_ABI == ABI_V4)
19738 cfa_restores
19739 = alloc_reg_note (REG_CFA_RESTORE,
19740 gen_rtx_REG (SImode, CR2_REGNO),
19741 cfa_restores);
19744 emit_jump_insn (par);
19746 /* We don't want anybody else emitting things after we jumped
19747 back. */
19748 return;
19751 insn = emit_insn (par);
19752 if (DEFAULT_ABI == ABI_V4)
19754 if (frame_pointer_needed)
19756 add_reg_note (insn, REG_CFA_DEF_CFA,
19757 plus_constant (frame_reg_rtx, sp_offset));
19758 RTX_FRAME_RELATED_P (insn) = 1;
19761 for (i = info->first_gp_reg_save; i < 32; i++)
19762 cfa_restores
19763 = alloc_reg_note (REG_CFA_RESTORE,
19764 gen_rtx_REG (reg_mode, i), cfa_restores);
19767 else if (using_load_multiple)
19769 rtvec p;
19770 p = rtvec_alloc (32 - info->first_gp_reg_save);
19771 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
19773 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19774 GEN_INT (info->gp_save_offset
19775 + sp_offset
19776 + reg_size * i));
19777 rtx mem = gen_frame_mem (reg_mode, addr);
19778 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
19780 RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, reg, mem);
19781 if (DEFAULT_ABI == ABI_V4)
19782 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
19783 cfa_restores);
19785 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
19786 if (DEFAULT_ABI == ABI_V4 && frame_pointer_needed)
19788 add_reg_note (insn, REG_CFA_DEF_CFA,
19789 plus_constant (frame_reg_rtx, sp_offset));
19790 RTX_FRAME_RELATED_P (insn) = 1;
19793 else
19795 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
19796 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
19798 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19799 GEN_INT (info->gp_save_offset
19800 + sp_offset
19801 + reg_size * i));
19802 rtx mem = gen_frame_mem (reg_mode, addr);
19803 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
19805 insn = emit_move_insn (reg, mem);
19806 if (DEFAULT_ABI == ABI_V4)
19808 if (frame_pointer_needed
19809 && info->first_gp_reg_save + i
19810 == HARD_FRAME_POINTER_REGNUM)
19812 add_reg_note (insn, REG_CFA_DEF_CFA,
19813 plus_constant (frame_reg_rtx, sp_offset));
19814 RTX_FRAME_RELATED_P (insn) = 1;
19817 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
19818 cfa_restores);
19823 if (restore_lr && !restoring_GPRs_inline)
19825 rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
19826 info->lr_save_offset + sp_offset);
19828 emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
19829 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO),
19830 gen_rtx_REG (Pmode, 0));
19833 /* Restore fpr's if we need to do it without calling a function. */
19834 if (restoring_FPRs_inline)
19835 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
19836 if ((df_regs_ever_live_p (info->first_fp_reg_save+i)
19837 && ! call_used_regs[info->first_fp_reg_save+i]))
19839 rtx addr, mem, reg;
19840 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19841 GEN_INT (info->fp_save_offset
19842 + sp_offset
19843 + 8 * i));
19844 mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
19845 ? DFmode : SFmode), addr);
19846 reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
19847 ? DFmode : SFmode),
19848 info->first_fp_reg_save + i);
19850 emit_move_insn (reg, mem);
19851 if (DEFAULT_ABI == ABI_V4)
19852 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
19853 cfa_restores);
19856 /* If we saved cr, restore it here. Just those that were used. */
19857 if (info->cr_save_p)
19859 rs6000_restore_saved_cr (cr_save_reg, using_mtcr_multiple);
19860 if (DEFAULT_ABI == ABI_V4)
19861 cfa_restores
19862 = alloc_reg_note (REG_CFA_RESTORE, gen_rtx_REG (SImode, CR2_REGNO),
19863 cfa_restores);
19866 /* If this is V.4, unwind the stack pointer after all of the loads
19867 have been done. */
19868 insn = rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx,
19869 sp_offset, !restoring_FPRs_inline);
19870 if (insn)
19872 if (cfa_restores)
19874 REG_NOTES (insn) = cfa_restores;
19875 cfa_restores = NULL_RTX;
19877 add_reg_note (insn, REG_CFA_DEF_CFA, sp_reg_rtx);
19878 RTX_FRAME_RELATED_P (insn) = 1;
19881 if (crtl->calls_eh_return)
19883 rtx sa = EH_RETURN_STACKADJ_RTX;
19884 emit_insn (gen_add3_insn (sp_reg_rtx, sp_reg_rtx, sa));
19887 if (!sibcall)
19889 rtvec p;
19890 bool lr = (strategy & SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR) == 0;
19891 if (! restoring_FPRs_inline)
19892 p = rtvec_alloc (4 + 64 - info->first_fp_reg_save);
19893 else
19894 p = rtvec_alloc (2);
19896 RTVEC_ELT (p, 0) = gen_rtx_RETURN (VOIDmode);
19897 RTVEC_ELT (p, 1) = ((restoring_FPRs_inline || !lr)
19898 ? gen_rtx_USE (VOIDmode, gen_rtx_REG (Pmode, 65))
19899 : gen_rtx_CLOBBER (VOIDmode,
19900 gen_rtx_REG (Pmode, 65)));
19902 /* If we have to restore more than two FP registers, branch to the
19903 restore function. It will return to our caller. */
19904 if (! restoring_FPRs_inline)
19906 int i;
19907 rtx sym;
19909 sym = rs6000_savres_routine_sym (info,
19910 /*savep=*/false,
19911 /*gpr=*/false,
19912 /*lr=*/lr);
19913 RTVEC_ELT (p, 2) = gen_rtx_USE (VOIDmode, sym);
19914 RTVEC_ELT (p, 3) = gen_rtx_USE (VOIDmode,
19915 gen_rtx_REG (Pmode,
19916 DEFAULT_ABI == ABI_AIX
19917 ? 1 : 11));
19918 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
19920 rtx addr, mem;
19921 addr = gen_rtx_PLUS (Pmode, sp_reg_rtx,
19922 GEN_INT (info->fp_save_offset + 8*i));
19923 mem = gen_frame_mem (DFmode, addr);
19925 RTVEC_ELT (p, i+4) =
19926 gen_rtx_SET (VOIDmode,
19927 gen_rtx_REG (DFmode, info->first_fp_reg_save + i),
19928 mem);
19932 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
19936 /* Write function epilogue. */
19938 static void
19939 rs6000_output_function_epilogue (FILE *file,
19940 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
19942 if (! HAVE_epilogue)
19944 rtx insn = get_last_insn ();
19945 /* If the last insn was a BARRIER, we don't have to write anything except
19946 the trace table. */
19947 if (GET_CODE (insn) == NOTE)
19948 insn = prev_nonnote_insn (insn);
19949 if (insn == 0 || GET_CODE (insn) != BARRIER)
19951 /* This is slightly ugly, but at least we don't have two
19952 copies of the epilogue-emitting code. */
19953 start_sequence ();
19955 /* A NOTE_INSN_DELETED is supposed to be at the start
19956 and end of the "toplevel" insn chain. */
19957 emit_note (NOTE_INSN_DELETED);
19958 rs6000_emit_epilogue (FALSE);
19959 emit_note (NOTE_INSN_DELETED);
19961 /* Expand INSN_ADDRESSES so final() doesn't crash. */
19963 rtx insn;
19964 unsigned addr = 0;
19965 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
19967 INSN_ADDRESSES_NEW (insn, addr);
19968 addr += 4;
19972 if (TARGET_DEBUG_STACK)
19973 debug_rtx_list (get_insns (), 100);
19974 final (get_insns (), file, FALSE);
19975 end_sequence ();
19979 #if TARGET_MACHO
19980 macho_branch_islands ();
19981 /* Mach-O doesn't support labels at the end of objects, so if
19982 it looks like we might want one, insert a NOP. */
19984 rtx insn = get_last_insn ();
19985 while (insn
19986 && NOTE_P (insn)
19987 && NOTE_KIND (insn) != NOTE_INSN_DELETED_LABEL)
19988 insn = PREV_INSN (insn);
19989 if (insn
19990 && (LABEL_P (insn)
19991 || (NOTE_P (insn)
19992 && NOTE_KIND (insn) == NOTE_INSN_DELETED_LABEL)))
19993 fputs ("\tnop\n", file);
19995 #endif
19997 /* Output a traceback table here. See /usr/include/sys/debug.h for info
19998 on its format.
20000 We don't output a traceback table if -finhibit-size-directive was
20001 used. The documentation for -finhibit-size-directive reads
20002 ``don't output a @code{.size} assembler directive, or anything
20003 else that would cause trouble if the function is split in the
20004 middle, and the two halves are placed at locations far apart in
20005 memory.'' The traceback table has this property, since it
20006 includes the offset from the start of the function to the
20007 traceback table itself.
20009 System V.4 Powerpc's (and the embedded ABI derived from it) use a
20010 different traceback table. */
20011 if (DEFAULT_ABI == ABI_AIX && ! flag_inhibit_size_directive
20012 && rs6000_traceback != traceback_none && !cfun->is_thunk)
20014 const char *fname = NULL;
20015 const char *language_string = lang_hooks.name;
20016 int fixed_parms = 0, float_parms = 0, parm_info = 0;
20017 int i;
20018 int optional_tbtab;
20019 rs6000_stack_t *info = rs6000_stack_info ();
20021 if (rs6000_traceback == traceback_full)
20022 optional_tbtab = 1;
20023 else if (rs6000_traceback == traceback_part)
20024 optional_tbtab = 0;
20025 else
20026 optional_tbtab = !optimize_size && !TARGET_ELF;
20028 if (optional_tbtab)
20030 fname = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0);
20031 while (*fname == '.') /* V.4 encodes . in the name */
20032 fname++;
20034 /* Need label immediately before tbtab, so we can compute
20035 its offset from the function start. */
20036 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
20037 ASM_OUTPUT_LABEL (file, fname);
20040 /* The .tbtab pseudo-op can only be used for the first eight
20041 expressions, since it can't handle the possibly variable
20042 length fields that follow. However, if you omit the optional
20043 fields, the assembler outputs zeros for all optional fields
20044 anyways, giving each variable length field is minimum length
20045 (as defined in sys/debug.h). Thus we can not use the .tbtab
20046 pseudo-op at all. */
20048 /* An all-zero word flags the start of the tbtab, for debuggers
20049 that have to find it by searching forward from the entry
20050 point or from the current pc. */
20051 fputs ("\t.long 0\n", file);
20053 /* Tbtab format type. Use format type 0. */
20054 fputs ("\t.byte 0,", file);
20056 /* Language type. Unfortunately, there does not seem to be any
20057 official way to discover the language being compiled, so we
20058 use language_string.
20059 C is 0. Fortran is 1. Pascal is 2. Ada is 3. C++ is 9.
20060 Java is 13. Objective-C is 14. Objective-C++ isn't assigned
20061 a number, so for now use 9. */
20062 if (! strcmp (language_string, "GNU C"))
20063 i = 0;
20064 else if (! strcmp (language_string, "GNU F77")
20065 || ! strcmp (language_string, "GNU Fortran"))
20066 i = 1;
20067 else if (! strcmp (language_string, "GNU Pascal"))
20068 i = 2;
20069 else if (! strcmp (language_string, "GNU Ada"))
20070 i = 3;
20071 else if (! strcmp (language_string, "GNU C++")
20072 || ! strcmp (language_string, "GNU Objective-C++"))
20073 i = 9;
20074 else if (! strcmp (language_string, "GNU Java"))
20075 i = 13;
20076 else if (! strcmp (language_string, "GNU Objective-C"))
20077 i = 14;
20078 else
20079 gcc_unreachable ();
20080 fprintf (file, "%d,", i);
20082 /* 8 single bit fields: global linkage (not set for C extern linkage,
20083 apparently a PL/I convention?), out-of-line epilogue/prologue, offset
20084 from start of procedure stored in tbtab, internal function, function
20085 has controlled storage, function has no toc, function uses fp,
20086 function logs/aborts fp operations. */
20087 /* Assume that fp operations are used if any fp reg must be saved. */
20088 fprintf (file, "%d,",
20089 (optional_tbtab << 5) | ((info->first_fp_reg_save != 64) << 1));
20091 /* 6 bitfields: function is interrupt handler, name present in
20092 proc table, function calls alloca, on condition directives
20093 (controls stack walks, 3 bits), saves condition reg, saves
20094 link reg. */
20095 /* The `function calls alloca' bit seems to be set whenever reg 31 is
20096 set up as a frame pointer, even when there is no alloca call. */
20097 fprintf (file, "%d,",
20098 ((optional_tbtab << 6)
20099 | ((optional_tbtab & frame_pointer_needed) << 5)
20100 | (info->cr_save_p << 1)
20101 | (info->lr_save_p)));
20103 /* 3 bitfields: saves backchain, fixup code, number of fpr saved
20104 (6 bits). */
20105 fprintf (file, "%d,",
20106 (info->push_p << 7) | (64 - info->first_fp_reg_save));
20108 /* 2 bitfields: spare bits (2 bits), number of gpr saved (6 bits). */
20109 fprintf (file, "%d,", (32 - first_reg_to_save ()));
20111 if (optional_tbtab)
20113 /* Compute the parameter info from the function decl argument
20114 list. */
20115 tree decl;
20116 int next_parm_info_bit = 31;
20118 for (decl = DECL_ARGUMENTS (current_function_decl);
20119 decl; decl = TREE_CHAIN (decl))
20121 rtx parameter = DECL_INCOMING_RTL (decl);
20122 enum machine_mode mode = GET_MODE (parameter);
20124 if (GET_CODE (parameter) == REG)
20126 if (SCALAR_FLOAT_MODE_P (mode))
20128 int bits;
20130 float_parms++;
20132 switch (mode)
20134 case SFmode:
20135 case SDmode:
20136 bits = 0x2;
20137 break;
20139 case DFmode:
20140 case DDmode:
20141 case TFmode:
20142 case TDmode:
20143 bits = 0x3;
20144 break;
20146 default:
20147 gcc_unreachable ();
20150 /* If only one bit will fit, don't or in this entry. */
20151 if (next_parm_info_bit > 0)
20152 parm_info |= (bits << (next_parm_info_bit - 1));
20153 next_parm_info_bit -= 2;
20155 else
20157 fixed_parms += ((GET_MODE_SIZE (mode)
20158 + (UNITS_PER_WORD - 1))
20159 / UNITS_PER_WORD);
20160 next_parm_info_bit -= 1;
20166 /* Number of fixed point parameters. */
20167 /* This is actually the number of words of fixed point parameters; thus
20168 an 8 byte struct counts as 2; and thus the maximum value is 8. */
20169 fprintf (file, "%d,", fixed_parms);
20171 /* 2 bitfields: number of floating point parameters (7 bits), parameters
20172 all on stack. */
20173 /* This is actually the number of fp registers that hold parameters;
20174 and thus the maximum value is 13. */
20175 /* Set parameters on stack bit if parameters are not in their original
20176 registers, regardless of whether they are on the stack? Xlc
20177 seems to set the bit when not optimizing. */
20178 fprintf (file, "%d\n", ((float_parms << 1) | (! optimize)));
20180 if (! optional_tbtab)
20181 return;
20183 /* Optional fields follow. Some are variable length. */
20185 /* Parameter types, left adjusted bit fields: 0 fixed, 10 single float,
20186 11 double float. */
20187 /* There is an entry for each parameter in a register, in the order that
20188 they occur in the parameter list. Any intervening arguments on the
20189 stack are ignored. If the list overflows a long (max possible length
20190 34 bits) then completely leave off all elements that don't fit. */
20191 /* Only emit this long if there was at least one parameter. */
20192 if (fixed_parms || float_parms)
20193 fprintf (file, "\t.long %d\n", parm_info);
20195 /* Offset from start of code to tb table. */
20196 fputs ("\t.long ", file);
20197 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
20198 if (TARGET_AIX)
20199 RS6000_OUTPUT_BASENAME (file, fname);
20200 else
20201 assemble_name (file, fname);
20202 putc ('-', file);
20203 rs6000_output_function_entry (file, fname);
20204 putc ('\n', file);
20206 /* Interrupt handler mask. */
20207 /* Omit this long, since we never set the interrupt handler bit
20208 above. */
20210 /* Number of CTL (controlled storage) anchors. */
20211 /* Omit this long, since the has_ctl bit is never set above. */
20213 /* Displacement into stack of each CTL anchor. */
20214 /* Omit this list of longs, because there are no CTL anchors. */
20216 /* Length of function name. */
20217 if (*fname == '*')
20218 ++fname;
20219 fprintf (file, "\t.short %d\n", (int) strlen (fname));
20221 /* Function name. */
20222 assemble_string (fname, strlen (fname));
20224 /* Register for alloca automatic storage; this is always reg 31.
20225 Only emit this if the alloca bit was set above. */
20226 if (frame_pointer_needed)
20227 fputs ("\t.byte 31\n", file);
20229 fputs ("\t.align 2\n", file);
20233 /* A C compound statement that outputs the assembler code for a thunk
20234 function, used to implement C++ virtual function calls with
20235 multiple inheritance. The thunk acts as a wrapper around a virtual
20236 function, adjusting the implicit object parameter before handing
20237 control off to the real function.
20239 First, emit code to add the integer DELTA to the location that
20240 contains the incoming first argument. Assume that this argument
20241 contains a pointer, and is the one used to pass the `this' pointer
20242 in C++. This is the incoming argument *before* the function
20243 prologue, e.g. `%o0' on a sparc. The addition must preserve the
20244 values of all other incoming arguments.
20246 After the addition, emit code to jump to FUNCTION, which is a
20247 `FUNCTION_DECL'. This is a direct pure jump, not a call, and does
20248 not touch the return address. Hence returning from FUNCTION will
20249 return to whoever called the current `thunk'.
20251 The effect must be as if FUNCTION had been called directly with the
20252 adjusted first argument. This macro is responsible for emitting
20253 all of the code for a thunk function; output_function_prologue()
20254 and output_function_epilogue() are not invoked.
20256 The THUNK_FNDECL is redundant. (DELTA and FUNCTION have already
20257 been extracted from it.) It might possibly be useful on some
20258 targets, but probably not.
20260 If you do not define this macro, the target-independent code in the
20261 C++ frontend will generate a less efficient heavyweight thunk that
20262 calls FUNCTION instead of jumping to it. The generic approach does
20263 not support varargs. */
20265 static void
20266 rs6000_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
20267 HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
20268 tree function)
20270 rtx this_rtx, insn, funexp;
20272 reload_completed = 1;
20273 epilogue_completed = 1;
20275 /* Mark the end of the (empty) prologue. */
20276 emit_note (NOTE_INSN_PROLOGUE_END);
20278 /* Find the "this" pointer. If the function returns a structure,
20279 the structure return pointer is in r3. */
20280 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function))
20281 this_rtx = gen_rtx_REG (Pmode, 4);
20282 else
20283 this_rtx = gen_rtx_REG (Pmode, 3);
20285 /* Apply the constant offset, if required. */
20286 if (delta)
20287 emit_insn (gen_add3_insn (this_rtx, this_rtx, GEN_INT (delta)));
20289 /* Apply the offset from the vtable, if required. */
20290 if (vcall_offset)
20292 rtx vcall_offset_rtx = GEN_INT (vcall_offset);
20293 rtx tmp = gen_rtx_REG (Pmode, 12);
20295 emit_move_insn (tmp, gen_rtx_MEM (Pmode, this_rtx));
20296 if (((unsigned HOST_WIDE_INT) vcall_offset) + 0x8000 >= 0x10000)
20298 emit_insn (gen_add3_insn (tmp, tmp, vcall_offset_rtx));
20299 emit_move_insn (tmp, gen_rtx_MEM (Pmode, tmp));
20301 else
20303 rtx loc = gen_rtx_PLUS (Pmode, tmp, vcall_offset_rtx);
20305 emit_move_insn (tmp, gen_rtx_MEM (Pmode, loc));
20307 emit_insn (gen_add3_insn (this_rtx, this_rtx, tmp));
20310 /* Generate a tail call to the target function. */
20311 if (!TREE_USED (function))
20313 assemble_external (function);
20314 TREE_USED (function) = 1;
20316 funexp = XEXP (DECL_RTL (function), 0);
20317 funexp = gen_rtx_MEM (FUNCTION_MODE, funexp);
20319 #if TARGET_MACHO
20320 if (MACHOPIC_INDIRECT)
20321 funexp = machopic_indirect_call_target (funexp);
20322 #endif
20324 /* gen_sibcall expects reload to convert scratch pseudo to LR so we must
20325 generate sibcall RTL explicitly. */
20326 insn = emit_call_insn (
20327 gen_rtx_PARALLEL (VOIDmode,
20328 gen_rtvec (4,
20329 gen_rtx_CALL (VOIDmode,
20330 funexp, const0_rtx),
20331 gen_rtx_USE (VOIDmode, const0_rtx),
20332 gen_rtx_USE (VOIDmode,
20333 gen_rtx_REG (SImode,
20334 LR_REGNO)),
20335 gen_rtx_RETURN (VOIDmode))));
20336 SIBLING_CALL_P (insn) = 1;
20337 emit_barrier ();
20339 /* Run just enough of rest_of_compilation to get the insns emitted.
20340 There's not really enough bulk here to make other passes such as
20341 instruction scheduling worth while. Note that use_thunk calls
20342 assemble_start_function and assemble_end_function. */
20343 insn = get_insns ();
20344 insn_locators_alloc ();
20345 shorten_branches (insn);
20346 final_start_function (insn, file, 1);
20347 final (insn, file, 1);
20348 final_end_function ();
20350 reload_completed = 0;
20351 epilogue_completed = 0;
20354 /* A quick summary of the various types of 'constant-pool tables'
20355 under PowerPC:
20357 Target Flags Name One table per
20358 AIX (none) AIX TOC object file
20359 AIX -mfull-toc AIX TOC object file
20360 AIX -mminimal-toc AIX minimal TOC translation unit
20361 SVR4/EABI (none) SVR4 SDATA object file
20362 SVR4/EABI -fpic SVR4 pic object file
20363 SVR4/EABI -fPIC SVR4 PIC translation unit
20364 SVR4/EABI -mrelocatable EABI TOC function
20365 SVR4/EABI -maix AIX TOC object file
20366 SVR4/EABI -maix -mminimal-toc
20367 AIX minimal TOC translation unit
20369 Name Reg. Set by entries contains:
20370 made by addrs? fp? sum?
20372 AIX TOC 2 crt0 as Y option option
20373 AIX minimal TOC 30 prolog gcc Y Y option
20374 SVR4 SDATA 13 crt0 gcc N Y N
20375 SVR4 pic 30 prolog ld Y not yet N
20376 SVR4 PIC 30 prolog gcc Y option option
20377 EABI TOC 30 prolog gcc Y option option
20381 /* Hash functions for the hash table. */
20383 static unsigned
20384 rs6000_hash_constant (rtx k)
20386 enum rtx_code code = GET_CODE (k);
20387 enum machine_mode mode = GET_MODE (k);
20388 unsigned result = (code << 3) ^ mode;
20389 const char *format;
20390 int flen, fidx;
20392 format = GET_RTX_FORMAT (code);
20393 flen = strlen (format);
20394 fidx = 0;
20396 switch (code)
20398 case LABEL_REF:
20399 return result * 1231 + (unsigned) INSN_UID (XEXP (k, 0));
20401 case CONST_DOUBLE:
20402 if (mode != VOIDmode)
20403 return real_hash (CONST_DOUBLE_REAL_VALUE (k)) * result;
20404 flen = 2;
20405 break;
20407 case CODE_LABEL:
20408 fidx = 3;
20409 break;
20411 default:
20412 break;
20415 for (; fidx < flen; fidx++)
20416 switch (format[fidx])
20418 case 's':
20420 unsigned i, len;
20421 const char *str = XSTR (k, fidx);
20422 len = strlen (str);
20423 result = result * 613 + len;
20424 for (i = 0; i < len; i++)
20425 result = result * 613 + (unsigned) str[i];
20426 break;
20428 case 'u':
20429 case 'e':
20430 result = result * 1231 + rs6000_hash_constant (XEXP (k, fidx));
20431 break;
20432 case 'i':
20433 case 'n':
20434 result = result * 613 + (unsigned) XINT (k, fidx);
20435 break;
20436 case 'w':
20437 if (sizeof (unsigned) >= sizeof (HOST_WIDE_INT))
20438 result = result * 613 + (unsigned) XWINT (k, fidx);
20439 else
20441 size_t i;
20442 for (i = 0; i < sizeof (HOST_WIDE_INT) / sizeof (unsigned); i++)
20443 result = result * 613 + (unsigned) (XWINT (k, fidx)
20444 >> CHAR_BIT * i);
20446 break;
20447 case '0':
20448 break;
20449 default:
20450 gcc_unreachable ();
20453 return result;
20456 static unsigned
20457 toc_hash_function (const void *hash_entry)
20459 const struct toc_hash_struct *thc =
20460 (const struct toc_hash_struct *) hash_entry;
20461 return rs6000_hash_constant (thc->key) ^ thc->key_mode;
20464 /* Compare H1 and H2 for equivalence. */
20466 static int
20467 toc_hash_eq (const void *h1, const void *h2)
20469 rtx r1 = ((const struct toc_hash_struct *) h1)->key;
20470 rtx r2 = ((const struct toc_hash_struct *) h2)->key;
20472 if (((const struct toc_hash_struct *) h1)->key_mode
20473 != ((const struct toc_hash_struct *) h2)->key_mode)
20474 return 0;
20476 return rtx_equal_p (r1, r2);
20479 /* These are the names given by the C++ front-end to vtables, and
20480 vtable-like objects. Ideally, this logic should not be here;
20481 instead, there should be some programmatic way of inquiring as
20482 to whether or not an object is a vtable. */
20484 #define VTABLE_NAME_P(NAME) \
20485 (strncmp ("_vt.", name, strlen ("_vt.")) == 0 \
20486 || strncmp ("_ZTV", name, strlen ("_ZTV")) == 0 \
20487 || strncmp ("_ZTT", name, strlen ("_ZTT")) == 0 \
20488 || strncmp ("_ZTI", name, strlen ("_ZTI")) == 0 \
20489 || strncmp ("_ZTC", name, strlen ("_ZTC")) == 0)
20491 #ifdef NO_DOLLAR_IN_LABEL
20492 /* Return a GGC-allocated character string translating dollar signs in
20493 input NAME to underscores. Used by XCOFF ASM_OUTPUT_LABELREF. */
20495 const char *
20496 rs6000_xcoff_strip_dollar (const char *name)
20498 char *strip, *p;
20499 int len;
20501 p = strchr (name, '$');
20503 if (p == 0 || p == name)
20504 return name;
20506 len = strlen (name);
20507 strip = (char *) alloca (len + 1);
20508 strcpy (strip, name);
20509 p = strchr (strip, '$');
20510 while (p)
20512 *p = '_';
20513 p = strchr (p + 1, '$');
20516 return ggc_alloc_string (strip, len);
20518 #endif
20520 void
20521 rs6000_output_symbol_ref (FILE *file, rtx x)
20523 /* Currently C++ toc references to vtables can be emitted before it
20524 is decided whether the vtable is public or private. If this is
20525 the case, then the linker will eventually complain that there is
20526 a reference to an unknown section. Thus, for vtables only,
20527 we emit the TOC reference to reference the symbol and not the
20528 section. */
20529 const char *name = XSTR (x, 0);
20531 if (VTABLE_NAME_P (name))
20533 RS6000_OUTPUT_BASENAME (file, name);
20535 else
20536 assemble_name (file, name);
20539 /* Output a TOC entry. We derive the entry name from what is being
20540 written. */
20542 void
20543 output_toc (FILE *file, rtx x, int labelno, enum machine_mode mode)
20545 char buf[256];
20546 const char *name = buf;
20547 rtx base = x;
20548 HOST_WIDE_INT offset = 0;
20550 gcc_assert (!TARGET_NO_TOC);
20552 /* When the linker won't eliminate them, don't output duplicate
20553 TOC entries (this happens on AIX if there is any kind of TOC,
20554 and on SVR4 under -fPIC or -mrelocatable). Don't do this for
20555 CODE_LABELs. */
20556 if (TARGET_TOC && GET_CODE (x) != LABEL_REF)
20558 struct toc_hash_struct *h;
20559 void * * found;
20561 /* Create toc_hash_table. This can't be done at OVERRIDE_OPTIONS
20562 time because GGC is not initialized at that point. */
20563 if (toc_hash_table == NULL)
20564 toc_hash_table = htab_create_ggc (1021, toc_hash_function,
20565 toc_hash_eq, NULL);
20567 h = GGC_NEW (struct toc_hash_struct);
20568 h->key = x;
20569 h->key_mode = mode;
20570 h->labelno = labelno;
20572 found = htab_find_slot (toc_hash_table, h, INSERT);
20573 if (*found == NULL)
20574 *found = h;
20575 else /* This is indeed a duplicate.
20576 Set this label equal to that label. */
20578 fputs ("\t.set ", file);
20579 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
20580 fprintf (file, "%d,", labelno);
20581 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
20582 fprintf (file, "%d\n", ((*(const struct toc_hash_struct **)
20583 found)->labelno));
20584 return;
20588 /* If we're going to put a double constant in the TOC, make sure it's
20589 aligned properly when strict alignment is on. */
20590 if (GET_CODE (x) == CONST_DOUBLE
20591 && STRICT_ALIGNMENT
20592 && GET_MODE_BITSIZE (mode) >= 64
20593 && ! (TARGET_NO_FP_IN_TOC && ! TARGET_MINIMAL_TOC)) {
20594 ASM_OUTPUT_ALIGN (file, 3);
20597 (*targetm.asm_out.internal_label) (file, "LC", labelno);
20599 /* Handle FP constants specially. Note that if we have a minimal
20600 TOC, things we put here aren't actually in the TOC, so we can allow
20601 FP constants. */
20602 if (GET_CODE (x) == CONST_DOUBLE &&
20603 (GET_MODE (x) == TFmode || GET_MODE (x) == TDmode))
20605 REAL_VALUE_TYPE rv;
20606 long k[4];
20608 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
20609 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
20610 REAL_VALUE_TO_TARGET_DECIMAL128 (rv, k);
20611 else
20612 REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv, k);
20614 if (TARGET_64BIT)
20616 if (TARGET_MINIMAL_TOC)
20617 fputs (DOUBLE_INT_ASM_OP, file);
20618 else
20619 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
20620 k[0] & 0xffffffff, k[1] & 0xffffffff,
20621 k[2] & 0xffffffff, k[3] & 0xffffffff);
20622 fprintf (file, "0x%lx%08lx,0x%lx%08lx\n",
20623 k[0] & 0xffffffff, k[1] & 0xffffffff,
20624 k[2] & 0xffffffff, k[3] & 0xffffffff);
20625 return;
20627 else
20629 if (TARGET_MINIMAL_TOC)
20630 fputs ("\t.long ", file);
20631 else
20632 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
20633 k[0] & 0xffffffff, k[1] & 0xffffffff,
20634 k[2] & 0xffffffff, k[3] & 0xffffffff);
20635 fprintf (file, "0x%lx,0x%lx,0x%lx,0x%lx\n",
20636 k[0] & 0xffffffff, k[1] & 0xffffffff,
20637 k[2] & 0xffffffff, k[3] & 0xffffffff);
20638 return;
20641 else if (GET_CODE (x) == CONST_DOUBLE &&
20642 (GET_MODE (x) == DFmode || GET_MODE (x) == DDmode))
20644 REAL_VALUE_TYPE rv;
20645 long k[2];
20647 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
20649 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
20650 REAL_VALUE_TO_TARGET_DECIMAL64 (rv, k);
20651 else
20652 REAL_VALUE_TO_TARGET_DOUBLE (rv, k);
20654 if (TARGET_64BIT)
20656 if (TARGET_MINIMAL_TOC)
20657 fputs (DOUBLE_INT_ASM_OP, file);
20658 else
20659 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
20660 k[0] & 0xffffffff, k[1] & 0xffffffff);
20661 fprintf (file, "0x%lx%08lx\n",
20662 k[0] & 0xffffffff, k[1] & 0xffffffff);
20663 return;
20665 else
20667 if (TARGET_MINIMAL_TOC)
20668 fputs ("\t.long ", file);
20669 else
20670 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
20671 k[0] & 0xffffffff, k[1] & 0xffffffff);
20672 fprintf (file, "0x%lx,0x%lx\n",
20673 k[0] & 0xffffffff, k[1] & 0xffffffff);
20674 return;
20677 else if (GET_CODE (x) == CONST_DOUBLE &&
20678 (GET_MODE (x) == SFmode || GET_MODE (x) == SDmode))
20680 REAL_VALUE_TYPE rv;
20681 long l;
20683 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
20684 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
20685 REAL_VALUE_TO_TARGET_DECIMAL32 (rv, l);
20686 else
20687 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
20689 if (TARGET_64BIT)
20691 if (TARGET_MINIMAL_TOC)
20692 fputs (DOUBLE_INT_ASM_OP, file);
20693 else
20694 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
20695 fprintf (file, "0x%lx00000000\n", l & 0xffffffff);
20696 return;
20698 else
20700 if (TARGET_MINIMAL_TOC)
20701 fputs ("\t.long ", file);
20702 else
20703 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
20704 fprintf (file, "0x%lx\n", l & 0xffffffff);
20705 return;
20708 else if (GET_MODE (x) == VOIDmode
20709 && (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE))
20711 unsigned HOST_WIDE_INT low;
20712 HOST_WIDE_INT high;
20714 if (GET_CODE (x) == CONST_DOUBLE)
20716 low = CONST_DOUBLE_LOW (x);
20717 high = CONST_DOUBLE_HIGH (x);
20719 else
20720 #if HOST_BITS_PER_WIDE_INT == 32
20722 low = INTVAL (x);
20723 high = (low & 0x80000000) ? ~0 : 0;
20725 #else
20727 low = INTVAL (x) & 0xffffffff;
20728 high = (HOST_WIDE_INT) INTVAL (x) >> 32;
20730 #endif
20732 /* TOC entries are always Pmode-sized, but since this
20733 is a bigendian machine then if we're putting smaller
20734 integer constants in the TOC we have to pad them.
20735 (This is still a win over putting the constants in
20736 a separate constant pool, because then we'd have
20737 to have both a TOC entry _and_ the actual constant.)
20739 For a 32-bit target, CONST_INT values are loaded and shifted
20740 entirely within `low' and can be stored in one TOC entry. */
20742 /* It would be easy to make this work, but it doesn't now. */
20743 gcc_assert (!TARGET_64BIT || POINTER_SIZE >= GET_MODE_BITSIZE (mode));
20745 if (POINTER_SIZE > GET_MODE_BITSIZE (mode))
20747 #if HOST_BITS_PER_WIDE_INT == 32
20748 lshift_double (low, high, POINTER_SIZE - GET_MODE_BITSIZE (mode),
20749 POINTER_SIZE, &low, &high, 0);
20750 #else
20751 low |= high << 32;
20752 low <<= POINTER_SIZE - GET_MODE_BITSIZE (mode);
20753 high = (HOST_WIDE_INT) low >> 32;
20754 low &= 0xffffffff;
20755 #endif
20758 if (TARGET_64BIT)
20760 if (TARGET_MINIMAL_TOC)
20761 fputs (DOUBLE_INT_ASM_OP, file);
20762 else
20763 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
20764 (long) high & 0xffffffff, (long) low & 0xffffffff);
20765 fprintf (file, "0x%lx%08lx\n",
20766 (long) high & 0xffffffff, (long) low & 0xffffffff);
20767 return;
20769 else
20771 if (POINTER_SIZE < GET_MODE_BITSIZE (mode))
20773 if (TARGET_MINIMAL_TOC)
20774 fputs ("\t.long ", file);
20775 else
20776 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
20777 (long) high & 0xffffffff, (long) low & 0xffffffff);
20778 fprintf (file, "0x%lx,0x%lx\n",
20779 (long) high & 0xffffffff, (long) low & 0xffffffff);
20781 else
20783 if (TARGET_MINIMAL_TOC)
20784 fputs ("\t.long ", file);
20785 else
20786 fprintf (file, "\t.tc IS_%lx[TC],", (long) low & 0xffffffff);
20787 fprintf (file, "0x%lx\n", (long) low & 0xffffffff);
20789 return;
20793 if (GET_CODE (x) == CONST)
20795 gcc_assert (GET_CODE (XEXP (x, 0)) == PLUS
20796 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT);
20798 base = XEXP (XEXP (x, 0), 0);
20799 offset = INTVAL (XEXP (XEXP (x, 0), 1));
20802 switch (GET_CODE (base))
20804 case SYMBOL_REF:
20805 name = XSTR (base, 0);
20806 break;
20808 case LABEL_REF:
20809 ASM_GENERATE_INTERNAL_LABEL (buf, "L",
20810 CODE_LABEL_NUMBER (XEXP (base, 0)));
20811 break;
20813 case CODE_LABEL:
20814 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (base));
20815 break;
20817 default:
20818 gcc_unreachable ();
20821 if (TARGET_MINIMAL_TOC)
20822 fputs (TARGET_32BIT ? "\t.long " : DOUBLE_INT_ASM_OP, file);
20823 else
20825 fputs ("\t.tc ", file);
20826 RS6000_OUTPUT_BASENAME (file, name);
20828 if (offset < 0)
20829 fprintf (file, ".N" HOST_WIDE_INT_PRINT_UNSIGNED, - offset);
20830 else if (offset)
20831 fprintf (file, ".P" HOST_WIDE_INT_PRINT_UNSIGNED, offset);
20833 fputs ("[TC],", file);
20836 /* Currently C++ toc references to vtables can be emitted before it
20837 is decided whether the vtable is public or private. If this is
20838 the case, then the linker will eventually complain that there is
20839 a TOC reference to an unknown section. Thus, for vtables only,
20840 we emit the TOC reference to reference the symbol and not the
20841 section. */
20842 if (VTABLE_NAME_P (name))
20844 RS6000_OUTPUT_BASENAME (file, name);
20845 if (offset < 0)
20846 fprintf (file, HOST_WIDE_INT_PRINT_DEC, offset);
20847 else if (offset > 0)
20848 fprintf (file, "+" HOST_WIDE_INT_PRINT_DEC, offset);
20850 else
20851 output_addr_const (file, x);
20852 putc ('\n', file);
20855 /* Output an assembler pseudo-op to write an ASCII string of N characters
20856 starting at P to FILE.
20858 On the RS/6000, we have to do this using the .byte operation and
20859 write out special characters outside the quoted string.
20860 Also, the assembler is broken; very long strings are truncated,
20861 so we must artificially break them up early. */
20863 void
20864 output_ascii (FILE *file, const char *p, int n)
20866 char c;
20867 int i, count_string;
20868 const char *for_string = "\t.byte \"";
20869 const char *for_decimal = "\t.byte ";
20870 const char *to_close = NULL;
20872 count_string = 0;
20873 for (i = 0; i < n; i++)
20875 c = *p++;
20876 if (c >= ' ' && c < 0177)
20878 if (for_string)
20879 fputs (for_string, file);
20880 putc (c, file);
20882 /* Write two quotes to get one. */
20883 if (c == '"')
20885 putc (c, file);
20886 ++count_string;
20889 for_string = NULL;
20890 for_decimal = "\"\n\t.byte ";
20891 to_close = "\"\n";
20892 ++count_string;
20894 if (count_string >= 512)
20896 fputs (to_close, file);
20898 for_string = "\t.byte \"";
20899 for_decimal = "\t.byte ";
20900 to_close = NULL;
20901 count_string = 0;
20904 else
20906 if (for_decimal)
20907 fputs (for_decimal, file);
20908 fprintf (file, "%d", c);
20910 for_string = "\n\t.byte \"";
20911 for_decimal = ", ";
20912 to_close = "\n";
20913 count_string = 0;
20917 /* Now close the string if we have written one. Then end the line. */
20918 if (to_close)
20919 fputs (to_close, file);
20922 /* Generate a unique section name for FILENAME for a section type
20923 represented by SECTION_DESC. Output goes into BUF.
20925 SECTION_DESC can be any string, as long as it is different for each
20926 possible section type.
20928 We name the section in the same manner as xlc. The name begins with an
20929 underscore followed by the filename (after stripping any leading directory
20930 names) with the last period replaced by the string SECTION_DESC. If
20931 FILENAME does not contain a period, SECTION_DESC is appended to the end of
20932 the name. */
20934 void
20935 rs6000_gen_section_name (char **buf, const char *filename,
20936 const char *section_desc)
20938 const char *q, *after_last_slash, *last_period = 0;
20939 char *p;
20940 int len;
20942 after_last_slash = filename;
20943 for (q = filename; *q; q++)
20945 if (*q == '/')
20946 after_last_slash = q + 1;
20947 else if (*q == '.')
20948 last_period = q;
20951 len = strlen (after_last_slash) + strlen (section_desc) + 2;
20952 *buf = (char *) xmalloc (len);
20954 p = *buf;
20955 *p++ = '_';
20957 for (q = after_last_slash; *q; q++)
20959 if (q == last_period)
20961 strcpy (p, section_desc);
20962 p += strlen (section_desc);
20963 break;
20966 else if (ISALNUM (*q))
20967 *p++ = *q;
20970 if (last_period == 0)
20971 strcpy (p, section_desc);
20972 else
20973 *p = '\0';
20976 /* Emit profile function. */
20978 void
20979 output_profile_hook (int labelno ATTRIBUTE_UNUSED)
20981 /* Non-standard profiling for kernels, which just saves LR then calls
20982 _mcount without worrying about arg saves. The idea is to change
20983 the function prologue as little as possible as it isn't easy to
20984 account for arg save/restore code added just for _mcount. */
20985 if (TARGET_PROFILE_KERNEL)
20986 return;
20988 if (DEFAULT_ABI == ABI_AIX)
20990 #ifndef NO_PROFILE_COUNTERS
20991 # define NO_PROFILE_COUNTERS 0
20992 #endif
20993 if (NO_PROFILE_COUNTERS)
20994 emit_library_call (init_one_libfunc (RS6000_MCOUNT),
20995 LCT_NORMAL, VOIDmode, 0);
20996 else
20998 char buf[30];
20999 const char *label_name;
21000 rtx fun;
21002 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
21003 label_name = (*targetm.strip_name_encoding) (ggc_strdup (buf));
21004 fun = gen_rtx_SYMBOL_REF (Pmode, label_name);
21006 emit_library_call (init_one_libfunc (RS6000_MCOUNT),
21007 LCT_NORMAL, VOIDmode, 1, fun, Pmode);
21010 else if (DEFAULT_ABI == ABI_DARWIN)
21012 const char *mcount_name = RS6000_MCOUNT;
21013 int caller_addr_regno = LR_REGNO;
21015 /* Be conservative and always set this, at least for now. */
21016 crtl->uses_pic_offset_table = 1;
21018 #if TARGET_MACHO
21019 /* For PIC code, set up a stub and collect the caller's address
21020 from r0, which is where the prologue puts it. */
21021 if (MACHOPIC_INDIRECT
21022 && crtl->uses_pic_offset_table)
21023 caller_addr_regno = 0;
21024 #endif
21025 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, mcount_name),
21026 LCT_NORMAL, VOIDmode, 1,
21027 gen_rtx_REG (Pmode, caller_addr_regno), Pmode);
21031 /* Write function profiler code. */
21033 void
21034 output_function_profiler (FILE *file, int labelno)
21036 char buf[100];
21038 switch (DEFAULT_ABI)
21040 default:
21041 gcc_unreachable ();
21043 case ABI_V4:
21044 if (!TARGET_32BIT)
21046 warning (0, "no profiling of 64-bit code for this ABI");
21047 return;
21049 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
21050 fprintf (file, "\tmflr %s\n", reg_names[0]);
21051 if (NO_PROFILE_COUNTERS)
21053 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
21054 reg_names[0], reg_names[1]);
21056 else if (TARGET_SECURE_PLT && flag_pic)
21058 asm_fprintf (file, "\tbcl 20,31,1f\n1:\n\t{st|stw} %s,4(%s)\n",
21059 reg_names[0], reg_names[1]);
21060 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
21061 asm_fprintf (file, "\t{cau|addis} %s,%s,",
21062 reg_names[12], reg_names[12]);
21063 assemble_name (file, buf);
21064 asm_fprintf (file, "-1b@ha\n\t{cal|la} %s,", reg_names[0]);
21065 assemble_name (file, buf);
21066 asm_fprintf (file, "-1b@l(%s)\n", reg_names[12]);
21068 else if (flag_pic == 1)
21070 fputs ("\tbl _GLOBAL_OFFSET_TABLE_@local-4\n", file);
21071 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
21072 reg_names[0], reg_names[1]);
21073 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
21074 asm_fprintf (file, "\t{l|lwz} %s,", reg_names[0]);
21075 assemble_name (file, buf);
21076 asm_fprintf (file, "@got(%s)\n", reg_names[12]);
21078 else if (flag_pic > 1)
21080 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
21081 reg_names[0], reg_names[1]);
21082 /* Now, we need to get the address of the label. */
21083 fputs ("\tbcl 20,31,1f\n\t.long ", file);
21084 assemble_name (file, buf);
21085 fputs ("-.\n1:", file);
21086 asm_fprintf (file, "\tmflr %s\n", reg_names[11]);
21087 asm_fprintf (file, "\t{l|lwz} %s,0(%s)\n",
21088 reg_names[0], reg_names[11]);
21089 asm_fprintf (file, "\t{cax|add} %s,%s,%s\n",
21090 reg_names[0], reg_names[0], reg_names[11]);
21092 else
21094 asm_fprintf (file, "\t{liu|lis} %s,", reg_names[12]);
21095 assemble_name (file, buf);
21096 fputs ("@ha\n", file);
21097 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
21098 reg_names[0], reg_names[1]);
21099 asm_fprintf (file, "\t{cal|la} %s,", reg_names[0]);
21100 assemble_name (file, buf);
21101 asm_fprintf (file, "@l(%s)\n", reg_names[12]);
21104 /* ABI_V4 saves the static chain reg with ASM_OUTPUT_REG_PUSH. */
21105 fprintf (file, "\tbl %s%s\n",
21106 RS6000_MCOUNT, flag_pic ? "@plt" : "");
21107 break;
21109 case ABI_AIX:
21110 case ABI_DARWIN:
21111 if (!TARGET_PROFILE_KERNEL)
21113 /* Don't do anything, done in output_profile_hook (). */
21115 else
21117 gcc_assert (!TARGET_32BIT);
21119 asm_fprintf (file, "\tmflr %s\n", reg_names[0]);
21120 asm_fprintf (file, "\tstd %s,16(%s)\n", reg_names[0], reg_names[1]);
21122 if (cfun->static_chain_decl != NULL)
21124 asm_fprintf (file, "\tstd %s,24(%s)\n",
21125 reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
21126 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
21127 asm_fprintf (file, "\tld %s,24(%s)\n",
21128 reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
21130 else
21131 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
21133 break;
21139 /* The following variable value is the last issued insn. */
21141 static rtx last_scheduled_insn;
21143 /* The following variable helps to balance issuing of load and
21144 store instructions */
21146 static int load_store_pendulum;
21148 /* Power4 load update and store update instructions are cracked into a
21149 load or store and an integer insn which are executed in the same cycle.
21150 Branches have their own dispatch slot which does not count against the
21151 GCC issue rate, but it changes the program flow so there are no other
21152 instructions to issue in this cycle. */
21154 static int
21155 rs6000_variable_issue (FILE *stream ATTRIBUTE_UNUSED,
21156 int verbose ATTRIBUTE_UNUSED,
21157 rtx insn, int more)
21159 last_scheduled_insn = insn;
21160 if (GET_CODE (PATTERN (insn)) == USE
21161 || GET_CODE (PATTERN (insn)) == CLOBBER)
21163 cached_can_issue_more = more;
21164 return cached_can_issue_more;
21167 if (insn_terminates_group_p (insn, current_group))
21169 cached_can_issue_more = 0;
21170 return cached_can_issue_more;
21173 /* If no reservation, but reach here */
21174 if (recog_memoized (insn) < 0)
21175 return more;
21177 if (rs6000_sched_groups)
21179 if (is_microcoded_insn (insn))
21180 cached_can_issue_more = 0;
21181 else if (is_cracked_insn (insn))
21182 cached_can_issue_more = more > 2 ? more - 2 : 0;
21183 else
21184 cached_can_issue_more = more - 1;
21186 return cached_can_issue_more;
21189 if (rs6000_cpu_attr == CPU_CELL && is_nonpipeline_insn (insn))
21190 return 0;
21192 cached_can_issue_more = more - 1;
21193 return cached_can_issue_more;
21196 /* Adjust the cost of a scheduling dependency. Return the new cost of
21197 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
21199 static int
21200 rs6000_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
21202 enum attr_type attr_type;
21204 if (! recog_memoized (insn))
21205 return 0;
21207 switch (REG_NOTE_KIND (link))
21209 case REG_DEP_TRUE:
21211 /* Data dependency; DEP_INSN writes a register that INSN reads
21212 some cycles later. */
21214 /* Separate a load from a narrower, dependent store. */
21215 if (rs6000_sched_groups
21216 && GET_CODE (PATTERN (insn)) == SET
21217 && GET_CODE (PATTERN (dep_insn)) == SET
21218 && GET_CODE (XEXP (PATTERN (insn), 1)) == MEM
21219 && GET_CODE (XEXP (PATTERN (dep_insn), 0)) == MEM
21220 && (GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (insn), 1)))
21221 > GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (dep_insn), 0)))))
21222 return cost + 14;
21224 attr_type = get_attr_type (insn);
21226 switch (attr_type)
21228 case TYPE_JMPREG:
21229 /* Tell the first scheduling pass about the latency between
21230 a mtctr and bctr (and mtlr and br/blr). The first
21231 scheduling pass will not know about this latency since
21232 the mtctr instruction, which has the latency associated
21233 to it, will be generated by reload. */
21234 return TARGET_POWER ? 5 : 4;
21235 case TYPE_BRANCH:
21236 /* Leave some extra cycles between a compare and its
21237 dependent branch, to inhibit expensive mispredicts. */
21238 if ((rs6000_cpu_attr == CPU_PPC603
21239 || rs6000_cpu_attr == CPU_PPC604
21240 || rs6000_cpu_attr == CPU_PPC604E
21241 || rs6000_cpu_attr == CPU_PPC620
21242 || rs6000_cpu_attr == CPU_PPC630
21243 || rs6000_cpu_attr == CPU_PPC750
21244 || rs6000_cpu_attr == CPU_PPC7400
21245 || rs6000_cpu_attr == CPU_PPC7450
21246 || rs6000_cpu_attr == CPU_POWER4
21247 || rs6000_cpu_attr == CPU_POWER5
21248 || rs6000_cpu_attr == CPU_POWER7
21249 || rs6000_cpu_attr == CPU_CELL)
21250 && recog_memoized (dep_insn)
21251 && (INSN_CODE (dep_insn) >= 0))
21253 switch (get_attr_type (dep_insn))
21255 case TYPE_CMP:
21256 case TYPE_COMPARE:
21257 case TYPE_DELAYED_COMPARE:
21258 case TYPE_IMUL_COMPARE:
21259 case TYPE_LMUL_COMPARE:
21260 case TYPE_FPCOMPARE:
21261 case TYPE_CR_LOGICAL:
21262 case TYPE_DELAYED_CR:
21263 return cost + 2;
21264 default:
21265 break;
21267 break;
21269 case TYPE_STORE:
21270 case TYPE_STORE_U:
21271 case TYPE_STORE_UX:
21272 case TYPE_FPSTORE:
21273 case TYPE_FPSTORE_U:
21274 case TYPE_FPSTORE_UX:
21275 if ((rs6000_cpu == PROCESSOR_POWER6)
21276 && recog_memoized (dep_insn)
21277 && (INSN_CODE (dep_insn) >= 0))
21280 if (GET_CODE (PATTERN (insn)) != SET)
21281 /* If this happens, we have to extend this to schedule
21282 optimally. Return default for now. */
21283 return cost;
21285 /* Adjust the cost for the case where the value written
21286 by a fixed point operation is used as the address
21287 gen value on a store. */
21288 switch (get_attr_type (dep_insn))
21290 case TYPE_LOAD:
21291 case TYPE_LOAD_U:
21292 case TYPE_LOAD_UX:
21293 case TYPE_CNTLZ:
21295 if (! store_data_bypass_p (dep_insn, insn))
21296 return 4;
21297 break;
21299 case TYPE_LOAD_EXT:
21300 case TYPE_LOAD_EXT_U:
21301 case TYPE_LOAD_EXT_UX:
21302 case TYPE_VAR_SHIFT_ROTATE:
21303 case TYPE_VAR_DELAYED_COMPARE:
21305 if (! store_data_bypass_p (dep_insn, insn))
21306 return 6;
21307 break;
21309 case TYPE_INTEGER:
21310 case TYPE_COMPARE:
21311 case TYPE_FAST_COMPARE:
21312 case TYPE_EXTS:
21313 case TYPE_SHIFT:
21314 case TYPE_INSERT_WORD:
21315 case TYPE_INSERT_DWORD:
21316 case TYPE_FPLOAD_U:
21317 case TYPE_FPLOAD_UX:
21318 case TYPE_STORE_U:
21319 case TYPE_STORE_UX:
21320 case TYPE_FPSTORE_U:
21321 case TYPE_FPSTORE_UX:
21323 if (! store_data_bypass_p (dep_insn, insn))
21324 return 3;
21325 break;
21327 case TYPE_IMUL:
21328 case TYPE_IMUL2:
21329 case TYPE_IMUL3:
21330 case TYPE_LMUL:
21331 case TYPE_IMUL_COMPARE:
21332 case TYPE_LMUL_COMPARE:
21334 if (! store_data_bypass_p (dep_insn, insn))
21335 return 17;
21336 break;
21338 case TYPE_IDIV:
21340 if (! store_data_bypass_p (dep_insn, insn))
21341 return 45;
21342 break;
21344 case TYPE_LDIV:
21346 if (! store_data_bypass_p (dep_insn, insn))
21347 return 57;
21348 break;
21350 default:
21351 break;
21354 break;
21356 case TYPE_LOAD:
21357 case TYPE_LOAD_U:
21358 case TYPE_LOAD_UX:
21359 case TYPE_LOAD_EXT:
21360 case TYPE_LOAD_EXT_U:
21361 case TYPE_LOAD_EXT_UX:
21362 if ((rs6000_cpu == PROCESSOR_POWER6)
21363 && recog_memoized (dep_insn)
21364 && (INSN_CODE (dep_insn) >= 0))
21367 /* Adjust the cost for the case where the value written
21368 by a fixed point instruction is used within the address
21369 gen portion of a subsequent load(u)(x) */
21370 switch (get_attr_type (dep_insn))
21372 case TYPE_LOAD:
21373 case TYPE_LOAD_U:
21374 case TYPE_LOAD_UX:
21375 case TYPE_CNTLZ:
21377 if (set_to_load_agen (dep_insn, insn))
21378 return 4;
21379 break;
21381 case TYPE_LOAD_EXT:
21382 case TYPE_LOAD_EXT_U:
21383 case TYPE_LOAD_EXT_UX:
21384 case TYPE_VAR_SHIFT_ROTATE:
21385 case TYPE_VAR_DELAYED_COMPARE:
21387 if (set_to_load_agen (dep_insn, insn))
21388 return 6;
21389 break;
21391 case TYPE_INTEGER:
21392 case TYPE_COMPARE:
21393 case TYPE_FAST_COMPARE:
21394 case TYPE_EXTS:
21395 case TYPE_SHIFT:
21396 case TYPE_INSERT_WORD:
21397 case TYPE_INSERT_DWORD:
21398 case TYPE_FPLOAD_U:
21399 case TYPE_FPLOAD_UX:
21400 case TYPE_STORE_U:
21401 case TYPE_STORE_UX:
21402 case TYPE_FPSTORE_U:
21403 case TYPE_FPSTORE_UX:
21405 if (set_to_load_agen (dep_insn, insn))
21406 return 3;
21407 break;
21409 case TYPE_IMUL:
21410 case TYPE_IMUL2:
21411 case TYPE_IMUL3:
21412 case TYPE_LMUL:
21413 case TYPE_IMUL_COMPARE:
21414 case TYPE_LMUL_COMPARE:
21416 if (set_to_load_agen (dep_insn, insn))
21417 return 17;
21418 break;
21420 case TYPE_IDIV:
21422 if (set_to_load_agen (dep_insn, insn))
21423 return 45;
21424 break;
21426 case TYPE_LDIV:
21428 if (set_to_load_agen (dep_insn, insn))
21429 return 57;
21430 break;
21432 default:
21433 break;
21436 break;
21438 case TYPE_FPLOAD:
21439 if ((rs6000_cpu == PROCESSOR_POWER6)
21440 && recog_memoized (dep_insn)
21441 && (INSN_CODE (dep_insn) >= 0)
21442 && (get_attr_type (dep_insn) == TYPE_MFFGPR))
21443 return 2;
21445 default:
21446 break;
21449 /* Fall out to return default cost. */
21451 break;
21453 case REG_DEP_OUTPUT:
21454 /* Output dependency; DEP_INSN writes a register that INSN writes some
21455 cycles later. */
21456 if ((rs6000_cpu == PROCESSOR_POWER6)
21457 && recog_memoized (dep_insn)
21458 && (INSN_CODE (dep_insn) >= 0))
21460 attr_type = get_attr_type (insn);
21462 switch (attr_type)
21464 case TYPE_FP:
21465 if (get_attr_type (dep_insn) == TYPE_FP)
21466 return 1;
21467 break;
21468 case TYPE_FPLOAD:
21469 if (get_attr_type (dep_insn) == TYPE_MFFGPR)
21470 return 2;
21471 break;
21472 default:
21473 break;
21476 case REG_DEP_ANTI:
21477 /* Anti dependency; DEP_INSN reads a register that INSN writes some
21478 cycles later. */
21479 return 0;
21481 default:
21482 gcc_unreachable ();
21485 return cost;
21488 /* Debug version of rs6000_adjust_cost. */
21490 static int
21491 rs6000_debug_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
21493 int ret = rs6000_adjust_cost (insn, link, dep_insn, cost);
21495 if (ret != cost)
21497 const char *dep;
21499 switch (REG_NOTE_KIND (link))
21501 default: dep = "unknown depencency"; break;
21502 case REG_DEP_TRUE: dep = "data dependency"; break;
21503 case REG_DEP_OUTPUT: dep = "output dependency"; break;
21504 case REG_DEP_ANTI: dep = "anti depencency"; break;
21507 fprintf (stderr,
21508 "\nrs6000_adjust_cost, final cost = %d, orig cost = %d, "
21509 "%s, insn:\n", ret, cost, dep);
21511 debug_rtx (insn);
21514 return ret;
21517 /* The function returns a true if INSN is microcoded.
21518 Return false otherwise. */
21520 static bool
21521 is_microcoded_insn (rtx insn)
21523 if (!insn || !NONDEBUG_INSN_P (insn)
21524 || GET_CODE (PATTERN (insn)) == USE
21525 || GET_CODE (PATTERN (insn)) == CLOBBER)
21526 return false;
21528 if (rs6000_cpu_attr == CPU_CELL)
21529 return get_attr_cell_micro (insn) == CELL_MICRO_ALWAYS;
21531 if (rs6000_sched_groups)
21533 enum attr_type type = get_attr_type (insn);
21534 if (type == TYPE_LOAD_EXT_U
21535 || type == TYPE_LOAD_EXT_UX
21536 || type == TYPE_LOAD_UX
21537 || type == TYPE_STORE_UX
21538 || type == TYPE_MFCR)
21539 return true;
21542 return false;
21545 /* The function returns true if INSN is cracked into 2 instructions
21546 by the processor (and therefore occupies 2 issue slots). */
21548 static bool
21549 is_cracked_insn (rtx insn)
21551 if (!insn || !NONDEBUG_INSN_P (insn)
21552 || GET_CODE (PATTERN (insn)) == USE
21553 || GET_CODE (PATTERN (insn)) == CLOBBER)
21554 return false;
21556 if (rs6000_sched_groups)
21558 enum attr_type type = get_attr_type (insn);
21559 if (type == TYPE_LOAD_U || type == TYPE_STORE_U
21560 || type == TYPE_FPLOAD_U || type == TYPE_FPSTORE_U
21561 || type == TYPE_FPLOAD_UX || type == TYPE_FPSTORE_UX
21562 || type == TYPE_LOAD_EXT || type == TYPE_DELAYED_CR
21563 || type == TYPE_COMPARE || type == TYPE_DELAYED_COMPARE
21564 || type == TYPE_IMUL_COMPARE || type == TYPE_LMUL_COMPARE
21565 || type == TYPE_IDIV || type == TYPE_LDIV
21566 || type == TYPE_INSERT_WORD)
21567 return true;
21570 return false;
21573 /* The function returns true if INSN can be issued only from
21574 the branch slot. */
21576 static bool
21577 is_branch_slot_insn (rtx insn)
21579 if (!insn || !NONDEBUG_INSN_P (insn)
21580 || GET_CODE (PATTERN (insn)) == USE
21581 || GET_CODE (PATTERN (insn)) == CLOBBER)
21582 return false;
21584 if (rs6000_sched_groups)
21586 enum attr_type type = get_attr_type (insn);
21587 if (type == TYPE_BRANCH || type == TYPE_JMPREG)
21588 return true;
21589 return false;
21592 return false;
21595 /* The function returns true if out_inst sets a value that is
21596 used in the address generation computation of in_insn */
21597 static bool
21598 set_to_load_agen (rtx out_insn, rtx in_insn)
21600 rtx out_set, in_set;
21602 /* For performance reasons, only handle the simple case where
21603 both loads are a single_set. */
21604 out_set = single_set (out_insn);
21605 if (out_set)
21607 in_set = single_set (in_insn);
21608 if (in_set)
21609 return reg_mentioned_p (SET_DEST (out_set), SET_SRC (in_set));
21612 return false;
21615 /* The function returns true if the target storage location of
21616 out_insn is adjacent to the target storage location of in_insn */
21617 /* Return 1 if memory locations are adjacent. */
21619 static bool
21620 adjacent_mem_locations (rtx insn1, rtx insn2)
21623 rtx a = get_store_dest (PATTERN (insn1));
21624 rtx b = get_store_dest (PATTERN (insn2));
21626 if ((GET_CODE (XEXP (a, 0)) == REG
21627 || (GET_CODE (XEXP (a, 0)) == PLUS
21628 && GET_CODE (XEXP (XEXP (a, 0), 1)) == CONST_INT))
21629 && (GET_CODE (XEXP (b, 0)) == REG
21630 || (GET_CODE (XEXP (b, 0)) == PLUS
21631 && GET_CODE (XEXP (XEXP (b, 0), 1)) == CONST_INT)))
21633 HOST_WIDE_INT val0 = 0, val1 = 0, val_diff;
21634 rtx reg0, reg1;
21636 if (GET_CODE (XEXP (a, 0)) == PLUS)
21638 reg0 = XEXP (XEXP (a, 0), 0);
21639 val0 = INTVAL (XEXP (XEXP (a, 0), 1));
21641 else
21642 reg0 = XEXP (a, 0);
21644 if (GET_CODE (XEXP (b, 0)) == PLUS)
21646 reg1 = XEXP (XEXP (b, 0), 0);
21647 val1 = INTVAL (XEXP (XEXP (b, 0), 1));
21649 else
21650 reg1 = XEXP (b, 0);
21652 val_diff = val1 - val0;
21654 return ((REGNO (reg0) == REGNO (reg1))
21655 && ((MEM_SIZE (a) && val_diff == INTVAL (MEM_SIZE (a)))
21656 || (MEM_SIZE (b) && val_diff == -INTVAL (MEM_SIZE (b)))));
21659 return false;
21662 /* A C statement (sans semicolon) to update the integer scheduling
21663 priority INSN_PRIORITY (INSN). Increase the priority to execute the
21664 INSN earlier, reduce the priority to execute INSN later. Do not
21665 define this macro if you do not need to adjust the scheduling
21666 priorities of insns. */
21668 static int
21669 rs6000_adjust_priority (rtx insn ATTRIBUTE_UNUSED, int priority)
21671 /* On machines (like the 750) which have asymmetric integer units,
21672 where one integer unit can do multiply and divides and the other
21673 can't, reduce the priority of multiply/divide so it is scheduled
21674 before other integer operations. */
21676 #if 0
21677 if (! INSN_P (insn))
21678 return priority;
21680 if (GET_CODE (PATTERN (insn)) == USE)
21681 return priority;
21683 switch (rs6000_cpu_attr) {
21684 case CPU_PPC750:
21685 switch (get_attr_type (insn))
21687 default:
21688 break;
21690 case TYPE_IMUL:
21691 case TYPE_IDIV:
21692 fprintf (stderr, "priority was %#x (%d) before adjustment\n",
21693 priority, priority);
21694 if (priority >= 0 && priority < 0x01000000)
21695 priority >>= 3;
21696 break;
21699 #endif
21701 if (insn_must_be_first_in_group (insn)
21702 && reload_completed
21703 && current_sched_info->sched_max_insns_priority
21704 && rs6000_sched_restricted_insns_priority)
21707 /* Prioritize insns that can be dispatched only in the first
21708 dispatch slot. */
21709 if (rs6000_sched_restricted_insns_priority == 1)
21710 /* Attach highest priority to insn. This means that in
21711 haifa-sched.c:ready_sort(), dispatch-slot restriction considerations
21712 precede 'priority' (critical path) considerations. */
21713 return current_sched_info->sched_max_insns_priority;
21714 else if (rs6000_sched_restricted_insns_priority == 2)
21715 /* Increase priority of insn by a minimal amount. This means that in
21716 haifa-sched.c:ready_sort(), only 'priority' (critical path)
21717 considerations precede dispatch-slot restriction considerations. */
21718 return (priority + 1);
21721 if (rs6000_cpu == PROCESSOR_POWER6
21722 && ((load_store_pendulum == -2 && is_load_insn (insn))
21723 || (load_store_pendulum == 2 && is_store_insn (insn))))
21724 /* Attach highest priority to insn if the scheduler has just issued two
21725 stores and this instruction is a load, or two loads and this instruction
21726 is a store. Power6 wants loads and stores scheduled alternately
21727 when possible */
21728 return current_sched_info->sched_max_insns_priority;
21730 return priority;
21733 /* Return true if the instruction is nonpipelined on the Cell. */
21734 static bool
21735 is_nonpipeline_insn (rtx insn)
21737 enum attr_type type;
21738 if (!insn || !NONDEBUG_INSN_P (insn)
21739 || GET_CODE (PATTERN (insn)) == USE
21740 || GET_CODE (PATTERN (insn)) == CLOBBER)
21741 return false;
21743 type = get_attr_type (insn);
21744 if (type == TYPE_IMUL
21745 || type == TYPE_IMUL2
21746 || type == TYPE_IMUL3
21747 || type == TYPE_LMUL
21748 || type == TYPE_IDIV
21749 || type == TYPE_LDIV
21750 || type == TYPE_SDIV
21751 || type == TYPE_DDIV
21752 || type == TYPE_SSQRT
21753 || type == TYPE_DSQRT
21754 || type == TYPE_MFCR
21755 || type == TYPE_MFCRF
21756 || type == TYPE_MFJMPR)
21758 return true;
21760 return false;
21764 /* Return how many instructions the machine can issue per cycle. */
21766 static int
21767 rs6000_issue_rate (void)
21769 /* Use issue rate of 1 for first scheduling pass to decrease degradation. */
21770 if (!reload_completed)
21771 return 1;
21773 switch (rs6000_cpu_attr) {
21774 case CPU_RIOS1: /* ? */
21775 case CPU_RS64A:
21776 case CPU_PPC601: /* ? */
21777 case CPU_PPC7450:
21778 return 3;
21779 case CPU_PPC440:
21780 case CPU_PPC603:
21781 case CPU_PPC750:
21782 case CPU_PPC7400:
21783 case CPU_PPC8540:
21784 case CPU_CELL:
21785 case CPU_PPCE300C2:
21786 case CPU_PPCE300C3:
21787 case CPU_PPCE500MC:
21788 return 2;
21789 case CPU_RIOS2:
21790 case CPU_PPC604:
21791 case CPU_PPC604E:
21792 case CPU_PPC620:
21793 case CPU_PPC630:
21794 return 4;
21795 case CPU_POWER4:
21796 case CPU_POWER5:
21797 case CPU_POWER6:
21798 case CPU_POWER7:
21799 return 5;
21800 default:
21801 return 1;
21805 /* Return how many instructions to look ahead for better insn
21806 scheduling. */
21808 static int
21809 rs6000_use_sched_lookahead (void)
21811 if (rs6000_cpu_attr == CPU_PPC8540)
21812 return 4;
21813 if (rs6000_cpu_attr == CPU_CELL)
21814 return (reload_completed ? 8 : 0);
21815 return 0;
21818 /* We are choosing insn from the ready queue. Return nonzero if INSN can be chosen. */
21819 static int
21820 rs6000_use_sched_lookahead_guard (rtx insn)
21822 if (rs6000_cpu_attr != CPU_CELL)
21823 return 1;
21825 if (insn == NULL_RTX || !INSN_P (insn))
21826 abort ();
21828 if (!reload_completed
21829 || is_nonpipeline_insn (insn)
21830 || is_microcoded_insn (insn))
21831 return 0;
21833 return 1;
21836 /* Determine is PAT refers to memory. */
21838 static bool
21839 is_mem_ref (rtx pat)
21841 const char * fmt;
21842 int i, j;
21843 bool ret = false;
21845 /* stack_tie does not produce any real memory traffic. */
21846 if (GET_CODE (pat) == UNSPEC
21847 && XINT (pat, 1) == UNSPEC_TIE)
21848 return false;
21850 if (GET_CODE (pat) == MEM)
21851 return true;
21853 /* Recursively process the pattern. */
21854 fmt = GET_RTX_FORMAT (GET_CODE (pat));
21856 for (i = GET_RTX_LENGTH (GET_CODE (pat)) - 1; i >= 0 && !ret; i--)
21858 if (fmt[i] == 'e')
21859 ret |= is_mem_ref (XEXP (pat, i));
21860 else if (fmt[i] == 'E')
21861 for (j = XVECLEN (pat, i) - 1; j >= 0; j--)
21862 ret |= is_mem_ref (XVECEXP (pat, i, j));
21865 return ret;
21868 /* Determine if PAT is a PATTERN of a load insn. */
21870 static bool
21871 is_load_insn1 (rtx pat)
21873 if (!pat || pat == NULL_RTX)
21874 return false;
21876 if (GET_CODE (pat) == SET)
21877 return is_mem_ref (SET_SRC (pat));
21879 if (GET_CODE (pat) == PARALLEL)
21881 int i;
21883 for (i = 0; i < XVECLEN (pat, 0); i++)
21884 if (is_load_insn1 (XVECEXP (pat, 0, i)))
21885 return true;
21888 return false;
21891 /* Determine if INSN loads from memory. */
21893 static bool
21894 is_load_insn (rtx insn)
21896 if (!insn || !INSN_P (insn))
21897 return false;
21899 if (GET_CODE (insn) == CALL_INSN)
21900 return false;
21902 return is_load_insn1 (PATTERN (insn));
21905 /* Determine if PAT is a PATTERN of a store insn. */
21907 static bool
21908 is_store_insn1 (rtx pat)
21910 if (!pat || pat == NULL_RTX)
21911 return false;
21913 if (GET_CODE (pat) == SET)
21914 return is_mem_ref (SET_DEST (pat));
21916 if (GET_CODE (pat) == PARALLEL)
21918 int i;
21920 for (i = 0; i < XVECLEN (pat, 0); i++)
21921 if (is_store_insn1 (XVECEXP (pat, 0, i)))
21922 return true;
21925 return false;
21928 /* Determine if INSN stores to memory. */
21930 static bool
21931 is_store_insn (rtx insn)
21933 if (!insn || !INSN_P (insn))
21934 return false;
21936 return is_store_insn1 (PATTERN (insn));
21939 /* Return the dest of a store insn. */
21941 static rtx
21942 get_store_dest (rtx pat)
21944 gcc_assert (is_store_insn1 (pat));
21946 if (GET_CODE (pat) == SET)
21947 return SET_DEST (pat);
21948 else if (GET_CODE (pat) == PARALLEL)
21950 int i;
21952 for (i = 0; i < XVECLEN (pat, 0); i++)
21954 rtx inner_pat = XVECEXP (pat, 0, i);
21955 if (GET_CODE (inner_pat) == SET
21956 && is_mem_ref (SET_DEST (inner_pat)))
21957 return inner_pat;
21960 /* We shouldn't get here, because we should have either a simple
21961 store insn or a store with update which are covered above. */
21962 gcc_unreachable();
21965 /* Returns whether the dependence between INSN and NEXT is considered
21966 costly by the given target. */
21968 static bool
21969 rs6000_is_costly_dependence (dep_t dep, int cost, int distance)
21971 rtx insn;
21972 rtx next;
21974 /* If the flag is not enabled - no dependence is considered costly;
21975 allow all dependent insns in the same group.
21976 This is the most aggressive option. */
21977 if (rs6000_sched_costly_dep == no_dep_costly)
21978 return false;
21980 /* If the flag is set to 1 - a dependence is always considered costly;
21981 do not allow dependent instructions in the same group.
21982 This is the most conservative option. */
21983 if (rs6000_sched_costly_dep == all_deps_costly)
21984 return true;
21986 insn = DEP_PRO (dep);
21987 next = DEP_CON (dep);
21989 if (rs6000_sched_costly_dep == store_to_load_dep_costly
21990 && is_load_insn (next)
21991 && is_store_insn (insn))
21992 /* Prevent load after store in the same group. */
21993 return true;
21995 if (rs6000_sched_costly_dep == true_store_to_load_dep_costly
21996 && is_load_insn (next)
21997 && is_store_insn (insn)
21998 && DEP_TYPE (dep) == REG_DEP_TRUE)
21999 /* Prevent load after store in the same group if it is a true
22000 dependence. */
22001 return true;
22003 /* The flag is set to X; dependences with latency >= X are considered costly,
22004 and will not be scheduled in the same group. */
22005 if (rs6000_sched_costly_dep <= max_dep_latency
22006 && ((cost - distance) >= (int)rs6000_sched_costly_dep))
22007 return true;
22009 return false;
22012 /* Return the next insn after INSN that is found before TAIL is reached,
22013 skipping any "non-active" insns - insns that will not actually occupy
22014 an issue slot. Return NULL_RTX if such an insn is not found. */
22016 static rtx
22017 get_next_active_insn (rtx insn, rtx tail)
22019 if (insn == NULL_RTX || insn == tail)
22020 return NULL_RTX;
22022 while (1)
22024 insn = NEXT_INSN (insn);
22025 if (insn == NULL_RTX || insn == tail)
22026 return NULL_RTX;
22028 if (CALL_P (insn)
22029 || JUMP_P (insn)
22030 || (NONJUMP_INSN_P (insn)
22031 && GET_CODE (PATTERN (insn)) != USE
22032 && GET_CODE (PATTERN (insn)) != CLOBBER
22033 && INSN_CODE (insn) != CODE_FOR_stack_tie))
22034 break;
22036 return insn;
22039 /* We are about to begin issuing insns for this clock cycle. */
22041 static int
22042 rs6000_sched_reorder (FILE *dump ATTRIBUTE_UNUSED, int sched_verbose,
22043 rtx *ready ATTRIBUTE_UNUSED,
22044 int *pn_ready ATTRIBUTE_UNUSED,
22045 int clock_var ATTRIBUTE_UNUSED)
22047 int n_ready = *pn_ready;
22049 if (sched_verbose)
22050 fprintf (dump, "// rs6000_sched_reorder :\n");
22052 /* Reorder the ready list, if the second to last ready insn
22053 is a nonepipeline insn. */
22054 if (rs6000_cpu_attr == CPU_CELL && n_ready > 1)
22056 if (is_nonpipeline_insn (ready[n_ready - 1])
22057 && (recog_memoized (ready[n_ready - 2]) > 0))
22058 /* Simply swap first two insns. */
22060 rtx tmp = ready[n_ready - 1];
22061 ready[n_ready - 1] = ready[n_ready - 2];
22062 ready[n_ready - 2] = tmp;
22066 if (rs6000_cpu == PROCESSOR_POWER6)
22067 load_store_pendulum = 0;
22069 return rs6000_issue_rate ();
22072 /* Like rs6000_sched_reorder, but called after issuing each insn. */
22074 static int
22075 rs6000_sched_reorder2 (FILE *dump, int sched_verbose, rtx *ready,
22076 int *pn_ready, int clock_var ATTRIBUTE_UNUSED)
22078 if (sched_verbose)
22079 fprintf (dump, "// rs6000_sched_reorder2 :\n");
22081 /* For Power6, we need to handle some special cases to try and keep the
22082 store queue from overflowing and triggering expensive flushes.
22084 This code monitors how load and store instructions are being issued
22085 and skews the ready list one way or the other to increase the likelihood
22086 that a desired instruction is issued at the proper time.
22088 A couple of things are done. First, we maintain a "load_store_pendulum"
22089 to track the current state of load/store issue.
22091 - If the pendulum is at zero, then no loads or stores have been
22092 issued in the current cycle so we do nothing.
22094 - If the pendulum is 1, then a single load has been issued in this
22095 cycle and we attempt to locate another load in the ready list to
22096 issue with it.
22098 - If the pendulum is -2, then two stores have already been
22099 issued in this cycle, so we increase the priority of the first load
22100 in the ready list to increase it's likelihood of being chosen first
22101 in the next cycle.
22103 - If the pendulum is -1, then a single store has been issued in this
22104 cycle and we attempt to locate another store in the ready list to
22105 issue with it, preferring a store to an adjacent memory location to
22106 facilitate store pairing in the store queue.
22108 - If the pendulum is 2, then two loads have already been
22109 issued in this cycle, so we increase the priority of the first store
22110 in the ready list to increase it's likelihood of being chosen first
22111 in the next cycle.
22113 - If the pendulum < -2 or > 2, then do nothing.
22115 Note: This code covers the most common scenarios. There exist non
22116 load/store instructions which make use of the LSU and which
22117 would need to be accounted for to strictly model the behavior
22118 of the machine. Those instructions are currently unaccounted
22119 for to help minimize compile time overhead of this code.
22121 if (rs6000_cpu == PROCESSOR_POWER6 && last_scheduled_insn)
22123 int pos;
22124 int i;
22125 rtx tmp;
22127 if (is_store_insn (last_scheduled_insn))
22128 /* Issuing a store, swing the load_store_pendulum to the left */
22129 load_store_pendulum--;
22130 else if (is_load_insn (last_scheduled_insn))
22131 /* Issuing a load, swing the load_store_pendulum to the right */
22132 load_store_pendulum++;
22133 else
22134 return cached_can_issue_more;
22136 /* If the pendulum is balanced, or there is only one instruction on
22137 the ready list, then all is well, so return. */
22138 if ((load_store_pendulum == 0) || (*pn_ready <= 1))
22139 return cached_can_issue_more;
22141 if (load_store_pendulum == 1)
22143 /* A load has been issued in this cycle. Scan the ready list
22144 for another load to issue with it */
22145 pos = *pn_ready-1;
22147 while (pos >= 0)
22149 if (is_load_insn (ready[pos]))
22151 /* Found a load. Move it to the head of the ready list,
22152 and adjust it's priority so that it is more likely to
22153 stay there */
22154 tmp = ready[pos];
22155 for (i=pos; i<*pn_ready-1; i++)
22156 ready[i] = ready[i + 1];
22157 ready[*pn_ready-1] = tmp;
22159 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
22160 INSN_PRIORITY (tmp)++;
22161 break;
22163 pos--;
22166 else if (load_store_pendulum == -2)
22168 /* Two stores have been issued in this cycle. Increase the
22169 priority of the first load in the ready list to favor it for
22170 issuing in the next cycle. */
22171 pos = *pn_ready-1;
22173 while (pos >= 0)
22175 if (is_load_insn (ready[pos])
22176 && !sel_sched_p ()
22177 && INSN_PRIORITY_KNOWN (ready[pos]))
22179 INSN_PRIORITY (ready[pos])++;
22181 /* Adjust the pendulum to account for the fact that a load
22182 was found and increased in priority. This is to prevent
22183 increasing the priority of multiple loads */
22184 load_store_pendulum--;
22186 break;
22188 pos--;
22191 else if (load_store_pendulum == -1)
22193 /* A store has been issued in this cycle. Scan the ready list for
22194 another store to issue with it, preferring a store to an adjacent
22195 memory location */
22196 int first_store_pos = -1;
22198 pos = *pn_ready-1;
22200 while (pos >= 0)
22202 if (is_store_insn (ready[pos]))
22204 /* Maintain the index of the first store found on the
22205 list */
22206 if (first_store_pos == -1)
22207 first_store_pos = pos;
22209 if (is_store_insn (last_scheduled_insn)
22210 && adjacent_mem_locations (last_scheduled_insn,ready[pos]))
22212 /* Found an adjacent store. Move it to the head of the
22213 ready list, and adjust it's priority so that it is
22214 more likely to stay there */
22215 tmp = ready[pos];
22216 for (i=pos; i<*pn_ready-1; i++)
22217 ready[i] = ready[i + 1];
22218 ready[*pn_ready-1] = tmp;
22220 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
22221 INSN_PRIORITY (tmp)++;
22223 first_store_pos = -1;
22225 break;
22228 pos--;
22231 if (first_store_pos >= 0)
22233 /* An adjacent store wasn't found, but a non-adjacent store was,
22234 so move the non-adjacent store to the front of the ready
22235 list, and adjust its priority so that it is more likely to
22236 stay there. */
22237 tmp = ready[first_store_pos];
22238 for (i=first_store_pos; i<*pn_ready-1; i++)
22239 ready[i] = ready[i + 1];
22240 ready[*pn_ready-1] = tmp;
22241 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
22242 INSN_PRIORITY (tmp)++;
22245 else if (load_store_pendulum == 2)
22247 /* Two loads have been issued in this cycle. Increase the priority
22248 of the first store in the ready list to favor it for issuing in
22249 the next cycle. */
22250 pos = *pn_ready-1;
22252 while (pos >= 0)
22254 if (is_store_insn (ready[pos])
22255 && !sel_sched_p ()
22256 && INSN_PRIORITY_KNOWN (ready[pos]))
22258 INSN_PRIORITY (ready[pos])++;
22260 /* Adjust the pendulum to account for the fact that a store
22261 was found and increased in priority. This is to prevent
22262 increasing the priority of multiple stores */
22263 load_store_pendulum++;
22265 break;
22267 pos--;
22272 return cached_can_issue_more;
22275 /* Return whether the presence of INSN causes a dispatch group termination
22276 of group WHICH_GROUP.
22278 If WHICH_GROUP == current_group, this function will return true if INSN
22279 causes the termination of the current group (i.e, the dispatch group to
22280 which INSN belongs). This means that INSN will be the last insn in the
22281 group it belongs to.
22283 If WHICH_GROUP == previous_group, this function will return true if INSN
22284 causes the termination of the previous group (i.e, the dispatch group that
22285 precedes the group to which INSN belongs). This means that INSN will be
22286 the first insn in the group it belongs to). */
22288 static bool
22289 insn_terminates_group_p (rtx insn, enum group_termination which_group)
22291 bool first, last;
22293 if (! insn)
22294 return false;
22296 first = insn_must_be_first_in_group (insn);
22297 last = insn_must_be_last_in_group (insn);
22299 if (first && last)
22300 return true;
22302 if (which_group == current_group)
22303 return last;
22304 else if (which_group == previous_group)
22305 return first;
22307 return false;
22311 static bool
22312 insn_must_be_first_in_group (rtx insn)
22314 enum attr_type type;
22316 if (!insn
22317 || GET_CODE (insn) == NOTE
22318 || DEBUG_INSN_P (insn)
22319 || GET_CODE (PATTERN (insn)) == USE
22320 || GET_CODE (PATTERN (insn)) == CLOBBER)
22321 return false;
22323 switch (rs6000_cpu)
22325 case PROCESSOR_POWER5:
22326 if (is_cracked_insn (insn))
22327 return true;
22328 case PROCESSOR_POWER4:
22329 if (is_microcoded_insn (insn))
22330 return true;
22332 if (!rs6000_sched_groups)
22333 return false;
22335 type = get_attr_type (insn);
22337 switch (type)
22339 case TYPE_MFCR:
22340 case TYPE_MFCRF:
22341 case TYPE_MTCR:
22342 case TYPE_DELAYED_CR:
22343 case TYPE_CR_LOGICAL:
22344 case TYPE_MTJMPR:
22345 case TYPE_MFJMPR:
22346 case TYPE_IDIV:
22347 case TYPE_LDIV:
22348 case TYPE_LOAD_L:
22349 case TYPE_STORE_C:
22350 case TYPE_ISYNC:
22351 case TYPE_SYNC:
22352 return true;
22353 default:
22354 break;
22356 break;
22357 case PROCESSOR_POWER6:
22358 type = get_attr_type (insn);
22360 switch (type)
22362 case TYPE_INSERT_DWORD:
22363 case TYPE_EXTS:
22364 case TYPE_CNTLZ:
22365 case TYPE_SHIFT:
22366 case TYPE_VAR_SHIFT_ROTATE:
22367 case TYPE_TRAP:
22368 case TYPE_IMUL:
22369 case TYPE_IMUL2:
22370 case TYPE_IMUL3:
22371 case TYPE_LMUL:
22372 case TYPE_IDIV:
22373 case TYPE_INSERT_WORD:
22374 case TYPE_DELAYED_COMPARE:
22375 case TYPE_IMUL_COMPARE:
22376 case TYPE_LMUL_COMPARE:
22377 case TYPE_FPCOMPARE:
22378 case TYPE_MFCR:
22379 case TYPE_MTCR:
22380 case TYPE_MFJMPR:
22381 case TYPE_MTJMPR:
22382 case TYPE_ISYNC:
22383 case TYPE_SYNC:
22384 case TYPE_LOAD_L:
22385 case TYPE_STORE_C:
22386 case TYPE_LOAD_U:
22387 case TYPE_LOAD_UX:
22388 case TYPE_LOAD_EXT_UX:
22389 case TYPE_STORE_U:
22390 case TYPE_STORE_UX:
22391 case TYPE_FPLOAD_U:
22392 case TYPE_FPLOAD_UX:
22393 case TYPE_FPSTORE_U:
22394 case TYPE_FPSTORE_UX:
22395 return true;
22396 default:
22397 break;
22399 break;
22400 case PROCESSOR_POWER7:
22401 type = get_attr_type (insn);
22403 switch (type)
22405 case TYPE_CR_LOGICAL:
22406 case TYPE_MFCR:
22407 case TYPE_MFCRF:
22408 case TYPE_MTCR:
22409 case TYPE_IDIV:
22410 case TYPE_LDIV:
22411 case TYPE_COMPARE:
22412 case TYPE_DELAYED_COMPARE:
22413 case TYPE_VAR_DELAYED_COMPARE:
22414 case TYPE_ISYNC:
22415 case TYPE_LOAD_L:
22416 case TYPE_STORE_C:
22417 case TYPE_LOAD_U:
22418 case TYPE_LOAD_UX:
22419 case TYPE_LOAD_EXT:
22420 case TYPE_LOAD_EXT_U:
22421 case TYPE_LOAD_EXT_UX:
22422 case TYPE_STORE_U:
22423 case TYPE_STORE_UX:
22424 case TYPE_FPLOAD_U:
22425 case TYPE_FPLOAD_UX:
22426 case TYPE_FPSTORE_U:
22427 case TYPE_FPSTORE_UX:
22428 case TYPE_MFJMPR:
22429 case TYPE_MTJMPR:
22430 return true;
22431 default:
22432 break;
22434 break;
22435 default:
22436 break;
22439 return false;
22442 static bool
22443 insn_must_be_last_in_group (rtx insn)
22445 enum attr_type type;
22447 if (!insn
22448 || GET_CODE (insn) == NOTE
22449 || DEBUG_INSN_P (insn)
22450 || GET_CODE (PATTERN (insn)) == USE
22451 || GET_CODE (PATTERN (insn)) == CLOBBER)
22452 return false;
22454 switch (rs6000_cpu) {
22455 case PROCESSOR_POWER4:
22456 case PROCESSOR_POWER5:
22457 if (is_microcoded_insn (insn))
22458 return true;
22460 if (is_branch_slot_insn (insn))
22461 return true;
22463 break;
22464 case PROCESSOR_POWER6:
22465 type = get_attr_type (insn);
22467 switch (type)
22469 case TYPE_EXTS:
22470 case TYPE_CNTLZ:
22471 case TYPE_SHIFT:
22472 case TYPE_VAR_SHIFT_ROTATE:
22473 case TYPE_TRAP:
22474 case TYPE_IMUL:
22475 case TYPE_IMUL2:
22476 case TYPE_IMUL3:
22477 case TYPE_LMUL:
22478 case TYPE_IDIV:
22479 case TYPE_DELAYED_COMPARE:
22480 case TYPE_IMUL_COMPARE:
22481 case TYPE_LMUL_COMPARE:
22482 case TYPE_FPCOMPARE:
22483 case TYPE_MFCR:
22484 case TYPE_MTCR:
22485 case TYPE_MFJMPR:
22486 case TYPE_MTJMPR:
22487 case TYPE_ISYNC:
22488 case TYPE_SYNC:
22489 case TYPE_LOAD_L:
22490 case TYPE_STORE_C:
22491 return true;
22492 default:
22493 break;
22495 break;
22496 case PROCESSOR_POWER7:
22497 type = get_attr_type (insn);
22499 switch (type)
22501 case TYPE_ISYNC:
22502 case TYPE_SYNC:
22503 case TYPE_LOAD_L:
22504 case TYPE_STORE_C:
22505 case TYPE_LOAD_EXT_U:
22506 case TYPE_LOAD_EXT_UX:
22507 case TYPE_STORE_UX:
22508 return true;
22509 default:
22510 break;
22512 break;
22513 default:
22514 break;
22517 return false;
22520 /* Return true if it is recommended to keep NEXT_INSN "far" (in a separate
22521 dispatch group) from the insns in GROUP_INSNS. Return false otherwise. */
22523 static bool
22524 is_costly_group (rtx *group_insns, rtx next_insn)
22526 int i;
22527 int issue_rate = rs6000_issue_rate ();
22529 for (i = 0; i < issue_rate; i++)
22531 sd_iterator_def sd_it;
22532 dep_t dep;
22533 rtx insn = group_insns[i];
22535 if (!insn)
22536 continue;
22538 FOR_EACH_DEP (insn, SD_LIST_FORW, sd_it, dep)
22540 rtx next = DEP_CON (dep);
22542 if (next == next_insn
22543 && rs6000_is_costly_dependence (dep, dep_cost (dep), 0))
22544 return true;
22548 return false;
22551 /* Utility of the function redefine_groups.
22552 Check if it is too costly to schedule NEXT_INSN together with GROUP_INSNS
22553 in the same dispatch group. If so, insert nops before NEXT_INSN, in order
22554 to keep it "far" (in a separate group) from GROUP_INSNS, following
22555 one of the following schemes, depending on the value of the flag
22556 -minsert_sched_nops = X:
22557 (1) X == sched_finish_regroup_exact: insert exactly as many nops as needed
22558 in order to force NEXT_INSN into a separate group.
22559 (2) X < sched_finish_regroup_exact: insert exactly X nops.
22560 GROUP_END, CAN_ISSUE_MORE and GROUP_COUNT record the state after nop
22561 insertion (has a group just ended, how many vacant issue slots remain in the
22562 last group, and how many dispatch groups were encountered so far). */
22564 static int
22565 force_new_group (int sched_verbose, FILE *dump, rtx *group_insns,
22566 rtx next_insn, bool *group_end, int can_issue_more,
22567 int *group_count)
22569 rtx nop;
22570 bool force;
22571 int issue_rate = rs6000_issue_rate ();
22572 bool end = *group_end;
22573 int i;
22575 if (next_insn == NULL_RTX || DEBUG_INSN_P (next_insn))
22576 return can_issue_more;
22578 if (rs6000_sched_insert_nops > sched_finish_regroup_exact)
22579 return can_issue_more;
22581 force = is_costly_group (group_insns, next_insn);
22582 if (!force)
22583 return can_issue_more;
22585 if (sched_verbose > 6)
22586 fprintf (dump,"force: group count = %d, can_issue_more = %d\n",
22587 *group_count ,can_issue_more);
22589 if (rs6000_sched_insert_nops == sched_finish_regroup_exact)
22591 if (*group_end)
22592 can_issue_more = 0;
22594 /* Since only a branch can be issued in the last issue_slot, it is
22595 sufficient to insert 'can_issue_more - 1' nops if next_insn is not
22596 a branch. If next_insn is a branch, we insert 'can_issue_more' nops;
22597 in this case the last nop will start a new group and the branch
22598 will be forced to the new group. */
22599 if (can_issue_more && !is_branch_slot_insn (next_insn))
22600 can_issue_more--;
22602 while (can_issue_more > 0)
22604 nop = gen_nop ();
22605 emit_insn_before (nop, next_insn);
22606 can_issue_more--;
22609 *group_end = true;
22610 return 0;
22613 if (rs6000_sched_insert_nops < sched_finish_regroup_exact)
22615 int n_nops = rs6000_sched_insert_nops;
22617 /* Nops can't be issued from the branch slot, so the effective
22618 issue_rate for nops is 'issue_rate - 1'. */
22619 if (can_issue_more == 0)
22620 can_issue_more = issue_rate;
22621 can_issue_more--;
22622 if (can_issue_more == 0)
22624 can_issue_more = issue_rate - 1;
22625 (*group_count)++;
22626 end = true;
22627 for (i = 0; i < issue_rate; i++)
22629 group_insns[i] = 0;
22633 while (n_nops > 0)
22635 nop = gen_nop ();
22636 emit_insn_before (nop, next_insn);
22637 if (can_issue_more == issue_rate - 1) /* new group begins */
22638 end = false;
22639 can_issue_more--;
22640 if (can_issue_more == 0)
22642 can_issue_more = issue_rate - 1;
22643 (*group_count)++;
22644 end = true;
22645 for (i = 0; i < issue_rate; i++)
22647 group_insns[i] = 0;
22650 n_nops--;
22653 /* Scale back relative to 'issue_rate' (instead of 'issue_rate - 1'). */
22654 can_issue_more++;
22656 /* Is next_insn going to start a new group? */
22657 *group_end
22658 = (end
22659 || (can_issue_more == 1 && !is_branch_slot_insn (next_insn))
22660 || (can_issue_more <= 2 && is_cracked_insn (next_insn))
22661 || (can_issue_more < issue_rate &&
22662 insn_terminates_group_p (next_insn, previous_group)));
22663 if (*group_end && end)
22664 (*group_count)--;
22666 if (sched_verbose > 6)
22667 fprintf (dump, "done force: group count = %d, can_issue_more = %d\n",
22668 *group_count, can_issue_more);
22669 return can_issue_more;
22672 return can_issue_more;
22675 /* This function tries to synch the dispatch groups that the compiler "sees"
22676 with the dispatch groups that the processor dispatcher is expected to
22677 form in practice. It tries to achieve this synchronization by forcing the
22678 estimated processor grouping on the compiler (as opposed to the function
22679 'pad_goups' which tries to force the scheduler's grouping on the processor).
22681 The function scans the insn sequence between PREV_HEAD_INSN and TAIL and
22682 examines the (estimated) dispatch groups that will be formed by the processor
22683 dispatcher. It marks these group boundaries to reflect the estimated
22684 processor grouping, overriding the grouping that the scheduler had marked.
22685 Depending on the value of the flag '-minsert-sched-nops' this function can
22686 force certain insns into separate groups or force a certain distance between
22687 them by inserting nops, for example, if there exists a "costly dependence"
22688 between the insns.
22690 The function estimates the group boundaries that the processor will form as
22691 follows: It keeps track of how many vacant issue slots are available after
22692 each insn. A subsequent insn will start a new group if one of the following
22693 4 cases applies:
22694 - no more vacant issue slots remain in the current dispatch group.
22695 - only the last issue slot, which is the branch slot, is vacant, but the next
22696 insn is not a branch.
22697 - only the last 2 or less issue slots, including the branch slot, are vacant,
22698 which means that a cracked insn (which occupies two issue slots) can't be
22699 issued in this group.
22700 - less than 'issue_rate' slots are vacant, and the next insn always needs to
22701 start a new group. */
22703 static int
22704 redefine_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail)
22706 rtx insn, next_insn;
22707 int issue_rate;
22708 int can_issue_more;
22709 int slot, i;
22710 bool group_end;
22711 int group_count = 0;
22712 rtx *group_insns;
22714 /* Initialize. */
22715 issue_rate = rs6000_issue_rate ();
22716 group_insns = XALLOCAVEC (rtx, issue_rate);
22717 for (i = 0; i < issue_rate; i++)
22719 group_insns[i] = 0;
22721 can_issue_more = issue_rate;
22722 slot = 0;
22723 insn = get_next_active_insn (prev_head_insn, tail);
22724 group_end = false;
22726 while (insn != NULL_RTX)
22728 slot = (issue_rate - can_issue_more);
22729 group_insns[slot] = insn;
22730 can_issue_more =
22731 rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more);
22732 if (insn_terminates_group_p (insn, current_group))
22733 can_issue_more = 0;
22735 next_insn = get_next_active_insn (insn, tail);
22736 if (next_insn == NULL_RTX)
22737 return group_count + 1;
22739 /* Is next_insn going to start a new group? */
22740 group_end
22741 = (can_issue_more == 0
22742 || (can_issue_more == 1 && !is_branch_slot_insn (next_insn))
22743 || (can_issue_more <= 2 && is_cracked_insn (next_insn))
22744 || (can_issue_more < issue_rate &&
22745 insn_terminates_group_p (next_insn, previous_group)));
22747 can_issue_more = force_new_group (sched_verbose, dump, group_insns,
22748 next_insn, &group_end, can_issue_more,
22749 &group_count);
22751 if (group_end)
22753 group_count++;
22754 can_issue_more = 0;
22755 for (i = 0; i < issue_rate; i++)
22757 group_insns[i] = 0;
22761 if (GET_MODE (next_insn) == TImode && can_issue_more)
22762 PUT_MODE (next_insn, VOIDmode);
22763 else if (!can_issue_more && GET_MODE (next_insn) != TImode)
22764 PUT_MODE (next_insn, TImode);
22766 insn = next_insn;
22767 if (can_issue_more == 0)
22768 can_issue_more = issue_rate;
22769 } /* while */
22771 return group_count;
22774 /* Scan the insn sequence between PREV_HEAD_INSN and TAIL and examine the
22775 dispatch group boundaries that the scheduler had marked. Pad with nops
22776 any dispatch groups which have vacant issue slots, in order to force the
22777 scheduler's grouping on the processor dispatcher. The function
22778 returns the number of dispatch groups found. */
22780 static int
22781 pad_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail)
22783 rtx insn, next_insn;
22784 rtx nop;
22785 int issue_rate;
22786 int can_issue_more;
22787 int group_end;
22788 int group_count = 0;
22790 /* Initialize issue_rate. */
22791 issue_rate = rs6000_issue_rate ();
22792 can_issue_more = issue_rate;
22794 insn = get_next_active_insn (prev_head_insn, tail);
22795 next_insn = get_next_active_insn (insn, tail);
22797 while (insn != NULL_RTX)
22799 can_issue_more =
22800 rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more);
22802 group_end = (next_insn == NULL_RTX || GET_MODE (next_insn) == TImode);
22804 if (next_insn == NULL_RTX)
22805 break;
22807 if (group_end)
22809 /* If the scheduler had marked group termination at this location
22810 (between insn and next_insn), and neither insn nor next_insn will
22811 force group termination, pad the group with nops to force group
22812 termination. */
22813 if (can_issue_more
22814 && (rs6000_sched_insert_nops == sched_finish_pad_groups)
22815 && !insn_terminates_group_p (insn, current_group)
22816 && !insn_terminates_group_p (next_insn, previous_group))
22818 if (!is_branch_slot_insn (next_insn))
22819 can_issue_more--;
22821 while (can_issue_more)
22823 nop = gen_nop ();
22824 emit_insn_before (nop, next_insn);
22825 can_issue_more--;
22829 can_issue_more = issue_rate;
22830 group_count++;
22833 insn = next_insn;
22834 next_insn = get_next_active_insn (insn, tail);
22837 return group_count;
22840 /* We're beginning a new block. Initialize data structures as necessary. */
22842 static void
22843 rs6000_sched_init (FILE *dump ATTRIBUTE_UNUSED,
22844 int sched_verbose ATTRIBUTE_UNUSED,
22845 int max_ready ATTRIBUTE_UNUSED)
22847 last_scheduled_insn = NULL_RTX;
22848 load_store_pendulum = 0;
22851 /* The following function is called at the end of scheduling BB.
22852 After reload, it inserts nops at insn group bundling. */
22854 static void
22855 rs6000_sched_finish (FILE *dump, int sched_verbose)
22857 int n_groups;
22859 if (sched_verbose)
22860 fprintf (dump, "=== Finishing schedule.\n");
22862 if (reload_completed && rs6000_sched_groups)
22864 /* Do not run sched_finish hook when selective scheduling enabled. */
22865 if (sel_sched_p ())
22866 return;
22868 if (rs6000_sched_insert_nops == sched_finish_none)
22869 return;
22871 if (rs6000_sched_insert_nops == sched_finish_pad_groups)
22872 n_groups = pad_groups (dump, sched_verbose,
22873 current_sched_info->prev_head,
22874 current_sched_info->next_tail);
22875 else
22876 n_groups = redefine_groups (dump, sched_verbose,
22877 current_sched_info->prev_head,
22878 current_sched_info->next_tail);
22880 if (sched_verbose >= 6)
22882 fprintf (dump, "ngroups = %d\n", n_groups);
22883 print_rtl (dump, current_sched_info->prev_head);
22884 fprintf (dump, "Done finish_sched\n");
22889 struct _rs6000_sched_context
22891 short cached_can_issue_more;
22892 rtx last_scheduled_insn;
22893 int load_store_pendulum;
22896 typedef struct _rs6000_sched_context rs6000_sched_context_def;
22897 typedef rs6000_sched_context_def *rs6000_sched_context_t;
22899 /* Allocate store for new scheduling context. */
22900 static void *
22901 rs6000_alloc_sched_context (void)
22903 return xmalloc (sizeof (rs6000_sched_context_def));
22906 /* If CLEAN_P is true then initializes _SC with clean data,
22907 and from the global context otherwise. */
22908 static void
22909 rs6000_init_sched_context (void *_sc, bool clean_p)
22911 rs6000_sched_context_t sc = (rs6000_sched_context_t) _sc;
22913 if (clean_p)
22915 sc->cached_can_issue_more = 0;
22916 sc->last_scheduled_insn = NULL_RTX;
22917 sc->load_store_pendulum = 0;
22919 else
22921 sc->cached_can_issue_more = cached_can_issue_more;
22922 sc->last_scheduled_insn = last_scheduled_insn;
22923 sc->load_store_pendulum = load_store_pendulum;
22927 /* Sets the global scheduling context to the one pointed to by _SC. */
22928 static void
22929 rs6000_set_sched_context (void *_sc)
22931 rs6000_sched_context_t sc = (rs6000_sched_context_t) _sc;
22933 gcc_assert (sc != NULL);
22935 cached_can_issue_more = sc->cached_can_issue_more;
22936 last_scheduled_insn = sc->last_scheduled_insn;
22937 load_store_pendulum = sc->load_store_pendulum;
22940 /* Free _SC. */
22941 static void
22942 rs6000_free_sched_context (void *_sc)
22944 gcc_assert (_sc != NULL);
22946 free (_sc);
22950 /* Length in units of the trampoline for entering a nested function. */
22953 rs6000_trampoline_size (void)
22955 int ret = 0;
22957 switch (DEFAULT_ABI)
22959 default:
22960 gcc_unreachable ();
22962 case ABI_AIX:
22963 ret = (TARGET_32BIT) ? 12 : 24;
22964 break;
22966 case ABI_DARWIN:
22967 case ABI_V4:
22968 ret = (TARGET_32BIT) ? 40 : 48;
22969 break;
22972 return ret;
22975 /* Emit RTL insns to initialize the variable parts of a trampoline.
22976 FNADDR is an RTX for the address of the function's pure code.
22977 CXT is an RTX for the static chain value for the function. */
22979 static void
22980 rs6000_trampoline_init (rtx m_tramp, tree fndecl, rtx cxt)
22982 int regsize = (TARGET_32BIT) ? 4 : 8;
22983 rtx fnaddr = XEXP (DECL_RTL (fndecl), 0);
22984 rtx ctx_reg = force_reg (Pmode, cxt);
22985 rtx addr = force_reg (Pmode, XEXP (m_tramp, 0));
22987 switch (DEFAULT_ABI)
22989 default:
22990 gcc_unreachable ();
22992 /* Under AIX, just build the 3 word function descriptor */
22993 case ABI_AIX:
22995 rtx fnmem = gen_const_mem (Pmode, force_reg (Pmode, fnaddr));
22996 rtx fn_reg = gen_reg_rtx (Pmode);
22997 rtx toc_reg = gen_reg_rtx (Pmode);
22999 /* Macro to shorten the code expansions below. */
23000 # define MEM_PLUS(MEM, OFFSET) adjust_address (MEM, Pmode, OFFSET)
23002 m_tramp = replace_equiv_address (m_tramp, addr);
23004 emit_move_insn (fn_reg, MEM_PLUS (fnmem, 0));
23005 emit_move_insn (toc_reg, MEM_PLUS (fnmem, regsize));
23006 emit_move_insn (MEM_PLUS (m_tramp, 0), fn_reg);
23007 emit_move_insn (MEM_PLUS (m_tramp, regsize), toc_reg);
23008 emit_move_insn (MEM_PLUS (m_tramp, 2*regsize), ctx_reg);
23010 # undef MEM_PLUS
23012 break;
23014 /* Under V.4/eabi/darwin, __trampoline_setup does the real work. */
23015 case ABI_DARWIN:
23016 case ABI_V4:
23017 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__trampoline_setup"),
23018 LCT_NORMAL, VOIDmode, 4,
23019 addr, Pmode,
23020 GEN_INT (rs6000_trampoline_size ()), SImode,
23021 fnaddr, Pmode,
23022 ctx_reg, Pmode);
23023 break;
23028 /* Handle the "altivec" attribute. The attribute may have
23029 arguments as follows:
23031 __attribute__((altivec(vector__)))
23032 __attribute__((altivec(pixel__))) (always followed by 'unsigned short')
23033 __attribute__((altivec(bool__))) (always followed by 'unsigned')
23035 and may appear more than once (e.g., 'vector bool char') in a
23036 given declaration. */
23038 static tree
23039 rs6000_handle_altivec_attribute (tree *node,
23040 tree name ATTRIBUTE_UNUSED,
23041 tree args,
23042 int flags ATTRIBUTE_UNUSED,
23043 bool *no_add_attrs)
23045 tree type = *node, result = NULL_TREE;
23046 enum machine_mode mode;
23047 int unsigned_p;
23048 char altivec_type
23049 = ((args && TREE_CODE (args) == TREE_LIST && TREE_VALUE (args)
23050 && TREE_CODE (TREE_VALUE (args)) == IDENTIFIER_NODE)
23051 ? *IDENTIFIER_POINTER (TREE_VALUE (args))
23052 : '?');
23054 while (POINTER_TYPE_P (type)
23055 || TREE_CODE (type) == FUNCTION_TYPE
23056 || TREE_CODE (type) == METHOD_TYPE
23057 || TREE_CODE (type) == ARRAY_TYPE)
23058 type = TREE_TYPE (type);
23060 mode = TYPE_MODE (type);
23062 /* Check for invalid AltiVec type qualifiers. */
23063 if (type == long_double_type_node)
23064 error ("use of %<long double%> in AltiVec types is invalid");
23065 else if (type == boolean_type_node)
23066 error ("use of boolean types in AltiVec types is invalid");
23067 else if (TREE_CODE (type) == COMPLEX_TYPE)
23068 error ("use of %<complex%> in AltiVec types is invalid");
23069 else if (DECIMAL_FLOAT_MODE_P (mode))
23070 error ("use of decimal floating point types in AltiVec types is invalid");
23071 else if (!TARGET_VSX)
23073 if (type == long_unsigned_type_node || type == long_integer_type_node)
23075 if (TARGET_64BIT)
23076 error ("use of %<long%> in AltiVec types is invalid for "
23077 "64-bit code without -mvsx");
23078 else if (rs6000_warn_altivec_long)
23079 warning (0, "use of %<long%> in AltiVec types is deprecated; "
23080 "use %<int%>");
23082 else if (type == long_long_unsigned_type_node
23083 || type == long_long_integer_type_node)
23084 error ("use of %<long long%> in AltiVec types is invalid without "
23085 "-mvsx");
23086 else if (type == double_type_node)
23087 error ("use of %<double%> in AltiVec types is invalid without -mvsx");
23090 switch (altivec_type)
23092 case 'v':
23093 unsigned_p = TYPE_UNSIGNED (type);
23094 switch (mode)
23096 case DImode:
23097 result = (unsigned_p ? unsigned_V2DI_type_node : V2DI_type_node);
23098 break;
23099 case SImode:
23100 result = (unsigned_p ? unsigned_V4SI_type_node : V4SI_type_node);
23101 break;
23102 case HImode:
23103 result = (unsigned_p ? unsigned_V8HI_type_node : V8HI_type_node);
23104 break;
23105 case QImode:
23106 result = (unsigned_p ? unsigned_V16QI_type_node : V16QI_type_node);
23107 break;
23108 case SFmode: result = V4SF_type_node; break;
23109 case DFmode: result = V2DF_type_node; break;
23110 /* If the user says 'vector int bool', we may be handed the 'bool'
23111 attribute _before_ the 'vector' attribute, and so select the
23112 proper type in the 'b' case below. */
23113 case V4SImode: case V8HImode: case V16QImode: case V4SFmode:
23114 case V2DImode: case V2DFmode:
23115 result = type;
23116 default: break;
23118 break;
23119 case 'b':
23120 switch (mode)
23122 case DImode: case V2DImode: result = bool_V2DI_type_node; break;
23123 case SImode: case V4SImode: result = bool_V4SI_type_node; break;
23124 case HImode: case V8HImode: result = bool_V8HI_type_node; break;
23125 case QImode: case V16QImode: result = bool_V16QI_type_node;
23126 default: break;
23128 break;
23129 case 'p':
23130 switch (mode)
23132 case V8HImode: result = pixel_V8HI_type_node;
23133 default: break;
23135 default: break;
23138 /* Propagate qualifiers attached to the element type
23139 onto the vector type. */
23140 if (result && result != type && TYPE_QUALS (type))
23141 result = build_qualified_type (result, TYPE_QUALS (type));
23143 *no_add_attrs = true; /* No need to hang on to the attribute. */
23145 if (result)
23146 *node = lang_hooks.types.reconstruct_complex_type (*node, result);
23148 return NULL_TREE;
23151 /* AltiVec defines four built-in scalar types that serve as vector
23152 elements; we must teach the compiler how to mangle them. */
23154 static const char *
23155 rs6000_mangle_type (const_tree type)
23157 type = TYPE_MAIN_VARIANT (type);
23159 if (TREE_CODE (type) != VOID_TYPE && TREE_CODE (type) != BOOLEAN_TYPE
23160 && TREE_CODE (type) != INTEGER_TYPE && TREE_CODE (type) != REAL_TYPE)
23161 return NULL;
23163 if (type == bool_char_type_node) return "U6__boolc";
23164 if (type == bool_short_type_node) return "U6__bools";
23165 if (type == pixel_type_node) return "u7__pixel";
23166 if (type == bool_int_type_node) return "U6__booli";
23167 if (type == bool_long_type_node) return "U6__booll";
23169 /* Mangle IBM extended float long double as `g' (__float128) on
23170 powerpc*-linux where long-double-64 previously was the default. */
23171 if (TYPE_MAIN_VARIANT (type) == long_double_type_node
23172 && TARGET_ELF
23173 && TARGET_LONG_DOUBLE_128
23174 && !TARGET_IEEEQUAD)
23175 return "g";
23177 /* For all other types, use normal C++ mangling. */
23178 return NULL;
23181 /* Handle a "longcall" or "shortcall" attribute; arguments as in
23182 struct attribute_spec.handler. */
23184 static tree
23185 rs6000_handle_longcall_attribute (tree *node, tree name,
23186 tree args ATTRIBUTE_UNUSED,
23187 int flags ATTRIBUTE_UNUSED,
23188 bool *no_add_attrs)
23190 if (TREE_CODE (*node) != FUNCTION_TYPE
23191 && TREE_CODE (*node) != FIELD_DECL
23192 && TREE_CODE (*node) != TYPE_DECL)
23194 warning (OPT_Wattributes, "%qE attribute only applies to functions",
23195 name);
23196 *no_add_attrs = true;
23199 return NULL_TREE;
23202 /* Set longcall attributes on all functions declared when
23203 rs6000_default_long_calls is true. */
23204 static void
23205 rs6000_set_default_type_attributes (tree type)
23207 if (rs6000_default_long_calls
23208 && (TREE_CODE (type) == FUNCTION_TYPE
23209 || TREE_CODE (type) == METHOD_TYPE))
23210 TYPE_ATTRIBUTES (type) = tree_cons (get_identifier ("longcall"),
23211 NULL_TREE,
23212 TYPE_ATTRIBUTES (type));
23214 #if TARGET_MACHO
23215 darwin_set_default_type_attributes (type);
23216 #endif
23219 /* Return a reference suitable for calling a function with the
23220 longcall attribute. */
23223 rs6000_longcall_ref (rtx call_ref)
23225 const char *call_name;
23226 tree node;
23228 if (GET_CODE (call_ref) != SYMBOL_REF)
23229 return call_ref;
23231 /* System V adds '.' to the internal name, so skip them. */
23232 call_name = XSTR (call_ref, 0);
23233 if (*call_name == '.')
23235 while (*call_name == '.')
23236 call_name++;
23238 node = get_identifier (call_name);
23239 call_ref = gen_rtx_SYMBOL_REF (VOIDmode, IDENTIFIER_POINTER (node));
23242 return force_reg (Pmode, call_ref);
23245 #ifndef TARGET_USE_MS_BITFIELD_LAYOUT
23246 #define TARGET_USE_MS_BITFIELD_LAYOUT 0
23247 #endif
23249 /* Handle a "ms_struct" or "gcc_struct" attribute; arguments as in
23250 struct attribute_spec.handler. */
23251 static tree
23252 rs6000_handle_struct_attribute (tree *node, tree name,
23253 tree args ATTRIBUTE_UNUSED,
23254 int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
23256 tree *type = NULL;
23257 if (DECL_P (*node))
23259 if (TREE_CODE (*node) == TYPE_DECL)
23260 type = &TREE_TYPE (*node);
23262 else
23263 type = node;
23265 if (!(type && (TREE_CODE (*type) == RECORD_TYPE
23266 || TREE_CODE (*type) == UNION_TYPE)))
23268 warning (OPT_Wattributes, "%qE attribute ignored", name);
23269 *no_add_attrs = true;
23272 else if ((is_attribute_p ("ms_struct", name)
23273 && lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (*type)))
23274 || ((is_attribute_p ("gcc_struct", name)
23275 && lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (*type)))))
23277 warning (OPT_Wattributes, "%qE incompatible attribute ignored",
23278 name);
23279 *no_add_attrs = true;
23282 return NULL_TREE;
23285 static bool
23286 rs6000_ms_bitfield_layout_p (const_tree record_type)
23288 return (TARGET_USE_MS_BITFIELD_LAYOUT &&
23289 !lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (record_type)))
23290 || lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (record_type));
23293 #ifdef USING_ELFOS_H
23295 /* A get_unnamed_section callback, used for switching to toc_section. */
23297 static void
23298 rs6000_elf_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
23300 if (DEFAULT_ABI == ABI_AIX
23301 && TARGET_MINIMAL_TOC
23302 && !TARGET_RELOCATABLE)
23304 if (!toc_initialized)
23306 toc_initialized = 1;
23307 fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);
23308 (*targetm.asm_out.internal_label) (asm_out_file, "LCTOC", 0);
23309 fprintf (asm_out_file, "\t.tc ");
23310 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1[TC],");
23311 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
23312 fprintf (asm_out_file, "\n");
23314 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
23315 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
23316 fprintf (asm_out_file, " = .+32768\n");
23318 else
23319 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
23321 else if (DEFAULT_ABI == ABI_AIX && !TARGET_RELOCATABLE)
23322 fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);
23323 else
23325 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
23326 if (!toc_initialized)
23328 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
23329 fprintf (asm_out_file, " = .+32768\n");
23330 toc_initialized = 1;
23335 /* Implement TARGET_ASM_INIT_SECTIONS. */
23337 static void
23338 rs6000_elf_asm_init_sections (void)
23340 toc_section
23341 = get_unnamed_section (0, rs6000_elf_output_toc_section_asm_op, NULL);
23343 sdata2_section
23344 = get_unnamed_section (SECTION_WRITE, output_section_asm_op,
23345 SDATA2_SECTION_ASM_OP);
23348 /* Implement TARGET_SELECT_RTX_SECTION. */
23350 static section *
23351 rs6000_elf_select_rtx_section (enum machine_mode mode, rtx x,
23352 unsigned HOST_WIDE_INT align)
23354 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
23355 return toc_section;
23356 else
23357 return default_elf_select_rtx_section (mode, x, align);
23360 /* For a SYMBOL_REF, set generic flags and then perform some
23361 target-specific processing.
23363 When the AIX ABI is requested on a non-AIX system, replace the
23364 function name with the real name (with a leading .) rather than the
23365 function descriptor name. This saves a lot of overriding code to
23366 read the prefixes. */
23368 static void
23369 rs6000_elf_encode_section_info (tree decl, rtx rtl, int first)
23371 default_encode_section_info (decl, rtl, first);
23373 if (first
23374 && TREE_CODE (decl) == FUNCTION_DECL
23375 && !TARGET_AIX
23376 && DEFAULT_ABI == ABI_AIX)
23378 rtx sym_ref = XEXP (rtl, 0);
23379 size_t len = strlen (XSTR (sym_ref, 0));
23380 char *str = XALLOCAVEC (char, len + 2);
23381 str[0] = '.';
23382 memcpy (str + 1, XSTR (sym_ref, 0), len + 1);
23383 XSTR (sym_ref, 0) = ggc_alloc_string (str, len + 1);
23387 static inline bool
23388 compare_section_name (const char *section, const char *templ)
23390 int len;
23392 len = strlen (templ);
23393 return (strncmp (section, templ, len) == 0
23394 && (section[len] == 0 || section[len] == '.'));
23397 bool
23398 rs6000_elf_in_small_data_p (const_tree decl)
23400 if (rs6000_sdata == SDATA_NONE)
23401 return false;
23403 /* We want to merge strings, so we never consider them small data. */
23404 if (TREE_CODE (decl) == STRING_CST)
23405 return false;
23407 /* Functions are never in the small data area. */
23408 if (TREE_CODE (decl) == FUNCTION_DECL)
23409 return false;
23411 if (TREE_CODE (decl) == VAR_DECL && DECL_SECTION_NAME (decl))
23413 const char *section = TREE_STRING_POINTER (DECL_SECTION_NAME (decl));
23414 if (compare_section_name (section, ".sdata")
23415 || compare_section_name (section, ".sdata2")
23416 || compare_section_name (section, ".gnu.linkonce.s")
23417 || compare_section_name (section, ".sbss")
23418 || compare_section_name (section, ".sbss2")
23419 || compare_section_name (section, ".gnu.linkonce.sb")
23420 || strcmp (section, ".PPC.EMB.sdata0") == 0
23421 || strcmp (section, ".PPC.EMB.sbss0") == 0)
23422 return true;
23424 else
23426 HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (decl));
23428 if (size > 0
23429 && (unsigned HOST_WIDE_INT) size <= g_switch_value
23430 /* If it's not public, and we're not going to reference it there,
23431 there's no need to put it in the small data section. */
23432 && (rs6000_sdata != SDATA_DATA || TREE_PUBLIC (decl)))
23433 return true;
23436 return false;
23439 #endif /* USING_ELFOS_H */
23441 /* Implement TARGET_USE_BLOCKS_FOR_CONSTANT_P. */
23443 static bool
23444 rs6000_use_blocks_for_constant_p (enum machine_mode mode, const_rtx x)
23446 return !ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode);
23449 /* Return a REG that occurs in ADDR with coefficient 1.
23450 ADDR can be effectively incremented by incrementing REG.
23452 r0 is special and we must not select it as an address
23453 register by this routine since our caller will try to
23454 increment the returned register via an "la" instruction. */
23457 find_addr_reg (rtx addr)
23459 while (GET_CODE (addr) == PLUS)
23461 if (GET_CODE (XEXP (addr, 0)) == REG
23462 && REGNO (XEXP (addr, 0)) != 0)
23463 addr = XEXP (addr, 0);
23464 else if (GET_CODE (XEXP (addr, 1)) == REG
23465 && REGNO (XEXP (addr, 1)) != 0)
23466 addr = XEXP (addr, 1);
23467 else if (CONSTANT_P (XEXP (addr, 0)))
23468 addr = XEXP (addr, 1);
23469 else if (CONSTANT_P (XEXP (addr, 1)))
23470 addr = XEXP (addr, 0);
23471 else
23472 gcc_unreachable ();
23474 gcc_assert (GET_CODE (addr) == REG && REGNO (addr) != 0);
23475 return addr;
23478 void
23479 rs6000_fatal_bad_address (rtx op)
23481 fatal_insn ("bad address", op);
23484 #if TARGET_MACHO
23486 static tree branch_island_list = 0;
23488 /* Remember to generate a branch island for far calls to the given
23489 function. */
23491 static void
23492 add_compiler_branch_island (tree label_name, tree function_name,
23493 int line_number)
23495 tree branch_island = build_tree_list (function_name, label_name);
23496 TREE_TYPE (branch_island) = build_int_cst (NULL_TREE, line_number);
23497 TREE_CHAIN (branch_island) = branch_island_list;
23498 branch_island_list = branch_island;
23501 #define BRANCH_ISLAND_LABEL_NAME(BRANCH_ISLAND) TREE_VALUE (BRANCH_ISLAND)
23502 #define BRANCH_ISLAND_FUNCTION_NAME(BRANCH_ISLAND) TREE_PURPOSE (BRANCH_ISLAND)
23503 #define BRANCH_ISLAND_LINE_NUMBER(BRANCH_ISLAND) \
23504 TREE_INT_CST_LOW (TREE_TYPE (BRANCH_ISLAND))
23506 /* Generate far-jump branch islands for everything on the
23507 branch_island_list. Invoked immediately after the last instruction
23508 of the epilogue has been emitted; the branch-islands must be
23509 appended to, and contiguous with, the function body. Mach-O stubs
23510 are generated in machopic_output_stub(). */
23512 static void
23513 macho_branch_islands (void)
23515 char tmp_buf[512];
23516 tree branch_island;
23518 for (branch_island = branch_island_list;
23519 branch_island;
23520 branch_island = TREE_CHAIN (branch_island))
23522 const char *label =
23523 IDENTIFIER_POINTER (BRANCH_ISLAND_LABEL_NAME (branch_island));
23524 const char *name =
23525 IDENTIFIER_POINTER (BRANCH_ISLAND_FUNCTION_NAME (branch_island));
23526 char name_buf[512];
23527 /* Cheap copy of the details from the Darwin ASM_OUTPUT_LABELREF(). */
23528 if (name[0] == '*' || name[0] == '&')
23529 strcpy (name_buf, name+1);
23530 else
23532 name_buf[0] = '_';
23533 strcpy (name_buf+1, name);
23535 strcpy (tmp_buf, "\n");
23536 strcat (tmp_buf, label);
23537 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
23538 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
23539 dbxout_stabd (N_SLINE, BRANCH_ISLAND_LINE_NUMBER (branch_island));
23540 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
23541 if (flag_pic)
23543 strcat (tmp_buf, ":\n\tmflr r0\n\tbcl 20,31,");
23544 strcat (tmp_buf, label);
23545 strcat (tmp_buf, "_pic\n");
23546 strcat (tmp_buf, label);
23547 strcat (tmp_buf, "_pic:\n\tmflr r11\n");
23549 strcat (tmp_buf, "\taddis r11,r11,ha16(");
23550 strcat (tmp_buf, name_buf);
23551 strcat (tmp_buf, " - ");
23552 strcat (tmp_buf, label);
23553 strcat (tmp_buf, "_pic)\n");
23555 strcat (tmp_buf, "\tmtlr r0\n");
23557 strcat (tmp_buf, "\taddi r12,r11,lo16(");
23558 strcat (tmp_buf, name_buf);
23559 strcat (tmp_buf, " - ");
23560 strcat (tmp_buf, label);
23561 strcat (tmp_buf, "_pic)\n");
23563 strcat (tmp_buf, "\tmtctr r12\n\tbctr\n");
23565 else
23567 strcat (tmp_buf, ":\nlis r12,hi16(");
23568 strcat (tmp_buf, name_buf);
23569 strcat (tmp_buf, ")\n\tori r12,r12,lo16(");
23570 strcat (tmp_buf, name_buf);
23571 strcat (tmp_buf, ")\n\tmtctr r12\n\tbctr");
23573 output_asm_insn (tmp_buf, 0);
23574 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
23575 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
23576 dbxout_stabd (N_SLINE, BRANCH_ISLAND_LINE_NUMBER (branch_island));
23577 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
23580 branch_island_list = 0;
23583 /* NO_PREVIOUS_DEF checks in the link list whether the function name is
23584 already there or not. */
23586 static int
23587 no_previous_def (tree function_name)
23589 tree branch_island;
23590 for (branch_island = branch_island_list;
23591 branch_island;
23592 branch_island = TREE_CHAIN (branch_island))
23593 if (function_name == BRANCH_ISLAND_FUNCTION_NAME (branch_island))
23594 return 0;
23595 return 1;
23598 /* GET_PREV_LABEL gets the label name from the previous definition of
23599 the function. */
23601 static tree
23602 get_prev_label (tree function_name)
23604 tree branch_island;
23605 for (branch_island = branch_island_list;
23606 branch_island;
23607 branch_island = TREE_CHAIN (branch_island))
23608 if (function_name == BRANCH_ISLAND_FUNCTION_NAME (branch_island))
23609 return BRANCH_ISLAND_LABEL_NAME (branch_island);
23610 return 0;
23613 #ifndef DARWIN_LINKER_GENERATES_ISLANDS
23614 #define DARWIN_LINKER_GENERATES_ISLANDS 0
23615 #endif
23617 /* KEXTs still need branch islands. */
23618 #define DARWIN_GENERATE_ISLANDS (!DARWIN_LINKER_GENERATES_ISLANDS \
23619 || flag_mkernel || flag_apple_kext)
23621 /* INSN is either a function call or a millicode call. It may have an
23622 unconditional jump in its delay slot.
23624 CALL_DEST is the routine we are calling. */
23626 char *
23627 output_call (rtx insn, rtx *operands, int dest_operand_number,
23628 int cookie_operand_number)
23630 static char buf[256];
23631 if (DARWIN_GENERATE_ISLANDS
23632 && GET_CODE (operands[dest_operand_number]) == SYMBOL_REF
23633 && (INTVAL (operands[cookie_operand_number]) & CALL_LONG))
23635 tree labelname;
23636 tree funname = get_identifier (XSTR (operands[dest_operand_number], 0));
23638 if (no_previous_def (funname))
23640 rtx label_rtx = gen_label_rtx ();
23641 char *label_buf, temp_buf[256];
23642 ASM_GENERATE_INTERNAL_LABEL (temp_buf, "L",
23643 CODE_LABEL_NUMBER (label_rtx));
23644 label_buf = temp_buf[0] == '*' ? temp_buf + 1 : temp_buf;
23645 labelname = get_identifier (label_buf);
23646 add_compiler_branch_island (labelname, funname, insn_line (insn));
23648 else
23649 labelname = get_prev_label (funname);
23651 /* "jbsr foo, L42" is Mach-O for "Link as 'bl foo' if a 'bl'
23652 instruction will reach 'foo', otherwise link as 'bl L42'".
23653 "L42" should be a 'branch island', that will do a far jump to
23654 'foo'. Branch islands are generated in
23655 macho_branch_islands(). */
23656 sprintf (buf, "jbsr %%z%d,%.246s",
23657 dest_operand_number, IDENTIFIER_POINTER (labelname));
23659 else
23660 sprintf (buf, "bl %%z%d", dest_operand_number);
23661 return buf;
23664 /* Generate PIC and indirect symbol stubs. */
23666 void
23667 machopic_output_stub (FILE *file, const char *symb, const char *stub)
23669 unsigned int length;
23670 char *symbol_name, *lazy_ptr_name;
23671 char *local_label_0;
23672 static int label = 0;
23674 /* Lose our funky encoding stuff so it doesn't contaminate the stub. */
23675 symb = (*targetm.strip_name_encoding) (symb);
23678 length = strlen (symb);
23679 symbol_name = XALLOCAVEC (char, length + 32);
23680 GEN_SYMBOL_NAME_FOR_SYMBOL (symbol_name, symb, length);
23682 lazy_ptr_name = XALLOCAVEC (char, length + 32);
23683 GEN_LAZY_PTR_NAME_FOR_SYMBOL (lazy_ptr_name, symb, length);
23685 if (flag_pic == 2)
23686 switch_to_section (darwin_sections[machopic_picsymbol_stub1_section]);
23687 else
23688 switch_to_section (darwin_sections[machopic_symbol_stub1_section]);
23690 if (flag_pic == 2)
23692 fprintf (file, "\t.align 5\n");
23694 fprintf (file, "%s:\n", stub);
23695 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
23697 label++;
23698 local_label_0 = XALLOCAVEC (char, sizeof ("\"L00000000000$spb\""));
23699 sprintf (local_label_0, "\"L%011d$spb\"", label);
23701 fprintf (file, "\tmflr r0\n");
23702 fprintf (file, "\tbcl 20,31,%s\n", local_label_0);
23703 fprintf (file, "%s:\n\tmflr r11\n", local_label_0);
23704 fprintf (file, "\taddis r11,r11,ha16(%s-%s)\n",
23705 lazy_ptr_name, local_label_0);
23706 fprintf (file, "\tmtlr r0\n");
23707 fprintf (file, "\t%s r12,lo16(%s-%s)(r11)\n",
23708 (TARGET_64BIT ? "ldu" : "lwzu"),
23709 lazy_ptr_name, local_label_0);
23710 fprintf (file, "\tmtctr r12\n");
23711 fprintf (file, "\tbctr\n");
23713 else
23715 fprintf (file, "\t.align 4\n");
23717 fprintf (file, "%s:\n", stub);
23718 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
23720 fprintf (file, "\tlis r11,ha16(%s)\n", lazy_ptr_name);
23721 fprintf (file, "\t%s r12,lo16(%s)(r11)\n",
23722 (TARGET_64BIT ? "ldu" : "lwzu"),
23723 lazy_ptr_name);
23724 fprintf (file, "\tmtctr r12\n");
23725 fprintf (file, "\tbctr\n");
23728 switch_to_section (darwin_sections[machopic_lazy_symbol_ptr_section]);
23729 fprintf (file, "%s:\n", lazy_ptr_name);
23730 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
23731 fprintf (file, "%sdyld_stub_binding_helper\n",
23732 (TARGET_64BIT ? DOUBLE_INT_ASM_OP : "\t.long\t"));
23735 /* Legitimize PIC addresses. If the address is already
23736 position-independent, we return ORIG. Newly generated
23737 position-independent addresses go into a reg. This is REG if non
23738 zero, otherwise we allocate register(s) as necessary. */
23740 #define SMALL_INT(X) ((UINTVAL (X) + 0x8000) < 0x10000)
23743 rs6000_machopic_legitimize_pic_address (rtx orig, enum machine_mode mode,
23744 rtx reg)
23746 rtx base, offset;
23748 if (reg == NULL && ! reload_in_progress && ! reload_completed)
23749 reg = gen_reg_rtx (Pmode);
23751 if (GET_CODE (orig) == CONST)
23753 rtx reg_temp;
23755 if (GET_CODE (XEXP (orig, 0)) == PLUS
23756 && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx)
23757 return orig;
23759 gcc_assert (GET_CODE (XEXP (orig, 0)) == PLUS);
23761 /* Use a different reg for the intermediate value, as
23762 it will be marked UNCHANGING. */
23763 reg_temp = !can_create_pseudo_p () ? reg : gen_reg_rtx (Pmode);
23764 base = rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 0),
23765 Pmode, reg_temp);
23766 offset =
23767 rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 1),
23768 Pmode, reg);
23770 if (GET_CODE (offset) == CONST_INT)
23772 if (SMALL_INT (offset))
23773 return plus_constant (base, INTVAL (offset));
23774 else if (! reload_in_progress && ! reload_completed)
23775 offset = force_reg (Pmode, offset);
23776 else
23778 rtx mem = force_const_mem (Pmode, orig);
23779 return machopic_legitimize_pic_address (mem, Pmode, reg);
23782 return gen_rtx_PLUS (Pmode, base, offset);
23785 /* Fall back on generic machopic code. */
23786 return machopic_legitimize_pic_address (orig, mode, reg);
23789 /* Output a .machine directive for the Darwin assembler, and call
23790 the generic start_file routine. */
23792 static void
23793 rs6000_darwin_file_start (void)
23795 static const struct
23797 const char *arg;
23798 const char *name;
23799 int if_set;
23800 } mapping[] = {
23801 { "ppc64", "ppc64", MASK_64BIT },
23802 { "970", "ppc970", MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64 },
23803 { "power4", "ppc970", 0 },
23804 { "G5", "ppc970", 0 },
23805 { "7450", "ppc7450", 0 },
23806 { "7400", "ppc7400", MASK_ALTIVEC },
23807 { "G4", "ppc7400", 0 },
23808 { "750", "ppc750", 0 },
23809 { "740", "ppc750", 0 },
23810 { "G3", "ppc750", 0 },
23811 { "604e", "ppc604e", 0 },
23812 { "604", "ppc604", 0 },
23813 { "603e", "ppc603", 0 },
23814 { "603", "ppc603", 0 },
23815 { "601", "ppc601", 0 },
23816 { NULL, "ppc", 0 } };
23817 const char *cpu_id = "";
23818 size_t i;
23820 rs6000_file_start ();
23821 darwin_file_start ();
23823 /* Determine the argument to -mcpu=. Default to G3 if not specified. */
23824 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
23825 if (rs6000_select[i].set_arch_p && rs6000_select[i].string
23826 && rs6000_select[i].string[0] != '\0')
23827 cpu_id = rs6000_select[i].string;
23829 /* Look through the mapping array. Pick the first name that either
23830 matches the argument, has a bit set in IF_SET that is also set
23831 in the target flags, or has a NULL name. */
23833 i = 0;
23834 while (mapping[i].arg != NULL
23835 && strcmp (mapping[i].arg, cpu_id) != 0
23836 && (mapping[i].if_set & target_flags) == 0)
23837 i++;
23839 fprintf (asm_out_file, "\t.machine %s\n", mapping[i].name);
23842 #endif /* TARGET_MACHO */
23844 #if TARGET_ELF
23845 static int
23846 rs6000_elf_reloc_rw_mask (void)
23848 if (flag_pic)
23849 return 3;
23850 else if (DEFAULT_ABI == ABI_AIX)
23851 return 2;
23852 else
23853 return 0;
23856 /* Record an element in the table of global constructors. SYMBOL is
23857 a SYMBOL_REF of the function to be called; PRIORITY is a number
23858 between 0 and MAX_INIT_PRIORITY.
23860 This differs from default_named_section_asm_out_constructor in
23861 that we have special handling for -mrelocatable. */
23863 static void
23864 rs6000_elf_asm_out_constructor (rtx symbol, int priority)
23866 const char *section = ".ctors";
23867 char buf[16];
23869 if (priority != DEFAULT_INIT_PRIORITY)
23871 sprintf (buf, ".ctors.%.5u",
23872 /* Invert the numbering so the linker puts us in the proper
23873 order; constructors are run from right to left, and the
23874 linker sorts in increasing order. */
23875 MAX_INIT_PRIORITY - priority);
23876 section = buf;
23879 switch_to_section (get_section (section, SECTION_WRITE, NULL));
23880 assemble_align (POINTER_SIZE);
23882 if (TARGET_RELOCATABLE)
23884 fputs ("\t.long (", asm_out_file);
23885 output_addr_const (asm_out_file, symbol);
23886 fputs (")@fixup\n", asm_out_file);
23888 else
23889 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
23892 static void
23893 rs6000_elf_asm_out_destructor (rtx symbol, int priority)
23895 const char *section = ".dtors";
23896 char buf[16];
23898 if (priority != DEFAULT_INIT_PRIORITY)
23900 sprintf (buf, ".dtors.%.5u",
23901 /* Invert the numbering so the linker puts us in the proper
23902 order; constructors are run from right to left, and the
23903 linker sorts in increasing order. */
23904 MAX_INIT_PRIORITY - priority);
23905 section = buf;
23908 switch_to_section (get_section (section, SECTION_WRITE, NULL));
23909 assemble_align (POINTER_SIZE);
23911 if (TARGET_RELOCATABLE)
23913 fputs ("\t.long (", asm_out_file);
23914 output_addr_const (asm_out_file, symbol);
23915 fputs (")@fixup\n", asm_out_file);
23917 else
23918 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
23921 void
23922 rs6000_elf_declare_function_name (FILE *file, const char *name, tree decl)
23924 if (TARGET_64BIT)
23926 fputs ("\t.section\t\".opd\",\"aw\"\n\t.align 3\n", file);
23927 ASM_OUTPUT_LABEL (file, name);
23928 fputs (DOUBLE_INT_ASM_OP, file);
23929 rs6000_output_function_entry (file, name);
23930 fputs (",.TOC.@tocbase,0\n\t.previous\n", file);
23931 if (DOT_SYMBOLS)
23933 fputs ("\t.size\t", file);
23934 assemble_name (file, name);
23935 fputs (",24\n\t.type\t.", file);
23936 assemble_name (file, name);
23937 fputs (",@function\n", file);
23938 if (TREE_PUBLIC (decl) && ! DECL_WEAK (decl))
23940 fputs ("\t.globl\t.", file);
23941 assemble_name (file, name);
23942 putc ('\n', file);
23945 else
23946 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
23947 ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
23948 rs6000_output_function_entry (file, name);
23949 fputs (":\n", file);
23950 return;
23953 if (TARGET_RELOCATABLE
23954 && !TARGET_SECURE_PLT
23955 && (get_pool_size () != 0 || crtl->profile)
23956 && uses_TOC ())
23958 char buf[256];
23960 (*targetm.asm_out.internal_label) (file, "LCL", rs6000_pic_labelno);
23962 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
23963 fprintf (file, "\t.long ");
23964 assemble_name (file, buf);
23965 putc ('-', file);
23966 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
23967 assemble_name (file, buf);
23968 putc ('\n', file);
23971 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
23972 ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
23974 if (DEFAULT_ABI == ABI_AIX)
23976 const char *desc_name, *orig_name;
23978 orig_name = (*targetm.strip_name_encoding) (name);
23979 desc_name = orig_name;
23980 while (*desc_name == '.')
23981 desc_name++;
23983 if (TREE_PUBLIC (decl))
23984 fprintf (file, "\t.globl %s\n", desc_name);
23986 fprintf (file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
23987 fprintf (file, "%s:\n", desc_name);
23988 fprintf (file, "\t.long %s\n", orig_name);
23989 fputs ("\t.long _GLOBAL_OFFSET_TABLE_\n", file);
23990 if (DEFAULT_ABI == ABI_AIX)
23991 fputs ("\t.long 0\n", file);
23992 fprintf (file, "\t.previous\n");
23994 ASM_OUTPUT_LABEL (file, name);
23997 static void
23998 rs6000_elf_end_indicate_exec_stack (void)
24000 if (TARGET_32BIT)
24001 file_end_indicate_exec_stack ();
24003 #endif
24005 #if TARGET_XCOFF
24006 static void
24007 rs6000_xcoff_asm_output_anchor (rtx symbol)
24009 char buffer[100];
24011 sprintf (buffer, "$ + " HOST_WIDE_INT_PRINT_DEC,
24012 SYMBOL_REF_BLOCK_OFFSET (symbol));
24013 ASM_OUTPUT_DEF (asm_out_file, XSTR (symbol, 0), buffer);
24016 static void
24017 rs6000_xcoff_asm_globalize_label (FILE *stream, const char *name)
24019 fputs (GLOBAL_ASM_OP, stream);
24020 RS6000_OUTPUT_BASENAME (stream, name);
24021 putc ('\n', stream);
24024 /* A get_unnamed_decl callback, used for read-only sections. PTR
24025 points to the section string variable. */
24027 static void
24028 rs6000_xcoff_output_readonly_section_asm_op (const void *directive)
24030 fprintf (asm_out_file, "\t.csect %s[RO],%s\n",
24031 *(const char *const *) directive,
24032 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR);
24035 /* Likewise for read-write sections. */
24037 static void
24038 rs6000_xcoff_output_readwrite_section_asm_op (const void *directive)
24040 fprintf (asm_out_file, "\t.csect %s[RW],%s\n",
24041 *(const char *const *) directive,
24042 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR);
24045 /* A get_unnamed_section callback, used for switching to toc_section. */
24047 static void
24048 rs6000_xcoff_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
24050 if (TARGET_MINIMAL_TOC)
24052 /* toc_section is always selected at least once from
24053 rs6000_xcoff_file_start, so this is guaranteed to
24054 always be defined once and only once in each file. */
24055 if (!toc_initialized)
24057 fputs ("\t.toc\nLCTOC..1:\n", asm_out_file);
24058 fputs ("\t.tc toc_table[TC],toc_table[RW]\n", asm_out_file);
24059 toc_initialized = 1;
24061 fprintf (asm_out_file, "\t.csect toc_table[RW]%s\n",
24062 (TARGET_32BIT ? "" : ",3"));
24064 else
24065 fputs ("\t.toc\n", asm_out_file);
24068 /* Implement TARGET_ASM_INIT_SECTIONS. */
24070 static void
24071 rs6000_xcoff_asm_init_sections (void)
24073 read_only_data_section
24074 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
24075 &xcoff_read_only_section_name);
24077 private_data_section
24078 = get_unnamed_section (SECTION_WRITE,
24079 rs6000_xcoff_output_readwrite_section_asm_op,
24080 &xcoff_private_data_section_name);
24082 read_only_private_data_section
24083 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
24084 &xcoff_private_data_section_name);
24086 toc_section
24087 = get_unnamed_section (0, rs6000_xcoff_output_toc_section_asm_op, NULL);
24089 readonly_data_section = read_only_data_section;
24090 exception_section = data_section;
24093 static int
24094 rs6000_xcoff_reloc_rw_mask (void)
24096 return 3;
24099 static void
24100 rs6000_xcoff_asm_named_section (const char *name, unsigned int flags,
24101 tree decl ATTRIBUTE_UNUSED)
24103 int smclass;
24104 static const char * const suffix[3] = { "PR", "RO", "RW" };
24106 if (flags & SECTION_CODE)
24107 smclass = 0;
24108 else if (flags & SECTION_WRITE)
24109 smclass = 2;
24110 else
24111 smclass = 1;
24113 fprintf (asm_out_file, "\t.csect %s%s[%s],%u\n",
24114 (flags & SECTION_CODE) ? "." : "",
24115 name, suffix[smclass], flags & SECTION_ENTSIZE);
24118 static section *
24119 rs6000_xcoff_select_section (tree decl, int reloc,
24120 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
24122 if (decl_readonly_section (decl, reloc))
24124 if (TREE_PUBLIC (decl))
24125 return read_only_data_section;
24126 else
24127 return read_only_private_data_section;
24129 else
24131 if (TREE_PUBLIC (decl))
24132 return data_section;
24133 else
24134 return private_data_section;
24138 static void
24139 rs6000_xcoff_unique_section (tree decl, int reloc ATTRIBUTE_UNUSED)
24141 const char *name;
24143 /* Use select_section for private and uninitialized data. */
24144 if (!TREE_PUBLIC (decl)
24145 || DECL_COMMON (decl)
24146 || DECL_INITIAL (decl) == NULL_TREE
24147 || DECL_INITIAL (decl) == error_mark_node
24148 || (flag_zero_initialized_in_bss
24149 && initializer_zerop (DECL_INITIAL (decl))))
24150 return;
24152 name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
24153 name = (*targetm.strip_name_encoding) (name);
24154 DECL_SECTION_NAME (decl) = build_string (strlen (name), name);
24157 /* Select section for constant in constant pool.
24159 On RS/6000, all constants are in the private read-only data area.
24160 However, if this is being placed in the TOC it must be output as a
24161 toc entry. */
24163 static section *
24164 rs6000_xcoff_select_rtx_section (enum machine_mode mode, rtx x,
24165 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
24167 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
24168 return toc_section;
24169 else
24170 return read_only_private_data_section;
24173 /* Remove any trailing [DS] or the like from the symbol name. */
24175 static const char *
24176 rs6000_xcoff_strip_name_encoding (const char *name)
24178 size_t len;
24179 if (*name == '*')
24180 name++;
24181 len = strlen (name);
24182 if (name[len - 1] == ']')
24183 return ggc_alloc_string (name, len - 4);
24184 else
24185 return name;
24188 /* Section attributes. AIX is always PIC. */
24190 static unsigned int
24191 rs6000_xcoff_section_type_flags (tree decl, const char *name, int reloc)
24193 unsigned int align;
24194 unsigned int flags = default_section_type_flags (decl, name, reloc);
24196 /* Align to at least UNIT size. */
24197 if (flags & SECTION_CODE)
24198 align = MIN_UNITS_PER_WORD;
24199 else
24200 /* Increase alignment of large objects if not already stricter. */
24201 align = MAX ((DECL_ALIGN (decl) / BITS_PER_UNIT),
24202 int_size_in_bytes (TREE_TYPE (decl)) > MIN_UNITS_PER_WORD
24203 ? UNITS_PER_FP_WORD : MIN_UNITS_PER_WORD);
24205 return flags | (exact_log2 (align) & SECTION_ENTSIZE);
24208 /* Output at beginning of assembler file.
24210 Initialize the section names for the RS/6000 at this point.
24212 Specify filename, including full path, to assembler.
24214 We want to go into the TOC section so at least one .toc will be emitted.
24215 Also, in order to output proper .bs/.es pairs, we need at least one static
24216 [RW] section emitted.
24218 Finally, declare mcount when profiling to make the assembler happy. */
24220 static void
24221 rs6000_xcoff_file_start (void)
24223 rs6000_gen_section_name (&xcoff_bss_section_name,
24224 main_input_filename, ".bss_");
24225 rs6000_gen_section_name (&xcoff_private_data_section_name,
24226 main_input_filename, ".rw_");
24227 rs6000_gen_section_name (&xcoff_read_only_section_name,
24228 main_input_filename, ".ro_");
24230 fputs ("\t.file\t", asm_out_file);
24231 output_quoted_string (asm_out_file, main_input_filename);
24232 fputc ('\n', asm_out_file);
24233 if (write_symbols != NO_DEBUG)
24234 switch_to_section (private_data_section);
24235 switch_to_section (text_section);
24236 if (profile_flag)
24237 fprintf (asm_out_file, "\t.extern %s\n", RS6000_MCOUNT);
24238 rs6000_file_start ();
24241 /* Output at end of assembler file.
24242 On the RS/6000, referencing data should automatically pull in text. */
24244 static void
24245 rs6000_xcoff_file_end (void)
24247 switch_to_section (text_section);
24248 fputs ("_section_.text:\n", asm_out_file);
24249 switch_to_section (data_section);
24250 fputs (TARGET_32BIT
24251 ? "\t.long _section_.text\n" : "\t.llong _section_.text\n",
24252 asm_out_file);
24254 #endif /* TARGET_XCOFF */
24256 /* Compute a (partial) cost for rtx X. Return true if the complete
24257 cost has been computed, and false if subexpressions should be
24258 scanned. In either case, *TOTAL contains the cost result. */
24260 static bool
24261 rs6000_rtx_costs (rtx x, int code, int outer_code, int *total,
24262 bool speed)
24264 enum machine_mode mode = GET_MODE (x);
24266 switch (code)
24268 /* On the RS/6000, if it is valid in the insn, it is free. */
24269 case CONST_INT:
24270 if (((outer_code == SET
24271 || outer_code == PLUS
24272 || outer_code == MINUS)
24273 && (satisfies_constraint_I (x)
24274 || satisfies_constraint_L (x)))
24275 || (outer_code == AND
24276 && (satisfies_constraint_K (x)
24277 || (mode == SImode
24278 ? satisfies_constraint_L (x)
24279 : satisfies_constraint_J (x))
24280 || mask_operand (x, mode)
24281 || (mode == DImode
24282 && mask64_operand (x, DImode))))
24283 || ((outer_code == IOR || outer_code == XOR)
24284 && (satisfies_constraint_K (x)
24285 || (mode == SImode
24286 ? satisfies_constraint_L (x)
24287 : satisfies_constraint_J (x))))
24288 || outer_code == ASHIFT
24289 || outer_code == ASHIFTRT
24290 || outer_code == LSHIFTRT
24291 || outer_code == ROTATE
24292 || outer_code == ROTATERT
24293 || outer_code == ZERO_EXTRACT
24294 || (outer_code == MULT
24295 && satisfies_constraint_I (x))
24296 || ((outer_code == DIV || outer_code == UDIV
24297 || outer_code == MOD || outer_code == UMOD)
24298 && exact_log2 (INTVAL (x)) >= 0)
24299 || (outer_code == COMPARE
24300 && (satisfies_constraint_I (x)
24301 || satisfies_constraint_K (x)))
24302 || (outer_code == EQ
24303 && (satisfies_constraint_I (x)
24304 || satisfies_constraint_K (x)
24305 || (mode == SImode
24306 ? satisfies_constraint_L (x)
24307 : satisfies_constraint_J (x))))
24308 || (outer_code == GTU
24309 && satisfies_constraint_I (x))
24310 || (outer_code == LTU
24311 && satisfies_constraint_P (x)))
24313 *total = 0;
24314 return true;
24316 else if ((outer_code == PLUS
24317 && reg_or_add_cint_operand (x, VOIDmode))
24318 || (outer_code == MINUS
24319 && reg_or_sub_cint_operand (x, VOIDmode))
24320 || ((outer_code == SET
24321 || outer_code == IOR
24322 || outer_code == XOR)
24323 && (INTVAL (x)
24324 & ~ (unsigned HOST_WIDE_INT) 0xffffffff) == 0))
24326 *total = COSTS_N_INSNS (1);
24327 return true;
24329 /* FALLTHRU */
24331 case CONST_DOUBLE:
24332 if (mode == DImode && code == CONST_DOUBLE)
24334 if ((outer_code == IOR || outer_code == XOR)
24335 && CONST_DOUBLE_HIGH (x) == 0
24336 && (CONST_DOUBLE_LOW (x)
24337 & ~ (unsigned HOST_WIDE_INT) 0xffff) == 0)
24339 *total = 0;
24340 return true;
24342 else if ((outer_code == AND && and64_2_operand (x, DImode))
24343 || ((outer_code == SET
24344 || outer_code == IOR
24345 || outer_code == XOR)
24346 && CONST_DOUBLE_HIGH (x) == 0))
24348 *total = COSTS_N_INSNS (1);
24349 return true;
24352 /* FALLTHRU */
24354 case CONST:
24355 case HIGH:
24356 case SYMBOL_REF:
24357 case MEM:
24358 /* When optimizing for size, MEM should be slightly more expensive
24359 than generating address, e.g., (plus (reg) (const)).
24360 L1 cache latency is about two instructions. */
24361 *total = !speed ? COSTS_N_INSNS (1) + 1 : COSTS_N_INSNS (2);
24362 return true;
24364 case LABEL_REF:
24365 *total = 0;
24366 return true;
24368 case PLUS:
24369 if (mode == DFmode)
24371 if (GET_CODE (XEXP (x, 0)) == MULT)
24373 /* FNMA accounted in outer NEG. */
24374 if (outer_code == NEG)
24375 *total = rs6000_cost->dmul - rs6000_cost->fp;
24376 else
24377 *total = rs6000_cost->dmul;
24379 else
24380 *total = rs6000_cost->fp;
24382 else if (mode == SFmode)
24384 /* FNMA accounted in outer NEG. */
24385 if (outer_code == NEG && GET_CODE (XEXP (x, 0)) == MULT)
24386 *total = 0;
24387 else
24388 *total = rs6000_cost->fp;
24390 else
24391 *total = COSTS_N_INSNS (1);
24392 return false;
24394 case MINUS:
24395 if (mode == DFmode)
24397 if (GET_CODE (XEXP (x, 0)) == MULT
24398 || GET_CODE (XEXP (x, 1)) == MULT)
24400 /* FNMA accounted in outer NEG. */
24401 if (outer_code == NEG)
24402 *total = rs6000_cost->dmul - rs6000_cost->fp;
24403 else
24404 *total = rs6000_cost->dmul;
24406 else
24407 *total = rs6000_cost->fp;
24409 else if (mode == SFmode)
24411 /* FNMA accounted in outer NEG. */
24412 if (outer_code == NEG && GET_CODE (XEXP (x, 0)) == MULT)
24413 *total = 0;
24414 else
24415 *total = rs6000_cost->fp;
24417 else
24418 *total = COSTS_N_INSNS (1);
24419 return false;
24421 case MULT:
24422 if (GET_CODE (XEXP (x, 1)) == CONST_INT
24423 && satisfies_constraint_I (XEXP (x, 1)))
24425 if (INTVAL (XEXP (x, 1)) >= -256
24426 && INTVAL (XEXP (x, 1)) <= 255)
24427 *total = rs6000_cost->mulsi_const9;
24428 else
24429 *total = rs6000_cost->mulsi_const;
24431 /* FMA accounted in outer PLUS/MINUS. */
24432 else if ((mode == DFmode || mode == SFmode)
24433 && (outer_code == PLUS || outer_code == MINUS))
24434 *total = 0;
24435 else if (mode == DFmode)
24436 *total = rs6000_cost->dmul;
24437 else if (mode == SFmode)
24438 *total = rs6000_cost->fp;
24439 else if (mode == DImode)
24440 *total = rs6000_cost->muldi;
24441 else
24442 *total = rs6000_cost->mulsi;
24443 return false;
24445 case DIV:
24446 case MOD:
24447 if (FLOAT_MODE_P (mode))
24449 *total = mode == DFmode ? rs6000_cost->ddiv
24450 : rs6000_cost->sdiv;
24451 return false;
24453 /* FALLTHRU */
24455 case UDIV:
24456 case UMOD:
24457 if (GET_CODE (XEXP (x, 1)) == CONST_INT
24458 && exact_log2 (INTVAL (XEXP (x, 1))) >= 0)
24460 if (code == DIV || code == MOD)
24461 /* Shift, addze */
24462 *total = COSTS_N_INSNS (2);
24463 else
24464 /* Shift */
24465 *total = COSTS_N_INSNS (1);
24467 else
24469 if (GET_MODE (XEXP (x, 1)) == DImode)
24470 *total = rs6000_cost->divdi;
24471 else
24472 *total = rs6000_cost->divsi;
24474 /* Add in shift and subtract for MOD. */
24475 if (code == MOD || code == UMOD)
24476 *total += COSTS_N_INSNS (2);
24477 return false;
24479 case CTZ:
24480 case FFS:
24481 *total = COSTS_N_INSNS (4);
24482 return false;
24484 case POPCOUNT:
24485 *total = COSTS_N_INSNS (6);
24486 return false;
24488 case NOT:
24489 if (outer_code == AND || outer_code == IOR || outer_code == XOR)
24491 *total = 0;
24492 return false;
24494 /* FALLTHRU */
24496 case AND:
24497 case CLZ:
24498 case IOR:
24499 case XOR:
24500 case ZERO_EXTRACT:
24501 *total = COSTS_N_INSNS (1);
24502 return false;
24504 case ASHIFT:
24505 case ASHIFTRT:
24506 case LSHIFTRT:
24507 case ROTATE:
24508 case ROTATERT:
24509 /* Handle mul_highpart. */
24510 if (outer_code == TRUNCATE
24511 && GET_CODE (XEXP (x, 0)) == MULT)
24513 if (mode == DImode)
24514 *total = rs6000_cost->muldi;
24515 else
24516 *total = rs6000_cost->mulsi;
24517 return true;
24519 else if (outer_code == AND)
24520 *total = 0;
24521 else
24522 *total = COSTS_N_INSNS (1);
24523 return false;
24525 case SIGN_EXTEND:
24526 case ZERO_EXTEND:
24527 if (GET_CODE (XEXP (x, 0)) == MEM)
24528 *total = 0;
24529 else
24530 *total = COSTS_N_INSNS (1);
24531 return false;
24533 case COMPARE:
24534 case NEG:
24535 case ABS:
24536 if (!FLOAT_MODE_P (mode))
24538 *total = COSTS_N_INSNS (1);
24539 return false;
24541 /* FALLTHRU */
24543 case FLOAT:
24544 case UNSIGNED_FLOAT:
24545 case FIX:
24546 case UNSIGNED_FIX:
24547 case FLOAT_TRUNCATE:
24548 *total = rs6000_cost->fp;
24549 return false;
24551 case FLOAT_EXTEND:
24552 if (mode == DFmode)
24553 *total = 0;
24554 else
24555 *total = rs6000_cost->fp;
24556 return false;
24558 case UNSPEC:
24559 switch (XINT (x, 1))
24561 case UNSPEC_FRSP:
24562 *total = rs6000_cost->fp;
24563 return true;
24565 default:
24566 break;
24568 break;
24570 case CALL:
24571 case IF_THEN_ELSE:
24572 if (!speed)
24574 *total = COSTS_N_INSNS (1);
24575 return true;
24577 else if (FLOAT_MODE_P (mode)
24578 && TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS)
24580 *total = rs6000_cost->fp;
24581 return false;
24583 break;
24585 case EQ:
24586 case GTU:
24587 case LTU:
24588 /* Carry bit requires mode == Pmode.
24589 NEG or PLUS already counted so only add one. */
24590 if (mode == Pmode
24591 && (outer_code == NEG || outer_code == PLUS))
24593 *total = COSTS_N_INSNS (1);
24594 return true;
24596 if (outer_code == SET)
24598 if (XEXP (x, 1) == const0_rtx)
24600 *total = COSTS_N_INSNS (2);
24601 return true;
24603 else if (mode == Pmode)
24605 *total = COSTS_N_INSNS (3);
24606 return false;
24609 /* FALLTHRU */
24611 case GT:
24612 case LT:
24613 case UNORDERED:
24614 if (outer_code == SET && (XEXP (x, 1) == const0_rtx))
24616 *total = COSTS_N_INSNS (2);
24617 return true;
24619 /* CC COMPARE. */
24620 if (outer_code == COMPARE)
24622 *total = 0;
24623 return true;
24625 break;
24627 default:
24628 break;
24631 return false;
24634 /* Debug form of r6000_rtx_costs that is selected if -mdebug=cost. */
24636 static bool
24637 rs6000_debug_rtx_costs (rtx x, int code, int outer_code, int *total,
24638 bool speed)
24640 bool ret = rs6000_rtx_costs (x, code, outer_code, total, speed);
24642 fprintf (stderr,
24643 "\nrs6000_rtx_costs, return = %s, code = %s, outer_code = %s, "
24644 "total = %d, speed = %s, x:\n",
24645 ret ? "complete" : "scan inner",
24646 GET_RTX_NAME (code),
24647 GET_RTX_NAME (outer_code),
24648 *total,
24649 speed ? "true" : "false");
24651 debug_rtx (x);
24653 return ret;
24656 /* Debug form of ADDRESS_COST that is selected if -mdebug=cost. */
24658 static int
24659 rs6000_debug_address_cost (rtx x, bool speed)
24661 int ret = TARGET_ADDRESS_COST (x, speed);
24663 fprintf (stderr, "\nrs6000_address_cost, return = %d, speed = %s, x:\n",
24664 ret, speed ? "true" : "false");
24665 debug_rtx (x);
24667 return ret;
24671 /* A C expression returning the cost of moving data from a register of class
24672 CLASS1 to one of CLASS2. */
24675 rs6000_register_move_cost (enum machine_mode mode,
24676 enum reg_class from, enum reg_class to)
24678 int ret;
24680 /* Moves from/to GENERAL_REGS. */
24681 if (reg_classes_intersect_p (to, GENERAL_REGS)
24682 || reg_classes_intersect_p (from, GENERAL_REGS))
24684 if (! reg_classes_intersect_p (to, GENERAL_REGS))
24685 from = to;
24687 if (from == FLOAT_REGS || from == ALTIVEC_REGS || from == VSX_REGS)
24688 ret = (rs6000_memory_move_cost (mode, from, 0)
24689 + rs6000_memory_move_cost (mode, GENERAL_REGS, 0));
24691 /* It's more expensive to move CR_REGS than CR0_REGS because of the
24692 shift. */
24693 else if (from == CR_REGS)
24694 ret = 4;
24696 /* Power6 has slower LR/CTR moves so make them more expensive than
24697 memory in order to bias spills to memory .*/
24698 else if (rs6000_cpu == PROCESSOR_POWER6
24699 && reg_classes_intersect_p (from, LINK_OR_CTR_REGS))
24700 ret = 6 * hard_regno_nregs[0][mode];
24702 else
24703 /* A move will cost one instruction per GPR moved. */
24704 ret = 2 * hard_regno_nregs[0][mode];
24707 /* If we have VSX, we can easily move between FPR or Altivec registers. */
24708 else if (VECTOR_UNIT_VSX_P (mode)
24709 && reg_classes_intersect_p (to, VSX_REGS)
24710 && reg_classes_intersect_p (from, VSX_REGS))
24711 ret = 2 * hard_regno_nregs[32][mode];
24713 /* Moving between two similar registers is just one instruction. */
24714 else if (reg_classes_intersect_p (to, from))
24715 ret = (mode == TFmode || mode == TDmode) ? 4 : 2;
24717 /* Everything else has to go through GENERAL_REGS. */
24718 else
24719 ret = (rs6000_register_move_cost (mode, GENERAL_REGS, to)
24720 + rs6000_register_move_cost (mode, from, GENERAL_REGS));
24722 if (TARGET_DEBUG_COST)
24723 fprintf (stderr,
24724 "rs6000_register_move_cost:, ret=%d, mode=%s, from=%s, to=%s\n",
24725 ret, GET_MODE_NAME (mode), reg_class_names[from],
24726 reg_class_names[to]);
24728 return ret;
24731 /* A C expressions returning the cost of moving data of MODE from a register to
24732 or from memory. */
24735 rs6000_memory_move_cost (enum machine_mode mode, enum reg_class rclass,
24736 int in ATTRIBUTE_UNUSED)
24738 int ret;
24740 if (reg_classes_intersect_p (rclass, GENERAL_REGS))
24741 ret = 4 * hard_regno_nregs[0][mode];
24742 else if (reg_classes_intersect_p (rclass, FLOAT_REGS))
24743 ret = 4 * hard_regno_nregs[32][mode];
24744 else if (reg_classes_intersect_p (rclass, ALTIVEC_REGS))
24745 ret = 4 * hard_regno_nregs[FIRST_ALTIVEC_REGNO][mode];
24746 else
24747 ret = 4 + rs6000_register_move_cost (mode, rclass, GENERAL_REGS);
24749 if (TARGET_DEBUG_COST)
24750 fprintf (stderr,
24751 "rs6000_memory_move_cost: ret=%d, mode=%s, rclass=%s, in=%d\n",
24752 ret, GET_MODE_NAME (mode), reg_class_names[rclass], in);
24754 return ret;
24757 /* Returns a code for a target-specific builtin that implements
24758 reciprocal of the function, or NULL_TREE if not available. */
24760 static tree
24761 rs6000_builtin_reciprocal (unsigned int fn, bool md_fn,
24762 bool sqrt ATTRIBUTE_UNUSED)
24764 if (! (TARGET_RECIP && TARGET_PPC_GFXOPT && !optimize_size
24765 && flag_finite_math_only && !flag_trapping_math
24766 && flag_unsafe_math_optimizations))
24767 return NULL_TREE;
24769 if (md_fn)
24770 return NULL_TREE;
24771 else
24772 switch (fn)
24774 case BUILT_IN_SQRTF:
24775 return rs6000_builtin_decls[RS6000_BUILTIN_RSQRTF];
24777 default:
24778 return NULL_TREE;
24782 /* Newton-Raphson approximation of single-precision floating point divide n/d.
24783 Assumes no trapping math and finite arguments. */
24785 void
24786 rs6000_emit_swdivsf (rtx dst, rtx n, rtx d)
24788 rtx x0, e0, e1, y1, u0, v0, one;
24790 x0 = gen_reg_rtx (SFmode);
24791 e0 = gen_reg_rtx (SFmode);
24792 e1 = gen_reg_rtx (SFmode);
24793 y1 = gen_reg_rtx (SFmode);
24794 u0 = gen_reg_rtx (SFmode);
24795 v0 = gen_reg_rtx (SFmode);
24796 one = force_reg (SFmode, CONST_DOUBLE_FROM_REAL_VALUE (dconst1, SFmode));
24798 /* x0 = 1./d estimate */
24799 emit_insn (gen_rtx_SET (VOIDmode, x0,
24800 gen_rtx_UNSPEC (SFmode, gen_rtvec (1, d),
24801 UNSPEC_FRES)));
24802 /* e0 = 1. - d * x0 */
24803 emit_insn (gen_rtx_SET (VOIDmode, e0,
24804 gen_rtx_MINUS (SFmode, one,
24805 gen_rtx_MULT (SFmode, d, x0))));
24806 /* e1 = e0 + e0 * e0 */
24807 emit_insn (gen_rtx_SET (VOIDmode, e1,
24808 gen_rtx_PLUS (SFmode,
24809 gen_rtx_MULT (SFmode, e0, e0), e0)));
24810 /* y1 = x0 + e1 * x0 */
24811 emit_insn (gen_rtx_SET (VOIDmode, y1,
24812 gen_rtx_PLUS (SFmode,
24813 gen_rtx_MULT (SFmode, e1, x0), x0)));
24814 /* u0 = n * y1 */
24815 emit_insn (gen_rtx_SET (VOIDmode, u0,
24816 gen_rtx_MULT (SFmode, n, y1)));
24817 /* v0 = n - d * u0 */
24818 emit_insn (gen_rtx_SET (VOIDmode, v0,
24819 gen_rtx_MINUS (SFmode, n,
24820 gen_rtx_MULT (SFmode, d, u0))));
24821 /* dst = u0 + v0 * y1 */
24822 emit_insn (gen_rtx_SET (VOIDmode, dst,
24823 gen_rtx_PLUS (SFmode,
24824 gen_rtx_MULT (SFmode, v0, y1), u0)));
24827 /* Newton-Raphson approximation of double-precision floating point divide n/d.
24828 Assumes no trapping math and finite arguments. */
24830 void
24831 rs6000_emit_swdivdf (rtx dst, rtx n, rtx d)
24833 rtx x0, e0, e1, e2, y1, y2, y3, u0, v0, one;
24835 x0 = gen_reg_rtx (DFmode);
24836 e0 = gen_reg_rtx (DFmode);
24837 e1 = gen_reg_rtx (DFmode);
24838 e2 = gen_reg_rtx (DFmode);
24839 y1 = gen_reg_rtx (DFmode);
24840 y2 = gen_reg_rtx (DFmode);
24841 y3 = gen_reg_rtx (DFmode);
24842 u0 = gen_reg_rtx (DFmode);
24843 v0 = gen_reg_rtx (DFmode);
24844 one = force_reg (DFmode, CONST_DOUBLE_FROM_REAL_VALUE (dconst1, DFmode));
24846 /* x0 = 1./d estimate */
24847 emit_insn (gen_rtx_SET (VOIDmode, x0,
24848 gen_rtx_UNSPEC (DFmode, gen_rtvec (1, d),
24849 UNSPEC_FRES)));
24850 /* e0 = 1. - d * x0 */
24851 emit_insn (gen_rtx_SET (VOIDmode, e0,
24852 gen_rtx_MINUS (DFmode, one,
24853 gen_rtx_MULT (SFmode, d, x0))));
24854 /* y1 = x0 + e0 * x0 */
24855 emit_insn (gen_rtx_SET (VOIDmode, y1,
24856 gen_rtx_PLUS (DFmode,
24857 gen_rtx_MULT (DFmode, e0, x0), x0)));
24858 /* e1 = e0 * e0 */
24859 emit_insn (gen_rtx_SET (VOIDmode, e1,
24860 gen_rtx_MULT (DFmode, e0, e0)));
24861 /* y2 = y1 + e1 * y1 */
24862 emit_insn (gen_rtx_SET (VOIDmode, y2,
24863 gen_rtx_PLUS (DFmode,
24864 gen_rtx_MULT (DFmode, e1, y1), y1)));
24865 /* e2 = e1 * e1 */
24866 emit_insn (gen_rtx_SET (VOIDmode, e2,
24867 gen_rtx_MULT (DFmode, e1, e1)));
24868 /* y3 = y2 + e2 * y2 */
24869 emit_insn (gen_rtx_SET (VOIDmode, y3,
24870 gen_rtx_PLUS (DFmode,
24871 gen_rtx_MULT (DFmode, e2, y2), y2)));
24872 /* u0 = n * y3 */
24873 emit_insn (gen_rtx_SET (VOIDmode, u0,
24874 gen_rtx_MULT (DFmode, n, y3)));
24875 /* v0 = n - d * u0 */
24876 emit_insn (gen_rtx_SET (VOIDmode, v0,
24877 gen_rtx_MINUS (DFmode, n,
24878 gen_rtx_MULT (DFmode, d, u0))));
24879 /* dst = u0 + v0 * y3 */
24880 emit_insn (gen_rtx_SET (VOIDmode, dst,
24881 gen_rtx_PLUS (DFmode,
24882 gen_rtx_MULT (DFmode, v0, y3), u0)));
24886 /* Newton-Raphson approximation of single-precision floating point rsqrt.
24887 Assumes no trapping math and finite arguments. */
24889 void
24890 rs6000_emit_swrsqrtsf (rtx dst, rtx src)
24892 rtx x0, x1, x2, y1, u0, u1, u2, v0, v1, v2, t0,
24893 half, one, halfthree, c1, cond, label;
24895 x0 = gen_reg_rtx (SFmode);
24896 x1 = gen_reg_rtx (SFmode);
24897 x2 = gen_reg_rtx (SFmode);
24898 y1 = gen_reg_rtx (SFmode);
24899 u0 = gen_reg_rtx (SFmode);
24900 u1 = gen_reg_rtx (SFmode);
24901 u2 = gen_reg_rtx (SFmode);
24902 v0 = gen_reg_rtx (SFmode);
24903 v1 = gen_reg_rtx (SFmode);
24904 v2 = gen_reg_rtx (SFmode);
24905 t0 = gen_reg_rtx (SFmode);
24906 halfthree = gen_reg_rtx (SFmode);
24907 cond = gen_rtx_REG (CCFPmode, CR1_REGNO);
24908 label = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
24910 /* check 0.0, 1.0, NaN, Inf by testing src * src = src */
24911 emit_insn (gen_rtx_SET (VOIDmode, t0,
24912 gen_rtx_MULT (SFmode, src, src)));
24914 emit_insn (gen_rtx_SET (VOIDmode, cond,
24915 gen_rtx_COMPARE (CCFPmode, t0, src)));
24916 c1 = gen_rtx_EQ (VOIDmode, cond, const0_rtx);
24917 emit_unlikely_jump (c1, label);
24919 half = force_reg (SFmode, CONST_DOUBLE_FROM_REAL_VALUE (dconsthalf, SFmode));
24920 one = force_reg (SFmode, CONST_DOUBLE_FROM_REAL_VALUE (dconst1, SFmode));
24922 /* halfthree = 1.5 = 1.0 + 0.5 */
24923 emit_insn (gen_rtx_SET (VOIDmode, halfthree,
24924 gen_rtx_PLUS (SFmode, one, half)));
24926 /* x0 = rsqrt estimate */
24927 emit_insn (gen_rtx_SET (VOIDmode, x0,
24928 gen_rtx_UNSPEC (SFmode, gen_rtvec (1, src),
24929 UNSPEC_RSQRT)));
24931 /* y1 = 0.5 * src = 1.5 * src - src -> fewer constants */
24932 emit_insn (gen_rtx_SET (VOIDmode, y1,
24933 gen_rtx_MINUS (SFmode,
24934 gen_rtx_MULT (SFmode, src, halfthree),
24935 src)));
24937 /* x1 = x0 * (1.5 - y1 * (x0 * x0)) */
24938 emit_insn (gen_rtx_SET (VOIDmode, u0,
24939 gen_rtx_MULT (SFmode, x0, x0)));
24940 emit_insn (gen_rtx_SET (VOIDmode, v0,
24941 gen_rtx_MINUS (SFmode,
24942 halfthree,
24943 gen_rtx_MULT (SFmode, y1, u0))));
24944 emit_insn (gen_rtx_SET (VOIDmode, x1,
24945 gen_rtx_MULT (SFmode, x0, v0)));
24947 /* x2 = x1 * (1.5 - y1 * (x1 * x1)) */
24948 emit_insn (gen_rtx_SET (VOIDmode, u1,
24949 gen_rtx_MULT (SFmode, x1, x1)));
24950 emit_insn (gen_rtx_SET (VOIDmode, v1,
24951 gen_rtx_MINUS (SFmode,
24952 halfthree,
24953 gen_rtx_MULT (SFmode, y1, u1))));
24954 emit_insn (gen_rtx_SET (VOIDmode, x2,
24955 gen_rtx_MULT (SFmode, x1, v1)));
24957 /* dst = x2 * (1.5 - y1 * (x2 * x2)) */
24958 emit_insn (gen_rtx_SET (VOIDmode, u2,
24959 gen_rtx_MULT (SFmode, x2, x2)));
24960 emit_insn (gen_rtx_SET (VOIDmode, v2,
24961 gen_rtx_MINUS (SFmode,
24962 halfthree,
24963 gen_rtx_MULT (SFmode, y1, u2))));
24964 emit_insn (gen_rtx_SET (VOIDmode, dst,
24965 gen_rtx_MULT (SFmode, x2, v2)));
24967 emit_label (XEXP (label, 0));
24970 /* Emit popcount intrinsic on TARGET_POPCNTB (Power5) and TARGET_POPCNTD
24971 (Power7) targets. DST is the target, and SRC is the argument operand. */
24973 void
24974 rs6000_emit_popcount (rtx dst, rtx src)
24976 enum machine_mode mode = GET_MODE (dst);
24977 rtx tmp1, tmp2;
24979 /* Use the PPC ISA 2.06 popcnt{w,d} instruction if we can. */
24980 if (TARGET_POPCNTD)
24982 if (mode == SImode)
24983 emit_insn (gen_popcntwsi2 (dst, src));
24984 else
24985 emit_insn (gen_popcntddi2 (dst, src));
24986 return;
24989 tmp1 = gen_reg_rtx (mode);
24991 if (mode == SImode)
24993 emit_insn (gen_popcntbsi2 (tmp1, src));
24994 tmp2 = expand_mult (SImode, tmp1, GEN_INT (0x01010101),
24995 NULL_RTX, 0);
24996 tmp2 = force_reg (SImode, tmp2);
24997 emit_insn (gen_lshrsi3 (dst, tmp2, GEN_INT (24)));
24999 else
25001 emit_insn (gen_popcntbdi2 (tmp1, src));
25002 tmp2 = expand_mult (DImode, tmp1,
25003 GEN_INT ((HOST_WIDE_INT)
25004 0x01010101 << 32 | 0x01010101),
25005 NULL_RTX, 0);
25006 tmp2 = force_reg (DImode, tmp2);
25007 emit_insn (gen_lshrdi3 (dst, tmp2, GEN_INT (56)));
25012 /* Emit parity intrinsic on TARGET_POPCNTB targets. DST is the
25013 target, and SRC is the argument operand. */
25015 void
25016 rs6000_emit_parity (rtx dst, rtx src)
25018 enum machine_mode mode = GET_MODE (dst);
25019 rtx tmp;
25021 tmp = gen_reg_rtx (mode);
25022 if (mode == SImode)
25024 /* Is mult+shift >= shift+xor+shift+xor? */
25025 if (rs6000_cost->mulsi_const >= COSTS_N_INSNS (3))
25027 rtx tmp1, tmp2, tmp3, tmp4;
25029 tmp1 = gen_reg_rtx (SImode);
25030 emit_insn (gen_popcntbsi2 (tmp1, src));
25032 tmp2 = gen_reg_rtx (SImode);
25033 emit_insn (gen_lshrsi3 (tmp2, tmp1, GEN_INT (16)));
25034 tmp3 = gen_reg_rtx (SImode);
25035 emit_insn (gen_xorsi3 (tmp3, tmp1, tmp2));
25037 tmp4 = gen_reg_rtx (SImode);
25038 emit_insn (gen_lshrsi3 (tmp4, tmp3, GEN_INT (8)));
25039 emit_insn (gen_xorsi3 (tmp, tmp3, tmp4));
25041 else
25042 rs6000_emit_popcount (tmp, src);
25043 emit_insn (gen_andsi3 (dst, tmp, const1_rtx));
25045 else
25047 /* Is mult+shift >= shift+xor+shift+xor+shift+xor? */
25048 if (rs6000_cost->muldi >= COSTS_N_INSNS (5))
25050 rtx tmp1, tmp2, tmp3, tmp4, tmp5, tmp6;
25052 tmp1 = gen_reg_rtx (DImode);
25053 emit_insn (gen_popcntbdi2 (tmp1, src));
25055 tmp2 = gen_reg_rtx (DImode);
25056 emit_insn (gen_lshrdi3 (tmp2, tmp1, GEN_INT (32)));
25057 tmp3 = gen_reg_rtx (DImode);
25058 emit_insn (gen_xordi3 (tmp3, tmp1, tmp2));
25060 tmp4 = gen_reg_rtx (DImode);
25061 emit_insn (gen_lshrdi3 (tmp4, tmp3, GEN_INT (16)));
25062 tmp5 = gen_reg_rtx (DImode);
25063 emit_insn (gen_xordi3 (tmp5, tmp3, tmp4));
25065 tmp6 = gen_reg_rtx (DImode);
25066 emit_insn (gen_lshrdi3 (tmp6, tmp5, GEN_INT (8)));
25067 emit_insn (gen_xordi3 (tmp, tmp5, tmp6));
25069 else
25070 rs6000_emit_popcount (tmp, src);
25071 emit_insn (gen_anddi3 (dst, tmp, const1_rtx));
25075 /* Return an RTX representing where to find the function value of a
25076 function returning MODE. */
25077 static rtx
25078 rs6000_complex_function_value (enum machine_mode mode)
25080 unsigned int regno;
25081 rtx r1, r2;
25082 enum machine_mode inner = GET_MODE_INNER (mode);
25083 unsigned int inner_bytes = GET_MODE_SIZE (inner);
25085 if (FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
25086 regno = FP_ARG_RETURN;
25087 else
25089 regno = GP_ARG_RETURN;
25091 /* 32-bit is OK since it'll go in r3/r4. */
25092 if (TARGET_32BIT && inner_bytes >= 4)
25093 return gen_rtx_REG (mode, regno);
25096 if (inner_bytes >= 8)
25097 return gen_rtx_REG (mode, regno);
25099 r1 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno),
25100 const0_rtx);
25101 r2 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno + 1),
25102 GEN_INT (inner_bytes));
25103 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
25106 /* Target hook for TARGET_FUNCTION_VALUE.
25108 On the SPE, both FPs and vectors are returned in r3.
25110 On RS/6000 an integer value is in r3 and a floating-point value is in
25111 fp1, unless -msoft-float. */
25114 rs6000_function_value (const_tree valtype,
25115 const_tree fn_decl_or_type ATTRIBUTE_UNUSED,
25116 bool outgoing ATTRIBUTE_UNUSED)
25118 enum machine_mode mode;
25119 unsigned int regno;
25121 /* Special handling for structs in darwin64. */
25122 if (rs6000_darwin64_abi
25123 && TYPE_MODE (valtype) == BLKmode
25124 && TREE_CODE (valtype) == RECORD_TYPE
25125 && int_size_in_bytes (valtype) > 0)
25127 CUMULATIVE_ARGS valcum;
25128 rtx valret;
25130 valcum.words = 0;
25131 valcum.fregno = FP_ARG_MIN_REG;
25132 valcum.vregno = ALTIVEC_ARG_MIN_REG;
25133 /* Do a trial code generation as if this were going to be passed as
25134 an argument; if any part goes in memory, we return NULL. */
25135 valret = rs6000_darwin64_record_arg (&valcum, valtype, 1, true);
25136 if (valret)
25137 return valret;
25138 /* Otherwise fall through to standard ABI rules. */
25141 if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DImode)
25143 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
25144 return gen_rtx_PARALLEL (DImode,
25145 gen_rtvec (2,
25146 gen_rtx_EXPR_LIST (VOIDmode,
25147 gen_rtx_REG (SImode, GP_ARG_RETURN),
25148 const0_rtx),
25149 gen_rtx_EXPR_LIST (VOIDmode,
25150 gen_rtx_REG (SImode,
25151 GP_ARG_RETURN + 1),
25152 GEN_INT (4))));
25154 if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DCmode)
25156 return gen_rtx_PARALLEL (DCmode,
25157 gen_rtvec (4,
25158 gen_rtx_EXPR_LIST (VOIDmode,
25159 gen_rtx_REG (SImode, GP_ARG_RETURN),
25160 const0_rtx),
25161 gen_rtx_EXPR_LIST (VOIDmode,
25162 gen_rtx_REG (SImode,
25163 GP_ARG_RETURN + 1),
25164 GEN_INT (4)),
25165 gen_rtx_EXPR_LIST (VOIDmode,
25166 gen_rtx_REG (SImode,
25167 GP_ARG_RETURN + 2),
25168 GEN_INT (8)),
25169 gen_rtx_EXPR_LIST (VOIDmode,
25170 gen_rtx_REG (SImode,
25171 GP_ARG_RETURN + 3),
25172 GEN_INT (12))));
25175 mode = TYPE_MODE (valtype);
25176 if ((INTEGRAL_TYPE_P (valtype) && GET_MODE_BITSIZE (mode) < BITS_PER_WORD)
25177 || POINTER_TYPE_P (valtype))
25178 mode = TARGET_32BIT ? SImode : DImode;
25180 if (DECIMAL_FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
25181 /* _Decimal128 must use an even/odd register pair. */
25182 regno = (mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN;
25183 else if (SCALAR_FLOAT_TYPE_P (valtype) && TARGET_HARD_FLOAT && TARGET_FPRS
25184 && ((TARGET_SINGLE_FLOAT && (mode == SFmode)) || TARGET_DOUBLE_FLOAT))
25185 regno = FP_ARG_RETURN;
25186 else if (TREE_CODE (valtype) == COMPLEX_TYPE
25187 && targetm.calls.split_complex_arg)
25188 return rs6000_complex_function_value (mode);
25189 else if (TREE_CODE (valtype) == VECTOR_TYPE
25190 && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI
25191 && ALTIVEC_VECTOR_MODE (mode))
25192 regno = ALTIVEC_ARG_RETURN;
25193 else if (TREE_CODE (valtype) == VECTOR_TYPE
25194 && TARGET_VSX && TARGET_ALTIVEC_ABI
25195 && VSX_VECTOR_MODE (mode))
25196 regno = ALTIVEC_ARG_RETURN;
25197 else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
25198 && (mode == DFmode || mode == DCmode
25199 || mode == TFmode || mode == TCmode))
25200 return spe_build_register_parallel (mode, GP_ARG_RETURN);
25201 else
25202 regno = GP_ARG_RETURN;
25204 return gen_rtx_REG (mode, regno);
25207 /* Define how to find the value returned by a library function
25208 assuming the value has mode MODE. */
25210 rs6000_libcall_value (enum machine_mode mode)
25212 unsigned int regno;
25214 if (TARGET_32BIT && TARGET_POWERPC64 && mode == DImode)
25216 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
25217 return gen_rtx_PARALLEL (DImode,
25218 gen_rtvec (2,
25219 gen_rtx_EXPR_LIST (VOIDmode,
25220 gen_rtx_REG (SImode, GP_ARG_RETURN),
25221 const0_rtx),
25222 gen_rtx_EXPR_LIST (VOIDmode,
25223 gen_rtx_REG (SImode,
25224 GP_ARG_RETURN + 1),
25225 GEN_INT (4))));
25228 if (DECIMAL_FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
25229 /* _Decimal128 must use an even/odd register pair. */
25230 regno = (mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN;
25231 else if (SCALAR_FLOAT_MODE_P (mode)
25232 && TARGET_HARD_FLOAT && TARGET_FPRS
25233 && ((TARGET_SINGLE_FLOAT && mode == SFmode) || TARGET_DOUBLE_FLOAT))
25234 regno = FP_ARG_RETURN;
25235 else if (ALTIVEC_VECTOR_MODE (mode)
25236 && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI)
25237 regno = ALTIVEC_ARG_RETURN;
25238 else if (VSX_VECTOR_MODE (mode)
25239 && TARGET_VSX && TARGET_ALTIVEC_ABI)
25240 regno = ALTIVEC_ARG_RETURN;
25241 else if (COMPLEX_MODE_P (mode) && targetm.calls.split_complex_arg)
25242 return rs6000_complex_function_value (mode);
25243 else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
25244 && (mode == DFmode || mode == DCmode
25245 || mode == TFmode || mode == TCmode))
25246 return spe_build_register_parallel (mode, GP_ARG_RETURN);
25247 else
25248 regno = GP_ARG_RETURN;
25250 return gen_rtx_REG (mode, regno);
25254 /* Given FROM and TO register numbers, say whether this elimination is allowed.
25255 Frame pointer elimination is automatically handled.
25257 For the RS/6000, if frame pointer elimination is being done, we would like
25258 to convert ap into fp, not sp.
25260 We need r30 if -mminimal-toc was specified, and there are constant pool
25261 references. */
25263 bool
25264 rs6000_can_eliminate (const int from, const int to)
25266 return (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM
25267 ? ! frame_pointer_needed
25268 : from == RS6000_PIC_OFFSET_TABLE_REGNUM
25269 ? ! TARGET_MINIMAL_TOC || TARGET_NO_TOC || get_pool_size () == 0
25270 : true);
25273 /* Define the offset between two registers, FROM to be eliminated and its
25274 replacement TO, at the start of a routine. */
25275 HOST_WIDE_INT
25276 rs6000_initial_elimination_offset (int from, int to)
25278 rs6000_stack_t *info = rs6000_stack_info ();
25279 HOST_WIDE_INT offset;
25281 if (from == HARD_FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
25282 offset = info->push_p ? 0 : -info->total_size;
25283 else if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
25285 offset = info->push_p ? 0 : -info->total_size;
25286 if (FRAME_GROWS_DOWNWARD)
25287 offset += info->fixed_size + info->vars_size + info->parm_size;
25289 else if (from == FRAME_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
25290 offset = FRAME_GROWS_DOWNWARD
25291 ? info->fixed_size + info->vars_size + info->parm_size
25292 : 0;
25293 else if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
25294 offset = info->total_size;
25295 else if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
25296 offset = info->push_p ? info->total_size : 0;
25297 else if (from == RS6000_PIC_OFFSET_TABLE_REGNUM)
25298 offset = 0;
25299 else
25300 gcc_unreachable ();
25302 return offset;
25305 static rtx
25306 rs6000_dwarf_register_span (rtx reg)
25308 rtx parts[8];
25309 int i, words;
25310 unsigned regno = REGNO (reg);
25311 enum machine_mode mode = GET_MODE (reg);
25313 if (TARGET_SPE
25314 && regno < 32
25315 && (SPE_VECTOR_MODE (GET_MODE (reg))
25316 || (TARGET_E500_DOUBLE && FLOAT_MODE_P (mode)
25317 && mode != SFmode && mode != SDmode && mode != SCmode)))
25319 else
25320 return NULL_RTX;
25322 regno = REGNO (reg);
25324 /* The duality of the SPE register size wreaks all kinds of havoc.
25325 This is a way of distinguishing r0 in 32-bits from r0 in
25326 64-bits. */
25327 words = (GET_MODE_SIZE (mode) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD;
25328 gcc_assert (words <= 4);
25329 for (i = 0; i < words; i++, regno++)
25331 if (BYTES_BIG_ENDIAN)
25333 parts[2 * i] = gen_rtx_REG (SImode, regno + 1200);
25334 parts[2 * i + 1] = gen_rtx_REG (SImode, regno);
25336 else
25338 parts[2 * i] = gen_rtx_REG (SImode, regno);
25339 parts[2 * i + 1] = gen_rtx_REG (SImode, regno + 1200);
25343 return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (words * 2, parts));
25346 /* Fill in sizes for SPE register high parts in table used by unwinder. */
25348 static void
25349 rs6000_init_dwarf_reg_sizes_extra (tree address)
25351 if (TARGET_SPE)
25353 int i;
25354 enum machine_mode mode = TYPE_MODE (char_type_node);
25355 rtx addr = expand_expr (address, NULL_RTX, VOIDmode, EXPAND_NORMAL);
25356 rtx mem = gen_rtx_MEM (BLKmode, addr);
25357 rtx value = gen_int_mode (4, mode);
25359 for (i = 1201; i < 1232; i++)
25361 int column = DWARF_REG_TO_UNWIND_COLUMN (i);
25362 HOST_WIDE_INT offset
25363 = DWARF_FRAME_REGNUM (column) * GET_MODE_SIZE (mode);
25365 emit_move_insn (adjust_address (mem, mode, offset), value);
25370 /* Map internal gcc register numbers to DWARF2 register numbers. */
25372 unsigned int
25373 rs6000_dbx_register_number (unsigned int regno)
25375 if (regno <= 63 || write_symbols != DWARF2_DEBUG)
25376 return regno;
25377 if (regno == MQ_REGNO)
25378 return 100;
25379 if (regno == LR_REGNO)
25380 return 108;
25381 if (regno == CTR_REGNO)
25382 return 109;
25383 if (CR_REGNO_P (regno))
25384 return regno - CR0_REGNO + 86;
25385 if (regno == XER_REGNO)
25386 return 101;
25387 if (ALTIVEC_REGNO_P (regno))
25388 return regno - FIRST_ALTIVEC_REGNO + 1124;
25389 if (regno == VRSAVE_REGNO)
25390 return 356;
25391 if (regno == VSCR_REGNO)
25392 return 67;
25393 if (regno == SPE_ACC_REGNO)
25394 return 99;
25395 if (regno == SPEFSCR_REGNO)
25396 return 612;
25397 /* SPE high reg number. We get these values of regno from
25398 rs6000_dwarf_register_span. */
25399 gcc_assert (regno >= 1200 && regno < 1232);
25400 return regno;
25403 /* target hook eh_return_filter_mode */
25404 static enum machine_mode
25405 rs6000_eh_return_filter_mode (void)
25407 return TARGET_32BIT ? SImode : word_mode;
25410 /* Target hook for scalar_mode_supported_p. */
25411 static bool
25412 rs6000_scalar_mode_supported_p (enum machine_mode mode)
25414 if (DECIMAL_FLOAT_MODE_P (mode))
25415 return default_decimal_float_supported_p ();
25416 else
25417 return default_scalar_mode_supported_p (mode);
25420 /* Target hook for vector_mode_supported_p. */
25421 static bool
25422 rs6000_vector_mode_supported_p (enum machine_mode mode)
25425 if (TARGET_PAIRED_FLOAT && PAIRED_VECTOR_MODE (mode))
25426 return true;
25428 if (TARGET_SPE && SPE_VECTOR_MODE (mode))
25429 return true;
25431 else if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode))
25432 return true;
25434 else
25435 return false;
25438 /* Target hook for invalid_arg_for_unprototyped_fn. */
25439 static const char *
25440 invalid_arg_for_unprototyped_fn (const_tree typelist, const_tree funcdecl, const_tree val)
25442 return (!rs6000_darwin64_abi
25443 && typelist == 0
25444 && TREE_CODE (TREE_TYPE (val)) == VECTOR_TYPE
25445 && (funcdecl == NULL_TREE
25446 || (TREE_CODE (funcdecl) == FUNCTION_DECL
25447 && DECL_BUILT_IN_CLASS (funcdecl) != BUILT_IN_MD)))
25448 ? N_("AltiVec argument passed to unprototyped function")
25449 : NULL;
25452 /* For TARGET_SECURE_PLT 32-bit PIC code we can save PIC register
25453 setup by using __stack_chk_fail_local hidden function instead of
25454 calling __stack_chk_fail directly. Otherwise it is better to call
25455 __stack_chk_fail directly. */
25457 static tree
25458 rs6000_stack_protect_fail (void)
25460 return (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
25461 ? default_hidden_stack_protect_fail ()
25462 : default_external_stack_protect_fail ();
25465 void
25466 rs6000_final_prescan_insn (rtx insn, rtx *operand ATTRIBUTE_UNUSED,
25467 int num_operands ATTRIBUTE_UNUSED)
25469 if (rs6000_warn_cell_microcode)
25471 const char *temp;
25472 int insn_code_number = recog_memoized (insn);
25473 location_t location = locator_location (INSN_LOCATOR (insn));
25475 /* Punt on insns we cannot recognize. */
25476 if (insn_code_number < 0)
25477 return;
25479 temp = get_insn_template (insn_code_number, insn);
25481 if (get_attr_cell_micro (insn) == CELL_MICRO_ALWAYS)
25482 warning_at (location, OPT_mwarn_cell_microcode,
25483 "emitting microcode insn %s\t[%s] #%d",
25484 temp, insn_data[INSN_CODE (insn)].name, INSN_UID (insn));
25485 else if (get_attr_cell_micro (insn) == CELL_MICRO_CONDITIONAL)
25486 warning_at (location, OPT_mwarn_cell_microcode,
25487 "emitting conditional microcode insn %s\t[%s] #%d",
25488 temp, insn_data[INSN_CODE (insn)].name, INSN_UID (insn));
25492 #include "gt-rs6000.h"