PR 43544, change TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION to take a tree argument
[official-gcc.git] / gcc / config / rs6000 / rs6000.c
blob91f66a9d59b1d8bbadf8447dc64535e67306ea13
1 /* Subroutines used for code generation on IBM RS/6000.
2 Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
4 Free Software Foundation, Inc.
5 Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
7 This file is part of GCC.
9 GCC is free software; you can redistribute it and/or modify it
10 under the terms of the GNU General Public License as published
11 by the Free Software Foundation; either version 3, or (at your
12 option) any later version.
14 GCC is distributed in the hope that it will be useful, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
17 License for more details.
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING3. If not see
21 <http://www.gnu.org/licenses/>. */
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 PPC476 processors. */
515 static const
516 struct processor_costs ppc476_cost = {
517 COSTS_N_INSNS (4), /* mulsi */
518 COSTS_N_INSNS (4), /* mulsi_const */
519 COSTS_N_INSNS (4), /* mulsi_const9 */
520 COSTS_N_INSNS (4), /* muldi */
521 COSTS_N_INSNS (11), /* divsi */
522 COSTS_N_INSNS (11), /* divdi */
523 COSTS_N_INSNS (6), /* fp */
524 COSTS_N_INSNS (6), /* dmul */
525 COSTS_N_INSNS (19), /* sdiv */
526 COSTS_N_INSNS (33), /* ddiv */
527 32, /* l1 cache line size */
528 32, /* l1 cache */
529 512, /* l2 cache */
530 1, /* streams */
533 /* Instruction costs on PPC601 processors. */
534 static const
535 struct processor_costs ppc601_cost = {
536 COSTS_N_INSNS (5), /* mulsi */
537 COSTS_N_INSNS (5), /* mulsi_const */
538 COSTS_N_INSNS (5), /* mulsi_const9 */
539 COSTS_N_INSNS (5), /* muldi */
540 COSTS_N_INSNS (36), /* divsi */
541 COSTS_N_INSNS (36), /* divdi */
542 COSTS_N_INSNS (4), /* fp */
543 COSTS_N_INSNS (5), /* dmul */
544 COSTS_N_INSNS (17), /* sdiv */
545 COSTS_N_INSNS (31), /* ddiv */
546 32, /* cache line size */
547 32, /* l1 cache */
548 256, /* l2 cache */
549 1, /* streams */
552 /* Instruction costs on PPC603 processors. */
553 static const
554 struct processor_costs ppc603_cost = {
555 COSTS_N_INSNS (5), /* mulsi */
556 COSTS_N_INSNS (3), /* mulsi_const */
557 COSTS_N_INSNS (2), /* mulsi_const9 */
558 COSTS_N_INSNS (5), /* muldi */
559 COSTS_N_INSNS (37), /* divsi */
560 COSTS_N_INSNS (37), /* divdi */
561 COSTS_N_INSNS (3), /* fp */
562 COSTS_N_INSNS (4), /* dmul */
563 COSTS_N_INSNS (18), /* sdiv */
564 COSTS_N_INSNS (33), /* ddiv */
565 32, /* cache line size */
566 8, /* l1 cache */
567 64, /* l2 cache */
568 1, /* streams */
571 /* Instruction costs on PPC604 processors. */
572 static const
573 struct processor_costs ppc604_cost = {
574 COSTS_N_INSNS (4), /* mulsi */
575 COSTS_N_INSNS (4), /* mulsi_const */
576 COSTS_N_INSNS (4), /* mulsi_const9 */
577 COSTS_N_INSNS (4), /* 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 16, /* l1 cache */
586 512, /* l2 cache */
587 1, /* streams */
590 /* Instruction costs on PPC604e processors. */
591 static const
592 struct processor_costs ppc604e_cost = {
593 COSTS_N_INSNS (2), /* mulsi */
594 COSTS_N_INSNS (2), /* mulsi_const */
595 COSTS_N_INSNS (2), /* mulsi_const9 */
596 COSTS_N_INSNS (2), /* muldi */
597 COSTS_N_INSNS (20), /* divsi */
598 COSTS_N_INSNS (20), /* 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 32, /* cache line size */
604 32, /* l1 cache */
605 1024, /* l2 cache */
606 1, /* streams */
609 /* Instruction costs on PPC620 processors. */
610 static const
611 struct processor_costs ppc620_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 (18), /* sdiv */
621 COSTS_N_INSNS (32), /* ddiv */
622 128, /* cache line size */
623 32, /* l1 cache */
624 1024, /* l2 cache */
625 1, /* streams */
628 /* Instruction costs on PPC630 processors. */
629 static const
630 struct processor_costs ppc630_cost = {
631 COSTS_N_INSNS (5), /* mulsi */
632 COSTS_N_INSNS (4), /* mulsi_const */
633 COSTS_N_INSNS (3), /* mulsi_const9 */
634 COSTS_N_INSNS (7), /* muldi */
635 COSTS_N_INSNS (21), /* divsi */
636 COSTS_N_INSNS (37), /* divdi */
637 COSTS_N_INSNS (3), /* fp */
638 COSTS_N_INSNS (3), /* dmul */
639 COSTS_N_INSNS (17), /* sdiv */
640 COSTS_N_INSNS (21), /* ddiv */
641 128, /* cache line size */
642 64, /* l1 cache */
643 1024, /* l2 cache */
644 1, /* streams */
647 /* Instruction costs on Cell processor. */
648 /* COSTS_N_INSNS (1) ~ one add. */
649 static const
650 struct processor_costs ppccell_cost = {
651 COSTS_N_INSNS (9/2)+2, /* mulsi */
652 COSTS_N_INSNS (6/2), /* mulsi_const */
653 COSTS_N_INSNS (6/2), /* mulsi_const9 */
654 COSTS_N_INSNS (15/2)+2, /* muldi */
655 COSTS_N_INSNS (38/2), /* divsi */
656 COSTS_N_INSNS (70/2), /* divdi */
657 COSTS_N_INSNS (10/2), /* fp */
658 COSTS_N_INSNS (10/2), /* dmul */
659 COSTS_N_INSNS (74/2), /* sdiv */
660 COSTS_N_INSNS (74/2), /* ddiv */
661 128, /* cache line size */
662 32, /* l1 cache */
663 512, /* l2 cache */
664 6, /* streams */
667 /* Instruction costs on PPC750 and PPC7400 processors. */
668 static const
669 struct processor_costs ppc750_cost = {
670 COSTS_N_INSNS (5), /* mulsi */
671 COSTS_N_INSNS (3), /* mulsi_const */
672 COSTS_N_INSNS (2), /* mulsi_const9 */
673 COSTS_N_INSNS (5), /* muldi */
674 COSTS_N_INSNS (17), /* divsi */
675 COSTS_N_INSNS (17), /* divdi */
676 COSTS_N_INSNS (3), /* fp */
677 COSTS_N_INSNS (3), /* dmul */
678 COSTS_N_INSNS (17), /* sdiv */
679 COSTS_N_INSNS (31), /* ddiv */
680 32, /* cache line size */
681 32, /* l1 cache */
682 512, /* l2 cache */
683 1, /* streams */
686 /* Instruction costs on PPC7450 processors. */
687 static const
688 struct processor_costs ppc7450_cost = {
689 COSTS_N_INSNS (4), /* mulsi */
690 COSTS_N_INSNS (3), /* mulsi_const */
691 COSTS_N_INSNS (3), /* mulsi_const9 */
692 COSTS_N_INSNS (4), /* muldi */
693 COSTS_N_INSNS (23), /* divsi */
694 COSTS_N_INSNS (23), /* divdi */
695 COSTS_N_INSNS (5), /* fp */
696 COSTS_N_INSNS (5), /* dmul */
697 COSTS_N_INSNS (21), /* sdiv */
698 COSTS_N_INSNS (35), /* ddiv */
699 32, /* cache line size */
700 32, /* l1 cache */
701 1024, /* l2 cache */
702 1, /* streams */
705 /* Instruction costs on PPC8540 processors. */
706 static const
707 struct processor_costs ppc8540_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 (4), /* fp */
715 COSTS_N_INSNS (4), /* dmul */
716 COSTS_N_INSNS (29), /* sdiv */
717 COSTS_N_INSNS (29), /* ddiv */
718 32, /* cache line size */
719 32, /* l1 cache */
720 256, /* l2 cache */
721 1, /* prefetch streams /*/
724 /* Instruction costs on E300C2 and E300C3 cores. */
725 static const
726 struct processor_costs ppce300c2c3_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 (19), /* divsi */
732 COSTS_N_INSNS (19), /* divdi */
733 COSTS_N_INSNS (3), /* fp */
734 COSTS_N_INSNS (4), /* dmul */
735 COSTS_N_INSNS (18), /* sdiv */
736 COSTS_N_INSNS (33), /* ddiv */
738 16, /* l1 cache */
739 16, /* l2 cache */
740 1, /* prefetch streams /*/
743 /* Instruction costs on PPCE500MC processors. */
744 static const
745 struct processor_costs ppce500mc_cost = {
746 COSTS_N_INSNS (4), /* mulsi */
747 COSTS_N_INSNS (4), /* mulsi_const */
748 COSTS_N_INSNS (4), /* mulsi_const9 */
749 COSTS_N_INSNS (4), /* muldi */
750 COSTS_N_INSNS (14), /* divsi */
751 COSTS_N_INSNS (14), /* divdi */
752 COSTS_N_INSNS (8), /* fp */
753 COSTS_N_INSNS (10), /* dmul */
754 COSTS_N_INSNS (36), /* sdiv */
755 COSTS_N_INSNS (66), /* ddiv */
756 64, /* cache line size */
757 32, /* l1 cache */
758 128, /* l2 cache */
759 1, /* prefetch streams /*/
762 /* Instruction costs on PPCE500MC64 processors. */
763 static const
764 struct processor_costs ppce500mc64_cost = {
765 COSTS_N_INSNS (4), /* mulsi */
766 COSTS_N_INSNS (4), /* mulsi_const */
767 COSTS_N_INSNS (4), /* mulsi_const9 */
768 COSTS_N_INSNS (4), /* muldi */
769 COSTS_N_INSNS (14), /* divsi */
770 COSTS_N_INSNS (14), /* divdi */
771 COSTS_N_INSNS (4), /* fp */
772 COSTS_N_INSNS (10), /* dmul */
773 COSTS_N_INSNS (36), /* sdiv */
774 COSTS_N_INSNS (66), /* ddiv */
775 64, /* cache line size */
776 32, /* l1 cache */
777 128, /* l2 cache */
778 1, /* prefetch streams /*/
781 /* Instruction costs on POWER4 and POWER5 processors. */
782 static const
783 struct processor_costs power4_cost = {
784 COSTS_N_INSNS (3), /* mulsi */
785 COSTS_N_INSNS (2), /* mulsi_const */
786 COSTS_N_INSNS (2), /* mulsi_const9 */
787 COSTS_N_INSNS (4), /* 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 (17), /* sdiv */
793 COSTS_N_INSNS (17), /* ddiv */
794 128, /* cache line size */
795 32, /* l1 cache */
796 1024, /* l2 cache */
797 8, /* prefetch streams /*/
800 /* Instruction costs on POWER6 processors. */
801 static const
802 struct processor_costs power6_cost = {
803 COSTS_N_INSNS (8), /* mulsi */
804 COSTS_N_INSNS (8), /* mulsi_const */
805 COSTS_N_INSNS (8), /* mulsi_const9 */
806 COSTS_N_INSNS (8), /* muldi */
807 COSTS_N_INSNS (22), /* divsi */
808 COSTS_N_INSNS (28), /* divdi */
809 COSTS_N_INSNS (3), /* fp */
810 COSTS_N_INSNS (3), /* dmul */
811 COSTS_N_INSNS (13), /* sdiv */
812 COSTS_N_INSNS (16), /* ddiv */
813 128, /* cache line size */
814 64, /* l1 cache */
815 2048, /* l2 cache */
816 16, /* prefetch streams */
819 /* Instruction costs on POWER7 processors. */
820 static const
821 struct processor_costs power7_cost = {
822 COSTS_N_INSNS (2), /* mulsi */
823 COSTS_N_INSNS (2), /* mulsi_const */
824 COSTS_N_INSNS (2), /* mulsi_const9 */
825 COSTS_N_INSNS (2), /* muldi */
826 COSTS_N_INSNS (18), /* divsi */
827 COSTS_N_INSNS (34), /* divdi */
828 COSTS_N_INSNS (3), /* fp */
829 COSTS_N_INSNS (3), /* dmul */
830 COSTS_N_INSNS (13), /* sdiv */
831 COSTS_N_INSNS (16), /* ddiv */
832 128, /* cache line size */
833 32, /* l1 cache */
834 256, /* l2 cache */
835 12, /* prefetch streams */
838 /* Instruction costs on POWER A2 processors. */
839 static const
840 struct processor_costs ppca2_cost = {
841 COSTS_N_INSNS (16), /* mulsi */
842 COSTS_N_INSNS (16), /* mulsi_const */
843 COSTS_N_INSNS (16), /* mulsi_const9 */
844 COSTS_N_INSNS (16), /* muldi */
845 COSTS_N_INSNS (22), /* divsi */
846 COSTS_N_INSNS (28), /* divdi */
847 COSTS_N_INSNS (3), /* fp */
848 COSTS_N_INSNS (3), /* dmul */
849 COSTS_N_INSNS (59), /* sdiv */
850 COSTS_N_INSNS (72), /* ddiv */
852 16, /* l1 cache */
853 2048, /* l2 cache */
854 16, /* prefetch streams */
858 /* Table that classifies rs6000 builtin functions (pure, const, etc.). */
859 #undef RS6000_BUILTIN
860 #undef RS6000_BUILTIN_EQUATE
861 #define RS6000_BUILTIN(NAME, TYPE) TYPE,
862 #define RS6000_BUILTIN_EQUATE(NAME, VALUE)
864 static const enum rs6000_btc builtin_classify[(int)RS6000_BUILTIN_COUNT] =
866 #include "rs6000-builtin.def"
869 #undef RS6000_BUILTIN
870 #undef RS6000_BUILTIN_EQUATE
873 static bool rs6000_function_ok_for_sibcall (tree, tree);
874 static const char *rs6000_invalid_within_doloop (const_rtx);
875 static bool rs6000_legitimate_address_p (enum machine_mode, rtx, bool);
876 static bool rs6000_debug_legitimate_address_p (enum machine_mode, rtx, bool);
877 static rtx rs6000_generate_compare (rtx, enum machine_mode);
878 static void rs6000_emit_stack_tie (void);
879 static void rs6000_frame_related (rtx, rtx, HOST_WIDE_INT, rtx, rtx);
880 static bool spe_func_has_64bit_regs_p (void);
881 static void emit_frame_save (rtx, rtx, enum machine_mode, unsigned int,
882 int, HOST_WIDE_INT);
883 static rtx gen_frame_mem_offset (enum machine_mode, rtx, int);
884 static void rs6000_emit_allocate_stack (HOST_WIDE_INT, int, int);
885 static unsigned rs6000_hash_constant (rtx);
886 static unsigned toc_hash_function (const void *);
887 static int toc_hash_eq (const void *, const void *);
888 static bool reg_offset_addressing_ok_p (enum machine_mode);
889 static bool virtual_stack_registers_memory_p (rtx);
890 static bool constant_pool_expr_p (rtx);
891 static bool legitimate_small_data_p (enum machine_mode, rtx);
892 static bool legitimate_lo_sum_address_p (enum machine_mode, rtx, int);
893 static struct machine_function * rs6000_init_machine_status (void);
894 static bool rs6000_assemble_integer (rtx, unsigned int, int);
895 static bool no_global_regs_above (int, bool);
896 #ifdef HAVE_GAS_HIDDEN
897 static void rs6000_assemble_visibility (tree, int);
898 #endif
899 static int rs6000_ra_ever_killed (void);
900 static tree rs6000_handle_longcall_attribute (tree *, tree, tree, int, bool *);
901 static tree rs6000_handle_altivec_attribute (tree *, tree, tree, int, bool *);
902 static bool rs6000_ms_bitfield_layout_p (const_tree);
903 static tree rs6000_handle_struct_attribute (tree *, tree, tree, int, bool *);
904 static void rs6000_eliminate_indexed_memrefs (rtx operands[2]);
905 static const char *rs6000_mangle_type (const_tree);
906 static void rs6000_set_default_type_attributes (tree);
907 static rtx rs6000_savres_routine_sym (rs6000_stack_t *, bool, bool, bool);
908 static rtx rs6000_emit_stack_reset (rs6000_stack_t *, rtx, rtx, int, bool);
909 static rtx rs6000_make_savres_rtx (rs6000_stack_t *, rtx, int,
910 enum machine_mode, bool, bool, bool);
911 static bool rs6000_reg_live_or_pic_offset_p (int);
912 static tree rs6000_builtin_vectorized_function (tree, tree, tree);
913 static int rs6000_savres_strategy (rs6000_stack_t *, bool, int, int);
914 static void rs6000_restore_saved_cr (rtx, int);
915 static void rs6000_output_function_prologue (FILE *, HOST_WIDE_INT);
916 static void rs6000_output_function_epilogue (FILE *, HOST_WIDE_INT);
917 static void rs6000_output_mi_thunk (FILE *, tree, HOST_WIDE_INT, HOST_WIDE_INT,
918 tree);
919 static rtx rs6000_emit_set_long_const (rtx, HOST_WIDE_INT, HOST_WIDE_INT);
920 static bool rs6000_return_in_memory (const_tree, const_tree);
921 static rtx rs6000_function_value (const_tree, const_tree, bool);
922 static void rs6000_file_start (void);
923 #if TARGET_ELF
924 static int rs6000_elf_reloc_rw_mask (void);
925 static void rs6000_elf_asm_out_constructor (rtx, int);
926 static void rs6000_elf_asm_out_destructor (rtx, int);
927 static void rs6000_elf_end_indicate_exec_stack (void) ATTRIBUTE_UNUSED;
928 static void rs6000_elf_asm_init_sections (void);
929 static section *rs6000_elf_select_rtx_section (enum machine_mode, rtx,
930 unsigned HOST_WIDE_INT);
931 static void rs6000_elf_encode_section_info (tree, rtx, int)
932 ATTRIBUTE_UNUSED;
933 #endif
934 static bool rs6000_use_blocks_for_constant_p (enum machine_mode, const_rtx);
935 static void rs6000_alloc_sdmode_stack_slot (void);
936 static void rs6000_instantiate_decls (void);
937 #if TARGET_XCOFF
938 static void rs6000_xcoff_asm_output_anchor (rtx);
939 static void rs6000_xcoff_asm_globalize_label (FILE *, const char *);
940 static void rs6000_xcoff_asm_init_sections (void);
941 static int rs6000_xcoff_reloc_rw_mask (void);
942 static void rs6000_xcoff_asm_named_section (const char *, unsigned int, tree);
943 static section *rs6000_xcoff_select_section (tree, int,
944 unsigned HOST_WIDE_INT);
945 static void rs6000_xcoff_unique_section (tree, int);
946 static section *rs6000_xcoff_select_rtx_section
947 (enum machine_mode, rtx, unsigned HOST_WIDE_INT);
948 static const char * rs6000_xcoff_strip_name_encoding (const char *);
949 static unsigned int rs6000_xcoff_section_type_flags (tree, const char *, int);
950 static void rs6000_xcoff_file_start (void);
951 static void rs6000_xcoff_file_end (void);
952 #endif
953 static int rs6000_variable_issue (FILE *, int, rtx, int);
954 static bool rs6000_rtx_costs (rtx, int, int, int *, bool);
955 static bool rs6000_debug_rtx_costs (rtx, int, int, int *, bool);
956 static int rs6000_debug_address_cost (rtx, bool);
957 static int rs6000_adjust_cost (rtx, rtx, rtx, int);
958 static int rs6000_debug_adjust_cost (rtx, rtx, rtx, int);
959 static void rs6000_sched_init (FILE *, int, int);
960 static bool is_microcoded_insn (rtx);
961 static bool is_nonpipeline_insn (rtx);
962 static bool is_cracked_insn (rtx);
963 static bool is_branch_slot_insn (rtx);
964 static bool is_load_insn (rtx);
965 static rtx get_store_dest (rtx pat);
966 static bool is_store_insn (rtx);
967 static bool set_to_load_agen (rtx,rtx);
968 static bool adjacent_mem_locations (rtx,rtx);
969 static int rs6000_adjust_priority (rtx, int);
970 static int rs6000_issue_rate (void);
971 static bool rs6000_is_costly_dependence (dep_t, int, int);
972 static rtx get_next_active_insn (rtx, rtx);
973 static bool insn_terminates_group_p (rtx , enum group_termination);
974 static bool insn_must_be_first_in_group (rtx);
975 static bool insn_must_be_last_in_group (rtx);
976 static bool is_costly_group (rtx *, rtx);
977 static int force_new_group (int, FILE *, rtx *, rtx, bool *, int, int *);
978 static int redefine_groups (FILE *, int, rtx, rtx);
979 static int pad_groups (FILE *, int, rtx, rtx);
980 static void rs6000_sched_finish (FILE *, int);
981 static int rs6000_sched_reorder (FILE *, int, rtx *, int *, int);
982 static int rs6000_sched_reorder2 (FILE *, int, rtx *, int *, int);
983 static int rs6000_use_sched_lookahead (void);
984 static int rs6000_use_sched_lookahead_guard (rtx);
985 static void * rs6000_alloc_sched_context (void);
986 static void rs6000_init_sched_context (void *, bool);
987 static void rs6000_set_sched_context (void *);
988 static void rs6000_free_sched_context (void *);
989 static tree rs6000_builtin_reciprocal (unsigned int, bool, bool);
990 static tree rs6000_builtin_mask_for_load (void);
991 static tree rs6000_builtin_mul_widen_even (tree);
992 static tree rs6000_builtin_mul_widen_odd (tree);
993 static tree rs6000_builtin_conversion (unsigned int, tree);
994 static tree rs6000_builtin_vec_perm (tree, tree *);
995 static bool rs6000_builtin_support_vector_misalignment (enum
996 machine_mode,
997 const_tree,
998 int, bool);
1000 static void def_builtin (int, const char *, tree, int);
1001 static bool rs6000_vector_alignment_reachable (const_tree, bool);
1002 static void rs6000_init_builtins (void);
1003 static tree rs6000_builtin_decl (unsigned, bool);
1005 static rtx rs6000_expand_unop_builtin (enum insn_code, tree, rtx);
1006 static rtx rs6000_expand_binop_builtin (enum insn_code, tree, rtx);
1007 static rtx rs6000_expand_ternop_builtin (enum insn_code, tree, rtx);
1008 static rtx rs6000_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
1009 static void altivec_init_builtins (void);
1010 static unsigned builtin_hash_function (const void *);
1011 static int builtin_hash_eq (const void *, const void *);
1012 static tree builtin_function_type (enum machine_mode, enum machine_mode,
1013 enum machine_mode, enum machine_mode,
1014 enum rs6000_builtins, const char *name);
1015 static void rs6000_common_init_builtins (void);
1016 static void rs6000_init_libfuncs (void);
1018 static void paired_init_builtins (void);
1019 static rtx paired_expand_builtin (tree, rtx, bool *);
1020 static rtx paired_expand_lv_builtin (enum insn_code, tree, rtx);
1021 static rtx paired_expand_stv_builtin (enum insn_code, tree);
1022 static rtx paired_expand_predicate_builtin (enum insn_code, tree, rtx);
1024 static void enable_mask_for_builtins (struct builtin_description *, int,
1025 enum rs6000_builtins,
1026 enum rs6000_builtins);
1027 static void spe_init_builtins (void);
1028 static rtx spe_expand_builtin (tree, rtx, bool *);
1029 static rtx spe_expand_stv_builtin (enum insn_code, tree);
1030 static rtx spe_expand_predicate_builtin (enum insn_code, tree, rtx);
1031 static rtx spe_expand_evsel_builtin (enum insn_code, tree, rtx);
1032 static int rs6000_emit_int_cmove (rtx, rtx, rtx, rtx);
1033 static rs6000_stack_t *rs6000_stack_info (void);
1034 static void debug_stack_info (rs6000_stack_t *);
1036 static rtx altivec_expand_builtin (tree, rtx, bool *);
1037 static rtx altivec_expand_ld_builtin (tree, rtx, bool *);
1038 static rtx altivec_expand_st_builtin (tree, rtx, bool *);
1039 static rtx altivec_expand_dst_builtin (tree, rtx, bool *);
1040 static rtx altivec_expand_abs_builtin (enum insn_code, tree, rtx);
1041 static rtx altivec_expand_predicate_builtin (enum insn_code, tree, rtx);
1042 static rtx altivec_expand_stv_builtin (enum insn_code, tree);
1043 static rtx altivec_expand_vec_init_builtin (tree, tree, rtx);
1044 static rtx altivec_expand_vec_set_builtin (tree);
1045 static rtx altivec_expand_vec_ext_builtin (tree, rtx);
1046 static int get_element_number (tree, tree);
1047 static bool rs6000_handle_option (size_t, const char *, int);
1048 static void rs6000_parse_tls_size_option (void);
1049 static void rs6000_parse_yes_no_option (const char *, const char *, int *);
1050 static int first_altivec_reg_to_save (void);
1051 static unsigned int compute_vrsave_mask (void);
1052 static void compute_save_world_info (rs6000_stack_t *info_ptr);
1053 static void is_altivec_return_reg (rtx, void *);
1054 static rtx generate_set_vrsave (rtx, rs6000_stack_t *, int);
1055 int easy_vector_constant (rtx, enum machine_mode);
1056 static rtx rs6000_dwarf_register_span (rtx);
1057 static void rs6000_init_dwarf_reg_sizes_extra (tree);
1058 static rtx rs6000_legitimize_address (rtx, rtx, enum machine_mode);
1059 static rtx rs6000_debug_legitimize_address (rtx, rtx, enum machine_mode);
1060 static rtx rs6000_legitimize_tls_address (rtx, enum tls_model);
1061 static void rs6000_output_dwarf_dtprel (FILE *, int, rtx) ATTRIBUTE_UNUSED;
1062 static rtx rs6000_delegitimize_address (rtx);
1063 static rtx rs6000_tls_get_addr (void);
1064 static rtx rs6000_got_sym (void);
1065 static int rs6000_tls_symbol_ref_1 (rtx *, void *);
1066 static const char *rs6000_get_some_local_dynamic_name (void);
1067 static int rs6000_get_some_local_dynamic_name_1 (rtx *, void *);
1068 static rtx rs6000_complex_function_value (enum machine_mode);
1069 static rtx rs6000_spe_function_arg (CUMULATIVE_ARGS *,
1070 enum machine_mode, tree);
1071 static void rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS *,
1072 HOST_WIDE_INT);
1073 static void rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS *,
1074 tree, HOST_WIDE_INT);
1075 static void rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS *,
1076 HOST_WIDE_INT,
1077 rtx[], int *);
1078 static void rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *,
1079 const_tree, HOST_WIDE_INT,
1080 rtx[], int *);
1081 static rtx rs6000_darwin64_record_arg (CUMULATIVE_ARGS *, const_tree, int, bool);
1082 static rtx rs6000_mixed_function_arg (enum machine_mode, tree, int);
1083 static void rs6000_move_block_from_reg (int regno, rtx x, int nregs);
1084 static void setup_incoming_varargs (CUMULATIVE_ARGS *,
1085 enum machine_mode, tree,
1086 int *, int);
1087 static bool rs6000_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode,
1088 const_tree, bool);
1089 static int rs6000_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode,
1090 tree, bool);
1091 static const char *invalid_arg_for_unprototyped_fn (const_tree, const_tree, const_tree);
1092 #if TARGET_MACHO
1093 static void macho_branch_islands (void);
1094 static int no_previous_def (tree function_name);
1095 static tree get_prev_label (tree function_name);
1096 static void rs6000_darwin_file_start (void);
1097 #endif
1099 static tree rs6000_build_builtin_va_list (void);
1100 static void rs6000_va_start (tree, rtx);
1101 static tree rs6000_gimplify_va_arg (tree, tree, gimple_seq *, gimple_seq *);
1102 static bool rs6000_must_pass_in_stack (enum machine_mode, const_tree);
1103 static bool rs6000_scalar_mode_supported_p (enum machine_mode);
1104 static bool rs6000_vector_mode_supported_p (enum machine_mode);
1105 static rtx rs6000_emit_vector_compare_inner (enum rtx_code, rtx, rtx);
1106 static rtx rs6000_emit_vector_compare (enum rtx_code, rtx, rtx,
1107 enum machine_mode);
1108 static tree rs6000_stack_protect_fail (void);
1110 static rtx rs6000_legitimize_reload_address (rtx, enum machine_mode, int, int,
1111 int, int *);
1113 static rtx rs6000_debug_legitimize_reload_address (rtx, enum machine_mode, int,
1114 int, int, int *);
1116 rtx (*rs6000_legitimize_reload_address_ptr) (rtx, enum machine_mode, int, int,
1117 int, int *)
1118 = rs6000_legitimize_reload_address;
1120 static bool rs6000_mode_dependent_address (rtx);
1121 static bool rs6000_debug_mode_dependent_address (rtx);
1122 bool (*rs6000_mode_dependent_address_ptr) (rtx)
1123 = rs6000_mode_dependent_address;
1125 static enum reg_class rs6000_secondary_reload_class (enum reg_class,
1126 enum machine_mode, rtx);
1127 static enum reg_class rs6000_debug_secondary_reload_class (enum reg_class,
1128 enum machine_mode,
1129 rtx);
1130 enum reg_class (*rs6000_secondary_reload_class_ptr) (enum reg_class,
1131 enum machine_mode, rtx)
1132 = rs6000_secondary_reload_class;
1134 static enum reg_class rs6000_preferred_reload_class (rtx, enum reg_class);
1135 static enum reg_class rs6000_debug_preferred_reload_class (rtx,
1136 enum reg_class);
1137 enum reg_class (*rs6000_preferred_reload_class_ptr) (rtx, enum reg_class)
1138 = rs6000_preferred_reload_class;
1140 static bool rs6000_secondary_memory_needed (enum reg_class, enum reg_class,
1141 enum machine_mode);
1143 static bool rs6000_debug_secondary_memory_needed (enum reg_class,
1144 enum reg_class,
1145 enum machine_mode);
1147 bool (*rs6000_secondary_memory_needed_ptr) (enum reg_class, enum reg_class,
1148 enum machine_mode)
1149 = rs6000_secondary_memory_needed;
1151 static bool rs6000_cannot_change_mode_class (enum machine_mode,
1152 enum machine_mode,
1153 enum reg_class);
1154 static bool rs6000_debug_cannot_change_mode_class (enum machine_mode,
1155 enum machine_mode,
1156 enum reg_class);
1158 bool (*rs6000_cannot_change_mode_class_ptr) (enum machine_mode,
1159 enum machine_mode,
1160 enum reg_class)
1161 = rs6000_cannot_change_mode_class;
1163 static enum reg_class rs6000_secondary_reload (bool, rtx, enum reg_class,
1164 enum machine_mode,
1165 struct secondary_reload_info *);
1167 static const enum reg_class *rs6000_ira_cover_classes (void);
1169 const int INSN_NOT_AVAILABLE = -1;
1170 static enum machine_mode rs6000_eh_return_filter_mode (void);
1171 static bool rs6000_can_eliminate (const int, const int);
1172 static void rs6000_trampoline_init (rtx, tree, rtx);
1174 /* Hash table stuff for keeping track of TOC entries. */
1176 struct GTY(()) toc_hash_struct
1178 /* `key' will satisfy CONSTANT_P; in fact, it will satisfy
1179 ASM_OUTPUT_SPECIAL_POOL_ENTRY_P. */
1180 rtx key;
1181 enum machine_mode key_mode;
1182 int labelno;
1185 static GTY ((param_is (struct toc_hash_struct))) htab_t toc_hash_table;
1187 /* Hash table to keep track of the argument types for builtin functions. */
1189 struct GTY(()) builtin_hash_struct
1191 tree type;
1192 enum machine_mode mode[4]; /* return value + 3 arguments. */
1193 unsigned char uns_p[4]; /* and whether the types are unsigned. */
1196 static GTY ((param_is (struct builtin_hash_struct))) htab_t builtin_hash_table;
1198 /* Default register names. */
1199 char rs6000_reg_names[][8] =
1201 "0", "1", "2", "3", "4", "5", "6", "7",
1202 "8", "9", "10", "11", "12", "13", "14", "15",
1203 "16", "17", "18", "19", "20", "21", "22", "23",
1204 "24", "25", "26", "27", "28", "29", "30", "31",
1205 "0", "1", "2", "3", "4", "5", "6", "7",
1206 "8", "9", "10", "11", "12", "13", "14", "15",
1207 "16", "17", "18", "19", "20", "21", "22", "23",
1208 "24", "25", "26", "27", "28", "29", "30", "31",
1209 "mq", "lr", "ctr","ap",
1210 "0", "1", "2", "3", "4", "5", "6", "7",
1211 "xer",
1212 /* AltiVec registers. */
1213 "0", "1", "2", "3", "4", "5", "6", "7",
1214 "8", "9", "10", "11", "12", "13", "14", "15",
1215 "16", "17", "18", "19", "20", "21", "22", "23",
1216 "24", "25", "26", "27", "28", "29", "30", "31",
1217 "vrsave", "vscr",
1218 /* SPE registers. */
1219 "spe_acc", "spefscr",
1220 /* Soft frame pointer. */
1221 "sfp"
1224 #ifdef TARGET_REGNAMES
1225 static const char alt_reg_names[][8] =
1227 "%r0", "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7",
1228 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15",
1229 "%r16", "%r17", "%r18", "%r19", "%r20", "%r21", "%r22", "%r23",
1230 "%r24", "%r25", "%r26", "%r27", "%r28", "%r29", "%r30", "%r31",
1231 "%f0", "%f1", "%f2", "%f3", "%f4", "%f5", "%f6", "%f7",
1232 "%f8", "%f9", "%f10", "%f11", "%f12", "%f13", "%f14", "%f15",
1233 "%f16", "%f17", "%f18", "%f19", "%f20", "%f21", "%f22", "%f23",
1234 "%f24", "%f25", "%f26", "%f27", "%f28", "%f29", "%f30", "%f31",
1235 "mq", "lr", "ctr", "ap",
1236 "%cr0", "%cr1", "%cr2", "%cr3", "%cr4", "%cr5", "%cr6", "%cr7",
1237 "xer",
1238 /* AltiVec registers. */
1239 "%v0", "%v1", "%v2", "%v3", "%v4", "%v5", "%v6", "%v7",
1240 "%v8", "%v9", "%v10", "%v11", "%v12", "%v13", "%v14", "%v15",
1241 "%v16", "%v17", "%v18", "%v19", "%v20", "%v21", "%v22", "%v23",
1242 "%v24", "%v25", "%v26", "%v27", "%v28", "%v29", "%v30", "%v31",
1243 "vrsave", "vscr",
1244 /* SPE registers. */
1245 "spe_acc", "spefscr",
1246 /* Soft frame pointer. */
1247 "sfp"
1249 #endif
1251 /* Table of valid machine attributes. */
1253 static const struct attribute_spec rs6000_attribute_table[] =
1255 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
1256 { "altivec", 1, 1, false, true, false, rs6000_handle_altivec_attribute },
1257 { "longcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute },
1258 { "shortcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute },
1259 { "ms_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute },
1260 { "gcc_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute },
1261 #ifdef SUBTARGET_ATTRIBUTE_TABLE
1262 SUBTARGET_ATTRIBUTE_TABLE,
1263 #endif
1264 { NULL, 0, 0, false, false, false, NULL }
1267 #ifndef MASK_STRICT_ALIGN
1268 #define MASK_STRICT_ALIGN 0
1269 #endif
1270 #ifndef TARGET_PROFILE_KERNEL
1271 #define TARGET_PROFILE_KERNEL 0
1272 #endif
1274 /* The VRSAVE bitmask puts bit %v0 as the most significant bit. */
1275 #define ALTIVEC_REG_BIT(REGNO) (0x80000000 >> ((REGNO) - FIRST_ALTIVEC_REGNO))
1277 /* Initialize the GCC target structure. */
1278 #undef TARGET_ATTRIBUTE_TABLE
1279 #define TARGET_ATTRIBUTE_TABLE rs6000_attribute_table
1280 #undef TARGET_SET_DEFAULT_TYPE_ATTRIBUTES
1281 #define TARGET_SET_DEFAULT_TYPE_ATTRIBUTES rs6000_set_default_type_attributes
1283 #undef TARGET_ASM_ALIGNED_DI_OP
1284 #define TARGET_ASM_ALIGNED_DI_OP DOUBLE_INT_ASM_OP
1286 /* Default unaligned ops are only provided for ELF. Find the ops needed
1287 for non-ELF systems. */
1288 #ifndef OBJECT_FORMAT_ELF
1289 #if TARGET_XCOFF
1290 /* For XCOFF. rs6000_assemble_integer will handle unaligned DIs on
1291 64-bit targets. */
1292 #undef TARGET_ASM_UNALIGNED_HI_OP
1293 #define TARGET_ASM_UNALIGNED_HI_OP "\t.vbyte\t2,"
1294 #undef TARGET_ASM_UNALIGNED_SI_OP
1295 #define TARGET_ASM_UNALIGNED_SI_OP "\t.vbyte\t4,"
1296 #undef TARGET_ASM_UNALIGNED_DI_OP
1297 #define TARGET_ASM_UNALIGNED_DI_OP "\t.vbyte\t8,"
1298 #else
1299 /* For Darwin. */
1300 #undef TARGET_ASM_UNALIGNED_HI_OP
1301 #define TARGET_ASM_UNALIGNED_HI_OP "\t.short\t"
1302 #undef TARGET_ASM_UNALIGNED_SI_OP
1303 #define TARGET_ASM_UNALIGNED_SI_OP "\t.long\t"
1304 #undef TARGET_ASM_UNALIGNED_DI_OP
1305 #define TARGET_ASM_UNALIGNED_DI_OP "\t.quad\t"
1306 #undef TARGET_ASM_ALIGNED_DI_OP
1307 #define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t"
1308 #endif
1309 #endif
1311 /* This hook deals with fixups for relocatable code and DI-mode objects
1312 in 64-bit code. */
1313 #undef TARGET_ASM_INTEGER
1314 #define TARGET_ASM_INTEGER rs6000_assemble_integer
1316 #ifdef HAVE_GAS_HIDDEN
1317 #undef TARGET_ASM_ASSEMBLE_VISIBILITY
1318 #define TARGET_ASM_ASSEMBLE_VISIBILITY rs6000_assemble_visibility
1319 #endif
1321 #undef TARGET_HAVE_TLS
1322 #define TARGET_HAVE_TLS HAVE_AS_TLS
1324 #undef TARGET_CANNOT_FORCE_CONST_MEM
1325 #define TARGET_CANNOT_FORCE_CONST_MEM rs6000_tls_referenced_p
1327 #undef TARGET_DELEGITIMIZE_ADDRESS
1328 #define TARGET_DELEGITIMIZE_ADDRESS rs6000_delegitimize_address
1330 #undef TARGET_ASM_FUNCTION_PROLOGUE
1331 #define TARGET_ASM_FUNCTION_PROLOGUE rs6000_output_function_prologue
1332 #undef TARGET_ASM_FUNCTION_EPILOGUE
1333 #define TARGET_ASM_FUNCTION_EPILOGUE rs6000_output_function_epilogue
1335 #undef TARGET_LEGITIMIZE_ADDRESS
1336 #define TARGET_LEGITIMIZE_ADDRESS rs6000_legitimize_address
1338 #undef TARGET_SCHED_VARIABLE_ISSUE
1339 #define TARGET_SCHED_VARIABLE_ISSUE rs6000_variable_issue
1341 #undef TARGET_SCHED_ISSUE_RATE
1342 #define TARGET_SCHED_ISSUE_RATE rs6000_issue_rate
1343 #undef TARGET_SCHED_ADJUST_COST
1344 #define TARGET_SCHED_ADJUST_COST rs6000_adjust_cost
1345 #undef TARGET_SCHED_ADJUST_PRIORITY
1346 #define TARGET_SCHED_ADJUST_PRIORITY rs6000_adjust_priority
1347 #undef TARGET_SCHED_IS_COSTLY_DEPENDENCE
1348 #define TARGET_SCHED_IS_COSTLY_DEPENDENCE rs6000_is_costly_dependence
1349 #undef TARGET_SCHED_INIT
1350 #define TARGET_SCHED_INIT rs6000_sched_init
1351 #undef TARGET_SCHED_FINISH
1352 #define TARGET_SCHED_FINISH rs6000_sched_finish
1353 #undef TARGET_SCHED_REORDER
1354 #define TARGET_SCHED_REORDER rs6000_sched_reorder
1355 #undef TARGET_SCHED_REORDER2
1356 #define TARGET_SCHED_REORDER2 rs6000_sched_reorder2
1358 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
1359 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD rs6000_use_sched_lookahead
1361 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD
1362 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD rs6000_use_sched_lookahead_guard
1364 #undef TARGET_SCHED_ALLOC_SCHED_CONTEXT
1365 #define TARGET_SCHED_ALLOC_SCHED_CONTEXT rs6000_alloc_sched_context
1366 #undef TARGET_SCHED_INIT_SCHED_CONTEXT
1367 #define TARGET_SCHED_INIT_SCHED_CONTEXT rs6000_init_sched_context
1368 #undef TARGET_SCHED_SET_SCHED_CONTEXT
1369 #define TARGET_SCHED_SET_SCHED_CONTEXT rs6000_set_sched_context
1370 #undef TARGET_SCHED_FREE_SCHED_CONTEXT
1371 #define TARGET_SCHED_FREE_SCHED_CONTEXT rs6000_free_sched_context
1373 #undef TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD
1374 #define TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD rs6000_builtin_mask_for_load
1375 #undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN
1376 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN rs6000_builtin_mul_widen_even
1377 #undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD
1378 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD rs6000_builtin_mul_widen_odd
1379 #undef TARGET_VECTORIZE_BUILTIN_CONVERSION
1380 #define TARGET_VECTORIZE_BUILTIN_CONVERSION rs6000_builtin_conversion
1381 #undef TARGET_VECTORIZE_BUILTIN_VEC_PERM
1382 #define TARGET_VECTORIZE_BUILTIN_VEC_PERM rs6000_builtin_vec_perm
1383 #undef TARGET_SUPPORT_VECTOR_MISALIGNMENT
1384 #define TARGET_SUPPORT_VECTOR_MISALIGNMENT \
1385 rs6000_builtin_support_vector_misalignment
1386 #undef TARGET_VECTOR_ALIGNMENT_REACHABLE
1387 #define TARGET_VECTOR_ALIGNMENT_REACHABLE rs6000_vector_alignment_reachable
1389 #undef TARGET_INIT_BUILTINS
1390 #define TARGET_INIT_BUILTINS rs6000_init_builtins
1391 #undef TARGET_BUILTIN_DECL
1392 #define TARGET_BUILTIN_DECL rs6000_builtin_decl
1394 #undef TARGET_EXPAND_BUILTIN
1395 #define TARGET_EXPAND_BUILTIN rs6000_expand_builtin
1397 #undef TARGET_MANGLE_TYPE
1398 #define TARGET_MANGLE_TYPE rs6000_mangle_type
1400 #undef TARGET_INIT_LIBFUNCS
1401 #define TARGET_INIT_LIBFUNCS rs6000_init_libfuncs
1403 #if TARGET_MACHO
1404 #undef TARGET_BINDS_LOCAL_P
1405 #define TARGET_BINDS_LOCAL_P darwin_binds_local_p
1406 #endif
1408 #undef TARGET_MS_BITFIELD_LAYOUT_P
1409 #define TARGET_MS_BITFIELD_LAYOUT_P rs6000_ms_bitfield_layout_p
1411 #undef TARGET_ASM_OUTPUT_MI_THUNK
1412 #define TARGET_ASM_OUTPUT_MI_THUNK rs6000_output_mi_thunk
1414 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
1415 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true
1417 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
1418 #define TARGET_FUNCTION_OK_FOR_SIBCALL rs6000_function_ok_for_sibcall
1420 #undef TARGET_INVALID_WITHIN_DOLOOP
1421 #define TARGET_INVALID_WITHIN_DOLOOP rs6000_invalid_within_doloop
1423 #undef TARGET_RTX_COSTS
1424 #define TARGET_RTX_COSTS rs6000_rtx_costs
1425 #undef TARGET_ADDRESS_COST
1426 #define TARGET_ADDRESS_COST hook_int_rtx_bool_0
1428 #undef TARGET_DWARF_REGISTER_SPAN
1429 #define TARGET_DWARF_REGISTER_SPAN rs6000_dwarf_register_span
1431 #undef TARGET_INIT_DWARF_REG_SIZES_EXTRA
1432 #define TARGET_INIT_DWARF_REG_SIZES_EXTRA rs6000_init_dwarf_reg_sizes_extra
1434 /* On rs6000, function arguments are promoted, as are function return
1435 values. */
1436 #undef TARGET_PROMOTE_FUNCTION_MODE
1437 #define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote
1439 #undef TARGET_RETURN_IN_MEMORY
1440 #define TARGET_RETURN_IN_MEMORY rs6000_return_in_memory
1442 #undef TARGET_SETUP_INCOMING_VARARGS
1443 #define TARGET_SETUP_INCOMING_VARARGS setup_incoming_varargs
1445 /* Always strict argument naming on rs6000. */
1446 #undef TARGET_STRICT_ARGUMENT_NAMING
1447 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
1448 #undef TARGET_PRETEND_OUTGOING_VARARGS_NAMED
1449 #define TARGET_PRETEND_OUTGOING_VARARGS_NAMED hook_bool_CUMULATIVE_ARGS_true
1450 #undef TARGET_SPLIT_COMPLEX_ARG
1451 #define TARGET_SPLIT_COMPLEX_ARG hook_bool_const_tree_true
1452 #undef TARGET_MUST_PASS_IN_STACK
1453 #define TARGET_MUST_PASS_IN_STACK rs6000_must_pass_in_stack
1454 #undef TARGET_PASS_BY_REFERENCE
1455 #define TARGET_PASS_BY_REFERENCE rs6000_pass_by_reference
1456 #undef TARGET_ARG_PARTIAL_BYTES
1457 #define TARGET_ARG_PARTIAL_BYTES rs6000_arg_partial_bytes
1459 #undef TARGET_BUILD_BUILTIN_VA_LIST
1460 #define TARGET_BUILD_BUILTIN_VA_LIST rs6000_build_builtin_va_list
1462 #undef TARGET_EXPAND_BUILTIN_VA_START
1463 #define TARGET_EXPAND_BUILTIN_VA_START rs6000_va_start
1465 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
1466 #define TARGET_GIMPLIFY_VA_ARG_EXPR rs6000_gimplify_va_arg
1468 #undef TARGET_EH_RETURN_FILTER_MODE
1469 #define TARGET_EH_RETURN_FILTER_MODE rs6000_eh_return_filter_mode
1471 #undef TARGET_SCALAR_MODE_SUPPORTED_P
1472 #define TARGET_SCALAR_MODE_SUPPORTED_P rs6000_scalar_mode_supported_p
1474 #undef TARGET_VECTOR_MODE_SUPPORTED_P
1475 #define TARGET_VECTOR_MODE_SUPPORTED_P rs6000_vector_mode_supported_p
1477 #undef TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN
1478 #define TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN invalid_arg_for_unprototyped_fn
1480 #undef TARGET_HANDLE_OPTION
1481 #define TARGET_HANDLE_OPTION rs6000_handle_option
1483 #undef TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION
1484 #define TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION \
1485 rs6000_builtin_vectorized_function
1487 #undef TARGET_DEFAULT_TARGET_FLAGS
1488 #define TARGET_DEFAULT_TARGET_FLAGS \
1489 (TARGET_DEFAULT)
1491 #undef TARGET_STACK_PROTECT_FAIL
1492 #define TARGET_STACK_PROTECT_FAIL rs6000_stack_protect_fail
1494 /* MPC604EUM 3.5.2 Weak Consistency between Multiple Processors
1495 The PowerPC architecture requires only weak consistency among
1496 processors--that is, memory accesses between processors need not be
1497 sequentially consistent and memory accesses among processors can occur
1498 in any order. The ability to order memory accesses weakly provides
1499 opportunities for more efficient use of the system bus. Unless a
1500 dependency exists, the 604e allows read operations to precede store
1501 operations. */
1502 #undef TARGET_RELAXED_ORDERING
1503 #define TARGET_RELAXED_ORDERING true
1505 #ifdef HAVE_AS_TLS
1506 #undef TARGET_ASM_OUTPUT_DWARF_DTPREL
1507 #define TARGET_ASM_OUTPUT_DWARF_DTPREL rs6000_output_dwarf_dtprel
1508 #endif
1510 /* Use a 32-bit anchor range. This leads to sequences like:
1512 addis tmp,anchor,high
1513 add dest,tmp,low
1515 where tmp itself acts as an anchor, and can be shared between
1516 accesses to the same 64k page. */
1517 #undef TARGET_MIN_ANCHOR_OFFSET
1518 #define TARGET_MIN_ANCHOR_OFFSET -0x7fffffff - 1
1519 #undef TARGET_MAX_ANCHOR_OFFSET
1520 #define TARGET_MAX_ANCHOR_OFFSET 0x7fffffff
1521 #undef TARGET_USE_BLOCKS_FOR_CONSTANT_P
1522 #define TARGET_USE_BLOCKS_FOR_CONSTANT_P rs6000_use_blocks_for_constant_p
1524 #undef TARGET_BUILTIN_RECIPROCAL
1525 #define TARGET_BUILTIN_RECIPROCAL rs6000_builtin_reciprocal
1527 #undef TARGET_EXPAND_TO_RTL_HOOK
1528 #define TARGET_EXPAND_TO_RTL_HOOK rs6000_alloc_sdmode_stack_slot
1530 #undef TARGET_INSTANTIATE_DECLS
1531 #define TARGET_INSTANTIATE_DECLS rs6000_instantiate_decls
1533 #undef TARGET_SECONDARY_RELOAD
1534 #define TARGET_SECONDARY_RELOAD rs6000_secondary_reload
1536 #undef TARGET_IRA_COVER_CLASSES
1537 #define TARGET_IRA_COVER_CLASSES rs6000_ira_cover_classes
1539 #undef TARGET_LEGITIMATE_ADDRESS_P
1540 #define TARGET_LEGITIMATE_ADDRESS_P rs6000_legitimate_address_p
1542 #undef TARGET_CAN_ELIMINATE
1543 #define TARGET_CAN_ELIMINATE rs6000_can_eliminate
1545 #undef TARGET_TRAMPOLINE_INIT
1546 #define TARGET_TRAMPOLINE_INIT rs6000_trampoline_init
1548 #undef TARGET_FUNCTION_VALUE
1549 #define TARGET_FUNCTION_VALUE rs6000_function_value
1551 struct gcc_target targetm = TARGET_INITIALIZER;
1553 /* Return number of consecutive hard regs needed starting at reg REGNO
1554 to hold something of mode MODE.
1555 This is ordinarily the length in words of a value of mode MODE
1556 but can be less for certain modes in special long registers.
1558 For the SPE, GPRs are 64 bits but only 32 bits are visible in
1559 scalar instructions. The upper 32 bits are only available to the
1560 SIMD instructions.
1562 POWER and PowerPC GPRs hold 32 bits worth;
1563 PowerPC64 GPRs and FPRs point register holds 64 bits worth. */
1565 static int
1566 rs6000_hard_regno_nregs_internal (int regno, enum machine_mode mode)
1568 unsigned HOST_WIDE_INT reg_size;
1570 if (FP_REGNO_P (regno))
1571 reg_size = (VECTOR_MEM_VSX_P (mode)
1572 ? UNITS_PER_VSX_WORD
1573 : UNITS_PER_FP_WORD);
1575 else if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode))
1576 reg_size = UNITS_PER_SPE_WORD;
1578 else if (ALTIVEC_REGNO_P (regno))
1579 reg_size = UNITS_PER_ALTIVEC_WORD;
1581 /* The value returned for SCmode in the E500 double case is 2 for
1582 ABI compatibility; storing an SCmode value in a single register
1583 would require function_arg and rs6000_spe_function_arg to handle
1584 SCmode so as to pass the value correctly in a pair of
1585 registers. */
1586 else if (TARGET_E500_DOUBLE && FLOAT_MODE_P (mode) && mode != SCmode
1587 && !DECIMAL_FLOAT_MODE_P (mode))
1588 reg_size = UNITS_PER_FP_WORD;
1590 else
1591 reg_size = UNITS_PER_WORD;
1593 return (GET_MODE_SIZE (mode) + reg_size - 1) / reg_size;
1596 /* Value is 1 if hard register REGNO can hold a value of machine-mode
1597 MODE. */
1598 static int
1599 rs6000_hard_regno_mode_ok (int regno, enum machine_mode mode)
1601 int last_regno = regno + rs6000_hard_regno_nregs[mode][regno] - 1;
1603 /* VSX registers that overlap the FPR registers are larger than for non-VSX
1604 implementations. Don't allow an item to be split between a FP register
1605 and an Altivec register. */
1606 if (VECTOR_MEM_VSX_P (mode))
1608 if (FP_REGNO_P (regno))
1609 return FP_REGNO_P (last_regno);
1611 if (ALTIVEC_REGNO_P (regno))
1612 return ALTIVEC_REGNO_P (last_regno);
1615 /* The GPRs can hold any mode, but values bigger than one register
1616 cannot go past R31. */
1617 if (INT_REGNO_P (regno))
1618 return INT_REGNO_P (last_regno);
1620 /* The float registers (except for VSX vector modes) can only hold floating
1621 modes and DImode. This excludes the 32-bit decimal float mode for
1622 now. */
1623 if (FP_REGNO_P (regno))
1625 if (SCALAR_FLOAT_MODE_P (mode)
1626 && (mode != TDmode || (regno % 2) == 0)
1627 && FP_REGNO_P (last_regno))
1628 return 1;
1630 if (GET_MODE_CLASS (mode) == MODE_INT
1631 && GET_MODE_SIZE (mode) == UNITS_PER_FP_WORD)
1632 return 1;
1634 if (PAIRED_SIMD_REGNO_P (regno) && TARGET_PAIRED_FLOAT
1635 && PAIRED_VECTOR_MODE (mode))
1636 return 1;
1638 return 0;
1641 /* The CR register can only hold CC modes. */
1642 if (CR_REGNO_P (regno))
1643 return GET_MODE_CLASS (mode) == MODE_CC;
1645 if (XER_REGNO_P (regno))
1646 return mode == PSImode;
1648 /* AltiVec only in AldyVec registers. */
1649 if (ALTIVEC_REGNO_P (regno))
1650 return VECTOR_MEM_ALTIVEC_OR_VSX_P (mode);
1652 /* ...but GPRs can hold SIMD data on the SPE in one register. */
1653 if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode))
1654 return 1;
1656 /* We cannot put TImode anywhere except general register and it must be able
1657 to fit within the register set. In the future, allow TImode in the
1658 Altivec or VSX registers. */
1660 return GET_MODE_SIZE (mode) <= UNITS_PER_WORD;
1663 /* Print interesting facts about registers. */
1664 static void
1665 rs6000_debug_reg_print (int first_regno, int last_regno, const char *reg_name)
1667 int r, m;
1669 for (r = first_regno; r <= last_regno; ++r)
1671 const char *comma = "";
1672 int len;
1674 if (first_regno == last_regno)
1675 fprintf (stderr, "%s:\t", reg_name);
1676 else
1677 fprintf (stderr, "%s%d:\t", reg_name, r - first_regno);
1679 len = 8;
1680 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1681 if (rs6000_hard_regno_mode_ok_p[m][r] && rs6000_hard_regno_nregs[m][r])
1683 if (len > 70)
1685 fprintf (stderr, ",\n\t");
1686 len = 8;
1687 comma = "";
1690 if (rs6000_hard_regno_nregs[m][r] > 1)
1691 len += fprintf (stderr, "%s%s/%d", comma, GET_MODE_NAME (m),
1692 rs6000_hard_regno_nregs[m][r]);
1693 else
1694 len += fprintf (stderr, "%s%s", comma, GET_MODE_NAME (m));
1696 comma = ", ";
1699 if (call_used_regs[r])
1701 if (len > 70)
1703 fprintf (stderr, ",\n\t");
1704 len = 8;
1705 comma = "";
1708 len += fprintf (stderr, "%s%s", comma, "call-used");
1709 comma = ", ";
1712 if (fixed_regs[r])
1714 if (len > 70)
1716 fprintf (stderr, ",\n\t");
1717 len = 8;
1718 comma = "";
1721 len += fprintf (stderr, "%s%s", comma, "fixed");
1722 comma = ", ";
1725 if (len > 70)
1727 fprintf (stderr, ",\n\t");
1728 comma = "";
1731 fprintf (stderr, "%sregno = %d\n", comma, r);
1735 /* Print various interesting information with -mdebug=reg. */
1736 static void
1737 rs6000_debug_reg_global (void)
1739 const char *nl = (const char *)0;
1740 int m;
1741 char costly_num[20];
1742 char nop_num[20];
1743 const char *costly_str;
1744 const char *nop_str;
1746 /* Map enum rs6000_vector to string. */
1747 static const char *rs6000_debug_vector_unit[] = {
1748 "none",
1749 "altivec",
1750 "vsx",
1751 "paired",
1752 "spe",
1753 "other"
1756 fprintf (stderr, "Register information: (last virtual reg = %d)\n",
1757 LAST_VIRTUAL_REGISTER);
1758 rs6000_debug_reg_print (0, 31, "gr");
1759 rs6000_debug_reg_print (32, 63, "fp");
1760 rs6000_debug_reg_print (FIRST_ALTIVEC_REGNO,
1761 LAST_ALTIVEC_REGNO,
1762 "vs");
1763 rs6000_debug_reg_print (LR_REGNO, LR_REGNO, "lr");
1764 rs6000_debug_reg_print (CTR_REGNO, CTR_REGNO, "ctr");
1765 rs6000_debug_reg_print (CR0_REGNO, CR7_REGNO, "cr");
1766 rs6000_debug_reg_print (MQ_REGNO, MQ_REGNO, "mq");
1767 rs6000_debug_reg_print (XER_REGNO, XER_REGNO, "xer");
1768 rs6000_debug_reg_print (VRSAVE_REGNO, VRSAVE_REGNO, "vrsave");
1769 rs6000_debug_reg_print (VSCR_REGNO, VSCR_REGNO, "vscr");
1770 rs6000_debug_reg_print (SPE_ACC_REGNO, SPE_ACC_REGNO, "spe_a");
1771 rs6000_debug_reg_print (SPEFSCR_REGNO, SPEFSCR_REGNO, "spe_f");
1773 fprintf (stderr,
1774 "\n"
1775 "d reg_class = %s\n"
1776 "f reg_class = %s\n"
1777 "v reg_class = %s\n"
1778 "wa reg_class = %s\n"
1779 "wd reg_class = %s\n"
1780 "wf reg_class = %s\n"
1781 "ws reg_class = %s\n\n",
1782 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_d]],
1783 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_f]],
1784 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_v]],
1785 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wa]],
1786 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wd]],
1787 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wf]],
1788 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_ws]]);
1790 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1791 if (rs6000_vector_unit[m] || rs6000_vector_mem[m])
1793 nl = "\n";
1794 fprintf (stderr, "Vector mode: %-5s arithmetic: %-8s move: %-8s\n",
1795 GET_MODE_NAME (m),
1796 rs6000_debug_vector_unit[ rs6000_vector_unit[m] ],
1797 rs6000_debug_vector_unit[ rs6000_vector_mem[m] ]);
1800 if (nl)
1801 fputs (nl, stderr);
1803 switch (rs6000_sched_costly_dep)
1805 case max_dep_latency:
1806 costly_str = "max_dep_latency";
1807 break;
1809 case no_dep_costly:
1810 costly_str = "no_dep_costly";
1811 break;
1813 case all_deps_costly:
1814 costly_str = "all_deps_costly";
1815 break;
1817 case true_store_to_load_dep_costly:
1818 costly_str = "true_store_to_load_dep_costly";
1819 break;
1821 case store_to_load_dep_costly:
1822 costly_str = "store_to_load_dep_costly";
1823 break;
1825 default:
1826 costly_str = costly_num;
1827 sprintf (costly_num, "%d", (int)rs6000_sched_costly_dep);
1828 break;
1831 switch (rs6000_sched_insert_nops)
1833 case sched_finish_regroup_exact:
1834 nop_str = "sched_finish_regroup_exact";
1835 break;
1837 case sched_finish_pad_groups:
1838 nop_str = "sched_finish_pad_groups";
1839 break;
1841 case sched_finish_none:
1842 nop_str = "sched_finish_none";
1843 break;
1845 default:
1846 nop_str = nop_num;
1847 sprintf (nop_num, "%d", (int)rs6000_sched_insert_nops);
1848 break;
1851 fprintf (stderr,
1852 "always_hint = %s\n"
1853 "align_branch_targets = %s\n"
1854 "sched_restricted_insns_priority = %d\n"
1855 "sched_costly_dep = %s\n"
1856 "sched_insert_nops = %s\n\n",
1857 rs6000_always_hint ? "true" : "false",
1858 rs6000_align_branch_targets ? "true" : "false",
1859 (int)rs6000_sched_restricted_insns_priority,
1860 costly_str, nop_str);
1863 /* Initialize the various global tables that are based on register size. */
1864 static void
1865 rs6000_init_hard_regno_mode_ok (void)
1867 int r, m, c;
1868 int align64;
1869 int align32;
1871 /* Precalculate REGNO_REG_CLASS. */
1872 rs6000_regno_regclass[0] = GENERAL_REGS;
1873 for (r = 1; r < 32; ++r)
1874 rs6000_regno_regclass[r] = BASE_REGS;
1876 for (r = 32; r < 64; ++r)
1877 rs6000_regno_regclass[r] = FLOAT_REGS;
1879 for (r = 64; r < FIRST_PSEUDO_REGISTER; ++r)
1880 rs6000_regno_regclass[r] = NO_REGS;
1882 for (r = FIRST_ALTIVEC_REGNO; r <= LAST_ALTIVEC_REGNO; ++r)
1883 rs6000_regno_regclass[r] = ALTIVEC_REGS;
1885 rs6000_regno_regclass[CR0_REGNO] = CR0_REGS;
1886 for (r = CR1_REGNO; r <= CR7_REGNO; ++r)
1887 rs6000_regno_regclass[r] = CR_REGS;
1889 rs6000_regno_regclass[MQ_REGNO] = MQ_REGS;
1890 rs6000_regno_regclass[LR_REGNO] = LINK_REGS;
1891 rs6000_regno_regclass[CTR_REGNO] = CTR_REGS;
1892 rs6000_regno_regclass[XER_REGNO] = XER_REGS;
1893 rs6000_regno_regclass[VRSAVE_REGNO] = VRSAVE_REGS;
1894 rs6000_regno_regclass[VSCR_REGNO] = VRSAVE_REGS;
1895 rs6000_regno_regclass[SPE_ACC_REGNO] = SPE_ACC_REGS;
1896 rs6000_regno_regclass[SPEFSCR_REGNO] = SPEFSCR_REGS;
1897 rs6000_regno_regclass[ARG_POINTER_REGNUM] = BASE_REGS;
1898 rs6000_regno_regclass[FRAME_POINTER_REGNUM] = BASE_REGS;
1900 /* Precalculate vector information, this must be set up before the
1901 rs6000_hard_regno_nregs_internal below. */
1902 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1904 rs6000_vector_unit[m] = rs6000_vector_mem[m] = VECTOR_NONE;
1905 rs6000_vector_reload[m][0] = CODE_FOR_nothing;
1906 rs6000_vector_reload[m][1] = CODE_FOR_nothing;
1909 for (c = 0; c < (int)(int)RS6000_CONSTRAINT_MAX; c++)
1910 rs6000_constraints[c] = NO_REGS;
1912 /* The VSX hardware allows native alignment for vectors, but control whether the compiler
1913 believes it can use native alignment or still uses 128-bit alignment. */
1914 if (TARGET_VSX && !TARGET_VSX_ALIGN_128)
1916 align64 = 64;
1917 align32 = 32;
1919 else
1921 align64 = 128;
1922 align32 = 128;
1925 /* V2DF mode, VSX only. */
1926 if (TARGET_VSX)
1928 rs6000_vector_unit[V2DFmode] = VECTOR_VSX;
1929 rs6000_vector_mem[V2DFmode] = VECTOR_VSX;
1930 rs6000_vector_align[V2DFmode] = align64;
1933 /* V4SF mode, either VSX or Altivec. */
1934 if (TARGET_VSX)
1936 rs6000_vector_unit[V4SFmode] = VECTOR_VSX;
1937 rs6000_vector_mem[V4SFmode] = VECTOR_VSX;
1938 rs6000_vector_align[V4SFmode] = align32;
1940 else if (TARGET_ALTIVEC)
1942 rs6000_vector_unit[V4SFmode] = VECTOR_ALTIVEC;
1943 rs6000_vector_mem[V4SFmode] = VECTOR_ALTIVEC;
1944 rs6000_vector_align[V4SFmode] = align32;
1947 /* V16QImode, V8HImode, V4SImode are Altivec only, but possibly do VSX loads
1948 and stores. */
1949 if (TARGET_ALTIVEC)
1951 rs6000_vector_unit[V4SImode] = VECTOR_ALTIVEC;
1952 rs6000_vector_unit[V8HImode] = VECTOR_ALTIVEC;
1953 rs6000_vector_unit[V16QImode] = VECTOR_ALTIVEC;
1954 rs6000_vector_align[V4SImode] = align32;
1955 rs6000_vector_align[V8HImode] = align32;
1956 rs6000_vector_align[V16QImode] = align32;
1958 if (TARGET_VSX)
1960 rs6000_vector_mem[V4SImode] = VECTOR_VSX;
1961 rs6000_vector_mem[V8HImode] = VECTOR_VSX;
1962 rs6000_vector_mem[V16QImode] = VECTOR_VSX;
1964 else
1966 rs6000_vector_mem[V4SImode] = VECTOR_ALTIVEC;
1967 rs6000_vector_mem[V8HImode] = VECTOR_ALTIVEC;
1968 rs6000_vector_mem[V16QImode] = VECTOR_ALTIVEC;
1972 /* V2DImode, only allow under VSX, which can do V2DI insert/splat/extract.
1973 Altivec doesn't have 64-bit support. */
1974 if (TARGET_VSX)
1976 rs6000_vector_mem[V2DImode] = VECTOR_VSX;
1977 rs6000_vector_unit[V2DImode] = VECTOR_NONE;
1978 rs6000_vector_align[V2DImode] = align64;
1981 /* DFmode, see if we want to use the VSX unit. */
1982 if (TARGET_VSX && TARGET_VSX_SCALAR_DOUBLE)
1984 rs6000_vector_unit[DFmode] = VECTOR_VSX;
1985 rs6000_vector_mem[DFmode]
1986 = (TARGET_VSX_SCALAR_MEMORY ? VECTOR_VSX : VECTOR_NONE);
1987 rs6000_vector_align[DFmode] = align64;
1990 /* TODO add SPE and paired floating point vector support. */
1992 /* Register class constaints for the constraints that depend on compile
1993 switches. */
1994 if (TARGET_HARD_FLOAT && TARGET_FPRS)
1995 rs6000_constraints[RS6000_CONSTRAINT_f] = FLOAT_REGS;
1997 if (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
1998 rs6000_constraints[RS6000_CONSTRAINT_d] = FLOAT_REGS;
2000 if (TARGET_VSX)
2002 /* At present, we just use VSX_REGS, but we have different constraints
2003 based on the use, in case we want to fine tune the default register
2004 class used. wa = any VSX register, wf = register class to use for
2005 V4SF, wd = register class to use for V2DF, and ws = register classs to
2006 use for DF scalars. */
2007 rs6000_constraints[RS6000_CONSTRAINT_wa] = VSX_REGS;
2008 rs6000_constraints[RS6000_CONSTRAINT_wf] = VSX_REGS;
2009 rs6000_constraints[RS6000_CONSTRAINT_wd] = VSX_REGS;
2010 if (TARGET_VSX_SCALAR_DOUBLE)
2011 rs6000_constraints[RS6000_CONSTRAINT_ws] = VSX_REGS;
2014 if (TARGET_ALTIVEC)
2015 rs6000_constraints[RS6000_CONSTRAINT_v] = ALTIVEC_REGS;
2017 /* Set up the reload helper functions. */
2018 if (TARGET_VSX || TARGET_ALTIVEC)
2020 if (TARGET_64BIT)
2022 rs6000_vector_reload[V16QImode][0] = CODE_FOR_reload_v16qi_di_store;
2023 rs6000_vector_reload[V16QImode][1] = CODE_FOR_reload_v16qi_di_load;
2024 rs6000_vector_reload[V8HImode][0] = CODE_FOR_reload_v8hi_di_store;
2025 rs6000_vector_reload[V8HImode][1] = CODE_FOR_reload_v8hi_di_load;
2026 rs6000_vector_reload[V4SImode][0] = CODE_FOR_reload_v4si_di_store;
2027 rs6000_vector_reload[V4SImode][1] = CODE_FOR_reload_v4si_di_load;
2028 rs6000_vector_reload[V2DImode][0] = CODE_FOR_reload_v2di_di_store;
2029 rs6000_vector_reload[V2DImode][1] = CODE_FOR_reload_v2di_di_load;
2030 rs6000_vector_reload[V4SFmode][0] = CODE_FOR_reload_v4sf_di_store;
2031 rs6000_vector_reload[V4SFmode][1] = CODE_FOR_reload_v4sf_di_load;
2032 rs6000_vector_reload[V2DFmode][0] = CODE_FOR_reload_v2df_di_store;
2033 rs6000_vector_reload[V2DFmode][1] = CODE_FOR_reload_v2df_di_load;
2035 else
2037 rs6000_vector_reload[V16QImode][0] = CODE_FOR_reload_v16qi_si_store;
2038 rs6000_vector_reload[V16QImode][1] = CODE_FOR_reload_v16qi_si_load;
2039 rs6000_vector_reload[V8HImode][0] = CODE_FOR_reload_v8hi_si_store;
2040 rs6000_vector_reload[V8HImode][1] = CODE_FOR_reload_v8hi_si_load;
2041 rs6000_vector_reload[V4SImode][0] = CODE_FOR_reload_v4si_si_store;
2042 rs6000_vector_reload[V4SImode][1] = CODE_FOR_reload_v4si_si_load;
2043 rs6000_vector_reload[V2DImode][0] = CODE_FOR_reload_v2di_si_store;
2044 rs6000_vector_reload[V2DImode][1] = CODE_FOR_reload_v2di_si_load;
2045 rs6000_vector_reload[V4SFmode][0] = CODE_FOR_reload_v4sf_si_store;
2046 rs6000_vector_reload[V4SFmode][1] = CODE_FOR_reload_v4sf_si_load;
2047 rs6000_vector_reload[V2DFmode][0] = CODE_FOR_reload_v2df_si_store;
2048 rs6000_vector_reload[V2DFmode][1] = CODE_FOR_reload_v2df_si_load;
2052 /* Precalculate HARD_REGNO_NREGS. */
2053 for (r = 0; r < FIRST_PSEUDO_REGISTER; ++r)
2054 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2055 rs6000_hard_regno_nregs[m][r]
2056 = rs6000_hard_regno_nregs_internal (r, (enum machine_mode)m);
2058 /* Precalculate HARD_REGNO_MODE_OK. */
2059 for (r = 0; r < FIRST_PSEUDO_REGISTER; ++r)
2060 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2061 if (rs6000_hard_regno_mode_ok (r, (enum machine_mode)m))
2062 rs6000_hard_regno_mode_ok_p[m][r] = true;
2064 /* Precalculate CLASS_MAX_NREGS sizes. */
2065 for (c = 0; c < LIM_REG_CLASSES; ++c)
2067 int reg_size;
2069 if (TARGET_VSX && VSX_REG_CLASS_P (c))
2070 reg_size = UNITS_PER_VSX_WORD;
2072 else if (c == ALTIVEC_REGS)
2073 reg_size = UNITS_PER_ALTIVEC_WORD;
2075 else if (c == FLOAT_REGS)
2076 reg_size = UNITS_PER_FP_WORD;
2078 else
2079 reg_size = UNITS_PER_WORD;
2081 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2082 rs6000_class_max_nregs[m][c]
2083 = (GET_MODE_SIZE (m) + reg_size - 1) / reg_size;
2086 if (TARGET_E500_DOUBLE)
2087 rs6000_class_max_nregs[DFmode][GENERAL_REGS] = 1;
2089 if (TARGET_DEBUG_REG)
2090 rs6000_debug_reg_global ();
2093 #if TARGET_MACHO
2094 /* The Darwin version of SUBTARGET_OVERRIDE_OPTIONS. */
2096 static void
2097 darwin_rs6000_override_options (void)
2099 /* The Darwin ABI always includes AltiVec, can't be (validly) turned
2100 off. */
2101 rs6000_altivec_abi = 1;
2102 TARGET_ALTIVEC_VRSAVE = 1;
2103 if (DEFAULT_ABI == ABI_DARWIN)
2105 if (MACHO_DYNAMIC_NO_PIC_P)
2107 if (flag_pic)
2108 warning (0, "-mdynamic-no-pic overrides -fpic or -fPIC");
2109 flag_pic = 0;
2111 else if (flag_pic == 1)
2113 flag_pic = 2;
2116 if (TARGET_64BIT && ! TARGET_POWERPC64)
2118 target_flags |= MASK_POWERPC64;
2119 warning (0, "-m64 requires PowerPC64 architecture, enabling");
2121 if (flag_mkernel)
2123 rs6000_default_long_calls = 1;
2124 target_flags |= MASK_SOFT_FLOAT;
2127 /* Make -m64 imply -maltivec. Darwin's 64-bit ABI includes
2128 Altivec. */
2129 if (!flag_mkernel && !flag_apple_kext
2130 && TARGET_64BIT
2131 && ! (target_flags_explicit & MASK_ALTIVEC))
2132 target_flags |= MASK_ALTIVEC;
2134 /* Unless the user (not the configurer) has explicitly overridden
2135 it with -mcpu=G3 or -mno-altivec, then 10.5+ targets default to
2136 G4 unless targetting the kernel. */
2137 if (!flag_mkernel
2138 && !flag_apple_kext
2139 && strverscmp (darwin_macosx_version_min, "10.5") >= 0
2140 && ! (target_flags_explicit & MASK_ALTIVEC)
2141 && ! rs6000_select[1].string)
2143 target_flags |= MASK_ALTIVEC;
2146 #endif
2148 /* If not otherwise specified by a target, make 'long double' equivalent to
2149 'double'. */
2151 #ifndef RS6000_DEFAULT_LONG_DOUBLE_SIZE
2152 #define RS6000_DEFAULT_LONG_DOUBLE_SIZE 64
2153 #endif
2155 /* Override command line options. Mostly we process the processor
2156 type and sometimes adjust other TARGET_ options. */
2158 void
2159 rs6000_override_options (const char *default_cpu)
2161 size_t i, j;
2162 struct rs6000_cpu_select *ptr;
2163 int set_masks;
2165 /* Simplifications for entries below. */
2167 enum {
2168 POWERPC_BASE_MASK = MASK_POWERPC | MASK_NEW_MNEMONICS,
2169 POWERPC_7400_MASK = POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_ALTIVEC
2172 /* This table occasionally claims that a processor does not support
2173 a particular feature even though it does, but the feature is slower
2174 than the alternative. Thus, it shouldn't be relied on as a
2175 complete description of the processor's support.
2177 Please keep this list in order, and don't forget to update the
2178 documentation in invoke.texi when adding a new processor or
2179 flag. */
2180 static struct ptt
2182 const char *const name; /* Canonical processor name. */
2183 const enum processor_type processor; /* Processor type enum value. */
2184 const int target_enable; /* Target flags to enable. */
2185 } const processor_target_table[]
2186 = {{"401", PROCESSOR_PPC403, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2187 {"403", PROCESSOR_PPC403,
2188 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_STRICT_ALIGN},
2189 {"405", PROCESSOR_PPC405,
2190 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
2191 {"405fp", PROCESSOR_PPC405,
2192 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
2193 {"440", PROCESSOR_PPC440,
2194 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
2195 {"440fp", PROCESSOR_PPC440,
2196 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
2197 {"464", PROCESSOR_PPC440,
2198 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
2199 {"464fp", PROCESSOR_PPC440,
2200 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
2201 {"476", PROCESSOR_PPC476,
2202 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_PPC_GFXOPT | MASK_MFCRF
2203 | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_MULHW | MASK_DLMZB},
2204 {"476fp", PROCESSOR_PPC476,
2205 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_MFCRF | MASK_POPCNTB
2206 | MASK_FPRND | MASK_CMPB | MASK_MULHW | MASK_DLMZB},
2207 {"505", PROCESSOR_MPCCORE, POWERPC_BASE_MASK},
2208 {"601", PROCESSOR_PPC601,
2209 MASK_POWER | POWERPC_BASE_MASK | MASK_MULTIPLE | MASK_STRING},
2210 {"602", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2211 {"603", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2212 {"603e", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2213 {"604", PROCESSOR_PPC604, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2214 {"604e", PROCESSOR_PPC604e, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2215 {"620", PROCESSOR_PPC620,
2216 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
2217 {"630", PROCESSOR_PPC630,
2218 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
2219 {"740", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2220 {"7400", PROCESSOR_PPC7400, POWERPC_7400_MASK},
2221 {"7450", PROCESSOR_PPC7450, POWERPC_7400_MASK},
2222 {"750", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2223 {"801", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2224 {"821", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2225 {"823", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2226 {"8540", PROCESSOR_PPC8540, POWERPC_BASE_MASK | MASK_STRICT_ALIGN
2227 | MASK_ISEL},
2228 /* 8548 has a dummy entry for now. */
2229 {"8548", PROCESSOR_PPC8540, POWERPC_BASE_MASK | MASK_STRICT_ALIGN
2230 | MASK_ISEL},
2231 {"a2", PROCESSOR_PPCA2,
2232 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64 | MASK_POPCNTB
2233 | MASK_CMPB | MASK_NO_UPDATE },
2234 {"e300c2", PROCESSOR_PPCE300C2, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2235 {"e300c3", PROCESSOR_PPCE300C3, POWERPC_BASE_MASK},
2236 {"e500mc", PROCESSOR_PPCE500MC, POWERPC_BASE_MASK | MASK_PPC_GFXOPT
2237 | MASK_ISEL},
2238 {"e500mc64", PROCESSOR_PPCE500MC64, POWERPC_BASE_MASK | MASK_POWERPC64
2239 | MASK_PPC_GFXOPT | MASK_ISEL},
2240 {"860", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2241 {"970", PROCESSOR_POWER4,
2242 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
2243 {"cell", PROCESSOR_CELL,
2244 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
2245 {"common", PROCESSOR_COMMON, MASK_NEW_MNEMONICS},
2246 {"ec603e", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2247 {"G3", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2248 {"G4", PROCESSOR_PPC7450, POWERPC_7400_MASK},
2249 {"G5", PROCESSOR_POWER4,
2250 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
2251 {"power", PROCESSOR_POWER, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2252 {"power2", PROCESSOR_POWER,
2253 MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING},
2254 {"power3", PROCESSOR_PPC630,
2255 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
2256 {"power4", PROCESSOR_POWER4,
2257 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2258 | MASK_MFCRF},
2259 {"power5", PROCESSOR_POWER5,
2260 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2261 | MASK_MFCRF | MASK_POPCNTB},
2262 {"power5+", PROCESSOR_POWER5,
2263 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2264 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND},
2265 {"power6", PROCESSOR_POWER6,
2266 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2267 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP},
2268 {"power6x", PROCESSOR_POWER6,
2269 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2270 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP
2271 | MASK_MFPGPR},
2272 {"power7", PROCESSOR_POWER7,
2273 POWERPC_7400_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_MFCRF
2274 | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP | MASK_POPCNTD
2275 | MASK_VSX}, /* Don't add MASK_ISEL by default */
2276 {"powerpc", PROCESSOR_POWERPC, POWERPC_BASE_MASK},
2277 {"powerpc64", PROCESSOR_POWERPC64,
2278 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
2279 {"rios", PROCESSOR_RIOS1, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2280 {"rios1", PROCESSOR_RIOS1, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2281 {"rios2", PROCESSOR_RIOS2,
2282 MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING},
2283 {"rsc", PROCESSOR_PPC601, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2284 {"rsc1", PROCESSOR_PPC601, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2285 {"rs64", PROCESSOR_RS64A,
2286 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64}
2289 const size_t ptt_size = ARRAY_SIZE (processor_target_table);
2291 /* Some OSs don't support saving the high part of 64-bit registers on
2292 context switch. Other OSs don't support saving Altivec registers.
2293 On those OSs, we don't touch the MASK_POWERPC64 or MASK_ALTIVEC
2294 settings; if the user wants either, the user must explicitly specify
2295 them and we won't interfere with the user's specification. */
2297 enum {
2298 POWER_MASKS = MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING,
2299 POWERPC_MASKS = (POWERPC_BASE_MASK | MASK_PPC_GPOPT | MASK_STRICT_ALIGN
2300 | MASK_PPC_GFXOPT | MASK_POWERPC64 | MASK_ALTIVEC
2301 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_MULHW
2302 | MASK_DLMZB | MASK_CMPB | MASK_MFPGPR | MASK_DFP
2303 | MASK_POPCNTD | MASK_VSX | MASK_ISEL | MASK_NO_UPDATE)
2306 /* Numerous experiment shows that IRA based loop pressure
2307 calculation works better for RTL loop invariant motion on targets
2308 with enough (>= 32) registers. It is an expensive optimization.
2309 So it is on only for peak performance. */
2310 if (optimize >= 3)
2311 flag_ira_loop_pressure = 1;
2313 /* Set the pointer size. */
2314 if (TARGET_64BIT)
2316 rs6000_pmode = (int)DImode;
2317 rs6000_pointer_size = 64;
2319 else
2321 rs6000_pmode = (int)SImode;
2322 rs6000_pointer_size = 32;
2325 set_masks = POWER_MASKS | POWERPC_MASKS | MASK_SOFT_FLOAT;
2326 #ifdef OS_MISSING_POWERPC64
2327 if (OS_MISSING_POWERPC64)
2328 set_masks &= ~MASK_POWERPC64;
2329 #endif
2330 #ifdef OS_MISSING_ALTIVEC
2331 if (OS_MISSING_ALTIVEC)
2332 set_masks &= ~MASK_ALTIVEC;
2333 #endif
2335 /* Don't override by the processor default if given explicitly. */
2336 set_masks &= ~target_flags_explicit;
2338 /* Identify the processor type. */
2339 rs6000_select[0].string = default_cpu;
2340 rs6000_cpu = TARGET_POWERPC64 ? PROCESSOR_DEFAULT64 : PROCESSOR_DEFAULT;
2342 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
2344 ptr = &rs6000_select[i];
2345 if (ptr->string != (char *)0 && ptr->string[0] != '\0')
2347 for (j = 0; j < ptt_size; j++)
2348 if (! strcmp (ptr->string, processor_target_table[j].name))
2350 if (ptr->set_tune_p)
2351 rs6000_cpu = processor_target_table[j].processor;
2353 if (ptr->set_arch_p)
2355 target_flags &= ~set_masks;
2356 target_flags |= (processor_target_table[j].target_enable
2357 & set_masks);
2359 break;
2362 if (j == ptt_size)
2363 error ("bad value (%s) for %s switch", ptr->string, ptr->name);
2367 if (rs6000_cpu == PROCESSOR_PPCE300C2 || rs6000_cpu == PROCESSOR_PPCE300C3
2368 || rs6000_cpu == PROCESSOR_PPCE500MC || rs6000_cpu == PROCESSOR_PPCE500MC64)
2370 if (TARGET_ALTIVEC)
2371 error ("AltiVec not supported in this target");
2372 if (TARGET_SPE)
2373 error ("Spe not supported in this target");
2376 /* Disable Cell microcode if we are optimizing for the Cell
2377 and not optimizing for size. */
2378 if (rs6000_gen_cell_microcode == -1)
2379 rs6000_gen_cell_microcode = !(rs6000_cpu == PROCESSOR_CELL
2380 && !optimize_size);
2382 /* If we are optimizing big endian systems for space and it's OK to
2383 use instructions that would be microcoded on the Cell, use the
2384 load/store multiple and string instructions. */
2385 if (BYTES_BIG_ENDIAN && optimize_size && rs6000_gen_cell_microcode)
2386 target_flags |= ~target_flags_explicit & (MASK_MULTIPLE | MASK_STRING);
2388 /* Don't allow -mmultiple or -mstring on little endian systems
2389 unless the cpu is a 750, because the hardware doesn't support the
2390 instructions used in little endian mode, and causes an alignment
2391 trap. The 750 does not cause an alignment trap (except when the
2392 target is unaligned). */
2394 if (!BYTES_BIG_ENDIAN && rs6000_cpu != PROCESSOR_PPC750)
2396 if (TARGET_MULTIPLE)
2398 target_flags &= ~MASK_MULTIPLE;
2399 if ((target_flags_explicit & MASK_MULTIPLE) != 0)
2400 warning (0, "-mmultiple is not supported on little endian systems");
2403 if (TARGET_STRING)
2405 target_flags &= ~MASK_STRING;
2406 if ((target_flags_explicit & MASK_STRING) != 0)
2407 warning (0, "-mstring is not supported on little endian systems");
2411 /* Add some warnings for VSX. */
2412 if (TARGET_VSX)
2414 const char *msg = NULL;
2415 if (!TARGET_HARD_FLOAT || !TARGET_FPRS
2416 || !TARGET_SINGLE_FLOAT || !TARGET_DOUBLE_FLOAT)
2418 if (target_flags_explicit & MASK_VSX)
2419 msg = N_("-mvsx requires hardware floating point");
2420 else
2421 target_flags &= ~ MASK_VSX;
2423 else if (TARGET_PAIRED_FLOAT)
2424 msg = N_("-mvsx and -mpaired are incompatible");
2425 /* The hardware will allow VSX and little endian, but until we make sure
2426 things like vector select, etc. work don't allow VSX on little endian
2427 systems at this point. */
2428 else if (!BYTES_BIG_ENDIAN)
2429 msg = N_("-mvsx used with little endian code");
2430 else if (TARGET_AVOID_XFORM > 0)
2431 msg = N_("-mvsx needs indexed addressing");
2432 else if (!TARGET_ALTIVEC && (target_flags_explicit & MASK_ALTIVEC))
2434 if (target_flags_explicit & MASK_VSX)
2435 msg = N_("-mvsx and -mno-altivec are incompatible");
2436 else
2437 msg = N_("-mno-altivec disables vsx");
2440 if (msg)
2442 warning (0, msg);
2443 target_flags &= ~ MASK_VSX;
2445 else if (TARGET_VSX && !TARGET_ALTIVEC)
2446 target_flags |= MASK_ALTIVEC;
2449 /* Set debug flags */
2450 if (rs6000_debug_name)
2452 if (! strcmp (rs6000_debug_name, "all"))
2453 rs6000_debug_stack = rs6000_debug_arg = rs6000_debug_reg
2454 = rs6000_debug_addr = rs6000_debug_cost = 1;
2455 else if (! strcmp (rs6000_debug_name, "stack"))
2456 rs6000_debug_stack = 1;
2457 else if (! strcmp (rs6000_debug_name, "arg"))
2458 rs6000_debug_arg = 1;
2459 else if (! strcmp (rs6000_debug_name, "reg"))
2460 rs6000_debug_reg = 1;
2461 else if (! strcmp (rs6000_debug_name, "addr"))
2462 rs6000_debug_addr = 1;
2463 else if (! strcmp (rs6000_debug_name, "cost"))
2464 rs6000_debug_cost = 1;
2465 else
2466 error ("unknown -mdebug-%s switch", rs6000_debug_name);
2468 /* If the appropriate debug option is enabled, replace the target hooks
2469 with debug versions that call the real version and then prints
2470 debugging information. */
2471 if (TARGET_DEBUG_COST)
2473 targetm.rtx_costs = rs6000_debug_rtx_costs;
2474 targetm.address_cost = rs6000_debug_address_cost;
2475 targetm.sched.adjust_cost = rs6000_debug_adjust_cost;
2478 if (TARGET_DEBUG_ADDR)
2480 targetm.legitimate_address_p = rs6000_debug_legitimate_address_p;
2481 targetm.legitimize_address = rs6000_debug_legitimize_address;
2482 rs6000_secondary_reload_class_ptr
2483 = rs6000_debug_secondary_reload_class;
2484 rs6000_secondary_memory_needed_ptr
2485 = rs6000_debug_secondary_memory_needed;
2486 rs6000_cannot_change_mode_class_ptr
2487 = rs6000_debug_cannot_change_mode_class;
2488 rs6000_preferred_reload_class_ptr
2489 = rs6000_debug_preferred_reload_class;
2490 rs6000_legitimize_reload_address_ptr
2491 = rs6000_debug_legitimize_reload_address;
2492 rs6000_mode_dependent_address_ptr
2493 = rs6000_debug_mode_dependent_address;
2497 if (rs6000_traceback_name)
2499 if (! strncmp (rs6000_traceback_name, "full", 4))
2500 rs6000_traceback = traceback_full;
2501 else if (! strncmp (rs6000_traceback_name, "part", 4))
2502 rs6000_traceback = traceback_part;
2503 else if (! strncmp (rs6000_traceback_name, "no", 2))
2504 rs6000_traceback = traceback_none;
2505 else
2506 error ("unknown -mtraceback arg %qs; expecting %<full%>, %<partial%> or %<none%>",
2507 rs6000_traceback_name);
2510 if (!rs6000_explicit_options.long_double)
2511 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
2513 #ifndef POWERPC_LINUX
2514 if (!rs6000_explicit_options.ieee)
2515 rs6000_ieeequad = 1;
2516 #endif
2518 /* Enable Altivec ABI for AIX -maltivec. */
2519 if (TARGET_XCOFF && (TARGET_ALTIVEC || TARGET_VSX))
2520 rs6000_altivec_abi = 1;
2522 /* The AltiVec ABI is the default for PowerPC-64 GNU/Linux. For
2523 PowerPC-32 GNU/Linux, -maltivec implies the AltiVec ABI. It can
2524 be explicitly overridden in either case. */
2525 if (TARGET_ELF)
2527 if (!rs6000_explicit_options.altivec_abi
2528 && (TARGET_64BIT || TARGET_ALTIVEC || TARGET_VSX))
2529 rs6000_altivec_abi = 1;
2531 /* Enable VRSAVE for AltiVec ABI, unless explicitly overridden. */
2532 if (!rs6000_explicit_options.vrsave)
2533 TARGET_ALTIVEC_VRSAVE = rs6000_altivec_abi;
2536 /* Set the Darwin64 ABI as default for 64-bit Darwin. */
2537 if (DEFAULT_ABI == ABI_DARWIN && TARGET_64BIT)
2539 rs6000_darwin64_abi = 1;
2540 #if TARGET_MACHO
2541 darwin_one_byte_bool = 1;
2542 #endif
2543 /* Default to natural alignment, for better performance. */
2544 rs6000_alignment_flags = MASK_ALIGN_NATURAL;
2547 /* Place FP constants in the constant pool instead of TOC
2548 if section anchors enabled. */
2549 if (flag_section_anchors)
2550 TARGET_NO_FP_IN_TOC = 1;
2552 /* Handle -mtls-size option. */
2553 rs6000_parse_tls_size_option ();
2555 #ifdef SUBTARGET_OVERRIDE_OPTIONS
2556 SUBTARGET_OVERRIDE_OPTIONS;
2557 #endif
2558 #ifdef SUBSUBTARGET_OVERRIDE_OPTIONS
2559 SUBSUBTARGET_OVERRIDE_OPTIONS;
2560 #endif
2561 #ifdef SUB3TARGET_OVERRIDE_OPTIONS
2562 SUB3TARGET_OVERRIDE_OPTIONS;
2563 #endif
2565 if (TARGET_E500 || rs6000_cpu == PROCESSOR_PPCE500MC
2566 || rs6000_cpu == PROCESSOR_PPCE500MC64)
2568 /* The e500 and e500mc do not have string instructions, and we set
2569 MASK_STRING above when optimizing for size. */
2570 if ((target_flags & MASK_STRING) != 0)
2571 target_flags = target_flags & ~MASK_STRING;
2573 else if (rs6000_select[1].string != NULL)
2575 /* For the powerpc-eabispe configuration, we set all these by
2576 default, so let's unset them if we manually set another
2577 CPU that is not the E500. */
2578 if (!rs6000_explicit_options.spe_abi)
2579 rs6000_spe_abi = 0;
2580 if (!rs6000_explicit_options.spe)
2581 rs6000_spe = 0;
2582 if (!rs6000_explicit_options.float_gprs)
2583 rs6000_float_gprs = 0;
2584 if (!(target_flags_explicit & MASK_ISEL))
2585 target_flags &= ~MASK_ISEL;
2588 /* Detect invalid option combinations with E500. */
2589 CHECK_E500_OPTIONS;
2591 rs6000_always_hint = (rs6000_cpu != PROCESSOR_POWER4
2592 && rs6000_cpu != PROCESSOR_POWER5
2593 && rs6000_cpu != PROCESSOR_POWER6
2594 && rs6000_cpu != PROCESSOR_POWER7
2595 && rs6000_cpu != PROCESSOR_PPCA2
2596 && rs6000_cpu != PROCESSOR_CELL);
2597 rs6000_sched_groups = (rs6000_cpu == PROCESSOR_POWER4
2598 || rs6000_cpu == PROCESSOR_POWER5
2599 || rs6000_cpu == PROCESSOR_POWER7);
2600 rs6000_align_branch_targets = (rs6000_cpu == PROCESSOR_POWER4
2601 || rs6000_cpu == PROCESSOR_POWER5
2602 || rs6000_cpu == PROCESSOR_POWER6
2603 || rs6000_cpu == PROCESSOR_POWER7
2604 || rs6000_cpu == PROCESSOR_PPCE500MC
2605 || rs6000_cpu == PROCESSOR_PPCE500MC64);
2607 /* Allow debug switches to override the above settings. */
2608 if (TARGET_ALWAYS_HINT > 0)
2609 rs6000_always_hint = TARGET_ALWAYS_HINT;
2611 if (TARGET_SCHED_GROUPS > 0)
2612 rs6000_sched_groups = TARGET_SCHED_GROUPS;
2614 if (TARGET_ALIGN_BRANCH_TARGETS > 0)
2615 rs6000_align_branch_targets = TARGET_ALIGN_BRANCH_TARGETS;
2617 rs6000_sched_restricted_insns_priority
2618 = (rs6000_sched_groups ? 1 : 0);
2620 /* Handle -msched-costly-dep option. */
2621 rs6000_sched_costly_dep
2622 = (rs6000_sched_groups ? store_to_load_dep_costly : no_dep_costly);
2624 if (rs6000_sched_costly_dep_str)
2626 if (! strcmp (rs6000_sched_costly_dep_str, "no"))
2627 rs6000_sched_costly_dep = no_dep_costly;
2628 else if (! strcmp (rs6000_sched_costly_dep_str, "all"))
2629 rs6000_sched_costly_dep = all_deps_costly;
2630 else if (! strcmp (rs6000_sched_costly_dep_str, "true_store_to_load"))
2631 rs6000_sched_costly_dep = true_store_to_load_dep_costly;
2632 else if (! strcmp (rs6000_sched_costly_dep_str, "store_to_load"))
2633 rs6000_sched_costly_dep = store_to_load_dep_costly;
2634 else
2635 rs6000_sched_costly_dep = ((enum rs6000_dependence_cost)
2636 atoi (rs6000_sched_costly_dep_str));
2639 /* Handle -minsert-sched-nops option. */
2640 rs6000_sched_insert_nops
2641 = (rs6000_sched_groups ? sched_finish_regroup_exact : sched_finish_none);
2643 if (rs6000_sched_insert_nops_str)
2645 if (! strcmp (rs6000_sched_insert_nops_str, "no"))
2646 rs6000_sched_insert_nops = sched_finish_none;
2647 else if (! strcmp (rs6000_sched_insert_nops_str, "pad"))
2648 rs6000_sched_insert_nops = sched_finish_pad_groups;
2649 else if (! strcmp (rs6000_sched_insert_nops_str, "regroup_exact"))
2650 rs6000_sched_insert_nops = sched_finish_regroup_exact;
2651 else
2652 rs6000_sched_insert_nops = ((enum rs6000_nop_insertion)
2653 atoi (rs6000_sched_insert_nops_str));
2656 #ifdef TARGET_REGNAMES
2657 /* If the user desires alternate register names, copy in the
2658 alternate names now. */
2659 if (TARGET_REGNAMES)
2660 memcpy (rs6000_reg_names, alt_reg_names, sizeof (rs6000_reg_names));
2661 #endif
2663 /* Set aix_struct_return last, after the ABI is determined.
2664 If -maix-struct-return or -msvr4-struct-return was explicitly
2665 used, don't override with the ABI default. */
2666 if (!rs6000_explicit_options.aix_struct_ret)
2667 aix_struct_return = (DEFAULT_ABI != ABI_V4 || DRAFT_V4_STRUCT_RET);
2669 if (TARGET_LONG_DOUBLE_128 && !TARGET_IEEEQUAD)
2670 REAL_MODE_FORMAT (TFmode) = &ibm_extended_format;
2672 if (TARGET_TOC)
2673 ASM_GENERATE_INTERNAL_LABEL (toc_label_name, "LCTOC", 1);
2675 /* We can only guarantee the availability of DI pseudo-ops when
2676 assembling for 64-bit targets. */
2677 if (!TARGET_64BIT)
2679 targetm.asm_out.aligned_op.di = NULL;
2680 targetm.asm_out.unaligned_op.di = NULL;
2683 /* Set branch target alignment, if not optimizing for size. */
2684 if (!optimize_size)
2686 /* Cell wants to be aligned 8byte for dual issue. */
2687 if (rs6000_cpu == PROCESSOR_CELL)
2689 if (align_functions <= 0)
2690 align_functions = 8;
2691 if (align_jumps <= 0)
2692 align_jumps = 8;
2693 if (align_loops <= 0)
2694 align_loops = 8;
2696 if (rs6000_align_branch_targets)
2698 if (align_functions <= 0)
2699 align_functions = 16;
2700 if (align_jumps <= 0)
2701 align_jumps = 16;
2702 if (align_loops <= 0)
2703 align_loops = 16;
2705 if (align_jumps_max_skip <= 0)
2706 align_jumps_max_skip = 15;
2707 if (align_loops_max_skip <= 0)
2708 align_loops_max_skip = 15;
2711 /* Arrange to save and restore machine status around nested functions. */
2712 init_machine_status = rs6000_init_machine_status;
2714 /* We should always be splitting complex arguments, but we can't break
2715 Linux and Darwin ABIs at the moment. For now, only AIX is fixed. */
2716 if (DEFAULT_ABI != ABI_AIX)
2717 targetm.calls.split_complex_arg = NULL;
2719 /* Initialize rs6000_cost with the appropriate target costs. */
2720 if (optimize_size)
2721 rs6000_cost = TARGET_POWERPC64 ? &size64_cost : &size32_cost;
2722 else
2723 switch (rs6000_cpu)
2725 case PROCESSOR_RIOS1:
2726 rs6000_cost = &rios1_cost;
2727 break;
2729 case PROCESSOR_RIOS2:
2730 rs6000_cost = &rios2_cost;
2731 break;
2733 case PROCESSOR_RS64A:
2734 rs6000_cost = &rs64a_cost;
2735 break;
2737 case PROCESSOR_MPCCORE:
2738 rs6000_cost = &mpccore_cost;
2739 break;
2741 case PROCESSOR_PPC403:
2742 rs6000_cost = &ppc403_cost;
2743 break;
2745 case PROCESSOR_PPC405:
2746 rs6000_cost = &ppc405_cost;
2747 break;
2749 case PROCESSOR_PPC440:
2750 rs6000_cost = &ppc440_cost;
2751 break;
2753 case PROCESSOR_PPC476:
2754 rs6000_cost = &ppc476_cost;
2755 break;
2757 case PROCESSOR_PPC601:
2758 rs6000_cost = &ppc601_cost;
2759 break;
2761 case PROCESSOR_PPC603:
2762 rs6000_cost = &ppc603_cost;
2763 break;
2765 case PROCESSOR_PPC604:
2766 rs6000_cost = &ppc604_cost;
2767 break;
2769 case PROCESSOR_PPC604e:
2770 rs6000_cost = &ppc604e_cost;
2771 break;
2773 case PROCESSOR_PPC620:
2774 rs6000_cost = &ppc620_cost;
2775 break;
2777 case PROCESSOR_PPC630:
2778 rs6000_cost = &ppc630_cost;
2779 break;
2781 case PROCESSOR_CELL:
2782 rs6000_cost = &ppccell_cost;
2783 break;
2785 case PROCESSOR_PPC750:
2786 case PROCESSOR_PPC7400:
2787 rs6000_cost = &ppc750_cost;
2788 break;
2790 case PROCESSOR_PPC7450:
2791 rs6000_cost = &ppc7450_cost;
2792 break;
2794 case PROCESSOR_PPC8540:
2795 rs6000_cost = &ppc8540_cost;
2796 break;
2798 case PROCESSOR_PPCE300C2:
2799 case PROCESSOR_PPCE300C3:
2800 rs6000_cost = &ppce300c2c3_cost;
2801 break;
2803 case PROCESSOR_PPCE500MC:
2804 rs6000_cost = &ppce500mc_cost;
2805 break;
2807 case PROCESSOR_PPCE500MC64:
2808 rs6000_cost = &ppce500mc64_cost;
2809 break;
2811 case PROCESSOR_POWER4:
2812 case PROCESSOR_POWER5:
2813 rs6000_cost = &power4_cost;
2814 break;
2816 case PROCESSOR_POWER6:
2817 rs6000_cost = &power6_cost;
2818 break;
2820 case PROCESSOR_POWER7:
2821 rs6000_cost = &power7_cost;
2822 break;
2824 case PROCESSOR_PPCA2:
2825 rs6000_cost = &ppca2_cost;
2826 break;
2828 default:
2829 gcc_unreachable ();
2832 if (!PARAM_SET_P (PARAM_SIMULTANEOUS_PREFETCHES))
2833 set_param_value ("simultaneous-prefetches",
2834 rs6000_cost->simultaneous_prefetches);
2835 if (!PARAM_SET_P (PARAM_L1_CACHE_SIZE))
2836 set_param_value ("l1-cache-size", rs6000_cost->l1_cache_size);
2837 if (!PARAM_SET_P (PARAM_L1_CACHE_LINE_SIZE))
2838 set_param_value ("l1-cache-line-size", rs6000_cost->cache_line_size);
2839 if (!PARAM_SET_P (PARAM_L2_CACHE_SIZE))
2840 set_param_value ("l2-cache-size", rs6000_cost->l2_cache_size);
2842 /* If using typedef char *va_list, signal that __builtin_va_start (&ap, 0)
2843 can be optimized to ap = __builtin_next_arg (0). */
2844 if (DEFAULT_ABI != ABI_V4)
2845 targetm.expand_builtin_va_start = NULL;
2847 /* Set up single/double float flags.
2848 If TARGET_HARD_FLOAT is set, but neither single or double is set,
2849 then set both flags. */
2850 if (TARGET_HARD_FLOAT && TARGET_FPRS
2851 && rs6000_single_float == 0 && rs6000_double_float == 0)
2852 rs6000_single_float = rs6000_double_float = 1;
2854 /* Reset single and double FP flags if target is E500. */
2855 if (TARGET_E500)
2857 rs6000_single_float = rs6000_double_float = 0;
2858 if (TARGET_E500_SINGLE)
2859 rs6000_single_float = 1;
2860 if (TARGET_E500_DOUBLE)
2861 rs6000_single_float = rs6000_double_float = 1;
2864 /* If not explicitly specified via option, decide whether to generate indexed
2865 load/store instructions. */
2866 if (TARGET_AVOID_XFORM == -1)
2867 /* Avoid indexed addressing when targeting Power6 in order to avoid
2868 the DERAT mispredict penalty. */
2869 TARGET_AVOID_XFORM = (rs6000_cpu == PROCESSOR_POWER6 && TARGET_CMPB);
2871 rs6000_init_hard_regno_mode_ok ();
2874 /* Implement targetm.vectorize.builtin_mask_for_load. */
2875 static tree
2876 rs6000_builtin_mask_for_load (void)
2878 if (TARGET_ALTIVEC || TARGET_VSX)
2879 return altivec_builtin_mask_for_load;
2880 else
2881 return 0;
2884 /* Implement targetm.vectorize.builtin_conversion.
2885 Returns a decl of a function that implements conversion of an integer vector
2886 into a floating-point vector, or vice-versa. TYPE is the type of the integer
2887 side of the conversion.
2888 Return NULL_TREE if it is not available. */
2889 static tree
2890 rs6000_builtin_conversion (unsigned int tcode, tree type)
2892 enum tree_code code = (enum tree_code) tcode;
2894 switch (code)
2896 case FIX_TRUNC_EXPR:
2897 switch (TYPE_MODE (type))
2899 case V2DImode:
2900 if (!VECTOR_UNIT_VSX_P (V2DFmode))
2901 return NULL_TREE;
2903 return TYPE_UNSIGNED (type)
2904 ? rs6000_builtin_decls[VSX_BUILTIN_XVCVDPUXDS_UNS]
2905 : rs6000_builtin_decls[VSX_BUILTIN_XVCVDPSXDS];
2907 case V4SImode:
2908 if (VECTOR_UNIT_NONE_P (V4SImode) || VECTOR_UNIT_NONE_P (V4SFmode))
2909 return NULL_TREE;
2911 return TYPE_UNSIGNED (type)
2912 ? rs6000_builtin_decls[VECTOR_BUILTIN_FIXUNS_V4SF_V4SI]
2913 : rs6000_builtin_decls[VECTOR_BUILTIN_FIX_V4SF_V4SI];
2915 default:
2916 return NULL_TREE;
2919 case FLOAT_EXPR:
2920 switch (TYPE_MODE (type))
2922 case V2DImode:
2923 if (!VECTOR_UNIT_VSX_P (V2DFmode))
2924 return NULL_TREE;
2926 return TYPE_UNSIGNED (type)
2927 ? rs6000_builtin_decls[VSX_BUILTIN_XVCVUXDDP]
2928 : rs6000_builtin_decls[VSX_BUILTIN_XVCVSXDDP];
2930 case V4SImode:
2931 if (VECTOR_UNIT_NONE_P (V4SImode) || VECTOR_UNIT_NONE_P (V4SFmode))
2932 return NULL_TREE;
2934 return TYPE_UNSIGNED (type)
2935 ? rs6000_builtin_decls[VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF]
2936 : rs6000_builtin_decls[VECTOR_BUILTIN_FLOAT_V4SI_V4SF];
2938 default:
2939 return NULL_TREE;
2942 default:
2943 return NULL_TREE;
2947 /* Implement targetm.vectorize.builtin_mul_widen_even. */
2948 static tree
2949 rs6000_builtin_mul_widen_even (tree type)
2951 if (!TARGET_ALTIVEC)
2952 return NULL_TREE;
2954 switch (TYPE_MODE (type))
2956 case V8HImode:
2957 return TYPE_UNSIGNED (type)
2958 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULEUH_UNS]
2959 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULESH];
2961 case V16QImode:
2962 return TYPE_UNSIGNED (type)
2963 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULEUB_UNS]
2964 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULESB];
2965 default:
2966 return NULL_TREE;
2970 /* Implement targetm.vectorize.builtin_mul_widen_odd. */
2971 static tree
2972 rs6000_builtin_mul_widen_odd (tree type)
2974 if (!TARGET_ALTIVEC)
2975 return NULL_TREE;
2977 switch (TYPE_MODE (type))
2979 case V8HImode:
2980 return TYPE_UNSIGNED (type)
2981 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOUH_UNS]
2982 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOSH];
2984 case V16QImode:
2985 return TYPE_UNSIGNED (type)
2986 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOUB_UNS]
2987 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOSB];
2988 default:
2989 return NULL_TREE;
2994 /* Return true iff, data reference of TYPE can reach vector alignment (16)
2995 after applying N number of iterations. This routine does not determine
2996 how may iterations are required to reach desired alignment. */
2998 static bool
2999 rs6000_vector_alignment_reachable (const_tree type ATTRIBUTE_UNUSED, bool is_packed)
3001 if (is_packed)
3002 return false;
3004 if (TARGET_32BIT)
3006 if (rs6000_alignment_flags == MASK_ALIGN_NATURAL)
3007 return true;
3009 if (rs6000_alignment_flags == MASK_ALIGN_POWER)
3010 return true;
3012 return false;
3014 else
3016 if (TARGET_MACHO)
3017 return false;
3019 /* Assuming that all other types are naturally aligned. CHECKME! */
3020 return true;
3024 /* Return true if the vector misalignment factor is supported by the
3025 target. */
3026 bool
3027 rs6000_builtin_support_vector_misalignment (enum machine_mode mode,
3028 const_tree type,
3029 int misalignment,
3030 bool is_packed)
3032 if (TARGET_VSX)
3034 /* Return if movmisalign pattern is not supported for this mode. */
3035 if (optab_handler (movmisalign_optab, mode)->insn_code ==
3036 CODE_FOR_nothing)
3037 return false;
3039 if (misalignment == -1)
3041 /* misalignment factor is unknown at compile time but we know
3042 it's word aligned. */
3043 if (rs6000_vector_alignment_reachable (type, is_packed))
3044 return true;
3045 return false;
3047 /* VSX supports word-aligned vector. */
3048 if (misalignment % 4 == 0)
3049 return true;
3051 return false;
3054 /* Implement targetm.vectorize.builtin_vec_perm. */
3055 tree
3056 rs6000_builtin_vec_perm (tree type, tree *mask_element_type)
3058 tree inner_type = TREE_TYPE (type);
3059 bool uns_p = TYPE_UNSIGNED (inner_type);
3060 tree d;
3062 *mask_element_type = unsigned_char_type_node;
3064 switch (TYPE_MODE (type))
3066 case V16QImode:
3067 d = (uns_p
3068 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_16QI_UNS]
3069 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_16QI]);
3070 break;
3072 case V8HImode:
3073 d = (uns_p
3074 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_8HI_UNS]
3075 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_8HI]);
3076 break;
3078 case V4SImode:
3079 d = (uns_p
3080 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SI_UNS]
3081 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SI]);
3082 break;
3084 case V4SFmode:
3085 d = rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SF];
3086 break;
3088 case V2DFmode:
3089 if (!TARGET_ALLOW_DF_PERMUTE)
3090 return NULL_TREE;
3092 d = rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DF];
3093 break;
3095 case V2DImode:
3096 if (!TARGET_ALLOW_DF_PERMUTE)
3097 return NULL_TREE;
3099 d = (uns_p
3100 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DI_UNS]
3101 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DI]);
3102 break;
3104 default:
3105 return NULL_TREE;
3108 gcc_assert (d);
3109 return d;
3112 /* Handle generic options of the form -mfoo=yes/no.
3113 NAME is the option name.
3114 VALUE is the option value.
3115 FLAG is the pointer to the flag where to store a 1 or 0, depending on
3116 whether the option value is 'yes' or 'no' respectively. */
3117 static void
3118 rs6000_parse_yes_no_option (const char *name, const char *value, int *flag)
3120 if (value == 0)
3121 return;
3122 else if (!strcmp (value, "yes"))
3123 *flag = 1;
3124 else if (!strcmp (value, "no"))
3125 *flag = 0;
3126 else
3127 error ("unknown -m%s= option specified: '%s'", name, value);
3130 /* Validate and record the size specified with the -mtls-size option. */
3132 static void
3133 rs6000_parse_tls_size_option (void)
3135 if (rs6000_tls_size_string == 0)
3136 return;
3137 else if (strcmp (rs6000_tls_size_string, "16") == 0)
3138 rs6000_tls_size = 16;
3139 else if (strcmp (rs6000_tls_size_string, "32") == 0)
3140 rs6000_tls_size = 32;
3141 else if (strcmp (rs6000_tls_size_string, "64") == 0)
3142 rs6000_tls_size = 64;
3143 else
3144 error ("bad value %qs for -mtls-size switch", rs6000_tls_size_string);
3147 void
3148 optimization_options (int level ATTRIBUTE_UNUSED, int size ATTRIBUTE_UNUSED)
3150 if (DEFAULT_ABI == ABI_DARWIN)
3151 /* The Darwin libraries never set errno, so we might as well
3152 avoid calling them when that's the only reason we would. */
3153 flag_errno_math = 0;
3155 /* Double growth factor to counter reduced min jump length. */
3156 set_param_value ("max-grow-copy-bb-insns", 16);
3158 /* Enable section anchors by default.
3159 Skip section anchors for Objective C and Objective C++
3160 until front-ends fixed. */
3161 if (!TARGET_MACHO && lang_hooks.name[4] != 'O')
3162 flag_section_anchors = 2;
3165 static enum fpu_type_t
3166 rs6000_parse_fpu_option (const char *option)
3168 if (!strcmp("none", option)) return FPU_NONE;
3169 if (!strcmp("sp_lite", option)) return FPU_SF_LITE;
3170 if (!strcmp("dp_lite", option)) return FPU_DF_LITE;
3171 if (!strcmp("sp_full", option)) return FPU_SF_FULL;
3172 if (!strcmp("dp_full", option)) return FPU_DF_FULL;
3173 error("unknown value %s for -mfpu", option);
3174 return FPU_NONE;
3177 /* Returns a function decl for a vectorized version of the builtin function
3178 with builtin function code FN and the result vector type TYPE, or NULL_TREE
3179 if it is not available. */
3181 static tree
3182 rs6000_builtin_vectorized_function (tree fndecl, tree type_out,
3183 tree type_in)
3185 enum machine_mode in_mode, out_mode;
3186 int in_n, out_n;
3187 enum built_in_function fn = DECL_FUNCTION_CODE (fndecl);
3189 if (TREE_CODE (type_out) != VECTOR_TYPE
3190 || TREE_CODE (type_in) != VECTOR_TYPE
3191 || !TARGET_VECTORIZE_BUILTINS
3192 || DECL_BUILT_IN_CLASS (fndecl) != BUILT_IN_NORMAL)
3193 return NULL_TREE;
3195 out_mode = TYPE_MODE (TREE_TYPE (type_out));
3196 out_n = TYPE_VECTOR_SUBPARTS (type_out);
3197 in_mode = TYPE_MODE (TREE_TYPE (type_in));
3198 in_n = TYPE_VECTOR_SUBPARTS (type_in);
3200 switch (fn)
3202 case BUILT_IN_COPYSIGN:
3203 if (VECTOR_UNIT_VSX_P (V2DFmode)
3204 && out_mode == DFmode && out_n == 2
3205 && in_mode == DFmode && in_n == 2)
3206 return rs6000_builtin_decls[VSX_BUILTIN_CPSGNDP];
3207 break;
3208 case BUILT_IN_COPYSIGNF:
3209 if (out_mode != SFmode || out_n != 4
3210 || in_mode != SFmode || in_n != 4)
3211 break;
3212 if (VECTOR_UNIT_VSX_P (V4SFmode))
3213 return rs6000_builtin_decls[VSX_BUILTIN_CPSGNSP];
3214 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3215 return rs6000_builtin_decls[ALTIVEC_BUILTIN_COPYSIGN_V4SF];
3216 break;
3217 case BUILT_IN_SQRT:
3218 if (VECTOR_UNIT_VSX_P (V2DFmode)
3219 && out_mode == DFmode && out_n == 2
3220 && in_mode == DFmode && in_n == 2)
3221 return rs6000_builtin_decls[VSX_BUILTIN_XVSQRTDP];
3222 break;
3223 case BUILT_IN_SQRTF:
3224 if (VECTOR_UNIT_VSX_P (V4SFmode)
3225 && out_mode == SFmode && out_n == 4
3226 && in_mode == SFmode && in_n == 4)
3227 return rs6000_builtin_decls[VSX_BUILTIN_XVSQRTSP];
3228 break;
3229 case BUILT_IN_CEIL:
3230 if (VECTOR_UNIT_VSX_P (V2DFmode)
3231 && out_mode == DFmode && out_n == 2
3232 && in_mode == DFmode && in_n == 2)
3233 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIP];
3234 break;
3235 case BUILT_IN_CEILF:
3236 if (out_mode != SFmode || out_n != 4
3237 || in_mode != SFmode || in_n != 4)
3238 break;
3239 if (VECTOR_UNIT_VSX_P (V4SFmode))
3240 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIP];
3241 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3242 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIP];
3243 break;
3244 case BUILT_IN_FLOOR:
3245 if (VECTOR_UNIT_VSX_P (V2DFmode)
3246 && out_mode == DFmode && out_n == 2
3247 && in_mode == DFmode && in_n == 2)
3248 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIM];
3249 break;
3250 case BUILT_IN_FLOORF:
3251 if (out_mode != SFmode || out_n != 4
3252 || in_mode != SFmode || in_n != 4)
3253 break;
3254 if (VECTOR_UNIT_VSX_P (V4SFmode))
3255 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIM];
3256 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3257 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIM];
3258 break;
3259 case BUILT_IN_TRUNC:
3260 if (VECTOR_UNIT_VSX_P (V2DFmode)
3261 && out_mode == DFmode && out_n == 2
3262 && in_mode == DFmode && in_n == 2)
3263 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIZ];
3264 break;
3265 case BUILT_IN_TRUNCF:
3266 if (out_mode != SFmode || out_n != 4
3267 || in_mode != SFmode || in_n != 4)
3268 break;
3269 if (VECTOR_UNIT_VSX_P (V4SFmode))
3270 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIZ];
3271 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3272 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIZ];
3273 break;
3274 case BUILT_IN_NEARBYINT:
3275 if (VECTOR_UNIT_VSX_P (V2DFmode)
3276 && flag_unsafe_math_optimizations
3277 && out_mode == DFmode && out_n == 2
3278 && in_mode == DFmode && in_n == 2)
3279 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPI];
3280 break;
3281 case BUILT_IN_NEARBYINTF:
3282 if (VECTOR_UNIT_VSX_P (V4SFmode)
3283 && flag_unsafe_math_optimizations
3284 && out_mode == SFmode && out_n == 4
3285 && in_mode == SFmode && in_n == 4)
3286 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPI];
3287 break;
3288 case BUILT_IN_RINT:
3289 if (VECTOR_UNIT_VSX_P (V2DFmode)
3290 && !flag_trapping_math
3291 && out_mode == DFmode && out_n == 2
3292 && in_mode == DFmode && in_n == 2)
3293 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIC];
3294 break;
3295 case BUILT_IN_RINTF:
3296 if (VECTOR_UNIT_VSX_P (V4SFmode)
3297 && !flag_trapping_math
3298 && out_mode == SFmode && out_n == 4
3299 && in_mode == SFmode && in_n == 4)
3300 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIC];
3301 break;
3302 default:
3303 break;
3305 return NULL_TREE;
3309 /* Implement TARGET_HANDLE_OPTION. */
3311 static bool
3312 rs6000_handle_option (size_t code, const char *arg, int value)
3314 enum fpu_type_t fpu_type = FPU_NONE;
3315 int isel;
3317 switch (code)
3319 case OPT_mno_power:
3320 target_flags &= ~(MASK_POWER | MASK_POWER2
3321 | MASK_MULTIPLE | MASK_STRING);
3322 target_flags_explicit |= (MASK_POWER | MASK_POWER2
3323 | MASK_MULTIPLE | MASK_STRING);
3324 break;
3325 case OPT_mno_powerpc:
3326 target_flags &= ~(MASK_POWERPC | MASK_PPC_GPOPT
3327 | MASK_PPC_GFXOPT | MASK_POWERPC64);
3328 target_flags_explicit |= (MASK_POWERPC | MASK_PPC_GPOPT
3329 | MASK_PPC_GFXOPT | MASK_POWERPC64);
3330 break;
3331 case OPT_mfull_toc:
3332 target_flags &= ~MASK_MINIMAL_TOC;
3333 TARGET_NO_FP_IN_TOC = 0;
3334 TARGET_NO_SUM_IN_TOC = 0;
3335 target_flags_explicit |= MASK_MINIMAL_TOC;
3336 #ifdef TARGET_USES_SYSV4_OPT
3337 /* Note, V.4 no longer uses a normal TOC, so make -mfull-toc, be
3338 just the same as -mminimal-toc. */
3339 target_flags |= MASK_MINIMAL_TOC;
3340 target_flags_explicit |= MASK_MINIMAL_TOC;
3341 #endif
3342 break;
3344 #ifdef TARGET_USES_SYSV4_OPT
3345 case OPT_mtoc:
3346 /* Make -mtoc behave like -mminimal-toc. */
3347 target_flags |= MASK_MINIMAL_TOC;
3348 target_flags_explicit |= MASK_MINIMAL_TOC;
3349 break;
3350 #endif
3352 #ifdef TARGET_USES_AIX64_OPT
3353 case OPT_maix64:
3354 #else
3355 case OPT_m64:
3356 #endif
3357 target_flags |= MASK_POWERPC64 | MASK_POWERPC;
3358 target_flags |= ~target_flags_explicit & MASK_PPC_GFXOPT;
3359 target_flags_explicit |= MASK_POWERPC64 | MASK_POWERPC;
3360 break;
3362 #ifdef TARGET_USES_AIX64_OPT
3363 case OPT_maix32:
3364 #else
3365 case OPT_m32:
3366 #endif
3367 target_flags &= ~MASK_POWERPC64;
3368 target_flags_explicit |= MASK_POWERPC64;
3369 break;
3371 case OPT_minsert_sched_nops_:
3372 rs6000_sched_insert_nops_str = arg;
3373 break;
3375 case OPT_mminimal_toc:
3376 if (value == 1)
3378 TARGET_NO_FP_IN_TOC = 0;
3379 TARGET_NO_SUM_IN_TOC = 0;
3381 break;
3383 case OPT_mpower:
3384 if (value == 1)
3386 target_flags |= (MASK_MULTIPLE | MASK_STRING);
3387 target_flags_explicit |= (MASK_MULTIPLE | MASK_STRING);
3389 break;
3391 case OPT_mpower2:
3392 if (value == 1)
3394 target_flags |= (MASK_POWER | MASK_MULTIPLE | MASK_STRING);
3395 target_flags_explicit |= (MASK_POWER | MASK_MULTIPLE | MASK_STRING);
3397 break;
3399 case OPT_mpowerpc_gpopt:
3400 case OPT_mpowerpc_gfxopt:
3401 if (value == 1)
3403 target_flags |= MASK_POWERPC;
3404 target_flags_explicit |= MASK_POWERPC;
3406 break;
3408 case OPT_maix_struct_return:
3409 case OPT_msvr4_struct_return:
3410 rs6000_explicit_options.aix_struct_ret = true;
3411 break;
3413 case OPT_mvrsave:
3414 rs6000_explicit_options.vrsave = true;
3415 TARGET_ALTIVEC_VRSAVE = value;
3416 break;
3418 case OPT_mvrsave_:
3419 rs6000_explicit_options.vrsave = true;
3420 rs6000_parse_yes_no_option ("vrsave", arg, &(TARGET_ALTIVEC_VRSAVE));
3421 break;
3423 case OPT_misel_:
3424 target_flags_explicit |= MASK_ISEL;
3425 isel = 0;
3426 rs6000_parse_yes_no_option ("isel", arg, &isel);
3427 if (isel)
3428 target_flags |= MASK_ISEL;
3429 else
3430 target_flags &= ~MASK_ISEL;
3431 break;
3433 case OPT_mspe:
3434 rs6000_explicit_options.spe = true;
3435 rs6000_spe = value;
3436 break;
3438 case OPT_mspe_:
3439 rs6000_explicit_options.spe = true;
3440 rs6000_parse_yes_no_option ("spe", arg, &(rs6000_spe));
3441 break;
3443 case OPT_mdebug_:
3444 rs6000_debug_name = arg;
3445 break;
3447 #ifdef TARGET_USES_SYSV4_OPT
3448 case OPT_mcall_:
3449 rs6000_abi_name = arg;
3450 break;
3452 case OPT_msdata_:
3453 rs6000_sdata_name = arg;
3454 break;
3456 case OPT_mtls_size_:
3457 rs6000_tls_size_string = arg;
3458 break;
3460 case OPT_mrelocatable:
3461 if (value == 1)
3463 target_flags |= MASK_MINIMAL_TOC;
3464 target_flags_explicit |= MASK_MINIMAL_TOC;
3465 TARGET_NO_FP_IN_TOC = 1;
3467 break;
3469 case OPT_mrelocatable_lib:
3470 if (value == 1)
3472 target_flags |= MASK_RELOCATABLE | MASK_MINIMAL_TOC;
3473 target_flags_explicit |= MASK_RELOCATABLE | MASK_MINIMAL_TOC;
3474 TARGET_NO_FP_IN_TOC = 1;
3476 else
3478 target_flags &= ~MASK_RELOCATABLE;
3479 target_flags_explicit |= MASK_RELOCATABLE;
3481 break;
3482 #endif
3484 case OPT_mabi_:
3485 if (!strcmp (arg, "altivec"))
3487 rs6000_explicit_options.altivec_abi = true;
3488 rs6000_altivec_abi = 1;
3490 /* Enabling the AltiVec ABI turns off the SPE ABI. */
3491 rs6000_spe_abi = 0;
3493 else if (! strcmp (arg, "no-altivec"))
3495 rs6000_explicit_options.altivec_abi = true;
3496 rs6000_altivec_abi = 0;
3498 else if (! strcmp (arg, "spe"))
3500 rs6000_explicit_options.spe_abi = true;
3501 rs6000_spe_abi = 1;
3502 rs6000_altivec_abi = 0;
3503 if (!TARGET_SPE_ABI)
3504 error ("not configured for ABI: '%s'", arg);
3506 else if (! strcmp (arg, "no-spe"))
3508 rs6000_explicit_options.spe_abi = true;
3509 rs6000_spe_abi = 0;
3512 /* These are here for testing during development only, do not
3513 document in the manual please. */
3514 else if (! strcmp (arg, "d64"))
3516 rs6000_darwin64_abi = 1;
3517 warning (0, "Using darwin64 ABI");
3519 else if (! strcmp (arg, "d32"))
3521 rs6000_darwin64_abi = 0;
3522 warning (0, "Using old darwin ABI");
3525 else if (! strcmp (arg, "ibmlongdouble"))
3527 rs6000_explicit_options.ieee = true;
3528 rs6000_ieeequad = 0;
3529 warning (0, "Using IBM extended precision long double");
3531 else if (! strcmp (arg, "ieeelongdouble"))
3533 rs6000_explicit_options.ieee = true;
3534 rs6000_ieeequad = 1;
3535 warning (0, "Using IEEE extended precision long double");
3538 else
3540 error ("unknown ABI specified: '%s'", arg);
3541 return false;
3543 break;
3545 case OPT_mcpu_:
3546 rs6000_select[1].string = arg;
3547 break;
3549 case OPT_mtune_:
3550 rs6000_select[2].string = arg;
3551 break;
3553 case OPT_mtraceback_:
3554 rs6000_traceback_name = arg;
3555 break;
3557 case OPT_mfloat_gprs_:
3558 rs6000_explicit_options.float_gprs = true;
3559 if (! strcmp (arg, "yes") || ! strcmp (arg, "single"))
3560 rs6000_float_gprs = 1;
3561 else if (! strcmp (arg, "double"))
3562 rs6000_float_gprs = 2;
3563 else if (! strcmp (arg, "no"))
3564 rs6000_float_gprs = 0;
3565 else
3567 error ("invalid option for -mfloat-gprs: '%s'", arg);
3568 return false;
3570 break;
3572 case OPT_mlong_double_:
3573 rs6000_explicit_options.long_double = true;
3574 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
3575 if (value != 64 && value != 128)
3577 error ("Unknown switch -mlong-double-%s", arg);
3578 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
3579 return false;
3581 else
3582 rs6000_long_double_type_size = value;
3583 break;
3585 case OPT_msched_costly_dep_:
3586 rs6000_sched_costly_dep_str = arg;
3587 break;
3589 case OPT_malign_:
3590 rs6000_explicit_options.alignment = true;
3591 if (! strcmp (arg, "power"))
3593 /* On 64-bit Darwin, power alignment is ABI-incompatible with
3594 some C library functions, so warn about it. The flag may be
3595 useful for performance studies from time to time though, so
3596 don't disable it entirely. */
3597 if (DEFAULT_ABI == ABI_DARWIN && TARGET_64BIT)
3598 warning (0, "-malign-power is not supported for 64-bit Darwin;"
3599 " it is incompatible with the installed C and C++ libraries");
3600 rs6000_alignment_flags = MASK_ALIGN_POWER;
3602 else if (! strcmp (arg, "natural"))
3603 rs6000_alignment_flags = MASK_ALIGN_NATURAL;
3604 else
3606 error ("unknown -malign-XXXXX option specified: '%s'", arg);
3607 return false;
3609 break;
3611 case OPT_msingle_float:
3612 if (!TARGET_SINGLE_FPU)
3613 warning (0, "-msingle-float option equivalent to -mhard-float");
3614 /* -msingle-float implies -mno-double-float and TARGET_HARD_FLOAT. */
3615 rs6000_double_float = 0;
3616 target_flags &= ~MASK_SOFT_FLOAT;
3617 target_flags_explicit |= MASK_SOFT_FLOAT;
3618 break;
3620 case OPT_mdouble_float:
3621 /* -mdouble-float implies -msingle-float and TARGET_HARD_FLOAT. */
3622 rs6000_single_float = 1;
3623 target_flags &= ~MASK_SOFT_FLOAT;
3624 target_flags_explicit |= MASK_SOFT_FLOAT;
3625 break;
3627 case OPT_msimple_fpu:
3628 if (!TARGET_SINGLE_FPU)
3629 warning (0, "-msimple-fpu option ignored");
3630 break;
3632 case OPT_mhard_float:
3633 /* -mhard_float implies -msingle-float and -mdouble-float. */
3634 rs6000_single_float = rs6000_double_float = 1;
3635 break;
3637 case OPT_msoft_float:
3638 /* -msoft_float implies -mnosingle-float and -mnodouble-float. */
3639 rs6000_single_float = rs6000_double_float = 0;
3640 break;
3642 case OPT_mfpu_:
3643 fpu_type = rs6000_parse_fpu_option(arg);
3644 if (fpu_type != FPU_NONE)
3645 /* If -mfpu is not none, then turn off SOFT_FLOAT, turn on HARD_FLOAT. */
3647 target_flags &= ~MASK_SOFT_FLOAT;
3648 target_flags_explicit |= MASK_SOFT_FLOAT;
3649 rs6000_xilinx_fpu = 1;
3650 if (fpu_type == FPU_SF_LITE || fpu_type == FPU_SF_FULL)
3651 rs6000_single_float = 1;
3652 if (fpu_type == FPU_DF_LITE || fpu_type == FPU_DF_FULL)
3653 rs6000_single_float = rs6000_double_float = 1;
3654 if (fpu_type == FPU_SF_LITE || fpu_type == FPU_DF_LITE)
3655 rs6000_simple_fpu = 1;
3657 else
3659 /* -mfpu=none is equivalent to -msoft-float */
3660 target_flags |= MASK_SOFT_FLOAT;
3661 target_flags_explicit |= MASK_SOFT_FLOAT;
3662 rs6000_single_float = rs6000_double_float = 0;
3664 break;
3666 return true;
3669 /* Do anything needed at the start of the asm file. */
3671 static void
3672 rs6000_file_start (void)
3674 size_t i;
3675 char buffer[80];
3676 const char *start = buffer;
3677 struct rs6000_cpu_select *ptr;
3678 const char *default_cpu = TARGET_CPU_DEFAULT;
3679 FILE *file = asm_out_file;
3681 default_file_start ();
3683 #ifdef TARGET_BI_ARCH
3684 if ((TARGET_DEFAULT ^ target_flags) & MASK_64BIT)
3685 default_cpu = 0;
3686 #endif
3688 if (flag_verbose_asm)
3690 sprintf (buffer, "\n%s rs6000/powerpc options:", ASM_COMMENT_START);
3691 rs6000_select[0].string = default_cpu;
3693 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
3695 ptr = &rs6000_select[i];
3696 if (ptr->string != (char *)0 && ptr->string[0] != '\0')
3698 fprintf (file, "%s %s%s", start, ptr->name, ptr->string);
3699 start = "";
3703 if (PPC405_ERRATUM77)
3705 fprintf (file, "%s PPC405CR_ERRATUM77", start);
3706 start = "";
3709 #ifdef USING_ELFOS_H
3710 switch (rs6000_sdata)
3712 case SDATA_NONE: fprintf (file, "%s -msdata=none", start); start = ""; break;
3713 case SDATA_DATA: fprintf (file, "%s -msdata=data", start); start = ""; break;
3714 case SDATA_SYSV: fprintf (file, "%s -msdata=sysv", start); start = ""; break;
3715 case SDATA_EABI: fprintf (file, "%s -msdata=eabi", start); start = ""; break;
3718 if (rs6000_sdata && g_switch_value)
3720 fprintf (file, "%s -G " HOST_WIDE_INT_PRINT_UNSIGNED, start,
3721 g_switch_value);
3722 start = "";
3724 #endif
3726 if (*start == '\0')
3727 putc ('\n', file);
3730 #ifdef HAVE_AS_GNU_ATTRIBUTE
3731 if (TARGET_32BIT && DEFAULT_ABI == ABI_V4)
3733 fprintf (file, "\t.gnu_attribute 4, %d\n",
3734 ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT) ? 1
3735 : (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT) ? 3
3736 : 2));
3737 fprintf (file, "\t.gnu_attribute 8, %d\n",
3738 (TARGET_ALTIVEC_ABI ? 2
3739 : TARGET_SPE_ABI ? 3
3740 : 1));
3741 fprintf (file, "\t.gnu_attribute 12, %d\n",
3742 aix_struct_return ? 2 : 1);
3745 #endif
3747 if (DEFAULT_ABI == ABI_AIX || (TARGET_ELF && flag_pic == 2))
3749 switch_to_section (toc_section);
3750 switch_to_section (text_section);
3755 /* Return nonzero if this function is known to have a null epilogue. */
3758 direct_return (void)
3760 if (reload_completed)
3762 rs6000_stack_t *info = rs6000_stack_info ();
3764 if (info->first_gp_reg_save == 32
3765 && info->first_fp_reg_save == 64
3766 && info->first_altivec_reg_save == LAST_ALTIVEC_REGNO + 1
3767 && ! info->lr_save_p
3768 && ! info->cr_save_p
3769 && info->vrsave_mask == 0
3770 && ! info->push_p)
3771 return 1;
3774 return 0;
3777 /* Return the number of instructions it takes to form a constant in an
3778 integer register. */
3781 num_insns_constant_wide (HOST_WIDE_INT value)
3783 /* signed constant loadable with {cal|addi} */
3784 if ((unsigned HOST_WIDE_INT) (value + 0x8000) < 0x10000)
3785 return 1;
3787 /* constant loadable with {cau|addis} */
3788 else if ((value & 0xffff) == 0
3789 && (value >> 31 == -1 || value >> 31 == 0))
3790 return 1;
3792 #if HOST_BITS_PER_WIDE_INT == 64
3793 else if (TARGET_POWERPC64)
3795 HOST_WIDE_INT low = ((value & 0xffffffff) ^ 0x80000000) - 0x80000000;
3796 HOST_WIDE_INT high = value >> 31;
3798 if (high == 0 || high == -1)
3799 return 2;
3801 high >>= 1;
3803 if (low == 0)
3804 return num_insns_constant_wide (high) + 1;
3805 else if (high == 0)
3806 return num_insns_constant_wide (low) + 1;
3807 else
3808 return (num_insns_constant_wide (high)
3809 + num_insns_constant_wide (low) + 1);
3811 #endif
3813 else
3814 return 2;
3818 num_insns_constant (rtx op, enum machine_mode mode)
3820 HOST_WIDE_INT low, high;
3822 switch (GET_CODE (op))
3824 case CONST_INT:
3825 #if HOST_BITS_PER_WIDE_INT == 64
3826 if ((INTVAL (op) >> 31) != 0 && (INTVAL (op) >> 31) != -1
3827 && mask64_operand (op, mode))
3828 return 2;
3829 else
3830 #endif
3831 return num_insns_constant_wide (INTVAL (op));
3833 case CONST_DOUBLE:
3834 if (mode == SFmode || mode == SDmode)
3836 long l;
3837 REAL_VALUE_TYPE rv;
3839 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
3840 if (DECIMAL_FLOAT_MODE_P (mode))
3841 REAL_VALUE_TO_TARGET_DECIMAL32 (rv, l);
3842 else
3843 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
3844 return num_insns_constant_wide ((HOST_WIDE_INT) l);
3847 if (mode == VOIDmode || mode == DImode)
3849 high = CONST_DOUBLE_HIGH (op);
3850 low = CONST_DOUBLE_LOW (op);
3852 else
3854 long l[2];
3855 REAL_VALUE_TYPE rv;
3857 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
3858 if (DECIMAL_FLOAT_MODE_P (mode))
3859 REAL_VALUE_TO_TARGET_DECIMAL64 (rv, l);
3860 else
3861 REAL_VALUE_TO_TARGET_DOUBLE (rv, l);
3862 high = l[WORDS_BIG_ENDIAN == 0];
3863 low = l[WORDS_BIG_ENDIAN != 0];
3866 if (TARGET_32BIT)
3867 return (num_insns_constant_wide (low)
3868 + num_insns_constant_wide (high));
3869 else
3871 if ((high == 0 && low >= 0)
3872 || (high == -1 && low < 0))
3873 return num_insns_constant_wide (low);
3875 else if (mask64_operand (op, mode))
3876 return 2;
3878 else if (low == 0)
3879 return num_insns_constant_wide (high) + 1;
3881 else
3882 return (num_insns_constant_wide (high)
3883 + num_insns_constant_wide (low) + 1);
3886 default:
3887 gcc_unreachable ();
3891 /* Interpret element ELT of the CONST_VECTOR OP as an integer value.
3892 If the mode of OP is MODE_VECTOR_INT, this simply returns the
3893 corresponding element of the vector, but for V4SFmode and V2SFmode,
3894 the corresponding "float" is interpreted as an SImode integer. */
3896 HOST_WIDE_INT
3897 const_vector_elt_as_int (rtx op, unsigned int elt)
3899 rtx tmp = CONST_VECTOR_ELT (op, elt);
3900 if (GET_MODE (op) == V4SFmode
3901 || GET_MODE (op) == V2SFmode)
3902 tmp = gen_lowpart (SImode, tmp);
3903 return INTVAL (tmp);
3906 /* Return true if OP can be synthesized with a particular vspltisb, vspltish
3907 or vspltisw instruction. OP is a CONST_VECTOR. Which instruction is used
3908 depends on STEP and COPIES, one of which will be 1. If COPIES > 1,
3909 all items are set to the same value and contain COPIES replicas of the
3910 vsplt's operand; if STEP > 1, one in STEP elements is set to the vsplt's
3911 operand and the others are set to the value of the operand's msb. */
3913 static bool
3914 vspltis_constant (rtx op, unsigned step, unsigned copies)
3916 enum machine_mode mode = GET_MODE (op);
3917 enum machine_mode inner = GET_MODE_INNER (mode);
3919 unsigned i;
3920 unsigned nunits = GET_MODE_NUNITS (mode);
3921 unsigned bitsize = GET_MODE_BITSIZE (inner);
3922 unsigned mask = GET_MODE_MASK (inner);
3924 HOST_WIDE_INT val = const_vector_elt_as_int (op, nunits - 1);
3925 HOST_WIDE_INT splat_val = val;
3926 HOST_WIDE_INT msb_val = val > 0 ? 0 : -1;
3928 /* Construct the value to be splatted, if possible. If not, return 0. */
3929 for (i = 2; i <= copies; i *= 2)
3931 HOST_WIDE_INT small_val;
3932 bitsize /= 2;
3933 small_val = splat_val >> bitsize;
3934 mask >>= bitsize;
3935 if (splat_val != ((small_val << bitsize) | (small_val & mask)))
3936 return false;
3937 splat_val = small_val;
3940 /* Check if SPLAT_VAL can really be the operand of a vspltis[bhw]. */
3941 if (EASY_VECTOR_15 (splat_val))
3944 /* Also check if we can splat, and then add the result to itself. Do so if
3945 the value is positive, of if the splat instruction is using OP's mode;
3946 for splat_val < 0, the splat and the add should use the same mode. */
3947 else if (EASY_VECTOR_15_ADD_SELF (splat_val)
3948 && (splat_val >= 0 || (step == 1 && copies == 1)))
3951 /* Also check if are loading up the most significant bit which can be done by
3952 loading up -1 and shifting the value left by -1. */
3953 else if (EASY_VECTOR_MSB (splat_val, inner))
3956 else
3957 return false;
3959 /* Check if VAL is present in every STEP-th element, and the
3960 other elements are filled with its most significant bit. */
3961 for (i = 0; i < nunits - 1; ++i)
3963 HOST_WIDE_INT desired_val;
3964 if (((i + 1) & (step - 1)) == 0)
3965 desired_val = val;
3966 else
3967 desired_val = msb_val;
3969 if (desired_val != const_vector_elt_as_int (op, i))
3970 return false;
3973 return true;
3977 /* Return true if OP is of the given MODE and can be synthesized
3978 with a vspltisb, vspltish or vspltisw. */
3980 bool
3981 easy_altivec_constant (rtx op, enum machine_mode mode)
3983 unsigned step, copies;
3985 if (mode == VOIDmode)
3986 mode = GET_MODE (op);
3987 else if (mode != GET_MODE (op))
3988 return false;
3990 /* Start with a vspltisw. */
3991 step = GET_MODE_NUNITS (mode) / 4;
3992 copies = 1;
3994 if (vspltis_constant (op, step, copies))
3995 return true;
3997 /* Then try with a vspltish. */
3998 if (step == 1)
3999 copies <<= 1;
4000 else
4001 step >>= 1;
4003 if (vspltis_constant (op, step, copies))
4004 return true;
4006 /* And finally a vspltisb. */
4007 if (step == 1)
4008 copies <<= 1;
4009 else
4010 step >>= 1;
4012 if (vspltis_constant (op, step, copies))
4013 return true;
4015 return false;
4018 /* Generate a VEC_DUPLICATE representing a vspltis[bhw] instruction whose
4019 result is OP. Abort if it is not possible. */
4022 gen_easy_altivec_constant (rtx op)
4024 enum machine_mode mode = GET_MODE (op);
4025 int nunits = GET_MODE_NUNITS (mode);
4026 rtx last = CONST_VECTOR_ELT (op, nunits - 1);
4027 unsigned step = nunits / 4;
4028 unsigned copies = 1;
4030 /* Start with a vspltisw. */
4031 if (vspltis_constant (op, step, copies))
4032 return gen_rtx_VEC_DUPLICATE (V4SImode, gen_lowpart (SImode, last));
4034 /* Then try with a vspltish. */
4035 if (step == 1)
4036 copies <<= 1;
4037 else
4038 step >>= 1;
4040 if (vspltis_constant (op, step, copies))
4041 return gen_rtx_VEC_DUPLICATE (V8HImode, gen_lowpart (HImode, last));
4043 /* And finally a vspltisb. */
4044 if (step == 1)
4045 copies <<= 1;
4046 else
4047 step >>= 1;
4049 if (vspltis_constant (op, step, copies))
4050 return gen_rtx_VEC_DUPLICATE (V16QImode, gen_lowpart (QImode, last));
4052 gcc_unreachable ();
4055 const char *
4056 output_vec_const_move (rtx *operands)
4058 int cst, cst2;
4059 enum machine_mode mode;
4060 rtx dest, vec;
4062 dest = operands[0];
4063 vec = operands[1];
4064 mode = GET_MODE (dest);
4066 if (TARGET_VSX && zero_constant (vec, mode))
4067 return "xxlxor %x0,%x0,%x0";
4069 if (TARGET_ALTIVEC)
4071 rtx splat_vec;
4072 if (zero_constant (vec, mode))
4073 return "vxor %0,%0,%0";
4075 splat_vec = gen_easy_altivec_constant (vec);
4076 gcc_assert (GET_CODE (splat_vec) == VEC_DUPLICATE);
4077 operands[1] = XEXP (splat_vec, 0);
4078 if (!EASY_VECTOR_15 (INTVAL (operands[1])))
4079 return "#";
4081 switch (GET_MODE (splat_vec))
4083 case V4SImode:
4084 return "vspltisw %0,%1";
4086 case V8HImode:
4087 return "vspltish %0,%1";
4089 case V16QImode:
4090 return "vspltisb %0,%1";
4092 default:
4093 gcc_unreachable ();
4097 gcc_assert (TARGET_SPE);
4099 /* Vector constant 0 is handled as a splitter of V2SI, and in the
4100 pattern of V1DI, V4HI, and V2SF.
4102 FIXME: We should probably return # and add post reload
4103 splitters for these, but this way is so easy ;-). */
4104 cst = INTVAL (CONST_VECTOR_ELT (vec, 0));
4105 cst2 = INTVAL (CONST_VECTOR_ELT (vec, 1));
4106 operands[1] = CONST_VECTOR_ELT (vec, 0);
4107 operands[2] = CONST_VECTOR_ELT (vec, 1);
4108 if (cst == cst2)
4109 return "li %0,%1\n\tevmergelo %0,%0,%0";
4110 else
4111 return "li %0,%1\n\tevmergelo %0,%0,%0\n\tli %0,%2";
4114 /* Initialize TARGET of vector PAIRED to VALS. */
4116 void
4117 paired_expand_vector_init (rtx target, rtx vals)
4119 enum machine_mode mode = GET_MODE (target);
4120 int n_elts = GET_MODE_NUNITS (mode);
4121 int n_var = 0;
4122 rtx x, new_rtx, tmp, constant_op, op1, op2;
4123 int i;
4125 for (i = 0; i < n_elts; ++i)
4127 x = XVECEXP (vals, 0, i);
4128 if (!CONSTANT_P (x))
4129 ++n_var;
4131 if (n_var == 0)
4133 /* Load from constant pool. */
4134 emit_move_insn (target, gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0)));
4135 return;
4138 if (n_var == 2)
4140 /* The vector is initialized only with non-constants. */
4141 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, XVECEXP (vals, 0, 0),
4142 XVECEXP (vals, 0, 1));
4144 emit_move_insn (target, new_rtx);
4145 return;
4148 /* One field is non-constant and the other one is a constant. Load the
4149 constant from the constant pool and use ps_merge instruction to
4150 construct the whole vector. */
4151 op1 = XVECEXP (vals, 0, 0);
4152 op2 = XVECEXP (vals, 0, 1);
4154 constant_op = (CONSTANT_P (op1)) ? op1 : op2;
4156 tmp = gen_reg_rtx (GET_MODE (constant_op));
4157 emit_move_insn (tmp, constant_op);
4159 if (CONSTANT_P (op1))
4160 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, tmp, op2);
4161 else
4162 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, op1, tmp);
4164 emit_move_insn (target, new_rtx);
4167 void
4168 paired_expand_vector_move (rtx operands[])
4170 rtx op0 = operands[0], op1 = operands[1];
4172 emit_move_insn (op0, op1);
4175 /* Emit vector compare for code RCODE. DEST is destination, OP1 and
4176 OP2 are two VEC_COND_EXPR operands, CC_OP0 and CC_OP1 are the two
4177 operands for the relation operation COND. This is a recursive
4178 function. */
4180 static void
4181 paired_emit_vector_compare (enum rtx_code rcode,
4182 rtx dest, rtx op0, rtx op1,
4183 rtx cc_op0, rtx cc_op1)
4185 rtx tmp = gen_reg_rtx (V2SFmode);
4186 rtx tmp1, max, min, equal_zero;
4188 gcc_assert (TARGET_PAIRED_FLOAT);
4189 gcc_assert (GET_MODE (op0) == GET_MODE (op1));
4191 switch (rcode)
4193 case LT:
4194 case LTU:
4195 paired_emit_vector_compare (GE, dest, op1, op0, cc_op0, cc_op1);
4196 return;
4197 case GE:
4198 case GEU:
4199 emit_insn (gen_subv2sf3 (tmp, cc_op0, cc_op1));
4200 emit_insn (gen_selv2sf4 (dest, tmp, op0, op1, CONST0_RTX (SFmode)));
4201 return;
4202 case LE:
4203 case LEU:
4204 paired_emit_vector_compare (GE, dest, op0, op1, cc_op1, cc_op0);
4205 return;
4206 case GT:
4207 paired_emit_vector_compare (LE, dest, op1, op0, cc_op0, cc_op1);
4208 return;
4209 case EQ:
4210 tmp1 = gen_reg_rtx (V2SFmode);
4211 max = gen_reg_rtx (V2SFmode);
4212 min = gen_reg_rtx (V2SFmode);
4213 equal_zero = gen_reg_rtx (V2SFmode);
4215 emit_insn (gen_subv2sf3 (tmp, cc_op0, cc_op1));
4216 emit_insn (gen_selv2sf4
4217 (max, tmp, cc_op0, cc_op1, CONST0_RTX (SFmode)));
4218 emit_insn (gen_subv2sf3 (tmp, cc_op1, cc_op0));
4219 emit_insn (gen_selv2sf4
4220 (min, tmp, cc_op0, cc_op1, CONST0_RTX (SFmode)));
4221 emit_insn (gen_subv2sf3 (tmp1, min, max));
4222 emit_insn (gen_selv2sf4 (dest, tmp1, op0, op1, CONST0_RTX (SFmode)));
4223 return;
4224 case NE:
4225 paired_emit_vector_compare (EQ, dest, op1, op0, cc_op0, cc_op1);
4226 return;
4227 case UNLE:
4228 paired_emit_vector_compare (LE, dest, op1, op0, cc_op0, cc_op1);
4229 return;
4230 case UNLT:
4231 paired_emit_vector_compare (LT, dest, op1, op0, cc_op0, cc_op1);
4232 return;
4233 case UNGE:
4234 paired_emit_vector_compare (GE, dest, op1, op0, cc_op0, cc_op1);
4235 return;
4236 case UNGT:
4237 paired_emit_vector_compare (GT, dest, op1, op0, cc_op0, cc_op1);
4238 return;
4239 default:
4240 gcc_unreachable ();
4243 return;
4246 /* Emit vector conditional expression.
4247 DEST is destination. OP1 and OP2 are two VEC_COND_EXPR operands.
4248 CC_OP0 and CC_OP1 are the two operands for the relation operation COND. */
4251 paired_emit_vector_cond_expr (rtx dest, rtx op1, rtx op2,
4252 rtx cond, rtx cc_op0, rtx cc_op1)
4254 enum rtx_code rcode = GET_CODE (cond);
4256 if (!TARGET_PAIRED_FLOAT)
4257 return 0;
4259 paired_emit_vector_compare (rcode, dest, op1, op2, cc_op0, cc_op1);
4261 return 1;
4264 /* Initialize vector TARGET to VALS. */
4266 void
4267 rs6000_expand_vector_init (rtx target, rtx vals)
4269 enum machine_mode mode = GET_MODE (target);
4270 enum machine_mode inner_mode = GET_MODE_INNER (mode);
4271 int n_elts = GET_MODE_NUNITS (mode);
4272 int n_var = 0, one_var = -1;
4273 bool all_same = true, all_const_zero = true;
4274 rtx x, mem;
4275 int i;
4277 for (i = 0; i < n_elts; ++i)
4279 x = XVECEXP (vals, 0, i);
4280 if (!CONSTANT_P (x))
4281 ++n_var, one_var = i;
4282 else if (x != CONST0_RTX (inner_mode))
4283 all_const_zero = false;
4285 if (i > 0 && !rtx_equal_p (x, XVECEXP (vals, 0, 0)))
4286 all_same = false;
4289 if (n_var == 0)
4291 rtx const_vec = gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0));
4292 bool int_vector_p = (GET_MODE_CLASS (mode) == MODE_VECTOR_INT);
4293 if ((int_vector_p || TARGET_VSX) && all_const_zero)
4295 /* Zero register. */
4296 emit_insn (gen_rtx_SET (VOIDmode, target,
4297 gen_rtx_XOR (mode, target, target)));
4298 return;
4300 else if (int_vector_p && easy_vector_constant (const_vec, mode))
4302 /* Splat immediate. */
4303 emit_insn (gen_rtx_SET (VOIDmode, target, const_vec));
4304 return;
4306 else
4308 /* Load from constant pool. */
4309 emit_move_insn (target, const_vec);
4310 return;
4314 /* Double word values on VSX can use xxpermdi or lxvdsx. */
4315 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
4317 if (all_same)
4319 rtx element = XVECEXP (vals, 0, 0);
4320 if (mode == V2DFmode)
4321 emit_insn (gen_vsx_splat_v2df (target, element));
4322 else
4323 emit_insn (gen_vsx_splat_v2di (target, element));
4325 else
4327 rtx op0 = copy_to_reg (XVECEXP (vals, 0, 0));
4328 rtx op1 = copy_to_reg (XVECEXP (vals, 0, 1));
4329 if (mode == V2DFmode)
4330 emit_insn (gen_vsx_concat_v2df (target, op0, op1));
4331 else
4332 emit_insn (gen_vsx_concat_v2di (target, op0, op1));
4334 return;
4337 /* With single precision floating point on VSX, know that internally single
4338 precision is actually represented as a double, and either make 2 V2DF
4339 vectors, and convert these vectors to single precision, or do one
4340 conversion, and splat the result to the other elements. */
4341 if (mode == V4SFmode && VECTOR_MEM_VSX_P (mode))
4343 if (all_same)
4345 rtx freg = gen_reg_rtx (V4SFmode);
4346 rtx sreg = copy_to_reg (XVECEXP (vals, 0, 0));
4348 emit_insn (gen_vsx_xscvdpsp_scalar (freg, sreg));
4349 emit_insn (gen_vsx_xxspltw_v4sf (target, freg, const0_rtx));
4351 else
4353 rtx dbl_even = gen_reg_rtx (V2DFmode);
4354 rtx dbl_odd = gen_reg_rtx (V2DFmode);
4355 rtx flt_even = gen_reg_rtx (V4SFmode);
4356 rtx flt_odd = gen_reg_rtx (V4SFmode);
4358 emit_insn (gen_vsx_concat_v2sf (dbl_even,
4359 copy_to_reg (XVECEXP (vals, 0, 0)),
4360 copy_to_reg (XVECEXP (vals, 0, 1))));
4361 emit_insn (gen_vsx_concat_v2sf (dbl_odd,
4362 copy_to_reg (XVECEXP (vals, 0, 2)),
4363 copy_to_reg (XVECEXP (vals, 0, 3))));
4364 emit_insn (gen_vsx_xvcvdpsp (flt_even, dbl_even));
4365 emit_insn (gen_vsx_xvcvdpsp (flt_odd, dbl_odd));
4366 emit_insn (gen_vec_extract_evenv4sf (target, flt_even, flt_odd));
4368 return;
4371 /* Store value to stack temp. Load vector element. Splat. However, splat
4372 of 64-bit items is not supported on Altivec. */
4373 if (all_same && GET_MODE_SIZE (mode) <= 4)
4375 mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0);
4376 emit_move_insn (adjust_address_nv (mem, inner_mode, 0),
4377 XVECEXP (vals, 0, 0));
4378 x = gen_rtx_UNSPEC (VOIDmode,
4379 gen_rtvec (1, const0_rtx), UNSPEC_LVE);
4380 emit_insn (gen_rtx_PARALLEL (VOIDmode,
4381 gen_rtvec (2,
4382 gen_rtx_SET (VOIDmode,
4383 target, mem),
4384 x)));
4385 x = gen_rtx_VEC_SELECT (inner_mode, target,
4386 gen_rtx_PARALLEL (VOIDmode,
4387 gen_rtvec (1, const0_rtx)));
4388 emit_insn (gen_rtx_SET (VOIDmode, target,
4389 gen_rtx_VEC_DUPLICATE (mode, x)));
4390 return;
4393 /* One field is non-constant. Load constant then overwrite
4394 varying field. */
4395 if (n_var == 1)
4397 rtx copy = copy_rtx (vals);
4399 /* Load constant part of vector, substitute neighboring value for
4400 varying element. */
4401 XVECEXP (copy, 0, one_var) = XVECEXP (vals, 0, (one_var + 1) % n_elts);
4402 rs6000_expand_vector_init (target, copy);
4404 /* Insert variable. */
4405 rs6000_expand_vector_set (target, XVECEXP (vals, 0, one_var), one_var);
4406 return;
4409 /* Construct the vector in memory one field at a time
4410 and load the whole vector. */
4411 mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
4412 for (i = 0; i < n_elts; i++)
4413 emit_move_insn (adjust_address_nv (mem, inner_mode,
4414 i * GET_MODE_SIZE (inner_mode)),
4415 XVECEXP (vals, 0, i));
4416 emit_move_insn (target, mem);
4419 /* Set field ELT of TARGET to VAL. */
4421 void
4422 rs6000_expand_vector_set (rtx target, rtx val, int elt)
4424 enum machine_mode mode = GET_MODE (target);
4425 enum machine_mode inner_mode = GET_MODE_INNER (mode);
4426 rtx reg = gen_reg_rtx (mode);
4427 rtx mask, mem, x;
4428 int width = GET_MODE_SIZE (inner_mode);
4429 int i;
4431 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
4433 rtx (*set_func) (rtx, rtx, rtx, rtx)
4434 = ((mode == V2DFmode) ? gen_vsx_set_v2df : gen_vsx_set_v2di);
4435 emit_insn (set_func (target, target, val, GEN_INT (elt)));
4436 return;
4439 /* Load single variable value. */
4440 mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0);
4441 emit_move_insn (adjust_address_nv (mem, inner_mode, 0), val);
4442 x = gen_rtx_UNSPEC (VOIDmode,
4443 gen_rtvec (1, const0_rtx), UNSPEC_LVE);
4444 emit_insn (gen_rtx_PARALLEL (VOIDmode,
4445 gen_rtvec (2,
4446 gen_rtx_SET (VOIDmode,
4447 reg, mem),
4448 x)));
4450 /* Linear sequence. */
4451 mask = gen_rtx_PARALLEL (V16QImode, rtvec_alloc (16));
4452 for (i = 0; i < 16; ++i)
4453 XVECEXP (mask, 0, i) = GEN_INT (i);
4455 /* Set permute mask to insert element into target. */
4456 for (i = 0; i < width; ++i)
4457 XVECEXP (mask, 0, elt*width + i)
4458 = GEN_INT (i + 0x10);
4459 x = gen_rtx_CONST_VECTOR (V16QImode, XVEC (mask, 0));
4460 x = gen_rtx_UNSPEC (mode,
4461 gen_rtvec (3, target, reg,
4462 force_reg (V16QImode, x)),
4463 UNSPEC_VPERM);
4464 emit_insn (gen_rtx_SET (VOIDmode, target, x));
4467 /* Extract field ELT from VEC into TARGET. */
4469 void
4470 rs6000_expand_vector_extract (rtx target, rtx vec, int elt)
4472 enum machine_mode mode = GET_MODE (vec);
4473 enum machine_mode inner_mode = GET_MODE_INNER (mode);
4474 rtx mem, x;
4476 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
4478 rtx (*extract_func) (rtx, rtx, rtx)
4479 = ((mode == V2DFmode) ? gen_vsx_extract_v2df : gen_vsx_extract_v2di);
4480 emit_insn (extract_func (target, vec, GEN_INT (elt)));
4481 return;
4484 /* Allocate mode-sized buffer. */
4485 mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
4487 /* Add offset to field within buffer matching vector element. */
4488 mem = adjust_address_nv (mem, mode, elt * GET_MODE_SIZE (inner_mode));
4490 /* Store single field into mode-sized buffer. */
4491 x = gen_rtx_UNSPEC (VOIDmode,
4492 gen_rtvec (1, const0_rtx), UNSPEC_STVE);
4493 emit_insn (gen_rtx_PARALLEL (VOIDmode,
4494 gen_rtvec (2,
4495 gen_rtx_SET (VOIDmode,
4496 mem, vec),
4497 x)));
4498 emit_move_insn (target, adjust_address_nv (mem, inner_mode, 0));
4501 /* Generates shifts and masks for a pair of rldicl or rldicr insns to
4502 implement ANDing by the mask IN. */
4503 void
4504 build_mask64_2_operands (rtx in, rtx *out)
4506 #if HOST_BITS_PER_WIDE_INT >= 64
4507 unsigned HOST_WIDE_INT c, lsb, m1, m2;
4508 int shift;
4510 gcc_assert (GET_CODE (in) == CONST_INT);
4512 c = INTVAL (in);
4513 if (c & 1)
4515 /* Assume c initially something like 0x00fff000000fffff. The idea
4516 is to rotate the word so that the middle ^^^^^^ group of zeros
4517 is at the MS end and can be cleared with an rldicl mask. We then
4518 rotate back and clear off the MS ^^ group of zeros with a
4519 second rldicl. */
4520 c = ~c; /* c == 0xff000ffffff00000 */
4521 lsb = c & -c; /* lsb == 0x0000000000100000 */
4522 m1 = -lsb; /* m1 == 0xfffffffffff00000 */
4523 c = ~c; /* c == 0x00fff000000fffff */
4524 c &= -lsb; /* c == 0x00fff00000000000 */
4525 lsb = c & -c; /* lsb == 0x0000100000000000 */
4526 c = ~c; /* c == 0xff000fffffffffff */
4527 c &= -lsb; /* c == 0xff00000000000000 */
4528 shift = 0;
4529 while ((lsb >>= 1) != 0)
4530 shift++; /* shift == 44 on exit from loop */
4531 m1 <<= 64 - shift; /* m1 == 0xffffff0000000000 */
4532 m1 = ~m1; /* m1 == 0x000000ffffffffff */
4533 m2 = ~c; /* m2 == 0x00ffffffffffffff */
4535 else
4537 /* Assume c initially something like 0xff000f0000000000. The idea
4538 is to rotate the word so that the ^^^ middle group of zeros
4539 is at the LS end and can be cleared with an rldicr mask. We then
4540 rotate back and clear off the LS group of ^^^^^^^^^^ zeros with
4541 a second rldicr. */
4542 lsb = c & -c; /* lsb == 0x0000010000000000 */
4543 m2 = -lsb; /* m2 == 0xffffff0000000000 */
4544 c = ~c; /* c == 0x00fff0ffffffffff */
4545 c &= -lsb; /* c == 0x00fff00000000000 */
4546 lsb = c & -c; /* lsb == 0x0000100000000000 */
4547 c = ~c; /* c == 0xff000fffffffffff */
4548 c &= -lsb; /* c == 0xff00000000000000 */
4549 shift = 0;
4550 while ((lsb >>= 1) != 0)
4551 shift++; /* shift == 44 on exit from loop */
4552 m1 = ~c; /* m1 == 0x00ffffffffffffff */
4553 m1 >>= shift; /* m1 == 0x0000000000000fff */
4554 m1 = ~m1; /* m1 == 0xfffffffffffff000 */
4557 /* Note that when we only have two 0->1 and 1->0 transitions, one of the
4558 masks will be all 1's. We are guaranteed more than one transition. */
4559 out[0] = GEN_INT (64 - shift);
4560 out[1] = GEN_INT (m1);
4561 out[2] = GEN_INT (shift);
4562 out[3] = GEN_INT (m2);
4563 #else
4564 (void)in;
4565 (void)out;
4566 gcc_unreachable ();
4567 #endif
4570 /* Return TRUE if OP is an invalid SUBREG operation on the e500. */
4572 bool
4573 invalid_e500_subreg (rtx op, enum machine_mode mode)
4575 if (TARGET_E500_DOUBLE)
4577 /* Reject (subreg:SI (reg:DF)); likewise with subreg:DI or
4578 subreg:TI and reg:TF. Decimal float modes are like integer
4579 modes (only low part of each register used) for this
4580 purpose. */
4581 if (GET_CODE (op) == SUBREG
4582 && (mode == SImode || mode == DImode || mode == TImode
4583 || mode == DDmode || mode == TDmode)
4584 && REG_P (SUBREG_REG (op))
4585 && (GET_MODE (SUBREG_REG (op)) == DFmode
4586 || GET_MODE (SUBREG_REG (op)) == TFmode))
4587 return true;
4589 /* Reject (subreg:DF (reg:DI)); likewise with subreg:TF and
4590 reg:TI. */
4591 if (GET_CODE (op) == SUBREG
4592 && (mode == DFmode || mode == TFmode)
4593 && REG_P (SUBREG_REG (op))
4594 && (GET_MODE (SUBREG_REG (op)) == DImode
4595 || GET_MODE (SUBREG_REG (op)) == TImode
4596 || GET_MODE (SUBREG_REG (op)) == DDmode
4597 || GET_MODE (SUBREG_REG (op)) == TDmode))
4598 return true;
4601 if (TARGET_SPE
4602 && GET_CODE (op) == SUBREG
4603 && mode == SImode
4604 && REG_P (SUBREG_REG (op))
4605 && SPE_VECTOR_MODE (GET_MODE (SUBREG_REG (op))))
4606 return true;
4608 return false;
4611 /* AIX increases natural record alignment to doubleword if the first
4612 field is an FP double while the FP fields remain word aligned. */
4614 unsigned int
4615 rs6000_special_round_type_align (tree type, unsigned int computed,
4616 unsigned int specified)
4618 unsigned int align = MAX (computed, specified);
4619 tree field = TYPE_FIELDS (type);
4621 /* Skip all non field decls */
4622 while (field != NULL && TREE_CODE (field) != FIELD_DECL)
4623 field = TREE_CHAIN (field);
4625 if (field != NULL && field != type)
4627 type = TREE_TYPE (field);
4628 while (TREE_CODE (type) == ARRAY_TYPE)
4629 type = TREE_TYPE (type);
4631 if (type != error_mark_node && TYPE_MODE (type) == DFmode)
4632 align = MAX (align, 64);
4635 return align;
4638 /* Darwin increases record alignment to the natural alignment of
4639 the first field. */
4641 unsigned int
4642 darwin_rs6000_special_round_type_align (tree type, unsigned int computed,
4643 unsigned int specified)
4645 unsigned int align = MAX (computed, specified);
4647 if (TYPE_PACKED (type))
4648 return align;
4650 /* Find the first field, looking down into aggregates. */
4651 do {
4652 tree field = TYPE_FIELDS (type);
4653 /* Skip all non field decls */
4654 while (field != NULL && TREE_CODE (field) != FIELD_DECL)
4655 field = TREE_CHAIN (field);
4656 if (! field)
4657 break;
4658 /* A packed field does not contribute any extra alignment. */
4659 if (DECL_PACKED (field))
4660 return align;
4661 type = TREE_TYPE (field);
4662 while (TREE_CODE (type) == ARRAY_TYPE)
4663 type = TREE_TYPE (type);
4664 } while (AGGREGATE_TYPE_P (type));
4666 if (! AGGREGATE_TYPE_P (type) && type != error_mark_node)
4667 align = MAX (align, TYPE_ALIGN (type));
4669 return align;
4672 /* Return 1 for an operand in small memory on V.4/eabi. */
4675 small_data_operand (rtx op ATTRIBUTE_UNUSED,
4676 enum machine_mode mode ATTRIBUTE_UNUSED)
4678 #if TARGET_ELF
4679 rtx sym_ref;
4681 if (rs6000_sdata == SDATA_NONE || rs6000_sdata == SDATA_DATA)
4682 return 0;
4684 if (DEFAULT_ABI != ABI_V4)
4685 return 0;
4687 /* Vector and float memory instructions have a limited offset on the
4688 SPE, so using a vector or float variable directly as an operand is
4689 not useful. */
4690 if (TARGET_SPE
4691 && (SPE_VECTOR_MODE (mode) || FLOAT_MODE_P (mode)))
4692 return 0;
4694 if (GET_CODE (op) == SYMBOL_REF)
4695 sym_ref = op;
4697 else if (GET_CODE (op) != CONST
4698 || GET_CODE (XEXP (op, 0)) != PLUS
4699 || GET_CODE (XEXP (XEXP (op, 0), 0)) != SYMBOL_REF
4700 || GET_CODE (XEXP (XEXP (op, 0), 1)) != CONST_INT)
4701 return 0;
4703 else
4705 rtx sum = XEXP (op, 0);
4706 HOST_WIDE_INT summand;
4708 /* We have to be careful here, because it is the referenced address
4709 that must be 32k from _SDA_BASE_, not just the symbol. */
4710 summand = INTVAL (XEXP (sum, 1));
4711 if (summand < 0 || (unsigned HOST_WIDE_INT) summand > g_switch_value)
4712 return 0;
4714 sym_ref = XEXP (sum, 0);
4717 return SYMBOL_REF_SMALL_P (sym_ref);
4718 #else
4719 return 0;
4720 #endif
4723 /* Return true if either operand is a general purpose register. */
4725 bool
4726 gpr_or_gpr_p (rtx op0, rtx op1)
4728 return ((REG_P (op0) && INT_REGNO_P (REGNO (op0)))
4729 || (REG_P (op1) && INT_REGNO_P (REGNO (op1))));
4733 /* Subroutines of rs6000_legitimize_address and rs6000_legitimate_address_p. */
4735 static bool
4736 reg_offset_addressing_ok_p (enum machine_mode mode)
4738 switch (mode)
4740 case V16QImode:
4741 case V8HImode:
4742 case V4SFmode:
4743 case V4SImode:
4744 case V2DFmode:
4745 case V2DImode:
4746 /* AltiVec/VSX vector modes. Only reg+reg addressing is valid. */
4747 if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode))
4748 return false;
4749 break;
4751 case V4HImode:
4752 case V2SImode:
4753 case V1DImode:
4754 case V2SFmode:
4755 /* Paired vector modes. Only reg+reg addressing is valid. */
4756 if (TARGET_PAIRED_FLOAT)
4757 return false;
4758 break;
4760 default:
4761 break;
4764 return true;
4767 static bool
4768 virtual_stack_registers_memory_p (rtx op)
4770 int regnum;
4772 if (GET_CODE (op) == REG)
4773 regnum = REGNO (op);
4775 else if (GET_CODE (op) == PLUS
4776 && GET_CODE (XEXP (op, 0)) == REG
4777 && GET_CODE (XEXP (op, 1)) == CONST_INT)
4778 regnum = REGNO (XEXP (op, 0));
4780 else
4781 return false;
4783 return (regnum >= FIRST_VIRTUAL_REGISTER
4784 && regnum <= LAST_VIRTUAL_REGISTER);
4787 static bool
4788 constant_pool_expr_p (rtx op)
4790 rtx base, offset;
4792 split_const (op, &base, &offset);
4793 return (GET_CODE (base) == SYMBOL_REF
4794 && CONSTANT_POOL_ADDRESS_P (base)
4795 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (base), Pmode));
4798 bool
4799 toc_relative_expr_p (rtx op)
4801 rtx base, offset;
4803 if (GET_CODE (op) != CONST)
4804 return false;
4806 split_const (op, &base, &offset);
4807 return (GET_CODE (base) == UNSPEC
4808 && XINT (base, 1) == UNSPEC_TOCREL);
4811 bool
4812 legitimate_constant_pool_address_p (rtx x)
4814 return (TARGET_TOC
4815 && GET_CODE (x) == PLUS
4816 && GET_CODE (XEXP (x, 0)) == REG
4817 && (TARGET_MINIMAL_TOC || REGNO (XEXP (x, 0)) == TOC_REGISTER)
4818 && toc_relative_expr_p (XEXP (x, 1)));
4821 static bool
4822 legitimate_small_data_p (enum machine_mode mode, rtx x)
4824 return (DEFAULT_ABI == ABI_V4
4825 && !flag_pic && !TARGET_TOC
4826 && (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST)
4827 && small_data_operand (x, mode));
4830 /* SPE offset addressing is limited to 5-bits worth of double words. */
4831 #define SPE_CONST_OFFSET_OK(x) (((x) & ~0xf8) == 0)
4833 bool
4834 rs6000_legitimate_offset_address_p (enum machine_mode mode, rtx x, int strict)
4836 unsigned HOST_WIDE_INT offset, extra;
4838 if (GET_CODE (x) != PLUS)
4839 return false;
4840 if (GET_CODE (XEXP (x, 0)) != REG)
4841 return false;
4842 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
4843 return false;
4844 if (!reg_offset_addressing_ok_p (mode))
4845 return virtual_stack_registers_memory_p (x);
4846 if (legitimate_constant_pool_address_p (x))
4847 return true;
4848 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
4849 return false;
4851 offset = INTVAL (XEXP (x, 1));
4852 extra = 0;
4853 switch (mode)
4855 case V4HImode:
4856 case V2SImode:
4857 case V1DImode:
4858 case V2SFmode:
4859 /* SPE vector modes. */
4860 return SPE_CONST_OFFSET_OK (offset);
4862 case DFmode:
4863 if (TARGET_E500_DOUBLE)
4864 return SPE_CONST_OFFSET_OK (offset);
4866 /* If we are using VSX scalar loads, restrict ourselves to reg+reg
4867 addressing. */
4868 if (VECTOR_MEM_VSX_P (DFmode))
4869 return false;
4871 case DDmode:
4872 case DImode:
4873 /* On e500v2, we may have:
4875 (subreg:DF (mem:DI (plus (reg) (const_int))) 0).
4877 Which gets addressed with evldd instructions. */
4878 if (TARGET_E500_DOUBLE)
4879 return SPE_CONST_OFFSET_OK (offset);
4881 if (mode == DFmode || mode == DDmode || !TARGET_POWERPC64)
4882 extra = 4;
4883 else if (offset & 3)
4884 return false;
4885 break;
4887 case TFmode:
4888 if (TARGET_E500_DOUBLE)
4889 return (SPE_CONST_OFFSET_OK (offset)
4890 && SPE_CONST_OFFSET_OK (offset + 8));
4892 case TDmode:
4893 case TImode:
4894 if (mode == TFmode || mode == TDmode || !TARGET_POWERPC64)
4895 extra = 12;
4896 else if (offset & 3)
4897 return false;
4898 else
4899 extra = 8;
4900 break;
4902 default:
4903 break;
4906 offset += 0x8000;
4907 return (offset < 0x10000) && (offset + extra < 0x10000);
4910 bool
4911 legitimate_indexed_address_p (rtx x, int strict)
4913 rtx op0, op1;
4915 if (GET_CODE (x) != PLUS)
4916 return false;
4918 op0 = XEXP (x, 0);
4919 op1 = XEXP (x, 1);
4921 /* Recognize the rtl generated by reload which we know will later be
4922 replaced with proper base and index regs. */
4923 if (!strict
4924 && reload_in_progress
4925 && (REG_P (op0) || GET_CODE (op0) == PLUS)
4926 && REG_P (op1))
4927 return true;
4929 return (REG_P (op0) && REG_P (op1)
4930 && ((INT_REG_OK_FOR_BASE_P (op0, strict)
4931 && INT_REG_OK_FOR_INDEX_P (op1, strict))
4932 || (INT_REG_OK_FOR_BASE_P (op1, strict)
4933 && INT_REG_OK_FOR_INDEX_P (op0, strict))));
4936 bool
4937 avoiding_indexed_address_p (enum machine_mode mode)
4939 /* Avoid indexed addressing for modes that have non-indexed
4940 load/store instruction forms. */
4941 return (TARGET_AVOID_XFORM && VECTOR_MEM_NONE_P (mode));
4944 inline bool
4945 legitimate_indirect_address_p (rtx x, int strict)
4947 return GET_CODE (x) == REG && INT_REG_OK_FOR_BASE_P (x, strict);
4950 bool
4951 macho_lo_sum_memory_operand (rtx x, enum machine_mode mode)
4953 if (!TARGET_MACHO || !flag_pic
4954 || mode != SImode || GET_CODE (x) != MEM)
4955 return false;
4956 x = XEXP (x, 0);
4958 if (GET_CODE (x) != LO_SUM)
4959 return false;
4960 if (GET_CODE (XEXP (x, 0)) != REG)
4961 return false;
4962 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 0))
4963 return false;
4964 x = XEXP (x, 1);
4966 return CONSTANT_P (x);
4969 static bool
4970 legitimate_lo_sum_address_p (enum machine_mode mode, rtx x, int strict)
4972 if (GET_CODE (x) != LO_SUM)
4973 return false;
4974 if (GET_CODE (XEXP (x, 0)) != REG)
4975 return false;
4976 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
4977 return false;
4978 /* Restrict addressing for DI because of our SUBREG hackery. */
4979 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
4980 || mode == DDmode || mode == TDmode
4981 || mode == DImode))
4982 return false;
4983 x = XEXP (x, 1);
4985 if (TARGET_ELF || TARGET_MACHO)
4987 if (DEFAULT_ABI != ABI_AIX && DEFAULT_ABI != ABI_DARWIN && flag_pic)
4988 return false;
4989 if (TARGET_TOC)
4990 return false;
4991 if (GET_MODE_NUNITS (mode) != 1)
4992 return false;
4993 if (GET_MODE_BITSIZE (mode) > 64
4994 || (GET_MODE_BITSIZE (mode) > 32 && !TARGET_POWERPC64
4995 && !(TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
4996 && (mode == DFmode || mode == DDmode))))
4997 return false;
4999 return CONSTANT_P (x);
5002 return false;
5006 /* Try machine-dependent ways of modifying an illegitimate address
5007 to be legitimate. If we find one, return the new, valid address.
5008 This is used from only one place: `memory_address' in explow.c.
5010 OLDX is the address as it was before break_out_memory_refs was
5011 called. In some cases it is useful to look at this to decide what
5012 needs to be done.
5014 It is always safe for this function to do nothing. It exists to
5015 recognize opportunities to optimize the output.
5017 On RS/6000, first check for the sum of a register with a constant
5018 integer that is out of range. If so, generate code to add the
5019 constant with the low-order 16 bits masked to the register and force
5020 this result into another register (this can be done with `cau').
5021 Then generate an address of REG+(CONST&0xffff), allowing for the
5022 possibility of bit 16 being a one.
5024 Then check for the sum of a register and something not constant, try to
5025 load the other things into a register and return the sum. */
5027 static rtx
5028 rs6000_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
5029 enum machine_mode mode)
5031 unsigned int extra = 0;
5033 if (!reg_offset_addressing_ok_p (mode))
5035 if (virtual_stack_registers_memory_p (x))
5036 return x;
5038 /* In theory we should not be seeing addresses of the form reg+0,
5039 but just in case it is generated, optimize it away. */
5040 if (GET_CODE (x) == PLUS && XEXP (x, 1) == const0_rtx)
5041 return force_reg (Pmode, XEXP (x, 0));
5043 /* Make sure both operands are registers. */
5044 else if (GET_CODE (x) == PLUS)
5045 return gen_rtx_PLUS (Pmode,
5046 force_reg (Pmode, XEXP (x, 0)),
5047 force_reg (Pmode, XEXP (x, 1)));
5048 else
5049 return force_reg (Pmode, x);
5051 if (GET_CODE (x) == SYMBOL_REF)
5053 enum tls_model model = SYMBOL_REF_TLS_MODEL (x);
5054 if (model != 0)
5055 return rs6000_legitimize_tls_address (x, model);
5058 switch (mode)
5060 case DFmode:
5061 case DDmode:
5062 extra = 4;
5063 break;
5064 case DImode:
5065 if (!TARGET_POWERPC64)
5066 extra = 4;
5067 break;
5068 case TFmode:
5069 case TDmode:
5070 extra = 12;
5071 break;
5072 case TImode:
5073 extra = TARGET_POWERPC64 ? 8 : 12;
5074 break;
5075 default:
5076 break;
5079 if (GET_CODE (x) == PLUS
5080 && GET_CODE (XEXP (x, 0)) == REG
5081 && GET_CODE (XEXP (x, 1)) == CONST_INT
5082 && ((unsigned HOST_WIDE_INT) (INTVAL (XEXP (x, 1)) + 0x8000)
5083 >= 0x10000 - extra)
5084 && !((TARGET_POWERPC64
5085 && (mode == DImode || mode == TImode)
5086 && (INTVAL (XEXP (x, 1)) & 3) != 0)
5087 || SPE_VECTOR_MODE (mode)
5088 || (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
5089 || mode == DImode || mode == DDmode
5090 || mode == TDmode))))
5092 HOST_WIDE_INT high_int, low_int;
5093 rtx sum;
5094 low_int = ((INTVAL (XEXP (x, 1)) & 0xffff) ^ 0x8000) - 0x8000;
5095 if (low_int >= 0x8000 - extra)
5096 low_int = 0;
5097 high_int = INTVAL (XEXP (x, 1)) - low_int;
5098 sum = force_operand (gen_rtx_PLUS (Pmode, XEXP (x, 0),
5099 GEN_INT (high_int)), 0);
5100 return plus_constant (sum, low_int);
5102 else if (GET_CODE (x) == PLUS
5103 && GET_CODE (XEXP (x, 0)) == REG
5104 && GET_CODE (XEXP (x, 1)) != CONST_INT
5105 && GET_MODE_NUNITS (mode) == 1
5106 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5107 || TARGET_POWERPC64
5108 || ((mode != DImode && mode != DFmode && mode != DDmode)
5109 || (TARGET_E500_DOUBLE && mode != DDmode)))
5110 && (TARGET_POWERPC64 || mode != DImode)
5111 && !avoiding_indexed_address_p (mode)
5112 && mode != TImode
5113 && mode != TFmode
5114 && mode != TDmode)
5116 return gen_rtx_PLUS (Pmode, XEXP (x, 0),
5117 force_reg (Pmode, force_operand (XEXP (x, 1), 0)));
5119 else if (SPE_VECTOR_MODE (mode)
5120 || (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
5121 || mode == DDmode || mode == TDmode
5122 || mode == DImode)))
5124 if (mode == DImode)
5125 return x;
5126 /* We accept [reg + reg] and [reg + OFFSET]. */
5128 if (GET_CODE (x) == PLUS)
5130 rtx op1 = XEXP (x, 0);
5131 rtx op2 = XEXP (x, 1);
5132 rtx y;
5134 op1 = force_reg (Pmode, op1);
5136 if (GET_CODE (op2) != REG
5137 && (GET_CODE (op2) != CONST_INT
5138 || !SPE_CONST_OFFSET_OK (INTVAL (op2))
5139 || (GET_MODE_SIZE (mode) > 8
5140 && !SPE_CONST_OFFSET_OK (INTVAL (op2) + 8))))
5141 op2 = force_reg (Pmode, op2);
5143 /* We can't always do [reg + reg] for these, because [reg +
5144 reg + offset] is not a legitimate addressing mode. */
5145 y = gen_rtx_PLUS (Pmode, op1, op2);
5147 if ((GET_MODE_SIZE (mode) > 8 || mode == DDmode) && REG_P (op2))
5148 return force_reg (Pmode, y);
5149 else
5150 return y;
5153 return force_reg (Pmode, x);
5155 else if (TARGET_ELF
5156 && TARGET_32BIT
5157 && TARGET_NO_TOC
5158 && ! flag_pic
5159 && GET_CODE (x) != CONST_INT
5160 && GET_CODE (x) != CONST_DOUBLE
5161 && CONSTANT_P (x)
5162 && GET_MODE_NUNITS (mode) == 1
5163 && (GET_MODE_BITSIZE (mode) <= 32
5164 || ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5165 && (mode == DFmode || mode == DDmode))))
5167 rtx reg = gen_reg_rtx (Pmode);
5168 emit_insn (gen_elf_high (reg, x));
5169 return gen_rtx_LO_SUM (Pmode, reg, x);
5171 else if (TARGET_MACHO && TARGET_32BIT && TARGET_NO_TOC
5172 && ! flag_pic
5173 #if TARGET_MACHO
5174 && ! MACHO_DYNAMIC_NO_PIC_P
5175 #endif
5176 && GET_CODE (x) != CONST_INT
5177 && GET_CODE (x) != CONST_DOUBLE
5178 && CONSTANT_P (x)
5179 && GET_MODE_NUNITS (mode) == 1
5180 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5181 || (mode != DFmode && mode != DDmode))
5182 && mode != DImode
5183 && mode != TImode)
5185 rtx reg = gen_reg_rtx (Pmode);
5186 emit_insn (gen_macho_high (reg, x));
5187 return gen_rtx_LO_SUM (Pmode, reg, x);
5189 else if (TARGET_TOC
5190 && GET_CODE (x) == SYMBOL_REF
5191 && constant_pool_expr_p (x)
5192 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), Pmode))
5194 return create_TOC_reference (x);
5196 else
5197 return x;
5200 /* Debug version of rs6000_legitimize_address. */
5201 static rtx
5202 rs6000_debug_legitimize_address (rtx x, rtx oldx, enum machine_mode mode)
5204 rtx ret;
5205 rtx insns;
5207 start_sequence ();
5208 ret = rs6000_legitimize_address (x, oldx, mode);
5209 insns = get_insns ();
5210 end_sequence ();
5212 if (ret != x)
5214 fprintf (stderr,
5215 "\nrs6000_legitimize_address: mode %s, old code %s, "
5216 "new code %s, modified\n",
5217 GET_MODE_NAME (mode), GET_RTX_NAME (GET_CODE (x)),
5218 GET_RTX_NAME (GET_CODE (ret)));
5220 fprintf (stderr, "Original address:\n");
5221 debug_rtx (x);
5223 fprintf (stderr, "oldx:\n");
5224 debug_rtx (oldx);
5226 fprintf (stderr, "New address:\n");
5227 debug_rtx (ret);
5229 if (insns)
5231 fprintf (stderr, "Insns added:\n");
5232 debug_rtx_list (insns, 20);
5235 else
5237 fprintf (stderr,
5238 "\nrs6000_legitimize_address: mode %s, code %s, no change:\n",
5239 GET_MODE_NAME (mode), GET_RTX_NAME (GET_CODE (x)));
5241 debug_rtx (x);
5244 if (insns)
5245 emit_insn (insns);
5247 return ret;
5250 /* This is called from dwarf2out.c via TARGET_ASM_OUTPUT_DWARF_DTPREL.
5251 We need to emit DTP-relative relocations. */
5253 static void
5254 rs6000_output_dwarf_dtprel (FILE *file, int size, rtx x)
5256 switch (size)
5258 case 4:
5259 fputs ("\t.long\t", file);
5260 break;
5261 case 8:
5262 fputs (DOUBLE_INT_ASM_OP, file);
5263 break;
5264 default:
5265 gcc_unreachable ();
5267 output_addr_const (file, x);
5268 fputs ("@dtprel+0x8000", file);
5271 /* In the name of slightly smaller debug output, and to cater to
5272 general assembler lossage, recognize various UNSPEC sequences
5273 and turn them back into a direct symbol reference. */
5275 static rtx
5276 rs6000_delegitimize_address (rtx orig_x)
5278 rtx x, y;
5280 orig_x = delegitimize_mem_from_attrs (orig_x);
5281 x = orig_x;
5282 if (MEM_P (x))
5283 x = XEXP (x, 0);
5285 if (GET_CODE (x) == PLUS
5286 && GET_CODE (XEXP (x, 1)) == CONST
5287 && GET_CODE (XEXP (x, 0)) == REG
5288 && REGNO (XEXP (x, 0)) == TOC_REGISTER)
5290 y = XEXP (XEXP (x, 1), 0);
5291 if (GET_CODE (y) == UNSPEC
5292 && XINT (y, 1) == UNSPEC_TOCREL)
5294 y = XVECEXP (y, 0, 0);
5295 if (!MEM_P (orig_x))
5296 return y;
5297 else
5298 return replace_equiv_address_nv (orig_x, y);
5300 return orig_x;
5303 if (TARGET_MACHO
5304 && GET_CODE (orig_x) == LO_SUM
5305 && GET_CODE (XEXP (x, 1)) == CONST)
5307 y = XEXP (XEXP (x, 1), 0);
5308 if (GET_CODE (y) == UNSPEC
5309 && XINT (y, 1) == UNSPEC_MACHOPIC_OFFSET)
5310 return XVECEXP (y, 0, 0);
5313 return orig_x;
5316 /* Construct the SYMBOL_REF for the tls_get_addr function. */
5318 static GTY(()) rtx rs6000_tls_symbol;
5319 static rtx
5320 rs6000_tls_get_addr (void)
5322 if (!rs6000_tls_symbol)
5323 rs6000_tls_symbol = init_one_libfunc ("__tls_get_addr");
5325 return rs6000_tls_symbol;
5328 /* Construct the SYMBOL_REF for TLS GOT references. */
5330 static GTY(()) rtx rs6000_got_symbol;
5331 static rtx
5332 rs6000_got_sym (void)
5334 if (!rs6000_got_symbol)
5336 rs6000_got_symbol = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
5337 SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_LOCAL;
5338 SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_EXTERNAL;
5341 return rs6000_got_symbol;
5344 /* ADDR contains a thread-local SYMBOL_REF. Generate code to compute
5345 this (thread-local) address. */
5347 static rtx
5348 rs6000_legitimize_tls_address (rtx addr, enum tls_model model)
5350 rtx dest, insn;
5352 dest = gen_reg_rtx (Pmode);
5353 if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 16)
5355 rtx tlsreg;
5357 if (TARGET_64BIT)
5359 tlsreg = gen_rtx_REG (Pmode, 13);
5360 insn = gen_tls_tprel_64 (dest, tlsreg, addr);
5362 else
5364 tlsreg = gen_rtx_REG (Pmode, 2);
5365 insn = gen_tls_tprel_32 (dest, tlsreg, addr);
5367 emit_insn (insn);
5369 else if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 32)
5371 rtx tlsreg, tmp;
5373 tmp = gen_reg_rtx (Pmode);
5374 if (TARGET_64BIT)
5376 tlsreg = gen_rtx_REG (Pmode, 13);
5377 insn = gen_tls_tprel_ha_64 (tmp, tlsreg, addr);
5379 else
5381 tlsreg = gen_rtx_REG (Pmode, 2);
5382 insn = gen_tls_tprel_ha_32 (tmp, tlsreg, addr);
5384 emit_insn (insn);
5385 if (TARGET_64BIT)
5386 insn = gen_tls_tprel_lo_64 (dest, tmp, addr);
5387 else
5388 insn = gen_tls_tprel_lo_32 (dest, tmp, addr);
5389 emit_insn (insn);
5391 else
5393 rtx r3, got, tga, tmp1, tmp2, eqv;
5395 /* We currently use relocations like @got@tlsgd for tls, which
5396 means the linker will handle allocation of tls entries, placing
5397 them in the .got section. So use a pointer to the .got section,
5398 not one to secondary TOC sections used by 64-bit -mminimal-toc,
5399 or to secondary GOT sections used by 32-bit -fPIC. */
5400 if (TARGET_64BIT)
5401 got = gen_rtx_REG (Pmode, 2);
5402 else
5404 if (flag_pic == 1)
5405 got = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
5406 else
5408 rtx gsym = rs6000_got_sym ();
5409 got = gen_reg_rtx (Pmode);
5410 if (flag_pic == 0)
5411 rs6000_emit_move (got, gsym, Pmode);
5412 else
5414 rtx tmp3, mem;
5415 rtx first, last;
5417 tmp1 = gen_reg_rtx (Pmode);
5418 tmp2 = gen_reg_rtx (Pmode);
5419 tmp3 = gen_reg_rtx (Pmode);
5420 mem = gen_const_mem (Pmode, tmp1);
5422 first = emit_insn (gen_load_toc_v4_PIC_1b (gsym));
5423 emit_move_insn (tmp1,
5424 gen_rtx_REG (Pmode, LR_REGNO));
5425 emit_move_insn (tmp2, mem);
5426 emit_insn (gen_addsi3 (tmp3, tmp1, tmp2));
5427 last = emit_move_insn (got, tmp3);
5428 set_unique_reg_note (last, REG_EQUAL, gsym);
5433 if (model == TLS_MODEL_GLOBAL_DYNAMIC)
5435 r3 = gen_rtx_REG (Pmode, 3);
5436 tga = rs6000_tls_get_addr ();
5438 if (DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
5439 insn = gen_tls_gd_aix64 (r3, got, addr, tga, const0_rtx);
5440 else if (DEFAULT_ABI == ABI_AIX && !TARGET_64BIT)
5441 insn = gen_tls_gd_aix32 (r3, got, addr, tga, const0_rtx);
5442 else if (DEFAULT_ABI == ABI_V4)
5443 insn = gen_tls_gd_sysvsi (r3, got, addr, tga, const0_rtx);
5444 else
5445 gcc_unreachable ();
5447 start_sequence ();
5448 insn = emit_call_insn (insn);
5449 RTL_CONST_CALL_P (insn) = 1;
5450 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), r3);
5451 if (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
5452 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), pic_offset_table_rtx);
5453 insn = get_insns ();
5454 end_sequence ();
5455 emit_libcall_block (insn, dest, r3, addr);
5457 else if (model == TLS_MODEL_LOCAL_DYNAMIC)
5459 r3 = gen_rtx_REG (Pmode, 3);
5460 tga = rs6000_tls_get_addr ();
5462 if (DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
5463 insn = gen_tls_ld_aix64 (r3, got, tga, const0_rtx);
5464 else if (DEFAULT_ABI == ABI_AIX && !TARGET_64BIT)
5465 insn = gen_tls_ld_aix32 (r3, got, tga, const0_rtx);
5466 else if (DEFAULT_ABI == ABI_V4)
5467 insn = gen_tls_ld_sysvsi (r3, got, tga, const0_rtx);
5468 else
5469 gcc_unreachable ();
5471 start_sequence ();
5472 insn = emit_call_insn (insn);
5473 RTL_CONST_CALL_P (insn) = 1;
5474 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), r3);
5475 if (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
5476 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), pic_offset_table_rtx);
5477 insn = get_insns ();
5478 end_sequence ();
5479 tmp1 = gen_reg_rtx (Pmode);
5480 eqv = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
5481 UNSPEC_TLSLD);
5482 emit_libcall_block (insn, tmp1, r3, eqv);
5483 if (rs6000_tls_size == 16)
5485 if (TARGET_64BIT)
5486 insn = gen_tls_dtprel_64 (dest, tmp1, addr);
5487 else
5488 insn = gen_tls_dtprel_32 (dest, tmp1, addr);
5490 else if (rs6000_tls_size == 32)
5492 tmp2 = gen_reg_rtx (Pmode);
5493 if (TARGET_64BIT)
5494 insn = gen_tls_dtprel_ha_64 (tmp2, tmp1, addr);
5495 else
5496 insn = gen_tls_dtprel_ha_32 (tmp2, tmp1, addr);
5497 emit_insn (insn);
5498 if (TARGET_64BIT)
5499 insn = gen_tls_dtprel_lo_64 (dest, tmp2, addr);
5500 else
5501 insn = gen_tls_dtprel_lo_32 (dest, tmp2, addr);
5503 else
5505 tmp2 = gen_reg_rtx (Pmode);
5506 if (TARGET_64BIT)
5507 insn = gen_tls_got_dtprel_64 (tmp2, got, addr);
5508 else
5509 insn = gen_tls_got_dtprel_32 (tmp2, got, addr);
5510 emit_insn (insn);
5511 insn = gen_rtx_SET (Pmode, dest,
5512 gen_rtx_PLUS (Pmode, tmp2, tmp1));
5514 emit_insn (insn);
5516 else
5518 /* IE, or 64-bit offset LE. */
5519 tmp2 = gen_reg_rtx (Pmode);
5520 if (TARGET_64BIT)
5521 insn = gen_tls_got_tprel_64 (tmp2, got, addr);
5522 else
5523 insn = gen_tls_got_tprel_32 (tmp2, got, addr);
5524 emit_insn (insn);
5525 if (TARGET_64BIT)
5526 insn = gen_tls_tls_64 (dest, tmp2, addr);
5527 else
5528 insn = gen_tls_tls_32 (dest, tmp2, addr);
5529 emit_insn (insn);
5533 return dest;
5536 /* Return 1 if X contains a thread-local symbol. */
5538 bool
5539 rs6000_tls_referenced_p (rtx x)
5541 if (! TARGET_HAVE_TLS)
5542 return false;
5544 return for_each_rtx (&x, &rs6000_tls_symbol_ref_1, 0);
5547 /* Return 1 if *X is a thread-local symbol. This is the same as
5548 rs6000_tls_symbol_ref except for the type of the unused argument. */
5550 static int
5551 rs6000_tls_symbol_ref_1 (rtx *x, void *data ATTRIBUTE_UNUSED)
5553 return RS6000_SYMBOL_REF_TLS_P (*x);
5556 /* Our implementation of LEGITIMIZE_RELOAD_ADDRESS. Returns a value to
5557 replace the input X, or the original X if no replacement is called for.
5558 The output parameter *WIN is 1 if the calling macro should goto WIN,
5559 0 if it should not.
5561 For RS/6000, we wish to handle large displacements off a base
5562 register by splitting the addend across an addiu/addis and the mem insn.
5563 This cuts number of extra insns needed from 3 to 1.
5565 On Darwin, we use this to generate code for floating point constants.
5566 A movsf_low is generated so we wind up with 2 instructions rather than 3.
5567 The Darwin code is inside #if TARGET_MACHO because only then are the
5568 machopic_* functions defined. */
5569 static rtx
5570 rs6000_legitimize_reload_address (rtx x, enum machine_mode mode,
5571 int opnum, int type,
5572 int ind_levels ATTRIBUTE_UNUSED, int *win)
5574 bool reg_offset_p = reg_offset_addressing_ok_p (mode);
5576 /* We must recognize output that we have already generated ourselves. */
5577 if (GET_CODE (x) == PLUS
5578 && GET_CODE (XEXP (x, 0)) == PLUS
5579 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
5580 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
5581 && GET_CODE (XEXP (x, 1)) == CONST_INT)
5583 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
5584 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
5585 opnum, (enum reload_type)type);
5586 *win = 1;
5587 return x;
5590 #if TARGET_MACHO
5591 if (DEFAULT_ABI == ABI_DARWIN && flag_pic
5592 && GET_CODE (x) == LO_SUM
5593 && GET_CODE (XEXP (x, 0)) == PLUS
5594 && XEXP (XEXP (x, 0), 0) == pic_offset_table_rtx
5595 && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH
5596 && XEXP (XEXP (XEXP (x, 0), 1), 0) == XEXP (x, 1)
5597 && machopic_operand_p (XEXP (x, 1)))
5599 /* Result of previous invocation of this function on Darwin
5600 floating point constant. */
5601 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
5602 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
5603 opnum, (enum reload_type)type);
5604 *win = 1;
5605 return x;
5607 #endif
5609 /* Force ld/std non-word aligned offset into base register by wrapping
5610 in offset 0. */
5611 if (GET_CODE (x) == PLUS
5612 && GET_CODE (XEXP (x, 0)) == REG
5613 && REGNO (XEXP (x, 0)) < 32
5614 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 1)
5615 && GET_CODE (XEXP (x, 1)) == CONST_INT
5616 && reg_offset_p
5617 && (INTVAL (XEXP (x, 1)) & 3) != 0
5618 && VECTOR_MEM_NONE_P (mode)
5619 && GET_MODE_SIZE (mode) >= UNITS_PER_WORD
5620 && TARGET_POWERPC64)
5622 x = gen_rtx_PLUS (GET_MODE (x), x, GEN_INT (0));
5623 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
5624 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
5625 opnum, (enum reload_type) type);
5626 *win = 1;
5627 return x;
5630 if (GET_CODE (x) == PLUS
5631 && GET_CODE (XEXP (x, 0)) == REG
5632 && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER
5633 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 1)
5634 && GET_CODE (XEXP (x, 1)) == CONST_INT
5635 && reg_offset_p
5636 && !SPE_VECTOR_MODE (mode)
5637 && !(TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
5638 || mode == DDmode || mode == TDmode
5639 || mode == DImode))
5640 && VECTOR_MEM_NONE_P (mode))
5642 HOST_WIDE_INT val = INTVAL (XEXP (x, 1));
5643 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
5644 HOST_WIDE_INT high
5645 = (((val - low) & 0xffffffff) ^ 0x80000000) - 0x80000000;
5647 /* Check for 32-bit overflow. */
5648 if (high + low != val)
5650 *win = 0;
5651 return x;
5654 /* Reload the high part into a base reg; leave the low part
5655 in the mem directly. */
5657 x = gen_rtx_PLUS (GET_MODE (x),
5658 gen_rtx_PLUS (GET_MODE (x), XEXP (x, 0),
5659 GEN_INT (high)),
5660 GEN_INT (low));
5662 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
5663 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
5664 opnum, (enum reload_type)type);
5665 *win = 1;
5666 return x;
5669 if (GET_CODE (x) == SYMBOL_REF
5670 && reg_offset_p
5671 && VECTOR_MEM_NONE_P (mode)
5672 && !SPE_VECTOR_MODE (mode)
5673 #if TARGET_MACHO
5674 && DEFAULT_ABI == ABI_DARWIN
5675 && (flag_pic || MACHO_DYNAMIC_NO_PIC_P)
5676 #else
5677 && DEFAULT_ABI == ABI_V4
5678 && !flag_pic
5679 #endif
5680 /* Don't do this for TFmode or TDmode, since the result isn't offsettable.
5681 The same goes for DImode without 64-bit gprs and DFmode and DDmode
5682 without fprs. */
5683 && mode != TFmode
5684 && mode != TDmode
5685 && (mode != DImode || TARGET_POWERPC64)
5686 && ((mode != DFmode && mode != DDmode) || TARGET_POWERPC64
5687 || (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)))
5689 #if TARGET_MACHO
5690 if (flag_pic)
5692 rtx offset = machopic_gen_offset (x);
5693 x = gen_rtx_LO_SUM (GET_MODE (x),
5694 gen_rtx_PLUS (Pmode, pic_offset_table_rtx,
5695 gen_rtx_HIGH (Pmode, offset)), offset);
5697 else
5698 #endif
5699 x = gen_rtx_LO_SUM (GET_MODE (x),
5700 gen_rtx_HIGH (Pmode, x), x);
5702 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
5703 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
5704 opnum, (enum reload_type)type);
5705 *win = 1;
5706 return x;
5709 /* Reload an offset address wrapped by an AND that represents the
5710 masking of the lower bits. Strip the outer AND and let reload
5711 convert the offset address into an indirect address. For VSX,
5712 force reload to create the address with an AND in a separate
5713 register, because we can't guarantee an altivec register will
5714 be used. */
5715 if (VECTOR_MEM_ALTIVEC_P (mode)
5716 && GET_CODE (x) == AND
5717 && GET_CODE (XEXP (x, 0)) == PLUS
5718 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
5719 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
5720 && GET_CODE (XEXP (x, 1)) == CONST_INT
5721 && INTVAL (XEXP (x, 1)) == -16)
5723 x = XEXP (x, 0);
5724 *win = 1;
5725 return x;
5728 if (TARGET_TOC
5729 && reg_offset_p
5730 && GET_CODE (x) == SYMBOL_REF
5731 && constant_pool_expr_p (x)
5732 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), mode))
5734 x = create_TOC_reference (x);
5735 *win = 1;
5736 return x;
5738 *win = 0;
5739 return x;
5742 /* Debug version of rs6000_legitimize_reload_address. */
5743 static rtx
5744 rs6000_debug_legitimize_reload_address (rtx x, enum machine_mode mode,
5745 int opnum, int type,
5746 int ind_levels, int *win)
5748 rtx ret = rs6000_legitimize_reload_address (x, mode, opnum, type,
5749 ind_levels, win);
5750 fprintf (stderr,
5751 "\nrs6000_legitimize_reload_address: mode = %s, opnum = %d, "
5752 "type = %d, ind_levels = %d, win = %d, original addr:\n",
5753 GET_MODE_NAME (mode), opnum, type, ind_levels, *win);
5754 debug_rtx (x);
5756 if (x == ret)
5757 fprintf (stderr, "Same address returned\n");
5758 else if (!ret)
5759 fprintf (stderr, "NULL returned\n");
5760 else
5762 fprintf (stderr, "New address:\n");
5763 debug_rtx (ret);
5766 return ret;
5769 /* TARGET_LEGITIMATE_ADDRESS_P recognizes an RTL expression
5770 that is a valid memory address for an instruction.
5771 The MODE argument is the machine mode for the MEM expression
5772 that wants to use this address.
5774 On the RS/6000, there are four valid address: a SYMBOL_REF that
5775 refers to a constant pool entry of an address (or the sum of it
5776 plus a constant), a short (16-bit signed) constant plus a register,
5777 the sum of two registers, or a register indirect, possibly with an
5778 auto-increment. For DFmode, DDmode and DImode with a constant plus
5779 register, we must ensure that both words are addressable or PowerPC64
5780 with offset word aligned.
5782 For modes spanning multiple registers (DFmode and DDmode in 32-bit GPRs,
5783 32-bit DImode, TImode, TFmode, TDmode), indexed addressing cannot be used
5784 because adjacent memory cells are accessed by adding word-sized offsets
5785 during assembly output. */
5786 bool
5787 rs6000_legitimate_address_p (enum machine_mode mode, rtx x, bool reg_ok_strict)
5789 bool reg_offset_p = reg_offset_addressing_ok_p (mode);
5791 /* If this is an unaligned stvx/ldvx type address, discard the outer AND. */
5792 if (VECTOR_MEM_ALTIVEC_P (mode)
5793 && GET_CODE (x) == AND
5794 && GET_CODE (XEXP (x, 1)) == CONST_INT
5795 && INTVAL (XEXP (x, 1)) == -16)
5796 x = XEXP (x, 0);
5798 if (RS6000_SYMBOL_REF_TLS_P (x))
5799 return 0;
5800 if (legitimate_indirect_address_p (x, reg_ok_strict))
5801 return 1;
5802 if ((GET_CODE (x) == PRE_INC || GET_CODE (x) == PRE_DEC)
5803 && !VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)
5804 && !SPE_VECTOR_MODE (mode)
5805 && mode != TFmode
5806 && mode != TDmode
5807 /* Restrict addressing for DI because of our SUBREG hackery. */
5808 && !(TARGET_E500_DOUBLE
5809 && (mode == DFmode || mode == DDmode || mode == DImode))
5810 && TARGET_UPDATE
5811 && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict))
5812 return 1;
5813 if (virtual_stack_registers_memory_p (x))
5814 return 1;
5815 if (reg_offset_p && legitimate_small_data_p (mode, x))
5816 return 1;
5817 if (reg_offset_p && legitimate_constant_pool_address_p (x))
5818 return 1;
5819 /* If not REG_OK_STRICT (before reload) let pass any stack offset. */
5820 if (! reg_ok_strict
5821 && reg_offset_p
5822 && GET_CODE (x) == PLUS
5823 && GET_CODE (XEXP (x, 0)) == REG
5824 && (XEXP (x, 0) == virtual_stack_vars_rtx
5825 || XEXP (x, 0) == arg_pointer_rtx)
5826 && GET_CODE (XEXP (x, 1)) == CONST_INT)
5827 return 1;
5828 if (rs6000_legitimate_offset_address_p (mode, x, reg_ok_strict))
5829 return 1;
5830 if (mode != TImode
5831 && mode != TFmode
5832 && mode != TDmode
5833 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5834 || TARGET_POWERPC64
5835 || (mode != DFmode && mode != DDmode)
5836 || (TARGET_E500_DOUBLE && mode != DDmode))
5837 && (TARGET_POWERPC64 || mode != DImode)
5838 && !avoiding_indexed_address_p (mode)
5839 && legitimate_indexed_address_p (x, reg_ok_strict))
5840 return 1;
5841 if (GET_CODE (x) == PRE_MODIFY
5842 && mode != TImode
5843 && mode != TFmode
5844 && mode != TDmode
5845 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5846 || TARGET_POWERPC64
5847 || ((mode != DFmode && mode != DDmode) || TARGET_E500_DOUBLE))
5848 && (TARGET_POWERPC64 || mode != DImode)
5849 && !VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)
5850 && !SPE_VECTOR_MODE (mode)
5851 /* Restrict addressing for DI because of our SUBREG hackery. */
5852 && !(TARGET_E500_DOUBLE
5853 && (mode == DFmode || mode == DDmode || mode == DImode))
5854 && TARGET_UPDATE
5855 && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict)
5856 && (rs6000_legitimate_offset_address_p (mode, XEXP (x, 1), reg_ok_strict)
5857 || (!avoiding_indexed_address_p (mode)
5858 && legitimate_indexed_address_p (XEXP (x, 1), reg_ok_strict)))
5859 && rtx_equal_p (XEXP (XEXP (x, 1), 0), XEXP (x, 0)))
5860 return 1;
5861 if (reg_offset_p && legitimate_lo_sum_address_p (mode, x, reg_ok_strict))
5862 return 1;
5863 return 0;
5866 /* Debug version of rs6000_legitimate_address_p. */
5867 static bool
5868 rs6000_debug_legitimate_address_p (enum machine_mode mode, rtx x,
5869 bool reg_ok_strict)
5871 bool ret = rs6000_legitimate_address_p (mode, x, reg_ok_strict);
5872 fprintf (stderr,
5873 "\nrs6000_legitimate_address_p: return = %s, mode = %s, "
5874 "strict = %d, code = %s\n",
5875 ret ? "true" : "false",
5876 GET_MODE_NAME (mode),
5877 reg_ok_strict,
5878 GET_RTX_NAME (GET_CODE (x)));
5879 debug_rtx (x);
5881 return ret;
5884 /* Go to LABEL if ADDR (a legitimate address expression)
5885 has an effect that depends on the machine mode it is used for.
5887 On the RS/6000 this is true of all integral offsets (since AltiVec
5888 and VSX modes don't allow them) or is a pre-increment or decrement.
5890 ??? Except that due to conceptual problems in offsettable_address_p
5891 we can't really report the problems of integral offsets. So leave
5892 this assuming that the adjustable offset must be valid for the
5893 sub-words of a TFmode operand, which is what we had before. */
5895 static bool
5896 rs6000_mode_dependent_address (rtx addr)
5898 switch (GET_CODE (addr))
5900 case PLUS:
5901 /* Any offset from virtual_stack_vars_rtx and arg_pointer_rtx
5902 is considered a legitimate address before reload, so there
5903 are no offset restrictions in that case. Note that this
5904 condition is safe in strict mode because any address involving
5905 virtual_stack_vars_rtx or arg_pointer_rtx would already have
5906 been rejected as illegitimate. */
5907 if (XEXP (addr, 0) != virtual_stack_vars_rtx
5908 && XEXP (addr, 0) != arg_pointer_rtx
5909 && GET_CODE (XEXP (addr, 1)) == CONST_INT)
5911 unsigned HOST_WIDE_INT val = INTVAL (XEXP (addr, 1));
5912 return val + 12 + 0x8000 >= 0x10000;
5914 break;
5916 case LO_SUM:
5917 return true;
5919 /* Auto-increment cases are now treated generically in recog.c. */
5920 case PRE_MODIFY:
5921 return TARGET_UPDATE;
5923 /* AND is only allowed in Altivec loads. */
5924 case AND:
5925 return true;
5927 default:
5928 break;
5931 return false;
5934 /* Debug version of rs6000_mode_dependent_address. */
5935 static bool
5936 rs6000_debug_mode_dependent_address (rtx addr)
5938 bool ret = rs6000_mode_dependent_address (addr);
5940 fprintf (stderr, "\nrs6000_mode_dependent_address: ret = %s\n",
5941 ret ? "true" : "false");
5942 debug_rtx (addr);
5944 return ret;
5947 /* Implement FIND_BASE_TERM. */
5950 rs6000_find_base_term (rtx op)
5952 rtx base, offset;
5954 split_const (op, &base, &offset);
5955 if (GET_CODE (base) == UNSPEC)
5956 switch (XINT (base, 1))
5958 case UNSPEC_TOCREL:
5959 case UNSPEC_MACHOPIC_OFFSET:
5960 /* OP represents SYM [+ OFFSET] - ANCHOR. SYM is the base term
5961 for aliasing purposes. */
5962 return XVECEXP (base, 0, 0);
5965 return op;
5968 /* More elaborate version of recog's offsettable_memref_p predicate
5969 that works around the ??? note of rs6000_mode_dependent_address.
5970 In particular it accepts
5972 (mem:DI (plus:SI (reg/f:SI 31 31) (const_int 32760 [0x7ff8])))
5974 in 32-bit mode, that the recog predicate rejects. */
5976 bool
5977 rs6000_offsettable_memref_p (rtx op)
5979 if (!MEM_P (op))
5980 return false;
5982 /* First mimic offsettable_memref_p. */
5983 if (offsettable_address_p (1, GET_MODE (op), XEXP (op, 0)))
5984 return true;
5986 /* offsettable_address_p invokes rs6000_mode_dependent_address, but
5987 the latter predicate knows nothing about the mode of the memory
5988 reference and, therefore, assumes that it is the largest supported
5989 mode (TFmode). As a consequence, legitimate offsettable memory
5990 references are rejected. rs6000_legitimate_offset_address_p contains
5991 the correct logic for the PLUS case of rs6000_mode_dependent_address. */
5992 return rs6000_legitimate_offset_address_p (GET_MODE (op), XEXP (op, 0), 1);
5995 /* Change register usage conditional on target flags. */
5996 void
5997 rs6000_conditional_register_usage (void)
5999 int i;
6001 /* Set MQ register fixed (already call_used) if not POWER
6002 architecture (RIOS1, RIOS2, RSC, and PPC601) so that it will not
6003 be allocated. */
6004 if (! TARGET_POWER)
6005 fixed_regs[64] = 1;
6007 /* 64-bit AIX and Linux reserve GPR13 for thread-private data. */
6008 if (TARGET_64BIT)
6009 fixed_regs[13] = call_used_regs[13]
6010 = call_really_used_regs[13] = 1;
6012 /* Conditionally disable FPRs. */
6013 if (TARGET_SOFT_FLOAT || !TARGET_FPRS)
6014 for (i = 32; i < 64; i++)
6015 fixed_regs[i] = call_used_regs[i]
6016 = call_really_used_regs[i] = 1;
6018 /* The TOC register is not killed across calls in a way that is
6019 visible to the compiler. */
6020 if (DEFAULT_ABI == ABI_AIX)
6021 call_really_used_regs[2] = 0;
6023 if (DEFAULT_ABI == ABI_V4
6024 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
6025 && flag_pic == 2)
6026 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
6028 if (DEFAULT_ABI == ABI_V4
6029 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
6030 && flag_pic == 1)
6031 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6032 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6033 = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
6035 if (DEFAULT_ABI == ABI_DARWIN
6036 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM)
6037 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6038 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6039 = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
6041 if (TARGET_TOC && TARGET_MINIMAL_TOC)
6042 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6043 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
6045 if (TARGET_SPE)
6047 global_regs[SPEFSCR_REGNO] = 1;
6048 /* We used to use r14 as FIXED_SCRATCH to address SPE 64-bit
6049 registers in prologues and epilogues. We no longer use r14
6050 for FIXED_SCRATCH, but we're keeping r14 out of the allocation
6051 pool for link-compatibility with older versions of GCC. Once
6052 "old" code has died out, we can return r14 to the allocation
6053 pool. */
6054 fixed_regs[14]
6055 = call_used_regs[14]
6056 = call_really_used_regs[14] = 1;
6059 if (!TARGET_ALTIVEC && !TARGET_VSX)
6061 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
6062 fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1;
6063 call_really_used_regs[VRSAVE_REGNO] = 1;
6066 if (TARGET_ALTIVEC || TARGET_VSX)
6067 global_regs[VSCR_REGNO] = 1;
6069 if (TARGET_ALTIVEC_ABI)
6071 for (i = FIRST_ALTIVEC_REGNO; i < FIRST_ALTIVEC_REGNO + 20; ++i)
6072 call_used_regs[i] = call_really_used_regs[i] = 1;
6074 /* AIX reserves VR20:31 in non-extended ABI mode. */
6075 if (TARGET_XCOFF)
6076 for (i = FIRST_ALTIVEC_REGNO + 20; i < FIRST_ALTIVEC_REGNO + 32; ++i)
6077 fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1;
6081 /* Try to output insns to set TARGET equal to the constant C if it can
6082 be done in less than N insns. Do all computations in MODE.
6083 Returns the place where the output has been placed if it can be
6084 done and the insns have been emitted. If it would take more than N
6085 insns, zero is returned and no insns and emitted. */
6088 rs6000_emit_set_const (rtx dest, enum machine_mode mode,
6089 rtx source, int n ATTRIBUTE_UNUSED)
6091 rtx result, insn, set;
6092 HOST_WIDE_INT c0, c1;
6094 switch (mode)
6096 case QImode:
6097 case HImode:
6098 if (dest == NULL)
6099 dest = gen_reg_rtx (mode);
6100 emit_insn (gen_rtx_SET (VOIDmode, dest, source));
6101 return dest;
6103 case SImode:
6104 result = !can_create_pseudo_p () ? dest : gen_reg_rtx (SImode);
6106 emit_insn (gen_rtx_SET (VOIDmode, copy_rtx (result),
6107 GEN_INT (INTVAL (source)
6108 & (~ (HOST_WIDE_INT) 0xffff))));
6109 emit_insn (gen_rtx_SET (VOIDmode, dest,
6110 gen_rtx_IOR (SImode, copy_rtx (result),
6111 GEN_INT (INTVAL (source) & 0xffff))));
6112 result = dest;
6113 break;
6115 case DImode:
6116 switch (GET_CODE (source))
6118 case CONST_INT:
6119 c0 = INTVAL (source);
6120 c1 = -(c0 < 0);
6121 break;
6123 case CONST_DOUBLE:
6124 #if HOST_BITS_PER_WIDE_INT >= 64
6125 c0 = CONST_DOUBLE_LOW (source);
6126 c1 = -(c0 < 0);
6127 #else
6128 c0 = CONST_DOUBLE_LOW (source);
6129 c1 = CONST_DOUBLE_HIGH (source);
6130 #endif
6131 break;
6133 default:
6134 gcc_unreachable ();
6137 result = rs6000_emit_set_long_const (dest, c0, c1);
6138 break;
6140 default:
6141 gcc_unreachable ();
6144 insn = get_last_insn ();
6145 set = single_set (insn);
6146 if (! CONSTANT_P (SET_SRC (set)))
6147 set_unique_reg_note (insn, REG_EQUAL, source);
6149 return result;
6152 /* Having failed to find a 3 insn sequence in rs6000_emit_set_const,
6153 fall back to a straight forward decomposition. We do this to avoid
6154 exponential run times encountered when looking for longer sequences
6155 with rs6000_emit_set_const. */
6156 static rtx
6157 rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c1, HOST_WIDE_INT c2)
6159 if (!TARGET_POWERPC64)
6161 rtx operand1, operand2;
6163 operand1 = operand_subword_force (dest, WORDS_BIG_ENDIAN == 0,
6164 DImode);
6165 operand2 = operand_subword_force (copy_rtx (dest), WORDS_BIG_ENDIAN != 0,
6166 DImode);
6167 emit_move_insn (operand1, GEN_INT (c1));
6168 emit_move_insn (operand2, GEN_INT (c2));
6170 else
6172 HOST_WIDE_INT ud1, ud2, ud3, ud4;
6174 ud1 = c1 & 0xffff;
6175 ud2 = (c1 & 0xffff0000) >> 16;
6176 #if HOST_BITS_PER_WIDE_INT >= 64
6177 c2 = c1 >> 32;
6178 #endif
6179 ud3 = c2 & 0xffff;
6180 ud4 = (c2 & 0xffff0000) >> 16;
6182 if ((ud4 == 0xffff && ud3 == 0xffff && ud2 == 0xffff && (ud1 & 0x8000))
6183 || (ud4 == 0 && ud3 == 0 && ud2 == 0 && ! (ud1 & 0x8000)))
6185 if (ud1 & 0x8000)
6186 emit_move_insn (dest, GEN_INT (((ud1 ^ 0x8000) - 0x8000)));
6187 else
6188 emit_move_insn (dest, GEN_INT (ud1));
6191 else if ((ud4 == 0xffff && ud3 == 0xffff && (ud2 & 0x8000))
6192 || (ud4 == 0 && ud3 == 0 && ! (ud2 & 0x8000)))
6194 if (ud2 & 0x8000)
6195 emit_move_insn (dest, GEN_INT (((ud2 << 16) ^ 0x80000000)
6196 - 0x80000000));
6197 else
6198 emit_move_insn (dest, GEN_INT (ud2 << 16));
6199 if (ud1 != 0)
6200 emit_move_insn (copy_rtx (dest),
6201 gen_rtx_IOR (DImode, copy_rtx (dest),
6202 GEN_INT (ud1)));
6204 else if (ud3 == 0 && ud4 == 0)
6206 gcc_assert (ud2 & 0x8000);
6207 emit_move_insn (dest, GEN_INT (((ud2 << 16) ^ 0x80000000)
6208 - 0x80000000));
6209 if (ud1 != 0)
6210 emit_move_insn (copy_rtx (dest),
6211 gen_rtx_IOR (DImode, copy_rtx (dest),
6212 GEN_INT (ud1)));
6213 emit_move_insn (copy_rtx (dest),
6214 gen_rtx_ZERO_EXTEND (DImode,
6215 gen_lowpart (SImode,
6216 copy_rtx (dest))));
6218 else if ((ud4 == 0xffff && (ud3 & 0x8000))
6219 || (ud4 == 0 && ! (ud3 & 0x8000)))
6221 if (ud3 & 0x8000)
6222 emit_move_insn (dest, GEN_INT (((ud3 << 16) ^ 0x80000000)
6223 - 0x80000000));
6224 else
6225 emit_move_insn (dest, GEN_INT (ud3 << 16));
6227 if (ud2 != 0)
6228 emit_move_insn (copy_rtx (dest),
6229 gen_rtx_IOR (DImode, copy_rtx (dest),
6230 GEN_INT (ud2)));
6231 emit_move_insn (copy_rtx (dest),
6232 gen_rtx_ASHIFT (DImode, copy_rtx (dest),
6233 GEN_INT (16)));
6234 if (ud1 != 0)
6235 emit_move_insn (copy_rtx (dest),
6236 gen_rtx_IOR (DImode, copy_rtx (dest),
6237 GEN_INT (ud1)));
6239 else
6241 if (ud4 & 0x8000)
6242 emit_move_insn (dest, GEN_INT (((ud4 << 16) ^ 0x80000000)
6243 - 0x80000000));
6244 else
6245 emit_move_insn (dest, GEN_INT (ud4 << 16));
6247 if (ud3 != 0)
6248 emit_move_insn (copy_rtx (dest),
6249 gen_rtx_IOR (DImode, copy_rtx (dest),
6250 GEN_INT (ud3)));
6252 emit_move_insn (copy_rtx (dest),
6253 gen_rtx_ASHIFT (DImode, copy_rtx (dest),
6254 GEN_INT (32)));
6255 if (ud2 != 0)
6256 emit_move_insn (copy_rtx (dest),
6257 gen_rtx_IOR (DImode, copy_rtx (dest),
6258 GEN_INT (ud2 << 16)));
6259 if (ud1 != 0)
6260 emit_move_insn (copy_rtx (dest),
6261 gen_rtx_IOR (DImode, copy_rtx (dest), GEN_INT (ud1)));
6264 return dest;
6267 /* Helper for the following. Get rid of [r+r] memory refs
6268 in cases where it won't work (TImode, TFmode, TDmode). */
6270 static void
6271 rs6000_eliminate_indexed_memrefs (rtx operands[2])
6273 if (GET_CODE (operands[0]) == MEM
6274 && GET_CODE (XEXP (operands[0], 0)) != REG
6275 && ! legitimate_constant_pool_address_p (XEXP (operands[0], 0))
6276 && ! reload_in_progress)
6277 operands[0]
6278 = replace_equiv_address (operands[0],
6279 copy_addr_to_reg (XEXP (operands[0], 0)));
6281 if (GET_CODE (operands[1]) == MEM
6282 && GET_CODE (XEXP (operands[1], 0)) != REG
6283 && ! legitimate_constant_pool_address_p (XEXP (operands[1], 0))
6284 && ! reload_in_progress)
6285 operands[1]
6286 = replace_equiv_address (operands[1],
6287 copy_addr_to_reg (XEXP (operands[1], 0)));
6290 /* Emit a move from SOURCE to DEST in mode MODE. */
6291 void
6292 rs6000_emit_move (rtx dest, rtx source, enum machine_mode mode)
6294 rtx operands[2];
6295 operands[0] = dest;
6296 operands[1] = source;
6298 if (TARGET_DEBUG_ADDR)
6300 fprintf (stderr,
6301 "\nrs6000_emit_move: mode = %s, reload_in_progress = %d, "
6302 "reload_completed = %d, can_create_pseudos = %d.\ndest:\n",
6303 GET_MODE_NAME (mode),
6304 reload_in_progress,
6305 reload_completed,
6306 can_create_pseudo_p ());
6307 debug_rtx (dest);
6308 fprintf (stderr, "source:\n");
6309 debug_rtx (source);
6312 /* Sanity checks. Check that we get CONST_DOUBLE only when we should. */
6313 if (GET_CODE (operands[1]) == CONST_DOUBLE
6314 && ! FLOAT_MODE_P (mode)
6315 && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
6317 /* FIXME. This should never happen. */
6318 /* Since it seems that it does, do the safe thing and convert
6319 to a CONST_INT. */
6320 operands[1] = gen_int_mode (CONST_DOUBLE_LOW (operands[1]), mode);
6322 gcc_assert (GET_CODE (operands[1]) != CONST_DOUBLE
6323 || FLOAT_MODE_P (mode)
6324 || ((CONST_DOUBLE_HIGH (operands[1]) != 0
6325 || CONST_DOUBLE_LOW (operands[1]) < 0)
6326 && (CONST_DOUBLE_HIGH (operands[1]) != -1
6327 || CONST_DOUBLE_LOW (operands[1]) >= 0)));
6329 /* Check if GCC is setting up a block move that will end up using FP
6330 registers as temporaries. We must make sure this is acceptable. */
6331 if (GET_CODE (operands[0]) == MEM
6332 && GET_CODE (operands[1]) == MEM
6333 && mode == DImode
6334 && (SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[0]))
6335 || SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[1])))
6336 && ! (SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[0]) > 32
6337 ? 32 : MEM_ALIGN (operands[0])))
6338 || SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[1]) > 32
6339 ? 32
6340 : MEM_ALIGN (operands[1]))))
6341 && ! MEM_VOLATILE_P (operands [0])
6342 && ! MEM_VOLATILE_P (operands [1]))
6344 emit_move_insn (adjust_address (operands[0], SImode, 0),
6345 adjust_address (operands[1], SImode, 0));
6346 emit_move_insn (adjust_address (copy_rtx (operands[0]), SImode, 4),
6347 adjust_address (copy_rtx (operands[1]), SImode, 4));
6348 return;
6351 if (can_create_pseudo_p () && GET_CODE (operands[0]) == MEM
6352 && !gpc_reg_operand (operands[1], mode))
6353 operands[1] = force_reg (mode, operands[1]);
6355 if (mode == SFmode && ! TARGET_POWERPC
6356 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
6357 && GET_CODE (operands[0]) == MEM)
6359 int regnum;
6361 if (reload_in_progress || reload_completed)
6362 regnum = true_regnum (operands[1]);
6363 else if (GET_CODE (operands[1]) == REG)
6364 regnum = REGNO (operands[1]);
6365 else
6366 regnum = -1;
6368 /* If operands[1] is a register, on POWER it may have
6369 double-precision data in it, so truncate it to single
6370 precision. */
6371 if (FP_REGNO_P (regnum) || regnum >= FIRST_PSEUDO_REGISTER)
6373 rtx newreg;
6374 newreg = (!can_create_pseudo_p () ? copy_rtx (operands[1])
6375 : gen_reg_rtx (mode));
6376 emit_insn (gen_aux_truncdfsf2 (newreg, operands[1]));
6377 operands[1] = newreg;
6381 /* Recognize the case where operand[1] is a reference to thread-local
6382 data and load its address to a register. */
6383 if (rs6000_tls_referenced_p (operands[1]))
6385 enum tls_model model;
6386 rtx tmp = operands[1];
6387 rtx addend = NULL;
6389 if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
6391 addend = XEXP (XEXP (tmp, 0), 1);
6392 tmp = XEXP (XEXP (tmp, 0), 0);
6395 gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
6396 model = SYMBOL_REF_TLS_MODEL (tmp);
6397 gcc_assert (model != 0);
6399 tmp = rs6000_legitimize_tls_address (tmp, model);
6400 if (addend)
6402 tmp = gen_rtx_PLUS (mode, tmp, addend);
6403 tmp = force_operand (tmp, operands[0]);
6405 operands[1] = tmp;
6408 /* Handle the case where reload calls us with an invalid address. */
6409 if (reload_in_progress && mode == Pmode
6410 && (! general_operand (operands[1], mode)
6411 || ! nonimmediate_operand (operands[0], mode)))
6412 goto emit_set;
6414 /* 128-bit constant floating-point values on Darwin should really be
6415 loaded as two parts. */
6416 if (!TARGET_IEEEQUAD && TARGET_LONG_DOUBLE_128
6417 && mode == TFmode && GET_CODE (operands[1]) == CONST_DOUBLE)
6419 /* DImode is used, not DFmode, because simplify_gen_subreg doesn't
6420 know how to get a DFmode SUBREG of a TFmode. */
6421 enum machine_mode imode = (TARGET_E500_DOUBLE ? DFmode : DImode);
6422 rs6000_emit_move (simplify_gen_subreg (imode, operands[0], mode, 0),
6423 simplify_gen_subreg (imode, operands[1], mode, 0),
6424 imode);
6425 rs6000_emit_move (simplify_gen_subreg (imode, operands[0], mode,
6426 GET_MODE_SIZE (imode)),
6427 simplify_gen_subreg (imode, operands[1], mode,
6428 GET_MODE_SIZE (imode)),
6429 imode);
6430 return;
6433 if (reload_in_progress && cfun->machine->sdmode_stack_slot != NULL_RTX)
6434 cfun->machine->sdmode_stack_slot =
6435 eliminate_regs (cfun->machine->sdmode_stack_slot, VOIDmode, NULL_RTX);
6437 if (reload_in_progress
6438 && mode == SDmode
6439 && MEM_P (operands[0])
6440 && rtx_equal_p (operands[0], cfun->machine->sdmode_stack_slot)
6441 && REG_P (operands[1]))
6443 if (FP_REGNO_P (REGNO (operands[1])))
6445 rtx mem = adjust_address_nv (operands[0], DDmode, 0);
6446 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
6447 emit_insn (gen_movsd_store (mem, operands[1]));
6449 else if (INT_REGNO_P (REGNO (operands[1])))
6451 rtx mem = adjust_address_nv (operands[0], mode, 4);
6452 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
6453 emit_insn (gen_movsd_hardfloat (mem, operands[1]));
6455 else
6456 gcc_unreachable();
6457 return;
6459 if (reload_in_progress
6460 && mode == SDmode
6461 && REG_P (operands[0])
6462 && MEM_P (operands[1])
6463 && rtx_equal_p (operands[1], cfun->machine->sdmode_stack_slot))
6465 if (FP_REGNO_P (REGNO (operands[0])))
6467 rtx mem = adjust_address_nv (operands[1], DDmode, 0);
6468 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
6469 emit_insn (gen_movsd_load (operands[0], mem));
6471 else if (INT_REGNO_P (REGNO (operands[0])))
6473 rtx mem = adjust_address_nv (operands[1], mode, 4);
6474 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
6475 emit_insn (gen_movsd_hardfloat (operands[0], mem));
6477 else
6478 gcc_unreachable();
6479 return;
6482 /* FIXME: In the long term, this switch statement should go away
6483 and be replaced by a sequence of tests based on things like
6484 mode == Pmode. */
6485 switch (mode)
6487 case HImode:
6488 case QImode:
6489 if (CONSTANT_P (operands[1])
6490 && GET_CODE (operands[1]) != CONST_INT)
6491 operands[1] = force_const_mem (mode, operands[1]);
6492 break;
6494 case TFmode:
6495 case TDmode:
6496 rs6000_eliminate_indexed_memrefs (operands);
6497 /* fall through */
6499 case DFmode:
6500 case DDmode:
6501 case SFmode:
6502 case SDmode:
6503 if (CONSTANT_P (operands[1])
6504 && ! easy_fp_constant (operands[1], mode))
6505 operands[1] = force_const_mem (mode, operands[1]);
6506 break;
6508 case V16QImode:
6509 case V8HImode:
6510 case V4SFmode:
6511 case V4SImode:
6512 case V4HImode:
6513 case V2SFmode:
6514 case V2SImode:
6515 case V1DImode:
6516 case V2DFmode:
6517 case V2DImode:
6518 if (CONSTANT_P (operands[1])
6519 && !easy_vector_constant (operands[1], mode))
6520 operands[1] = force_const_mem (mode, operands[1]);
6521 break;
6523 case SImode:
6524 case DImode:
6525 /* Use default pattern for address of ELF small data */
6526 if (TARGET_ELF
6527 && mode == Pmode
6528 && DEFAULT_ABI == ABI_V4
6529 && (GET_CODE (operands[1]) == SYMBOL_REF
6530 || GET_CODE (operands[1]) == CONST)
6531 && small_data_operand (operands[1], mode))
6533 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
6534 return;
6537 if (DEFAULT_ABI == ABI_V4
6538 && mode == Pmode && mode == SImode
6539 && flag_pic == 1 && got_operand (operands[1], mode))
6541 emit_insn (gen_movsi_got (operands[0], operands[1]));
6542 return;
6545 if ((TARGET_ELF || DEFAULT_ABI == ABI_DARWIN)
6546 && TARGET_NO_TOC
6547 && ! flag_pic
6548 && mode == Pmode
6549 && CONSTANT_P (operands[1])
6550 && GET_CODE (operands[1]) != HIGH
6551 && GET_CODE (operands[1]) != CONST_INT)
6553 rtx target = (!can_create_pseudo_p ()
6554 ? operands[0]
6555 : gen_reg_rtx (mode));
6557 /* If this is a function address on -mcall-aixdesc,
6558 convert it to the address of the descriptor. */
6559 if (DEFAULT_ABI == ABI_AIX
6560 && GET_CODE (operands[1]) == SYMBOL_REF
6561 && XSTR (operands[1], 0)[0] == '.')
6563 const char *name = XSTR (operands[1], 0);
6564 rtx new_ref;
6565 while (*name == '.')
6566 name++;
6567 new_ref = gen_rtx_SYMBOL_REF (Pmode, name);
6568 CONSTANT_POOL_ADDRESS_P (new_ref)
6569 = CONSTANT_POOL_ADDRESS_P (operands[1]);
6570 SYMBOL_REF_FLAGS (new_ref) = SYMBOL_REF_FLAGS (operands[1]);
6571 SYMBOL_REF_USED (new_ref) = SYMBOL_REF_USED (operands[1]);
6572 SYMBOL_REF_DATA (new_ref) = SYMBOL_REF_DATA (operands[1]);
6573 operands[1] = new_ref;
6576 if (DEFAULT_ABI == ABI_DARWIN)
6578 #if TARGET_MACHO
6579 if (MACHO_DYNAMIC_NO_PIC_P)
6581 /* Take care of any required data indirection. */
6582 operands[1] = rs6000_machopic_legitimize_pic_address (
6583 operands[1], mode, operands[0]);
6584 if (operands[0] != operands[1])
6585 emit_insn (gen_rtx_SET (VOIDmode,
6586 operands[0], operands[1]));
6587 return;
6589 #endif
6590 emit_insn (gen_macho_high (target, operands[1]));
6591 emit_insn (gen_macho_low (operands[0], target, operands[1]));
6592 return;
6595 emit_insn (gen_elf_high (target, operands[1]));
6596 emit_insn (gen_elf_low (operands[0], target, operands[1]));
6597 return;
6600 /* If this is a SYMBOL_REF that refers to a constant pool entry,
6601 and we have put it in the TOC, we just need to make a TOC-relative
6602 reference to it. */
6603 if (TARGET_TOC
6604 && GET_CODE (operands[1]) == SYMBOL_REF
6605 && constant_pool_expr_p (operands[1])
6606 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (operands[1]),
6607 get_pool_mode (operands[1])))
6609 operands[1] = create_TOC_reference (operands[1]);
6611 else if (mode == Pmode
6612 && CONSTANT_P (operands[1])
6613 && ((GET_CODE (operands[1]) != CONST_INT
6614 && ! easy_fp_constant (operands[1], mode))
6615 || (GET_CODE (operands[1]) == CONST_INT
6616 && num_insns_constant (operands[1], mode) > 2)
6617 || (GET_CODE (operands[0]) == REG
6618 && FP_REGNO_P (REGNO (operands[0]))))
6619 && GET_CODE (operands[1]) != HIGH
6620 && ! legitimate_constant_pool_address_p (operands[1])
6621 && ! toc_relative_expr_p (operands[1]))
6624 #if TARGET_MACHO
6625 /* Darwin uses a special PIC legitimizer. */
6626 if (DEFAULT_ABI == ABI_DARWIN && MACHOPIC_INDIRECT)
6628 operands[1] =
6629 rs6000_machopic_legitimize_pic_address (operands[1], mode,
6630 operands[0]);
6631 if (operands[0] != operands[1])
6632 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
6633 return;
6635 #endif
6637 /* If we are to limit the number of things we put in the TOC and
6638 this is a symbol plus a constant we can add in one insn,
6639 just put the symbol in the TOC and add the constant. Don't do
6640 this if reload is in progress. */
6641 if (GET_CODE (operands[1]) == CONST
6642 && TARGET_NO_SUM_IN_TOC && ! reload_in_progress
6643 && GET_CODE (XEXP (operands[1], 0)) == PLUS
6644 && add_operand (XEXP (XEXP (operands[1], 0), 1), mode)
6645 && (GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == LABEL_REF
6646 || GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == SYMBOL_REF)
6647 && ! side_effects_p (operands[0]))
6649 rtx sym =
6650 force_const_mem (mode, XEXP (XEXP (operands[1], 0), 0));
6651 rtx other = XEXP (XEXP (operands[1], 0), 1);
6653 sym = force_reg (mode, sym);
6654 emit_insn (gen_add3_insn (operands[0], sym, other));
6655 return;
6658 operands[1] = force_const_mem (mode, operands[1]);
6660 if (TARGET_TOC
6661 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
6662 && constant_pool_expr_p (XEXP (operands[1], 0))
6663 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (
6664 get_pool_constant (XEXP (operands[1], 0)),
6665 get_pool_mode (XEXP (operands[1], 0))))
6667 operands[1]
6668 = gen_const_mem (mode,
6669 create_TOC_reference (XEXP (operands[1], 0)));
6670 set_mem_alias_set (operands[1], get_TOC_alias_set ());
6673 break;
6675 case TImode:
6676 rs6000_eliminate_indexed_memrefs (operands);
6678 if (TARGET_POWER)
6680 emit_insn (gen_rtx_PARALLEL (VOIDmode,
6681 gen_rtvec (2,
6682 gen_rtx_SET (VOIDmode,
6683 operands[0], operands[1]),
6684 gen_rtx_CLOBBER (VOIDmode,
6685 gen_rtx_SCRATCH (SImode)))));
6686 return;
6688 break;
6690 default:
6691 fatal_insn ("bad move", gen_rtx_SET (VOIDmode, dest, source));
6694 /* Above, we may have called force_const_mem which may have returned
6695 an invalid address. If we can, fix this up; otherwise, reload will
6696 have to deal with it. */
6697 if (GET_CODE (operands[1]) == MEM && ! reload_in_progress)
6698 operands[1] = validize_mem (operands[1]);
6700 emit_set:
6701 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
6704 /* Nonzero if we can use a floating-point register to pass this arg. */
6705 #define USE_FP_FOR_ARG_P(CUM,MODE,TYPE) \
6706 (SCALAR_FLOAT_MODE_P (MODE) \
6707 && (CUM)->fregno <= FP_ARG_MAX_REG \
6708 && TARGET_HARD_FLOAT && TARGET_FPRS)
6710 /* Nonzero if we can use an AltiVec register to pass this arg. */
6711 #define USE_ALTIVEC_FOR_ARG_P(CUM,MODE,TYPE,NAMED) \
6712 ((ALTIVEC_VECTOR_MODE (MODE) || VSX_VECTOR_MODE (MODE)) \
6713 && (CUM)->vregno <= ALTIVEC_ARG_MAX_REG \
6714 && TARGET_ALTIVEC_ABI \
6715 && (NAMED))
6717 /* Return a nonzero value to say to return the function value in
6718 memory, just as large structures are always returned. TYPE will be
6719 the data type of the value, and FNTYPE will be the type of the
6720 function doing the returning, or @code{NULL} for libcalls.
6722 The AIX ABI for the RS/6000 specifies that all structures are
6723 returned in memory. The Darwin ABI does the same. The SVR4 ABI
6724 specifies that structures <= 8 bytes are returned in r3/r4, but a
6725 draft put them in memory, and GCC used to implement the draft
6726 instead of the final standard. Therefore, aix_struct_return
6727 controls this instead of DEFAULT_ABI; V.4 targets needing backward
6728 compatibility can change DRAFT_V4_STRUCT_RET to override the
6729 default, and -m switches get the final word. See
6730 rs6000_override_options for more details.
6732 The PPC32 SVR4 ABI uses IEEE double extended for long double, if 128-bit
6733 long double support is enabled. These values are returned in memory.
6735 int_size_in_bytes returns -1 for variable size objects, which go in
6736 memory always. The cast to unsigned makes -1 > 8. */
6738 static bool
6739 rs6000_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
6741 /* In the darwin64 abi, try to use registers for larger structs
6742 if possible. */
6743 if (rs6000_darwin64_abi
6744 && TREE_CODE (type) == RECORD_TYPE
6745 && int_size_in_bytes (type) > 0)
6747 CUMULATIVE_ARGS valcum;
6748 rtx valret;
6750 valcum.words = 0;
6751 valcum.fregno = FP_ARG_MIN_REG;
6752 valcum.vregno = ALTIVEC_ARG_MIN_REG;
6753 /* Do a trial code generation as if this were going to be passed
6754 as an argument; if any part goes in memory, we return NULL. */
6755 valret = rs6000_darwin64_record_arg (&valcum, type, 1, true);
6756 if (valret)
6757 return false;
6758 /* Otherwise fall through to more conventional ABI rules. */
6761 if (AGGREGATE_TYPE_P (type)
6762 && (aix_struct_return
6763 || (unsigned HOST_WIDE_INT) int_size_in_bytes (type) > 8))
6764 return true;
6766 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
6767 modes only exist for GCC vector types if -maltivec. */
6768 if (TARGET_32BIT && !TARGET_ALTIVEC_ABI
6769 && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
6770 return false;
6772 /* Return synthetic vectors in memory. */
6773 if (TREE_CODE (type) == VECTOR_TYPE
6774 && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
6776 static bool warned_for_return_big_vectors = false;
6777 if (!warned_for_return_big_vectors)
6779 warning (0, "GCC vector returned by reference: "
6780 "non-standard ABI extension with no compatibility guarantee");
6781 warned_for_return_big_vectors = true;
6783 return true;
6786 if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && TYPE_MODE (type) == TFmode)
6787 return true;
6789 return false;
6792 /* Initialize a variable CUM of type CUMULATIVE_ARGS
6793 for a call to a function whose data type is FNTYPE.
6794 For a library call, FNTYPE is 0.
6796 For incoming args we set the number of arguments in the prototype large
6797 so we never return a PARALLEL. */
6799 void
6800 init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype,
6801 rtx libname ATTRIBUTE_UNUSED, int incoming,
6802 int libcall, int n_named_args)
6804 static CUMULATIVE_ARGS zero_cumulative;
6806 *cum = zero_cumulative;
6807 cum->words = 0;
6808 cum->fregno = FP_ARG_MIN_REG;
6809 cum->vregno = ALTIVEC_ARG_MIN_REG;
6810 cum->prototype = (fntype && TYPE_ARG_TYPES (fntype));
6811 cum->call_cookie = ((DEFAULT_ABI == ABI_V4 && libcall)
6812 ? CALL_LIBCALL : CALL_NORMAL);
6813 cum->sysv_gregno = GP_ARG_MIN_REG;
6814 cum->stdarg = fntype
6815 && (TYPE_ARG_TYPES (fntype) != 0
6816 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
6817 != void_type_node));
6819 cum->nargs_prototype = 0;
6820 if (incoming || cum->prototype)
6821 cum->nargs_prototype = n_named_args;
6823 /* Check for a longcall attribute. */
6824 if ((!fntype && rs6000_default_long_calls)
6825 || (fntype
6826 && lookup_attribute ("longcall", TYPE_ATTRIBUTES (fntype))
6827 && !lookup_attribute ("shortcall", TYPE_ATTRIBUTES (fntype))))
6828 cum->call_cookie |= CALL_LONG;
6830 if (TARGET_DEBUG_ARG)
6832 fprintf (stderr, "\ninit_cumulative_args:");
6833 if (fntype)
6835 tree ret_type = TREE_TYPE (fntype);
6836 fprintf (stderr, " ret code = %s,",
6837 tree_code_name[ (int)TREE_CODE (ret_type) ]);
6840 if (cum->call_cookie & CALL_LONG)
6841 fprintf (stderr, " longcall,");
6843 fprintf (stderr, " proto = %d, nargs = %d\n",
6844 cum->prototype, cum->nargs_prototype);
6847 if (fntype
6848 && !TARGET_ALTIVEC
6849 && TARGET_ALTIVEC_ABI
6850 && ALTIVEC_VECTOR_MODE (TYPE_MODE (TREE_TYPE (fntype))))
6852 error ("cannot return value in vector register because"
6853 " altivec instructions are disabled, use -maltivec"
6854 " to enable them");
6858 /* Return true if TYPE must be passed on the stack and not in registers. */
6860 static bool
6861 rs6000_must_pass_in_stack (enum machine_mode mode, const_tree type)
6863 if (DEFAULT_ABI == ABI_AIX || TARGET_64BIT)
6864 return must_pass_in_stack_var_size (mode, type);
6865 else
6866 return must_pass_in_stack_var_size_or_pad (mode, type);
6869 /* If defined, a C expression which determines whether, and in which
6870 direction, to pad out an argument with extra space. The value
6871 should be of type `enum direction': either `upward' to pad above
6872 the argument, `downward' to pad below, or `none' to inhibit
6873 padding.
6875 For the AIX ABI structs are always stored left shifted in their
6876 argument slot. */
6878 enum direction
6879 function_arg_padding (enum machine_mode mode, const_tree type)
6881 #ifndef AGGREGATE_PADDING_FIXED
6882 #define AGGREGATE_PADDING_FIXED 0
6883 #endif
6884 #ifndef AGGREGATES_PAD_UPWARD_ALWAYS
6885 #define AGGREGATES_PAD_UPWARD_ALWAYS 0
6886 #endif
6888 if (!AGGREGATE_PADDING_FIXED)
6890 /* GCC used to pass structures of the same size as integer types as
6891 if they were in fact integers, ignoring FUNCTION_ARG_PADDING.
6892 i.e. Structures of size 1 or 2 (or 4 when TARGET_64BIT) were
6893 passed padded downward, except that -mstrict-align further
6894 muddied the water in that multi-component structures of 2 and 4
6895 bytes in size were passed padded upward.
6897 The following arranges for best compatibility with previous
6898 versions of gcc, but removes the -mstrict-align dependency. */
6899 if (BYTES_BIG_ENDIAN)
6901 HOST_WIDE_INT size = 0;
6903 if (mode == BLKmode)
6905 if (type && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST)
6906 size = int_size_in_bytes (type);
6908 else
6909 size = GET_MODE_SIZE (mode);
6911 if (size == 1 || size == 2 || size == 4)
6912 return downward;
6914 return upward;
6917 if (AGGREGATES_PAD_UPWARD_ALWAYS)
6919 if (type != 0 && AGGREGATE_TYPE_P (type))
6920 return upward;
6923 /* Fall back to the default. */
6924 return DEFAULT_FUNCTION_ARG_PADDING (mode, type);
6927 /* If defined, a C expression that gives the alignment boundary, in bits,
6928 of an argument with the specified mode and type. If it is not defined,
6929 PARM_BOUNDARY is used for all arguments.
6931 V.4 wants long longs and doubles to be double word aligned. Just
6932 testing the mode size is a boneheaded way to do this as it means
6933 that other types such as complex int are also double word aligned.
6934 However, we're stuck with this because changing the ABI might break
6935 existing library interfaces.
6937 Doubleword align SPE vectors.
6938 Quadword align Altivec vectors.
6939 Quadword align large synthetic vector types. */
6942 function_arg_boundary (enum machine_mode mode, tree type)
6944 if (DEFAULT_ABI == ABI_V4
6945 && (GET_MODE_SIZE (mode) == 8
6946 || (TARGET_HARD_FLOAT
6947 && TARGET_FPRS
6948 && (mode == TFmode || mode == TDmode))))
6949 return 64;
6950 else if (SPE_VECTOR_MODE (mode)
6951 || (type && TREE_CODE (type) == VECTOR_TYPE
6952 && int_size_in_bytes (type) >= 8
6953 && int_size_in_bytes (type) < 16))
6954 return 64;
6955 else if ((ALTIVEC_VECTOR_MODE (mode) || VSX_VECTOR_MODE (mode))
6956 || (type && TREE_CODE (type) == VECTOR_TYPE
6957 && int_size_in_bytes (type) >= 16))
6958 return 128;
6959 else if (rs6000_darwin64_abi && mode == BLKmode
6960 && type && TYPE_ALIGN (type) > 64)
6961 return 128;
6962 else
6963 return PARM_BOUNDARY;
6966 /* For a function parm of MODE and TYPE, return the starting word in
6967 the parameter area. NWORDS of the parameter area are already used. */
6969 static unsigned int
6970 rs6000_parm_start (enum machine_mode mode, tree type, unsigned int nwords)
6972 unsigned int align;
6973 unsigned int parm_offset;
6975 align = function_arg_boundary (mode, type) / PARM_BOUNDARY - 1;
6976 parm_offset = DEFAULT_ABI == ABI_V4 ? 2 : 6;
6977 return nwords + (-(parm_offset + nwords) & align);
6980 /* Compute the size (in words) of a function argument. */
6982 static unsigned long
6983 rs6000_arg_size (enum machine_mode mode, tree type)
6985 unsigned long size;
6987 if (mode != BLKmode)
6988 size = GET_MODE_SIZE (mode);
6989 else
6990 size = int_size_in_bytes (type);
6992 if (TARGET_32BIT)
6993 return (size + 3) >> 2;
6994 else
6995 return (size + 7) >> 3;
6998 /* Use this to flush pending int fields. */
7000 static void
7001 rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS *cum,
7002 HOST_WIDE_INT bitpos)
7004 unsigned int startbit, endbit;
7005 int intregs, intoffset;
7006 enum machine_mode mode;
7008 if (cum->intoffset == -1)
7009 return;
7011 intoffset = cum->intoffset;
7012 cum->intoffset = -1;
7014 if (intoffset % BITS_PER_WORD != 0)
7016 mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD,
7017 MODE_INT, 0);
7018 if (mode == BLKmode)
7020 /* We couldn't find an appropriate mode, which happens,
7021 e.g., in packed structs when there are 3 bytes to load.
7022 Back intoffset back to the beginning of the word in this
7023 case. */
7024 intoffset = intoffset & -BITS_PER_WORD;
7028 startbit = intoffset & -BITS_PER_WORD;
7029 endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD;
7030 intregs = (endbit - startbit) / BITS_PER_WORD;
7031 cum->words += intregs;
7034 /* The darwin64 ABI calls for us to recurse down through structs,
7035 looking for elements passed in registers. Unfortunately, we have
7036 to track int register count here also because of misalignments
7037 in powerpc alignment mode. */
7039 static void
7040 rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS *cum,
7041 tree type,
7042 HOST_WIDE_INT startbitpos)
7044 tree f;
7046 for (f = TYPE_FIELDS (type); f ; f = TREE_CHAIN (f))
7047 if (TREE_CODE (f) == FIELD_DECL)
7049 HOST_WIDE_INT bitpos = startbitpos;
7050 tree ftype = TREE_TYPE (f);
7051 enum machine_mode mode;
7052 if (ftype == error_mark_node)
7053 continue;
7054 mode = TYPE_MODE (ftype);
7056 if (DECL_SIZE (f) != 0
7057 && host_integerp (bit_position (f), 1))
7058 bitpos += int_bit_position (f);
7060 /* ??? FIXME: else assume zero offset. */
7062 if (TREE_CODE (ftype) == RECORD_TYPE)
7063 rs6000_darwin64_record_arg_advance_recurse (cum, ftype, bitpos);
7064 else if (USE_FP_FOR_ARG_P (cum, mode, ftype))
7066 rs6000_darwin64_record_arg_advance_flush (cum, bitpos);
7067 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
7068 cum->words += (GET_MODE_SIZE (mode) + 7) >> 3;
7070 else if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, 1))
7072 rs6000_darwin64_record_arg_advance_flush (cum, bitpos);
7073 cum->vregno++;
7074 cum->words += 2;
7076 else if (cum->intoffset == -1)
7077 cum->intoffset = bitpos;
7081 /* Update the data in CUM to advance over an argument
7082 of mode MODE and data type TYPE.
7083 (TYPE is null for libcalls where that information may not be available.)
7085 Note that for args passed by reference, function_arg will be called
7086 with MODE and TYPE set to that of the pointer to the arg, not the arg
7087 itself. */
7089 void
7090 function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
7091 tree type, int named, int depth)
7093 int size;
7095 /* Only tick off an argument if we're not recursing. */
7096 if (depth == 0)
7097 cum->nargs_prototype--;
7099 if (TARGET_ALTIVEC_ABI
7100 && (ALTIVEC_VECTOR_MODE (mode)
7101 || VSX_VECTOR_MODE (mode)
7102 || (type && TREE_CODE (type) == VECTOR_TYPE
7103 && int_size_in_bytes (type) == 16)))
7105 bool stack = false;
7107 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
7109 cum->vregno++;
7110 if (!TARGET_ALTIVEC)
7111 error ("cannot pass argument in vector register because"
7112 " altivec instructions are disabled, use -maltivec"
7113 " to enable them");
7115 /* PowerPC64 Linux and AIX allocate GPRs for a vector argument
7116 even if it is going to be passed in a vector register.
7117 Darwin does the same for variable-argument functions. */
7118 if ((DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
7119 || (cum->stdarg && DEFAULT_ABI != ABI_V4))
7120 stack = true;
7122 else
7123 stack = true;
7125 if (stack)
7127 int align;
7129 /* Vector parameters must be 16-byte aligned. This places
7130 them at 2 mod 4 in terms of words in 32-bit mode, since
7131 the parameter save area starts at offset 24 from the
7132 stack. In 64-bit mode, they just have to start on an
7133 even word, since the parameter save area is 16-byte
7134 aligned. Space for GPRs is reserved even if the argument
7135 will be passed in memory. */
7136 if (TARGET_32BIT)
7137 align = (2 - cum->words) & 3;
7138 else
7139 align = cum->words & 1;
7140 cum->words += align + rs6000_arg_size (mode, type);
7142 if (TARGET_DEBUG_ARG)
7144 fprintf (stderr, "function_adv: words = %2d, align=%d, ",
7145 cum->words, align);
7146 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s\n",
7147 cum->nargs_prototype, cum->prototype,
7148 GET_MODE_NAME (mode));
7152 else if (TARGET_SPE_ABI && TARGET_SPE && SPE_VECTOR_MODE (mode)
7153 && !cum->stdarg
7154 && cum->sysv_gregno <= GP_ARG_MAX_REG)
7155 cum->sysv_gregno++;
7157 else if (rs6000_darwin64_abi
7158 && mode == BLKmode
7159 && TREE_CODE (type) == RECORD_TYPE
7160 && (size = int_size_in_bytes (type)) > 0)
7162 /* Variable sized types have size == -1 and are
7163 treated as if consisting entirely of ints.
7164 Pad to 16 byte boundary if needed. */
7165 if (TYPE_ALIGN (type) >= 2 * BITS_PER_WORD
7166 && (cum->words % 2) != 0)
7167 cum->words++;
7168 /* For varargs, we can just go up by the size of the struct. */
7169 if (!named)
7170 cum->words += (size + 7) / 8;
7171 else
7173 /* It is tempting to say int register count just goes up by
7174 sizeof(type)/8, but this is wrong in a case such as
7175 { int; double; int; } [powerpc alignment]. We have to
7176 grovel through the fields for these too. */
7177 cum->intoffset = 0;
7178 rs6000_darwin64_record_arg_advance_recurse (cum, type, 0);
7179 rs6000_darwin64_record_arg_advance_flush (cum,
7180 size * BITS_PER_UNIT);
7183 else if (DEFAULT_ABI == ABI_V4)
7185 if (TARGET_HARD_FLOAT && TARGET_FPRS
7186 && ((TARGET_SINGLE_FLOAT && mode == SFmode)
7187 || (TARGET_DOUBLE_FLOAT && mode == DFmode)
7188 || (mode == TFmode && !TARGET_IEEEQUAD)
7189 || mode == SDmode || mode == DDmode || mode == TDmode))
7191 /* _Decimal128 must use an even/odd register pair. This assumes
7192 that the register number is odd when fregno is odd. */
7193 if (mode == TDmode && (cum->fregno % 2) == 1)
7194 cum->fregno++;
7196 if (cum->fregno + (mode == TFmode || mode == TDmode ? 1 : 0)
7197 <= FP_ARG_V4_MAX_REG)
7198 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
7199 else
7201 cum->fregno = FP_ARG_V4_MAX_REG + 1;
7202 if (mode == DFmode || mode == TFmode
7203 || mode == DDmode || mode == TDmode)
7204 cum->words += cum->words & 1;
7205 cum->words += rs6000_arg_size (mode, type);
7208 else
7210 int n_words = rs6000_arg_size (mode, type);
7211 int gregno = cum->sysv_gregno;
7213 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
7214 (r7,r8) or (r9,r10). As does any other 2 word item such
7215 as complex int due to a historical mistake. */
7216 if (n_words == 2)
7217 gregno += (1 - gregno) & 1;
7219 /* Multi-reg args are not split between registers and stack. */
7220 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
7222 /* Long long and SPE vectors are aligned on the stack.
7223 So are other 2 word items such as complex int due to
7224 a historical mistake. */
7225 if (n_words == 2)
7226 cum->words += cum->words & 1;
7227 cum->words += n_words;
7230 /* Note: continuing to accumulate gregno past when we've started
7231 spilling to the stack indicates the fact that we've started
7232 spilling to the stack to expand_builtin_saveregs. */
7233 cum->sysv_gregno = gregno + n_words;
7236 if (TARGET_DEBUG_ARG)
7238 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
7239 cum->words, cum->fregno);
7240 fprintf (stderr, "gregno = %2d, nargs = %4d, proto = %d, ",
7241 cum->sysv_gregno, cum->nargs_prototype, cum->prototype);
7242 fprintf (stderr, "mode = %4s, named = %d\n",
7243 GET_MODE_NAME (mode), named);
7246 else
7248 int n_words = rs6000_arg_size (mode, type);
7249 int start_words = cum->words;
7250 int align_words = rs6000_parm_start (mode, type, start_words);
7252 cum->words = align_words + n_words;
7254 if (SCALAR_FLOAT_MODE_P (mode)
7255 && TARGET_HARD_FLOAT && TARGET_FPRS)
7257 /* _Decimal128 must be passed in an even/odd float register pair.
7258 This assumes that the register number is odd when fregno is
7259 odd. */
7260 if (mode == TDmode && (cum->fregno % 2) == 1)
7261 cum->fregno++;
7262 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
7265 if (TARGET_DEBUG_ARG)
7267 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
7268 cum->words, cum->fregno);
7269 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s, ",
7270 cum->nargs_prototype, cum->prototype, GET_MODE_NAME (mode));
7271 fprintf (stderr, "named = %d, align = %d, depth = %d\n",
7272 named, align_words - start_words, depth);
7277 static rtx
7278 spe_build_register_parallel (enum machine_mode mode, int gregno)
7280 rtx r1, r3, r5, r7;
7282 switch (mode)
7284 case DFmode:
7285 r1 = gen_rtx_REG (DImode, gregno);
7286 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
7287 return gen_rtx_PARALLEL (mode, gen_rtvec (1, r1));
7289 case DCmode:
7290 case TFmode:
7291 r1 = gen_rtx_REG (DImode, gregno);
7292 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
7293 r3 = gen_rtx_REG (DImode, gregno + 2);
7294 r3 = gen_rtx_EXPR_LIST (VOIDmode, r3, GEN_INT (8));
7295 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r3));
7297 case TCmode:
7298 r1 = gen_rtx_REG (DImode, gregno);
7299 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
7300 r3 = gen_rtx_REG (DImode, gregno + 2);
7301 r3 = gen_rtx_EXPR_LIST (VOIDmode, r3, GEN_INT (8));
7302 r5 = gen_rtx_REG (DImode, gregno + 4);
7303 r5 = gen_rtx_EXPR_LIST (VOIDmode, r5, GEN_INT (16));
7304 r7 = gen_rtx_REG (DImode, gregno + 6);
7305 r7 = gen_rtx_EXPR_LIST (VOIDmode, r7, GEN_INT (24));
7306 return gen_rtx_PARALLEL (mode, gen_rtvec (4, r1, r3, r5, r7));
7308 default:
7309 gcc_unreachable ();
7313 /* Determine where to put a SIMD argument on the SPE. */
7314 static rtx
7315 rs6000_spe_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
7316 tree type)
7318 int gregno = cum->sysv_gregno;
7320 /* On E500 v2, double arithmetic is done on the full 64-bit GPR, but
7321 are passed and returned in a pair of GPRs for ABI compatibility. */
7322 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
7323 || mode == DCmode || mode == TCmode))
7325 int n_words = rs6000_arg_size (mode, type);
7327 /* Doubles go in an odd/even register pair (r5/r6, etc). */
7328 if (mode == DFmode)
7329 gregno += (1 - gregno) & 1;
7331 /* Multi-reg args are not split between registers and stack. */
7332 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
7333 return NULL_RTX;
7335 return spe_build_register_parallel (mode, gregno);
7337 if (cum->stdarg)
7339 int n_words = rs6000_arg_size (mode, type);
7341 /* SPE vectors are put in odd registers. */
7342 if (n_words == 2 && (gregno & 1) == 0)
7343 gregno += 1;
7345 if (gregno + n_words - 1 <= GP_ARG_MAX_REG)
7347 rtx r1, r2;
7348 enum machine_mode m = SImode;
7350 r1 = gen_rtx_REG (m, gregno);
7351 r1 = gen_rtx_EXPR_LIST (m, r1, const0_rtx);
7352 r2 = gen_rtx_REG (m, gregno + 1);
7353 r2 = gen_rtx_EXPR_LIST (m, r2, GEN_INT (4));
7354 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
7356 else
7357 return NULL_RTX;
7359 else
7361 if (gregno <= GP_ARG_MAX_REG)
7362 return gen_rtx_REG (mode, gregno);
7363 else
7364 return NULL_RTX;
7368 /* A subroutine of rs6000_darwin64_record_arg. Assign the bits of the
7369 structure between cum->intoffset and bitpos to integer registers. */
7371 static void
7372 rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS *cum,
7373 HOST_WIDE_INT bitpos, rtx rvec[], int *k)
7375 enum machine_mode mode;
7376 unsigned int regno;
7377 unsigned int startbit, endbit;
7378 int this_regno, intregs, intoffset;
7379 rtx reg;
7381 if (cum->intoffset == -1)
7382 return;
7384 intoffset = cum->intoffset;
7385 cum->intoffset = -1;
7387 /* If this is the trailing part of a word, try to only load that
7388 much into the register. Otherwise load the whole register. Note
7389 that in the latter case we may pick up unwanted bits. It's not a
7390 problem at the moment but may wish to revisit. */
7392 if (intoffset % BITS_PER_WORD != 0)
7394 mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD,
7395 MODE_INT, 0);
7396 if (mode == BLKmode)
7398 /* We couldn't find an appropriate mode, which happens,
7399 e.g., in packed structs when there are 3 bytes to load.
7400 Back intoffset back to the beginning of the word in this
7401 case. */
7402 intoffset = intoffset & -BITS_PER_WORD;
7403 mode = word_mode;
7406 else
7407 mode = word_mode;
7409 startbit = intoffset & -BITS_PER_WORD;
7410 endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD;
7411 intregs = (endbit - startbit) / BITS_PER_WORD;
7412 this_regno = cum->words + intoffset / BITS_PER_WORD;
7414 if (intregs > 0 && intregs > GP_ARG_NUM_REG - this_regno)
7415 cum->use_stack = 1;
7417 intregs = MIN (intregs, GP_ARG_NUM_REG - this_regno);
7418 if (intregs <= 0)
7419 return;
7421 intoffset /= BITS_PER_UNIT;
7424 regno = GP_ARG_MIN_REG + this_regno;
7425 reg = gen_rtx_REG (mode, regno);
7426 rvec[(*k)++] =
7427 gen_rtx_EXPR_LIST (VOIDmode, reg, GEN_INT (intoffset));
7429 this_regno += 1;
7430 intoffset = (intoffset | (UNITS_PER_WORD-1)) + 1;
7431 mode = word_mode;
7432 intregs -= 1;
7434 while (intregs > 0);
7437 /* Recursive workhorse for the following. */
7439 static void
7440 rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *cum, const_tree type,
7441 HOST_WIDE_INT startbitpos, rtx rvec[],
7442 int *k)
7444 tree f;
7446 for (f = TYPE_FIELDS (type); f ; f = TREE_CHAIN (f))
7447 if (TREE_CODE (f) == FIELD_DECL)
7449 HOST_WIDE_INT bitpos = startbitpos;
7450 tree ftype = TREE_TYPE (f);
7451 enum machine_mode mode;
7452 if (ftype == error_mark_node)
7453 continue;
7454 mode = TYPE_MODE (ftype);
7456 if (DECL_SIZE (f) != 0
7457 && host_integerp (bit_position (f), 1))
7458 bitpos += int_bit_position (f);
7460 /* ??? FIXME: else assume zero offset. */
7462 if (TREE_CODE (ftype) == RECORD_TYPE)
7463 rs6000_darwin64_record_arg_recurse (cum, ftype, bitpos, rvec, k);
7464 else if (cum->named && USE_FP_FOR_ARG_P (cum, mode, ftype))
7466 #if 0
7467 switch (mode)
7469 case SCmode: mode = SFmode; break;
7470 case DCmode: mode = DFmode; break;
7471 case TCmode: mode = TFmode; break;
7472 default: break;
7474 #endif
7475 rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
7476 rvec[(*k)++]
7477 = gen_rtx_EXPR_LIST (VOIDmode,
7478 gen_rtx_REG (mode, cum->fregno++),
7479 GEN_INT (bitpos / BITS_PER_UNIT));
7480 if (mode == TFmode || mode == TDmode)
7481 cum->fregno++;
7483 else if (cum->named && USE_ALTIVEC_FOR_ARG_P (cum, mode, ftype, 1))
7485 rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
7486 rvec[(*k)++]
7487 = gen_rtx_EXPR_LIST (VOIDmode,
7488 gen_rtx_REG (mode, cum->vregno++),
7489 GEN_INT (bitpos / BITS_PER_UNIT));
7491 else if (cum->intoffset == -1)
7492 cum->intoffset = bitpos;
7496 /* For the darwin64 ABI, we want to construct a PARALLEL consisting of
7497 the register(s) to be used for each field and subfield of a struct
7498 being passed by value, along with the offset of where the
7499 register's value may be found in the block. FP fields go in FP
7500 register, vector fields go in vector registers, and everything
7501 else goes in int registers, packed as in memory.
7503 This code is also used for function return values. RETVAL indicates
7504 whether this is the case.
7506 Much of this is taken from the SPARC V9 port, which has a similar
7507 calling convention. */
7509 static rtx
7510 rs6000_darwin64_record_arg (CUMULATIVE_ARGS *orig_cum, const_tree type,
7511 int named, bool retval)
7513 rtx rvec[FIRST_PSEUDO_REGISTER];
7514 int k = 1, kbase = 1;
7515 HOST_WIDE_INT typesize = int_size_in_bytes (type);
7516 /* This is a copy; modifications are not visible to our caller. */
7517 CUMULATIVE_ARGS copy_cum = *orig_cum;
7518 CUMULATIVE_ARGS *cum = &copy_cum;
7520 /* Pad to 16 byte boundary if needed. */
7521 if (!retval && TYPE_ALIGN (type) >= 2 * BITS_PER_WORD
7522 && (cum->words % 2) != 0)
7523 cum->words++;
7525 cum->intoffset = 0;
7526 cum->use_stack = 0;
7527 cum->named = named;
7529 /* Put entries into rvec[] for individual FP and vector fields, and
7530 for the chunks of memory that go in int regs. Note we start at
7531 element 1; 0 is reserved for an indication of using memory, and
7532 may or may not be filled in below. */
7533 rs6000_darwin64_record_arg_recurse (cum, type, 0, rvec, &k);
7534 rs6000_darwin64_record_arg_flush (cum, typesize * BITS_PER_UNIT, rvec, &k);
7536 /* If any part of the struct went on the stack put all of it there.
7537 This hack is because the generic code for
7538 FUNCTION_ARG_PARTIAL_NREGS cannot handle cases where the register
7539 parts of the struct are not at the beginning. */
7540 if (cum->use_stack)
7542 if (retval)
7543 return NULL_RTX; /* doesn't go in registers at all */
7544 kbase = 0;
7545 rvec[0] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
7547 if (k > 1 || cum->use_stack)
7548 return gen_rtx_PARALLEL (BLKmode, gen_rtvec_v (k - kbase, &rvec[kbase]));
7549 else
7550 return NULL_RTX;
7553 /* Determine where to place an argument in 64-bit mode with 32-bit ABI. */
7555 static rtx
7556 rs6000_mixed_function_arg (enum machine_mode mode, tree type, int align_words)
7558 int n_units;
7559 int i, k;
7560 rtx rvec[GP_ARG_NUM_REG + 1];
7562 if (align_words >= GP_ARG_NUM_REG)
7563 return NULL_RTX;
7565 n_units = rs6000_arg_size (mode, type);
7567 /* Optimize the simple case where the arg fits in one gpr, except in
7568 the case of BLKmode due to assign_parms assuming that registers are
7569 BITS_PER_WORD wide. */
7570 if (n_units == 0
7571 || (n_units == 1 && mode != BLKmode))
7572 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
7574 k = 0;
7575 if (align_words + n_units > GP_ARG_NUM_REG)
7576 /* Not all of the arg fits in gprs. Say that it goes in memory too,
7577 using a magic NULL_RTX component.
7578 This is not strictly correct. Only some of the arg belongs in
7579 memory, not all of it. However, the normal scheme using
7580 function_arg_partial_nregs can result in unusual subregs, eg.
7581 (subreg:SI (reg:DF) 4), which are not handled well. The code to
7582 store the whole arg to memory is often more efficient than code
7583 to store pieces, and we know that space is available in the right
7584 place for the whole arg. */
7585 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
7587 i = 0;
7590 rtx r = gen_rtx_REG (SImode, GP_ARG_MIN_REG + align_words);
7591 rtx off = GEN_INT (i++ * 4);
7592 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
7594 while (++align_words < GP_ARG_NUM_REG && --n_units != 0);
7596 return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
7599 /* Determine where to put an argument to a function.
7600 Value is zero to push the argument on the stack,
7601 or a hard register in which to store the argument.
7603 MODE is the argument's machine mode.
7604 TYPE is the data type of the argument (as a tree).
7605 This is null for libcalls where that information may
7606 not be available.
7607 CUM is a variable of type CUMULATIVE_ARGS which gives info about
7608 the preceding args and about the function being called. It is
7609 not modified in this routine.
7610 NAMED is nonzero if this argument is a named parameter
7611 (otherwise it is an extra parameter matching an ellipsis).
7613 On RS/6000 the first eight words of non-FP are normally in registers
7614 and the rest are pushed. Under AIX, the first 13 FP args are in registers.
7615 Under V.4, the first 8 FP args are in registers.
7617 If this is floating-point and no prototype is specified, we use
7618 both an FP and integer register (or possibly FP reg and stack). Library
7619 functions (when CALL_LIBCALL is set) always have the proper types for args,
7620 so we can pass the FP value just in one register. emit_library_function
7621 doesn't support PARALLEL anyway.
7623 Note that for args passed by reference, function_arg will be called
7624 with MODE and TYPE set to that of the pointer to the arg, not the arg
7625 itself. */
7628 function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
7629 tree type, int named)
7631 enum rs6000_abi abi = DEFAULT_ABI;
7633 /* Return a marker to indicate whether CR1 needs to set or clear the
7634 bit that V.4 uses to say fp args were passed in registers.
7635 Assume that we don't need the marker for software floating point,
7636 or compiler generated library calls. */
7637 if (mode == VOIDmode)
7639 if (abi == ABI_V4
7640 && (cum->call_cookie & CALL_LIBCALL) == 0
7641 && (cum->stdarg
7642 || (cum->nargs_prototype < 0
7643 && (cum->prototype || TARGET_NO_PROTOTYPE))))
7645 /* For the SPE, we need to crxor CR6 always. */
7646 if (TARGET_SPE_ABI)
7647 return GEN_INT (cum->call_cookie | CALL_V4_SET_FP_ARGS);
7648 else if (TARGET_HARD_FLOAT && TARGET_FPRS)
7649 return GEN_INT (cum->call_cookie
7650 | ((cum->fregno == FP_ARG_MIN_REG)
7651 ? CALL_V4_SET_FP_ARGS
7652 : CALL_V4_CLEAR_FP_ARGS));
7655 return GEN_INT (cum->call_cookie);
7658 if (rs6000_darwin64_abi && mode == BLKmode
7659 && TREE_CODE (type) == RECORD_TYPE)
7661 rtx rslt = rs6000_darwin64_record_arg (cum, type, named, false);
7662 if (rslt != NULL_RTX)
7663 return rslt;
7664 /* Else fall through to usual handling. */
7667 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
7668 if (TARGET_64BIT && ! cum->prototype)
7670 /* Vector parameters get passed in vector register
7671 and also in GPRs or memory, in absence of prototype. */
7672 int align_words;
7673 rtx slot;
7674 align_words = (cum->words + 1) & ~1;
7676 if (align_words >= GP_ARG_NUM_REG)
7678 slot = NULL_RTX;
7680 else
7682 slot = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
7684 return gen_rtx_PARALLEL (mode,
7685 gen_rtvec (2,
7686 gen_rtx_EXPR_LIST (VOIDmode,
7687 slot, const0_rtx),
7688 gen_rtx_EXPR_LIST (VOIDmode,
7689 gen_rtx_REG (mode, cum->vregno),
7690 const0_rtx)));
7692 else
7693 return gen_rtx_REG (mode, cum->vregno);
7694 else if (TARGET_ALTIVEC_ABI
7695 && (ALTIVEC_VECTOR_MODE (mode)
7696 || VSX_VECTOR_MODE (mode)
7697 || (type && TREE_CODE (type) == VECTOR_TYPE
7698 && int_size_in_bytes (type) == 16)))
7700 if (named || abi == ABI_V4)
7701 return NULL_RTX;
7702 else
7704 /* Vector parameters to varargs functions under AIX or Darwin
7705 get passed in memory and possibly also in GPRs. */
7706 int align, align_words, n_words;
7707 enum machine_mode part_mode;
7709 /* Vector parameters must be 16-byte aligned. This places them at
7710 2 mod 4 in terms of words in 32-bit mode, since the parameter
7711 save area starts at offset 24 from the stack. In 64-bit mode,
7712 they just have to start on an even word, since the parameter
7713 save area is 16-byte aligned. */
7714 if (TARGET_32BIT)
7715 align = (2 - cum->words) & 3;
7716 else
7717 align = cum->words & 1;
7718 align_words = cum->words + align;
7720 /* Out of registers? Memory, then. */
7721 if (align_words >= GP_ARG_NUM_REG)
7722 return NULL_RTX;
7724 if (TARGET_32BIT && TARGET_POWERPC64)
7725 return rs6000_mixed_function_arg (mode, type, align_words);
7727 /* The vector value goes in GPRs. Only the part of the
7728 value in GPRs is reported here. */
7729 part_mode = mode;
7730 n_words = rs6000_arg_size (mode, type);
7731 if (align_words + n_words > GP_ARG_NUM_REG)
7732 /* Fortunately, there are only two possibilities, the value
7733 is either wholly in GPRs or half in GPRs and half not. */
7734 part_mode = DImode;
7736 return gen_rtx_REG (part_mode, GP_ARG_MIN_REG + align_words);
7739 else if (TARGET_SPE_ABI && TARGET_SPE
7740 && (SPE_VECTOR_MODE (mode)
7741 || (TARGET_E500_DOUBLE && (mode == DFmode
7742 || mode == DCmode
7743 || mode == TFmode
7744 || mode == TCmode))))
7745 return rs6000_spe_function_arg (cum, mode, type);
7747 else if (abi == ABI_V4)
7749 if (TARGET_HARD_FLOAT && TARGET_FPRS
7750 && ((TARGET_SINGLE_FLOAT && mode == SFmode)
7751 || (TARGET_DOUBLE_FLOAT && mode == DFmode)
7752 || (mode == TFmode && !TARGET_IEEEQUAD)
7753 || mode == SDmode || mode == DDmode || mode == TDmode))
7755 /* _Decimal128 must use an even/odd register pair. This assumes
7756 that the register number is odd when fregno is odd. */
7757 if (mode == TDmode && (cum->fregno % 2) == 1)
7758 cum->fregno++;
7760 if (cum->fregno + (mode == TFmode || mode == TDmode ? 1 : 0)
7761 <= FP_ARG_V4_MAX_REG)
7762 return gen_rtx_REG (mode, cum->fregno);
7763 else
7764 return NULL_RTX;
7766 else
7768 int n_words = rs6000_arg_size (mode, type);
7769 int gregno = cum->sysv_gregno;
7771 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
7772 (r7,r8) or (r9,r10). As does any other 2 word item such
7773 as complex int due to a historical mistake. */
7774 if (n_words == 2)
7775 gregno += (1 - gregno) & 1;
7777 /* Multi-reg args are not split between registers and stack. */
7778 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
7779 return NULL_RTX;
7781 if (TARGET_32BIT && TARGET_POWERPC64)
7782 return rs6000_mixed_function_arg (mode, type,
7783 gregno - GP_ARG_MIN_REG);
7784 return gen_rtx_REG (mode, gregno);
7787 else
7789 int align_words = rs6000_parm_start (mode, type, cum->words);
7791 /* _Decimal128 must be passed in an even/odd float register pair.
7792 This assumes that the register number is odd when fregno is odd. */
7793 if (mode == TDmode && (cum->fregno % 2) == 1)
7794 cum->fregno++;
7796 if (USE_FP_FOR_ARG_P (cum, mode, type))
7798 rtx rvec[GP_ARG_NUM_REG + 1];
7799 rtx r;
7800 int k;
7801 bool needs_psave;
7802 enum machine_mode fmode = mode;
7803 unsigned long n_fpreg = (GET_MODE_SIZE (mode) + 7) >> 3;
7805 if (cum->fregno + n_fpreg > FP_ARG_MAX_REG + 1)
7807 /* Currently, we only ever need one reg here because complex
7808 doubles are split. */
7809 gcc_assert (cum->fregno == FP_ARG_MAX_REG
7810 && (fmode == TFmode || fmode == TDmode));
7812 /* Long double or _Decimal128 split over regs and memory. */
7813 fmode = DECIMAL_FLOAT_MODE_P (fmode) ? DDmode : DFmode;
7816 /* Do we also need to pass this arg in the parameter save
7817 area? */
7818 needs_psave = (type
7819 && (cum->nargs_prototype <= 0
7820 || (DEFAULT_ABI == ABI_AIX
7821 && TARGET_XL_COMPAT
7822 && align_words >= GP_ARG_NUM_REG)));
7824 if (!needs_psave && mode == fmode)
7825 return gen_rtx_REG (fmode, cum->fregno);
7827 k = 0;
7828 if (needs_psave)
7830 /* Describe the part that goes in gprs or the stack.
7831 This piece must come first, before the fprs. */
7832 if (align_words < GP_ARG_NUM_REG)
7834 unsigned long n_words = rs6000_arg_size (mode, type);
7836 if (align_words + n_words > GP_ARG_NUM_REG
7837 || (TARGET_32BIT && TARGET_POWERPC64))
7839 /* If this is partially on the stack, then we only
7840 include the portion actually in registers here. */
7841 enum machine_mode rmode = TARGET_32BIT ? SImode : DImode;
7842 rtx off;
7843 int i = 0;
7844 if (align_words + n_words > GP_ARG_NUM_REG)
7845 /* Not all of the arg fits in gprs. Say that it
7846 goes in memory too, using a magic NULL_RTX
7847 component. Also see comment in
7848 rs6000_mixed_function_arg for why the normal
7849 function_arg_partial_nregs scheme doesn't work
7850 in this case. */
7851 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX,
7852 const0_rtx);
7855 r = gen_rtx_REG (rmode,
7856 GP_ARG_MIN_REG + align_words);
7857 off = GEN_INT (i++ * GET_MODE_SIZE (rmode));
7858 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
7860 while (++align_words < GP_ARG_NUM_REG && --n_words != 0);
7862 else
7864 /* The whole arg fits in gprs. */
7865 r = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
7866 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
7869 else
7870 /* It's entirely in memory. */
7871 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
7874 /* Describe where this piece goes in the fprs. */
7875 r = gen_rtx_REG (fmode, cum->fregno);
7876 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
7878 return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
7880 else if (align_words < GP_ARG_NUM_REG)
7882 if (TARGET_32BIT && TARGET_POWERPC64)
7883 return rs6000_mixed_function_arg (mode, type, align_words);
7885 if (mode == BLKmode)
7886 mode = Pmode;
7888 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
7890 else
7891 return NULL_RTX;
7895 /* For an arg passed partly in registers and partly in memory, this is
7896 the number of bytes passed in registers. For args passed entirely in
7897 registers or entirely in memory, zero. When an arg is described by a
7898 PARALLEL, perhaps using more than one register type, this function
7899 returns the number of bytes used by the first element of the PARALLEL. */
7901 static int
7902 rs6000_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode,
7903 tree type, bool named)
7905 int ret = 0;
7906 int align_words;
7908 if (DEFAULT_ABI == ABI_V4)
7909 return 0;
7911 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named)
7912 && cum->nargs_prototype >= 0)
7913 return 0;
7915 /* In this complicated case we just disable the partial_nregs code. */
7916 if (rs6000_darwin64_abi && mode == BLKmode
7917 && TREE_CODE (type) == RECORD_TYPE
7918 && int_size_in_bytes (type) > 0)
7919 return 0;
7921 align_words = rs6000_parm_start (mode, type, cum->words);
7923 if (USE_FP_FOR_ARG_P (cum, mode, type))
7925 /* If we are passing this arg in the fixed parameter save area
7926 (gprs or memory) as well as fprs, then this function should
7927 return the number of partial bytes passed in the parameter
7928 save area rather than partial bytes passed in fprs. */
7929 if (type
7930 && (cum->nargs_prototype <= 0
7931 || (DEFAULT_ABI == ABI_AIX
7932 && TARGET_XL_COMPAT
7933 && align_words >= GP_ARG_NUM_REG)))
7934 return 0;
7935 else if (cum->fregno + ((GET_MODE_SIZE (mode) + 7) >> 3)
7936 > FP_ARG_MAX_REG + 1)
7937 ret = (FP_ARG_MAX_REG + 1 - cum->fregno) * 8;
7938 else if (cum->nargs_prototype >= 0)
7939 return 0;
7942 if (align_words < GP_ARG_NUM_REG
7943 && GP_ARG_NUM_REG < align_words + rs6000_arg_size (mode, type))
7944 ret = (GP_ARG_NUM_REG - align_words) * (TARGET_32BIT ? 4 : 8);
7946 if (ret != 0 && TARGET_DEBUG_ARG)
7947 fprintf (stderr, "rs6000_arg_partial_bytes: %d\n", ret);
7949 return ret;
7952 /* A C expression that indicates when an argument must be passed by
7953 reference. If nonzero for an argument, a copy of that argument is
7954 made in memory and a pointer to the argument is passed instead of
7955 the argument itself. The pointer is passed in whatever way is
7956 appropriate for passing a pointer to that type.
7958 Under V.4, aggregates and long double are passed by reference.
7960 As an extension to all 32-bit ABIs, AltiVec vectors are passed by
7961 reference unless the AltiVec vector extension ABI is in force.
7963 As an extension to all ABIs, variable sized types are passed by
7964 reference. */
7966 static bool
7967 rs6000_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
7968 enum machine_mode mode, const_tree type,
7969 bool named ATTRIBUTE_UNUSED)
7971 if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && mode == TFmode)
7973 if (TARGET_DEBUG_ARG)
7974 fprintf (stderr, "function_arg_pass_by_reference: V4 long double\n");
7975 return 1;
7978 if (!type)
7979 return 0;
7981 if (DEFAULT_ABI == ABI_V4 && AGGREGATE_TYPE_P (type))
7983 if (TARGET_DEBUG_ARG)
7984 fprintf (stderr, "function_arg_pass_by_reference: V4 aggregate\n");
7985 return 1;
7988 if (int_size_in_bytes (type) < 0)
7990 if (TARGET_DEBUG_ARG)
7991 fprintf (stderr, "function_arg_pass_by_reference: variable size\n");
7992 return 1;
7995 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
7996 modes only exist for GCC vector types if -maltivec. */
7997 if (TARGET_32BIT && !TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
7999 if (TARGET_DEBUG_ARG)
8000 fprintf (stderr, "function_arg_pass_by_reference: AltiVec\n");
8001 return 1;
8004 /* Pass synthetic vectors in memory. */
8005 if (TREE_CODE (type) == VECTOR_TYPE
8006 && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
8008 static bool warned_for_pass_big_vectors = false;
8009 if (TARGET_DEBUG_ARG)
8010 fprintf (stderr, "function_arg_pass_by_reference: synthetic vector\n");
8011 if (!warned_for_pass_big_vectors)
8013 warning (0, "GCC vector passed by reference: "
8014 "non-standard ABI extension with no compatibility guarantee");
8015 warned_for_pass_big_vectors = true;
8017 return 1;
8020 return 0;
8023 static void
8024 rs6000_move_block_from_reg (int regno, rtx x, int nregs)
8026 int i;
8027 enum machine_mode reg_mode = TARGET_32BIT ? SImode : DImode;
8029 if (nregs == 0)
8030 return;
8032 for (i = 0; i < nregs; i++)
8034 rtx tem = adjust_address_nv (x, reg_mode, i * GET_MODE_SIZE (reg_mode));
8035 if (reload_completed)
8037 if (! strict_memory_address_p (reg_mode, XEXP (tem, 0)))
8038 tem = NULL_RTX;
8039 else
8040 tem = simplify_gen_subreg (reg_mode, x, BLKmode,
8041 i * GET_MODE_SIZE (reg_mode));
8043 else
8044 tem = replace_equiv_address (tem, XEXP (tem, 0));
8046 gcc_assert (tem);
8048 emit_move_insn (tem, gen_rtx_REG (reg_mode, regno + i));
8052 /* Perform any needed actions needed for a function that is receiving a
8053 variable number of arguments.
8055 CUM is as above.
8057 MODE and TYPE are the mode and type of the current parameter.
8059 PRETEND_SIZE is a variable that should be set to the amount of stack
8060 that must be pushed by the prolog to pretend that our caller pushed
8063 Normally, this macro will push all remaining incoming registers on the
8064 stack and set PRETEND_SIZE to the length of the registers pushed. */
8066 static void
8067 setup_incoming_varargs (CUMULATIVE_ARGS *cum, enum machine_mode mode,
8068 tree type, int *pretend_size ATTRIBUTE_UNUSED,
8069 int no_rtl)
8071 CUMULATIVE_ARGS next_cum;
8072 int reg_size = TARGET_32BIT ? 4 : 8;
8073 rtx save_area = NULL_RTX, mem;
8074 int first_reg_offset;
8075 alias_set_type set;
8077 /* Skip the last named argument. */
8078 next_cum = *cum;
8079 function_arg_advance (&next_cum, mode, type, 1, 0);
8081 if (DEFAULT_ABI == ABI_V4)
8083 first_reg_offset = next_cum.sysv_gregno - GP_ARG_MIN_REG;
8085 if (! no_rtl)
8087 int gpr_reg_num = 0, gpr_size = 0, fpr_size = 0;
8088 HOST_WIDE_INT offset = 0;
8090 /* Try to optimize the size of the varargs save area.
8091 The ABI requires that ap.reg_save_area is doubleword
8092 aligned, but we don't need to allocate space for all
8093 the bytes, only those to which we actually will save
8094 anything. */
8095 if (cfun->va_list_gpr_size && first_reg_offset < GP_ARG_NUM_REG)
8096 gpr_reg_num = GP_ARG_NUM_REG - first_reg_offset;
8097 if (TARGET_HARD_FLOAT && TARGET_FPRS
8098 && next_cum.fregno <= FP_ARG_V4_MAX_REG
8099 && cfun->va_list_fpr_size)
8101 if (gpr_reg_num)
8102 fpr_size = (next_cum.fregno - FP_ARG_MIN_REG)
8103 * UNITS_PER_FP_WORD;
8104 if (cfun->va_list_fpr_size
8105 < FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
8106 fpr_size += cfun->va_list_fpr_size * UNITS_PER_FP_WORD;
8107 else
8108 fpr_size += (FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
8109 * UNITS_PER_FP_WORD;
8111 if (gpr_reg_num)
8113 offset = -((first_reg_offset * reg_size) & ~7);
8114 if (!fpr_size && gpr_reg_num > cfun->va_list_gpr_size)
8116 gpr_reg_num = cfun->va_list_gpr_size;
8117 if (reg_size == 4 && (first_reg_offset & 1))
8118 gpr_reg_num++;
8120 gpr_size = (gpr_reg_num * reg_size + 7) & ~7;
8122 else if (fpr_size)
8123 offset = - (int) (next_cum.fregno - FP_ARG_MIN_REG)
8124 * UNITS_PER_FP_WORD
8125 - (int) (GP_ARG_NUM_REG * reg_size);
8127 if (gpr_size + fpr_size)
8129 rtx reg_save_area
8130 = assign_stack_local (BLKmode, gpr_size + fpr_size, 64);
8131 gcc_assert (GET_CODE (reg_save_area) == MEM);
8132 reg_save_area = XEXP (reg_save_area, 0);
8133 if (GET_CODE (reg_save_area) == PLUS)
8135 gcc_assert (XEXP (reg_save_area, 0)
8136 == virtual_stack_vars_rtx);
8137 gcc_assert (GET_CODE (XEXP (reg_save_area, 1)) == CONST_INT);
8138 offset += INTVAL (XEXP (reg_save_area, 1));
8140 else
8141 gcc_assert (reg_save_area == virtual_stack_vars_rtx);
8144 cfun->machine->varargs_save_offset = offset;
8145 save_area = plus_constant (virtual_stack_vars_rtx, offset);
8148 else
8150 first_reg_offset = next_cum.words;
8151 save_area = virtual_incoming_args_rtx;
8153 if (targetm.calls.must_pass_in_stack (mode, type))
8154 first_reg_offset += rs6000_arg_size (TYPE_MODE (type), type);
8157 set = get_varargs_alias_set ();
8158 if (! no_rtl && first_reg_offset < GP_ARG_NUM_REG
8159 && cfun->va_list_gpr_size)
8161 int nregs = GP_ARG_NUM_REG - first_reg_offset;
8163 if (va_list_gpr_counter_field)
8165 /* V4 va_list_gpr_size counts number of registers needed. */
8166 if (nregs > cfun->va_list_gpr_size)
8167 nregs = cfun->va_list_gpr_size;
8169 else
8171 /* char * va_list instead counts number of bytes needed. */
8172 if (nregs > cfun->va_list_gpr_size / reg_size)
8173 nregs = cfun->va_list_gpr_size / reg_size;
8176 mem = gen_rtx_MEM (BLKmode,
8177 plus_constant (save_area,
8178 first_reg_offset * reg_size));
8179 MEM_NOTRAP_P (mem) = 1;
8180 set_mem_alias_set (mem, set);
8181 set_mem_align (mem, BITS_PER_WORD);
8183 rs6000_move_block_from_reg (GP_ARG_MIN_REG + first_reg_offset, mem,
8184 nregs);
8187 /* Save FP registers if needed. */
8188 if (DEFAULT_ABI == ABI_V4
8189 && TARGET_HARD_FLOAT && TARGET_FPRS
8190 && ! no_rtl
8191 && next_cum.fregno <= FP_ARG_V4_MAX_REG
8192 && cfun->va_list_fpr_size)
8194 int fregno = next_cum.fregno, nregs;
8195 rtx cr1 = gen_rtx_REG (CCmode, CR1_REGNO);
8196 rtx lab = gen_label_rtx ();
8197 int off = (GP_ARG_NUM_REG * reg_size) + ((fregno - FP_ARG_MIN_REG)
8198 * UNITS_PER_FP_WORD);
8200 emit_jump_insn
8201 (gen_rtx_SET (VOIDmode,
8202 pc_rtx,
8203 gen_rtx_IF_THEN_ELSE (VOIDmode,
8204 gen_rtx_NE (VOIDmode, cr1,
8205 const0_rtx),
8206 gen_rtx_LABEL_REF (VOIDmode, lab),
8207 pc_rtx)));
8209 for (nregs = 0;
8210 fregno <= FP_ARG_V4_MAX_REG && nregs < cfun->va_list_fpr_size;
8211 fregno++, off += UNITS_PER_FP_WORD, nregs++)
8213 mem = gen_rtx_MEM ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
8214 ? DFmode : SFmode,
8215 plus_constant (save_area, off));
8216 MEM_NOTRAP_P (mem) = 1;
8217 set_mem_alias_set (mem, set);
8218 set_mem_align (mem, GET_MODE_ALIGNMENT (
8219 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
8220 ? DFmode : SFmode));
8221 emit_move_insn (mem, gen_rtx_REG (
8222 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
8223 ? DFmode : SFmode, fregno));
8226 emit_label (lab);
8230 /* Create the va_list data type. */
8232 static tree
8233 rs6000_build_builtin_va_list (void)
8235 tree f_gpr, f_fpr, f_res, f_ovf, f_sav, record, type_decl;
8237 /* For AIX, prefer 'char *' because that's what the system
8238 header files like. */
8239 if (DEFAULT_ABI != ABI_V4)
8240 return build_pointer_type (char_type_node);
8242 record = (*lang_hooks.types.make_type) (RECORD_TYPE);
8243 type_decl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
8244 get_identifier ("__va_list_tag"), record);
8246 f_gpr = build_decl (BUILTINS_LOCATION, FIELD_DECL, get_identifier ("gpr"),
8247 unsigned_char_type_node);
8248 f_fpr = build_decl (BUILTINS_LOCATION, FIELD_DECL, get_identifier ("fpr"),
8249 unsigned_char_type_node);
8250 /* Give the two bytes of padding a name, so that -Wpadded won't warn on
8251 every user file. */
8252 f_res = build_decl (BUILTINS_LOCATION, FIELD_DECL,
8253 get_identifier ("reserved"), short_unsigned_type_node);
8254 f_ovf = build_decl (BUILTINS_LOCATION, FIELD_DECL,
8255 get_identifier ("overflow_arg_area"),
8256 ptr_type_node);
8257 f_sav = build_decl (BUILTINS_LOCATION, FIELD_DECL,
8258 get_identifier ("reg_save_area"),
8259 ptr_type_node);
8261 va_list_gpr_counter_field = f_gpr;
8262 va_list_fpr_counter_field = f_fpr;
8264 DECL_FIELD_CONTEXT (f_gpr) = record;
8265 DECL_FIELD_CONTEXT (f_fpr) = record;
8266 DECL_FIELD_CONTEXT (f_res) = record;
8267 DECL_FIELD_CONTEXT (f_ovf) = record;
8268 DECL_FIELD_CONTEXT (f_sav) = record;
8270 TREE_CHAIN (record) = type_decl;
8271 TYPE_NAME (record) = type_decl;
8272 TYPE_FIELDS (record) = f_gpr;
8273 TREE_CHAIN (f_gpr) = f_fpr;
8274 TREE_CHAIN (f_fpr) = f_res;
8275 TREE_CHAIN (f_res) = f_ovf;
8276 TREE_CHAIN (f_ovf) = f_sav;
8278 layout_type (record);
8280 /* The correct type is an array type of one element. */
8281 return build_array_type (record, build_index_type (size_zero_node));
8284 /* Implement va_start. */
8286 static void
8287 rs6000_va_start (tree valist, rtx nextarg)
8289 HOST_WIDE_INT words, n_gpr, n_fpr;
8290 tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
8291 tree gpr, fpr, ovf, sav, t;
8293 /* Only SVR4 needs something special. */
8294 if (DEFAULT_ABI != ABI_V4)
8296 std_expand_builtin_va_start (valist, nextarg);
8297 return;
8300 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
8301 f_fpr = TREE_CHAIN (f_gpr);
8302 f_res = TREE_CHAIN (f_fpr);
8303 f_ovf = TREE_CHAIN (f_res);
8304 f_sav = TREE_CHAIN (f_ovf);
8306 valist = build_va_arg_indirect_ref (valist);
8307 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
8308 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), unshare_expr (valist),
8309 f_fpr, NULL_TREE);
8310 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), unshare_expr (valist),
8311 f_ovf, NULL_TREE);
8312 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), unshare_expr (valist),
8313 f_sav, NULL_TREE);
8315 /* Count number of gp and fp argument registers used. */
8316 words = crtl->args.info.words;
8317 n_gpr = MIN (crtl->args.info.sysv_gregno - GP_ARG_MIN_REG,
8318 GP_ARG_NUM_REG);
8319 n_fpr = MIN (crtl->args.info.fregno - FP_ARG_MIN_REG,
8320 FP_ARG_NUM_REG);
8322 if (TARGET_DEBUG_ARG)
8323 fprintf (stderr, "va_start: words = "HOST_WIDE_INT_PRINT_DEC", n_gpr = "
8324 HOST_WIDE_INT_PRINT_DEC", n_fpr = "HOST_WIDE_INT_PRINT_DEC"\n",
8325 words, n_gpr, n_fpr);
8327 if (cfun->va_list_gpr_size)
8329 t = build2 (MODIFY_EXPR, TREE_TYPE (gpr), gpr,
8330 build_int_cst (NULL_TREE, n_gpr));
8331 TREE_SIDE_EFFECTS (t) = 1;
8332 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
8335 if (cfun->va_list_fpr_size)
8337 t = build2 (MODIFY_EXPR, TREE_TYPE (fpr), fpr,
8338 build_int_cst (NULL_TREE, n_fpr));
8339 TREE_SIDE_EFFECTS (t) = 1;
8340 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
8343 /* Find the overflow area. */
8344 t = make_tree (TREE_TYPE (ovf), virtual_incoming_args_rtx);
8345 if (words != 0)
8346 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (ovf), t,
8347 size_int (words * UNITS_PER_WORD));
8348 t = build2 (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
8349 TREE_SIDE_EFFECTS (t) = 1;
8350 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
8352 /* If there were no va_arg invocations, don't set up the register
8353 save area. */
8354 if (!cfun->va_list_gpr_size
8355 && !cfun->va_list_fpr_size
8356 && n_gpr < GP_ARG_NUM_REG
8357 && n_fpr < FP_ARG_V4_MAX_REG)
8358 return;
8360 /* Find the register save area. */
8361 t = make_tree (TREE_TYPE (sav), virtual_stack_vars_rtx);
8362 if (cfun->machine->varargs_save_offset)
8363 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (sav), t,
8364 size_int (cfun->machine->varargs_save_offset));
8365 t = build2 (MODIFY_EXPR, TREE_TYPE (sav), sav, t);
8366 TREE_SIDE_EFFECTS (t) = 1;
8367 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
8370 /* Implement va_arg. */
8372 tree
8373 rs6000_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
8374 gimple_seq *post_p)
8376 tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
8377 tree gpr, fpr, ovf, sav, reg, t, u;
8378 int size, rsize, n_reg, sav_ofs, sav_scale;
8379 tree lab_false, lab_over, addr;
8380 int align;
8381 tree ptrtype = build_pointer_type_for_mode (type, ptr_mode, true);
8382 int regalign = 0;
8383 gimple stmt;
8385 if (pass_by_reference (NULL, TYPE_MODE (type), type, false))
8387 t = rs6000_gimplify_va_arg (valist, ptrtype, pre_p, post_p);
8388 return build_va_arg_indirect_ref (t);
8391 if (DEFAULT_ABI != ABI_V4)
8393 if (targetm.calls.split_complex_arg && TREE_CODE (type) == COMPLEX_TYPE)
8395 tree elem_type = TREE_TYPE (type);
8396 enum machine_mode elem_mode = TYPE_MODE (elem_type);
8397 int elem_size = GET_MODE_SIZE (elem_mode);
8399 if (elem_size < UNITS_PER_WORD)
8401 tree real_part, imag_part;
8402 gimple_seq post = NULL;
8404 real_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
8405 &post);
8406 /* Copy the value into a temporary, lest the formal temporary
8407 be reused out from under us. */
8408 real_part = get_initialized_tmp_var (real_part, pre_p, &post);
8409 gimple_seq_add_seq (pre_p, post);
8411 imag_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
8412 post_p);
8414 return build2 (COMPLEX_EXPR, type, real_part, imag_part);
8418 return std_gimplify_va_arg_expr (valist, type, pre_p, post_p);
8421 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
8422 f_fpr = TREE_CHAIN (f_gpr);
8423 f_res = TREE_CHAIN (f_fpr);
8424 f_ovf = TREE_CHAIN (f_res);
8425 f_sav = TREE_CHAIN (f_ovf);
8427 valist = build_va_arg_indirect_ref (valist);
8428 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
8429 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), unshare_expr (valist),
8430 f_fpr, NULL_TREE);
8431 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), unshare_expr (valist),
8432 f_ovf, NULL_TREE);
8433 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), unshare_expr (valist),
8434 f_sav, NULL_TREE);
8436 size = int_size_in_bytes (type);
8437 rsize = (size + 3) / 4;
8438 align = 1;
8440 if (TARGET_HARD_FLOAT && TARGET_FPRS
8441 && ((TARGET_SINGLE_FLOAT && TYPE_MODE (type) == SFmode)
8442 || (TARGET_DOUBLE_FLOAT
8443 && (TYPE_MODE (type) == DFmode
8444 || TYPE_MODE (type) == TFmode
8445 || TYPE_MODE (type) == SDmode
8446 || TYPE_MODE (type) == DDmode
8447 || TYPE_MODE (type) == TDmode))))
8449 /* FP args go in FP registers, if present. */
8450 reg = fpr;
8451 n_reg = (size + 7) / 8;
8452 sav_ofs = ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? 8 : 4) * 4;
8453 sav_scale = ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? 8 : 4);
8454 if (TYPE_MODE (type) != SFmode && TYPE_MODE (type) != SDmode)
8455 align = 8;
8457 else
8459 /* Otherwise into GP registers. */
8460 reg = gpr;
8461 n_reg = rsize;
8462 sav_ofs = 0;
8463 sav_scale = 4;
8464 if (n_reg == 2)
8465 align = 8;
8468 /* Pull the value out of the saved registers.... */
8470 lab_over = NULL;
8471 addr = create_tmp_var (ptr_type_node, "addr");
8473 /* AltiVec vectors never go in registers when -mabi=altivec. */
8474 if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
8475 align = 16;
8476 else
8478 lab_false = create_artificial_label (input_location);
8479 lab_over = create_artificial_label (input_location);
8481 /* Long long and SPE vectors are aligned in the registers.
8482 As are any other 2 gpr item such as complex int due to a
8483 historical mistake. */
8484 u = reg;
8485 if (n_reg == 2 && reg == gpr)
8487 regalign = 1;
8488 u = build2 (BIT_AND_EXPR, TREE_TYPE (reg), unshare_expr (reg),
8489 build_int_cst (TREE_TYPE (reg), n_reg - 1));
8490 u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg),
8491 unshare_expr (reg), u);
8493 /* _Decimal128 is passed in even/odd fpr pairs; the stored
8494 reg number is 0 for f1, so we want to make it odd. */
8495 else if (reg == fpr && TYPE_MODE (type) == TDmode)
8497 t = build2 (BIT_IOR_EXPR, TREE_TYPE (reg), unshare_expr (reg),
8498 build_int_cst (TREE_TYPE (reg), 1));
8499 u = build2 (MODIFY_EXPR, void_type_node, unshare_expr (reg), t);
8502 t = fold_convert (TREE_TYPE (reg), size_int (8 - n_reg + 1));
8503 t = build2 (GE_EXPR, boolean_type_node, u, t);
8504 u = build1 (GOTO_EXPR, void_type_node, lab_false);
8505 t = build3 (COND_EXPR, void_type_node, t, u, NULL_TREE);
8506 gimplify_and_add (t, pre_p);
8508 t = sav;
8509 if (sav_ofs)
8510 t = build2 (POINTER_PLUS_EXPR, ptr_type_node, sav, size_int (sav_ofs));
8512 u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg), unshare_expr (reg),
8513 build_int_cst (TREE_TYPE (reg), n_reg));
8514 u = fold_convert (sizetype, u);
8515 u = build2 (MULT_EXPR, sizetype, u, size_int (sav_scale));
8516 t = build2 (POINTER_PLUS_EXPR, ptr_type_node, t, u);
8518 /* _Decimal32 varargs are located in the second word of the 64-bit
8519 FP register for 32-bit binaries. */
8520 if (!TARGET_POWERPC64
8521 && TARGET_HARD_FLOAT && TARGET_FPRS
8522 && TYPE_MODE (type) == SDmode)
8523 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (size));
8525 gimplify_assign (addr, t, pre_p);
8527 gimple_seq_add_stmt (pre_p, gimple_build_goto (lab_over));
8529 stmt = gimple_build_label (lab_false);
8530 gimple_seq_add_stmt (pre_p, stmt);
8532 if ((n_reg == 2 && !regalign) || n_reg > 2)
8534 /* Ensure that we don't find any more args in regs.
8535 Alignment has taken care of for special cases. */
8536 gimplify_assign (reg, build_int_cst (TREE_TYPE (reg), 8), pre_p);
8540 /* ... otherwise out of the overflow area. */
8542 /* Care for on-stack alignment if needed. */
8543 t = ovf;
8544 if (align != 1)
8546 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (align - 1));
8547 t = fold_convert (sizetype, t);
8548 t = build2 (BIT_AND_EXPR, TREE_TYPE (t), t,
8549 size_int (-align));
8550 t = fold_convert (TREE_TYPE (ovf), t);
8552 gimplify_expr (&t, pre_p, NULL, is_gimple_val, fb_rvalue);
8554 gimplify_assign (unshare_expr (addr), t, pre_p);
8556 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (size));
8557 gimplify_assign (unshare_expr (ovf), t, pre_p);
8559 if (lab_over)
8561 stmt = gimple_build_label (lab_over);
8562 gimple_seq_add_stmt (pre_p, stmt);
8565 if (STRICT_ALIGNMENT
8566 && (TYPE_ALIGN (type)
8567 > (unsigned) BITS_PER_UNIT * (align < 4 ? 4 : align)))
8569 /* The value (of type complex double, for example) may not be
8570 aligned in memory in the saved registers, so copy via a
8571 temporary. (This is the same code as used for SPARC.) */
8572 tree tmp = create_tmp_var (type, "va_arg_tmp");
8573 tree dest_addr = build_fold_addr_expr (tmp);
8575 tree copy = build_call_expr (implicit_built_in_decls[BUILT_IN_MEMCPY],
8576 3, dest_addr, addr, size_int (rsize * 4));
8578 gimplify_and_add (copy, pre_p);
8579 addr = dest_addr;
8582 addr = fold_convert (ptrtype, addr);
8583 return build_va_arg_indirect_ref (addr);
8586 /* Builtins. */
8588 static void
8589 def_builtin (int mask, const char *name, tree type, int code)
8591 if ((mask & target_flags) || TARGET_PAIRED_FLOAT)
8593 tree t;
8594 if (rs6000_builtin_decls[code])
8595 fatal_error ("internal error: builtin function to %s already processed.",
8596 name);
8598 rs6000_builtin_decls[code] = t =
8599 add_builtin_function (name, type, code, BUILT_IN_MD,
8600 NULL, NULL_TREE);
8602 gcc_assert (code >= 0 && code < (int)RS6000_BUILTIN_COUNT);
8603 switch (builtin_classify[code])
8605 default:
8606 gcc_unreachable ();
8608 /* assume builtin can do anything. */
8609 case RS6000_BTC_MISC:
8610 break;
8612 /* const function, function only depends on the inputs. */
8613 case RS6000_BTC_CONST:
8614 TREE_READONLY (t) = 1;
8615 TREE_NOTHROW (t) = 1;
8616 break;
8618 /* pure function, function can read global memory. */
8619 case RS6000_BTC_PURE:
8620 DECL_PURE_P (t) = 1;
8621 TREE_NOTHROW (t) = 1;
8622 break;
8624 /* Function is a math function. If rounding mode is on, then treat
8625 the function as not reading global memory, but it can have
8626 arbitrary side effects. If it is off, then assume the function is
8627 a const function. This mimics the ATTR_MATHFN_FPROUNDING
8628 attribute in builtin-attribute.def that is used for the math
8629 functions. */
8630 case RS6000_BTC_FP_PURE:
8631 TREE_NOTHROW (t) = 1;
8632 if (flag_rounding_math)
8634 DECL_PURE_P (t) = 1;
8635 DECL_IS_NOVOPS (t) = 1;
8637 else
8638 TREE_READONLY (t) = 1;
8639 break;
8644 /* Simple ternary operations: VECd = foo (VECa, VECb, VECc). */
8646 static const struct builtin_description bdesc_3arg[] =
8648 { MASK_ALTIVEC, CODE_FOR_altivec_vmaddfp, "__builtin_altivec_vmaddfp", ALTIVEC_BUILTIN_VMADDFP },
8649 { MASK_ALTIVEC, CODE_FOR_altivec_vmhaddshs, "__builtin_altivec_vmhaddshs", ALTIVEC_BUILTIN_VMHADDSHS },
8650 { MASK_ALTIVEC, CODE_FOR_altivec_vmhraddshs, "__builtin_altivec_vmhraddshs", ALTIVEC_BUILTIN_VMHRADDSHS },
8651 { MASK_ALTIVEC, CODE_FOR_altivec_vmladduhm, "__builtin_altivec_vmladduhm", ALTIVEC_BUILTIN_VMLADDUHM},
8652 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumubm, "__builtin_altivec_vmsumubm", ALTIVEC_BUILTIN_VMSUMUBM },
8653 { MASK_ALTIVEC, CODE_FOR_altivec_vmsummbm, "__builtin_altivec_vmsummbm", ALTIVEC_BUILTIN_VMSUMMBM },
8654 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhm, "__builtin_altivec_vmsumuhm", ALTIVEC_BUILTIN_VMSUMUHM },
8655 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshm, "__builtin_altivec_vmsumshm", ALTIVEC_BUILTIN_VMSUMSHM },
8656 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhs, "__builtin_altivec_vmsumuhs", ALTIVEC_BUILTIN_VMSUMUHS },
8657 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshs, "__builtin_altivec_vmsumshs", ALTIVEC_BUILTIN_VMSUMSHS },
8658 { MASK_ALTIVEC, CODE_FOR_altivec_vnmsubfp, "__builtin_altivec_vnmsubfp", ALTIVEC_BUILTIN_VNMSUBFP },
8659 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2df, "__builtin_altivec_vperm_2df", ALTIVEC_BUILTIN_VPERM_2DF },
8660 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2di, "__builtin_altivec_vperm_2di", ALTIVEC_BUILTIN_VPERM_2DI },
8661 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4sf, "__builtin_altivec_vperm_4sf", ALTIVEC_BUILTIN_VPERM_4SF },
8662 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4si, "__builtin_altivec_vperm_4si", ALTIVEC_BUILTIN_VPERM_4SI },
8663 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v8hi, "__builtin_altivec_vperm_8hi", ALTIVEC_BUILTIN_VPERM_8HI },
8664 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_altivec_vperm_16qi", ALTIVEC_BUILTIN_VPERM_16QI },
8665 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2di_uns, "__builtin_altivec_vperm_2di_uns", ALTIVEC_BUILTIN_VPERM_2DI_UNS },
8666 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4si_uns, "__builtin_altivec_vperm_4si_uns", ALTIVEC_BUILTIN_VPERM_4SI_UNS },
8667 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v8hi_uns, "__builtin_altivec_vperm_8hi_uns", ALTIVEC_BUILTIN_VPERM_8HI_UNS },
8668 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_altivec_vperm_16qi_uns", ALTIVEC_BUILTIN_VPERM_16QI_UNS },
8669 { MASK_ALTIVEC, CODE_FOR_vector_select_v4sf, "__builtin_altivec_vsel_4sf", ALTIVEC_BUILTIN_VSEL_4SF },
8670 { MASK_ALTIVEC, CODE_FOR_vector_select_v4si, "__builtin_altivec_vsel_4si", ALTIVEC_BUILTIN_VSEL_4SI },
8671 { MASK_ALTIVEC, CODE_FOR_vector_select_v8hi, "__builtin_altivec_vsel_8hi", ALTIVEC_BUILTIN_VSEL_8HI },
8672 { MASK_ALTIVEC, CODE_FOR_vector_select_v16qi, "__builtin_altivec_vsel_16qi", ALTIVEC_BUILTIN_VSEL_16QI },
8673 { MASK_ALTIVEC, CODE_FOR_vector_select_v2df, "__builtin_altivec_vsel_2df", ALTIVEC_BUILTIN_VSEL_2DF },
8674 { MASK_ALTIVEC, CODE_FOR_vector_select_v2di, "__builtin_altivec_vsel_2di", ALTIVEC_BUILTIN_VSEL_2DI },
8675 { MASK_ALTIVEC, CODE_FOR_vector_select_v4si_uns, "__builtin_altivec_vsel_4si_uns", ALTIVEC_BUILTIN_VSEL_4SI_UNS },
8676 { MASK_ALTIVEC, CODE_FOR_vector_select_v8hi_uns, "__builtin_altivec_vsel_8hi_uns", ALTIVEC_BUILTIN_VSEL_8HI_UNS },
8677 { MASK_ALTIVEC, CODE_FOR_vector_select_v16qi_uns, "__builtin_altivec_vsel_16qi_uns", ALTIVEC_BUILTIN_VSEL_16QI_UNS },
8678 { MASK_ALTIVEC, CODE_FOR_vector_select_v2di_uns, "__builtin_altivec_vsel_2di_uns", ALTIVEC_BUILTIN_VSEL_2DI_UNS },
8679 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v16qi, "__builtin_altivec_vsldoi_16qi", ALTIVEC_BUILTIN_VSLDOI_16QI },
8680 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v8hi, "__builtin_altivec_vsldoi_8hi", ALTIVEC_BUILTIN_VSLDOI_8HI },
8681 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v4si, "__builtin_altivec_vsldoi_4si", ALTIVEC_BUILTIN_VSLDOI_4SI },
8682 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v4sf, "__builtin_altivec_vsldoi_4sf", ALTIVEC_BUILTIN_VSLDOI_4SF },
8684 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_madd", ALTIVEC_BUILTIN_VEC_MADD },
8685 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_madds", ALTIVEC_BUILTIN_VEC_MADDS },
8686 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mladd", ALTIVEC_BUILTIN_VEC_MLADD },
8687 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mradds", ALTIVEC_BUILTIN_VEC_MRADDS },
8688 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msum", ALTIVEC_BUILTIN_VEC_MSUM },
8689 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumshm", ALTIVEC_BUILTIN_VEC_VMSUMSHM },
8690 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumuhm", ALTIVEC_BUILTIN_VEC_VMSUMUHM },
8691 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsummbm", ALTIVEC_BUILTIN_VEC_VMSUMMBM },
8692 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumubm", ALTIVEC_BUILTIN_VEC_VMSUMUBM },
8693 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msums", ALTIVEC_BUILTIN_VEC_MSUMS },
8694 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumshs", ALTIVEC_BUILTIN_VEC_VMSUMSHS },
8695 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumuhs", ALTIVEC_BUILTIN_VEC_VMSUMUHS },
8696 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nmsub", ALTIVEC_BUILTIN_VEC_NMSUB },
8697 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_perm", ALTIVEC_BUILTIN_VEC_PERM },
8698 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sel", ALTIVEC_BUILTIN_VEC_SEL },
8700 { MASK_VSX, CODE_FOR_vsx_fmaddv2df4, "__builtin_vsx_xvmadddp", VSX_BUILTIN_XVMADDDP },
8701 { MASK_VSX, CODE_FOR_vsx_fmsubv2df4, "__builtin_vsx_xvmsubdp", VSX_BUILTIN_XVMSUBDP },
8702 { MASK_VSX, CODE_FOR_vsx_fnmaddv2df4, "__builtin_vsx_xvnmadddp", VSX_BUILTIN_XVNMADDDP },
8703 { MASK_VSX, CODE_FOR_vsx_fnmsubv2df4, "__builtin_vsx_xvnmsubdp", VSX_BUILTIN_XVNMSUBDP },
8705 { MASK_VSX, CODE_FOR_vsx_fmaddv4sf4, "__builtin_vsx_xvmaddsp", VSX_BUILTIN_XVMADDSP },
8706 { MASK_VSX, CODE_FOR_vsx_fmsubv4sf4, "__builtin_vsx_xvmsubsp", VSX_BUILTIN_XVMSUBSP },
8707 { MASK_VSX, CODE_FOR_vsx_fnmaddv4sf4, "__builtin_vsx_xvnmaddsp", VSX_BUILTIN_XVNMADDSP },
8708 { MASK_VSX, CODE_FOR_vsx_fnmsubv4sf4, "__builtin_vsx_xvnmsubsp", VSX_BUILTIN_XVNMSUBSP },
8710 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msub", VSX_BUILTIN_VEC_MSUB },
8711 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nmadd", VSX_BUILTIN_VEC_NMADD },
8713 { MASK_VSX, CODE_FOR_vector_select_v2di, "__builtin_vsx_xxsel_2di", VSX_BUILTIN_XXSEL_2DI },
8714 { MASK_VSX, CODE_FOR_vector_select_v2df, "__builtin_vsx_xxsel_2df", VSX_BUILTIN_XXSEL_2DF },
8715 { MASK_VSX, CODE_FOR_vector_select_v4sf, "__builtin_vsx_xxsel_4sf", VSX_BUILTIN_XXSEL_4SF },
8716 { MASK_VSX, CODE_FOR_vector_select_v4si, "__builtin_vsx_xxsel_4si", VSX_BUILTIN_XXSEL_4SI },
8717 { MASK_VSX, CODE_FOR_vector_select_v8hi, "__builtin_vsx_xxsel_8hi", VSX_BUILTIN_XXSEL_8HI },
8718 { MASK_VSX, CODE_FOR_vector_select_v16qi, "__builtin_vsx_xxsel_16qi", VSX_BUILTIN_XXSEL_16QI },
8719 { MASK_VSX, CODE_FOR_vector_select_v2di_uns, "__builtin_vsx_xxsel_2di_uns", VSX_BUILTIN_XXSEL_2DI_UNS },
8720 { MASK_VSX, CODE_FOR_vector_select_v4si_uns, "__builtin_vsx_xxsel_4si_uns", VSX_BUILTIN_XXSEL_4SI_UNS },
8721 { MASK_VSX, CODE_FOR_vector_select_v8hi_uns, "__builtin_vsx_xxsel_8hi_uns", VSX_BUILTIN_XXSEL_8HI_UNS },
8722 { MASK_VSX, CODE_FOR_vector_select_v16qi_uns, "__builtin_vsx_xxsel_16qi_uns", VSX_BUILTIN_XXSEL_16QI_UNS },
8724 { MASK_VSX, CODE_FOR_altivec_vperm_v2di, "__builtin_vsx_vperm_2di", VSX_BUILTIN_VPERM_2DI },
8725 { MASK_VSX, CODE_FOR_altivec_vperm_v2df, "__builtin_vsx_vperm_2df", VSX_BUILTIN_VPERM_2DF },
8726 { MASK_VSX, CODE_FOR_altivec_vperm_v4sf, "__builtin_vsx_vperm_4sf", VSX_BUILTIN_VPERM_4SF },
8727 { MASK_VSX, CODE_FOR_altivec_vperm_v4si, "__builtin_vsx_vperm_4si", VSX_BUILTIN_VPERM_4SI },
8728 { MASK_VSX, CODE_FOR_altivec_vperm_v8hi, "__builtin_vsx_vperm_8hi", VSX_BUILTIN_VPERM_8HI },
8729 { MASK_VSX, CODE_FOR_altivec_vperm_v16qi, "__builtin_vsx_vperm_16qi", VSX_BUILTIN_VPERM_16QI },
8730 { MASK_VSX, CODE_FOR_altivec_vperm_v2di_uns, "__builtin_vsx_vperm_2di_uns", VSX_BUILTIN_VPERM_2DI_UNS },
8731 { MASK_VSX, CODE_FOR_altivec_vperm_v4si_uns, "__builtin_vsx_vperm_4si_uns", VSX_BUILTIN_VPERM_4SI_UNS },
8732 { MASK_VSX, CODE_FOR_altivec_vperm_v8hi_uns, "__builtin_vsx_vperm_8hi_uns", VSX_BUILTIN_VPERM_8HI_UNS },
8733 { MASK_VSX, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_vsx_vperm_16qi_uns", VSX_BUILTIN_VPERM_16QI_UNS },
8735 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v2df, "__builtin_vsx_xxpermdi_2df", VSX_BUILTIN_XXPERMDI_2DF },
8736 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v2di, "__builtin_vsx_xxpermdi_2di", VSX_BUILTIN_XXPERMDI_2DI },
8737 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v4sf, "__builtin_vsx_xxpermdi_4sf", VSX_BUILTIN_XXPERMDI_4SF },
8738 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v4si, "__builtin_vsx_xxpermdi_4si", VSX_BUILTIN_XXPERMDI_4SI },
8739 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v8hi, "__builtin_vsx_xxpermdi_8hi", VSX_BUILTIN_XXPERMDI_8HI },
8740 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v16qi, "__builtin_vsx_xxpermdi_16qi", VSX_BUILTIN_XXPERMDI_16QI },
8741 { MASK_VSX, CODE_FOR_nothing, "__builtin_vsx_xxpermdi", VSX_BUILTIN_VEC_XXPERMDI },
8742 { MASK_VSX, CODE_FOR_vsx_set_v2df, "__builtin_vsx_set_2df", VSX_BUILTIN_SET_2DF },
8743 { MASK_VSX, CODE_FOR_vsx_set_v2di, "__builtin_vsx_set_2di", VSX_BUILTIN_SET_2DI },
8745 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v2di, "__builtin_vsx_xxsldwi_2di", VSX_BUILTIN_XXSLDWI_2DI },
8746 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v2df, "__builtin_vsx_xxsldwi_2df", VSX_BUILTIN_XXSLDWI_2DF },
8747 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v4sf, "__builtin_vsx_xxsldwi_4sf", VSX_BUILTIN_XXSLDWI_4SF },
8748 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v4si, "__builtin_vsx_xxsldwi_4si", VSX_BUILTIN_XXSLDWI_4SI },
8749 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v8hi, "__builtin_vsx_xxsldwi_8hi", VSX_BUILTIN_XXSLDWI_8HI },
8750 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v16qi, "__builtin_vsx_xxsldwi_16qi", VSX_BUILTIN_XXSLDWI_16QI },
8751 { MASK_VSX, CODE_FOR_nothing, "__builtin_vsx_xxsldwi", VSX_BUILTIN_VEC_XXSLDWI },
8753 { 0, CODE_FOR_paired_msub, "__builtin_paired_msub", PAIRED_BUILTIN_MSUB },
8754 { 0, CODE_FOR_paired_madd, "__builtin_paired_madd", PAIRED_BUILTIN_MADD },
8755 { 0, CODE_FOR_paired_madds0, "__builtin_paired_madds0", PAIRED_BUILTIN_MADDS0 },
8756 { 0, CODE_FOR_paired_madds1, "__builtin_paired_madds1", PAIRED_BUILTIN_MADDS1 },
8757 { 0, CODE_FOR_paired_nmsub, "__builtin_paired_nmsub", PAIRED_BUILTIN_NMSUB },
8758 { 0, CODE_FOR_paired_nmadd, "__builtin_paired_nmadd", PAIRED_BUILTIN_NMADD },
8759 { 0, CODE_FOR_paired_sum0, "__builtin_paired_sum0", PAIRED_BUILTIN_SUM0 },
8760 { 0, CODE_FOR_paired_sum1, "__builtin_paired_sum1", PAIRED_BUILTIN_SUM1 },
8761 { 0, CODE_FOR_selv2sf4, "__builtin_paired_selv2sf4", PAIRED_BUILTIN_SELV2SF4 },
8764 /* DST operations: void foo (void *, const int, const char). */
8766 static const struct builtin_description bdesc_dst[] =
8768 { MASK_ALTIVEC, CODE_FOR_altivec_dst, "__builtin_altivec_dst", ALTIVEC_BUILTIN_DST },
8769 { MASK_ALTIVEC, CODE_FOR_altivec_dstt, "__builtin_altivec_dstt", ALTIVEC_BUILTIN_DSTT },
8770 { MASK_ALTIVEC, CODE_FOR_altivec_dstst, "__builtin_altivec_dstst", ALTIVEC_BUILTIN_DSTST },
8771 { MASK_ALTIVEC, CODE_FOR_altivec_dststt, "__builtin_altivec_dststt", ALTIVEC_BUILTIN_DSTSTT },
8773 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dst", ALTIVEC_BUILTIN_VEC_DST },
8774 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dstt", ALTIVEC_BUILTIN_VEC_DSTT },
8775 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dstst", ALTIVEC_BUILTIN_VEC_DSTST },
8776 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dststt", ALTIVEC_BUILTIN_VEC_DSTSTT }
8779 /* Simple binary operations: VECc = foo (VECa, VECb). */
8781 static struct builtin_description bdesc_2arg[] =
8783 { MASK_ALTIVEC, CODE_FOR_addv16qi3, "__builtin_altivec_vaddubm", ALTIVEC_BUILTIN_VADDUBM },
8784 { MASK_ALTIVEC, CODE_FOR_addv8hi3, "__builtin_altivec_vadduhm", ALTIVEC_BUILTIN_VADDUHM },
8785 { MASK_ALTIVEC, CODE_FOR_addv4si3, "__builtin_altivec_vadduwm", ALTIVEC_BUILTIN_VADDUWM },
8786 { MASK_ALTIVEC, CODE_FOR_addv4sf3, "__builtin_altivec_vaddfp", ALTIVEC_BUILTIN_VADDFP },
8787 { MASK_ALTIVEC, CODE_FOR_altivec_vaddcuw, "__builtin_altivec_vaddcuw", ALTIVEC_BUILTIN_VADDCUW },
8788 { MASK_ALTIVEC, CODE_FOR_altivec_vaddubs, "__builtin_altivec_vaddubs", ALTIVEC_BUILTIN_VADDUBS },
8789 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsbs, "__builtin_altivec_vaddsbs", ALTIVEC_BUILTIN_VADDSBS },
8790 { MASK_ALTIVEC, CODE_FOR_altivec_vadduhs, "__builtin_altivec_vadduhs", ALTIVEC_BUILTIN_VADDUHS },
8791 { MASK_ALTIVEC, CODE_FOR_altivec_vaddshs, "__builtin_altivec_vaddshs", ALTIVEC_BUILTIN_VADDSHS },
8792 { MASK_ALTIVEC, CODE_FOR_altivec_vadduws, "__builtin_altivec_vadduws", ALTIVEC_BUILTIN_VADDUWS },
8793 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsws, "__builtin_altivec_vaddsws", ALTIVEC_BUILTIN_VADDSWS },
8794 { MASK_ALTIVEC, CODE_FOR_andv4si3, "__builtin_altivec_vand", ALTIVEC_BUILTIN_VAND },
8795 { MASK_ALTIVEC, CODE_FOR_andcv4si3, "__builtin_altivec_vandc", ALTIVEC_BUILTIN_VANDC },
8796 { MASK_ALTIVEC, CODE_FOR_altivec_vavgub, "__builtin_altivec_vavgub", ALTIVEC_BUILTIN_VAVGUB },
8797 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsb, "__builtin_altivec_vavgsb", ALTIVEC_BUILTIN_VAVGSB },
8798 { MASK_ALTIVEC, CODE_FOR_altivec_vavguh, "__builtin_altivec_vavguh", ALTIVEC_BUILTIN_VAVGUH },
8799 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsh, "__builtin_altivec_vavgsh", ALTIVEC_BUILTIN_VAVGSH },
8800 { MASK_ALTIVEC, CODE_FOR_altivec_vavguw, "__builtin_altivec_vavguw", ALTIVEC_BUILTIN_VAVGUW },
8801 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsw, "__builtin_altivec_vavgsw", ALTIVEC_BUILTIN_VAVGSW },
8802 { MASK_ALTIVEC, CODE_FOR_altivec_vcfux, "__builtin_altivec_vcfux", ALTIVEC_BUILTIN_VCFUX },
8803 { MASK_ALTIVEC, CODE_FOR_altivec_vcfsx, "__builtin_altivec_vcfsx", ALTIVEC_BUILTIN_VCFSX },
8804 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpbfp, "__builtin_altivec_vcmpbfp", ALTIVEC_BUILTIN_VCMPBFP },
8805 { MASK_ALTIVEC, CODE_FOR_vector_eqv16qi, "__builtin_altivec_vcmpequb", ALTIVEC_BUILTIN_VCMPEQUB },
8806 { MASK_ALTIVEC, CODE_FOR_vector_eqv8hi, "__builtin_altivec_vcmpequh", ALTIVEC_BUILTIN_VCMPEQUH },
8807 { MASK_ALTIVEC, CODE_FOR_vector_eqv4si, "__builtin_altivec_vcmpequw", ALTIVEC_BUILTIN_VCMPEQUW },
8808 { MASK_ALTIVEC, CODE_FOR_vector_eqv4sf, "__builtin_altivec_vcmpeqfp", ALTIVEC_BUILTIN_VCMPEQFP },
8809 { MASK_ALTIVEC, CODE_FOR_vector_gev4sf, "__builtin_altivec_vcmpgefp", ALTIVEC_BUILTIN_VCMPGEFP },
8810 { MASK_ALTIVEC, CODE_FOR_vector_gtuv16qi, "__builtin_altivec_vcmpgtub", ALTIVEC_BUILTIN_VCMPGTUB },
8811 { MASK_ALTIVEC, CODE_FOR_vector_gtv16qi, "__builtin_altivec_vcmpgtsb", ALTIVEC_BUILTIN_VCMPGTSB },
8812 { MASK_ALTIVEC, CODE_FOR_vector_gtuv8hi, "__builtin_altivec_vcmpgtuh", ALTIVEC_BUILTIN_VCMPGTUH },
8813 { MASK_ALTIVEC, CODE_FOR_vector_gtv8hi, "__builtin_altivec_vcmpgtsh", ALTIVEC_BUILTIN_VCMPGTSH },
8814 { MASK_ALTIVEC, CODE_FOR_vector_gtuv4si, "__builtin_altivec_vcmpgtuw", ALTIVEC_BUILTIN_VCMPGTUW },
8815 { MASK_ALTIVEC, CODE_FOR_vector_gtv4si, "__builtin_altivec_vcmpgtsw", ALTIVEC_BUILTIN_VCMPGTSW },
8816 { MASK_ALTIVEC, CODE_FOR_vector_gtv4sf, "__builtin_altivec_vcmpgtfp", ALTIVEC_BUILTIN_VCMPGTFP },
8817 { MASK_ALTIVEC, CODE_FOR_altivec_vctsxs, "__builtin_altivec_vctsxs", ALTIVEC_BUILTIN_VCTSXS },
8818 { MASK_ALTIVEC, CODE_FOR_altivec_vctuxs, "__builtin_altivec_vctuxs", ALTIVEC_BUILTIN_VCTUXS },
8819 { MASK_ALTIVEC, CODE_FOR_umaxv16qi3, "__builtin_altivec_vmaxub", ALTIVEC_BUILTIN_VMAXUB },
8820 { MASK_ALTIVEC, CODE_FOR_smaxv16qi3, "__builtin_altivec_vmaxsb", ALTIVEC_BUILTIN_VMAXSB },
8821 { MASK_ALTIVEC, CODE_FOR_umaxv8hi3, "__builtin_altivec_vmaxuh", ALTIVEC_BUILTIN_VMAXUH },
8822 { MASK_ALTIVEC, CODE_FOR_smaxv8hi3, "__builtin_altivec_vmaxsh", ALTIVEC_BUILTIN_VMAXSH },
8823 { MASK_ALTIVEC, CODE_FOR_umaxv4si3, "__builtin_altivec_vmaxuw", ALTIVEC_BUILTIN_VMAXUW },
8824 { MASK_ALTIVEC, CODE_FOR_smaxv4si3, "__builtin_altivec_vmaxsw", ALTIVEC_BUILTIN_VMAXSW },
8825 { MASK_ALTIVEC, CODE_FOR_smaxv4sf3, "__builtin_altivec_vmaxfp", ALTIVEC_BUILTIN_VMAXFP },
8826 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghb, "__builtin_altivec_vmrghb", ALTIVEC_BUILTIN_VMRGHB },
8827 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghh, "__builtin_altivec_vmrghh", ALTIVEC_BUILTIN_VMRGHH },
8828 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghw, "__builtin_altivec_vmrghw", ALTIVEC_BUILTIN_VMRGHW },
8829 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglb, "__builtin_altivec_vmrglb", ALTIVEC_BUILTIN_VMRGLB },
8830 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglh, "__builtin_altivec_vmrglh", ALTIVEC_BUILTIN_VMRGLH },
8831 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglw, "__builtin_altivec_vmrglw", ALTIVEC_BUILTIN_VMRGLW },
8832 { MASK_ALTIVEC, CODE_FOR_uminv16qi3, "__builtin_altivec_vminub", ALTIVEC_BUILTIN_VMINUB },
8833 { MASK_ALTIVEC, CODE_FOR_sminv16qi3, "__builtin_altivec_vminsb", ALTIVEC_BUILTIN_VMINSB },
8834 { MASK_ALTIVEC, CODE_FOR_uminv8hi3, "__builtin_altivec_vminuh", ALTIVEC_BUILTIN_VMINUH },
8835 { MASK_ALTIVEC, CODE_FOR_sminv8hi3, "__builtin_altivec_vminsh", ALTIVEC_BUILTIN_VMINSH },
8836 { MASK_ALTIVEC, CODE_FOR_uminv4si3, "__builtin_altivec_vminuw", ALTIVEC_BUILTIN_VMINUW },
8837 { MASK_ALTIVEC, CODE_FOR_sminv4si3, "__builtin_altivec_vminsw", ALTIVEC_BUILTIN_VMINSW },
8838 { MASK_ALTIVEC, CODE_FOR_sminv4sf3, "__builtin_altivec_vminfp", ALTIVEC_BUILTIN_VMINFP },
8839 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleub, "__builtin_altivec_vmuleub", ALTIVEC_BUILTIN_VMULEUB },
8840 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleub, "__builtin_altivec_vmuleub_uns", ALTIVEC_BUILTIN_VMULEUB_UNS },
8841 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesb, "__builtin_altivec_vmulesb", ALTIVEC_BUILTIN_VMULESB },
8842 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleuh, "__builtin_altivec_vmuleuh", ALTIVEC_BUILTIN_VMULEUH },
8843 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleuh, "__builtin_altivec_vmuleuh_uns", ALTIVEC_BUILTIN_VMULEUH_UNS },
8844 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesh, "__builtin_altivec_vmulesh", ALTIVEC_BUILTIN_VMULESH },
8845 { MASK_ALTIVEC, CODE_FOR_altivec_vmuloub, "__builtin_altivec_vmuloub", ALTIVEC_BUILTIN_VMULOUB },
8846 { MASK_ALTIVEC, CODE_FOR_altivec_vmuloub, "__builtin_altivec_vmuloub_uns", ALTIVEC_BUILTIN_VMULOUB_UNS },
8847 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosb, "__builtin_altivec_vmulosb", ALTIVEC_BUILTIN_VMULOSB },
8848 { MASK_ALTIVEC, CODE_FOR_altivec_vmulouh, "__builtin_altivec_vmulouh", ALTIVEC_BUILTIN_VMULOUH },
8849 { MASK_ALTIVEC, CODE_FOR_altivec_vmulouh, "__builtin_altivec_vmulouh_uns", ALTIVEC_BUILTIN_VMULOUH_UNS },
8850 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosh, "__builtin_altivec_vmulosh", ALTIVEC_BUILTIN_VMULOSH },
8851 { MASK_ALTIVEC, CODE_FOR_norv4si3, "__builtin_altivec_vnor", ALTIVEC_BUILTIN_VNOR },
8852 { MASK_ALTIVEC, CODE_FOR_iorv4si3, "__builtin_altivec_vor", ALTIVEC_BUILTIN_VOR },
8853 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhum, "__builtin_altivec_vpkuhum", ALTIVEC_BUILTIN_VPKUHUM },
8854 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwum, "__builtin_altivec_vpkuwum", ALTIVEC_BUILTIN_VPKUWUM },
8855 { MASK_ALTIVEC, CODE_FOR_altivec_vpkpx, "__builtin_altivec_vpkpx", ALTIVEC_BUILTIN_VPKPX },
8856 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshss, "__builtin_altivec_vpkshss", ALTIVEC_BUILTIN_VPKSHSS },
8857 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswss, "__builtin_altivec_vpkswss", ALTIVEC_BUILTIN_VPKSWSS },
8858 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhus, "__builtin_altivec_vpkuhus", ALTIVEC_BUILTIN_VPKUHUS },
8859 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshus, "__builtin_altivec_vpkshus", ALTIVEC_BUILTIN_VPKSHUS },
8860 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwus, "__builtin_altivec_vpkuwus", ALTIVEC_BUILTIN_VPKUWUS },
8861 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswus, "__builtin_altivec_vpkswus", ALTIVEC_BUILTIN_VPKSWUS },
8862 { MASK_ALTIVEC, CODE_FOR_vrotlv16qi3, "__builtin_altivec_vrlb", ALTIVEC_BUILTIN_VRLB },
8863 { MASK_ALTIVEC, CODE_FOR_vrotlv8hi3, "__builtin_altivec_vrlh", ALTIVEC_BUILTIN_VRLH },
8864 { MASK_ALTIVEC, CODE_FOR_vrotlv4si3, "__builtin_altivec_vrlw", ALTIVEC_BUILTIN_VRLW },
8865 { MASK_ALTIVEC, CODE_FOR_vashlv16qi3, "__builtin_altivec_vslb", ALTIVEC_BUILTIN_VSLB },
8866 { MASK_ALTIVEC, CODE_FOR_vashlv8hi3, "__builtin_altivec_vslh", ALTIVEC_BUILTIN_VSLH },
8867 { MASK_ALTIVEC, CODE_FOR_vashlv4si3, "__builtin_altivec_vslw", ALTIVEC_BUILTIN_VSLW },
8868 { MASK_ALTIVEC, CODE_FOR_altivec_vsl, "__builtin_altivec_vsl", ALTIVEC_BUILTIN_VSL },
8869 { MASK_ALTIVEC, CODE_FOR_altivec_vslo, "__builtin_altivec_vslo", ALTIVEC_BUILTIN_VSLO },
8870 { MASK_ALTIVEC, CODE_FOR_altivec_vspltb, "__builtin_altivec_vspltb", ALTIVEC_BUILTIN_VSPLTB },
8871 { MASK_ALTIVEC, CODE_FOR_altivec_vsplth, "__builtin_altivec_vsplth", ALTIVEC_BUILTIN_VSPLTH },
8872 { MASK_ALTIVEC, CODE_FOR_altivec_vspltw, "__builtin_altivec_vspltw", ALTIVEC_BUILTIN_VSPLTW },
8873 { MASK_ALTIVEC, CODE_FOR_vlshrv16qi3, "__builtin_altivec_vsrb", ALTIVEC_BUILTIN_VSRB },
8874 { MASK_ALTIVEC, CODE_FOR_vlshrv8hi3, "__builtin_altivec_vsrh", ALTIVEC_BUILTIN_VSRH },
8875 { MASK_ALTIVEC, CODE_FOR_vlshrv4si3, "__builtin_altivec_vsrw", ALTIVEC_BUILTIN_VSRW },
8876 { MASK_ALTIVEC, CODE_FOR_vashrv16qi3, "__builtin_altivec_vsrab", ALTIVEC_BUILTIN_VSRAB },
8877 { MASK_ALTIVEC, CODE_FOR_vashrv8hi3, "__builtin_altivec_vsrah", ALTIVEC_BUILTIN_VSRAH },
8878 { MASK_ALTIVEC, CODE_FOR_vashrv4si3, "__builtin_altivec_vsraw", ALTIVEC_BUILTIN_VSRAW },
8879 { MASK_ALTIVEC, CODE_FOR_altivec_vsr, "__builtin_altivec_vsr", ALTIVEC_BUILTIN_VSR },
8880 { MASK_ALTIVEC, CODE_FOR_altivec_vsro, "__builtin_altivec_vsro", ALTIVEC_BUILTIN_VSRO },
8881 { MASK_ALTIVEC, CODE_FOR_subv16qi3, "__builtin_altivec_vsububm", ALTIVEC_BUILTIN_VSUBUBM },
8882 { MASK_ALTIVEC, CODE_FOR_subv8hi3, "__builtin_altivec_vsubuhm", ALTIVEC_BUILTIN_VSUBUHM },
8883 { MASK_ALTIVEC, CODE_FOR_subv4si3, "__builtin_altivec_vsubuwm", ALTIVEC_BUILTIN_VSUBUWM },
8884 { MASK_ALTIVEC, CODE_FOR_subv4sf3, "__builtin_altivec_vsubfp", ALTIVEC_BUILTIN_VSUBFP },
8885 { MASK_ALTIVEC, CODE_FOR_altivec_vsubcuw, "__builtin_altivec_vsubcuw", ALTIVEC_BUILTIN_VSUBCUW },
8886 { MASK_ALTIVEC, CODE_FOR_altivec_vsububs, "__builtin_altivec_vsububs", ALTIVEC_BUILTIN_VSUBUBS },
8887 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsbs, "__builtin_altivec_vsubsbs", ALTIVEC_BUILTIN_VSUBSBS },
8888 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuhs, "__builtin_altivec_vsubuhs", ALTIVEC_BUILTIN_VSUBUHS },
8889 { MASK_ALTIVEC, CODE_FOR_altivec_vsubshs, "__builtin_altivec_vsubshs", ALTIVEC_BUILTIN_VSUBSHS },
8890 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuws, "__builtin_altivec_vsubuws", ALTIVEC_BUILTIN_VSUBUWS },
8891 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsws, "__builtin_altivec_vsubsws", ALTIVEC_BUILTIN_VSUBSWS },
8892 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4ubs, "__builtin_altivec_vsum4ubs", ALTIVEC_BUILTIN_VSUM4UBS },
8893 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4sbs, "__builtin_altivec_vsum4sbs", ALTIVEC_BUILTIN_VSUM4SBS },
8894 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4shs, "__builtin_altivec_vsum4shs", ALTIVEC_BUILTIN_VSUM4SHS },
8895 { MASK_ALTIVEC, CODE_FOR_altivec_vsum2sws, "__builtin_altivec_vsum2sws", ALTIVEC_BUILTIN_VSUM2SWS },
8896 { MASK_ALTIVEC, CODE_FOR_altivec_vsumsws, "__builtin_altivec_vsumsws", ALTIVEC_BUILTIN_VSUMSWS },
8897 { MASK_ALTIVEC, CODE_FOR_xorv4si3, "__builtin_altivec_vxor", ALTIVEC_BUILTIN_VXOR },
8898 { MASK_ALTIVEC, CODE_FOR_vector_copysignv4sf3, "__builtin_altivec_copysignfp", ALTIVEC_BUILTIN_COPYSIGN_V4SF },
8900 { MASK_VSX, CODE_FOR_addv2df3, "__builtin_vsx_xvadddp", VSX_BUILTIN_XVADDDP },
8901 { MASK_VSX, CODE_FOR_subv2df3, "__builtin_vsx_xvsubdp", VSX_BUILTIN_XVSUBDP },
8902 { MASK_VSX, CODE_FOR_mulv2df3, "__builtin_vsx_xvmuldp", VSX_BUILTIN_XVMULDP },
8903 { MASK_VSX, CODE_FOR_divv2df3, "__builtin_vsx_xvdivdp", VSX_BUILTIN_XVDIVDP },
8904 { MASK_VSX, CODE_FOR_sminv2df3, "__builtin_vsx_xvmindp", VSX_BUILTIN_XVMINDP },
8905 { MASK_VSX, CODE_FOR_smaxv2df3, "__builtin_vsx_xvmaxdp", VSX_BUILTIN_XVMAXDP },
8906 { MASK_VSX, CODE_FOR_vsx_tdivv2df3_fe, "__builtin_vsx_xvtdivdp_fe", VSX_BUILTIN_XVTDIVDP_FE },
8907 { MASK_VSX, CODE_FOR_vsx_tdivv2df3_fg, "__builtin_vsx_xvtdivdp_fg", VSX_BUILTIN_XVTDIVDP_FG },
8908 { MASK_VSX, CODE_FOR_vector_eqv2df, "__builtin_vsx_xvcmpeqdp", VSX_BUILTIN_XVCMPEQDP },
8909 { MASK_VSX, CODE_FOR_vector_gtv2df, "__builtin_vsx_xvcmpgtdp", VSX_BUILTIN_XVCMPGTDP },
8910 { MASK_VSX, CODE_FOR_vector_gev2df, "__builtin_vsx_xvcmpgedp", VSX_BUILTIN_XVCMPGEDP },
8912 { MASK_VSX, CODE_FOR_addv4sf3, "__builtin_vsx_xvaddsp", VSX_BUILTIN_XVADDSP },
8913 { MASK_VSX, CODE_FOR_subv4sf3, "__builtin_vsx_xvsubsp", VSX_BUILTIN_XVSUBSP },
8914 { MASK_VSX, CODE_FOR_mulv4sf3, "__builtin_vsx_xvmulsp", VSX_BUILTIN_XVMULSP },
8915 { MASK_VSX, CODE_FOR_divv4sf3, "__builtin_vsx_xvdivsp", VSX_BUILTIN_XVDIVSP },
8916 { MASK_VSX, CODE_FOR_sminv4sf3, "__builtin_vsx_xvminsp", VSX_BUILTIN_XVMINSP },
8917 { MASK_VSX, CODE_FOR_smaxv4sf3, "__builtin_vsx_xvmaxsp", VSX_BUILTIN_XVMAXSP },
8918 { MASK_VSX, CODE_FOR_vsx_tdivv4sf3_fe, "__builtin_vsx_xvtdivsp_fe", VSX_BUILTIN_XVTDIVSP_FE },
8919 { MASK_VSX, CODE_FOR_vsx_tdivv4sf3_fg, "__builtin_vsx_xvtdivsp_fg", VSX_BUILTIN_XVTDIVSP_FG },
8920 { MASK_VSX, CODE_FOR_vector_eqv4sf, "__builtin_vsx_xvcmpeqsp", VSX_BUILTIN_XVCMPEQSP },
8921 { MASK_VSX, CODE_FOR_vector_gtv4sf, "__builtin_vsx_xvcmpgtsp", VSX_BUILTIN_XVCMPGTSP },
8922 { MASK_VSX, CODE_FOR_vector_gev4sf, "__builtin_vsx_xvcmpgesp", VSX_BUILTIN_XVCMPGESP },
8924 { MASK_VSX, CODE_FOR_smindf3, "__builtin_vsx_xsmindp", VSX_BUILTIN_XSMINDP },
8925 { MASK_VSX, CODE_FOR_smaxdf3, "__builtin_vsx_xsmaxdp", VSX_BUILTIN_XSMAXDP },
8926 { MASK_VSX, CODE_FOR_vsx_tdivdf3_fe, "__builtin_vsx_xstdivdp_fe", VSX_BUILTIN_XSTDIVDP_FE },
8927 { MASK_VSX, CODE_FOR_vsx_tdivdf3_fg, "__builtin_vsx_xstdivdp_fg", VSX_BUILTIN_XSTDIVDP_FG },
8928 { MASK_VSX, CODE_FOR_vector_copysignv2df3, "__builtin_vsx_cpsgndp", VSX_BUILTIN_CPSGNDP },
8929 { MASK_VSX, CODE_FOR_vector_copysignv4sf3, "__builtin_vsx_cpsgnsp", VSX_BUILTIN_CPSGNSP },
8931 { MASK_VSX, CODE_FOR_vsx_concat_v2df, "__builtin_vsx_concat_2df", VSX_BUILTIN_CONCAT_2DF },
8932 { MASK_VSX, CODE_FOR_vsx_concat_v2di, "__builtin_vsx_concat_2di", VSX_BUILTIN_CONCAT_2DI },
8933 { MASK_VSX, CODE_FOR_vsx_splat_v2df, "__builtin_vsx_splat_2df", VSX_BUILTIN_SPLAT_2DF },
8934 { MASK_VSX, CODE_FOR_vsx_splat_v2di, "__builtin_vsx_splat_2di", VSX_BUILTIN_SPLAT_2DI },
8935 { MASK_VSX, CODE_FOR_vsx_xxmrghw_v4sf, "__builtin_vsx_xxmrghw", VSX_BUILTIN_XXMRGHW_4SF },
8936 { MASK_VSX, CODE_FOR_vsx_xxmrghw_v4si, "__builtin_vsx_xxmrghw_4si", VSX_BUILTIN_XXMRGHW_4SI },
8937 { MASK_VSX, CODE_FOR_vsx_xxmrglw_v4sf, "__builtin_vsx_xxmrglw", VSX_BUILTIN_XXMRGLW_4SF },
8938 { MASK_VSX, CODE_FOR_vsx_xxmrglw_v4si, "__builtin_vsx_xxmrglw_4si", VSX_BUILTIN_XXMRGLW_4SI },
8939 { MASK_VSX, CODE_FOR_vec_interleave_lowv2df, "__builtin_vsx_mergel_2df", VSX_BUILTIN_VEC_MERGEL_V2DF },
8940 { MASK_VSX, CODE_FOR_vec_interleave_lowv2di, "__builtin_vsx_mergel_2di", VSX_BUILTIN_VEC_MERGEL_V2DI },
8941 { MASK_VSX, CODE_FOR_vec_interleave_highv2df, "__builtin_vsx_mergeh_2df", VSX_BUILTIN_VEC_MERGEH_V2DF },
8942 { MASK_VSX, CODE_FOR_vec_interleave_highv2di, "__builtin_vsx_mergeh_2di", VSX_BUILTIN_VEC_MERGEH_V2DI },
8944 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_add", ALTIVEC_BUILTIN_VEC_ADD },
8945 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vaddfp", ALTIVEC_BUILTIN_VEC_VADDFP },
8946 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduwm", ALTIVEC_BUILTIN_VEC_VADDUWM },
8947 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhm", ALTIVEC_BUILTIN_VEC_VADDUHM },
8948 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubm", ALTIVEC_BUILTIN_VEC_VADDUBM },
8949 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_addc", ALTIVEC_BUILTIN_VEC_ADDC },
8950 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_adds", ALTIVEC_BUILTIN_VEC_ADDS },
8951 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddsws", ALTIVEC_BUILTIN_VEC_VADDSWS },
8952 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduws", ALTIVEC_BUILTIN_VEC_VADDUWS },
8953 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddshs", ALTIVEC_BUILTIN_VEC_VADDSHS },
8954 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhs", ALTIVEC_BUILTIN_VEC_VADDUHS },
8955 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddsbs", ALTIVEC_BUILTIN_VEC_VADDSBS },
8956 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubs", ALTIVEC_BUILTIN_VEC_VADDUBS },
8957 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_and", ALTIVEC_BUILTIN_VEC_AND },
8958 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_andc", ALTIVEC_BUILTIN_VEC_ANDC },
8959 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_avg", ALTIVEC_BUILTIN_VEC_AVG },
8960 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsw", ALTIVEC_BUILTIN_VEC_VAVGSW },
8961 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavguw", ALTIVEC_BUILTIN_VEC_VAVGUW },
8962 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsh", ALTIVEC_BUILTIN_VEC_VAVGSH },
8963 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavguh", ALTIVEC_BUILTIN_VEC_VAVGUH },
8964 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsb", ALTIVEC_BUILTIN_VEC_VAVGSB },
8965 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgub", ALTIVEC_BUILTIN_VEC_VAVGUB },
8966 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpb", ALTIVEC_BUILTIN_VEC_CMPB },
8967 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpeq", ALTIVEC_BUILTIN_VEC_CMPEQ },
8968 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpeqfp", ALTIVEC_BUILTIN_VEC_VCMPEQFP },
8969 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequw", ALTIVEC_BUILTIN_VEC_VCMPEQUW },
8970 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequh", ALTIVEC_BUILTIN_VEC_VCMPEQUH },
8971 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequb", ALTIVEC_BUILTIN_VEC_VCMPEQUB },
8972 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpge", ALTIVEC_BUILTIN_VEC_CMPGE },
8973 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpgt", ALTIVEC_BUILTIN_VEC_CMPGT },
8974 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtfp", ALTIVEC_BUILTIN_VEC_VCMPGTFP },
8975 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsw", ALTIVEC_BUILTIN_VEC_VCMPGTSW },
8976 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtuw", ALTIVEC_BUILTIN_VEC_VCMPGTUW },
8977 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsh", ALTIVEC_BUILTIN_VEC_VCMPGTSH },
8978 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtuh", ALTIVEC_BUILTIN_VEC_VCMPGTUH },
8979 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsb", ALTIVEC_BUILTIN_VEC_VCMPGTSB },
8980 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtub", ALTIVEC_BUILTIN_VEC_VCMPGTUB },
8981 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmple", ALTIVEC_BUILTIN_VEC_CMPLE },
8982 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmplt", ALTIVEC_BUILTIN_VEC_CMPLT },
8983 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_copysign", ALTIVEC_BUILTIN_VEC_COPYSIGN },
8984 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_max", ALTIVEC_BUILTIN_VEC_MAX },
8985 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vmaxfp", ALTIVEC_BUILTIN_VEC_VMAXFP },
8986 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsw", ALTIVEC_BUILTIN_VEC_VMAXSW },
8987 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxuw", ALTIVEC_BUILTIN_VEC_VMAXUW },
8988 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsh", ALTIVEC_BUILTIN_VEC_VMAXSH },
8989 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxuh", ALTIVEC_BUILTIN_VEC_VMAXUH },
8990 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsb", ALTIVEC_BUILTIN_VEC_VMAXSB },
8991 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxub", ALTIVEC_BUILTIN_VEC_VMAXUB },
8992 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mergeh", ALTIVEC_BUILTIN_VEC_MERGEH },
8993 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghw", ALTIVEC_BUILTIN_VEC_VMRGHW },
8994 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghh", ALTIVEC_BUILTIN_VEC_VMRGHH },
8995 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghb", ALTIVEC_BUILTIN_VEC_VMRGHB },
8996 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mergel", ALTIVEC_BUILTIN_VEC_MERGEL },
8997 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglw", ALTIVEC_BUILTIN_VEC_VMRGLW },
8998 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglh", ALTIVEC_BUILTIN_VEC_VMRGLH },
8999 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglb", ALTIVEC_BUILTIN_VEC_VMRGLB },
9000 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_min", ALTIVEC_BUILTIN_VEC_MIN },
9001 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vminfp", ALTIVEC_BUILTIN_VEC_VMINFP },
9002 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsw", ALTIVEC_BUILTIN_VEC_VMINSW },
9003 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminuw", ALTIVEC_BUILTIN_VEC_VMINUW },
9004 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsh", ALTIVEC_BUILTIN_VEC_VMINSH },
9005 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminuh", ALTIVEC_BUILTIN_VEC_VMINUH },
9006 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsb", ALTIVEC_BUILTIN_VEC_VMINSB },
9007 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminub", ALTIVEC_BUILTIN_VEC_VMINUB },
9008 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mule", ALTIVEC_BUILTIN_VEC_MULE },
9009 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuleub", ALTIVEC_BUILTIN_VEC_VMULEUB },
9010 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulesb", ALTIVEC_BUILTIN_VEC_VMULESB },
9011 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuleuh", ALTIVEC_BUILTIN_VEC_VMULEUH },
9012 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulesh", ALTIVEC_BUILTIN_VEC_VMULESH },
9013 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mulo", ALTIVEC_BUILTIN_VEC_MULO },
9014 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulosh", ALTIVEC_BUILTIN_VEC_VMULOSH },
9015 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulouh", ALTIVEC_BUILTIN_VEC_VMULOUH },
9016 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulosb", ALTIVEC_BUILTIN_VEC_VMULOSB },
9017 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuloub", ALTIVEC_BUILTIN_VEC_VMULOUB },
9018 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_nor", ALTIVEC_BUILTIN_VEC_NOR },
9019 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_or", ALTIVEC_BUILTIN_VEC_OR },
9020 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_pack", ALTIVEC_BUILTIN_VEC_PACK },
9021 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuwum", ALTIVEC_BUILTIN_VEC_VPKUWUM },
9022 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuhum", ALTIVEC_BUILTIN_VEC_VPKUHUM },
9023 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packpx", ALTIVEC_BUILTIN_VEC_PACKPX },
9024 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packs", ALTIVEC_BUILTIN_VEC_PACKS },
9025 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkswss", ALTIVEC_BUILTIN_VEC_VPKSWSS },
9026 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuwus", ALTIVEC_BUILTIN_VEC_VPKUWUS },
9027 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkshss", ALTIVEC_BUILTIN_VEC_VPKSHSS },
9028 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuhus", ALTIVEC_BUILTIN_VEC_VPKUHUS },
9029 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packsu", ALTIVEC_BUILTIN_VEC_PACKSU },
9030 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkswus", ALTIVEC_BUILTIN_VEC_VPKSWUS },
9031 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkshus", ALTIVEC_BUILTIN_VEC_VPKSHUS },
9032 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rl", ALTIVEC_BUILTIN_VEC_RL },
9033 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlw", ALTIVEC_BUILTIN_VEC_VRLW },
9034 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlh", ALTIVEC_BUILTIN_VEC_VRLH },
9035 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlb", ALTIVEC_BUILTIN_VEC_VRLB },
9036 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sl", ALTIVEC_BUILTIN_VEC_SL },
9037 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslw", ALTIVEC_BUILTIN_VEC_VSLW },
9038 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslh", ALTIVEC_BUILTIN_VEC_VSLH },
9039 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslb", ALTIVEC_BUILTIN_VEC_VSLB },
9040 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sll", ALTIVEC_BUILTIN_VEC_SLL },
9041 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_slo", ALTIVEC_BUILTIN_VEC_SLO },
9042 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sr", ALTIVEC_BUILTIN_VEC_SR },
9043 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrw", ALTIVEC_BUILTIN_VEC_VSRW },
9044 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrh", ALTIVEC_BUILTIN_VEC_VSRH },
9045 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrb", ALTIVEC_BUILTIN_VEC_VSRB },
9046 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sra", ALTIVEC_BUILTIN_VEC_SRA },
9047 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsraw", ALTIVEC_BUILTIN_VEC_VSRAW },
9048 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrah", ALTIVEC_BUILTIN_VEC_VSRAH },
9049 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrab", ALTIVEC_BUILTIN_VEC_VSRAB },
9050 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_srl", ALTIVEC_BUILTIN_VEC_SRL },
9051 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sro", ALTIVEC_BUILTIN_VEC_SRO },
9052 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_sub", ALTIVEC_BUILTIN_VEC_SUB },
9053 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vsubfp", ALTIVEC_BUILTIN_VEC_VSUBFP },
9054 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuwm", ALTIVEC_BUILTIN_VEC_VSUBUWM },
9055 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuhm", ALTIVEC_BUILTIN_VEC_VSUBUHM },
9056 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsububm", ALTIVEC_BUILTIN_VEC_VSUBUBM },
9057 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_subc", ALTIVEC_BUILTIN_VEC_SUBC },
9058 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_subs", ALTIVEC_BUILTIN_VEC_SUBS },
9059 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubsws", ALTIVEC_BUILTIN_VEC_VSUBSWS },
9060 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuws", ALTIVEC_BUILTIN_VEC_VSUBUWS },
9061 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubshs", ALTIVEC_BUILTIN_VEC_VSUBSHS },
9062 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuhs", ALTIVEC_BUILTIN_VEC_VSUBUHS },
9063 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubsbs", ALTIVEC_BUILTIN_VEC_VSUBSBS },
9064 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsububs", ALTIVEC_BUILTIN_VEC_VSUBUBS },
9065 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sum4s", ALTIVEC_BUILTIN_VEC_SUM4S },
9066 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4shs", ALTIVEC_BUILTIN_VEC_VSUM4SHS },
9067 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4sbs", ALTIVEC_BUILTIN_VEC_VSUM4SBS },
9068 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4ubs", ALTIVEC_BUILTIN_VEC_VSUM4UBS },
9069 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sum2s", ALTIVEC_BUILTIN_VEC_SUM2S },
9070 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sums", ALTIVEC_BUILTIN_VEC_SUMS },
9071 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_xor", ALTIVEC_BUILTIN_VEC_XOR },
9073 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_mul", VSX_BUILTIN_VEC_MUL },
9074 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_div", VSX_BUILTIN_VEC_DIV },
9076 { 0, CODE_FOR_paired_divv2sf3, "__builtin_paired_divv2sf3", PAIRED_BUILTIN_DIVV2SF3 },
9077 { 0, CODE_FOR_paired_addv2sf3, "__builtin_paired_addv2sf3", PAIRED_BUILTIN_ADDV2SF3 },
9078 { 0, CODE_FOR_paired_subv2sf3, "__builtin_paired_subv2sf3", PAIRED_BUILTIN_SUBV2SF3 },
9079 { 0, CODE_FOR_paired_mulv2sf3, "__builtin_paired_mulv2sf3", PAIRED_BUILTIN_MULV2SF3 },
9080 { 0, CODE_FOR_paired_muls0, "__builtin_paired_muls0", PAIRED_BUILTIN_MULS0 },
9081 { 0, CODE_FOR_paired_muls1, "__builtin_paired_muls1", PAIRED_BUILTIN_MULS1 },
9082 { 0, CODE_FOR_paired_merge00, "__builtin_paired_merge00", PAIRED_BUILTIN_MERGE00 },
9083 { 0, CODE_FOR_paired_merge01, "__builtin_paired_merge01", PAIRED_BUILTIN_MERGE01 },
9084 { 0, CODE_FOR_paired_merge10, "__builtin_paired_merge10", PAIRED_BUILTIN_MERGE10 },
9085 { 0, CODE_FOR_paired_merge11, "__builtin_paired_merge11", PAIRED_BUILTIN_MERGE11 },
9087 /* Place holder, leave as first spe builtin. */
9088 { 0, CODE_FOR_addv2si3, "__builtin_spe_evaddw", SPE_BUILTIN_EVADDW },
9089 { 0, CODE_FOR_andv2si3, "__builtin_spe_evand", SPE_BUILTIN_EVAND },
9090 { 0, CODE_FOR_spe_evandc, "__builtin_spe_evandc", SPE_BUILTIN_EVANDC },
9091 { 0, CODE_FOR_divv2si3, "__builtin_spe_evdivws", SPE_BUILTIN_EVDIVWS },
9092 { 0, CODE_FOR_spe_evdivwu, "__builtin_spe_evdivwu", SPE_BUILTIN_EVDIVWU },
9093 { 0, CODE_FOR_spe_eveqv, "__builtin_spe_eveqv", SPE_BUILTIN_EVEQV },
9094 { 0, CODE_FOR_spe_evfsadd, "__builtin_spe_evfsadd", SPE_BUILTIN_EVFSADD },
9095 { 0, CODE_FOR_spe_evfsdiv, "__builtin_spe_evfsdiv", SPE_BUILTIN_EVFSDIV },
9096 { 0, CODE_FOR_spe_evfsmul, "__builtin_spe_evfsmul", SPE_BUILTIN_EVFSMUL },
9097 { 0, CODE_FOR_spe_evfssub, "__builtin_spe_evfssub", SPE_BUILTIN_EVFSSUB },
9098 { 0, CODE_FOR_spe_evmergehi, "__builtin_spe_evmergehi", SPE_BUILTIN_EVMERGEHI },
9099 { 0, CODE_FOR_spe_evmergehilo, "__builtin_spe_evmergehilo", SPE_BUILTIN_EVMERGEHILO },
9100 { 0, CODE_FOR_spe_evmergelo, "__builtin_spe_evmergelo", SPE_BUILTIN_EVMERGELO },
9101 { 0, CODE_FOR_spe_evmergelohi, "__builtin_spe_evmergelohi", SPE_BUILTIN_EVMERGELOHI },
9102 { 0, CODE_FOR_spe_evmhegsmfaa, "__builtin_spe_evmhegsmfaa", SPE_BUILTIN_EVMHEGSMFAA },
9103 { 0, CODE_FOR_spe_evmhegsmfan, "__builtin_spe_evmhegsmfan", SPE_BUILTIN_EVMHEGSMFAN },
9104 { 0, CODE_FOR_spe_evmhegsmiaa, "__builtin_spe_evmhegsmiaa", SPE_BUILTIN_EVMHEGSMIAA },
9105 { 0, CODE_FOR_spe_evmhegsmian, "__builtin_spe_evmhegsmian", SPE_BUILTIN_EVMHEGSMIAN },
9106 { 0, CODE_FOR_spe_evmhegumiaa, "__builtin_spe_evmhegumiaa", SPE_BUILTIN_EVMHEGUMIAA },
9107 { 0, CODE_FOR_spe_evmhegumian, "__builtin_spe_evmhegumian", SPE_BUILTIN_EVMHEGUMIAN },
9108 { 0, CODE_FOR_spe_evmhesmf, "__builtin_spe_evmhesmf", SPE_BUILTIN_EVMHESMF },
9109 { 0, CODE_FOR_spe_evmhesmfa, "__builtin_spe_evmhesmfa", SPE_BUILTIN_EVMHESMFA },
9110 { 0, CODE_FOR_spe_evmhesmfaaw, "__builtin_spe_evmhesmfaaw", SPE_BUILTIN_EVMHESMFAAW },
9111 { 0, CODE_FOR_spe_evmhesmfanw, "__builtin_spe_evmhesmfanw", SPE_BUILTIN_EVMHESMFANW },
9112 { 0, CODE_FOR_spe_evmhesmi, "__builtin_spe_evmhesmi", SPE_BUILTIN_EVMHESMI },
9113 { 0, CODE_FOR_spe_evmhesmia, "__builtin_spe_evmhesmia", SPE_BUILTIN_EVMHESMIA },
9114 { 0, CODE_FOR_spe_evmhesmiaaw, "__builtin_spe_evmhesmiaaw", SPE_BUILTIN_EVMHESMIAAW },
9115 { 0, CODE_FOR_spe_evmhesmianw, "__builtin_spe_evmhesmianw", SPE_BUILTIN_EVMHESMIANW },
9116 { 0, CODE_FOR_spe_evmhessf, "__builtin_spe_evmhessf", SPE_BUILTIN_EVMHESSF },
9117 { 0, CODE_FOR_spe_evmhessfa, "__builtin_spe_evmhessfa", SPE_BUILTIN_EVMHESSFA },
9118 { 0, CODE_FOR_spe_evmhessfaaw, "__builtin_spe_evmhessfaaw", SPE_BUILTIN_EVMHESSFAAW },
9119 { 0, CODE_FOR_spe_evmhessfanw, "__builtin_spe_evmhessfanw", SPE_BUILTIN_EVMHESSFANW },
9120 { 0, CODE_FOR_spe_evmhessiaaw, "__builtin_spe_evmhessiaaw", SPE_BUILTIN_EVMHESSIAAW },
9121 { 0, CODE_FOR_spe_evmhessianw, "__builtin_spe_evmhessianw", SPE_BUILTIN_EVMHESSIANW },
9122 { 0, CODE_FOR_spe_evmheumi, "__builtin_spe_evmheumi", SPE_BUILTIN_EVMHEUMI },
9123 { 0, CODE_FOR_spe_evmheumia, "__builtin_spe_evmheumia", SPE_BUILTIN_EVMHEUMIA },
9124 { 0, CODE_FOR_spe_evmheumiaaw, "__builtin_spe_evmheumiaaw", SPE_BUILTIN_EVMHEUMIAAW },
9125 { 0, CODE_FOR_spe_evmheumianw, "__builtin_spe_evmheumianw", SPE_BUILTIN_EVMHEUMIANW },
9126 { 0, CODE_FOR_spe_evmheusiaaw, "__builtin_spe_evmheusiaaw", SPE_BUILTIN_EVMHEUSIAAW },
9127 { 0, CODE_FOR_spe_evmheusianw, "__builtin_spe_evmheusianw", SPE_BUILTIN_EVMHEUSIANW },
9128 { 0, CODE_FOR_spe_evmhogsmfaa, "__builtin_spe_evmhogsmfaa", SPE_BUILTIN_EVMHOGSMFAA },
9129 { 0, CODE_FOR_spe_evmhogsmfan, "__builtin_spe_evmhogsmfan", SPE_BUILTIN_EVMHOGSMFAN },
9130 { 0, CODE_FOR_spe_evmhogsmiaa, "__builtin_spe_evmhogsmiaa", SPE_BUILTIN_EVMHOGSMIAA },
9131 { 0, CODE_FOR_spe_evmhogsmian, "__builtin_spe_evmhogsmian", SPE_BUILTIN_EVMHOGSMIAN },
9132 { 0, CODE_FOR_spe_evmhogumiaa, "__builtin_spe_evmhogumiaa", SPE_BUILTIN_EVMHOGUMIAA },
9133 { 0, CODE_FOR_spe_evmhogumian, "__builtin_spe_evmhogumian", SPE_BUILTIN_EVMHOGUMIAN },
9134 { 0, CODE_FOR_spe_evmhosmf, "__builtin_spe_evmhosmf", SPE_BUILTIN_EVMHOSMF },
9135 { 0, CODE_FOR_spe_evmhosmfa, "__builtin_spe_evmhosmfa", SPE_BUILTIN_EVMHOSMFA },
9136 { 0, CODE_FOR_spe_evmhosmfaaw, "__builtin_spe_evmhosmfaaw", SPE_BUILTIN_EVMHOSMFAAW },
9137 { 0, CODE_FOR_spe_evmhosmfanw, "__builtin_spe_evmhosmfanw", SPE_BUILTIN_EVMHOSMFANW },
9138 { 0, CODE_FOR_spe_evmhosmi, "__builtin_spe_evmhosmi", SPE_BUILTIN_EVMHOSMI },
9139 { 0, CODE_FOR_spe_evmhosmia, "__builtin_spe_evmhosmia", SPE_BUILTIN_EVMHOSMIA },
9140 { 0, CODE_FOR_spe_evmhosmiaaw, "__builtin_spe_evmhosmiaaw", SPE_BUILTIN_EVMHOSMIAAW },
9141 { 0, CODE_FOR_spe_evmhosmianw, "__builtin_spe_evmhosmianw", SPE_BUILTIN_EVMHOSMIANW },
9142 { 0, CODE_FOR_spe_evmhossf, "__builtin_spe_evmhossf", SPE_BUILTIN_EVMHOSSF },
9143 { 0, CODE_FOR_spe_evmhossfa, "__builtin_spe_evmhossfa", SPE_BUILTIN_EVMHOSSFA },
9144 { 0, CODE_FOR_spe_evmhossfaaw, "__builtin_spe_evmhossfaaw", SPE_BUILTIN_EVMHOSSFAAW },
9145 { 0, CODE_FOR_spe_evmhossfanw, "__builtin_spe_evmhossfanw", SPE_BUILTIN_EVMHOSSFANW },
9146 { 0, CODE_FOR_spe_evmhossiaaw, "__builtin_spe_evmhossiaaw", SPE_BUILTIN_EVMHOSSIAAW },
9147 { 0, CODE_FOR_spe_evmhossianw, "__builtin_spe_evmhossianw", SPE_BUILTIN_EVMHOSSIANW },
9148 { 0, CODE_FOR_spe_evmhoumi, "__builtin_spe_evmhoumi", SPE_BUILTIN_EVMHOUMI },
9149 { 0, CODE_FOR_spe_evmhoumia, "__builtin_spe_evmhoumia", SPE_BUILTIN_EVMHOUMIA },
9150 { 0, CODE_FOR_spe_evmhoumiaaw, "__builtin_spe_evmhoumiaaw", SPE_BUILTIN_EVMHOUMIAAW },
9151 { 0, CODE_FOR_spe_evmhoumianw, "__builtin_spe_evmhoumianw", SPE_BUILTIN_EVMHOUMIANW },
9152 { 0, CODE_FOR_spe_evmhousiaaw, "__builtin_spe_evmhousiaaw", SPE_BUILTIN_EVMHOUSIAAW },
9153 { 0, CODE_FOR_spe_evmhousianw, "__builtin_spe_evmhousianw", SPE_BUILTIN_EVMHOUSIANW },
9154 { 0, CODE_FOR_spe_evmwhsmf, "__builtin_spe_evmwhsmf", SPE_BUILTIN_EVMWHSMF },
9155 { 0, CODE_FOR_spe_evmwhsmfa, "__builtin_spe_evmwhsmfa", SPE_BUILTIN_EVMWHSMFA },
9156 { 0, CODE_FOR_spe_evmwhsmi, "__builtin_spe_evmwhsmi", SPE_BUILTIN_EVMWHSMI },
9157 { 0, CODE_FOR_spe_evmwhsmia, "__builtin_spe_evmwhsmia", SPE_BUILTIN_EVMWHSMIA },
9158 { 0, CODE_FOR_spe_evmwhssf, "__builtin_spe_evmwhssf", SPE_BUILTIN_EVMWHSSF },
9159 { 0, CODE_FOR_spe_evmwhssfa, "__builtin_spe_evmwhssfa", SPE_BUILTIN_EVMWHSSFA },
9160 { 0, CODE_FOR_spe_evmwhumi, "__builtin_spe_evmwhumi", SPE_BUILTIN_EVMWHUMI },
9161 { 0, CODE_FOR_spe_evmwhumia, "__builtin_spe_evmwhumia", SPE_BUILTIN_EVMWHUMIA },
9162 { 0, CODE_FOR_spe_evmwlsmiaaw, "__builtin_spe_evmwlsmiaaw", SPE_BUILTIN_EVMWLSMIAAW },
9163 { 0, CODE_FOR_spe_evmwlsmianw, "__builtin_spe_evmwlsmianw", SPE_BUILTIN_EVMWLSMIANW },
9164 { 0, CODE_FOR_spe_evmwlssiaaw, "__builtin_spe_evmwlssiaaw", SPE_BUILTIN_EVMWLSSIAAW },
9165 { 0, CODE_FOR_spe_evmwlssianw, "__builtin_spe_evmwlssianw", SPE_BUILTIN_EVMWLSSIANW },
9166 { 0, CODE_FOR_spe_evmwlumi, "__builtin_spe_evmwlumi", SPE_BUILTIN_EVMWLUMI },
9167 { 0, CODE_FOR_spe_evmwlumia, "__builtin_spe_evmwlumia", SPE_BUILTIN_EVMWLUMIA },
9168 { 0, CODE_FOR_spe_evmwlumiaaw, "__builtin_spe_evmwlumiaaw", SPE_BUILTIN_EVMWLUMIAAW },
9169 { 0, CODE_FOR_spe_evmwlumianw, "__builtin_spe_evmwlumianw", SPE_BUILTIN_EVMWLUMIANW },
9170 { 0, CODE_FOR_spe_evmwlusiaaw, "__builtin_spe_evmwlusiaaw", SPE_BUILTIN_EVMWLUSIAAW },
9171 { 0, CODE_FOR_spe_evmwlusianw, "__builtin_spe_evmwlusianw", SPE_BUILTIN_EVMWLUSIANW },
9172 { 0, CODE_FOR_spe_evmwsmf, "__builtin_spe_evmwsmf", SPE_BUILTIN_EVMWSMF },
9173 { 0, CODE_FOR_spe_evmwsmfa, "__builtin_spe_evmwsmfa", SPE_BUILTIN_EVMWSMFA },
9174 { 0, CODE_FOR_spe_evmwsmfaa, "__builtin_spe_evmwsmfaa", SPE_BUILTIN_EVMWSMFAA },
9175 { 0, CODE_FOR_spe_evmwsmfan, "__builtin_spe_evmwsmfan", SPE_BUILTIN_EVMWSMFAN },
9176 { 0, CODE_FOR_spe_evmwsmi, "__builtin_spe_evmwsmi", SPE_BUILTIN_EVMWSMI },
9177 { 0, CODE_FOR_spe_evmwsmia, "__builtin_spe_evmwsmia", SPE_BUILTIN_EVMWSMIA },
9178 { 0, CODE_FOR_spe_evmwsmiaa, "__builtin_spe_evmwsmiaa", SPE_BUILTIN_EVMWSMIAA },
9179 { 0, CODE_FOR_spe_evmwsmian, "__builtin_spe_evmwsmian", SPE_BUILTIN_EVMWSMIAN },
9180 { 0, CODE_FOR_spe_evmwssf, "__builtin_spe_evmwssf", SPE_BUILTIN_EVMWSSF },
9181 { 0, CODE_FOR_spe_evmwssfa, "__builtin_spe_evmwssfa", SPE_BUILTIN_EVMWSSFA },
9182 { 0, CODE_FOR_spe_evmwssfaa, "__builtin_spe_evmwssfaa", SPE_BUILTIN_EVMWSSFAA },
9183 { 0, CODE_FOR_spe_evmwssfan, "__builtin_spe_evmwssfan", SPE_BUILTIN_EVMWSSFAN },
9184 { 0, CODE_FOR_spe_evmwumi, "__builtin_spe_evmwumi", SPE_BUILTIN_EVMWUMI },
9185 { 0, CODE_FOR_spe_evmwumia, "__builtin_spe_evmwumia", SPE_BUILTIN_EVMWUMIA },
9186 { 0, CODE_FOR_spe_evmwumiaa, "__builtin_spe_evmwumiaa", SPE_BUILTIN_EVMWUMIAA },
9187 { 0, CODE_FOR_spe_evmwumian, "__builtin_spe_evmwumian", SPE_BUILTIN_EVMWUMIAN },
9188 { 0, CODE_FOR_spe_evnand, "__builtin_spe_evnand", SPE_BUILTIN_EVNAND },
9189 { 0, CODE_FOR_spe_evnor, "__builtin_spe_evnor", SPE_BUILTIN_EVNOR },
9190 { 0, CODE_FOR_spe_evor, "__builtin_spe_evor", SPE_BUILTIN_EVOR },
9191 { 0, CODE_FOR_spe_evorc, "__builtin_spe_evorc", SPE_BUILTIN_EVORC },
9192 { 0, CODE_FOR_spe_evrlw, "__builtin_spe_evrlw", SPE_BUILTIN_EVRLW },
9193 { 0, CODE_FOR_spe_evslw, "__builtin_spe_evslw", SPE_BUILTIN_EVSLW },
9194 { 0, CODE_FOR_spe_evsrws, "__builtin_spe_evsrws", SPE_BUILTIN_EVSRWS },
9195 { 0, CODE_FOR_spe_evsrwu, "__builtin_spe_evsrwu", SPE_BUILTIN_EVSRWU },
9196 { 0, CODE_FOR_subv2si3, "__builtin_spe_evsubfw", SPE_BUILTIN_EVSUBFW },
9198 /* SPE binary operations expecting a 5-bit unsigned literal. */
9199 { 0, CODE_FOR_spe_evaddiw, "__builtin_spe_evaddiw", SPE_BUILTIN_EVADDIW },
9201 { 0, CODE_FOR_spe_evrlwi, "__builtin_spe_evrlwi", SPE_BUILTIN_EVRLWI },
9202 { 0, CODE_FOR_spe_evslwi, "__builtin_spe_evslwi", SPE_BUILTIN_EVSLWI },
9203 { 0, CODE_FOR_spe_evsrwis, "__builtin_spe_evsrwis", SPE_BUILTIN_EVSRWIS },
9204 { 0, CODE_FOR_spe_evsrwiu, "__builtin_spe_evsrwiu", SPE_BUILTIN_EVSRWIU },
9205 { 0, CODE_FOR_spe_evsubifw, "__builtin_spe_evsubifw", SPE_BUILTIN_EVSUBIFW },
9206 { 0, CODE_FOR_spe_evmwhssfaa, "__builtin_spe_evmwhssfaa", SPE_BUILTIN_EVMWHSSFAA },
9207 { 0, CODE_FOR_spe_evmwhssmaa, "__builtin_spe_evmwhssmaa", SPE_BUILTIN_EVMWHSSMAA },
9208 { 0, CODE_FOR_spe_evmwhsmfaa, "__builtin_spe_evmwhsmfaa", SPE_BUILTIN_EVMWHSMFAA },
9209 { 0, CODE_FOR_spe_evmwhsmiaa, "__builtin_spe_evmwhsmiaa", SPE_BUILTIN_EVMWHSMIAA },
9210 { 0, CODE_FOR_spe_evmwhusiaa, "__builtin_spe_evmwhusiaa", SPE_BUILTIN_EVMWHUSIAA },
9211 { 0, CODE_FOR_spe_evmwhumiaa, "__builtin_spe_evmwhumiaa", SPE_BUILTIN_EVMWHUMIAA },
9212 { 0, CODE_FOR_spe_evmwhssfan, "__builtin_spe_evmwhssfan", SPE_BUILTIN_EVMWHSSFAN },
9213 { 0, CODE_FOR_spe_evmwhssian, "__builtin_spe_evmwhssian", SPE_BUILTIN_EVMWHSSIAN },
9214 { 0, CODE_FOR_spe_evmwhsmfan, "__builtin_spe_evmwhsmfan", SPE_BUILTIN_EVMWHSMFAN },
9215 { 0, CODE_FOR_spe_evmwhsmian, "__builtin_spe_evmwhsmian", SPE_BUILTIN_EVMWHSMIAN },
9216 { 0, CODE_FOR_spe_evmwhusian, "__builtin_spe_evmwhusian", SPE_BUILTIN_EVMWHUSIAN },
9217 { 0, CODE_FOR_spe_evmwhumian, "__builtin_spe_evmwhumian", SPE_BUILTIN_EVMWHUMIAN },
9218 { 0, CODE_FOR_spe_evmwhgssfaa, "__builtin_spe_evmwhgssfaa", SPE_BUILTIN_EVMWHGSSFAA },
9219 { 0, CODE_FOR_spe_evmwhgsmfaa, "__builtin_spe_evmwhgsmfaa", SPE_BUILTIN_EVMWHGSMFAA },
9220 { 0, CODE_FOR_spe_evmwhgsmiaa, "__builtin_spe_evmwhgsmiaa", SPE_BUILTIN_EVMWHGSMIAA },
9221 { 0, CODE_FOR_spe_evmwhgumiaa, "__builtin_spe_evmwhgumiaa", SPE_BUILTIN_EVMWHGUMIAA },
9222 { 0, CODE_FOR_spe_evmwhgssfan, "__builtin_spe_evmwhgssfan", SPE_BUILTIN_EVMWHGSSFAN },
9223 { 0, CODE_FOR_spe_evmwhgsmfan, "__builtin_spe_evmwhgsmfan", SPE_BUILTIN_EVMWHGSMFAN },
9224 { 0, CODE_FOR_spe_evmwhgsmian, "__builtin_spe_evmwhgsmian", SPE_BUILTIN_EVMWHGSMIAN },
9225 { 0, CODE_FOR_spe_evmwhgumian, "__builtin_spe_evmwhgumian", SPE_BUILTIN_EVMWHGUMIAN },
9226 { 0, CODE_FOR_spe_brinc, "__builtin_spe_brinc", SPE_BUILTIN_BRINC },
9228 /* Place-holder. Leave as last binary SPE builtin. */
9229 { 0, CODE_FOR_xorv2si3, "__builtin_spe_evxor", SPE_BUILTIN_EVXOR }
9232 /* AltiVec predicates. */
9234 struct builtin_description_predicates
9236 const unsigned int mask;
9237 const enum insn_code icode;
9238 const char *const name;
9239 const enum rs6000_builtins code;
9242 static const struct builtin_description_predicates bdesc_altivec_preds[] =
9244 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpbfp_p, "__builtin_altivec_vcmpbfp_p",
9245 ALTIVEC_BUILTIN_VCMPBFP_P },
9246 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_eq_v4sf_p,
9247 "__builtin_altivec_vcmpeqfp_p", ALTIVEC_BUILTIN_VCMPEQFP_P },
9248 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_ge_v4sf_p,
9249 "__builtin_altivec_vcmpgefp_p", ALTIVEC_BUILTIN_VCMPGEFP_P },
9250 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_gt_v4sf_p,
9251 "__builtin_altivec_vcmpgtfp_p", ALTIVEC_BUILTIN_VCMPGTFP_P },
9252 { MASK_ALTIVEC, CODE_FOR_vector_eq_v4si_p, "__builtin_altivec_vcmpequw_p",
9253 ALTIVEC_BUILTIN_VCMPEQUW_P },
9254 { MASK_ALTIVEC, CODE_FOR_vector_gt_v4si_p, "__builtin_altivec_vcmpgtsw_p",
9255 ALTIVEC_BUILTIN_VCMPGTSW_P },
9256 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v4si_p, "__builtin_altivec_vcmpgtuw_p",
9257 ALTIVEC_BUILTIN_VCMPGTUW_P },
9258 { MASK_ALTIVEC, CODE_FOR_vector_eq_v8hi_p, "__builtin_altivec_vcmpequh_p",
9259 ALTIVEC_BUILTIN_VCMPEQUH_P },
9260 { MASK_ALTIVEC, CODE_FOR_vector_gt_v8hi_p, "__builtin_altivec_vcmpgtsh_p",
9261 ALTIVEC_BUILTIN_VCMPGTSH_P },
9262 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v8hi_p, "__builtin_altivec_vcmpgtuh_p",
9263 ALTIVEC_BUILTIN_VCMPGTUH_P },
9264 { MASK_ALTIVEC, CODE_FOR_vector_eq_v16qi_p, "__builtin_altivec_vcmpequb_p",
9265 ALTIVEC_BUILTIN_VCMPEQUB_P },
9266 { MASK_ALTIVEC, CODE_FOR_vector_gt_v16qi_p, "__builtin_altivec_vcmpgtsb_p",
9267 ALTIVEC_BUILTIN_VCMPGTSB_P },
9268 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v16qi_p, "__builtin_altivec_vcmpgtub_p",
9269 ALTIVEC_BUILTIN_VCMPGTUB_P },
9271 { MASK_VSX, CODE_FOR_vector_eq_v4sf_p, "__builtin_vsx_xvcmpeqsp_p",
9272 VSX_BUILTIN_XVCMPEQSP_P },
9273 { MASK_VSX, CODE_FOR_vector_ge_v4sf_p, "__builtin_vsx_xvcmpgesp_p",
9274 VSX_BUILTIN_XVCMPGESP_P },
9275 { MASK_VSX, CODE_FOR_vector_gt_v4sf_p, "__builtin_vsx_xvcmpgtsp_p",
9276 VSX_BUILTIN_XVCMPGTSP_P },
9277 { MASK_VSX, CODE_FOR_vector_eq_v2df_p, "__builtin_vsx_xvcmpeqdp_p",
9278 VSX_BUILTIN_XVCMPEQDP_P },
9279 { MASK_VSX, CODE_FOR_vector_ge_v2df_p, "__builtin_vsx_xvcmpgedp_p",
9280 VSX_BUILTIN_XVCMPGEDP_P },
9281 { MASK_VSX, CODE_FOR_vector_gt_v2df_p, "__builtin_vsx_xvcmpgtdp_p",
9282 VSX_BUILTIN_XVCMPGTDP_P },
9284 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpeq_p",
9285 ALTIVEC_BUILTIN_VCMPEQ_P },
9286 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpgt_p",
9287 ALTIVEC_BUILTIN_VCMPGT_P },
9288 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpge_p",
9289 ALTIVEC_BUILTIN_VCMPGE_P }
9292 /* SPE predicates. */
9293 static struct builtin_description bdesc_spe_predicates[] =
9295 /* Place-holder. Leave as first. */
9296 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evcmpeq", SPE_BUILTIN_EVCMPEQ },
9297 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evcmpgts", SPE_BUILTIN_EVCMPGTS },
9298 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evcmpgtu", SPE_BUILTIN_EVCMPGTU },
9299 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evcmplts", SPE_BUILTIN_EVCMPLTS },
9300 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evcmpltu", SPE_BUILTIN_EVCMPLTU },
9301 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evfscmpeq", SPE_BUILTIN_EVFSCMPEQ },
9302 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evfscmpgt", SPE_BUILTIN_EVFSCMPGT },
9303 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evfscmplt", SPE_BUILTIN_EVFSCMPLT },
9304 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evfststeq", SPE_BUILTIN_EVFSTSTEQ },
9305 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evfststgt", SPE_BUILTIN_EVFSTSTGT },
9306 /* Place-holder. Leave as last. */
9307 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evfststlt", SPE_BUILTIN_EVFSTSTLT },
9310 /* SPE evsel predicates. */
9311 static struct builtin_description bdesc_spe_evsel[] =
9313 /* Place-holder. Leave as first. */
9314 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evsel_gts", SPE_BUILTIN_EVSEL_CMPGTS },
9315 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evsel_gtu", SPE_BUILTIN_EVSEL_CMPGTU },
9316 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evsel_lts", SPE_BUILTIN_EVSEL_CMPLTS },
9317 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evsel_ltu", SPE_BUILTIN_EVSEL_CMPLTU },
9318 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evsel_eq", SPE_BUILTIN_EVSEL_CMPEQ },
9319 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evsel_fsgt", SPE_BUILTIN_EVSEL_FSCMPGT },
9320 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evsel_fslt", SPE_BUILTIN_EVSEL_FSCMPLT },
9321 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evsel_fseq", SPE_BUILTIN_EVSEL_FSCMPEQ },
9322 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evsel_fststgt", SPE_BUILTIN_EVSEL_FSTSTGT },
9323 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evsel_fststlt", SPE_BUILTIN_EVSEL_FSTSTLT },
9324 /* Place-holder. Leave as last. */
9325 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evsel_fststeq", SPE_BUILTIN_EVSEL_FSTSTEQ },
9328 /* PAIRED predicates. */
9329 static const struct builtin_description bdesc_paired_preds[] =
9331 /* Place-holder. Leave as first. */
9332 { 0, CODE_FOR_paired_cmpu0, "__builtin_paired_cmpu0", PAIRED_BUILTIN_CMPU0 },
9333 /* Place-holder. Leave as last. */
9334 { 0, CODE_FOR_paired_cmpu1, "__builtin_paired_cmpu1", PAIRED_BUILTIN_CMPU1 },
9337 /* ABS* operations. */
9339 static const struct builtin_description bdesc_abs[] =
9341 { MASK_ALTIVEC, CODE_FOR_absv4si2, "__builtin_altivec_abs_v4si", ALTIVEC_BUILTIN_ABS_V4SI },
9342 { MASK_ALTIVEC, CODE_FOR_absv8hi2, "__builtin_altivec_abs_v8hi", ALTIVEC_BUILTIN_ABS_V8HI },
9343 { MASK_ALTIVEC, CODE_FOR_absv4sf2, "__builtin_altivec_abs_v4sf", ALTIVEC_BUILTIN_ABS_V4SF },
9344 { MASK_ALTIVEC, CODE_FOR_absv16qi2, "__builtin_altivec_abs_v16qi", ALTIVEC_BUILTIN_ABS_V16QI },
9345 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v4si, "__builtin_altivec_abss_v4si", ALTIVEC_BUILTIN_ABSS_V4SI },
9346 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v8hi, "__builtin_altivec_abss_v8hi", ALTIVEC_BUILTIN_ABSS_V8HI },
9347 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v16qi, "__builtin_altivec_abss_v16qi", ALTIVEC_BUILTIN_ABSS_V16QI },
9348 { MASK_VSX, CODE_FOR_absv2df2, "__builtin_vsx_xvabsdp", VSX_BUILTIN_XVABSDP },
9349 { MASK_VSX, CODE_FOR_vsx_nabsv2df2, "__builtin_vsx_xvnabsdp", VSX_BUILTIN_XVNABSDP },
9350 { MASK_VSX, CODE_FOR_absv4sf2, "__builtin_vsx_xvabssp", VSX_BUILTIN_XVABSSP },
9351 { MASK_VSX, CODE_FOR_vsx_nabsv4sf2, "__builtin_vsx_xvnabssp", VSX_BUILTIN_XVNABSSP },
9354 /* Simple unary operations: VECb = foo (unsigned literal) or VECb =
9355 foo (VECa). */
9357 static struct builtin_description bdesc_1arg[] =
9359 { MASK_ALTIVEC, CODE_FOR_altivec_vexptefp, "__builtin_altivec_vexptefp", ALTIVEC_BUILTIN_VEXPTEFP },
9360 { MASK_ALTIVEC, CODE_FOR_altivec_vlogefp, "__builtin_altivec_vlogefp", ALTIVEC_BUILTIN_VLOGEFP },
9361 { MASK_ALTIVEC, CODE_FOR_altivec_vrefp, "__builtin_altivec_vrefp", ALTIVEC_BUILTIN_VREFP },
9362 { MASK_ALTIVEC, CODE_FOR_vector_floorv4sf2, "__builtin_altivec_vrfim", ALTIVEC_BUILTIN_VRFIM },
9363 { MASK_ALTIVEC, CODE_FOR_altivec_vrfin, "__builtin_altivec_vrfin", ALTIVEC_BUILTIN_VRFIN },
9364 { MASK_ALTIVEC, CODE_FOR_vector_ceilv4sf2, "__builtin_altivec_vrfip", ALTIVEC_BUILTIN_VRFIP },
9365 { MASK_ALTIVEC, CODE_FOR_vector_btruncv4sf2, "__builtin_altivec_vrfiz", ALTIVEC_BUILTIN_VRFIZ },
9366 { MASK_ALTIVEC, CODE_FOR_altivec_vrsqrtefp, "__builtin_altivec_vrsqrtefp", ALTIVEC_BUILTIN_VRSQRTEFP },
9367 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisb, "__builtin_altivec_vspltisb", ALTIVEC_BUILTIN_VSPLTISB },
9368 { MASK_ALTIVEC, CODE_FOR_altivec_vspltish, "__builtin_altivec_vspltish", ALTIVEC_BUILTIN_VSPLTISH },
9369 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisw, "__builtin_altivec_vspltisw", ALTIVEC_BUILTIN_VSPLTISW },
9370 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsb, "__builtin_altivec_vupkhsb", ALTIVEC_BUILTIN_VUPKHSB },
9371 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhpx, "__builtin_altivec_vupkhpx", ALTIVEC_BUILTIN_VUPKHPX },
9372 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsh, "__builtin_altivec_vupkhsh", ALTIVEC_BUILTIN_VUPKHSH },
9373 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsb, "__builtin_altivec_vupklsb", ALTIVEC_BUILTIN_VUPKLSB },
9374 { MASK_ALTIVEC, CODE_FOR_altivec_vupklpx, "__builtin_altivec_vupklpx", ALTIVEC_BUILTIN_VUPKLPX },
9375 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsh, "__builtin_altivec_vupklsh", ALTIVEC_BUILTIN_VUPKLSH },
9377 { MASK_VSX, CODE_FOR_negv2df2, "__builtin_vsx_xvnegdp", VSX_BUILTIN_XVNEGDP },
9378 { MASK_VSX, CODE_FOR_sqrtv2df2, "__builtin_vsx_xvsqrtdp", VSX_BUILTIN_XVSQRTDP },
9379 { MASK_VSX, CODE_FOR_vsx_rsqrtev2df2, "__builtin_vsx_xvrsqrtedp", VSX_BUILTIN_XVRSQRTEDP },
9380 { MASK_VSX, CODE_FOR_vsx_tsqrtv2df2_fe, "__builtin_vsx_xvtsqrtdp_fe", VSX_BUILTIN_XVTSQRTDP_FE },
9381 { MASK_VSX, CODE_FOR_vsx_tsqrtv2df2_fg, "__builtin_vsx_xvtsqrtdp_fg", VSX_BUILTIN_XVTSQRTDP_FG },
9382 { MASK_VSX, CODE_FOR_vsx_frev2df2, "__builtin_vsx_xvredp", VSX_BUILTIN_XVREDP },
9384 { MASK_VSX, CODE_FOR_negv4sf2, "__builtin_vsx_xvnegsp", VSX_BUILTIN_XVNEGSP },
9385 { MASK_VSX, CODE_FOR_sqrtv4sf2, "__builtin_vsx_xvsqrtsp", VSX_BUILTIN_XVSQRTSP },
9386 { MASK_VSX, CODE_FOR_vsx_rsqrtev4sf2, "__builtin_vsx_xvrsqrtesp", VSX_BUILTIN_XVRSQRTESP },
9387 { MASK_VSX, CODE_FOR_vsx_tsqrtv4sf2_fe, "__builtin_vsx_xvtsqrtsp_fe", VSX_BUILTIN_XVTSQRTSP_FE },
9388 { MASK_VSX, CODE_FOR_vsx_tsqrtv4sf2_fg, "__builtin_vsx_xvtsqrtsp_fg", VSX_BUILTIN_XVTSQRTSP_FG },
9389 { MASK_VSX, CODE_FOR_vsx_frev4sf2, "__builtin_vsx_xvresp", VSX_BUILTIN_XVRESP },
9391 { MASK_VSX, CODE_FOR_vsx_xscvdpsp, "__builtin_vsx_xscvdpsp", VSX_BUILTIN_XSCVDPSP },
9392 { MASK_VSX, CODE_FOR_vsx_xscvdpsp, "__builtin_vsx_xscvspdp", VSX_BUILTIN_XSCVSPDP },
9393 { MASK_VSX, CODE_FOR_vsx_xvcvdpsp, "__builtin_vsx_xvcvdpsp", VSX_BUILTIN_XVCVDPSP },
9394 { MASK_VSX, CODE_FOR_vsx_xvcvspdp, "__builtin_vsx_xvcvspdp", VSX_BUILTIN_XVCVSPDP },
9395 { MASK_VSX, CODE_FOR_vsx_tsqrtdf2_fe, "__builtin_vsx_xstsqrtdp_fe", VSX_BUILTIN_XSTSQRTDP_FE },
9396 { MASK_VSX, CODE_FOR_vsx_tsqrtdf2_fg, "__builtin_vsx_xstsqrtdp_fg", VSX_BUILTIN_XSTSQRTDP_FG },
9398 { MASK_VSX, CODE_FOR_vsx_fix_truncv2dfv2di2, "__builtin_vsx_xvcvdpsxds", VSX_BUILTIN_XVCVDPSXDS },
9399 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv2dfv2di2, "__builtin_vsx_xvcvdpuxds", VSX_BUILTIN_XVCVDPUXDS },
9400 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv2dfv2di2, "__builtin_vsx_xvcvdpuxds_uns", VSX_BUILTIN_XVCVDPUXDS_UNS },
9401 { MASK_VSX, CODE_FOR_vsx_floatv2div2df2, "__builtin_vsx_xvcvsxddp", VSX_BUILTIN_XVCVSXDDP },
9402 { MASK_VSX, CODE_FOR_vsx_floatunsv2div2df2, "__builtin_vsx_xvcvuxddp", VSX_BUILTIN_XVCVUXDDP },
9403 { MASK_VSX, CODE_FOR_vsx_floatunsv2div2df2, "__builtin_vsx_xvcvuxddp_uns", VSX_BUILTIN_XVCVUXDDP_UNS },
9405 { MASK_VSX, CODE_FOR_vsx_fix_truncv4sfv4si2, "__builtin_vsx_xvcvspsxws", VSX_BUILTIN_XVCVSPSXWS },
9406 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv4sfv4si2, "__builtin_vsx_xvcvspuxws", VSX_BUILTIN_XVCVSPUXWS },
9407 { MASK_VSX, CODE_FOR_vsx_floatv4siv4sf2, "__builtin_vsx_xvcvsxwsp", VSX_BUILTIN_XVCVSXWSP },
9408 { MASK_VSX, CODE_FOR_vsx_floatunsv4siv4sf2, "__builtin_vsx_xvcvuxwsp", VSX_BUILTIN_XVCVUXWSP },
9410 { MASK_VSX, CODE_FOR_vsx_xvcvdpsxws, "__builtin_vsx_xvcvdpsxws", VSX_BUILTIN_XVCVDPSXWS },
9411 { MASK_VSX, CODE_FOR_vsx_xvcvdpuxws, "__builtin_vsx_xvcvdpuxws", VSX_BUILTIN_XVCVDPUXWS },
9412 { MASK_VSX, CODE_FOR_vsx_xvcvsxwdp, "__builtin_vsx_xvcvsxwdp", VSX_BUILTIN_XVCVSXWDP },
9413 { MASK_VSX, CODE_FOR_vsx_xvcvuxwdp, "__builtin_vsx_xvcvuxwdp", VSX_BUILTIN_XVCVUXWDP },
9414 { MASK_VSX, CODE_FOR_vsx_xvrdpi, "__builtin_vsx_xvrdpi", VSX_BUILTIN_XVRDPI },
9415 { MASK_VSX, CODE_FOR_vsx_xvrdpic, "__builtin_vsx_xvrdpic", VSX_BUILTIN_XVRDPIC },
9416 { MASK_VSX, CODE_FOR_vsx_floorv2df2, "__builtin_vsx_xvrdpim", VSX_BUILTIN_XVRDPIM },
9417 { MASK_VSX, CODE_FOR_vsx_ceilv2df2, "__builtin_vsx_xvrdpip", VSX_BUILTIN_XVRDPIP },
9418 { MASK_VSX, CODE_FOR_vsx_btruncv2df2, "__builtin_vsx_xvrdpiz", VSX_BUILTIN_XVRDPIZ },
9420 { MASK_VSX, CODE_FOR_vsx_xvcvspsxds, "__builtin_vsx_xvcvspsxds", VSX_BUILTIN_XVCVSPSXDS },
9421 { MASK_VSX, CODE_FOR_vsx_xvcvspuxds, "__builtin_vsx_xvcvspuxds", VSX_BUILTIN_XVCVSPUXDS },
9422 { MASK_VSX, CODE_FOR_vsx_xvcvsxdsp, "__builtin_vsx_xvcvsxdsp", VSX_BUILTIN_XVCVSXDSP },
9423 { MASK_VSX, CODE_FOR_vsx_xvcvuxdsp, "__builtin_vsx_xvcvuxdsp", VSX_BUILTIN_XVCVUXDSP },
9424 { MASK_VSX, CODE_FOR_vsx_xvrspi, "__builtin_vsx_xvrspi", VSX_BUILTIN_XVRSPI },
9425 { MASK_VSX, CODE_FOR_vsx_xvrspic, "__builtin_vsx_xvrspic", VSX_BUILTIN_XVRSPIC },
9426 { MASK_VSX, CODE_FOR_vsx_floorv4sf2, "__builtin_vsx_xvrspim", VSX_BUILTIN_XVRSPIM },
9427 { MASK_VSX, CODE_FOR_vsx_ceilv4sf2, "__builtin_vsx_xvrspip", VSX_BUILTIN_XVRSPIP },
9428 { MASK_VSX, CODE_FOR_vsx_btruncv4sf2, "__builtin_vsx_xvrspiz", VSX_BUILTIN_XVRSPIZ },
9430 { MASK_VSX, CODE_FOR_vsx_xsrdpi, "__builtin_vsx_xsrdpi", VSX_BUILTIN_XSRDPI },
9431 { MASK_VSX, CODE_FOR_vsx_xsrdpic, "__builtin_vsx_xsrdpic", VSX_BUILTIN_XSRDPIC },
9432 { MASK_VSX, CODE_FOR_vsx_floordf2, "__builtin_vsx_xsrdpim", VSX_BUILTIN_XSRDPIM },
9433 { MASK_VSX, CODE_FOR_vsx_ceildf2, "__builtin_vsx_xsrdpip", VSX_BUILTIN_XSRDPIP },
9434 { MASK_VSX, CODE_FOR_vsx_btruncdf2, "__builtin_vsx_xsrdpiz", VSX_BUILTIN_XSRDPIZ },
9436 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abs", ALTIVEC_BUILTIN_VEC_ABS },
9437 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abss", ALTIVEC_BUILTIN_VEC_ABSS },
9438 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_ceil", ALTIVEC_BUILTIN_VEC_CEIL },
9439 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_expte", ALTIVEC_BUILTIN_VEC_EXPTE },
9440 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_floor", ALTIVEC_BUILTIN_VEC_FLOOR },
9441 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_loge", ALTIVEC_BUILTIN_VEC_LOGE },
9442 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mtvscr", ALTIVEC_BUILTIN_VEC_MTVSCR },
9443 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_re", ALTIVEC_BUILTIN_VEC_RE },
9444 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_round", ALTIVEC_BUILTIN_VEC_ROUND },
9445 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rsqrte", ALTIVEC_BUILTIN_VEC_RSQRTE },
9446 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_trunc", ALTIVEC_BUILTIN_VEC_TRUNC },
9447 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_unpackh", ALTIVEC_BUILTIN_VEC_UNPACKH },
9448 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhsh", ALTIVEC_BUILTIN_VEC_VUPKHSH },
9449 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhpx", ALTIVEC_BUILTIN_VEC_VUPKHPX },
9450 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhsb", ALTIVEC_BUILTIN_VEC_VUPKHSB },
9451 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_unpackl", ALTIVEC_BUILTIN_VEC_UNPACKL },
9452 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklpx", ALTIVEC_BUILTIN_VEC_VUPKLPX },
9453 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsh", ALTIVEC_BUILTIN_VEC_VUPKLSH },
9454 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsb", ALTIVEC_BUILTIN_VEC_VUPKLSB },
9456 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_nearbyint", ALTIVEC_BUILTIN_VEC_NEARBYINT },
9457 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_rint", ALTIVEC_BUILTIN_VEC_RINT },
9458 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_sqrt", ALTIVEC_BUILTIN_VEC_SQRT },
9460 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_floatv4siv4sf2, "__builtin_vec_float_sisf", VECTOR_BUILTIN_FLOAT_V4SI_V4SF },
9461 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_unsigned_floatv4siv4sf2, "__builtin_vec_uns_float_sisf", VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF },
9462 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_fix_truncv4sfv4si2, "__builtin_vec_fix_sfsi", VECTOR_BUILTIN_FIX_V4SF_V4SI },
9463 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_fixuns_truncv4sfv4si2, "__builtin_vec_fixuns_sfsi", VECTOR_BUILTIN_FIXUNS_V4SF_V4SI },
9465 /* The SPE unary builtins must start with SPE_BUILTIN_EVABS and
9466 end with SPE_BUILTIN_EVSUBFUSIAAW. */
9467 { 0, CODE_FOR_absv2si2, "__builtin_spe_evabs", SPE_BUILTIN_EVABS },
9468 { 0, CODE_FOR_spe_evaddsmiaaw, "__builtin_spe_evaddsmiaaw", SPE_BUILTIN_EVADDSMIAAW },
9469 { 0, CODE_FOR_spe_evaddssiaaw, "__builtin_spe_evaddssiaaw", SPE_BUILTIN_EVADDSSIAAW },
9470 { 0, CODE_FOR_spe_evaddumiaaw, "__builtin_spe_evaddumiaaw", SPE_BUILTIN_EVADDUMIAAW },
9471 { 0, CODE_FOR_spe_evaddusiaaw, "__builtin_spe_evaddusiaaw", SPE_BUILTIN_EVADDUSIAAW },
9472 { 0, CODE_FOR_spe_evcntlsw, "__builtin_spe_evcntlsw", SPE_BUILTIN_EVCNTLSW },
9473 { 0, CODE_FOR_spe_evcntlzw, "__builtin_spe_evcntlzw", SPE_BUILTIN_EVCNTLZW },
9474 { 0, CODE_FOR_spe_evextsb, "__builtin_spe_evextsb", SPE_BUILTIN_EVEXTSB },
9475 { 0, CODE_FOR_spe_evextsh, "__builtin_spe_evextsh", SPE_BUILTIN_EVEXTSH },
9476 { 0, CODE_FOR_spe_evfsabs, "__builtin_spe_evfsabs", SPE_BUILTIN_EVFSABS },
9477 { 0, CODE_FOR_spe_evfscfsf, "__builtin_spe_evfscfsf", SPE_BUILTIN_EVFSCFSF },
9478 { 0, CODE_FOR_spe_evfscfsi, "__builtin_spe_evfscfsi", SPE_BUILTIN_EVFSCFSI },
9479 { 0, CODE_FOR_spe_evfscfuf, "__builtin_spe_evfscfuf", SPE_BUILTIN_EVFSCFUF },
9480 { 0, CODE_FOR_spe_evfscfui, "__builtin_spe_evfscfui", SPE_BUILTIN_EVFSCFUI },
9481 { 0, CODE_FOR_spe_evfsctsf, "__builtin_spe_evfsctsf", SPE_BUILTIN_EVFSCTSF },
9482 { 0, CODE_FOR_spe_evfsctsi, "__builtin_spe_evfsctsi", SPE_BUILTIN_EVFSCTSI },
9483 { 0, CODE_FOR_spe_evfsctsiz, "__builtin_spe_evfsctsiz", SPE_BUILTIN_EVFSCTSIZ },
9484 { 0, CODE_FOR_spe_evfsctuf, "__builtin_spe_evfsctuf", SPE_BUILTIN_EVFSCTUF },
9485 { 0, CODE_FOR_spe_evfsctui, "__builtin_spe_evfsctui", SPE_BUILTIN_EVFSCTUI },
9486 { 0, CODE_FOR_spe_evfsctuiz, "__builtin_spe_evfsctuiz", SPE_BUILTIN_EVFSCTUIZ },
9487 { 0, CODE_FOR_spe_evfsnabs, "__builtin_spe_evfsnabs", SPE_BUILTIN_EVFSNABS },
9488 { 0, CODE_FOR_spe_evfsneg, "__builtin_spe_evfsneg", SPE_BUILTIN_EVFSNEG },
9489 { 0, CODE_FOR_spe_evmra, "__builtin_spe_evmra", SPE_BUILTIN_EVMRA },
9490 { 0, CODE_FOR_negv2si2, "__builtin_spe_evneg", SPE_BUILTIN_EVNEG },
9491 { 0, CODE_FOR_spe_evrndw, "__builtin_spe_evrndw", SPE_BUILTIN_EVRNDW },
9492 { 0, CODE_FOR_spe_evsubfsmiaaw, "__builtin_spe_evsubfsmiaaw", SPE_BUILTIN_EVSUBFSMIAAW },
9493 { 0, CODE_FOR_spe_evsubfssiaaw, "__builtin_spe_evsubfssiaaw", SPE_BUILTIN_EVSUBFSSIAAW },
9494 { 0, CODE_FOR_spe_evsubfumiaaw, "__builtin_spe_evsubfumiaaw", SPE_BUILTIN_EVSUBFUMIAAW },
9496 /* Place-holder. Leave as last unary SPE builtin. */
9497 { 0, CODE_FOR_spe_evsubfusiaaw, "__builtin_spe_evsubfusiaaw", SPE_BUILTIN_EVSUBFUSIAAW },
9499 { 0, CODE_FOR_paired_absv2sf2, "__builtin_paired_absv2sf2", PAIRED_BUILTIN_ABSV2SF2 },
9500 { 0, CODE_FOR_nabsv2sf2, "__builtin_paired_nabsv2sf2", PAIRED_BUILTIN_NABSV2SF2 },
9501 { 0, CODE_FOR_paired_negv2sf2, "__builtin_paired_negv2sf2", PAIRED_BUILTIN_NEGV2SF2 },
9502 { 0, CODE_FOR_sqrtv2sf2, "__builtin_paired_sqrtv2sf2", PAIRED_BUILTIN_SQRTV2SF2 },
9503 { 0, CODE_FOR_resv2sf2, "__builtin_paired_resv2sf2", PAIRED_BUILTIN_RESV2SF2 }
9506 static rtx
9507 rs6000_expand_unop_builtin (enum insn_code icode, tree exp, rtx target)
9509 rtx pat;
9510 tree arg0 = CALL_EXPR_ARG (exp, 0);
9511 rtx op0 = expand_normal (arg0);
9512 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9513 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
9515 if (icode == CODE_FOR_nothing)
9516 /* Builtin not supported on this processor. */
9517 return 0;
9519 /* If we got invalid arguments bail out before generating bad rtl. */
9520 if (arg0 == error_mark_node)
9521 return const0_rtx;
9523 if (icode == CODE_FOR_altivec_vspltisb
9524 || icode == CODE_FOR_altivec_vspltish
9525 || icode == CODE_FOR_altivec_vspltisw
9526 || icode == CODE_FOR_spe_evsplatfi
9527 || icode == CODE_FOR_spe_evsplati)
9529 /* Only allow 5-bit *signed* literals. */
9530 if (GET_CODE (op0) != CONST_INT
9531 || INTVAL (op0) > 15
9532 || INTVAL (op0) < -16)
9534 error ("argument 1 must be a 5-bit signed literal");
9535 return const0_rtx;
9539 if (target == 0
9540 || GET_MODE (target) != tmode
9541 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
9542 target = gen_reg_rtx (tmode);
9544 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
9545 op0 = copy_to_mode_reg (mode0, op0);
9547 pat = GEN_FCN (icode) (target, op0);
9548 if (! pat)
9549 return 0;
9550 emit_insn (pat);
9552 return target;
9555 static rtx
9556 altivec_expand_abs_builtin (enum insn_code icode, tree exp, rtx target)
9558 rtx pat, scratch1, scratch2;
9559 tree arg0 = CALL_EXPR_ARG (exp, 0);
9560 rtx op0 = expand_normal (arg0);
9561 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9562 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
9564 /* If we have invalid arguments, bail out before generating bad rtl. */
9565 if (arg0 == error_mark_node)
9566 return const0_rtx;
9568 if (target == 0
9569 || GET_MODE (target) != tmode
9570 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
9571 target = gen_reg_rtx (tmode);
9573 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
9574 op0 = copy_to_mode_reg (mode0, op0);
9576 scratch1 = gen_reg_rtx (mode0);
9577 scratch2 = gen_reg_rtx (mode0);
9579 pat = GEN_FCN (icode) (target, op0, scratch1, scratch2);
9580 if (! pat)
9581 return 0;
9582 emit_insn (pat);
9584 return target;
9587 static rtx
9588 rs6000_expand_binop_builtin (enum insn_code icode, tree exp, rtx target)
9590 rtx pat;
9591 tree arg0 = CALL_EXPR_ARG (exp, 0);
9592 tree arg1 = CALL_EXPR_ARG (exp, 1);
9593 rtx op0 = expand_normal (arg0);
9594 rtx op1 = expand_normal (arg1);
9595 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9596 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
9597 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
9599 if (icode == CODE_FOR_nothing)
9600 /* Builtin not supported on this processor. */
9601 return 0;
9603 /* If we got invalid arguments bail out before generating bad rtl. */
9604 if (arg0 == error_mark_node || arg1 == error_mark_node)
9605 return const0_rtx;
9607 if (icode == CODE_FOR_altivec_vcfux
9608 || icode == CODE_FOR_altivec_vcfsx
9609 || icode == CODE_FOR_altivec_vctsxs
9610 || icode == CODE_FOR_altivec_vctuxs
9611 || icode == CODE_FOR_altivec_vspltb
9612 || icode == CODE_FOR_altivec_vsplth
9613 || icode == CODE_FOR_altivec_vspltw
9614 || icode == CODE_FOR_spe_evaddiw
9615 || icode == CODE_FOR_spe_evldd
9616 || icode == CODE_FOR_spe_evldh
9617 || icode == CODE_FOR_spe_evldw
9618 || icode == CODE_FOR_spe_evlhhesplat
9619 || icode == CODE_FOR_spe_evlhhossplat
9620 || icode == CODE_FOR_spe_evlhhousplat
9621 || icode == CODE_FOR_spe_evlwhe
9622 || icode == CODE_FOR_spe_evlwhos
9623 || icode == CODE_FOR_spe_evlwhou
9624 || icode == CODE_FOR_spe_evlwhsplat
9625 || icode == CODE_FOR_spe_evlwwsplat
9626 || icode == CODE_FOR_spe_evrlwi
9627 || icode == CODE_FOR_spe_evslwi
9628 || icode == CODE_FOR_spe_evsrwis
9629 || icode == CODE_FOR_spe_evsubifw
9630 || icode == CODE_FOR_spe_evsrwiu)
9632 /* Only allow 5-bit unsigned literals. */
9633 STRIP_NOPS (arg1);
9634 if (TREE_CODE (arg1) != INTEGER_CST
9635 || TREE_INT_CST_LOW (arg1) & ~0x1f)
9637 error ("argument 2 must be a 5-bit unsigned literal");
9638 return const0_rtx;
9642 if (target == 0
9643 || GET_MODE (target) != tmode
9644 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
9645 target = gen_reg_rtx (tmode);
9647 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
9648 op0 = copy_to_mode_reg (mode0, op0);
9649 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
9650 op1 = copy_to_mode_reg (mode1, op1);
9652 pat = GEN_FCN (icode) (target, op0, op1);
9653 if (! pat)
9654 return 0;
9655 emit_insn (pat);
9657 return target;
9660 static rtx
9661 altivec_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
9663 rtx pat, scratch;
9664 tree cr6_form = CALL_EXPR_ARG (exp, 0);
9665 tree arg0 = CALL_EXPR_ARG (exp, 1);
9666 tree arg1 = CALL_EXPR_ARG (exp, 2);
9667 rtx op0 = expand_normal (arg0);
9668 rtx op1 = expand_normal (arg1);
9669 enum machine_mode tmode = SImode;
9670 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
9671 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
9672 int cr6_form_int;
9674 if (TREE_CODE (cr6_form) != INTEGER_CST)
9676 error ("argument 1 of __builtin_altivec_predicate must be a constant");
9677 return const0_rtx;
9679 else
9680 cr6_form_int = TREE_INT_CST_LOW (cr6_form);
9682 gcc_assert (mode0 == mode1);
9684 /* If we have invalid arguments, bail out before generating bad rtl. */
9685 if (arg0 == error_mark_node || arg1 == error_mark_node)
9686 return const0_rtx;
9688 if (target == 0
9689 || GET_MODE (target) != tmode
9690 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
9691 target = gen_reg_rtx (tmode);
9693 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
9694 op0 = copy_to_mode_reg (mode0, op0);
9695 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
9696 op1 = copy_to_mode_reg (mode1, op1);
9698 scratch = gen_reg_rtx (mode0);
9700 pat = GEN_FCN (icode) (scratch, op0, op1);
9701 if (! pat)
9702 return 0;
9703 emit_insn (pat);
9705 /* The vec_any* and vec_all* predicates use the same opcodes for two
9706 different operations, but the bits in CR6 will be different
9707 depending on what information we want. So we have to play tricks
9708 with CR6 to get the right bits out.
9710 If you think this is disgusting, look at the specs for the
9711 AltiVec predicates. */
9713 switch (cr6_form_int)
9715 case 0:
9716 emit_insn (gen_cr6_test_for_zero (target));
9717 break;
9718 case 1:
9719 emit_insn (gen_cr6_test_for_zero_reverse (target));
9720 break;
9721 case 2:
9722 emit_insn (gen_cr6_test_for_lt (target));
9723 break;
9724 case 3:
9725 emit_insn (gen_cr6_test_for_lt_reverse (target));
9726 break;
9727 default:
9728 error ("argument 1 of __builtin_altivec_predicate is out of range");
9729 break;
9732 return target;
9735 static rtx
9736 paired_expand_lv_builtin (enum insn_code icode, tree exp, rtx target)
9738 rtx pat, addr;
9739 tree arg0 = CALL_EXPR_ARG (exp, 0);
9740 tree arg1 = CALL_EXPR_ARG (exp, 1);
9741 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9742 enum machine_mode mode0 = Pmode;
9743 enum machine_mode mode1 = Pmode;
9744 rtx op0 = expand_normal (arg0);
9745 rtx op1 = expand_normal (arg1);
9747 if (icode == CODE_FOR_nothing)
9748 /* Builtin not supported on this processor. */
9749 return 0;
9751 /* If we got invalid arguments bail out before generating bad rtl. */
9752 if (arg0 == error_mark_node || arg1 == error_mark_node)
9753 return const0_rtx;
9755 if (target == 0
9756 || GET_MODE (target) != tmode
9757 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
9758 target = gen_reg_rtx (tmode);
9760 op1 = copy_to_mode_reg (mode1, op1);
9762 if (op0 == const0_rtx)
9764 addr = gen_rtx_MEM (tmode, op1);
9766 else
9768 op0 = copy_to_mode_reg (mode0, op0);
9769 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op0, op1));
9772 pat = GEN_FCN (icode) (target, addr);
9774 if (! pat)
9775 return 0;
9776 emit_insn (pat);
9778 return target;
9781 static rtx
9782 altivec_expand_lv_builtin (enum insn_code icode, tree exp, rtx target, bool blk)
9784 rtx pat, addr;
9785 tree arg0 = CALL_EXPR_ARG (exp, 0);
9786 tree arg1 = CALL_EXPR_ARG (exp, 1);
9787 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9788 enum machine_mode mode0 = Pmode;
9789 enum machine_mode mode1 = Pmode;
9790 rtx op0 = expand_normal (arg0);
9791 rtx op1 = expand_normal (arg1);
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 || arg1 == error_mark_node)
9799 return const0_rtx;
9801 if (target == 0
9802 || GET_MODE (target) != tmode
9803 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
9804 target = gen_reg_rtx (tmode);
9806 op1 = copy_to_mode_reg (mode1, op1);
9808 if (op0 == const0_rtx)
9810 addr = gen_rtx_MEM (blk ? BLKmode : tmode, op1);
9812 else
9814 op0 = copy_to_mode_reg (mode0, op0);
9815 addr = gen_rtx_MEM (blk ? BLKmode : tmode, gen_rtx_PLUS (Pmode, op0, op1));
9818 pat = GEN_FCN (icode) (target, addr);
9820 if (! pat)
9821 return 0;
9822 emit_insn (pat);
9824 return target;
9827 static rtx
9828 spe_expand_stv_builtin (enum insn_code icode, tree exp)
9830 tree arg0 = CALL_EXPR_ARG (exp, 0);
9831 tree arg1 = CALL_EXPR_ARG (exp, 1);
9832 tree arg2 = CALL_EXPR_ARG (exp, 2);
9833 rtx op0 = expand_normal (arg0);
9834 rtx op1 = expand_normal (arg1);
9835 rtx op2 = expand_normal (arg2);
9836 rtx pat;
9837 enum machine_mode mode0 = insn_data[icode].operand[0].mode;
9838 enum machine_mode mode1 = insn_data[icode].operand[1].mode;
9839 enum machine_mode mode2 = insn_data[icode].operand[2].mode;
9841 /* Invalid arguments. Bail before doing anything stoopid! */
9842 if (arg0 == error_mark_node
9843 || arg1 == error_mark_node
9844 || arg2 == error_mark_node)
9845 return const0_rtx;
9847 if (! (*insn_data[icode].operand[2].predicate) (op0, mode2))
9848 op0 = copy_to_mode_reg (mode2, op0);
9849 if (! (*insn_data[icode].operand[0].predicate) (op1, mode0))
9850 op1 = copy_to_mode_reg (mode0, op1);
9851 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
9852 op2 = copy_to_mode_reg (mode1, op2);
9854 pat = GEN_FCN (icode) (op1, op2, op0);
9855 if (pat)
9856 emit_insn (pat);
9857 return NULL_RTX;
9860 static rtx
9861 paired_expand_stv_builtin (enum insn_code icode, tree exp)
9863 tree arg0 = CALL_EXPR_ARG (exp, 0);
9864 tree arg1 = CALL_EXPR_ARG (exp, 1);
9865 tree arg2 = CALL_EXPR_ARG (exp, 2);
9866 rtx op0 = expand_normal (arg0);
9867 rtx op1 = expand_normal (arg1);
9868 rtx op2 = expand_normal (arg2);
9869 rtx pat, addr;
9870 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9871 enum machine_mode mode1 = Pmode;
9872 enum machine_mode mode2 = Pmode;
9874 /* Invalid arguments. Bail before doing anything stoopid! */
9875 if (arg0 == error_mark_node
9876 || arg1 == error_mark_node
9877 || arg2 == error_mark_node)
9878 return const0_rtx;
9880 if (! (*insn_data[icode].operand[1].predicate) (op0, tmode))
9881 op0 = copy_to_mode_reg (tmode, op0);
9883 op2 = copy_to_mode_reg (mode2, op2);
9885 if (op1 == const0_rtx)
9887 addr = gen_rtx_MEM (tmode, op2);
9889 else
9891 op1 = copy_to_mode_reg (mode1, op1);
9892 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op1, op2));
9895 pat = GEN_FCN (icode) (addr, op0);
9896 if (pat)
9897 emit_insn (pat);
9898 return NULL_RTX;
9901 static rtx
9902 altivec_expand_stv_builtin (enum insn_code icode, tree exp)
9904 tree arg0 = CALL_EXPR_ARG (exp, 0);
9905 tree arg1 = CALL_EXPR_ARG (exp, 1);
9906 tree arg2 = CALL_EXPR_ARG (exp, 2);
9907 rtx op0 = expand_normal (arg0);
9908 rtx op1 = expand_normal (arg1);
9909 rtx op2 = expand_normal (arg2);
9910 rtx pat, addr;
9911 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9912 enum machine_mode mode1 = Pmode;
9913 enum machine_mode mode2 = Pmode;
9915 /* Invalid arguments. Bail before doing anything stoopid! */
9916 if (arg0 == error_mark_node
9917 || arg1 == error_mark_node
9918 || arg2 == error_mark_node)
9919 return const0_rtx;
9921 if (! (*insn_data[icode].operand[1].predicate) (op0, tmode))
9922 op0 = copy_to_mode_reg (tmode, op0);
9924 op2 = copy_to_mode_reg (mode2, op2);
9926 if (op1 == const0_rtx)
9928 addr = gen_rtx_MEM (tmode, op2);
9930 else
9932 op1 = copy_to_mode_reg (mode1, op1);
9933 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op1, op2));
9936 pat = GEN_FCN (icode) (addr, op0);
9937 if (pat)
9938 emit_insn (pat);
9939 return NULL_RTX;
9942 static rtx
9943 rs6000_expand_ternop_builtin (enum insn_code icode, tree exp, rtx target)
9945 rtx pat;
9946 tree arg0 = CALL_EXPR_ARG (exp, 0);
9947 tree arg1 = CALL_EXPR_ARG (exp, 1);
9948 tree arg2 = CALL_EXPR_ARG (exp, 2);
9949 rtx op0 = expand_normal (arg0);
9950 rtx op1 = expand_normal (arg1);
9951 rtx op2 = expand_normal (arg2);
9952 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9953 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
9954 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
9955 enum machine_mode mode2 = insn_data[icode].operand[3].mode;
9957 if (icode == CODE_FOR_nothing)
9958 /* Builtin not supported on this processor. */
9959 return 0;
9961 /* If we got invalid arguments bail out before generating bad rtl. */
9962 if (arg0 == error_mark_node
9963 || arg1 == error_mark_node
9964 || arg2 == error_mark_node)
9965 return const0_rtx;
9967 switch (icode)
9969 case CODE_FOR_altivec_vsldoi_v4sf:
9970 case CODE_FOR_altivec_vsldoi_v4si:
9971 case CODE_FOR_altivec_vsldoi_v8hi:
9972 case CODE_FOR_altivec_vsldoi_v16qi:
9973 /* Only allow 4-bit unsigned literals. */
9974 STRIP_NOPS (arg2);
9975 if (TREE_CODE (arg2) != INTEGER_CST
9976 || TREE_INT_CST_LOW (arg2) & ~0xf)
9978 error ("argument 3 must be a 4-bit unsigned literal");
9979 return const0_rtx;
9981 break;
9983 case CODE_FOR_vsx_xxpermdi_v2df:
9984 case CODE_FOR_vsx_xxpermdi_v2di:
9985 case CODE_FOR_vsx_xxsldwi_v16qi:
9986 case CODE_FOR_vsx_xxsldwi_v8hi:
9987 case CODE_FOR_vsx_xxsldwi_v4si:
9988 case CODE_FOR_vsx_xxsldwi_v4sf:
9989 case CODE_FOR_vsx_xxsldwi_v2di:
9990 case CODE_FOR_vsx_xxsldwi_v2df:
9991 /* Only allow 2-bit unsigned literals. */
9992 STRIP_NOPS (arg2);
9993 if (TREE_CODE (arg2) != INTEGER_CST
9994 || TREE_INT_CST_LOW (arg2) & ~0x3)
9996 error ("argument 3 must be a 2-bit unsigned literal");
9997 return const0_rtx;
9999 break;
10001 case CODE_FOR_vsx_set_v2df:
10002 case CODE_FOR_vsx_set_v2di:
10003 /* Only allow 1-bit unsigned literals. */
10004 STRIP_NOPS (arg2);
10005 if (TREE_CODE (arg2) != INTEGER_CST
10006 || TREE_INT_CST_LOW (arg2) & ~0x1)
10008 error ("argument 3 must be a 1-bit unsigned literal");
10009 return const0_rtx;
10011 break;
10013 default:
10014 break;
10017 if (target == 0
10018 || GET_MODE (target) != tmode
10019 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10020 target = gen_reg_rtx (tmode);
10022 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10023 op0 = copy_to_mode_reg (mode0, op0);
10024 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
10025 op1 = copy_to_mode_reg (mode1, op1);
10026 if (! (*insn_data[icode].operand[3].predicate) (op2, mode2))
10027 op2 = copy_to_mode_reg (mode2, op2);
10029 if (TARGET_PAIRED_FLOAT && icode == CODE_FOR_selv2sf4)
10030 pat = GEN_FCN (icode) (target, op0, op1, op2, CONST0_RTX (SFmode));
10031 else
10032 pat = GEN_FCN (icode) (target, op0, op1, op2);
10033 if (! pat)
10034 return 0;
10035 emit_insn (pat);
10037 return target;
10040 /* Expand the lvx builtins. */
10041 static rtx
10042 altivec_expand_ld_builtin (tree exp, rtx target, bool *expandedp)
10044 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10045 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10046 tree arg0;
10047 enum machine_mode tmode, mode0;
10048 rtx pat, op0;
10049 enum insn_code icode;
10051 switch (fcode)
10053 case ALTIVEC_BUILTIN_LD_INTERNAL_16qi:
10054 icode = CODE_FOR_vector_load_v16qi;
10055 break;
10056 case ALTIVEC_BUILTIN_LD_INTERNAL_8hi:
10057 icode = CODE_FOR_vector_load_v8hi;
10058 break;
10059 case ALTIVEC_BUILTIN_LD_INTERNAL_4si:
10060 icode = CODE_FOR_vector_load_v4si;
10061 break;
10062 case ALTIVEC_BUILTIN_LD_INTERNAL_4sf:
10063 icode = CODE_FOR_vector_load_v4sf;
10064 break;
10065 default:
10066 *expandedp = false;
10067 return NULL_RTX;
10070 *expandedp = true;
10072 arg0 = CALL_EXPR_ARG (exp, 0);
10073 op0 = expand_normal (arg0);
10074 tmode = insn_data[icode].operand[0].mode;
10075 mode0 = insn_data[icode].operand[1].mode;
10077 if (target == 0
10078 || GET_MODE (target) != tmode
10079 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10080 target = gen_reg_rtx (tmode);
10082 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10083 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
10085 pat = GEN_FCN (icode) (target, op0);
10086 if (! pat)
10087 return 0;
10088 emit_insn (pat);
10089 return target;
10092 /* Expand the stvx builtins. */
10093 static rtx
10094 altivec_expand_st_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
10095 bool *expandedp)
10097 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10098 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10099 tree arg0, arg1;
10100 enum machine_mode mode0, mode1;
10101 rtx pat, op0, op1;
10102 enum insn_code icode;
10104 switch (fcode)
10106 case ALTIVEC_BUILTIN_ST_INTERNAL_16qi:
10107 icode = CODE_FOR_vector_store_v16qi;
10108 break;
10109 case ALTIVEC_BUILTIN_ST_INTERNAL_8hi:
10110 icode = CODE_FOR_vector_store_v8hi;
10111 break;
10112 case ALTIVEC_BUILTIN_ST_INTERNAL_4si:
10113 icode = CODE_FOR_vector_store_v4si;
10114 break;
10115 case ALTIVEC_BUILTIN_ST_INTERNAL_4sf:
10116 icode = CODE_FOR_vector_store_v4sf;
10117 break;
10118 default:
10119 *expandedp = false;
10120 return NULL_RTX;
10123 arg0 = CALL_EXPR_ARG (exp, 0);
10124 arg1 = CALL_EXPR_ARG (exp, 1);
10125 op0 = expand_normal (arg0);
10126 op1 = expand_normal (arg1);
10127 mode0 = insn_data[icode].operand[0].mode;
10128 mode1 = insn_data[icode].operand[1].mode;
10130 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
10131 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
10132 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
10133 op1 = copy_to_mode_reg (mode1, op1);
10135 pat = GEN_FCN (icode) (op0, op1);
10136 if (pat)
10137 emit_insn (pat);
10139 *expandedp = true;
10140 return NULL_RTX;
10143 /* Expand the dst builtins. */
10144 static rtx
10145 altivec_expand_dst_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
10146 bool *expandedp)
10148 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10149 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10150 tree arg0, arg1, arg2;
10151 enum machine_mode mode0, mode1, mode2;
10152 rtx pat, op0, op1, op2;
10153 const struct builtin_description *d;
10154 size_t i;
10156 *expandedp = false;
10158 /* Handle DST variants. */
10159 d = bdesc_dst;
10160 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
10161 if (d->code == fcode)
10163 arg0 = CALL_EXPR_ARG (exp, 0);
10164 arg1 = CALL_EXPR_ARG (exp, 1);
10165 arg2 = CALL_EXPR_ARG (exp, 2);
10166 op0 = expand_normal (arg0);
10167 op1 = expand_normal (arg1);
10168 op2 = expand_normal (arg2);
10169 mode0 = insn_data[d->icode].operand[0].mode;
10170 mode1 = insn_data[d->icode].operand[1].mode;
10171 mode2 = insn_data[d->icode].operand[2].mode;
10173 /* Invalid arguments, bail out before generating bad rtl. */
10174 if (arg0 == error_mark_node
10175 || arg1 == error_mark_node
10176 || arg2 == error_mark_node)
10177 return const0_rtx;
10179 *expandedp = true;
10180 STRIP_NOPS (arg2);
10181 if (TREE_CODE (arg2) != INTEGER_CST
10182 || TREE_INT_CST_LOW (arg2) & ~0x3)
10184 error ("argument to %qs must be a 2-bit unsigned literal", d->name);
10185 return const0_rtx;
10188 if (! (*insn_data[d->icode].operand[0].predicate) (op0, mode0))
10189 op0 = copy_to_mode_reg (Pmode, op0);
10190 if (! (*insn_data[d->icode].operand[1].predicate) (op1, mode1))
10191 op1 = copy_to_mode_reg (mode1, op1);
10193 pat = GEN_FCN (d->icode) (op0, op1, op2);
10194 if (pat != 0)
10195 emit_insn (pat);
10197 return NULL_RTX;
10200 return NULL_RTX;
10203 /* Expand vec_init builtin. */
10204 static rtx
10205 altivec_expand_vec_init_builtin (tree type, tree exp, rtx target)
10207 enum machine_mode tmode = TYPE_MODE (type);
10208 enum machine_mode inner_mode = GET_MODE_INNER (tmode);
10209 int i, n_elt = GET_MODE_NUNITS (tmode);
10210 rtvec v = rtvec_alloc (n_elt);
10212 gcc_assert (VECTOR_MODE_P (tmode));
10213 gcc_assert (n_elt == call_expr_nargs (exp));
10215 for (i = 0; i < n_elt; ++i)
10217 rtx x = expand_normal (CALL_EXPR_ARG (exp, i));
10218 RTVEC_ELT (v, i) = gen_lowpart (inner_mode, x);
10221 if (!target || !register_operand (target, tmode))
10222 target = gen_reg_rtx (tmode);
10224 rs6000_expand_vector_init (target, gen_rtx_PARALLEL (tmode, v));
10225 return target;
10228 /* Return the integer constant in ARG. Constrain it to be in the range
10229 of the subparts of VEC_TYPE; issue an error if not. */
10231 static int
10232 get_element_number (tree vec_type, tree arg)
10234 unsigned HOST_WIDE_INT elt, max = TYPE_VECTOR_SUBPARTS (vec_type) - 1;
10236 if (!host_integerp (arg, 1)
10237 || (elt = tree_low_cst (arg, 1), elt > max))
10239 error ("selector must be an integer constant in the range 0..%wi", max);
10240 return 0;
10243 return elt;
10246 /* Expand vec_set builtin. */
10247 static rtx
10248 altivec_expand_vec_set_builtin (tree exp)
10250 enum machine_mode tmode, mode1;
10251 tree arg0, arg1, arg2;
10252 int elt;
10253 rtx op0, op1;
10255 arg0 = CALL_EXPR_ARG (exp, 0);
10256 arg1 = CALL_EXPR_ARG (exp, 1);
10257 arg2 = CALL_EXPR_ARG (exp, 2);
10259 tmode = TYPE_MODE (TREE_TYPE (arg0));
10260 mode1 = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
10261 gcc_assert (VECTOR_MODE_P (tmode));
10263 op0 = expand_expr (arg0, NULL_RTX, tmode, EXPAND_NORMAL);
10264 op1 = expand_expr (arg1, NULL_RTX, mode1, EXPAND_NORMAL);
10265 elt = get_element_number (TREE_TYPE (arg0), arg2);
10267 if (GET_MODE (op1) != mode1 && GET_MODE (op1) != VOIDmode)
10268 op1 = convert_modes (mode1, GET_MODE (op1), op1, true);
10270 op0 = force_reg (tmode, op0);
10271 op1 = force_reg (mode1, op1);
10273 rs6000_expand_vector_set (op0, op1, elt);
10275 return op0;
10278 /* Expand vec_ext builtin. */
10279 static rtx
10280 altivec_expand_vec_ext_builtin (tree exp, rtx target)
10282 enum machine_mode tmode, mode0;
10283 tree arg0, arg1;
10284 int elt;
10285 rtx op0;
10287 arg0 = CALL_EXPR_ARG (exp, 0);
10288 arg1 = CALL_EXPR_ARG (exp, 1);
10290 op0 = expand_normal (arg0);
10291 elt = get_element_number (TREE_TYPE (arg0), arg1);
10293 tmode = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
10294 mode0 = TYPE_MODE (TREE_TYPE (arg0));
10295 gcc_assert (VECTOR_MODE_P (mode0));
10297 op0 = force_reg (mode0, op0);
10299 if (optimize || !target || !register_operand (target, tmode))
10300 target = gen_reg_rtx (tmode);
10302 rs6000_expand_vector_extract (target, op0, elt);
10304 return target;
10307 /* Expand the builtin in EXP and store the result in TARGET. Store
10308 true in *EXPANDEDP if we found a builtin to expand. */
10309 static rtx
10310 altivec_expand_builtin (tree exp, rtx target, bool *expandedp)
10312 const struct builtin_description *d;
10313 const struct builtin_description_predicates *dp;
10314 size_t i;
10315 enum insn_code icode;
10316 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10317 tree arg0;
10318 rtx op0, pat;
10319 enum machine_mode tmode, mode0;
10320 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10322 if ((fcode >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
10323 && fcode <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
10324 || (fcode >= VSX_BUILTIN_OVERLOADED_FIRST
10325 && fcode <= VSX_BUILTIN_OVERLOADED_LAST))
10327 *expandedp = true;
10328 error ("unresolved overload for Altivec builtin %qF", fndecl);
10329 return const0_rtx;
10332 target = altivec_expand_ld_builtin (exp, target, expandedp);
10333 if (*expandedp)
10334 return target;
10336 target = altivec_expand_st_builtin (exp, target, expandedp);
10337 if (*expandedp)
10338 return target;
10340 target = altivec_expand_dst_builtin (exp, target, expandedp);
10341 if (*expandedp)
10342 return target;
10344 *expandedp = true;
10346 switch (fcode)
10348 case ALTIVEC_BUILTIN_STVX:
10349 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx, exp);
10350 case ALTIVEC_BUILTIN_STVEBX:
10351 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvebx, exp);
10352 case ALTIVEC_BUILTIN_STVEHX:
10353 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvehx, exp);
10354 case ALTIVEC_BUILTIN_STVEWX:
10355 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvewx, exp);
10356 case ALTIVEC_BUILTIN_STVXL:
10357 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvxl, exp);
10359 case ALTIVEC_BUILTIN_STVLX:
10360 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlx, exp);
10361 case ALTIVEC_BUILTIN_STVLXL:
10362 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlxl, exp);
10363 case ALTIVEC_BUILTIN_STVRX:
10364 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrx, exp);
10365 case ALTIVEC_BUILTIN_STVRXL:
10366 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrxl, exp);
10368 case ALTIVEC_BUILTIN_MFVSCR:
10369 icode = CODE_FOR_altivec_mfvscr;
10370 tmode = insn_data[icode].operand[0].mode;
10372 if (target == 0
10373 || GET_MODE (target) != tmode
10374 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10375 target = gen_reg_rtx (tmode);
10377 pat = GEN_FCN (icode) (target);
10378 if (! pat)
10379 return 0;
10380 emit_insn (pat);
10381 return target;
10383 case ALTIVEC_BUILTIN_MTVSCR:
10384 icode = CODE_FOR_altivec_mtvscr;
10385 arg0 = CALL_EXPR_ARG (exp, 0);
10386 op0 = expand_normal (arg0);
10387 mode0 = insn_data[icode].operand[0].mode;
10389 /* If we got invalid arguments bail out before generating bad rtl. */
10390 if (arg0 == error_mark_node)
10391 return const0_rtx;
10393 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
10394 op0 = copy_to_mode_reg (mode0, op0);
10396 pat = GEN_FCN (icode) (op0);
10397 if (pat)
10398 emit_insn (pat);
10399 return NULL_RTX;
10401 case ALTIVEC_BUILTIN_DSSALL:
10402 emit_insn (gen_altivec_dssall ());
10403 return NULL_RTX;
10405 case ALTIVEC_BUILTIN_DSS:
10406 icode = CODE_FOR_altivec_dss;
10407 arg0 = CALL_EXPR_ARG (exp, 0);
10408 STRIP_NOPS (arg0);
10409 op0 = expand_normal (arg0);
10410 mode0 = insn_data[icode].operand[0].mode;
10412 /* If we got invalid arguments bail out before generating bad rtl. */
10413 if (arg0 == error_mark_node)
10414 return const0_rtx;
10416 if (TREE_CODE (arg0) != INTEGER_CST
10417 || TREE_INT_CST_LOW (arg0) & ~0x3)
10419 error ("argument to dss must be a 2-bit unsigned literal");
10420 return const0_rtx;
10423 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
10424 op0 = copy_to_mode_reg (mode0, op0);
10426 emit_insn (gen_altivec_dss (op0));
10427 return NULL_RTX;
10429 case ALTIVEC_BUILTIN_VEC_INIT_V4SI:
10430 case ALTIVEC_BUILTIN_VEC_INIT_V8HI:
10431 case ALTIVEC_BUILTIN_VEC_INIT_V16QI:
10432 case ALTIVEC_BUILTIN_VEC_INIT_V4SF:
10433 case VSX_BUILTIN_VEC_INIT_V2DF:
10434 case VSX_BUILTIN_VEC_INIT_V2DI:
10435 return altivec_expand_vec_init_builtin (TREE_TYPE (exp), exp, target);
10437 case ALTIVEC_BUILTIN_VEC_SET_V4SI:
10438 case ALTIVEC_BUILTIN_VEC_SET_V8HI:
10439 case ALTIVEC_BUILTIN_VEC_SET_V16QI:
10440 case ALTIVEC_BUILTIN_VEC_SET_V4SF:
10441 case VSX_BUILTIN_VEC_SET_V2DF:
10442 case VSX_BUILTIN_VEC_SET_V2DI:
10443 return altivec_expand_vec_set_builtin (exp);
10445 case ALTIVEC_BUILTIN_VEC_EXT_V4SI:
10446 case ALTIVEC_BUILTIN_VEC_EXT_V8HI:
10447 case ALTIVEC_BUILTIN_VEC_EXT_V16QI:
10448 case ALTIVEC_BUILTIN_VEC_EXT_V4SF:
10449 case VSX_BUILTIN_VEC_EXT_V2DF:
10450 case VSX_BUILTIN_VEC_EXT_V2DI:
10451 return altivec_expand_vec_ext_builtin (exp, target);
10453 default:
10454 break;
10455 /* Fall through. */
10458 /* Expand abs* operations. */
10459 d = bdesc_abs;
10460 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
10461 if (d->code == fcode)
10462 return altivec_expand_abs_builtin (d->icode, exp, target);
10464 /* Expand the AltiVec predicates. */
10465 dp = bdesc_altivec_preds;
10466 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
10467 if (dp->code == fcode)
10468 return altivec_expand_predicate_builtin (dp->icode, exp, target);
10470 /* LV* are funky. We initialized them differently. */
10471 switch (fcode)
10473 case ALTIVEC_BUILTIN_LVSL:
10474 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsl,
10475 exp, target, false);
10476 case ALTIVEC_BUILTIN_LVSR:
10477 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsr,
10478 exp, target, false);
10479 case ALTIVEC_BUILTIN_LVEBX:
10480 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvebx,
10481 exp, target, false);
10482 case ALTIVEC_BUILTIN_LVEHX:
10483 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvehx,
10484 exp, target, false);
10485 case ALTIVEC_BUILTIN_LVEWX:
10486 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvewx,
10487 exp, target, false);
10488 case ALTIVEC_BUILTIN_LVXL:
10489 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvxl,
10490 exp, target, false);
10491 case ALTIVEC_BUILTIN_LVX:
10492 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx,
10493 exp, target, false);
10494 case ALTIVEC_BUILTIN_LVLX:
10495 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlx,
10496 exp, target, true);
10497 case ALTIVEC_BUILTIN_LVLXL:
10498 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlxl,
10499 exp, target, true);
10500 case ALTIVEC_BUILTIN_LVRX:
10501 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrx,
10502 exp, target, true);
10503 case ALTIVEC_BUILTIN_LVRXL:
10504 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrxl,
10505 exp, target, true);
10506 default:
10507 break;
10508 /* Fall through. */
10511 *expandedp = false;
10512 return NULL_RTX;
10515 /* Expand the builtin in EXP and store the result in TARGET. Store
10516 true in *EXPANDEDP if we found a builtin to expand. */
10517 static rtx
10518 paired_expand_builtin (tree exp, rtx target, bool * expandedp)
10520 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10521 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10522 const struct builtin_description *d;
10523 size_t i;
10525 *expandedp = true;
10527 switch (fcode)
10529 case PAIRED_BUILTIN_STX:
10530 return paired_expand_stv_builtin (CODE_FOR_paired_stx, exp);
10531 case PAIRED_BUILTIN_LX:
10532 return paired_expand_lv_builtin (CODE_FOR_paired_lx, exp, target);
10533 default:
10534 break;
10535 /* Fall through. */
10538 /* Expand the paired predicates. */
10539 d = bdesc_paired_preds;
10540 for (i = 0; i < ARRAY_SIZE (bdesc_paired_preds); i++, d++)
10541 if (d->code == fcode)
10542 return paired_expand_predicate_builtin (d->icode, exp, target);
10544 *expandedp = false;
10545 return NULL_RTX;
10548 /* Binops that need to be initialized manually, but can be expanded
10549 automagically by rs6000_expand_binop_builtin. */
10550 static struct builtin_description bdesc_2arg_spe[] =
10552 { 0, CODE_FOR_spe_evlddx, "__builtin_spe_evlddx", SPE_BUILTIN_EVLDDX },
10553 { 0, CODE_FOR_spe_evldwx, "__builtin_spe_evldwx", SPE_BUILTIN_EVLDWX },
10554 { 0, CODE_FOR_spe_evldhx, "__builtin_spe_evldhx", SPE_BUILTIN_EVLDHX },
10555 { 0, CODE_FOR_spe_evlwhex, "__builtin_spe_evlwhex", SPE_BUILTIN_EVLWHEX },
10556 { 0, CODE_FOR_spe_evlwhoux, "__builtin_spe_evlwhoux", SPE_BUILTIN_EVLWHOUX },
10557 { 0, CODE_FOR_spe_evlwhosx, "__builtin_spe_evlwhosx", SPE_BUILTIN_EVLWHOSX },
10558 { 0, CODE_FOR_spe_evlwwsplatx, "__builtin_spe_evlwwsplatx", SPE_BUILTIN_EVLWWSPLATX },
10559 { 0, CODE_FOR_spe_evlwhsplatx, "__builtin_spe_evlwhsplatx", SPE_BUILTIN_EVLWHSPLATX },
10560 { 0, CODE_FOR_spe_evlhhesplatx, "__builtin_spe_evlhhesplatx", SPE_BUILTIN_EVLHHESPLATX },
10561 { 0, CODE_FOR_spe_evlhhousplatx, "__builtin_spe_evlhhousplatx", SPE_BUILTIN_EVLHHOUSPLATX },
10562 { 0, CODE_FOR_spe_evlhhossplatx, "__builtin_spe_evlhhossplatx", SPE_BUILTIN_EVLHHOSSPLATX },
10563 { 0, CODE_FOR_spe_evldd, "__builtin_spe_evldd", SPE_BUILTIN_EVLDD },
10564 { 0, CODE_FOR_spe_evldw, "__builtin_spe_evldw", SPE_BUILTIN_EVLDW },
10565 { 0, CODE_FOR_spe_evldh, "__builtin_spe_evldh", SPE_BUILTIN_EVLDH },
10566 { 0, CODE_FOR_spe_evlwhe, "__builtin_spe_evlwhe", SPE_BUILTIN_EVLWHE },
10567 { 0, CODE_FOR_spe_evlwhou, "__builtin_spe_evlwhou", SPE_BUILTIN_EVLWHOU },
10568 { 0, CODE_FOR_spe_evlwhos, "__builtin_spe_evlwhos", SPE_BUILTIN_EVLWHOS },
10569 { 0, CODE_FOR_spe_evlwwsplat, "__builtin_spe_evlwwsplat", SPE_BUILTIN_EVLWWSPLAT },
10570 { 0, CODE_FOR_spe_evlwhsplat, "__builtin_spe_evlwhsplat", SPE_BUILTIN_EVLWHSPLAT },
10571 { 0, CODE_FOR_spe_evlhhesplat, "__builtin_spe_evlhhesplat", SPE_BUILTIN_EVLHHESPLAT },
10572 { 0, CODE_FOR_spe_evlhhousplat, "__builtin_spe_evlhhousplat", SPE_BUILTIN_EVLHHOUSPLAT },
10573 { 0, CODE_FOR_spe_evlhhossplat, "__builtin_spe_evlhhossplat", SPE_BUILTIN_EVLHHOSSPLAT }
10576 /* Expand the builtin in EXP and store the result in TARGET. Store
10577 true in *EXPANDEDP if we found a builtin to expand.
10579 This expands the SPE builtins that are not simple unary and binary
10580 operations. */
10581 static rtx
10582 spe_expand_builtin (tree exp, rtx target, bool *expandedp)
10584 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10585 tree arg1, arg0;
10586 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10587 enum insn_code icode;
10588 enum machine_mode tmode, mode0;
10589 rtx pat, op0;
10590 struct builtin_description *d;
10591 size_t i;
10593 *expandedp = true;
10595 /* Syntax check for a 5-bit unsigned immediate. */
10596 switch (fcode)
10598 case SPE_BUILTIN_EVSTDD:
10599 case SPE_BUILTIN_EVSTDH:
10600 case SPE_BUILTIN_EVSTDW:
10601 case SPE_BUILTIN_EVSTWHE:
10602 case SPE_BUILTIN_EVSTWHO:
10603 case SPE_BUILTIN_EVSTWWE:
10604 case SPE_BUILTIN_EVSTWWO:
10605 arg1 = CALL_EXPR_ARG (exp, 2);
10606 if (TREE_CODE (arg1) != INTEGER_CST
10607 || TREE_INT_CST_LOW (arg1) & ~0x1f)
10609 error ("argument 2 must be a 5-bit unsigned literal");
10610 return const0_rtx;
10612 break;
10613 default:
10614 break;
10617 /* The evsplat*i instructions are not quite generic. */
10618 switch (fcode)
10620 case SPE_BUILTIN_EVSPLATFI:
10621 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplatfi,
10622 exp, target);
10623 case SPE_BUILTIN_EVSPLATI:
10624 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplati,
10625 exp, target);
10626 default:
10627 break;
10630 d = (struct builtin_description *) bdesc_2arg_spe;
10631 for (i = 0; i < ARRAY_SIZE (bdesc_2arg_spe); ++i, ++d)
10632 if (d->code == fcode)
10633 return rs6000_expand_binop_builtin (d->icode, exp, target);
10635 d = (struct builtin_description *) bdesc_spe_predicates;
10636 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, ++d)
10637 if (d->code == fcode)
10638 return spe_expand_predicate_builtin (d->icode, exp, target);
10640 d = (struct builtin_description *) bdesc_spe_evsel;
10641 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, ++d)
10642 if (d->code == fcode)
10643 return spe_expand_evsel_builtin (d->icode, exp, target);
10645 switch (fcode)
10647 case SPE_BUILTIN_EVSTDDX:
10648 return spe_expand_stv_builtin (CODE_FOR_spe_evstddx, exp);
10649 case SPE_BUILTIN_EVSTDHX:
10650 return spe_expand_stv_builtin (CODE_FOR_spe_evstdhx, exp);
10651 case SPE_BUILTIN_EVSTDWX:
10652 return spe_expand_stv_builtin (CODE_FOR_spe_evstdwx, exp);
10653 case SPE_BUILTIN_EVSTWHEX:
10654 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhex, exp);
10655 case SPE_BUILTIN_EVSTWHOX:
10656 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhox, exp);
10657 case SPE_BUILTIN_EVSTWWEX:
10658 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwex, exp);
10659 case SPE_BUILTIN_EVSTWWOX:
10660 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwox, exp);
10661 case SPE_BUILTIN_EVSTDD:
10662 return spe_expand_stv_builtin (CODE_FOR_spe_evstdd, exp);
10663 case SPE_BUILTIN_EVSTDH:
10664 return spe_expand_stv_builtin (CODE_FOR_spe_evstdh, exp);
10665 case SPE_BUILTIN_EVSTDW:
10666 return spe_expand_stv_builtin (CODE_FOR_spe_evstdw, exp);
10667 case SPE_BUILTIN_EVSTWHE:
10668 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhe, exp);
10669 case SPE_BUILTIN_EVSTWHO:
10670 return spe_expand_stv_builtin (CODE_FOR_spe_evstwho, exp);
10671 case SPE_BUILTIN_EVSTWWE:
10672 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwe, exp);
10673 case SPE_BUILTIN_EVSTWWO:
10674 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwo, exp);
10675 case SPE_BUILTIN_MFSPEFSCR:
10676 icode = CODE_FOR_spe_mfspefscr;
10677 tmode = insn_data[icode].operand[0].mode;
10679 if (target == 0
10680 || GET_MODE (target) != tmode
10681 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10682 target = gen_reg_rtx (tmode);
10684 pat = GEN_FCN (icode) (target);
10685 if (! pat)
10686 return 0;
10687 emit_insn (pat);
10688 return target;
10689 case SPE_BUILTIN_MTSPEFSCR:
10690 icode = CODE_FOR_spe_mtspefscr;
10691 arg0 = CALL_EXPR_ARG (exp, 0);
10692 op0 = expand_normal (arg0);
10693 mode0 = insn_data[icode].operand[0].mode;
10695 if (arg0 == error_mark_node)
10696 return const0_rtx;
10698 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
10699 op0 = copy_to_mode_reg (mode0, op0);
10701 pat = GEN_FCN (icode) (op0);
10702 if (pat)
10703 emit_insn (pat);
10704 return NULL_RTX;
10705 default:
10706 break;
10709 *expandedp = false;
10710 return NULL_RTX;
10713 static rtx
10714 paired_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
10716 rtx pat, scratch, tmp;
10717 tree form = CALL_EXPR_ARG (exp, 0);
10718 tree arg0 = CALL_EXPR_ARG (exp, 1);
10719 tree arg1 = CALL_EXPR_ARG (exp, 2);
10720 rtx op0 = expand_normal (arg0);
10721 rtx op1 = expand_normal (arg1);
10722 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10723 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
10724 int form_int;
10725 enum rtx_code code;
10727 if (TREE_CODE (form) != INTEGER_CST)
10729 error ("argument 1 of __builtin_paired_predicate must be a constant");
10730 return const0_rtx;
10732 else
10733 form_int = TREE_INT_CST_LOW (form);
10735 gcc_assert (mode0 == mode1);
10737 if (arg0 == error_mark_node || arg1 == error_mark_node)
10738 return const0_rtx;
10740 if (target == 0
10741 || GET_MODE (target) != SImode
10742 || !(*insn_data[icode].operand[0].predicate) (target, SImode))
10743 target = gen_reg_rtx (SImode);
10744 if (!(*insn_data[icode].operand[1].predicate) (op0, mode0))
10745 op0 = copy_to_mode_reg (mode0, op0);
10746 if (!(*insn_data[icode].operand[2].predicate) (op1, mode1))
10747 op1 = copy_to_mode_reg (mode1, op1);
10749 scratch = gen_reg_rtx (CCFPmode);
10751 pat = GEN_FCN (icode) (scratch, op0, op1);
10752 if (!pat)
10753 return const0_rtx;
10755 emit_insn (pat);
10757 switch (form_int)
10759 /* LT bit. */
10760 case 0:
10761 code = LT;
10762 break;
10763 /* GT bit. */
10764 case 1:
10765 code = GT;
10766 break;
10767 /* EQ bit. */
10768 case 2:
10769 code = EQ;
10770 break;
10771 /* UN bit. */
10772 case 3:
10773 emit_insn (gen_move_from_CR_ov_bit (target, scratch));
10774 return target;
10775 default:
10776 error ("argument 1 of __builtin_paired_predicate is out of range");
10777 return const0_rtx;
10780 tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx);
10781 emit_move_insn (target, tmp);
10782 return target;
10785 static rtx
10786 spe_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
10788 rtx pat, scratch, tmp;
10789 tree form = CALL_EXPR_ARG (exp, 0);
10790 tree arg0 = CALL_EXPR_ARG (exp, 1);
10791 tree arg1 = CALL_EXPR_ARG (exp, 2);
10792 rtx op0 = expand_normal (arg0);
10793 rtx op1 = expand_normal (arg1);
10794 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10795 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
10796 int form_int;
10797 enum rtx_code code;
10799 if (TREE_CODE (form) != INTEGER_CST)
10801 error ("argument 1 of __builtin_spe_predicate must be a constant");
10802 return const0_rtx;
10804 else
10805 form_int = TREE_INT_CST_LOW (form);
10807 gcc_assert (mode0 == mode1);
10809 if (arg0 == error_mark_node || arg1 == error_mark_node)
10810 return const0_rtx;
10812 if (target == 0
10813 || GET_MODE (target) != SImode
10814 || ! (*insn_data[icode].operand[0].predicate) (target, SImode))
10815 target = gen_reg_rtx (SImode);
10817 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10818 op0 = copy_to_mode_reg (mode0, op0);
10819 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
10820 op1 = copy_to_mode_reg (mode1, op1);
10822 scratch = gen_reg_rtx (CCmode);
10824 pat = GEN_FCN (icode) (scratch, op0, op1);
10825 if (! pat)
10826 return const0_rtx;
10827 emit_insn (pat);
10829 /* There are 4 variants for each predicate: _any_, _all_, _upper_,
10830 _lower_. We use one compare, but look in different bits of the
10831 CR for each variant.
10833 There are 2 elements in each SPE simd type (upper/lower). The CR
10834 bits are set as follows:
10836 BIT0 | BIT 1 | BIT 2 | BIT 3
10837 U | L | (U | L) | (U & L)
10839 So, for an "all" relationship, BIT 3 would be set.
10840 For an "any" relationship, BIT 2 would be set. Etc.
10842 Following traditional nomenclature, these bits map to:
10844 BIT0 | BIT 1 | BIT 2 | BIT 3
10845 LT | GT | EQ | OV
10847 Later, we will generate rtl to look in the LT/EQ/EQ/OV bits.
10850 switch (form_int)
10852 /* All variant. OV bit. */
10853 case 0:
10854 /* We need to get to the OV bit, which is the ORDERED bit. We
10855 could generate (ordered:SI (reg:CC xx) (const_int 0)), but
10856 that's ugly and will make validate_condition_mode die.
10857 So let's just use another pattern. */
10858 emit_insn (gen_move_from_CR_ov_bit (target, scratch));
10859 return target;
10860 /* Any variant. EQ bit. */
10861 case 1:
10862 code = EQ;
10863 break;
10864 /* Upper variant. LT bit. */
10865 case 2:
10866 code = LT;
10867 break;
10868 /* Lower variant. GT bit. */
10869 case 3:
10870 code = GT;
10871 break;
10872 default:
10873 error ("argument 1 of __builtin_spe_predicate is out of range");
10874 return const0_rtx;
10877 tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx);
10878 emit_move_insn (target, tmp);
10880 return target;
10883 /* The evsel builtins look like this:
10885 e = __builtin_spe_evsel_OP (a, b, c, d);
10887 and work like this:
10889 e[upper] = a[upper] *OP* b[upper] ? c[upper] : d[upper];
10890 e[lower] = a[lower] *OP* b[lower] ? c[lower] : d[lower];
10893 static rtx
10894 spe_expand_evsel_builtin (enum insn_code icode, tree exp, rtx target)
10896 rtx pat, scratch;
10897 tree arg0 = CALL_EXPR_ARG (exp, 0);
10898 tree arg1 = CALL_EXPR_ARG (exp, 1);
10899 tree arg2 = CALL_EXPR_ARG (exp, 2);
10900 tree arg3 = CALL_EXPR_ARG (exp, 3);
10901 rtx op0 = expand_normal (arg0);
10902 rtx op1 = expand_normal (arg1);
10903 rtx op2 = expand_normal (arg2);
10904 rtx op3 = expand_normal (arg3);
10905 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10906 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
10908 gcc_assert (mode0 == mode1);
10910 if (arg0 == error_mark_node || arg1 == error_mark_node
10911 || arg2 == error_mark_node || arg3 == error_mark_node)
10912 return const0_rtx;
10914 if (target == 0
10915 || GET_MODE (target) != mode0
10916 || ! (*insn_data[icode].operand[0].predicate) (target, mode0))
10917 target = gen_reg_rtx (mode0);
10919 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10920 op0 = copy_to_mode_reg (mode0, op0);
10921 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
10922 op1 = copy_to_mode_reg (mode0, op1);
10923 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
10924 op2 = copy_to_mode_reg (mode0, op2);
10925 if (! (*insn_data[icode].operand[1].predicate) (op3, mode1))
10926 op3 = copy_to_mode_reg (mode0, op3);
10928 /* Generate the compare. */
10929 scratch = gen_reg_rtx (CCmode);
10930 pat = GEN_FCN (icode) (scratch, op0, op1);
10931 if (! pat)
10932 return const0_rtx;
10933 emit_insn (pat);
10935 if (mode0 == V2SImode)
10936 emit_insn (gen_spe_evsel (target, op2, op3, scratch));
10937 else
10938 emit_insn (gen_spe_evsel_fs (target, op2, op3, scratch));
10940 return target;
10943 /* Expand an expression EXP that calls a built-in function,
10944 with result going to TARGET if that's convenient
10945 (and in mode MODE if that's convenient).
10946 SUBTARGET may be used as the target for computing one of EXP's operands.
10947 IGNORE is nonzero if the value is to be ignored. */
10949 static rtx
10950 rs6000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
10951 enum machine_mode mode ATTRIBUTE_UNUSED,
10952 int ignore ATTRIBUTE_UNUSED)
10954 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10955 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10956 const struct builtin_description *d;
10957 size_t i;
10958 rtx ret;
10959 bool success;
10961 if (fcode == RS6000_BUILTIN_RECIP)
10962 return rs6000_expand_binop_builtin (CODE_FOR_recipdf3, exp, target);
10964 if (fcode == RS6000_BUILTIN_RECIPF)
10965 return rs6000_expand_binop_builtin (CODE_FOR_recipsf3, exp, target);
10967 if (fcode == RS6000_BUILTIN_RSQRTF)
10968 return rs6000_expand_unop_builtin (CODE_FOR_rsqrtsf2, exp, target);
10970 if (fcode == RS6000_BUILTIN_BSWAP_HI)
10971 return rs6000_expand_unop_builtin (CODE_FOR_bswaphi2, exp, target);
10973 if (fcode == POWER7_BUILTIN_BPERMD)
10974 return rs6000_expand_binop_builtin (((TARGET_64BIT)
10975 ? CODE_FOR_bpermd_di
10976 : CODE_FOR_bpermd_si), exp, target);
10978 if (fcode == ALTIVEC_BUILTIN_MASK_FOR_LOAD
10979 || fcode == ALTIVEC_BUILTIN_MASK_FOR_STORE)
10981 int icode = (int) CODE_FOR_altivec_lvsr;
10982 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10983 enum machine_mode mode = insn_data[icode].operand[1].mode;
10984 tree arg;
10985 rtx op, addr, pat;
10987 gcc_assert (TARGET_ALTIVEC);
10989 arg = CALL_EXPR_ARG (exp, 0);
10990 gcc_assert (TREE_CODE (TREE_TYPE (arg)) == POINTER_TYPE);
10991 op = expand_expr (arg, NULL_RTX, Pmode, EXPAND_NORMAL);
10992 addr = memory_address (mode, op);
10993 if (fcode == ALTIVEC_BUILTIN_MASK_FOR_STORE)
10994 op = addr;
10995 else
10997 /* For the load case need to negate the address. */
10998 op = gen_reg_rtx (GET_MODE (addr));
10999 emit_insn (gen_rtx_SET (VOIDmode, op,
11000 gen_rtx_NEG (GET_MODE (addr), addr)));
11002 op = gen_rtx_MEM (mode, op);
11004 if (target == 0
11005 || GET_MODE (target) != tmode
11006 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11007 target = gen_reg_rtx (tmode);
11009 /*pat = gen_altivec_lvsr (target, op);*/
11010 pat = GEN_FCN (icode) (target, op);
11011 if (!pat)
11012 return 0;
11013 emit_insn (pat);
11015 return target;
11018 /* FIXME: There's got to be a nicer way to handle this case than
11019 constructing a new CALL_EXPR. */
11020 if (fcode == ALTIVEC_BUILTIN_VCFUX
11021 || fcode == ALTIVEC_BUILTIN_VCFSX
11022 || fcode == ALTIVEC_BUILTIN_VCTUXS
11023 || fcode == ALTIVEC_BUILTIN_VCTSXS)
11025 if (call_expr_nargs (exp) == 1)
11026 exp = build_call_nary (TREE_TYPE (exp), CALL_EXPR_FN (exp),
11027 2, CALL_EXPR_ARG (exp, 0), integer_zero_node);
11030 if (TARGET_ALTIVEC)
11032 ret = altivec_expand_builtin (exp, target, &success);
11034 if (success)
11035 return ret;
11037 if (TARGET_SPE)
11039 ret = spe_expand_builtin (exp, target, &success);
11041 if (success)
11042 return ret;
11044 if (TARGET_PAIRED_FLOAT)
11046 ret = paired_expand_builtin (exp, target, &success);
11048 if (success)
11049 return ret;
11052 gcc_assert (TARGET_ALTIVEC || TARGET_VSX || TARGET_SPE || TARGET_PAIRED_FLOAT);
11054 /* Handle simple unary operations. */
11055 d = (struct builtin_description *) bdesc_1arg;
11056 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
11057 if (d->code == fcode)
11058 return rs6000_expand_unop_builtin (d->icode, exp, target);
11060 /* Handle simple binary operations. */
11061 d = (struct builtin_description *) bdesc_2arg;
11062 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
11063 if (d->code == fcode)
11064 return rs6000_expand_binop_builtin (d->icode, exp, target);
11066 /* Handle simple ternary operations. */
11067 d = bdesc_3arg;
11068 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
11069 if (d->code == fcode)
11070 return rs6000_expand_ternop_builtin (d->icode, exp, target);
11072 gcc_unreachable ();
11075 static void
11076 rs6000_init_builtins (void)
11078 tree tdecl;
11080 V2SI_type_node = build_vector_type (intSI_type_node, 2);
11081 V2SF_type_node = build_vector_type (float_type_node, 2);
11082 V2DI_type_node = build_vector_type (intDI_type_node, 2);
11083 V2DF_type_node = build_vector_type (double_type_node, 2);
11084 V4HI_type_node = build_vector_type (intHI_type_node, 4);
11085 V4SI_type_node = build_vector_type (intSI_type_node, 4);
11086 V4SF_type_node = build_vector_type (float_type_node, 4);
11087 V8HI_type_node = build_vector_type (intHI_type_node, 8);
11088 V16QI_type_node = build_vector_type (intQI_type_node, 16);
11090 unsigned_V16QI_type_node = build_vector_type (unsigned_intQI_type_node, 16);
11091 unsigned_V8HI_type_node = build_vector_type (unsigned_intHI_type_node, 8);
11092 unsigned_V4SI_type_node = build_vector_type (unsigned_intSI_type_node, 4);
11093 unsigned_V2DI_type_node = build_vector_type (unsigned_intDI_type_node, 2);
11095 opaque_V2SF_type_node = build_opaque_vector_type (float_type_node, 2);
11096 opaque_V2SI_type_node = build_opaque_vector_type (intSI_type_node, 2);
11097 opaque_p_V2SI_type_node = build_pointer_type (opaque_V2SI_type_node);
11098 opaque_V4SI_type_node = build_opaque_vector_type (intSI_type_node, 4);
11100 /* The 'vector bool ...' types must be kept distinct from 'vector unsigned ...'
11101 types, especially in C++ land. Similarly, 'vector pixel' is distinct from
11102 'vector unsigned short'. */
11104 bool_char_type_node = build_distinct_type_copy (unsigned_intQI_type_node);
11105 bool_short_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
11106 bool_int_type_node = build_distinct_type_copy (unsigned_intSI_type_node);
11107 bool_long_type_node = build_distinct_type_copy (unsigned_intDI_type_node);
11108 pixel_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
11110 long_integer_type_internal_node = long_integer_type_node;
11111 long_unsigned_type_internal_node = long_unsigned_type_node;
11112 intQI_type_internal_node = intQI_type_node;
11113 uintQI_type_internal_node = unsigned_intQI_type_node;
11114 intHI_type_internal_node = intHI_type_node;
11115 uintHI_type_internal_node = unsigned_intHI_type_node;
11116 intSI_type_internal_node = intSI_type_node;
11117 uintSI_type_internal_node = unsigned_intSI_type_node;
11118 intDI_type_internal_node = intDI_type_node;
11119 uintDI_type_internal_node = unsigned_intDI_type_node;
11120 float_type_internal_node = float_type_node;
11121 double_type_internal_node = float_type_node;
11122 void_type_internal_node = void_type_node;
11124 /* Initialize the modes for builtin_function_type, mapping a machine mode to
11125 tree type node. */
11126 builtin_mode_to_type[QImode][0] = integer_type_node;
11127 builtin_mode_to_type[HImode][0] = integer_type_node;
11128 builtin_mode_to_type[SImode][0] = intSI_type_node;
11129 builtin_mode_to_type[SImode][1] = unsigned_intSI_type_node;
11130 builtin_mode_to_type[DImode][0] = intDI_type_node;
11131 builtin_mode_to_type[DImode][1] = unsigned_intDI_type_node;
11132 builtin_mode_to_type[SFmode][0] = float_type_node;
11133 builtin_mode_to_type[DFmode][0] = double_type_node;
11134 builtin_mode_to_type[V2SImode][0] = V2SI_type_node;
11135 builtin_mode_to_type[V2SFmode][0] = V2SF_type_node;
11136 builtin_mode_to_type[V2DImode][0] = V2DI_type_node;
11137 builtin_mode_to_type[V2DImode][1] = unsigned_V2DI_type_node;
11138 builtin_mode_to_type[V2DFmode][0] = V2DF_type_node;
11139 builtin_mode_to_type[V4HImode][0] = V4HI_type_node;
11140 builtin_mode_to_type[V4SImode][0] = V4SI_type_node;
11141 builtin_mode_to_type[V4SImode][1] = unsigned_V4SI_type_node;
11142 builtin_mode_to_type[V4SFmode][0] = V4SF_type_node;
11143 builtin_mode_to_type[V8HImode][0] = V8HI_type_node;
11144 builtin_mode_to_type[V8HImode][1] = unsigned_V8HI_type_node;
11145 builtin_mode_to_type[V16QImode][0] = V16QI_type_node;
11146 builtin_mode_to_type[V16QImode][1] = unsigned_V16QI_type_node;
11148 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
11149 get_identifier ("__bool char"),
11150 bool_char_type_node);
11151 TYPE_NAME (bool_char_type_node) = tdecl;
11152 (*lang_hooks.decls.pushdecl) (tdecl);
11153 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
11154 get_identifier ("__bool short"),
11155 bool_short_type_node);
11156 TYPE_NAME (bool_short_type_node) = tdecl;
11157 (*lang_hooks.decls.pushdecl) (tdecl);
11158 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
11159 get_identifier ("__bool int"),
11160 bool_int_type_node);
11161 TYPE_NAME (bool_int_type_node) = tdecl;
11162 (*lang_hooks.decls.pushdecl) (tdecl);
11163 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL, get_identifier ("__pixel"),
11164 pixel_type_node);
11165 TYPE_NAME (pixel_type_node) = tdecl;
11166 (*lang_hooks.decls.pushdecl) (tdecl);
11168 bool_V16QI_type_node = build_vector_type (bool_char_type_node, 16);
11169 bool_V8HI_type_node = build_vector_type (bool_short_type_node, 8);
11170 bool_V4SI_type_node = build_vector_type (bool_int_type_node, 4);
11171 bool_V2DI_type_node = build_vector_type (bool_long_type_node, 2);
11172 pixel_V8HI_type_node = build_vector_type (pixel_type_node, 8);
11174 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
11175 get_identifier ("__vector unsigned char"),
11176 unsigned_V16QI_type_node);
11177 TYPE_NAME (unsigned_V16QI_type_node) = tdecl;
11178 (*lang_hooks.decls.pushdecl) (tdecl);
11179 tdecl = build_decl (BUILTINS_LOCATION,
11180 TYPE_DECL, get_identifier ("__vector signed char"),
11181 V16QI_type_node);
11182 TYPE_NAME (V16QI_type_node) = tdecl;
11183 (*lang_hooks.decls.pushdecl) (tdecl);
11184 tdecl = build_decl (BUILTINS_LOCATION,
11185 TYPE_DECL, get_identifier ("__vector __bool char"),
11186 bool_V16QI_type_node);
11187 TYPE_NAME ( bool_V16QI_type_node) = tdecl;
11188 (*lang_hooks.decls.pushdecl) (tdecl);
11190 tdecl = build_decl (BUILTINS_LOCATION,
11191 TYPE_DECL, get_identifier ("__vector unsigned short"),
11192 unsigned_V8HI_type_node);
11193 TYPE_NAME (unsigned_V8HI_type_node) = tdecl;
11194 (*lang_hooks.decls.pushdecl) (tdecl);
11195 tdecl = build_decl (BUILTINS_LOCATION,
11196 TYPE_DECL, get_identifier ("__vector signed short"),
11197 V8HI_type_node);
11198 TYPE_NAME (V8HI_type_node) = tdecl;
11199 (*lang_hooks.decls.pushdecl) (tdecl);
11200 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
11201 get_identifier ("__vector __bool short"),
11202 bool_V8HI_type_node);
11203 TYPE_NAME (bool_V8HI_type_node) = tdecl;
11204 (*lang_hooks.decls.pushdecl) (tdecl);
11206 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
11207 get_identifier ("__vector unsigned int"),
11208 unsigned_V4SI_type_node);
11209 TYPE_NAME (unsigned_V4SI_type_node) = tdecl;
11210 (*lang_hooks.decls.pushdecl) (tdecl);
11211 tdecl = build_decl (BUILTINS_LOCATION,
11212 TYPE_DECL, get_identifier ("__vector signed int"),
11213 V4SI_type_node);
11214 TYPE_NAME (V4SI_type_node) = tdecl;
11215 (*lang_hooks.decls.pushdecl) (tdecl);
11216 tdecl = build_decl (BUILTINS_LOCATION,
11217 TYPE_DECL, get_identifier ("__vector __bool int"),
11218 bool_V4SI_type_node);
11219 TYPE_NAME (bool_V4SI_type_node) = tdecl;
11220 (*lang_hooks.decls.pushdecl) (tdecl);
11222 tdecl = build_decl (BUILTINS_LOCATION,
11223 TYPE_DECL, get_identifier ("__vector float"),
11224 V4SF_type_node);
11225 TYPE_NAME (V4SF_type_node) = tdecl;
11226 (*lang_hooks.decls.pushdecl) (tdecl);
11227 tdecl = build_decl (BUILTINS_LOCATION,
11228 TYPE_DECL, get_identifier ("__vector __pixel"),
11229 pixel_V8HI_type_node);
11230 TYPE_NAME (pixel_V8HI_type_node) = tdecl;
11231 (*lang_hooks.decls.pushdecl) (tdecl);
11233 if (TARGET_VSX)
11235 tdecl = build_decl (BUILTINS_LOCATION,
11236 TYPE_DECL, get_identifier ("__vector double"),
11237 V2DF_type_node);
11238 TYPE_NAME (V2DF_type_node) = tdecl;
11239 (*lang_hooks.decls.pushdecl) (tdecl);
11241 tdecl = build_decl (BUILTINS_LOCATION,
11242 TYPE_DECL, get_identifier ("__vector long"),
11243 V2DI_type_node);
11244 TYPE_NAME (V2DI_type_node) = tdecl;
11245 (*lang_hooks.decls.pushdecl) (tdecl);
11247 tdecl = build_decl (BUILTINS_LOCATION,
11248 TYPE_DECL, get_identifier ("__vector unsigned long"),
11249 unsigned_V2DI_type_node);
11250 TYPE_NAME (unsigned_V2DI_type_node) = tdecl;
11251 (*lang_hooks.decls.pushdecl) (tdecl);
11253 tdecl = build_decl (BUILTINS_LOCATION,
11254 TYPE_DECL, get_identifier ("__vector __bool long"),
11255 bool_V2DI_type_node);
11256 TYPE_NAME (bool_V2DI_type_node) = tdecl;
11257 (*lang_hooks.decls.pushdecl) (tdecl);
11260 if (TARGET_PAIRED_FLOAT)
11261 paired_init_builtins ();
11262 if (TARGET_SPE)
11263 spe_init_builtins ();
11264 if (TARGET_ALTIVEC)
11265 altivec_init_builtins ();
11266 if (TARGET_ALTIVEC || TARGET_SPE || TARGET_PAIRED_FLOAT || TARGET_VSX)
11267 rs6000_common_init_builtins ();
11268 if (TARGET_PPC_GFXOPT)
11270 tree ftype = builtin_function_type (SFmode, SFmode, SFmode, VOIDmode,
11271 RS6000_BUILTIN_RECIPF,
11272 "__builtin_recipdivf");
11273 def_builtin (MASK_PPC_GFXOPT, "__builtin_recipdivf", ftype,
11274 RS6000_BUILTIN_RECIPF);
11276 ftype = builtin_function_type (SFmode, SFmode, VOIDmode, VOIDmode,
11277 RS6000_BUILTIN_RSQRTF,
11278 "__builtin_rsqrtf");
11279 def_builtin (MASK_PPC_GFXOPT, "__builtin_rsqrtf", ftype,
11280 RS6000_BUILTIN_RSQRTF);
11282 if (TARGET_POPCNTB)
11284 tree ftype = builtin_function_type (DFmode, DFmode, DFmode, VOIDmode,
11285 RS6000_BUILTIN_RECIP,
11286 "__builtin_recipdiv");
11287 def_builtin (MASK_POPCNTB, "__builtin_recipdiv", ftype,
11288 RS6000_BUILTIN_RECIP);
11291 if (TARGET_POPCNTD)
11293 enum machine_mode mode = (TARGET_64BIT) ? DImode : SImode;
11294 tree ftype = builtin_function_type (mode, mode, mode, VOIDmode,
11295 POWER7_BUILTIN_BPERMD,
11296 "__builtin_bpermd");
11297 def_builtin (MASK_POPCNTD, "__builtin_bpermd", ftype,
11298 POWER7_BUILTIN_BPERMD);
11300 if (TARGET_POWERPC)
11302 /* Don't use builtin_function_type here, as it maps HI/QI to SI. */
11303 tree ftype = build_function_type_list (unsigned_intHI_type_node,
11304 unsigned_intHI_type_node,
11305 NULL_TREE);
11306 def_builtin (MASK_POWERPC, "__builtin_bswap16", ftype,
11307 RS6000_BUILTIN_BSWAP_HI);
11310 #if TARGET_XCOFF
11311 /* AIX libm provides clog as __clog. */
11312 if (built_in_decls [BUILT_IN_CLOG])
11313 set_user_assembler_name (built_in_decls [BUILT_IN_CLOG], "__clog");
11314 #endif
11316 #ifdef SUBTARGET_INIT_BUILTINS
11317 SUBTARGET_INIT_BUILTINS;
11318 #endif
11321 /* Returns the rs6000 builtin decl for CODE. */
11323 static tree
11324 rs6000_builtin_decl (unsigned code, bool initialize_p ATTRIBUTE_UNUSED)
11326 if (code >= RS6000_BUILTIN_COUNT)
11327 return error_mark_node;
11329 return rs6000_builtin_decls[code];
11332 /* Search through a set of builtins and enable the mask bits.
11333 DESC is an array of builtins.
11334 SIZE is the total number of builtins.
11335 START is the builtin enum at which to start.
11336 END is the builtin enum at which to end. */
11337 static void
11338 enable_mask_for_builtins (struct builtin_description *desc, int size,
11339 enum rs6000_builtins start,
11340 enum rs6000_builtins end)
11342 int i;
11344 for (i = 0; i < size; ++i)
11345 if (desc[i].code == start)
11346 break;
11348 if (i == size)
11349 return;
11351 for (; i < size; ++i)
11353 /* Flip all the bits on. */
11354 desc[i].mask = target_flags;
11355 if (desc[i].code == end)
11356 break;
11360 static void
11361 spe_init_builtins (void)
11363 tree endlink = void_list_node;
11364 tree puint_type_node = build_pointer_type (unsigned_type_node);
11365 tree pushort_type_node = build_pointer_type (short_unsigned_type_node);
11366 struct builtin_description *d;
11367 size_t i;
11369 tree v2si_ftype_4_v2si
11370 = build_function_type
11371 (opaque_V2SI_type_node,
11372 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11373 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11374 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11375 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11376 endlink)))));
11378 tree v2sf_ftype_4_v2sf
11379 = build_function_type
11380 (opaque_V2SF_type_node,
11381 tree_cons (NULL_TREE, opaque_V2SF_type_node,
11382 tree_cons (NULL_TREE, opaque_V2SF_type_node,
11383 tree_cons (NULL_TREE, opaque_V2SF_type_node,
11384 tree_cons (NULL_TREE, opaque_V2SF_type_node,
11385 endlink)))));
11387 tree int_ftype_int_v2si_v2si
11388 = build_function_type
11389 (integer_type_node,
11390 tree_cons (NULL_TREE, integer_type_node,
11391 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11392 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11393 endlink))));
11395 tree int_ftype_int_v2sf_v2sf
11396 = build_function_type
11397 (integer_type_node,
11398 tree_cons (NULL_TREE, integer_type_node,
11399 tree_cons (NULL_TREE, opaque_V2SF_type_node,
11400 tree_cons (NULL_TREE, opaque_V2SF_type_node,
11401 endlink))));
11403 tree void_ftype_v2si_puint_int
11404 = build_function_type (void_type_node,
11405 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11406 tree_cons (NULL_TREE, puint_type_node,
11407 tree_cons (NULL_TREE,
11408 integer_type_node,
11409 endlink))));
11411 tree void_ftype_v2si_puint_char
11412 = build_function_type (void_type_node,
11413 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11414 tree_cons (NULL_TREE, puint_type_node,
11415 tree_cons (NULL_TREE,
11416 char_type_node,
11417 endlink))));
11419 tree void_ftype_v2si_pv2si_int
11420 = build_function_type (void_type_node,
11421 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11422 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
11423 tree_cons (NULL_TREE,
11424 integer_type_node,
11425 endlink))));
11427 tree void_ftype_v2si_pv2si_char
11428 = build_function_type (void_type_node,
11429 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11430 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
11431 tree_cons (NULL_TREE,
11432 char_type_node,
11433 endlink))));
11435 tree void_ftype_int
11436 = build_function_type (void_type_node,
11437 tree_cons (NULL_TREE, integer_type_node, endlink));
11439 tree int_ftype_void
11440 = build_function_type (integer_type_node, endlink);
11442 tree v2si_ftype_pv2si_int
11443 = build_function_type (opaque_V2SI_type_node,
11444 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
11445 tree_cons (NULL_TREE, integer_type_node,
11446 endlink)));
11448 tree v2si_ftype_puint_int
11449 = build_function_type (opaque_V2SI_type_node,
11450 tree_cons (NULL_TREE, puint_type_node,
11451 tree_cons (NULL_TREE, integer_type_node,
11452 endlink)));
11454 tree v2si_ftype_pushort_int
11455 = build_function_type (opaque_V2SI_type_node,
11456 tree_cons (NULL_TREE, pushort_type_node,
11457 tree_cons (NULL_TREE, integer_type_node,
11458 endlink)));
11460 tree v2si_ftype_signed_char
11461 = build_function_type (opaque_V2SI_type_node,
11462 tree_cons (NULL_TREE, signed_char_type_node,
11463 endlink));
11465 /* The initialization of the simple binary and unary builtins is
11466 done in rs6000_common_init_builtins, but we have to enable the
11467 mask bits here manually because we have run out of `target_flags'
11468 bits. We really need to redesign this mask business. */
11470 enable_mask_for_builtins ((struct builtin_description *) bdesc_2arg,
11471 ARRAY_SIZE (bdesc_2arg),
11472 SPE_BUILTIN_EVADDW,
11473 SPE_BUILTIN_EVXOR);
11474 enable_mask_for_builtins ((struct builtin_description *) bdesc_1arg,
11475 ARRAY_SIZE (bdesc_1arg),
11476 SPE_BUILTIN_EVABS,
11477 SPE_BUILTIN_EVSUBFUSIAAW);
11478 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_predicates,
11479 ARRAY_SIZE (bdesc_spe_predicates),
11480 SPE_BUILTIN_EVCMPEQ,
11481 SPE_BUILTIN_EVFSTSTLT);
11482 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_evsel,
11483 ARRAY_SIZE (bdesc_spe_evsel),
11484 SPE_BUILTIN_EVSEL_CMPGTS,
11485 SPE_BUILTIN_EVSEL_FSTSTEQ);
11487 (*lang_hooks.decls.pushdecl)
11488 (build_decl (BUILTINS_LOCATION, TYPE_DECL,
11489 get_identifier ("__ev64_opaque__"),
11490 opaque_V2SI_type_node));
11492 /* Initialize irregular SPE builtins. */
11494 def_builtin (target_flags, "__builtin_spe_mtspefscr", void_ftype_int, SPE_BUILTIN_MTSPEFSCR);
11495 def_builtin (target_flags, "__builtin_spe_mfspefscr", int_ftype_void, SPE_BUILTIN_MFSPEFSCR);
11496 def_builtin (target_flags, "__builtin_spe_evstddx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDDX);
11497 def_builtin (target_flags, "__builtin_spe_evstdhx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDHX);
11498 def_builtin (target_flags, "__builtin_spe_evstdwx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDWX);
11499 def_builtin (target_flags, "__builtin_spe_evstwhex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHEX);
11500 def_builtin (target_flags, "__builtin_spe_evstwhox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHOX);
11501 def_builtin (target_flags, "__builtin_spe_evstwwex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWEX);
11502 def_builtin (target_flags, "__builtin_spe_evstwwox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWOX);
11503 def_builtin (target_flags, "__builtin_spe_evstdd", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDD);
11504 def_builtin (target_flags, "__builtin_spe_evstdh", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDH);
11505 def_builtin (target_flags, "__builtin_spe_evstdw", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDW);
11506 def_builtin (target_flags, "__builtin_spe_evstwhe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHE);
11507 def_builtin (target_flags, "__builtin_spe_evstwho", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHO);
11508 def_builtin (target_flags, "__builtin_spe_evstwwe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWE);
11509 def_builtin (target_flags, "__builtin_spe_evstwwo", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWO);
11510 def_builtin (target_flags, "__builtin_spe_evsplatfi", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATFI);
11511 def_builtin (target_flags, "__builtin_spe_evsplati", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATI);
11513 /* Loads. */
11514 def_builtin (target_flags, "__builtin_spe_evlddx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDDX);
11515 def_builtin (target_flags, "__builtin_spe_evldwx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDWX);
11516 def_builtin (target_flags, "__builtin_spe_evldhx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDHX);
11517 def_builtin (target_flags, "__builtin_spe_evlwhex", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHEX);
11518 def_builtin (target_flags, "__builtin_spe_evlwhoux", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOUX);
11519 def_builtin (target_flags, "__builtin_spe_evlwhosx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOSX);
11520 def_builtin (target_flags, "__builtin_spe_evlwwsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLATX);
11521 def_builtin (target_flags, "__builtin_spe_evlwhsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLATX);
11522 def_builtin (target_flags, "__builtin_spe_evlhhesplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLATX);
11523 def_builtin (target_flags, "__builtin_spe_evlhhousplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLATX);
11524 def_builtin (target_flags, "__builtin_spe_evlhhossplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLATX);
11525 def_builtin (target_flags, "__builtin_spe_evldd", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDD);
11526 def_builtin (target_flags, "__builtin_spe_evldw", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDW);
11527 def_builtin (target_flags, "__builtin_spe_evldh", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDH);
11528 def_builtin (target_flags, "__builtin_spe_evlhhesplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLAT);
11529 def_builtin (target_flags, "__builtin_spe_evlhhossplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLAT);
11530 def_builtin (target_flags, "__builtin_spe_evlhhousplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLAT);
11531 def_builtin (target_flags, "__builtin_spe_evlwhe", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHE);
11532 def_builtin (target_flags, "__builtin_spe_evlwhos", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOS);
11533 def_builtin (target_flags, "__builtin_spe_evlwhou", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOU);
11534 def_builtin (target_flags, "__builtin_spe_evlwhsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLAT);
11535 def_builtin (target_flags, "__builtin_spe_evlwwsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLAT);
11537 /* Predicates. */
11538 d = (struct builtin_description *) bdesc_spe_predicates;
11539 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, d++)
11541 tree type;
11543 switch (insn_data[d->icode].operand[1].mode)
11545 case V2SImode:
11546 type = int_ftype_int_v2si_v2si;
11547 break;
11548 case V2SFmode:
11549 type = int_ftype_int_v2sf_v2sf;
11550 break;
11551 default:
11552 gcc_unreachable ();
11555 def_builtin (d->mask, d->name, type, d->code);
11558 /* Evsel predicates. */
11559 d = (struct builtin_description *) bdesc_spe_evsel;
11560 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, d++)
11562 tree type;
11564 switch (insn_data[d->icode].operand[1].mode)
11566 case V2SImode:
11567 type = v2si_ftype_4_v2si;
11568 break;
11569 case V2SFmode:
11570 type = v2sf_ftype_4_v2sf;
11571 break;
11572 default:
11573 gcc_unreachable ();
11576 def_builtin (d->mask, d->name, type, d->code);
11580 static void
11581 paired_init_builtins (void)
11583 const struct builtin_description *d;
11584 size_t i;
11585 tree endlink = void_list_node;
11587 tree int_ftype_int_v2sf_v2sf
11588 = build_function_type
11589 (integer_type_node,
11590 tree_cons (NULL_TREE, integer_type_node,
11591 tree_cons (NULL_TREE, V2SF_type_node,
11592 tree_cons (NULL_TREE, V2SF_type_node,
11593 endlink))));
11594 tree pcfloat_type_node =
11595 build_pointer_type (build_qualified_type
11596 (float_type_node, TYPE_QUAL_CONST));
11598 tree v2sf_ftype_long_pcfloat = build_function_type_list (V2SF_type_node,
11599 long_integer_type_node,
11600 pcfloat_type_node,
11601 NULL_TREE);
11602 tree void_ftype_v2sf_long_pcfloat =
11603 build_function_type_list (void_type_node,
11604 V2SF_type_node,
11605 long_integer_type_node,
11606 pcfloat_type_node,
11607 NULL_TREE);
11610 def_builtin (0, "__builtin_paired_lx", v2sf_ftype_long_pcfloat,
11611 PAIRED_BUILTIN_LX);
11614 def_builtin (0, "__builtin_paired_stx", void_ftype_v2sf_long_pcfloat,
11615 PAIRED_BUILTIN_STX);
11617 /* Predicates. */
11618 d = bdesc_paired_preds;
11619 for (i = 0; i < ARRAY_SIZE (bdesc_paired_preds); ++i, d++)
11621 tree type;
11623 switch (insn_data[d->icode].operand[1].mode)
11625 case V2SFmode:
11626 type = int_ftype_int_v2sf_v2sf;
11627 break;
11628 default:
11629 gcc_unreachable ();
11632 def_builtin (d->mask, d->name, type, d->code);
11636 static void
11637 altivec_init_builtins (void)
11639 const struct builtin_description *d;
11640 const struct builtin_description_predicates *dp;
11641 size_t i;
11642 tree ftype;
11644 tree pfloat_type_node = build_pointer_type (float_type_node);
11645 tree pint_type_node = build_pointer_type (integer_type_node);
11646 tree pshort_type_node = build_pointer_type (short_integer_type_node);
11647 tree pchar_type_node = build_pointer_type (char_type_node);
11649 tree pvoid_type_node = build_pointer_type (void_type_node);
11651 tree pcfloat_type_node = build_pointer_type (build_qualified_type (float_type_node, TYPE_QUAL_CONST));
11652 tree pcint_type_node = build_pointer_type (build_qualified_type (integer_type_node, TYPE_QUAL_CONST));
11653 tree pcshort_type_node = build_pointer_type (build_qualified_type (short_integer_type_node, TYPE_QUAL_CONST));
11654 tree pcchar_type_node = build_pointer_type (build_qualified_type (char_type_node, TYPE_QUAL_CONST));
11656 tree pcvoid_type_node = build_pointer_type (build_qualified_type (void_type_node, TYPE_QUAL_CONST));
11658 tree int_ftype_opaque
11659 = build_function_type_list (integer_type_node,
11660 opaque_V4SI_type_node, NULL_TREE);
11661 tree opaque_ftype_opaque
11662 = build_function_type (integer_type_node,
11663 NULL_TREE);
11664 tree opaque_ftype_opaque_int
11665 = build_function_type_list (opaque_V4SI_type_node,
11666 opaque_V4SI_type_node, integer_type_node, NULL_TREE);
11667 tree opaque_ftype_opaque_opaque_int
11668 = build_function_type_list (opaque_V4SI_type_node,
11669 opaque_V4SI_type_node, opaque_V4SI_type_node,
11670 integer_type_node, NULL_TREE);
11671 tree int_ftype_int_opaque_opaque
11672 = build_function_type_list (integer_type_node,
11673 integer_type_node, opaque_V4SI_type_node,
11674 opaque_V4SI_type_node, NULL_TREE);
11675 tree int_ftype_int_v4si_v4si
11676 = build_function_type_list (integer_type_node,
11677 integer_type_node, V4SI_type_node,
11678 V4SI_type_node, NULL_TREE);
11679 tree v4sf_ftype_pcfloat
11680 = build_function_type_list (V4SF_type_node, pcfloat_type_node, NULL_TREE);
11681 tree void_ftype_pfloat_v4sf
11682 = build_function_type_list (void_type_node,
11683 pfloat_type_node, V4SF_type_node, NULL_TREE);
11684 tree v4si_ftype_pcint
11685 = build_function_type_list (V4SI_type_node, pcint_type_node, NULL_TREE);
11686 tree void_ftype_pint_v4si
11687 = build_function_type_list (void_type_node,
11688 pint_type_node, V4SI_type_node, NULL_TREE);
11689 tree v8hi_ftype_pcshort
11690 = build_function_type_list (V8HI_type_node, pcshort_type_node, NULL_TREE);
11691 tree void_ftype_pshort_v8hi
11692 = build_function_type_list (void_type_node,
11693 pshort_type_node, V8HI_type_node, NULL_TREE);
11694 tree v16qi_ftype_pcchar
11695 = build_function_type_list (V16QI_type_node, pcchar_type_node, NULL_TREE);
11696 tree void_ftype_pchar_v16qi
11697 = build_function_type_list (void_type_node,
11698 pchar_type_node, V16QI_type_node, NULL_TREE);
11699 tree void_ftype_v4si
11700 = build_function_type_list (void_type_node, V4SI_type_node, NULL_TREE);
11701 tree v8hi_ftype_void
11702 = build_function_type (V8HI_type_node, void_list_node);
11703 tree void_ftype_void
11704 = build_function_type (void_type_node, void_list_node);
11705 tree void_ftype_int
11706 = build_function_type_list (void_type_node, integer_type_node, NULL_TREE);
11708 tree opaque_ftype_long_pcvoid
11709 = build_function_type_list (opaque_V4SI_type_node,
11710 long_integer_type_node, pcvoid_type_node, NULL_TREE);
11711 tree v16qi_ftype_long_pcvoid
11712 = build_function_type_list (V16QI_type_node,
11713 long_integer_type_node, pcvoid_type_node, NULL_TREE);
11714 tree v8hi_ftype_long_pcvoid
11715 = build_function_type_list (V8HI_type_node,
11716 long_integer_type_node, pcvoid_type_node, NULL_TREE);
11717 tree v4si_ftype_long_pcvoid
11718 = build_function_type_list (V4SI_type_node,
11719 long_integer_type_node, pcvoid_type_node, NULL_TREE);
11721 tree void_ftype_opaque_long_pvoid
11722 = build_function_type_list (void_type_node,
11723 opaque_V4SI_type_node, long_integer_type_node,
11724 pvoid_type_node, NULL_TREE);
11725 tree void_ftype_v4si_long_pvoid
11726 = build_function_type_list (void_type_node,
11727 V4SI_type_node, long_integer_type_node,
11728 pvoid_type_node, NULL_TREE);
11729 tree void_ftype_v16qi_long_pvoid
11730 = build_function_type_list (void_type_node,
11731 V16QI_type_node, long_integer_type_node,
11732 pvoid_type_node, NULL_TREE);
11733 tree void_ftype_v8hi_long_pvoid
11734 = build_function_type_list (void_type_node,
11735 V8HI_type_node, long_integer_type_node,
11736 pvoid_type_node, NULL_TREE);
11737 tree int_ftype_int_v8hi_v8hi
11738 = build_function_type_list (integer_type_node,
11739 integer_type_node, V8HI_type_node,
11740 V8HI_type_node, NULL_TREE);
11741 tree int_ftype_int_v16qi_v16qi
11742 = build_function_type_list (integer_type_node,
11743 integer_type_node, V16QI_type_node,
11744 V16QI_type_node, NULL_TREE);
11745 tree int_ftype_int_v4sf_v4sf
11746 = build_function_type_list (integer_type_node,
11747 integer_type_node, V4SF_type_node,
11748 V4SF_type_node, NULL_TREE);
11749 tree int_ftype_int_v2df_v2df
11750 = build_function_type_list (integer_type_node,
11751 integer_type_node, V2DF_type_node,
11752 V2DF_type_node, NULL_TREE);
11753 tree v4si_ftype_v4si
11754 = build_function_type_list (V4SI_type_node, V4SI_type_node, NULL_TREE);
11755 tree v8hi_ftype_v8hi
11756 = build_function_type_list (V8HI_type_node, V8HI_type_node, NULL_TREE);
11757 tree v16qi_ftype_v16qi
11758 = build_function_type_list (V16QI_type_node, V16QI_type_node, NULL_TREE);
11759 tree v4sf_ftype_v4sf
11760 = build_function_type_list (V4SF_type_node, V4SF_type_node, NULL_TREE);
11761 tree v2df_ftype_v2df
11762 = build_function_type_list (V2DF_type_node, V2DF_type_node, NULL_TREE);
11763 tree void_ftype_pcvoid_int_int
11764 = build_function_type_list (void_type_node,
11765 pcvoid_type_node, integer_type_node,
11766 integer_type_node, NULL_TREE);
11768 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_4sf", v4sf_ftype_pcfloat,
11769 ALTIVEC_BUILTIN_LD_INTERNAL_4sf);
11770 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_4sf", void_ftype_pfloat_v4sf,
11771 ALTIVEC_BUILTIN_ST_INTERNAL_4sf);
11772 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_4si", v4si_ftype_pcint,
11773 ALTIVEC_BUILTIN_LD_INTERNAL_4si);
11774 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_4si", void_ftype_pint_v4si,
11775 ALTIVEC_BUILTIN_ST_INTERNAL_4si);
11776 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_8hi", v8hi_ftype_pcshort,
11777 ALTIVEC_BUILTIN_LD_INTERNAL_8hi);
11778 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_8hi", void_ftype_pshort_v8hi,
11779 ALTIVEC_BUILTIN_ST_INTERNAL_8hi);
11780 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_16qi", v16qi_ftype_pcchar,
11781 ALTIVEC_BUILTIN_LD_INTERNAL_16qi);
11782 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_16qi", void_ftype_pchar_v16qi,
11783 ALTIVEC_BUILTIN_ST_INTERNAL_16qi);
11784 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mtvscr", void_ftype_v4si, ALTIVEC_BUILTIN_MTVSCR);
11785 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mfvscr", v8hi_ftype_void, ALTIVEC_BUILTIN_MFVSCR);
11786 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dssall", void_ftype_void, ALTIVEC_BUILTIN_DSSALL);
11787 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dss", void_ftype_int, ALTIVEC_BUILTIN_DSS);
11788 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSL);
11789 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSR);
11790 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEBX);
11791 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEHX);
11792 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEWX);
11793 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvxl", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVXL);
11794 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVX);
11795 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVX);
11796 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvewx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVEWX);
11797 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvxl", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVXL);
11798 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvebx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVEBX);
11799 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvehx", void_ftype_v8hi_long_pvoid, ALTIVEC_BUILTIN_STVEHX);
11800 def_builtin (MASK_ALTIVEC, "__builtin_vec_ld", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LD);
11801 def_builtin (MASK_ALTIVEC, "__builtin_vec_lde", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDE);
11802 def_builtin (MASK_ALTIVEC, "__builtin_vec_ldl", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDL);
11803 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSL);
11804 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSR);
11805 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEBX);
11806 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEHX);
11807 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEWX);
11808 def_builtin (MASK_ALTIVEC, "__builtin_vec_st", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_ST);
11809 def_builtin (MASK_ALTIVEC, "__builtin_vec_ste", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STE);
11810 def_builtin (MASK_ALTIVEC, "__builtin_vec_stl", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STL);
11811 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvewx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEWX);
11812 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvebx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEBX);
11813 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvehx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEHX);
11815 if (rs6000_cpu == PROCESSOR_CELL)
11817 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvlx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVLX);
11818 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvlxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVLXL);
11819 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvrx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVRX);
11820 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvrxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVRXL);
11822 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvlx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVLX);
11823 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvlxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVLXL);
11824 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvrx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVRX);
11825 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvrxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVRXL);
11827 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvlx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVLX);
11828 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvlxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVLXL);
11829 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvrx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVRX);
11830 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvrxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVRXL);
11832 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvlx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVLX);
11833 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvlxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVLXL);
11834 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvrx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVRX);
11835 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvrxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVRXL);
11837 def_builtin (MASK_ALTIVEC, "__builtin_vec_step", int_ftype_opaque, ALTIVEC_BUILTIN_VEC_STEP);
11838 def_builtin (MASK_ALTIVEC, "__builtin_vec_splats", opaque_ftype_opaque, ALTIVEC_BUILTIN_VEC_SPLATS);
11839 def_builtin (MASK_ALTIVEC, "__builtin_vec_promote", opaque_ftype_opaque, ALTIVEC_BUILTIN_VEC_PROMOTE);
11841 def_builtin (MASK_ALTIVEC, "__builtin_vec_sld", opaque_ftype_opaque_opaque_int, ALTIVEC_BUILTIN_VEC_SLD);
11842 def_builtin (MASK_ALTIVEC, "__builtin_vec_splat", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_SPLAT);
11843 def_builtin (MASK_ALTIVEC, "__builtin_vec_extract", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_EXTRACT);
11844 def_builtin (MASK_ALTIVEC, "__builtin_vec_insert", opaque_ftype_opaque_opaque_int, ALTIVEC_BUILTIN_VEC_INSERT);
11845 def_builtin (MASK_ALTIVEC, "__builtin_vec_vspltw", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTW);
11846 def_builtin (MASK_ALTIVEC, "__builtin_vec_vsplth", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTH);
11847 def_builtin (MASK_ALTIVEC, "__builtin_vec_vspltb", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTB);
11848 def_builtin (MASK_ALTIVEC, "__builtin_vec_ctf", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTF);
11849 def_builtin (MASK_ALTIVEC, "__builtin_vec_vcfsx", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFSX);
11850 def_builtin (MASK_ALTIVEC, "__builtin_vec_vcfux", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFUX);
11851 def_builtin (MASK_ALTIVEC, "__builtin_vec_cts", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTS);
11852 def_builtin (MASK_ALTIVEC, "__builtin_vec_ctu", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTU);
11854 /* Add the DST variants. */
11855 d = bdesc_dst;
11856 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
11857 def_builtin (d->mask, d->name, void_ftype_pcvoid_int_int, d->code);
11859 /* Initialize the predicates. */
11860 dp = bdesc_altivec_preds;
11861 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
11863 enum machine_mode mode1;
11864 tree type;
11865 bool is_overloaded = ((dp->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
11866 && dp->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
11867 || (dp->code >= VSX_BUILTIN_OVERLOADED_FIRST
11868 && dp->code <= VSX_BUILTIN_OVERLOADED_LAST));
11870 if (is_overloaded)
11871 mode1 = VOIDmode;
11872 else
11873 mode1 = insn_data[dp->icode].operand[1].mode;
11875 switch (mode1)
11877 case VOIDmode:
11878 type = int_ftype_int_opaque_opaque;
11879 break;
11880 case V4SImode:
11881 type = int_ftype_int_v4si_v4si;
11882 break;
11883 case V8HImode:
11884 type = int_ftype_int_v8hi_v8hi;
11885 break;
11886 case V16QImode:
11887 type = int_ftype_int_v16qi_v16qi;
11888 break;
11889 case V4SFmode:
11890 type = int_ftype_int_v4sf_v4sf;
11891 break;
11892 case V2DFmode:
11893 type = int_ftype_int_v2df_v2df;
11894 break;
11895 default:
11896 gcc_unreachable ();
11899 def_builtin (dp->mask, dp->name, type, dp->code);
11902 /* Initialize the abs* operators. */
11903 d = bdesc_abs;
11904 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
11906 enum machine_mode mode0;
11907 tree type;
11909 mode0 = insn_data[d->icode].operand[0].mode;
11911 switch (mode0)
11913 case V4SImode:
11914 type = v4si_ftype_v4si;
11915 break;
11916 case V8HImode:
11917 type = v8hi_ftype_v8hi;
11918 break;
11919 case V16QImode:
11920 type = v16qi_ftype_v16qi;
11921 break;
11922 case V4SFmode:
11923 type = v4sf_ftype_v4sf;
11924 break;
11925 case V2DFmode:
11926 type = v2df_ftype_v2df;
11927 break;
11928 default:
11929 gcc_unreachable ();
11932 def_builtin (d->mask, d->name, type, d->code);
11935 if (TARGET_ALTIVEC)
11937 tree decl;
11939 /* Initialize target builtin that implements
11940 targetm.vectorize.builtin_mask_for_load. */
11942 decl = add_builtin_function ("__builtin_altivec_mask_for_load",
11943 v16qi_ftype_long_pcvoid,
11944 ALTIVEC_BUILTIN_MASK_FOR_LOAD,
11945 BUILT_IN_MD, NULL, NULL_TREE);
11946 TREE_READONLY (decl) = 1;
11947 /* Record the decl. Will be used by rs6000_builtin_mask_for_load. */
11948 altivec_builtin_mask_for_load = decl;
11951 /* Access to the vec_init patterns. */
11952 ftype = build_function_type_list (V4SI_type_node, integer_type_node,
11953 integer_type_node, integer_type_node,
11954 integer_type_node, NULL_TREE);
11955 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v4si", ftype,
11956 ALTIVEC_BUILTIN_VEC_INIT_V4SI);
11958 ftype = build_function_type_list (V8HI_type_node, short_integer_type_node,
11959 short_integer_type_node,
11960 short_integer_type_node,
11961 short_integer_type_node,
11962 short_integer_type_node,
11963 short_integer_type_node,
11964 short_integer_type_node,
11965 short_integer_type_node, NULL_TREE);
11966 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v8hi", ftype,
11967 ALTIVEC_BUILTIN_VEC_INIT_V8HI);
11969 ftype = build_function_type_list (V16QI_type_node, char_type_node,
11970 char_type_node, char_type_node,
11971 char_type_node, char_type_node,
11972 char_type_node, char_type_node,
11973 char_type_node, char_type_node,
11974 char_type_node, char_type_node,
11975 char_type_node, char_type_node,
11976 char_type_node, char_type_node,
11977 char_type_node, NULL_TREE);
11978 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v16qi", ftype,
11979 ALTIVEC_BUILTIN_VEC_INIT_V16QI);
11981 ftype = build_function_type_list (V4SF_type_node, float_type_node,
11982 float_type_node, float_type_node,
11983 float_type_node, NULL_TREE);
11984 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v4sf", ftype,
11985 ALTIVEC_BUILTIN_VEC_INIT_V4SF);
11987 if (TARGET_VSX)
11989 ftype = build_function_type_list (V2DF_type_node, double_type_node,
11990 double_type_node, NULL_TREE);
11991 def_builtin (MASK_VSX, "__builtin_vec_init_v2df", ftype,
11992 VSX_BUILTIN_VEC_INIT_V2DF);
11994 ftype = build_function_type_list (V2DI_type_node, intDI_type_node,
11995 intDI_type_node, NULL_TREE);
11996 def_builtin (MASK_VSX, "__builtin_vec_init_v2di", ftype,
11997 VSX_BUILTIN_VEC_INIT_V2DI);
12000 /* Access to the vec_set patterns. */
12001 ftype = build_function_type_list (V4SI_type_node, V4SI_type_node,
12002 intSI_type_node,
12003 integer_type_node, NULL_TREE);
12004 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v4si", ftype,
12005 ALTIVEC_BUILTIN_VEC_SET_V4SI);
12007 ftype = build_function_type_list (V8HI_type_node, V8HI_type_node,
12008 intHI_type_node,
12009 integer_type_node, NULL_TREE);
12010 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v8hi", ftype,
12011 ALTIVEC_BUILTIN_VEC_SET_V8HI);
12013 ftype = build_function_type_list (V16QI_type_node, V16QI_type_node,
12014 intQI_type_node,
12015 integer_type_node, NULL_TREE);
12016 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v16qi", ftype,
12017 ALTIVEC_BUILTIN_VEC_SET_V16QI);
12019 ftype = build_function_type_list (V4SF_type_node, V4SF_type_node,
12020 float_type_node,
12021 integer_type_node, NULL_TREE);
12022 def_builtin (MASK_ALTIVEC|MASK_VSX, "__builtin_vec_set_v4sf", ftype,
12023 ALTIVEC_BUILTIN_VEC_SET_V4SF);
12025 if (TARGET_VSX)
12027 ftype = build_function_type_list (V2DF_type_node, V2DF_type_node,
12028 double_type_node,
12029 integer_type_node, NULL_TREE);
12030 def_builtin (MASK_VSX, "__builtin_vec_set_v2df", ftype,
12031 VSX_BUILTIN_VEC_SET_V2DF);
12033 ftype = build_function_type_list (V2DI_type_node, V2DI_type_node,
12034 intDI_type_node,
12035 integer_type_node, NULL_TREE);
12036 def_builtin (MASK_VSX, "__builtin_vec_set_v2di", ftype,
12037 VSX_BUILTIN_VEC_SET_V2DI);
12040 /* Access to the vec_extract patterns. */
12041 ftype = build_function_type_list (intSI_type_node, V4SI_type_node,
12042 integer_type_node, NULL_TREE);
12043 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v4si", ftype,
12044 ALTIVEC_BUILTIN_VEC_EXT_V4SI);
12046 ftype = build_function_type_list (intHI_type_node, V8HI_type_node,
12047 integer_type_node, NULL_TREE);
12048 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v8hi", ftype,
12049 ALTIVEC_BUILTIN_VEC_EXT_V8HI);
12051 ftype = build_function_type_list (intQI_type_node, V16QI_type_node,
12052 integer_type_node, NULL_TREE);
12053 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v16qi", ftype,
12054 ALTIVEC_BUILTIN_VEC_EXT_V16QI);
12056 ftype = build_function_type_list (float_type_node, V4SF_type_node,
12057 integer_type_node, NULL_TREE);
12058 def_builtin (MASK_ALTIVEC|MASK_VSX, "__builtin_vec_ext_v4sf", ftype,
12059 ALTIVEC_BUILTIN_VEC_EXT_V4SF);
12061 if (TARGET_VSX)
12063 ftype = build_function_type_list (double_type_node, V2DF_type_node,
12064 integer_type_node, NULL_TREE);
12065 def_builtin (MASK_VSX, "__builtin_vec_ext_v2df", ftype,
12066 VSX_BUILTIN_VEC_EXT_V2DF);
12068 ftype = build_function_type_list (intDI_type_node, V2DI_type_node,
12069 integer_type_node, NULL_TREE);
12070 def_builtin (MASK_VSX, "__builtin_vec_ext_v2di", ftype,
12071 VSX_BUILTIN_VEC_EXT_V2DI);
12075 /* Hash function for builtin functions with up to 3 arguments and a return
12076 type. */
12077 static unsigned
12078 builtin_hash_function (const void *hash_entry)
12080 unsigned ret = 0;
12081 int i;
12082 const struct builtin_hash_struct *bh =
12083 (const struct builtin_hash_struct *) hash_entry;
12085 for (i = 0; i < 4; i++)
12087 ret = (ret * (unsigned)MAX_MACHINE_MODE) + ((unsigned)bh->mode[i]);
12088 ret = (ret * 2) + bh->uns_p[i];
12091 return ret;
12094 /* Compare builtin hash entries H1 and H2 for equivalence. */
12095 static int
12096 builtin_hash_eq (const void *h1, const void *h2)
12098 const struct builtin_hash_struct *p1 = (const struct builtin_hash_struct *) h1;
12099 const struct builtin_hash_struct *p2 = (const struct builtin_hash_struct *) h2;
12101 return ((p1->mode[0] == p2->mode[0])
12102 && (p1->mode[1] == p2->mode[1])
12103 && (p1->mode[2] == p2->mode[2])
12104 && (p1->mode[3] == p2->mode[3])
12105 && (p1->uns_p[0] == p2->uns_p[0])
12106 && (p1->uns_p[1] == p2->uns_p[1])
12107 && (p1->uns_p[2] == p2->uns_p[2])
12108 && (p1->uns_p[3] == p2->uns_p[3]));
12111 /* Map types for builtin functions with an explicit return type and up to 3
12112 arguments. Functions with fewer than 3 arguments use VOIDmode as the type
12113 of the argument. */
12114 static tree
12115 builtin_function_type (enum machine_mode mode_ret, enum machine_mode mode_arg0,
12116 enum machine_mode mode_arg1, enum machine_mode mode_arg2,
12117 enum rs6000_builtins builtin, const char *name)
12119 struct builtin_hash_struct h;
12120 struct builtin_hash_struct *h2;
12121 void **found;
12122 int num_args = 3;
12123 int i;
12124 tree ret_type = NULL_TREE;
12125 tree arg_type[3] = { NULL_TREE, NULL_TREE, NULL_TREE };
12126 tree args;
12128 /* Create builtin_hash_table. */
12129 if (builtin_hash_table == NULL)
12130 builtin_hash_table = htab_create_ggc (1500, builtin_hash_function,
12131 builtin_hash_eq, NULL);
12133 h.type = NULL_TREE;
12134 h.mode[0] = mode_ret;
12135 h.mode[1] = mode_arg0;
12136 h.mode[2] = mode_arg1;
12137 h.mode[3] = mode_arg2;
12138 h.uns_p[0] = 0;
12139 h.uns_p[1] = 0;
12140 h.uns_p[2] = 0;
12141 h.uns_p[3] = 0;
12143 /* If the builtin is a type that produces unsigned results or takes unsigned
12144 arguments, and it is returned as a decl for the vectorizer (such as
12145 widening multiplies, permute), make sure the arguments and return value
12146 are type correct. */
12147 switch (builtin)
12149 /* unsigned 2 argument functions. */
12150 case ALTIVEC_BUILTIN_VMULEUB_UNS:
12151 case ALTIVEC_BUILTIN_VMULEUH_UNS:
12152 case ALTIVEC_BUILTIN_VMULOUB_UNS:
12153 case ALTIVEC_BUILTIN_VMULOUH_UNS:
12154 h.uns_p[0] = 1;
12155 h.uns_p[1] = 1;
12156 h.uns_p[2] = 1;
12157 break;
12159 /* unsigned 3 argument functions. */
12160 case ALTIVEC_BUILTIN_VPERM_16QI_UNS:
12161 case ALTIVEC_BUILTIN_VPERM_8HI_UNS:
12162 case ALTIVEC_BUILTIN_VPERM_4SI_UNS:
12163 case ALTIVEC_BUILTIN_VPERM_2DI_UNS:
12164 case ALTIVEC_BUILTIN_VSEL_16QI_UNS:
12165 case ALTIVEC_BUILTIN_VSEL_8HI_UNS:
12166 case ALTIVEC_BUILTIN_VSEL_4SI_UNS:
12167 case ALTIVEC_BUILTIN_VSEL_2DI_UNS:
12168 case VSX_BUILTIN_VPERM_16QI_UNS:
12169 case VSX_BUILTIN_VPERM_8HI_UNS:
12170 case VSX_BUILTIN_VPERM_4SI_UNS:
12171 case VSX_BUILTIN_VPERM_2DI_UNS:
12172 case VSX_BUILTIN_XXSEL_16QI_UNS:
12173 case VSX_BUILTIN_XXSEL_8HI_UNS:
12174 case VSX_BUILTIN_XXSEL_4SI_UNS:
12175 case VSX_BUILTIN_XXSEL_2DI_UNS:
12176 h.uns_p[0] = 1;
12177 h.uns_p[1] = 1;
12178 h.uns_p[2] = 1;
12179 h.uns_p[3] = 1;
12180 break;
12182 /* signed permute functions with unsigned char mask. */
12183 case ALTIVEC_BUILTIN_VPERM_16QI:
12184 case ALTIVEC_BUILTIN_VPERM_8HI:
12185 case ALTIVEC_BUILTIN_VPERM_4SI:
12186 case ALTIVEC_BUILTIN_VPERM_4SF:
12187 case ALTIVEC_BUILTIN_VPERM_2DI:
12188 case ALTIVEC_BUILTIN_VPERM_2DF:
12189 case VSX_BUILTIN_VPERM_16QI:
12190 case VSX_BUILTIN_VPERM_8HI:
12191 case VSX_BUILTIN_VPERM_4SI:
12192 case VSX_BUILTIN_VPERM_4SF:
12193 case VSX_BUILTIN_VPERM_2DI:
12194 case VSX_BUILTIN_VPERM_2DF:
12195 h.uns_p[3] = 1;
12196 break;
12198 /* unsigned args, signed return. */
12199 case VSX_BUILTIN_XVCVUXDDP_UNS:
12200 case VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF:
12201 h.uns_p[1] = 1;
12202 break;
12204 /* signed args, unsigned return. */
12205 case VSX_BUILTIN_XVCVDPUXDS_UNS:
12206 case VECTOR_BUILTIN_FIXUNS_V4SF_V4SI:
12207 h.uns_p[0] = 1;
12208 break;
12210 default:
12211 break;
12214 /* Figure out how many args are present. */
12215 while (num_args > 0 && h.mode[num_args] == VOIDmode)
12216 num_args--;
12218 if (num_args == 0)
12219 fatal_error ("internal error: builtin function %s had no type", name);
12221 ret_type = builtin_mode_to_type[h.mode[0]][h.uns_p[0]];
12222 if (!ret_type && h.uns_p[0])
12223 ret_type = builtin_mode_to_type[h.mode[0]][0];
12225 if (!ret_type)
12226 fatal_error ("internal error: builtin function %s had an unexpected "
12227 "return type %s", name, GET_MODE_NAME (h.mode[0]));
12229 for (i = 0; i < num_args; i++)
12231 int m = (int) h.mode[i+1];
12232 int uns_p = h.uns_p[i+1];
12234 arg_type[i] = builtin_mode_to_type[m][uns_p];
12235 if (!arg_type[i] && uns_p)
12236 arg_type[i] = builtin_mode_to_type[m][0];
12238 if (!arg_type[i])
12239 fatal_error ("internal error: builtin function %s, argument %d "
12240 "had unexpected argument type %s", name, i,
12241 GET_MODE_NAME (m));
12244 found = htab_find_slot (builtin_hash_table, &h, INSERT);
12245 if (*found == NULL)
12247 h2 = GGC_NEW (struct builtin_hash_struct);
12248 *h2 = h;
12249 *found = (void *)h2;
12250 args = void_list_node;
12252 for (i = num_args - 1; i >= 0; i--)
12253 args = tree_cons (NULL_TREE, arg_type[i], args);
12255 h2->type = build_function_type (ret_type, args);
12258 return ((struct builtin_hash_struct *)(*found))->type;
12261 static void
12262 rs6000_common_init_builtins (void)
12264 const struct builtin_description *d;
12265 size_t i;
12267 tree opaque_ftype_opaque = NULL_TREE;
12268 tree opaque_ftype_opaque_opaque = NULL_TREE;
12269 tree opaque_ftype_opaque_opaque_opaque = NULL_TREE;
12270 tree v2si_ftype_qi = NULL_TREE;
12271 tree v2si_ftype_v2si_qi = NULL_TREE;
12272 tree v2si_ftype_int_qi = NULL_TREE;
12274 if (!TARGET_PAIRED_FLOAT)
12276 builtin_mode_to_type[V2SImode][0] = opaque_V2SI_type_node;
12277 builtin_mode_to_type[V2SFmode][0] = opaque_V2SF_type_node;
12280 /* Add the ternary operators. */
12281 d = bdesc_3arg;
12282 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
12284 tree type;
12285 int mask = d->mask;
12287 if ((mask != 0 && (mask & target_flags) == 0)
12288 || (mask == 0 && !TARGET_PAIRED_FLOAT))
12289 continue;
12291 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
12292 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
12293 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
12294 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
12296 if (! (type = opaque_ftype_opaque_opaque_opaque))
12297 type = opaque_ftype_opaque_opaque_opaque
12298 = build_function_type_list (opaque_V4SI_type_node,
12299 opaque_V4SI_type_node,
12300 opaque_V4SI_type_node,
12301 opaque_V4SI_type_node,
12302 NULL_TREE);
12304 else
12306 enum insn_code icode = d->icode;
12307 if (d->name == 0 || icode == CODE_FOR_nothing)
12308 continue;
12310 type = builtin_function_type (insn_data[icode].operand[0].mode,
12311 insn_data[icode].operand[1].mode,
12312 insn_data[icode].operand[2].mode,
12313 insn_data[icode].operand[3].mode,
12314 d->code, d->name);
12317 def_builtin (d->mask, d->name, type, d->code);
12320 /* Add the binary operators. */
12321 d = bdesc_2arg;
12322 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
12324 enum machine_mode mode0, mode1, mode2;
12325 tree type;
12326 int mask = d->mask;
12328 if ((mask != 0 && (mask & target_flags) == 0)
12329 || (mask == 0 && !TARGET_PAIRED_FLOAT))
12330 continue;
12332 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
12333 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
12334 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
12335 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
12337 if (! (type = opaque_ftype_opaque_opaque))
12338 type = opaque_ftype_opaque_opaque
12339 = build_function_type_list (opaque_V4SI_type_node,
12340 opaque_V4SI_type_node,
12341 opaque_V4SI_type_node,
12342 NULL_TREE);
12344 else
12346 enum insn_code icode = d->icode;
12347 if (d->name == 0 || icode == CODE_FOR_nothing)
12348 continue;
12350 mode0 = insn_data[icode].operand[0].mode;
12351 mode1 = insn_data[icode].operand[1].mode;
12352 mode2 = insn_data[icode].operand[2].mode;
12354 if (mode0 == V2SImode && mode1 == V2SImode && mode2 == QImode)
12356 if (! (type = v2si_ftype_v2si_qi))
12357 type = v2si_ftype_v2si_qi
12358 = build_function_type_list (opaque_V2SI_type_node,
12359 opaque_V2SI_type_node,
12360 char_type_node,
12361 NULL_TREE);
12364 else if (mode0 == V2SImode && GET_MODE_CLASS (mode1) == MODE_INT
12365 && mode2 == QImode)
12367 if (! (type = v2si_ftype_int_qi))
12368 type = v2si_ftype_int_qi
12369 = build_function_type_list (opaque_V2SI_type_node,
12370 integer_type_node,
12371 char_type_node,
12372 NULL_TREE);
12375 else
12376 type = builtin_function_type (mode0, mode1, mode2, VOIDmode,
12377 d->code, d->name);
12380 def_builtin (d->mask, d->name, type, d->code);
12383 /* Add the simple unary operators. */
12384 d = (struct builtin_description *) bdesc_1arg;
12385 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
12387 enum machine_mode mode0, mode1;
12388 tree type;
12389 int mask = d->mask;
12391 if ((mask != 0 && (mask & target_flags) == 0)
12392 || (mask == 0 && !TARGET_PAIRED_FLOAT))
12393 continue;
12395 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
12396 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
12397 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
12398 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
12400 if (! (type = opaque_ftype_opaque))
12401 type = opaque_ftype_opaque
12402 = build_function_type_list (opaque_V4SI_type_node,
12403 opaque_V4SI_type_node,
12404 NULL_TREE);
12406 else
12408 enum insn_code icode = d->icode;
12409 if (d->name == 0 || icode == CODE_FOR_nothing)
12410 continue;
12412 mode0 = insn_data[icode].operand[0].mode;
12413 mode1 = insn_data[icode].operand[1].mode;
12415 if (mode0 == V2SImode && mode1 == QImode)
12417 if (! (type = v2si_ftype_qi))
12418 type = v2si_ftype_qi
12419 = build_function_type_list (opaque_V2SI_type_node,
12420 char_type_node,
12421 NULL_TREE);
12424 else
12425 type = builtin_function_type (mode0, mode1, VOIDmode, VOIDmode,
12426 d->code, d->name);
12429 def_builtin (d->mask, d->name, type, d->code);
12433 static void
12434 rs6000_init_libfuncs (void)
12436 if (DEFAULT_ABI != ABI_V4 && TARGET_XCOFF
12437 && !TARGET_POWER2 && !TARGET_POWERPC)
12439 /* AIX library routines for float->int conversion. */
12440 set_conv_libfunc (sfix_optab, SImode, DFmode, "__itrunc");
12441 set_conv_libfunc (ufix_optab, SImode, DFmode, "__uitrunc");
12442 set_conv_libfunc (sfix_optab, SImode, TFmode, "_qitrunc");
12443 set_conv_libfunc (ufix_optab, SImode, TFmode, "_quitrunc");
12446 if (!TARGET_IEEEQUAD)
12447 /* AIX/Darwin/64-bit Linux quad floating point routines. */
12448 if (!TARGET_XL_COMPAT)
12450 set_optab_libfunc (add_optab, TFmode, "__gcc_qadd");
12451 set_optab_libfunc (sub_optab, TFmode, "__gcc_qsub");
12452 set_optab_libfunc (smul_optab, TFmode, "__gcc_qmul");
12453 set_optab_libfunc (sdiv_optab, TFmode, "__gcc_qdiv");
12455 if (!(TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)))
12457 set_optab_libfunc (neg_optab, TFmode, "__gcc_qneg");
12458 set_optab_libfunc (eq_optab, TFmode, "__gcc_qeq");
12459 set_optab_libfunc (ne_optab, TFmode, "__gcc_qne");
12460 set_optab_libfunc (gt_optab, TFmode, "__gcc_qgt");
12461 set_optab_libfunc (ge_optab, TFmode, "__gcc_qge");
12462 set_optab_libfunc (lt_optab, TFmode, "__gcc_qlt");
12463 set_optab_libfunc (le_optab, TFmode, "__gcc_qle");
12465 set_conv_libfunc (sext_optab, TFmode, SFmode, "__gcc_stoq");
12466 set_conv_libfunc (sext_optab, TFmode, DFmode, "__gcc_dtoq");
12467 set_conv_libfunc (trunc_optab, SFmode, TFmode, "__gcc_qtos");
12468 set_conv_libfunc (trunc_optab, DFmode, TFmode, "__gcc_qtod");
12469 set_conv_libfunc (sfix_optab, SImode, TFmode, "__gcc_qtoi");
12470 set_conv_libfunc (ufix_optab, SImode, TFmode, "__gcc_qtou");
12471 set_conv_libfunc (sfloat_optab, TFmode, SImode, "__gcc_itoq");
12472 set_conv_libfunc (ufloat_optab, TFmode, SImode, "__gcc_utoq");
12475 if (!(TARGET_HARD_FLOAT && TARGET_FPRS))
12476 set_optab_libfunc (unord_optab, TFmode, "__gcc_qunord");
12478 else
12480 set_optab_libfunc (add_optab, TFmode, "_xlqadd");
12481 set_optab_libfunc (sub_optab, TFmode, "_xlqsub");
12482 set_optab_libfunc (smul_optab, TFmode, "_xlqmul");
12483 set_optab_libfunc (sdiv_optab, TFmode, "_xlqdiv");
12485 else
12487 /* 32-bit SVR4 quad floating point routines. */
12489 set_optab_libfunc (add_optab, TFmode, "_q_add");
12490 set_optab_libfunc (sub_optab, TFmode, "_q_sub");
12491 set_optab_libfunc (neg_optab, TFmode, "_q_neg");
12492 set_optab_libfunc (smul_optab, TFmode, "_q_mul");
12493 set_optab_libfunc (sdiv_optab, TFmode, "_q_div");
12494 if (TARGET_PPC_GPOPT || TARGET_POWER2)
12495 set_optab_libfunc (sqrt_optab, TFmode, "_q_sqrt");
12497 set_optab_libfunc (eq_optab, TFmode, "_q_feq");
12498 set_optab_libfunc (ne_optab, TFmode, "_q_fne");
12499 set_optab_libfunc (gt_optab, TFmode, "_q_fgt");
12500 set_optab_libfunc (ge_optab, TFmode, "_q_fge");
12501 set_optab_libfunc (lt_optab, TFmode, "_q_flt");
12502 set_optab_libfunc (le_optab, TFmode, "_q_fle");
12504 set_conv_libfunc (sext_optab, TFmode, SFmode, "_q_stoq");
12505 set_conv_libfunc (sext_optab, TFmode, DFmode, "_q_dtoq");
12506 set_conv_libfunc (trunc_optab, SFmode, TFmode, "_q_qtos");
12507 set_conv_libfunc (trunc_optab, DFmode, TFmode, "_q_qtod");
12508 set_conv_libfunc (sfix_optab, SImode, TFmode, "_q_qtoi");
12509 set_conv_libfunc (ufix_optab, SImode, TFmode, "_q_qtou");
12510 set_conv_libfunc (sfloat_optab, TFmode, SImode, "_q_itoq");
12511 set_conv_libfunc (ufloat_optab, TFmode, SImode, "_q_utoq");
12516 /* Expand a block clear operation, and return 1 if successful. Return 0
12517 if we should let the compiler generate normal code.
12519 operands[0] is the destination
12520 operands[1] is the length
12521 operands[3] is the alignment */
12524 expand_block_clear (rtx operands[])
12526 rtx orig_dest = operands[0];
12527 rtx bytes_rtx = operands[1];
12528 rtx align_rtx = operands[3];
12529 bool constp = (GET_CODE (bytes_rtx) == CONST_INT);
12530 HOST_WIDE_INT align;
12531 HOST_WIDE_INT bytes;
12532 int offset;
12533 int clear_bytes;
12534 int clear_step;
12536 /* If this is not a fixed size move, just call memcpy */
12537 if (! constp)
12538 return 0;
12540 /* This must be a fixed size alignment */
12541 gcc_assert (GET_CODE (align_rtx) == CONST_INT);
12542 align = INTVAL (align_rtx) * BITS_PER_UNIT;
12544 /* Anything to clear? */
12545 bytes = INTVAL (bytes_rtx);
12546 if (bytes <= 0)
12547 return 1;
12549 /* Use the builtin memset after a point, to avoid huge code bloat.
12550 When optimize_size, avoid any significant code bloat; calling
12551 memset is about 4 instructions, so allow for one instruction to
12552 load zero and three to do clearing. */
12553 if (TARGET_ALTIVEC && align >= 128)
12554 clear_step = 16;
12555 else if (TARGET_POWERPC64 && align >= 32)
12556 clear_step = 8;
12557 else if (TARGET_SPE && align >= 64)
12558 clear_step = 8;
12559 else
12560 clear_step = 4;
12562 if (optimize_size && bytes > 3 * clear_step)
12563 return 0;
12564 if (! optimize_size && bytes > 8 * clear_step)
12565 return 0;
12567 for (offset = 0; bytes > 0; offset += clear_bytes, bytes -= clear_bytes)
12569 enum machine_mode mode = BLKmode;
12570 rtx dest;
12572 if (bytes >= 16 && TARGET_ALTIVEC && align >= 128)
12574 clear_bytes = 16;
12575 mode = V4SImode;
12577 else if (bytes >= 8 && TARGET_SPE && align >= 64)
12579 clear_bytes = 8;
12580 mode = V2SImode;
12582 else if (bytes >= 8 && TARGET_POWERPC64
12583 /* 64-bit loads and stores require word-aligned
12584 displacements. */
12585 && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
12587 clear_bytes = 8;
12588 mode = DImode;
12590 else if (bytes >= 4 && (align >= 32 || !STRICT_ALIGNMENT))
12591 { /* move 4 bytes */
12592 clear_bytes = 4;
12593 mode = SImode;
12595 else if (bytes >= 2 && (align >= 16 || !STRICT_ALIGNMENT))
12596 { /* move 2 bytes */
12597 clear_bytes = 2;
12598 mode = HImode;
12600 else /* move 1 byte at a time */
12602 clear_bytes = 1;
12603 mode = QImode;
12606 dest = adjust_address (orig_dest, mode, offset);
12608 emit_move_insn (dest, CONST0_RTX (mode));
12611 return 1;
12615 /* Expand a block move operation, and return 1 if successful. Return 0
12616 if we should let the compiler generate normal code.
12618 operands[0] is the destination
12619 operands[1] is the source
12620 operands[2] is the length
12621 operands[3] is the alignment */
12623 #define MAX_MOVE_REG 4
12626 expand_block_move (rtx operands[])
12628 rtx orig_dest = operands[0];
12629 rtx orig_src = operands[1];
12630 rtx bytes_rtx = operands[2];
12631 rtx align_rtx = operands[3];
12632 int constp = (GET_CODE (bytes_rtx) == CONST_INT);
12633 int align;
12634 int bytes;
12635 int offset;
12636 int move_bytes;
12637 rtx stores[MAX_MOVE_REG];
12638 int num_reg = 0;
12640 /* If this is not a fixed size move, just call memcpy */
12641 if (! constp)
12642 return 0;
12644 /* This must be a fixed size alignment */
12645 gcc_assert (GET_CODE (align_rtx) == CONST_INT);
12646 align = INTVAL (align_rtx) * BITS_PER_UNIT;
12648 /* Anything to move? */
12649 bytes = INTVAL (bytes_rtx);
12650 if (bytes <= 0)
12651 return 1;
12653 /* store_one_arg depends on expand_block_move to handle at least the size of
12654 reg_parm_stack_space. */
12655 if (bytes > (TARGET_POWERPC64 ? 64 : 32))
12656 return 0;
12658 for (offset = 0; bytes > 0; offset += move_bytes, bytes -= move_bytes)
12660 union {
12661 rtx (*movmemsi) (rtx, rtx, rtx, rtx);
12662 rtx (*mov) (rtx, rtx);
12663 } gen_func;
12664 enum machine_mode mode = BLKmode;
12665 rtx src, dest;
12667 /* Altivec first, since it will be faster than a string move
12668 when it applies, and usually not significantly larger. */
12669 if (TARGET_ALTIVEC && bytes >= 16 && align >= 128)
12671 move_bytes = 16;
12672 mode = V4SImode;
12673 gen_func.mov = gen_movv4si;
12675 else if (TARGET_SPE && bytes >= 8 && align >= 64)
12677 move_bytes = 8;
12678 mode = V2SImode;
12679 gen_func.mov = gen_movv2si;
12681 else if (TARGET_STRING
12682 && bytes > 24 /* move up to 32 bytes at a time */
12683 && ! fixed_regs[5]
12684 && ! fixed_regs[6]
12685 && ! fixed_regs[7]
12686 && ! fixed_regs[8]
12687 && ! fixed_regs[9]
12688 && ! fixed_regs[10]
12689 && ! fixed_regs[11]
12690 && ! fixed_regs[12])
12692 move_bytes = (bytes > 32) ? 32 : bytes;
12693 gen_func.movmemsi = gen_movmemsi_8reg;
12695 else if (TARGET_STRING
12696 && bytes > 16 /* move up to 24 bytes at a time */
12697 && ! fixed_regs[5]
12698 && ! fixed_regs[6]
12699 && ! fixed_regs[7]
12700 && ! fixed_regs[8]
12701 && ! fixed_regs[9]
12702 && ! fixed_regs[10])
12704 move_bytes = (bytes > 24) ? 24 : bytes;
12705 gen_func.movmemsi = gen_movmemsi_6reg;
12707 else if (TARGET_STRING
12708 && bytes > 8 /* move up to 16 bytes at a time */
12709 && ! fixed_regs[5]
12710 && ! fixed_regs[6]
12711 && ! fixed_regs[7]
12712 && ! fixed_regs[8])
12714 move_bytes = (bytes > 16) ? 16 : bytes;
12715 gen_func.movmemsi = gen_movmemsi_4reg;
12717 else if (bytes >= 8 && TARGET_POWERPC64
12718 /* 64-bit loads and stores require word-aligned
12719 displacements. */
12720 && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
12722 move_bytes = 8;
12723 mode = DImode;
12724 gen_func.mov = gen_movdi;
12726 else if (TARGET_STRING && bytes > 4 && !TARGET_POWERPC64)
12727 { /* move up to 8 bytes at a time */
12728 move_bytes = (bytes > 8) ? 8 : bytes;
12729 gen_func.movmemsi = gen_movmemsi_2reg;
12731 else if (bytes >= 4 && (align >= 32 || !STRICT_ALIGNMENT))
12732 { /* move 4 bytes */
12733 move_bytes = 4;
12734 mode = SImode;
12735 gen_func.mov = gen_movsi;
12737 else if (bytes >= 2 && (align >= 16 || !STRICT_ALIGNMENT))
12738 { /* move 2 bytes */
12739 move_bytes = 2;
12740 mode = HImode;
12741 gen_func.mov = gen_movhi;
12743 else if (TARGET_STRING && bytes > 1)
12744 { /* move up to 4 bytes at a time */
12745 move_bytes = (bytes > 4) ? 4 : bytes;
12746 gen_func.movmemsi = gen_movmemsi_1reg;
12748 else /* move 1 byte at a time */
12750 move_bytes = 1;
12751 mode = QImode;
12752 gen_func.mov = gen_movqi;
12755 src = adjust_address (orig_src, mode, offset);
12756 dest = adjust_address (orig_dest, mode, offset);
12758 if (mode != BLKmode)
12760 rtx tmp_reg = gen_reg_rtx (mode);
12762 emit_insn ((*gen_func.mov) (tmp_reg, src));
12763 stores[num_reg++] = (*gen_func.mov) (dest, tmp_reg);
12766 if (mode == BLKmode || num_reg >= MAX_MOVE_REG || bytes == move_bytes)
12768 int i;
12769 for (i = 0; i < num_reg; i++)
12770 emit_insn (stores[i]);
12771 num_reg = 0;
12774 if (mode == BLKmode)
12776 /* Move the address into scratch registers. The movmemsi
12777 patterns require zero offset. */
12778 if (!REG_P (XEXP (src, 0)))
12780 rtx src_reg = copy_addr_to_reg (XEXP (src, 0));
12781 src = replace_equiv_address (src, src_reg);
12783 set_mem_size (src, GEN_INT (move_bytes));
12785 if (!REG_P (XEXP (dest, 0)))
12787 rtx dest_reg = copy_addr_to_reg (XEXP (dest, 0));
12788 dest = replace_equiv_address (dest, dest_reg);
12790 set_mem_size (dest, GEN_INT (move_bytes));
12792 emit_insn ((*gen_func.movmemsi) (dest, src,
12793 GEN_INT (move_bytes & 31),
12794 align_rtx));
12798 return 1;
12802 /* Return a string to perform a load_multiple operation.
12803 operands[0] is the vector.
12804 operands[1] is the source address.
12805 operands[2] is the first destination register. */
12807 const char *
12808 rs6000_output_load_multiple (rtx operands[3])
12810 /* We have to handle the case where the pseudo used to contain the address
12811 is assigned to one of the output registers. */
12812 int i, j;
12813 int words = XVECLEN (operands[0], 0);
12814 rtx xop[10];
12816 if (XVECLEN (operands[0], 0) == 1)
12817 return "{l|lwz} %2,0(%1)";
12819 for (i = 0; i < words; i++)
12820 if (refers_to_regno_p (REGNO (operands[2]) + i,
12821 REGNO (operands[2]) + i + 1, operands[1], 0))
12823 if (i == words-1)
12825 xop[0] = GEN_INT (4 * (words-1));
12826 xop[1] = operands[1];
12827 xop[2] = operands[2];
12828 output_asm_insn ("{lsi|lswi} %2,%1,%0\n\t{l|lwz} %1,%0(%1)", xop);
12829 return "";
12831 else if (i == 0)
12833 xop[0] = GEN_INT (4 * (words-1));
12834 xop[1] = operands[1];
12835 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + 1);
12836 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);
12837 return "";
12839 else
12841 for (j = 0; j < words; j++)
12842 if (j != i)
12844 xop[0] = GEN_INT (j * 4);
12845 xop[1] = operands[1];
12846 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + j);
12847 output_asm_insn ("{l|lwz} %2,%0(%1)", xop);
12849 xop[0] = GEN_INT (i * 4);
12850 xop[1] = operands[1];
12851 output_asm_insn ("{l|lwz} %1,%0(%1)", xop);
12852 return "";
12856 return "{lsi|lswi} %2,%1,%N0";
12860 /* A validation routine: say whether CODE, a condition code, and MODE
12861 match. The other alternatives either don't make sense or should
12862 never be generated. */
12864 void
12865 validate_condition_mode (enum rtx_code code, enum machine_mode mode)
12867 gcc_assert ((GET_RTX_CLASS (code) == RTX_COMPARE
12868 || GET_RTX_CLASS (code) == RTX_COMM_COMPARE)
12869 && GET_MODE_CLASS (mode) == MODE_CC);
12871 /* These don't make sense. */
12872 gcc_assert ((code != GT && code != LT && code != GE && code != LE)
12873 || mode != CCUNSmode);
12875 gcc_assert ((code != GTU && code != LTU && code != GEU && code != LEU)
12876 || mode == CCUNSmode);
12878 gcc_assert (mode == CCFPmode
12879 || (code != ORDERED && code != UNORDERED
12880 && code != UNEQ && code != LTGT
12881 && code != UNGT && code != UNLT
12882 && code != UNGE && code != UNLE));
12884 /* These should never be generated except for
12885 flag_finite_math_only. */
12886 gcc_assert (mode != CCFPmode
12887 || flag_finite_math_only
12888 || (code != LE && code != GE
12889 && code != UNEQ && code != LTGT
12890 && code != UNGT && code != UNLT));
12892 /* These are invalid; the information is not there. */
12893 gcc_assert (mode != CCEQmode || code == EQ || code == NE);
12897 /* Return 1 if ANDOP is a mask that has no bits on that are not in the
12898 mask required to convert the result of a rotate insn into a shift
12899 left insn of SHIFTOP bits. Both are known to be SImode CONST_INT. */
12902 includes_lshift_p (rtx shiftop, rtx andop)
12904 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
12906 shift_mask <<= INTVAL (shiftop);
12908 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
12911 /* Similar, but for right shift. */
12914 includes_rshift_p (rtx shiftop, rtx andop)
12916 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
12918 shift_mask >>= INTVAL (shiftop);
12920 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
12923 /* Return 1 if ANDOP is a mask suitable for use with an rldic insn
12924 to perform a left shift. It must have exactly SHIFTOP least
12925 significant 0's, then one or more 1's, then zero or more 0's. */
12928 includes_rldic_lshift_p (rtx shiftop, rtx andop)
12930 if (GET_CODE (andop) == CONST_INT)
12932 HOST_WIDE_INT c, lsb, shift_mask;
12934 c = INTVAL (andop);
12935 if (c == 0 || c == ~0)
12936 return 0;
12938 shift_mask = ~0;
12939 shift_mask <<= INTVAL (shiftop);
12941 /* Find the least significant one bit. */
12942 lsb = c & -c;
12944 /* It must coincide with the LSB of the shift mask. */
12945 if (-lsb != shift_mask)
12946 return 0;
12948 /* Invert to look for the next transition (if any). */
12949 c = ~c;
12951 /* Remove the low group of ones (originally low group of zeros). */
12952 c &= -lsb;
12954 /* Again find the lsb, and check we have all 1's above. */
12955 lsb = c & -c;
12956 return c == -lsb;
12958 else if (GET_CODE (andop) == CONST_DOUBLE
12959 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
12961 HOST_WIDE_INT low, high, lsb;
12962 HOST_WIDE_INT shift_mask_low, shift_mask_high;
12964 low = CONST_DOUBLE_LOW (andop);
12965 if (HOST_BITS_PER_WIDE_INT < 64)
12966 high = CONST_DOUBLE_HIGH (andop);
12968 if ((low == 0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == 0))
12969 || (low == ~0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0)))
12970 return 0;
12972 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
12974 shift_mask_high = ~0;
12975 if (INTVAL (shiftop) > 32)
12976 shift_mask_high <<= INTVAL (shiftop) - 32;
12978 lsb = high & -high;
12980 if (-lsb != shift_mask_high || INTVAL (shiftop) < 32)
12981 return 0;
12983 high = ~high;
12984 high &= -lsb;
12986 lsb = high & -high;
12987 return high == -lsb;
12990 shift_mask_low = ~0;
12991 shift_mask_low <<= INTVAL (shiftop);
12993 lsb = low & -low;
12995 if (-lsb != shift_mask_low)
12996 return 0;
12998 if (HOST_BITS_PER_WIDE_INT < 64)
12999 high = ~high;
13000 low = ~low;
13001 low &= -lsb;
13003 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
13005 lsb = high & -high;
13006 return high == -lsb;
13009 lsb = low & -low;
13010 return low == -lsb && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0);
13012 else
13013 return 0;
13016 /* Return 1 if ANDOP is a mask suitable for use with an rldicr insn
13017 to perform a left shift. It must have SHIFTOP or more least
13018 significant 0's, with the remainder of the word 1's. */
13021 includes_rldicr_lshift_p (rtx shiftop, rtx andop)
13023 if (GET_CODE (andop) == CONST_INT)
13025 HOST_WIDE_INT c, lsb, shift_mask;
13027 shift_mask = ~0;
13028 shift_mask <<= INTVAL (shiftop);
13029 c = INTVAL (andop);
13031 /* Find the least significant one bit. */
13032 lsb = c & -c;
13034 /* It must be covered by the shift mask.
13035 This test also rejects c == 0. */
13036 if ((lsb & shift_mask) == 0)
13037 return 0;
13039 /* Check we have all 1's above the transition, and reject all 1's. */
13040 return c == -lsb && lsb != 1;
13042 else if (GET_CODE (andop) == CONST_DOUBLE
13043 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
13045 HOST_WIDE_INT low, lsb, shift_mask_low;
13047 low = CONST_DOUBLE_LOW (andop);
13049 if (HOST_BITS_PER_WIDE_INT < 64)
13051 HOST_WIDE_INT high, shift_mask_high;
13053 high = CONST_DOUBLE_HIGH (andop);
13055 if (low == 0)
13057 shift_mask_high = ~0;
13058 if (INTVAL (shiftop) > 32)
13059 shift_mask_high <<= INTVAL (shiftop) - 32;
13061 lsb = high & -high;
13063 if ((lsb & shift_mask_high) == 0)
13064 return 0;
13066 return high == -lsb;
13068 if (high != ~0)
13069 return 0;
13072 shift_mask_low = ~0;
13073 shift_mask_low <<= INTVAL (shiftop);
13075 lsb = low & -low;
13077 if ((lsb & shift_mask_low) == 0)
13078 return 0;
13080 return low == -lsb && lsb != 1;
13082 else
13083 return 0;
13086 /* Return 1 if operands will generate a valid arguments to rlwimi
13087 instruction for insert with right shift in 64-bit mode. The mask may
13088 not start on the first bit or stop on the last bit because wrap-around
13089 effects of instruction do not correspond to semantics of RTL insn. */
13092 insvdi_rshift_rlwimi_p (rtx sizeop, rtx startop, rtx shiftop)
13094 if (INTVAL (startop) > 32
13095 && INTVAL (startop) < 64
13096 && INTVAL (sizeop) > 1
13097 && INTVAL (sizeop) + INTVAL (startop) < 64
13098 && INTVAL (shiftop) > 0
13099 && INTVAL (sizeop) + INTVAL (shiftop) < 32
13100 && (64 - (INTVAL (shiftop) & 63)) >= INTVAL (sizeop))
13101 return 1;
13103 return 0;
13106 /* Return 1 if REGNO (reg1) == REGNO (reg2) - 1 making them candidates
13107 for lfq and stfq insns iff the registers are hard registers. */
13110 registers_ok_for_quad_peep (rtx reg1, rtx reg2)
13112 /* We might have been passed a SUBREG. */
13113 if (GET_CODE (reg1) != REG || GET_CODE (reg2) != REG)
13114 return 0;
13116 /* We might have been passed non floating point registers. */
13117 if (!FP_REGNO_P (REGNO (reg1))
13118 || !FP_REGNO_P (REGNO (reg2)))
13119 return 0;
13121 return (REGNO (reg1) == REGNO (reg2) - 1);
13124 /* Return 1 if addr1 and addr2 are suitable for lfq or stfq insn.
13125 addr1 and addr2 must be in consecutive memory locations
13126 (addr2 == addr1 + 8). */
13129 mems_ok_for_quad_peep (rtx mem1, rtx mem2)
13131 rtx addr1, addr2;
13132 unsigned int reg1, reg2;
13133 int offset1, offset2;
13135 /* The mems cannot be volatile. */
13136 if (MEM_VOLATILE_P (mem1) || MEM_VOLATILE_P (mem2))
13137 return 0;
13139 addr1 = XEXP (mem1, 0);
13140 addr2 = XEXP (mem2, 0);
13142 /* Extract an offset (if used) from the first addr. */
13143 if (GET_CODE (addr1) == PLUS)
13145 /* If not a REG, return zero. */
13146 if (GET_CODE (XEXP (addr1, 0)) != REG)
13147 return 0;
13148 else
13150 reg1 = REGNO (XEXP (addr1, 0));
13151 /* The offset must be constant! */
13152 if (GET_CODE (XEXP (addr1, 1)) != CONST_INT)
13153 return 0;
13154 offset1 = INTVAL (XEXP (addr1, 1));
13157 else if (GET_CODE (addr1) != REG)
13158 return 0;
13159 else
13161 reg1 = REGNO (addr1);
13162 /* This was a simple (mem (reg)) expression. Offset is 0. */
13163 offset1 = 0;
13166 /* And now for the second addr. */
13167 if (GET_CODE (addr2) == PLUS)
13169 /* If not a REG, return zero. */
13170 if (GET_CODE (XEXP (addr2, 0)) != REG)
13171 return 0;
13172 else
13174 reg2 = REGNO (XEXP (addr2, 0));
13175 /* The offset must be constant. */
13176 if (GET_CODE (XEXP (addr2, 1)) != CONST_INT)
13177 return 0;
13178 offset2 = INTVAL (XEXP (addr2, 1));
13181 else if (GET_CODE (addr2) != REG)
13182 return 0;
13183 else
13185 reg2 = REGNO (addr2);
13186 /* This was a simple (mem (reg)) expression. Offset is 0. */
13187 offset2 = 0;
13190 /* Both of these must have the same base register. */
13191 if (reg1 != reg2)
13192 return 0;
13194 /* The offset for the second addr must be 8 more than the first addr. */
13195 if (offset2 != offset1 + 8)
13196 return 0;
13198 /* All the tests passed. addr1 and addr2 are valid for lfq or stfq
13199 instructions. */
13200 return 1;
13205 rs6000_secondary_memory_needed_rtx (enum machine_mode mode)
13207 static bool eliminated = false;
13208 rtx ret;
13210 if (mode != SDmode)
13211 ret = assign_stack_local (mode, GET_MODE_SIZE (mode), 0);
13212 else
13214 rtx mem = cfun->machine->sdmode_stack_slot;
13215 gcc_assert (mem != NULL_RTX);
13217 if (!eliminated)
13219 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
13220 cfun->machine->sdmode_stack_slot = mem;
13221 eliminated = true;
13223 ret = mem;
13226 if (TARGET_DEBUG_ADDR)
13228 fprintf (stderr, "\nrs6000_secondary_memory_needed_rtx, mode %s, rtx:\n",
13229 GET_MODE_NAME (mode));
13230 if (!ret)
13231 fprintf (stderr, "\tNULL_RTX\n");
13232 else
13233 debug_rtx (ret);
13236 return ret;
13239 static tree
13240 rs6000_check_sdmode (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
13242 /* Don't walk into types. */
13243 if (*tp == NULL_TREE || *tp == error_mark_node || TYPE_P (*tp))
13245 *walk_subtrees = 0;
13246 return NULL_TREE;
13249 switch (TREE_CODE (*tp))
13251 case VAR_DECL:
13252 case PARM_DECL:
13253 case FIELD_DECL:
13254 case RESULT_DECL:
13255 case SSA_NAME:
13256 case REAL_CST:
13257 case INDIRECT_REF:
13258 case ALIGN_INDIRECT_REF:
13259 case MISALIGNED_INDIRECT_REF:
13260 case VIEW_CONVERT_EXPR:
13261 if (TYPE_MODE (TREE_TYPE (*tp)) == SDmode)
13262 return *tp;
13263 break;
13264 default:
13265 break;
13268 return NULL_TREE;
13271 enum reload_reg_type {
13272 GPR_REGISTER_TYPE,
13273 VECTOR_REGISTER_TYPE,
13274 OTHER_REGISTER_TYPE
13277 static enum reload_reg_type
13278 rs6000_reload_register_type (enum reg_class rclass)
13280 switch (rclass)
13282 case GENERAL_REGS:
13283 case BASE_REGS:
13284 return GPR_REGISTER_TYPE;
13286 case FLOAT_REGS:
13287 case ALTIVEC_REGS:
13288 case VSX_REGS:
13289 return VECTOR_REGISTER_TYPE;
13291 default:
13292 return OTHER_REGISTER_TYPE;
13296 /* Inform reload about cases where moving X with a mode MODE to a register in
13297 RCLASS requires an extra scratch or immediate register. Return the class
13298 needed for the immediate register.
13300 For VSX and Altivec, we may need a register to convert sp+offset into
13301 reg+sp. */
13303 static enum reg_class
13304 rs6000_secondary_reload (bool in_p,
13305 rtx x,
13306 enum reg_class rclass,
13307 enum machine_mode mode,
13308 secondary_reload_info *sri)
13310 enum reg_class ret = ALL_REGS;
13311 enum insn_code icode;
13312 bool default_p = false;
13314 sri->icode = CODE_FOR_nothing;
13316 /* Convert vector loads and stores into gprs to use an additional base
13317 register. */
13318 icode = rs6000_vector_reload[mode][in_p != false];
13319 if (icode != CODE_FOR_nothing)
13321 ret = NO_REGS;
13322 sri->icode = CODE_FOR_nothing;
13323 sri->extra_cost = 0;
13325 if (GET_CODE (x) == MEM)
13327 rtx addr = XEXP (x, 0);
13329 /* Loads to and stores from gprs can do reg+offset, and wouldn't need
13330 an extra register in that case, but it would need an extra
13331 register if the addressing is reg+reg or (reg+reg)&(-16). */
13332 if (rclass == GENERAL_REGS || rclass == BASE_REGS)
13334 if (!legitimate_indirect_address_p (addr, false)
13335 && !rs6000_legitimate_offset_address_p (TImode, addr, false))
13337 sri->icode = icode;
13338 /* account for splitting the loads, and converting the
13339 address from reg+reg to reg. */
13340 sri->extra_cost = (((TARGET_64BIT) ? 3 : 5)
13341 + ((GET_CODE (addr) == AND) ? 1 : 0));
13344 /* Loads to and stores from vector registers can only do reg+reg
13345 addressing. Altivec registers can also do (reg+reg)&(-16). */
13346 else if (rclass == VSX_REGS || rclass == ALTIVEC_REGS
13347 || rclass == FLOAT_REGS || rclass == NO_REGS)
13349 if (!VECTOR_MEM_ALTIVEC_P (mode)
13350 && GET_CODE (addr) == AND
13351 && GET_CODE (XEXP (addr, 1)) == CONST_INT
13352 && INTVAL (XEXP (addr, 1)) == -16
13353 && (legitimate_indirect_address_p (XEXP (addr, 0), false)
13354 || legitimate_indexed_address_p (XEXP (addr, 0), false)))
13356 sri->icode = icode;
13357 sri->extra_cost = ((GET_CODE (XEXP (addr, 0)) == PLUS)
13358 ? 2 : 1);
13360 else if (!legitimate_indirect_address_p (addr, false)
13361 && (rclass == NO_REGS
13362 || !legitimate_indexed_address_p (addr, false)))
13364 sri->icode = icode;
13365 sri->extra_cost = 1;
13367 else
13368 icode = CODE_FOR_nothing;
13370 /* Any other loads, including to pseudo registers which haven't been
13371 assigned to a register yet, default to require a scratch
13372 register. */
13373 else
13375 sri->icode = icode;
13376 sri->extra_cost = 2;
13379 else if (REG_P (x))
13381 int regno = true_regnum (x);
13383 icode = CODE_FOR_nothing;
13384 if (regno < 0 || regno >= FIRST_PSEUDO_REGISTER)
13385 default_p = true;
13386 else
13388 enum reg_class xclass = REGNO_REG_CLASS (regno);
13389 enum reload_reg_type rtype1 = rs6000_reload_register_type (rclass);
13390 enum reload_reg_type rtype2 = rs6000_reload_register_type (xclass);
13392 /* If memory is needed, use default_secondary_reload to create the
13393 stack slot. */
13394 if (rtype1 != rtype2 || rtype1 == OTHER_REGISTER_TYPE)
13395 default_p = true;
13396 else
13397 ret = NO_REGS;
13400 else
13401 default_p = true;
13403 else
13404 default_p = true;
13406 if (default_p)
13407 ret = default_secondary_reload (in_p, x, rclass, mode, sri);
13409 gcc_assert (ret != ALL_REGS);
13411 if (TARGET_DEBUG_ADDR)
13413 fprintf (stderr,
13414 "\nrs6000_secondary_reload, return %s, in_p = %s, rclass = %s, "
13415 "mode = %s",
13416 reg_class_names[ret],
13417 in_p ? "true" : "false",
13418 reg_class_names[rclass],
13419 GET_MODE_NAME (mode));
13421 if (default_p)
13422 fprintf (stderr, ", default secondary reload");
13424 if (sri->icode != CODE_FOR_nothing)
13425 fprintf (stderr, ", reload func = %s, extra cost = %d\n",
13426 insn_data[sri->icode].name, sri->extra_cost);
13427 else
13428 fprintf (stderr, "\n");
13430 debug_rtx (x);
13433 return ret;
13436 /* Fixup reload addresses for Altivec or VSX loads/stores to change SP+offset
13437 to SP+reg addressing. */
13439 void
13440 rs6000_secondary_reload_inner (rtx reg, rtx mem, rtx scratch, bool store_p)
13442 int regno = true_regnum (reg);
13443 enum machine_mode mode = GET_MODE (reg);
13444 enum reg_class rclass;
13445 rtx addr;
13446 rtx and_op2 = NULL_RTX;
13447 rtx addr_op1;
13448 rtx addr_op2;
13449 rtx scratch_or_premodify = scratch;
13450 rtx and_rtx;
13451 rtx cc_clobber;
13453 if (TARGET_DEBUG_ADDR)
13455 fprintf (stderr, "\nrs6000_secondary_reload_inner, type = %s\n",
13456 store_p ? "store" : "load");
13457 fprintf (stderr, "reg:\n");
13458 debug_rtx (reg);
13459 fprintf (stderr, "mem:\n");
13460 debug_rtx (mem);
13461 fprintf (stderr, "scratch:\n");
13462 debug_rtx (scratch);
13465 gcc_assert (regno >= 0 && regno < FIRST_PSEUDO_REGISTER);
13466 gcc_assert (GET_CODE (mem) == MEM);
13467 rclass = REGNO_REG_CLASS (regno);
13468 addr = XEXP (mem, 0);
13470 switch (rclass)
13472 /* GPRs can handle reg + small constant, all other addresses need to use
13473 the scratch register. */
13474 case GENERAL_REGS:
13475 case BASE_REGS:
13476 if (GET_CODE (addr) == AND)
13478 and_op2 = XEXP (addr, 1);
13479 addr = XEXP (addr, 0);
13482 if (GET_CODE (addr) == PRE_MODIFY)
13484 scratch_or_premodify = XEXP (addr, 0);
13485 gcc_assert (REG_P (scratch_or_premodify));
13486 gcc_assert (GET_CODE (XEXP (addr, 1)) == PLUS);
13487 addr = XEXP (addr, 1);
13490 if (GET_CODE (addr) == PLUS
13491 && (!rs6000_legitimate_offset_address_p (TImode, addr, false)
13492 || and_op2 != NULL_RTX))
13494 addr_op1 = XEXP (addr, 0);
13495 addr_op2 = XEXP (addr, 1);
13496 gcc_assert (legitimate_indirect_address_p (addr_op1, false));
13498 if (!REG_P (addr_op2)
13499 && (GET_CODE (addr_op2) != CONST_INT
13500 || !satisfies_constraint_I (addr_op2)))
13502 if (TARGET_DEBUG_ADDR)
13504 fprintf (stderr,
13505 "\nMove plus addr to register %s, mode = %s: ",
13506 rs6000_reg_names[REGNO (scratch)],
13507 GET_MODE_NAME (mode));
13508 debug_rtx (addr_op2);
13510 rs6000_emit_move (scratch, addr_op2, Pmode);
13511 addr_op2 = scratch;
13514 emit_insn (gen_rtx_SET (VOIDmode,
13515 scratch_or_premodify,
13516 gen_rtx_PLUS (Pmode,
13517 addr_op1,
13518 addr_op2)));
13520 addr = scratch_or_premodify;
13521 scratch_or_premodify = scratch;
13523 else if (!legitimate_indirect_address_p (addr, false)
13524 && !rs6000_legitimate_offset_address_p (TImode, addr, false))
13526 if (TARGET_DEBUG_ADDR)
13528 fprintf (stderr, "\nMove addr to register %s, mode = %s: ",
13529 rs6000_reg_names[REGNO (scratch_or_premodify)],
13530 GET_MODE_NAME (mode));
13531 debug_rtx (addr);
13533 rs6000_emit_move (scratch_or_premodify, addr, Pmode);
13534 addr = scratch_or_premodify;
13535 scratch_or_premodify = scratch;
13537 break;
13539 /* Float/Altivec registers can only handle reg+reg addressing. Move
13540 other addresses into a scratch register. */
13541 case FLOAT_REGS:
13542 case VSX_REGS:
13543 case ALTIVEC_REGS:
13545 /* With float regs, we need to handle the AND ourselves, since we can't
13546 use the Altivec instruction with an implicit AND -16. Allow scalar
13547 loads to float registers to use reg+offset even if VSX. */
13548 if (GET_CODE (addr) == AND
13549 && (rclass != ALTIVEC_REGS || GET_MODE_SIZE (mode) != 16
13550 || GET_CODE (XEXP (addr, 1)) != CONST_INT
13551 || INTVAL (XEXP (addr, 1)) != -16
13552 || !VECTOR_MEM_ALTIVEC_P (mode)))
13554 and_op2 = XEXP (addr, 1);
13555 addr = XEXP (addr, 0);
13558 /* If we aren't using a VSX load, save the PRE_MODIFY register and use it
13559 as the address later. */
13560 if (GET_CODE (addr) == PRE_MODIFY
13561 && (!VECTOR_MEM_VSX_P (mode)
13562 || and_op2 != NULL_RTX
13563 || !legitimate_indexed_address_p (XEXP (addr, 1), false)))
13565 scratch_or_premodify = XEXP (addr, 0);
13566 gcc_assert (legitimate_indirect_address_p (scratch_or_premodify,
13567 false));
13568 gcc_assert (GET_CODE (XEXP (addr, 1)) == PLUS);
13569 addr = XEXP (addr, 1);
13572 if (legitimate_indirect_address_p (addr, false) /* reg */
13573 || legitimate_indexed_address_p (addr, false) /* reg+reg */
13574 || GET_CODE (addr) == PRE_MODIFY /* VSX pre-modify */
13575 || (GET_CODE (addr) == AND /* Altivec memory */
13576 && GET_CODE (XEXP (addr, 1)) == CONST_INT
13577 && INTVAL (XEXP (addr, 1)) == -16
13578 && VECTOR_MEM_ALTIVEC_P (mode))
13579 || (rclass == FLOAT_REGS /* legacy float mem */
13580 && GET_MODE_SIZE (mode) == 8
13581 && and_op2 == NULL_RTX
13582 && scratch_or_premodify == scratch
13583 && rs6000_legitimate_offset_address_p (mode, addr, false)))
13586 else if (GET_CODE (addr) == PLUS)
13588 addr_op1 = XEXP (addr, 0);
13589 addr_op2 = XEXP (addr, 1);
13590 gcc_assert (REG_P (addr_op1));
13592 if (TARGET_DEBUG_ADDR)
13594 fprintf (stderr, "\nMove plus addr to register %s, mode = %s: ",
13595 rs6000_reg_names[REGNO (scratch)], GET_MODE_NAME (mode));
13596 debug_rtx (addr_op2);
13598 rs6000_emit_move (scratch, addr_op2, Pmode);
13599 emit_insn (gen_rtx_SET (VOIDmode,
13600 scratch_or_premodify,
13601 gen_rtx_PLUS (Pmode,
13602 addr_op1,
13603 scratch)));
13604 addr = scratch_or_premodify;
13605 scratch_or_premodify = scratch;
13608 else if (GET_CODE (addr) == SYMBOL_REF || GET_CODE (addr) == CONST
13609 || GET_CODE (addr) == CONST_INT || REG_P (addr))
13611 if (TARGET_DEBUG_ADDR)
13613 fprintf (stderr, "\nMove addr to register %s, mode = %s: ",
13614 rs6000_reg_names[REGNO (scratch_or_premodify)],
13615 GET_MODE_NAME (mode));
13616 debug_rtx (addr);
13619 rs6000_emit_move (scratch_or_premodify, addr, Pmode);
13620 addr = scratch_or_premodify;
13621 scratch_or_premodify = scratch;
13624 else
13625 gcc_unreachable ();
13627 break;
13629 default:
13630 gcc_unreachable ();
13633 /* If the original address involved a pre-modify that we couldn't use the VSX
13634 memory instruction with update, and we haven't taken care of already,
13635 store the address in the pre-modify register and use that as the
13636 address. */
13637 if (scratch_or_premodify != scratch && scratch_or_premodify != addr)
13639 emit_insn (gen_rtx_SET (VOIDmode, scratch_or_premodify, addr));
13640 addr = scratch_or_premodify;
13643 /* If the original address involved an AND -16 and we couldn't use an ALTIVEC
13644 memory instruction, recreate the AND now, including the clobber which is
13645 generated by the general ANDSI3/ANDDI3 patterns for the
13646 andi. instruction. */
13647 if (and_op2 != NULL_RTX)
13649 if (! legitimate_indirect_address_p (addr, false))
13651 emit_insn (gen_rtx_SET (VOIDmode, scratch, addr));
13652 addr = scratch;
13655 if (TARGET_DEBUG_ADDR)
13657 fprintf (stderr, "\nAnd addr to register %s, mode = %s: ",
13658 rs6000_reg_names[REGNO (scratch)], GET_MODE_NAME (mode));
13659 debug_rtx (and_op2);
13662 and_rtx = gen_rtx_SET (VOIDmode,
13663 scratch,
13664 gen_rtx_AND (Pmode,
13665 addr,
13666 and_op2));
13668 cc_clobber = gen_rtx_CLOBBER (CCmode, gen_rtx_SCRATCH (CCmode));
13669 emit_insn (gen_rtx_PARALLEL (VOIDmode,
13670 gen_rtvec (2, and_rtx, cc_clobber)));
13671 addr = scratch;
13674 /* Adjust the address if it changed. */
13675 if (addr != XEXP (mem, 0))
13677 mem = change_address (mem, mode, addr);
13678 if (TARGET_DEBUG_ADDR)
13679 fprintf (stderr, "\nrs6000_secondary_reload_inner, mem adjusted.\n");
13682 /* Now create the move. */
13683 if (store_p)
13684 emit_insn (gen_rtx_SET (VOIDmode, mem, reg));
13685 else
13686 emit_insn (gen_rtx_SET (VOIDmode, reg, mem));
13688 return;
13691 /* Target hook to return the cover classes for Integrated Register Allocator.
13692 Cover classes is a set of non-intersected register classes covering all hard
13693 registers used for register allocation purpose. Any move between two
13694 registers of a cover class should be cheaper than load or store of the
13695 registers. The value is array of register classes with LIM_REG_CLASSES used
13696 as the end marker.
13698 We need two IRA_COVER_CLASSES, one for pre-VSX, and the other for VSX to
13699 account for the Altivec and Floating registers being subsets of the VSX
13700 register set under VSX, but distinct register sets on pre-VSX machines. */
13702 static const enum reg_class *
13703 rs6000_ira_cover_classes (void)
13705 static const enum reg_class cover_pre_vsx[] = IRA_COVER_CLASSES_PRE_VSX;
13706 static const enum reg_class cover_vsx[] = IRA_COVER_CLASSES_VSX;
13708 return (TARGET_VSX) ? cover_vsx : cover_pre_vsx;
13711 /* Allocate a 64-bit stack slot to be used for copying SDmode
13712 values through if this function has any SDmode references. */
13714 static void
13715 rs6000_alloc_sdmode_stack_slot (void)
13717 tree t;
13718 basic_block bb;
13719 gimple_stmt_iterator gsi;
13721 gcc_assert (cfun->machine->sdmode_stack_slot == NULL_RTX);
13723 FOR_EACH_BB (bb)
13724 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
13726 tree ret = walk_gimple_op (gsi_stmt (gsi), rs6000_check_sdmode, NULL);
13727 if (ret)
13729 rtx stack = assign_stack_local (DDmode, GET_MODE_SIZE (DDmode), 0);
13730 cfun->machine->sdmode_stack_slot = adjust_address_nv (stack,
13731 SDmode, 0);
13732 return;
13736 /* Check for any SDmode parameters of the function. */
13737 for (t = DECL_ARGUMENTS (cfun->decl); t; t = TREE_CHAIN (t))
13739 if (TREE_TYPE (t) == error_mark_node)
13740 continue;
13742 if (TYPE_MODE (TREE_TYPE (t)) == SDmode
13743 || TYPE_MODE (DECL_ARG_TYPE (t)) == SDmode)
13745 rtx stack = assign_stack_local (DDmode, GET_MODE_SIZE (DDmode), 0);
13746 cfun->machine->sdmode_stack_slot = adjust_address_nv (stack,
13747 SDmode, 0);
13748 return;
13753 static void
13754 rs6000_instantiate_decls (void)
13756 if (cfun->machine->sdmode_stack_slot != NULL_RTX)
13757 instantiate_decl_rtl (cfun->machine->sdmode_stack_slot);
13760 /* Given an rtx X being reloaded into a reg required to be
13761 in class CLASS, return the class of reg to actually use.
13762 In general this is just CLASS; but on some machines
13763 in some cases it is preferable to use a more restrictive class.
13765 On the RS/6000, we have to return NO_REGS when we want to reload a
13766 floating-point CONST_DOUBLE to force it to be copied to memory.
13768 We also don't want to reload integer values into floating-point
13769 registers if we can at all help it. In fact, this can
13770 cause reload to die, if it tries to generate a reload of CTR
13771 into a FP register and discovers it doesn't have the memory location
13772 required.
13774 ??? Would it be a good idea to have reload do the converse, that is
13775 try to reload floating modes into FP registers if possible?
13778 static enum reg_class
13779 rs6000_preferred_reload_class (rtx x, enum reg_class rclass)
13781 enum machine_mode mode = GET_MODE (x);
13783 if (VECTOR_UNIT_VSX_P (mode)
13784 && x == CONST0_RTX (mode) && VSX_REG_CLASS_P (rclass))
13785 return rclass;
13787 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode)
13788 && (rclass == ALTIVEC_REGS || rclass == VSX_REGS)
13789 && easy_vector_constant (x, mode))
13790 return ALTIVEC_REGS;
13792 if (CONSTANT_P (x) && reg_classes_intersect_p (rclass, FLOAT_REGS))
13793 return NO_REGS;
13795 if (GET_MODE_CLASS (mode) == MODE_INT && rclass == NON_SPECIAL_REGS)
13796 return GENERAL_REGS;
13798 /* For VSX, prefer the traditional registers for DF if the address is of the
13799 form reg+offset because we can use the non-VSX loads. Prefer the Altivec
13800 registers if Altivec is handling the vector operations (i.e. V16QI, V8HI,
13801 and V4SI). */
13802 if (rclass == VSX_REGS && VECTOR_MEM_VSX_P (mode))
13804 if (mode == DFmode && GET_CODE (x) == MEM)
13806 rtx addr = XEXP (x, 0);
13808 if (legitimate_indirect_address_p (addr, false)) /* reg */
13809 return VSX_REGS;
13811 if (legitimate_indexed_address_p (addr, false)) /* reg+reg */
13812 return VSX_REGS;
13814 if (GET_CODE (addr) == PRE_MODIFY
13815 && legitimate_indexed_address_p (XEXP (addr, 0), false))
13816 return VSX_REGS;
13818 return FLOAT_REGS;
13821 if (VECTOR_UNIT_ALTIVEC_P (mode))
13822 return ALTIVEC_REGS;
13824 return rclass;
13827 return rclass;
13830 /* Debug version of rs6000_preferred_reload_class. */
13831 static enum reg_class
13832 rs6000_debug_preferred_reload_class (rtx x, enum reg_class rclass)
13834 enum reg_class ret = rs6000_preferred_reload_class (x, rclass);
13836 fprintf (stderr,
13837 "\nrs6000_preferred_reload_class, return %s, rclass = %s, "
13838 "mode = %s, x:\n",
13839 reg_class_names[ret], reg_class_names[rclass],
13840 GET_MODE_NAME (GET_MODE (x)));
13841 debug_rtx (x);
13843 return ret;
13846 /* If we are copying between FP or AltiVec registers and anything else, we need
13847 a memory location. The exception is when we are targeting ppc64 and the
13848 move to/from fpr to gpr instructions are available. Also, under VSX, you
13849 can copy vector registers from the FP register set to the Altivec register
13850 set and vice versa. */
13852 static bool
13853 rs6000_secondary_memory_needed (enum reg_class class1,
13854 enum reg_class class2,
13855 enum machine_mode mode)
13857 if (class1 == class2)
13858 return false;
13860 /* Under VSX, there are 3 register classes that values could be in (VSX_REGS,
13861 ALTIVEC_REGS, and FLOAT_REGS). We don't need to use memory to copy
13862 between these classes. But we need memory for other things that can go in
13863 FLOAT_REGS like SFmode. */
13864 if (TARGET_VSX
13865 && (VECTOR_MEM_VSX_P (mode) || VECTOR_UNIT_VSX_P (mode))
13866 && (class1 == VSX_REGS || class1 == ALTIVEC_REGS
13867 || class1 == FLOAT_REGS))
13868 return (class2 != VSX_REGS && class2 != ALTIVEC_REGS
13869 && class2 != FLOAT_REGS);
13871 if (class1 == VSX_REGS || class2 == VSX_REGS)
13872 return true;
13874 if (class1 == FLOAT_REGS
13875 && (!TARGET_MFPGPR || !TARGET_POWERPC64
13876 || ((mode != DFmode)
13877 && (mode != DDmode)
13878 && (mode != DImode))))
13879 return true;
13881 if (class2 == FLOAT_REGS
13882 && (!TARGET_MFPGPR || !TARGET_POWERPC64
13883 || ((mode != DFmode)
13884 && (mode != DDmode)
13885 && (mode != DImode))))
13886 return true;
13888 if (class1 == ALTIVEC_REGS || class2 == ALTIVEC_REGS)
13889 return true;
13891 return false;
13894 /* Debug version of rs6000_secondary_memory_needed. */
13895 static bool
13896 rs6000_debug_secondary_memory_needed (enum reg_class class1,
13897 enum reg_class class2,
13898 enum machine_mode mode)
13900 bool ret = rs6000_secondary_memory_needed (class1, class2, mode);
13902 fprintf (stderr,
13903 "rs6000_secondary_memory_needed, return: %s, class1 = %s, "
13904 "class2 = %s, mode = %s\n",
13905 ret ? "true" : "false", reg_class_names[class1],
13906 reg_class_names[class2], GET_MODE_NAME (mode));
13908 return ret;
13911 /* Return the register class of a scratch register needed to copy IN into
13912 or out of a register in RCLASS in MODE. If it can be done directly,
13913 NO_REGS is returned. */
13915 static enum reg_class
13916 rs6000_secondary_reload_class (enum reg_class rclass, enum machine_mode mode,
13917 rtx in)
13919 int regno;
13921 if (TARGET_ELF || (DEFAULT_ABI == ABI_DARWIN
13922 #if TARGET_MACHO
13923 && MACHOPIC_INDIRECT
13924 #endif
13927 /* We cannot copy a symbolic operand directly into anything
13928 other than BASE_REGS for TARGET_ELF. So indicate that a
13929 register from BASE_REGS is needed as an intermediate
13930 register.
13932 On Darwin, pic addresses require a load from memory, which
13933 needs a base register. */
13934 if (rclass != BASE_REGS
13935 && (GET_CODE (in) == SYMBOL_REF
13936 || GET_CODE (in) == HIGH
13937 || GET_CODE (in) == LABEL_REF
13938 || GET_CODE (in) == CONST))
13939 return BASE_REGS;
13942 if (GET_CODE (in) == REG)
13944 regno = REGNO (in);
13945 if (regno >= FIRST_PSEUDO_REGISTER)
13947 regno = true_regnum (in);
13948 if (regno >= FIRST_PSEUDO_REGISTER)
13949 regno = -1;
13952 else if (GET_CODE (in) == SUBREG)
13954 regno = true_regnum (in);
13955 if (regno >= FIRST_PSEUDO_REGISTER)
13956 regno = -1;
13958 else
13959 regno = -1;
13961 /* We can place anything into GENERAL_REGS and can put GENERAL_REGS
13962 into anything. */
13963 if (rclass == GENERAL_REGS || rclass == BASE_REGS
13964 || (regno >= 0 && INT_REGNO_P (regno)))
13965 return NO_REGS;
13967 /* Constants, memory, and FP registers can go into FP registers. */
13968 if ((regno == -1 || FP_REGNO_P (regno))
13969 && (rclass == FLOAT_REGS || rclass == NON_SPECIAL_REGS))
13970 return (mode != SDmode) ? NO_REGS : GENERAL_REGS;
13972 /* Memory, and FP/altivec registers can go into fp/altivec registers under
13973 VSX. */
13974 if (TARGET_VSX
13975 && (regno == -1 || VSX_REGNO_P (regno))
13976 && VSX_REG_CLASS_P (rclass))
13977 return NO_REGS;
13979 /* Memory, and AltiVec registers can go into AltiVec registers. */
13980 if ((regno == -1 || ALTIVEC_REGNO_P (regno))
13981 && rclass == ALTIVEC_REGS)
13982 return NO_REGS;
13984 /* We can copy among the CR registers. */
13985 if ((rclass == CR_REGS || rclass == CR0_REGS)
13986 && regno >= 0 && CR_REGNO_P (regno))
13987 return NO_REGS;
13989 /* Otherwise, we need GENERAL_REGS. */
13990 return GENERAL_REGS;
13993 /* Debug version of rs6000_secondary_reload_class. */
13994 static enum reg_class
13995 rs6000_debug_secondary_reload_class (enum reg_class rclass,
13996 enum machine_mode mode, rtx in)
13998 enum reg_class ret = rs6000_secondary_reload_class (rclass, mode, in);
13999 fprintf (stderr,
14000 "\nrs6000_secondary_reload_class, return %s, rclass = %s, "
14001 "mode = %s, input rtx:\n",
14002 reg_class_names[ret], reg_class_names[rclass],
14003 GET_MODE_NAME (mode));
14004 debug_rtx (in);
14006 return ret;
14009 /* Return nonzero if for CLASS a mode change from FROM to TO is invalid. */
14011 static bool
14012 rs6000_cannot_change_mode_class (enum machine_mode from,
14013 enum machine_mode to,
14014 enum reg_class rclass)
14016 unsigned from_size = GET_MODE_SIZE (from);
14017 unsigned to_size = GET_MODE_SIZE (to);
14019 if (from_size != to_size)
14021 enum reg_class xclass = (TARGET_VSX) ? VSX_REGS : FLOAT_REGS;
14022 return ((from_size < 8 || to_size < 8 || TARGET_IEEEQUAD)
14023 && reg_classes_intersect_p (xclass, rclass));
14026 if (TARGET_E500_DOUBLE
14027 && ((((to) == DFmode) + ((from) == DFmode)) == 1
14028 || (((to) == TFmode) + ((from) == TFmode)) == 1
14029 || (((to) == DDmode) + ((from) == DDmode)) == 1
14030 || (((to) == TDmode) + ((from) == TDmode)) == 1
14031 || (((to) == DImode) + ((from) == DImode)) == 1))
14032 return true;
14034 /* Since the VSX register set includes traditional floating point registers
14035 and altivec registers, just check for the size being different instead of
14036 trying to check whether the modes are vector modes. Otherwise it won't
14037 allow say DF and DI to change classes. */
14038 if (TARGET_VSX && VSX_REG_CLASS_P (rclass))
14039 return (from_size != 8 && from_size != 16);
14041 if (TARGET_ALTIVEC && rclass == ALTIVEC_REGS
14042 && (ALTIVEC_VECTOR_MODE (from) + ALTIVEC_VECTOR_MODE (to)) == 1)
14043 return true;
14045 if (TARGET_SPE && (SPE_VECTOR_MODE (from) + SPE_VECTOR_MODE (to)) == 1
14046 && reg_classes_intersect_p (GENERAL_REGS, rclass))
14047 return true;
14049 return false;
14052 /* Debug version of rs6000_cannot_change_mode_class. */
14053 static bool
14054 rs6000_debug_cannot_change_mode_class (enum machine_mode from,
14055 enum machine_mode to,
14056 enum reg_class rclass)
14058 bool ret = rs6000_cannot_change_mode_class (from, to, rclass);
14060 fprintf (stderr,
14061 "rs6000_cannot_change_mode_class, return %s, from = %s, "
14062 "to = %s, rclass = %s\n",
14063 ret ? "true" : "false",
14064 GET_MODE_NAME (from), GET_MODE_NAME (to),
14065 reg_class_names[rclass]);
14067 return ret;
14070 /* Given a comparison operation, return the bit number in CCR to test. We
14071 know this is a valid comparison.
14073 SCC_P is 1 if this is for an scc. That means that %D will have been
14074 used instead of %C, so the bits will be in different places.
14076 Return -1 if OP isn't a valid comparison for some reason. */
14079 ccr_bit (rtx op, int scc_p)
14081 enum rtx_code code = GET_CODE (op);
14082 enum machine_mode cc_mode;
14083 int cc_regnum;
14084 int base_bit;
14085 rtx reg;
14087 if (!COMPARISON_P (op))
14088 return -1;
14090 reg = XEXP (op, 0);
14092 gcc_assert (GET_CODE (reg) == REG && CR_REGNO_P (REGNO (reg)));
14094 cc_mode = GET_MODE (reg);
14095 cc_regnum = REGNO (reg);
14096 base_bit = 4 * (cc_regnum - CR0_REGNO);
14098 validate_condition_mode (code, cc_mode);
14100 /* When generating a sCOND operation, only positive conditions are
14101 allowed. */
14102 gcc_assert (!scc_p
14103 || code == EQ || code == GT || code == LT || code == UNORDERED
14104 || code == GTU || code == LTU);
14106 switch (code)
14108 case NE:
14109 return scc_p ? base_bit + 3 : base_bit + 2;
14110 case EQ:
14111 return base_bit + 2;
14112 case GT: case GTU: case UNLE:
14113 return base_bit + 1;
14114 case LT: case LTU: case UNGE:
14115 return base_bit;
14116 case ORDERED: case UNORDERED:
14117 return base_bit + 3;
14119 case GE: case GEU:
14120 /* If scc, we will have done a cror to put the bit in the
14121 unordered position. So test that bit. For integer, this is ! LT
14122 unless this is an scc insn. */
14123 return scc_p ? base_bit + 3 : base_bit;
14125 case LE: case LEU:
14126 return scc_p ? base_bit + 3 : base_bit + 1;
14128 default:
14129 gcc_unreachable ();
14133 /* Return the GOT register. */
14136 rs6000_got_register (rtx value ATTRIBUTE_UNUSED)
14138 /* The second flow pass currently (June 1999) can't update
14139 regs_ever_live without disturbing other parts of the compiler, so
14140 update it here to make the prolog/epilogue code happy. */
14141 if (!can_create_pseudo_p ()
14142 && !df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM))
14143 df_set_regs_ever_live (RS6000_PIC_OFFSET_TABLE_REGNUM, true);
14145 crtl->uses_pic_offset_table = 1;
14147 return pic_offset_table_rtx;
14150 /* Function to init struct machine_function.
14151 This will be called, via a pointer variable,
14152 from push_function_context. */
14154 static struct machine_function *
14155 rs6000_init_machine_status (void)
14157 return GGC_CNEW (machine_function);
14160 /* These macros test for integers and extract the low-order bits. */
14161 #define INT_P(X) \
14162 ((GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST_DOUBLE) \
14163 && GET_MODE (X) == VOIDmode)
14165 #define INT_LOWPART(X) \
14166 (GET_CODE (X) == CONST_INT ? INTVAL (X) : CONST_DOUBLE_LOW (X))
14169 extract_MB (rtx op)
14171 int i;
14172 unsigned long val = INT_LOWPART (op);
14174 /* If the high bit is zero, the value is the first 1 bit we find
14175 from the left. */
14176 if ((val & 0x80000000) == 0)
14178 gcc_assert (val & 0xffffffff);
14180 i = 1;
14181 while (((val <<= 1) & 0x80000000) == 0)
14182 ++i;
14183 return i;
14186 /* If the high bit is set and the low bit is not, or the mask is all
14187 1's, the value is zero. */
14188 if ((val & 1) == 0 || (val & 0xffffffff) == 0xffffffff)
14189 return 0;
14191 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
14192 from the right. */
14193 i = 31;
14194 while (((val >>= 1) & 1) != 0)
14195 --i;
14197 return i;
14201 extract_ME (rtx op)
14203 int i;
14204 unsigned long val = INT_LOWPART (op);
14206 /* If the low bit is zero, the value is the first 1 bit we find from
14207 the right. */
14208 if ((val & 1) == 0)
14210 gcc_assert (val & 0xffffffff);
14212 i = 30;
14213 while (((val >>= 1) & 1) == 0)
14214 --i;
14216 return i;
14219 /* If the low bit is set and the high bit is not, or the mask is all
14220 1's, the value is 31. */
14221 if ((val & 0x80000000) == 0 || (val & 0xffffffff) == 0xffffffff)
14222 return 31;
14224 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
14225 from the left. */
14226 i = 0;
14227 while (((val <<= 1) & 0x80000000) != 0)
14228 ++i;
14230 return i;
14233 /* Locate some local-dynamic symbol still in use by this function
14234 so that we can print its name in some tls_ld pattern. */
14236 static const char *
14237 rs6000_get_some_local_dynamic_name (void)
14239 rtx insn;
14241 if (cfun->machine->some_ld_name)
14242 return cfun->machine->some_ld_name;
14244 for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
14245 if (INSN_P (insn)
14246 && for_each_rtx (&PATTERN (insn),
14247 rs6000_get_some_local_dynamic_name_1, 0))
14248 return cfun->machine->some_ld_name;
14250 gcc_unreachable ();
14253 /* Helper function for rs6000_get_some_local_dynamic_name. */
14255 static int
14256 rs6000_get_some_local_dynamic_name_1 (rtx *px, void *data ATTRIBUTE_UNUSED)
14258 rtx x = *px;
14260 if (GET_CODE (x) == SYMBOL_REF)
14262 const char *str = XSTR (x, 0);
14263 if (SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_DYNAMIC)
14265 cfun->machine->some_ld_name = str;
14266 return 1;
14270 return 0;
14273 /* Write out a function code label. */
14275 void
14276 rs6000_output_function_entry (FILE *file, const char *fname)
14278 if (fname[0] != '.')
14280 switch (DEFAULT_ABI)
14282 default:
14283 gcc_unreachable ();
14285 case ABI_AIX:
14286 if (DOT_SYMBOLS)
14287 putc ('.', file);
14288 else
14289 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "L.");
14290 break;
14292 case ABI_V4:
14293 case ABI_DARWIN:
14294 break;
14297 if (TARGET_AIX)
14298 RS6000_OUTPUT_BASENAME (file, fname);
14299 else
14300 assemble_name (file, fname);
14303 /* Print an operand. Recognize special options, documented below. */
14305 #if TARGET_ELF
14306 #define SMALL_DATA_RELOC ((rs6000_sdata == SDATA_EABI) ? "sda21" : "sdarel")
14307 #define SMALL_DATA_REG ((rs6000_sdata == SDATA_EABI) ? 0 : 13)
14308 #else
14309 #define SMALL_DATA_RELOC "sda21"
14310 #define SMALL_DATA_REG 0
14311 #endif
14313 void
14314 print_operand (FILE *file, rtx x, int code)
14316 int i;
14317 HOST_WIDE_INT val;
14318 unsigned HOST_WIDE_INT uval;
14320 switch (code)
14322 case '.':
14323 /* Write out an instruction after the call which may be replaced
14324 with glue code by the loader. This depends on the AIX version. */
14325 asm_fprintf (file, RS6000_CALL_GLUE);
14326 return;
14328 /* %a is output_address. */
14330 case 'A':
14331 /* If X is a constant integer whose low-order 5 bits are zero,
14332 write 'l'. Otherwise, write 'r'. This is a kludge to fix a bug
14333 in the AIX assembler where "sri" with a zero shift count
14334 writes a trash instruction. */
14335 if (GET_CODE (x) == CONST_INT && (INTVAL (x) & 31) == 0)
14336 putc ('l', file);
14337 else
14338 putc ('r', file);
14339 return;
14341 case 'b':
14342 /* If constant, low-order 16 bits of constant, unsigned.
14343 Otherwise, write normally. */
14344 if (INT_P (x))
14345 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 0xffff);
14346 else
14347 print_operand (file, x, 0);
14348 return;
14350 case 'B':
14351 /* If the low-order bit is zero, write 'r'; otherwise, write 'l'
14352 for 64-bit mask direction. */
14353 putc (((INT_LOWPART (x) & 1) == 0 ? 'r' : 'l'), file);
14354 return;
14356 /* %c is output_addr_const if a CONSTANT_ADDRESS_P, otherwise
14357 output_operand. */
14359 case 'c':
14360 /* X is a CR register. Print the number of the GT bit of the CR. */
14361 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
14362 output_operand_lossage ("invalid %%c value");
14363 else
14364 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 1);
14365 return;
14367 case 'D':
14368 /* Like 'J' but get to the GT bit only. */
14369 gcc_assert (GET_CODE (x) == REG);
14371 /* Bit 1 is GT bit. */
14372 i = 4 * (REGNO (x) - CR0_REGNO) + 1;
14374 /* Add one for shift count in rlinm for scc. */
14375 fprintf (file, "%d", i + 1);
14376 return;
14378 case 'E':
14379 /* X is a CR register. Print the number of the EQ bit of the CR */
14380 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
14381 output_operand_lossage ("invalid %%E value");
14382 else
14383 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 2);
14384 return;
14386 case 'f':
14387 /* X is a CR register. Print the shift count needed to move it
14388 to the high-order four bits. */
14389 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
14390 output_operand_lossage ("invalid %%f value");
14391 else
14392 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO));
14393 return;
14395 case 'F':
14396 /* Similar, but print the count for the rotate in the opposite
14397 direction. */
14398 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
14399 output_operand_lossage ("invalid %%F value");
14400 else
14401 fprintf (file, "%d", 32 - 4 * (REGNO (x) - CR0_REGNO));
14402 return;
14404 case 'G':
14405 /* X is a constant integer. If it is negative, print "m",
14406 otherwise print "z". This is to make an aze or ame insn. */
14407 if (GET_CODE (x) != CONST_INT)
14408 output_operand_lossage ("invalid %%G value");
14409 else if (INTVAL (x) >= 0)
14410 putc ('z', file);
14411 else
14412 putc ('m', file);
14413 return;
14415 case 'h':
14416 /* If constant, output low-order five bits. Otherwise, write
14417 normally. */
14418 if (INT_P (x))
14419 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 31);
14420 else
14421 print_operand (file, x, 0);
14422 return;
14424 case 'H':
14425 /* If constant, output low-order six bits. Otherwise, write
14426 normally. */
14427 if (INT_P (x))
14428 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 63);
14429 else
14430 print_operand (file, x, 0);
14431 return;
14433 case 'I':
14434 /* Print `i' if this is a constant, else nothing. */
14435 if (INT_P (x))
14436 putc ('i', file);
14437 return;
14439 case 'j':
14440 /* Write the bit number in CCR for jump. */
14441 i = ccr_bit (x, 0);
14442 if (i == -1)
14443 output_operand_lossage ("invalid %%j code");
14444 else
14445 fprintf (file, "%d", i);
14446 return;
14448 case 'J':
14449 /* Similar, but add one for shift count in rlinm for scc and pass
14450 scc flag to `ccr_bit'. */
14451 i = ccr_bit (x, 1);
14452 if (i == -1)
14453 output_operand_lossage ("invalid %%J code");
14454 else
14455 /* If we want bit 31, write a shift count of zero, not 32. */
14456 fprintf (file, "%d", i == 31 ? 0 : i + 1);
14457 return;
14459 case 'k':
14460 /* X must be a constant. Write the 1's complement of the
14461 constant. */
14462 if (! INT_P (x))
14463 output_operand_lossage ("invalid %%k value");
14464 else
14465 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ~ INT_LOWPART (x));
14466 return;
14468 case 'K':
14469 /* X must be a symbolic constant on ELF. Write an
14470 expression suitable for an 'addi' that adds in the low 16
14471 bits of the MEM. */
14472 if (GET_CODE (x) != CONST)
14474 print_operand_address (file, x);
14475 fputs ("@l", file);
14477 else
14479 if (GET_CODE (XEXP (x, 0)) != PLUS
14480 || (GET_CODE (XEXP (XEXP (x, 0), 0)) != SYMBOL_REF
14481 && GET_CODE (XEXP (XEXP (x, 0), 0)) != LABEL_REF)
14482 || GET_CODE (XEXP (XEXP (x, 0), 1)) != CONST_INT)
14483 output_operand_lossage ("invalid %%K value");
14484 print_operand_address (file, XEXP (XEXP (x, 0), 0));
14485 fputs ("@l", file);
14486 /* For GNU as, there must be a non-alphanumeric character
14487 between 'l' and the number. The '-' is added by
14488 print_operand() already. */
14489 if (INTVAL (XEXP (XEXP (x, 0), 1)) >= 0)
14490 fputs ("+", file);
14491 print_operand (file, XEXP (XEXP (x, 0), 1), 0);
14493 return;
14495 /* %l is output_asm_label. */
14497 case 'L':
14498 /* Write second word of DImode or DFmode reference. Works on register
14499 or non-indexed memory only. */
14500 if (GET_CODE (x) == REG)
14501 fputs (reg_names[REGNO (x) + 1], file);
14502 else if (GET_CODE (x) == MEM)
14504 /* Handle possible auto-increment. Since it is pre-increment and
14505 we have already done it, we can just use an offset of word. */
14506 if (GET_CODE (XEXP (x, 0)) == PRE_INC
14507 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
14508 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
14509 UNITS_PER_WORD));
14510 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
14511 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
14512 UNITS_PER_WORD));
14513 else
14514 output_address (XEXP (adjust_address_nv (x, SImode,
14515 UNITS_PER_WORD),
14516 0));
14518 if (small_data_operand (x, GET_MODE (x)))
14519 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
14520 reg_names[SMALL_DATA_REG]);
14522 return;
14524 case 'm':
14525 /* MB value for a mask operand. */
14526 if (! mask_operand (x, SImode))
14527 output_operand_lossage ("invalid %%m value");
14529 fprintf (file, "%d", extract_MB (x));
14530 return;
14532 case 'M':
14533 /* ME value for a mask operand. */
14534 if (! mask_operand (x, SImode))
14535 output_operand_lossage ("invalid %%M value");
14537 fprintf (file, "%d", extract_ME (x));
14538 return;
14540 /* %n outputs the negative of its operand. */
14542 case 'N':
14543 /* Write the number of elements in the vector times 4. */
14544 if (GET_CODE (x) != PARALLEL)
14545 output_operand_lossage ("invalid %%N value");
14546 else
14547 fprintf (file, "%d", XVECLEN (x, 0) * 4);
14548 return;
14550 case 'O':
14551 /* Similar, but subtract 1 first. */
14552 if (GET_CODE (x) != PARALLEL)
14553 output_operand_lossage ("invalid %%O value");
14554 else
14555 fprintf (file, "%d", (XVECLEN (x, 0) - 1) * 4);
14556 return;
14558 case 'p':
14559 /* X is a CONST_INT that is a power of two. Output the logarithm. */
14560 if (! INT_P (x)
14561 || INT_LOWPART (x) < 0
14562 || (i = exact_log2 (INT_LOWPART (x))) < 0)
14563 output_operand_lossage ("invalid %%p value");
14564 else
14565 fprintf (file, "%d", i);
14566 return;
14568 case 'P':
14569 /* The operand must be an indirect memory reference. The result
14570 is the register name. */
14571 if (GET_CODE (x) != MEM || GET_CODE (XEXP (x, 0)) != REG
14572 || REGNO (XEXP (x, 0)) >= 32)
14573 output_operand_lossage ("invalid %%P value");
14574 else
14575 fputs (reg_names[REGNO (XEXP (x, 0))], file);
14576 return;
14578 case 'q':
14579 /* This outputs the logical code corresponding to a boolean
14580 expression. The expression may have one or both operands
14581 negated (if one, only the first one). For condition register
14582 logical operations, it will also treat the negated
14583 CR codes as NOTs, but not handle NOTs of them. */
14585 const char *const *t = 0;
14586 const char *s;
14587 enum rtx_code code = GET_CODE (x);
14588 static const char * const tbl[3][3] = {
14589 { "and", "andc", "nor" },
14590 { "or", "orc", "nand" },
14591 { "xor", "eqv", "xor" } };
14593 if (code == AND)
14594 t = tbl[0];
14595 else if (code == IOR)
14596 t = tbl[1];
14597 else if (code == XOR)
14598 t = tbl[2];
14599 else
14600 output_operand_lossage ("invalid %%q value");
14602 if (GET_CODE (XEXP (x, 0)) != NOT)
14603 s = t[0];
14604 else
14606 if (GET_CODE (XEXP (x, 1)) == NOT)
14607 s = t[2];
14608 else
14609 s = t[1];
14612 fputs (s, file);
14614 return;
14616 case 'Q':
14617 if (TARGET_MFCRF)
14618 fputc (',', file);
14619 /* FALLTHRU */
14620 else
14621 return;
14623 case 'R':
14624 /* X is a CR register. Print the mask for `mtcrf'. */
14625 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
14626 output_operand_lossage ("invalid %%R value");
14627 else
14628 fprintf (file, "%d", 128 >> (REGNO (x) - CR0_REGNO));
14629 return;
14631 case 's':
14632 /* Low 5 bits of 32 - value */
14633 if (! INT_P (x))
14634 output_operand_lossage ("invalid %%s value");
14635 else
14636 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (32 - INT_LOWPART (x)) & 31);
14637 return;
14639 case 'S':
14640 /* PowerPC64 mask position. All 0's is excluded.
14641 CONST_INT 32-bit mask is considered sign-extended so any
14642 transition must occur within the CONST_INT, not on the boundary. */
14643 if (! mask64_operand (x, DImode))
14644 output_operand_lossage ("invalid %%S value");
14646 uval = INT_LOWPART (x);
14648 if (uval & 1) /* Clear Left */
14650 #if HOST_BITS_PER_WIDE_INT > 64
14651 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
14652 #endif
14653 i = 64;
14655 else /* Clear Right */
14657 uval = ~uval;
14658 #if HOST_BITS_PER_WIDE_INT > 64
14659 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
14660 #endif
14661 i = 63;
14663 while (uval != 0)
14664 --i, uval >>= 1;
14665 gcc_assert (i >= 0);
14666 fprintf (file, "%d", i);
14667 return;
14669 case 't':
14670 /* Like 'J' but get to the OVERFLOW/UNORDERED bit. */
14671 gcc_assert (GET_CODE (x) == REG && GET_MODE (x) == CCmode);
14673 /* Bit 3 is OV bit. */
14674 i = 4 * (REGNO (x) - CR0_REGNO) + 3;
14676 /* If we want bit 31, write a shift count of zero, not 32. */
14677 fprintf (file, "%d", i == 31 ? 0 : i + 1);
14678 return;
14680 case 'T':
14681 /* Print the symbolic name of a branch target register. */
14682 if (GET_CODE (x) != REG || (REGNO (x) != LR_REGNO
14683 && REGNO (x) != CTR_REGNO))
14684 output_operand_lossage ("invalid %%T value");
14685 else if (REGNO (x) == LR_REGNO)
14686 fputs (TARGET_NEW_MNEMONICS ? "lr" : "r", file);
14687 else
14688 fputs ("ctr", file);
14689 return;
14691 case 'u':
14692 /* High-order 16 bits of constant for use in unsigned operand. */
14693 if (! INT_P (x))
14694 output_operand_lossage ("invalid %%u value");
14695 else
14696 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
14697 (INT_LOWPART (x) >> 16) & 0xffff);
14698 return;
14700 case 'v':
14701 /* High-order 16 bits of constant for use in signed operand. */
14702 if (! INT_P (x))
14703 output_operand_lossage ("invalid %%v value");
14704 else
14705 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
14706 (INT_LOWPART (x) >> 16) & 0xffff);
14707 return;
14709 case 'U':
14710 /* Print `u' if this has an auto-increment or auto-decrement. */
14711 if (GET_CODE (x) == MEM
14712 && (GET_CODE (XEXP (x, 0)) == PRE_INC
14713 || GET_CODE (XEXP (x, 0)) == PRE_DEC
14714 || GET_CODE (XEXP (x, 0)) == PRE_MODIFY))
14715 putc ('u', file);
14716 return;
14718 case 'V':
14719 /* Print the trap code for this operand. */
14720 switch (GET_CODE (x))
14722 case EQ:
14723 fputs ("eq", file); /* 4 */
14724 break;
14725 case NE:
14726 fputs ("ne", file); /* 24 */
14727 break;
14728 case LT:
14729 fputs ("lt", file); /* 16 */
14730 break;
14731 case LE:
14732 fputs ("le", file); /* 20 */
14733 break;
14734 case GT:
14735 fputs ("gt", file); /* 8 */
14736 break;
14737 case GE:
14738 fputs ("ge", file); /* 12 */
14739 break;
14740 case LTU:
14741 fputs ("llt", file); /* 2 */
14742 break;
14743 case LEU:
14744 fputs ("lle", file); /* 6 */
14745 break;
14746 case GTU:
14747 fputs ("lgt", file); /* 1 */
14748 break;
14749 case GEU:
14750 fputs ("lge", file); /* 5 */
14751 break;
14752 default:
14753 gcc_unreachable ();
14755 break;
14757 case 'w':
14758 /* If constant, low-order 16 bits of constant, signed. Otherwise, write
14759 normally. */
14760 if (INT_P (x))
14761 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
14762 ((INT_LOWPART (x) & 0xffff) ^ 0x8000) - 0x8000);
14763 else
14764 print_operand (file, x, 0);
14765 return;
14767 case 'W':
14768 /* MB value for a PowerPC64 rldic operand. */
14769 val = (GET_CODE (x) == CONST_INT
14770 ? INTVAL (x) : CONST_DOUBLE_HIGH (x));
14772 if (val < 0)
14773 i = -1;
14774 else
14775 for (i = 0; i < HOST_BITS_PER_WIDE_INT; i++)
14776 if ((val <<= 1) < 0)
14777 break;
14779 #if HOST_BITS_PER_WIDE_INT == 32
14780 if (GET_CODE (x) == CONST_INT && i >= 0)
14781 i += 32; /* zero-extend high-part was all 0's */
14782 else if (GET_CODE (x) == CONST_DOUBLE && i == 32)
14784 val = CONST_DOUBLE_LOW (x);
14786 gcc_assert (val);
14787 if (val < 0)
14788 --i;
14789 else
14790 for ( ; i < 64; i++)
14791 if ((val <<= 1) < 0)
14792 break;
14794 #endif
14796 fprintf (file, "%d", i + 1);
14797 return;
14799 case 'x':
14800 /* X is a FPR or Altivec register used in a VSX context. */
14801 if (GET_CODE (x) != REG || !VSX_REGNO_P (REGNO (x)))
14802 output_operand_lossage ("invalid %%x value");
14803 else
14805 int reg = REGNO (x);
14806 int vsx_reg = (FP_REGNO_P (reg)
14807 ? reg - 32
14808 : reg - FIRST_ALTIVEC_REGNO + 32);
14810 #ifdef TARGET_REGNAMES
14811 if (TARGET_REGNAMES)
14812 fprintf (file, "%%vs%d", vsx_reg);
14813 else
14814 #endif
14815 fprintf (file, "%d", vsx_reg);
14817 return;
14819 case 'X':
14820 if (GET_CODE (x) == MEM
14821 && (legitimate_indexed_address_p (XEXP (x, 0), 0)
14822 || (GET_CODE (XEXP (x, 0)) == PRE_MODIFY
14823 && legitimate_indexed_address_p (XEXP (XEXP (x, 0), 1), 0))))
14824 putc ('x', file);
14825 return;
14827 case 'Y':
14828 /* Like 'L', for third word of TImode */
14829 if (GET_CODE (x) == REG)
14830 fputs (reg_names[REGNO (x) + 2], file);
14831 else if (GET_CODE (x) == MEM)
14833 if (GET_CODE (XEXP (x, 0)) == PRE_INC
14834 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
14835 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
14836 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
14837 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
14838 else
14839 output_address (XEXP (adjust_address_nv (x, SImode, 8), 0));
14840 if (small_data_operand (x, GET_MODE (x)))
14841 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
14842 reg_names[SMALL_DATA_REG]);
14844 return;
14846 case 'z':
14847 /* X is a SYMBOL_REF. Write out the name preceded by a
14848 period and without any trailing data in brackets. Used for function
14849 names. If we are configured for System V (or the embedded ABI) on
14850 the PowerPC, do not emit the period, since those systems do not use
14851 TOCs and the like. */
14852 gcc_assert (GET_CODE (x) == SYMBOL_REF);
14854 /* Mark the decl as referenced so that cgraph will output the
14855 function. */
14856 if (SYMBOL_REF_DECL (x))
14857 mark_decl_referenced (SYMBOL_REF_DECL (x));
14859 /* For macho, check to see if we need a stub. */
14860 if (TARGET_MACHO)
14862 const char *name = XSTR (x, 0);
14863 #if TARGET_MACHO
14864 if (MACHOPIC_INDIRECT
14865 && machopic_classify_symbol (x) == MACHOPIC_UNDEFINED_FUNCTION)
14866 name = machopic_indirection_name (x, /*stub_p=*/true);
14867 #endif
14868 assemble_name (file, name);
14870 else if (!DOT_SYMBOLS)
14871 assemble_name (file, XSTR (x, 0));
14872 else
14873 rs6000_output_function_entry (file, XSTR (x, 0));
14874 return;
14876 case 'Z':
14877 /* Like 'L', for last word of TImode. */
14878 if (GET_CODE (x) == REG)
14879 fputs (reg_names[REGNO (x) + 3], file);
14880 else if (GET_CODE (x) == MEM)
14882 if (GET_CODE (XEXP (x, 0)) == PRE_INC
14883 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
14884 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
14885 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
14886 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
14887 else
14888 output_address (XEXP (adjust_address_nv (x, SImode, 12), 0));
14889 if (small_data_operand (x, GET_MODE (x)))
14890 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
14891 reg_names[SMALL_DATA_REG]);
14893 return;
14895 /* Print AltiVec or SPE memory operand. */
14896 case 'y':
14898 rtx tmp;
14900 gcc_assert (GET_CODE (x) == MEM);
14902 tmp = XEXP (x, 0);
14904 /* Ugly hack because %y is overloaded. */
14905 if ((TARGET_SPE || TARGET_E500_DOUBLE)
14906 && (GET_MODE_SIZE (GET_MODE (x)) == 8
14907 || GET_MODE (x) == TFmode
14908 || GET_MODE (x) == TImode))
14910 /* Handle [reg]. */
14911 if (GET_CODE (tmp) == REG)
14913 fprintf (file, "0(%s)", reg_names[REGNO (tmp)]);
14914 break;
14916 /* Handle [reg+UIMM]. */
14917 else if (GET_CODE (tmp) == PLUS &&
14918 GET_CODE (XEXP (tmp, 1)) == CONST_INT)
14920 int x;
14922 gcc_assert (GET_CODE (XEXP (tmp, 0)) == REG);
14924 x = INTVAL (XEXP (tmp, 1));
14925 fprintf (file, "%d(%s)", x, reg_names[REGNO (XEXP (tmp, 0))]);
14926 break;
14929 /* Fall through. Must be [reg+reg]. */
14931 if (VECTOR_MEM_ALTIVEC_P (GET_MODE (x))
14932 && GET_CODE (tmp) == AND
14933 && GET_CODE (XEXP (tmp, 1)) == CONST_INT
14934 && INTVAL (XEXP (tmp, 1)) == -16)
14935 tmp = XEXP (tmp, 0);
14936 else if (VECTOR_MEM_VSX_P (GET_MODE (x))
14937 && GET_CODE (tmp) == PRE_MODIFY)
14938 tmp = XEXP (tmp, 1);
14939 if (GET_CODE (tmp) == REG)
14940 fprintf (file, "0,%s", reg_names[REGNO (tmp)]);
14941 else
14943 if (!GET_CODE (tmp) == PLUS
14944 || !REG_P (XEXP (tmp, 0))
14945 || !REG_P (XEXP (tmp, 1)))
14947 output_operand_lossage ("invalid %%y value, try using the 'Z' constraint");
14948 break;
14951 if (REGNO (XEXP (tmp, 0)) == 0)
14952 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 1)) ],
14953 reg_names[ REGNO (XEXP (tmp, 0)) ]);
14954 else
14955 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 0)) ],
14956 reg_names[ REGNO (XEXP (tmp, 1)) ]);
14958 break;
14961 case 0:
14962 if (GET_CODE (x) == REG)
14963 fprintf (file, "%s", reg_names[REGNO (x)]);
14964 else if (GET_CODE (x) == MEM)
14966 /* We need to handle PRE_INC and PRE_DEC here, since we need to
14967 know the width from the mode. */
14968 if (GET_CODE (XEXP (x, 0)) == PRE_INC)
14969 fprintf (file, "%d(%s)", GET_MODE_SIZE (GET_MODE (x)),
14970 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
14971 else if (GET_CODE (XEXP (x, 0)) == PRE_DEC)
14972 fprintf (file, "%d(%s)", - GET_MODE_SIZE (GET_MODE (x)),
14973 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
14974 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
14975 output_address (XEXP (XEXP (x, 0), 1));
14976 else
14977 output_address (XEXP (x, 0));
14979 else
14980 output_addr_const (file, x);
14981 return;
14983 case '&':
14984 assemble_name (file, rs6000_get_some_local_dynamic_name ());
14985 return;
14987 default:
14988 output_operand_lossage ("invalid %%xn code");
14992 /* Print the address of an operand. */
14994 void
14995 print_operand_address (FILE *file, rtx x)
14997 if (GET_CODE (x) == REG)
14998 fprintf (file, "0(%s)", reg_names[ REGNO (x) ]);
14999 else if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST
15000 || GET_CODE (x) == LABEL_REF)
15002 output_addr_const (file, x);
15003 if (small_data_operand (x, GET_MODE (x)))
15004 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
15005 reg_names[SMALL_DATA_REG]);
15006 else
15007 gcc_assert (!TARGET_TOC);
15009 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == REG)
15011 gcc_assert (REG_P (XEXP (x, 0)));
15012 if (REGNO (XEXP (x, 0)) == 0)
15013 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 1)) ],
15014 reg_names[ REGNO (XEXP (x, 0)) ]);
15015 else
15016 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 0)) ],
15017 reg_names[ REGNO (XEXP (x, 1)) ]);
15019 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == CONST_INT)
15020 fprintf (file, HOST_WIDE_INT_PRINT_DEC "(%s)",
15021 INTVAL (XEXP (x, 1)), reg_names[ REGNO (XEXP (x, 0)) ]);
15022 #if TARGET_ELF
15023 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
15024 && CONSTANT_P (XEXP (x, 1)))
15026 output_addr_const (file, XEXP (x, 1));
15027 fprintf (file, "@l(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
15029 #endif
15030 #if TARGET_MACHO
15031 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
15032 && CONSTANT_P (XEXP (x, 1)))
15034 fprintf (file, "lo16(");
15035 output_addr_const (file, XEXP (x, 1));
15036 fprintf (file, ")(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
15038 #endif
15039 else if (legitimate_constant_pool_address_p (x))
15041 output_addr_const (file, XEXP (x, 1));
15042 fprintf (file, "(%s)", reg_names[REGNO (XEXP (x, 0))]);
15044 else
15045 gcc_unreachable ();
15048 /* Implement OUTPUT_ADDR_CONST_EXTRA for address X. */
15050 bool
15051 rs6000_output_addr_const_extra (FILE *file, rtx x)
15053 if (GET_CODE (x) == UNSPEC)
15054 switch (XINT (x, 1))
15056 case UNSPEC_TOCREL:
15057 x = XVECEXP (x, 0, 0);
15058 gcc_assert (GET_CODE (x) == SYMBOL_REF);
15059 output_addr_const (file, x);
15060 if (!TARGET_AIX || (TARGET_ELF && TARGET_MINIMAL_TOC))
15062 putc ('-', file);
15063 assemble_name (file, toc_label_name);
15065 else if (TARGET_ELF)
15066 fputs ("@toc", file);
15067 return true;
15069 #if TARGET_MACHO
15070 case UNSPEC_MACHOPIC_OFFSET:
15071 output_addr_const (file, XVECEXP (x, 0, 0));
15072 putc ('-', file);
15073 machopic_output_function_base_name (file);
15074 return true;
15075 #endif
15077 return false;
15080 /* Target hook for assembling integer objects. The PowerPC version has
15081 to handle fixup entries for relocatable code if RELOCATABLE_NEEDS_FIXUP
15082 is defined. It also needs to handle DI-mode objects on 64-bit
15083 targets. */
15085 static bool
15086 rs6000_assemble_integer (rtx x, unsigned int size, int aligned_p)
15088 #ifdef RELOCATABLE_NEEDS_FIXUP
15089 /* Special handling for SI values. */
15090 if (RELOCATABLE_NEEDS_FIXUP && size == 4 && aligned_p)
15092 static int recurse = 0;
15094 /* For -mrelocatable, we mark all addresses that need to be fixed up
15095 in the .fixup section. */
15096 if (TARGET_RELOCATABLE
15097 && in_section != toc_section
15098 && in_section != text_section
15099 && !unlikely_text_section_p (in_section)
15100 && !recurse
15101 && GET_CODE (x) != CONST_INT
15102 && GET_CODE (x) != CONST_DOUBLE
15103 && CONSTANT_P (x))
15105 char buf[256];
15107 recurse = 1;
15108 ASM_GENERATE_INTERNAL_LABEL (buf, "LCP", fixuplabelno);
15109 fixuplabelno++;
15110 ASM_OUTPUT_LABEL (asm_out_file, buf);
15111 fprintf (asm_out_file, "\t.long\t(");
15112 output_addr_const (asm_out_file, x);
15113 fprintf (asm_out_file, ")@fixup\n");
15114 fprintf (asm_out_file, "\t.section\t\".fixup\",\"aw\"\n");
15115 ASM_OUTPUT_ALIGN (asm_out_file, 2);
15116 fprintf (asm_out_file, "\t.long\t");
15117 assemble_name (asm_out_file, buf);
15118 fprintf (asm_out_file, "\n\t.previous\n");
15119 recurse = 0;
15120 return true;
15122 /* Remove initial .'s to turn a -mcall-aixdesc function
15123 address into the address of the descriptor, not the function
15124 itself. */
15125 else if (GET_CODE (x) == SYMBOL_REF
15126 && XSTR (x, 0)[0] == '.'
15127 && DEFAULT_ABI == ABI_AIX)
15129 const char *name = XSTR (x, 0);
15130 while (*name == '.')
15131 name++;
15133 fprintf (asm_out_file, "\t.long\t%s\n", name);
15134 return true;
15137 #endif /* RELOCATABLE_NEEDS_FIXUP */
15138 return default_assemble_integer (x, size, aligned_p);
15141 #ifdef HAVE_GAS_HIDDEN
15142 /* Emit an assembler directive to set symbol visibility for DECL to
15143 VISIBILITY_TYPE. */
15145 static void
15146 rs6000_assemble_visibility (tree decl, int vis)
15148 /* Functions need to have their entry point symbol visibility set as
15149 well as their descriptor symbol visibility. */
15150 if (DEFAULT_ABI == ABI_AIX
15151 && DOT_SYMBOLS
15152 && TREE_CODE (decl) == FUNCTION_DECL)
15154 static const char * const visibility_types[] = {
15155 NULL, "internal", "hidden", "protected"
15158 const char *name, *type;
15160 name = ((* targetm.strip_name_encoding)
15161 (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))));
15162 type = visibility_types[vis];
15164 fprintf (asm_out_file, "\t.%s\t%s\n", type, name);
15165 fprintf (asm_out_file, "\t.%s\t.%s\n", type, name);
15167 else
15168 default_assemble_visibility (decl, vis);
15170 #endif
15172 enum rtx_code
15173 rs6000_reverse_condition (enum machine_mode mode, enum rtx_code code)
15175 /* Reversal of FP compares takes care -- an ordered compare
15176 becomes an unordered compare and vice versa. */
15177 if (mode == CCFPmode
15178 && (!flag_finite_math_only
15179 || code == UNLT || code == UNLE || code == UNGT || code == UNGE
15180 || code == UNEQ || code == LTGT))
15181 return reverse_condition_maybe_unordered (code);
15182 else
15183 return reverse_condition (code);
15186 /* Generate a compare for CODE. Return a brand-new rtx that
15187 represents the result of the compare. */
15189 static rtx
15190 rs6000_generate_compare (rtx cmp, enum machine_mode mode)
15192 enum machine_mode comp_mode;
15193 rtx compare_result;
15194 enum rtx_code code = GET_CODE (cmp);
15195 rtx op0 = XEXP (cmp, 0);
15196 rtx op1 = XEXP (cmp, 1);
15198 if (FLOAT_MODE_P (mode))
15199 comp_mode = CCFPmode;
15200 else if (code == GTU || code == LTU
15201 || code == GEU || code == LEU)
15202 comp_mode = CCUNSmode;
15203 else if ((code == EQ || code == NE)
15204 && GET_CODE (op0) == SUBREG
15205 && GET_CODE (op1) == SUBREG
15206 && SUBREG_PROMOTED_UNSIGNED_P (op0)
15207 && SUBREG_PROMOTED_UNSIGNED_P (op1))
15208 /* These are unsigned values, perhaps there will be a later
15209 ordering compare that can be shared with this one.
15210 Unfortunately we cannot detect the signedness of the operands
15211 for non-subregs. */
15212 comp_mode = CCUNSmode;
15213 else
15214 comp_mode = CCmode;
15216 /* First, the compare. */
15217 compare_result = gen_reg_rtx (comp_mode);
15219 /* E500 FP compare instructions on the GPRs. Yuck! */
15220 if ((!TARGET_FPRS && TARGET_HARD_FLOAT)
15221 && FLOAT_MODE_P (mode))
15223 rtx cmp, or_result, compare_result2;
15224 enum machine_mode op_mode = GET_MODE (op0);
15226 if (op_mode == VOIDmode)
15227 op_mode = GET_MODE (op1);
15229 /* The E500 FP compare instructions toggle the GT bit (CR bit 1) only.
15230 This explains the following mess. */
15232 switch (code)
15234 case EQ: case UNEQ: case NE: case LTGT:
15235 switch (op_mode)
15237 case SFmode:
15238 cmp = (flag_finite_math_only && !flag_trapping_math)
15239 ? gen_tstsfeq_gpr (compare_result, op0, op1)
15240 : gen_cmpsfeq_gpr (compare_result, op0, op1);
15241 break;
15243 case DFmode:
15244 cmp = (flag_finite_math_only && !flag_trapping_math)
15245 ? gen_tstdfeq_gpr (compare_result, op0, op1)
15246 : gen_cmpdfeq_gpr (compare_result, op0, op1);
15247 break;
15249 case TFmode:
15250 cmp = (flag_finite_math_only && !flag_trapping_math)
15251 ? gen_tsttfeq_gpr (compare_result, op0, op1)
15252 : gen_cmptfeq_gpr (compare_result, op0, op1);
15253 break;
15255 default:
15256 gcc_unreachable ();
15258 break;
15260 case GT: case GTU: case UNGT: case UNGE: case GE: case GEU:
15261 switch (op_mode)
15263 case SFmode:
15264 cmp = (flag_finite_math_only && !flag_trapping_math)
15265 ? gen_tstsfgt_gpr (compare_result, op0, op1)
15266 : gen_cmpsfgt_gpr (compare_result, op0, op1);
15267 break;
15269 case DFmode:
15270 cmp = (flag_finite_math_only && !flag_trapping_math)
15271 ? gen_tstdfgt_gpr (compare_result, op0, op1)
15272 : gen_cmpdfgt_gpr (compare_result, op0, op1);
15273 break;
15275 case TFmode:
15276 cmp = (flag_finite_math_only && !flag_trapping_math)
15277 ? gen_tsttfgt_gpr (compare_result, op0, op1)
15278 : gen_cmptfgt_gpr (compare_result, op0, op1);
15279 break;
15281 default:
15282 gcc_unreachable ();
15284 break;
15286 case LT: case LTU: case UNLT: case UNLE: case LE: case LEU:
15287 switch (op_mode)
15289 case SFmode:
15290 cmp = (flag_finite_math_only && !flag_trapping_math)
15291 ? gen_tstsflt_gpr (compare_result, op0, op1)
15292 : gen_cmpsflt_gpr (compare_result, op0, op1);
15293 break;
15295 case DFmode:
15296 cmp = (flag_finite_math_only && !flag_trapping_math)
15297 ? gen_tstdflt_gpr (compare_result, op0, op1)
15298 : gen_cmpdflt_gpr (compare_result, op0, op1);
15299 break;
15301 case TFmode:
15302 cmp = (flag_finite_math_only && !flag_trapping_math)
15303 ? gen_tsttflt_gpr (compare_result, op0, op1)
15304 : gen_cmptflt_gpr (compare_result, op0, op1);
15305 break;
15307 default:
15308 gcc_unreachable ();
15310 break;
15311 default:
15312 gcc_unreachable ();
15315 /* Synthesize LE and GE from LT/GT || EQ. */
15316 if (code == LE || code == GE || code == LEU || code == GEU)
15318 emit_insn (cmp);
15320 switch (code)
15322 case LE: code = LT; break;
15323 case GE: code = GT; break;
15324 case LEU: code = LT; break;
15325 case GEU: code = GT; break;
15326 default: gcc_unreachable ();
15329 compare_result2 = gen_reg_rtx (CCFPmode);
15331 /* Do the EQ. */
15332 switch (op_mode)
15334 case SFmode:
15335 cmp = (flag_finite_math_only && !flag_trapping_math)
15336 ? gen_tstsfeq_gpr (compare_result2, op0, op1)
15337 : gen_cmpsfeq_gpr (compare_result2, op0, op1);
15338 break;
15340 case DFmode:
15341 cmp = (flag_finite_math_only && !flag_trapping_math)
15342 ? gen_tstdfeq_gpr (compare_result2, op0, op1)
15343 : gen_cmpdfeq_gpr (compare_result2, op0, op1);
15344 break;
15346 case TFmode:
15347 cmp = (flag_finite_math_only && !flag_trapping_math)
15348 ? gen_tsttfeq_gpr (compare_result2, op0, op1)
15349 : gen_cmptfeq_gpr (compare_result2, op0, op1);
15350 break;
15352 default:
15353 gcc_unreachable ();
15355 emit_insn (cmp);
15357 /* OR them together. */
15358 or_result = gen_reg_rtx (CCFPmode);
15359 cmp = gen_e500_cr_ior_compare (or_result, compare_result,
15360 compare_result2);
15361 compare_result = or_result;
15362 code = EQ;
15364 else
15366 if (code == NE || code == LTGT)
15367 code = NE;
15368 else
15369 code = EQ;
15372 emit_insn (cmp);
15374 else
15376 /* Generate XLC-compatible TFmode compare as PARALLEL with extra
15377 CLOBBERs to match cmptf_internal2 pattern. */
15378 if (comp_mode == CCFPmode && TARGET_XL_COMPAT
15379 && GET_MODE (op0) == TFmode
15380 && !TARGET_IEEEQUAD
15381 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128)
15382 emit_insn (gen_rtx_PARALLEL (VOIDmode,
15383 gen_rtvec (9,
15384 gen_rtx_SET (VOIDmode,
15385 compare_result,
15386 gen_rtx_COMPARE (comp_mode, op0, op1)),
15387 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15388 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15389 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15390 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15391 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15392 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15393 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15394 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)))));
15395 else if (GET_CODE (op1) == UNSPEC
15396 && XINT (op1, 1) == UNSPEC_SP_TEST)
15398 rtx op1b = XVECEXP (op1, 0, 0);
15399 comp_mode = CCEQmode;
15400 compare_result = gen_reg_rtx (CCEQmode);
15401 if (TARGET_64BIT)
15402 emit_insn (gen_stack_protect_testdi (compare_result, op0, op1b));
15403 else
15404 emit_insn (gen_stack_protect_testsi (compare_result, op0, op1b));
15406 else
15407 emit_insn (gen_rtx_SET (VOIDmode, compare_result,
15408 gen_rtx_COMPARE (comp_mode, op0, op1)));
15411 /* Some kinds of FP comparisons need an OR operation;
15412 under flag_finite_math_only we don't bother. */
15413 if (FLOAT_MODE_P (mode)
15414 && !flag_finite_math_only
15415 && !(TARGET_HARD_FLOAT && !TARGET_FPRS)
15416 && (code == LE || code == GE
15417 || code == UNEQ || code == LTGT
15418 || code == UNGT || code == UNLT))
15420 enum rtx_code or1, or2;
15421 rtx or1_rtx, or2_rtx, compare2_rtx;
15422 rtx or_result = gen_reg_rtx (CCEQmode);
15424 switch (code)
15426 case LE: or1 = LT; or2 = EQ; break;
15427 case GE: or1 = GT; or2 = EQ; break;
15428 case UNEQ: or1 = UNORDERED; or2 = EQ; break;
15429 case LTGT: or1 = LT; or2 = GT; break;
15430 case UNGT: or1 = UNORDERED; or2 = GT; break;
15431 case UNLT: or1 = UNORDERED; or2 = LT; break;
15432 default: gcc_unreachable ();
15434 validate_condition_mode (or1, comp_mode);
15435 validate_condition_mode (or2, comp_mode);
15436 or1_rtx = gen_rtx_fmt_ee (or1, SImode, compare_result, const0_rtx);
15437 or2_rtx = gen_rtx_fmt_ee (or2, SImode, compare_result, const0_rtx);
15438 compare2_rtx = gen_rtx_COMPARE (CCEQmode,
15439 gen_rtx_IOR (SImode, or1_rtx, or2_rtx),
15440 const_true_rtx);
15441 emit_insn (gen_rtx_SET (VOIDmode, or_result, compare2_rtx));
15443 compare_result = or_result;
15444 code = EQ;
15447 validate_condition_mode (code, GET_MODE (compare_result));
15449 return gen_rtx_fmt_ee (code, VOIDmode, compare_result, const0_rtx);
15453 /* Emit the RTL for an sCOND pattern. */
15455 void
15456 rs6000_emit_sISEL (enum machine_mode mode, rtx operands[])
15458 rtx condition_rtx;
15459 enum machine_mode op_mode;
15460 enum rtx_code cond_code;
15461 rtx result = operands[0];
15463 condition_rtx = rs6000_generate_compare (operands[1], mode);
15464 cond_code = GET_CODE (condition_rtx);
15466 op_mode = GET_MODE (XEXP (operands[1], 0));
15467 if (op_mode == VOIDmode)
15468 op_mode = GET_MODE (XEXP (operands[1], 1));
15470 if (TARGET_POWERPC64 && GET_MODE (result) == DImode)
15472 PUT_MODE (condition_rtx, DImode);
15473 if (cond_code == GEU || cond_code == GTU || cond_code == LEU
15474 || cond_code == LTU)
15475 emit_insn (gen_isel_unsigned_di (result, condition_rtx,
15476 force_reg (DImode, const1_rtx),
15477 force_reg (DImode, const0_rtx),
15478 XEXP (condition_rtx, 0)));
15479 else
15480 emit_insn (gen_isel_signed_di (result, condition_rtx,
15481 force_reg (DImode, const1_rtx),
15482 force_reg (DImode, const0_rtx),
15483 XEXP (condition_rtx, 0)));
15485 else
15487 PUT_MODE (condition_rtx, SImode);
15488 if (cond_code == GEU || cond_code == GTU || cond_code == LEU
15489 || cond_code == LTU)
15490 emit_insn (gen_isel_unsigned_si (result, condition_rtx,
15491 force_reg (SImode, const1_rtx),
15492 force_reg (SImode, const0_rtx),
15493 XEXP (condition_rtx, 0)));
15494 else
15495 emit_insn (gen_isel_signed_si (result, condition_rtx,
15496 force_reg (SImode, const1_rtx),
15497 force_reg (SImode, const0_rtx),
15498 XEXP (condition_rtx, 0)));
15502 void
15503 rs6000_emit_sCOND (enum machine_mode mode, rtx operands[])
15505 rtx condition_rtx;
15506 enum machine_mode op_mode;
15507 enum rtx_code cond_code;
15508 rtx result = operands[0];
15510 if (TARGET_ISEL && (mode == SImode || mode == DImode))
15512 rs6000_emit_sISEL (mode, operands);
15513 return;
15516 condition_rtx = rs6000_generate_compare (operands[1], mode);
15517 cond_code = GET_CODE (condition_rtx);
15519 if (FLOAT_MODE_P (mode)
15520 && !TARGET_FPRS && TARGET_HARD_FLOAT)
15522 rtx t;
15524 PUT_MODE (condition_rtx, SImode);
15525 t = XEXP (condition_rtx, 0);
15527 gcc_assert (cond_code == NE || cond_code == EQ);
15529 if (cond_code == NE)
15530 emit_insn (gen_e500_flip_gt_bit (t, t));
15532 emit_insn (gen_move_from_CR_gt_bit (result, t));
15533 return;
15536 if (cond_code == NE
15537 || cond_code == GE || cond_code == LE
15538 || cond_code == GEU || cond_code == LEU
15539 || cond_code == ORDERED || cond_code == UNGE || cond_code == UNLE)
15541 rtx not_result = gen_reg_rtx (CCEQmode);
15542 rtx not_op, rev_cond_rtx;
15543 enum machine_mode cc_mode;
15545 cc_mode = GET_MODE (XEXP (condition_rtx, 0));
15547 rev_cond_rtx = gen_rtx_fmt_ee (rs6000_reverse_condition (cc_mode, cond_code),
15548 SImode, XEXP (condition_rtx, 0), const0_rtx);
15549 not_op = gen_rtx_COMPARE (CCEQmode, rev_cond_rtx, const0_rtx);
15550 emit_insn (gen_rtx_SET (VOIDmode, not_result, not_op));
15551 condition_rtx = gen_rtx_EQ (VOIDmode, not_result, const0_rtx);
15554 op_mode = GET_MODE (XEXP (operands[1], 0));
15555 if (op_mode == VOIDmode)
15556 op_mode = GET_MODE (XEXP (operands[1], 1));
15558 if (TARGET_POWERPC64 && (op_mode == DImode || FLOAT_MODE_P (mode)))
15560 PUT_MODE (condition_rtx, DImode);
15561 convert_move (result, condition_rtx, 0);
15563 else
15565 PUT_MODE (condition_rtx, SImode);
15566 emit_insn (gen_rtx_SET (VOIDmode, result, condition_rtx));
15570 /* Emit a branch of kind CODE to location LOC. */
15572 void
15573 rs6000_emit_cbranch (enum machine_mode mode, rtx operands[])
15575 rtx condition_rtx, loc_ref;
15577 condition_rtx = rs6000_generate_compare (operands[0], mode);
15578 loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands[3]);
15579 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
15580 gen_rtx_IF_THEN_ELSE (VOIDmode, condition_rtx,
15581 loc_ref, pc_rtx)));
15584 /* Return the string to output a conditional branch to LABEL, which is
15585 the operand number of the label, or -1 if the branch is really a
15586 conditional return.
15588 OP is the conditional expression. XEXP (OP, 0) is assumed to be a
15589 condition code register and its mode specifies what kind of
15590 comparison we made.
15592 REVERSED is nonzero if we should reverse the sense of the comparison.
15594 INSN is the insn. */
15596 char *
15597 output_cbranch (rtx op, const char *label, int reversed, rtx insn)
15599 static char string[64];
15600 enum rtx_code code = GET_CODE (op);
15601 rtx cc_reg = XEXP (op, 0);
15602 enum machine_mode mode = GET_MODE (cc_reg);
15603 int cc_regno = REGNO (cc_reg) - CR0_REGNO;
15604 int need_longbranch = label != NULL && get_attr_length (insn) == 8;
15605 int really_reversed = reversed ^ need_longbranch;
15606 char *s = string;
15607 const char *ccode;
15608 const char *pred;
15609 rtx note;
15611 validate_condition_mode (code, mode);
15613 /* Work out which way this really branches. We could use
15614 reverse_condition_maybe_unordered here always but this
15615 makes the resulting assembler clearer. */
15616 if (really_reversed)
15618 /* Reversal of FP compares takes care -- an ordered compare
15619 becomes an unordered compare and vice versa. */
15620 if (mode == CCFPmode)
15621 code = reverse_condition_maybe_unordered (code);
15622 else
15623 code = reverse_condition (code);
15626 if ((!TARGET_FPRS && TARGET_HARD_FLOAT) && mode == CCFPmode)
15628 /* The efscmp/tst* instructions twiddle bit 2, which maps nicely
15629 to the GT bit. */
15630 switch (code)
15632 case EQ:
15633 /* Opposite of GT. */
15634 code = GT;
15635 break;
15637 case NE:
15638 code = UNLE;
15639 break;
15641 default:
15642 gcc_unreachable ();
15646 switch (code)
15648 /* Not all of these are actually distinct opcodes, but
15649 we distinguish them for clarity of the resulting assembler. */
15650 case NE: case LTGT:
15651 ccode = "ne"; break;
15652 case EQ: case UNEQ:
15653 ccode = "eq"; break;
15654 case GE: case GEU:
15655 ccode = "ge"; break;
15656 case GT: case GTU: case UNGT:
15657 ccode = "gt"; break;
15658 case LE: case LEU:
15659 ccode = "le"; break;
15660 case LT: case LTU: case UNLT:
15661 ccode = "lt"; break;
15662 case UNORDERED: ccode = "un"; break;
15663 case ORDERED: ccode = "nu"; break;
15664 case UNGE: ccode = "nl"; break;
15665 case UNLE: ccode = "ng"; break;
15666 default:
15667 gcc_unreachable ();
15670 /* Maybe we have a guess as to how likely the branch is.
15671 The old mnemonics don't have a way to specify this information. */
15672 pred = "";
15673 note = find_reg_note (insn, REG_BR_PROB, NULL_RTX);
15674 if (note != NULL_RTX)
15676 /* PROB is the difference from 50%. */
15677 int prob = INTVAL (XEXP (note, 0)) - REG_BR_PROB_BASE / 2;
15679 /* Only hint for highly probable/improbable branches on newer
15680 cpus as static prediction overrides processor dynamic
15681 prediction. For older cpus we may as well always hint, but
15682 assume not taken for branches that are very close to 50% as a
15683 mispredicted taken branch is more expensive than a
15684 mispredicted not-taken branch. */
15685 if (rs6000_always_hint
15686 || (abs (prob) > REG_BR_PROB_BASE / 100 * 48
15687 && br_prob_note_reliable_p (note)))
15689 if (abs (prob) > REG_BR_PROB_BASE / 20
15690 && ((prob > 0) ^ need_longbranch))
15691 pred = "+";
15692 else
15693 pred = "-";
15697 if (label == NULL)
15698 s += sprintf (s, "{b%sr|b%slr%s} ", ccode, ccode, pred);
15699 else
15700 s += sprintf (s, "{b%s|b%s%s} ", ccode, ccode, pred);
15702 /* We need to escape any '%' characters in the reg_names string.
15703 Assume they'd only be the first character.... */
15704 if (reg_names[cc_regno + CR0_REGNO][0] == '%')
15705 *s++ = '%';
15706 s += sprintf (s, "%s", reg_names[cc_regno + CR0_REGNO]);
15708 if (label != NULL)
15710 /* If the branch distance was too far, we may have to use an
15711 unconditional branch to go the distance. */
15712 if (need_longbranch)
15713 s += sprintf (s, ",$+8\n\tb %s", label);
15714 else
15715 s += sprintf (s, ",%s", label);
15718 return string;
15721 /* Return the string to flip the GT bit on a CR. */
15722 char *
15723 output_e500_flip_gt_bit (rtx dst, rtx src)
15725 static char string[64];
15726 int a, b;
15728 gcc_assert (GET_CODE (dst) == REG && CR_REGNO_P (REGNO (dst))
15729 && GET_CODE (src) == REG && CR_REGNO_P (REGNO (src)));
15731 /* GT bit. */
15732 a = 4 * (REGNO (dst) - CR0_REGNO) + 1;
15733 b = 4 * (REGNO (src) - CR0_REGNO) + 1;
15735 sprintf (string, "crnot %d,%d", a, b);
15736 return string;
15739 /* Return insn for VSX or Altivec comparisons. */
15741 static rtx
15742 rs6000_emit_vector_compare_inner (enum rtx_code code, rtx op0, rtx op1)
15744 rtx mask;
15745 enum machine_mode mode = GET_MODE (op0);
15747 switch (code)
15749 default:
15750 break;
15752 case GE:
15753 if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
15754 return NULL_RTX;
15756 case EQ:
15757 case GT:
15758 case GTU:
15759 mask = gen_reg_rtx (mode);
15760 emit_insn (gen_rtx_SET (VOIDmode,
15761 mask,
15762 gen_rtx_fmt_ee (code, mode, op0, op1)));
15763 return mask;
15766 return NULL_RTX;
15769 /* Emit vector compare for operands OP0 and OP1 using code RCODE.
15770 DMODE is expected destination mode. This is a recursive function. */
15772 static rtx
15773 rs6000_emit_vector_compare (enum rtx_code rcode,
15774 rtx op0, rtx op1,
15775 enum machine_mode dmode)
15777 rtx mask;
15778 bool swap_operands = false;
15779 bool try_again = false;
15781 gcc_assert (VECTOR_UNIT_ALTIVEC_OR_VSX_P (dmode));
15782 gcc_assert (GET_MODE (op0) == GET_MODE (op1));
15784 /* See if the comparison works as is. */
15785 mask = rs6000_emit_vector_compare_inner (rcode, op0, op1);
15786 if (mask)
15787 return mask;
15789 switch (rcode)
15791 case LT:
15792 rcode = GT;
15793 swap_operands = true;
15794 try_again = true;
15795 break;
15796 case LTU:
15797 rcode = GTU;
15798 swap_operands = true;
15799 try_again = true;
15800 break;
15801 case NE:
15802 case UNLE:
15803 case UNLT:
15804 case UNGE:
15805 case UNGT:
15806 /* Invert condition and try again.
15807 e.g., A != B becomes ~(A==B). */
15809 enum rtx_code rev_code;
15810 enum insn_code nor_code;
15811 rtx mask2;
15813 rev_code = reverse_condition_maybe_unordered (rcode);
15814 if (rev_code == UNKNOWN)
15815 return NULL_RTX;
15817 nor_code = optab_handler (one_cmpl_optab, (int)dmode)->insn_code;
15818 if (nor_code == CODE_FOR_nothing)
15819 return NULL_RTX;
15821 mask2 = rs6000_emit_vector_compare (rev_code, op0, op1, dmode);
15822 if (!mask2)
15823 return NULL_RTX;
15825 mask = gen_reg_rtx (dmode);
15826 emit_insn (GEN_FCN (nor_code) (mask, mask2));
15827 return mask;
15829 break;
15830 case GE:
15831 case GEU:
15832 case LE:
15833 case LEU:
15834 /* Try GT/GTU/LT/LTU OR EQ */
15836 rtx c_rtx, eq_rtx;
15837 enum insn_code ior_code;
15838 enum rtx_code new_code;
15840 switch (rcode)
15842 case GE:
15843 new_code = GT;
15844 break;
15846 case GEU:
15847 new_code = GTU;
15848 break;
15850 case LE:
15851 new_code = LT;
15852 break;
15854 case LEU:
15855 new_code = LTU;
15856 break;
15858 default:
15859 gcc_unreachable ();
15862 ior_code = optab_handler (ior_optab, (int)dmode)->insn_code;
15863 if (ior_code == CODE_FOR_nothing)
15864 return NULL_RTX;
15866 c_rtx = rs6000_emit_vector_compare (new_code, op0, op1, dmode);
15867 if (!c_rtx)
15868 return NULL_RTX;
15870 eq_rtx = rs6000_emit_vector_compare (EQ, op0, op1, dmode);
15871 if (!eq_rtx)
15872 return NULL_RTX;
15874 mask = gen_reg_rtx (dmode);
15875 emit_insn (GEN_FCN (ior_code) (mask, c_rtx, eq_rtx));
15876 return mask;
15878 break;
15879 default:
15880 return NULL_RTX;
15883 if (try_again)
15885 if (swap_operands)
15887 rtx tmp;
15888 tmp = op0;
15889 op0 = op1;
15890 op1 = tmp;
15893 mask = rs6000_emit_vector_compare_inner (rcode, op0, op1);
15894 if (mask)
15895 return mask;
15898 /* You only get two chances. */
15899 return NULL_RTX;
15902 /* Emit vector conditional expression. DEST is destination. OP_TRUE and
15903 OP_FALSE are two VEC_COND_EXPR operands. CC_OP0 and CC_OP1 are the two
15904 operands for the relation operation COND. */
15907 rs6000_emit_vector_cond_expr (rtx dest, rtx op_true, rtx op_false,
15908 rtx cond, rtx cc_op0, rtx cc_op1)
15910 enum machine_mode dest_mode = GET_MODE (dest);
15911 enum rtx_code rcode = GET_CODE (cond);
15912 enum machine_mode cc_mode = CCmode;
15913 rtx mask;
15914 rtx cond2;
15915 rtx tmp;
15916 bool invert_move = false;
15918 if (VECTOR_UNIT_NONE_P (dest_mode))
15919 return 0;
15921 switch (rcode)
15923 /* Swap operands if we can, and fall back to doing the operation as
15924 specified, and doing a NOR to invert the test. */
15925 case NE:
15926 case UNLE:
15927 case UNLT:
15928 case UNGE:
15929 case UNGT:
15930 /* Invert condition and try again.
15931 e.g., A = (B != C) ? D : E becomes A = (B == C) ? E : D. */
15932 invert_move = true;
15933 rcode = reverse_condition_maybe_unordered (rcode);
15934 if (rcode == UNKNOWN)
15935 return 0;
15936 break;
15938 /* Mark unsigned tests with CCUNSmode. */
15939 case GTU:
15940 case GEU:
15941 case LTU:
15942 case LEU:
15943 cc_mode = CCUNSmode;
15944 break;
15946 default:
15947 break;
15950 /* Get the vector mask for the given relational operations. */
15951 mask = rs6000_emit_vector_compare (rcode, cc_op0, cc_op1, dest_mode);
15953 if (!mask)
15954 return 0;
15956 if (invert_move)
15958 tmp = op_true;
15959 op_true = op_false;
15960 op_false = tmp;
15963 cond2 = gen_rtx_fmt_ee (NE, cc_mode, mask, const0_rtx);
15964 emit_insn (gen_rtx_SET (VOIDmode,
15965 dest,
15966 gen_rtx_IF_THEN_ELSE (dest_mode,
15967 cond2,
15968 op_true,
15969 op_false)));
15970 return 1;
15973 /* Emit a conditional move: move TRUE_COND to DEST if OP of the
15974 operands of the last comparison is nonzero/true, FALSE_COND if it
15975 is zero/false. Return 0 if the hardware has no such operation. */
15978 rs6000_emit_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
15980 enum rtx_code code = GET_CODE (op);
15981 rtx op0 = XEXP (op, 0);
15982 rtx op1 = XEXP (op, 1);
15983 REAL_VALUE_TYPE c1;
15984 enum machine_mode compare_mode = GET_MODE (op0);
15985 enum machine_mode result_mode = GET_MODE (dest);
15986 rtx temp;
15987 bool is_against_zero;
15989 /* These modes should always match. */
15990 if (GET_MODE (op1) != compare_mode
15991 /* In the isel case however, we can use a compare immediate, so
15992 op1 may be a small constant. */
15993 && (!TARGET_ISEL || !short_cint_operand (op1, VOIDmode)))
15994 return 0;
15995 if (GET_MODE (true_cond) != result_mode)
15996 return 0;
15997 if (GET_MODE (false_cond) != result_mode)
15998 return 0;
16000 /* First, work out if the hardware can do this at all, or
16001 if it's too slow.... */
16002 if (!FLOAT_MODE_P (compare_mode))
16004 if (TARGET_ISEL)
16005 return rs6000_emit_int_cmove (dest, op, true_cond, false_cond);
16006 return 0;
16008 else if (TARGET_HARD_FLOAT && !TARGET_FPRS
16009 && SCALAR_FLOAT_MODE_P (compare_mode))
16010 return 0;
16012 is_against_zero = op1 == CONST0_RTX (compare_mode);
16014 /* A floating-point subtract might overflow, underflow, or produce
16015 an inexact result, thus changing the floating-point flags, so it
16016 can't be generated if we care about that. It's safe if one side
16017 of the construct is zero, since then no subtract will be
16018 generated. */
16019 if (SCALAR_FLOAT_MODE_P (compare_mode)
16020 && flag_trapping_math && ! is_against_zero)
16021 return 0;
16023 /* Eliminate half of the comparisons by switching operands, this
16024 makes the remaining code simpler. */
16025 if (code == UNLT || code == UNGT || code == UNORDERED || code == NE
16026 || code == LTGT || code == LT || code == UNLE)
16028 code = reverse_condition_maybe_unordered (code);
16029 temp = true_cond;
16030 true_cond = false_cond;
16031 false_cond = temp;
16034 /* UNEQ and LTGT take four instructions for a comparison with zero,
16035 it'll probably be faster to use a branch here too. */
16036 if (code == UNEQ && HONOR_NANS (compare_mode))
16037 return 0;
16039 if (GET_CODE (op1) == CONST_DOUBLE)
16040 REAL_VALUE_FROM_CONST_DOUBLE (c1, op1);
16042 /* We're going to try to implement comparisons by performing
16043 a subtract, then comparing against zero. Unfortunately,
16044 Inf - Inf is NaN which is not zero, and so if we don't
16045 know that the operand is finite and the comparison
16046 would treat EQ different to UNORDERED, we can't do it. */
16047 if (HONOR_INFINITIES (compare_mode)
16048 && code != GT && code != UNGE
16049 && (GET_CODE (op1) != CONST_DOUBLE || real_isinf (&c1))
16050 /* Constructs of the form (a OP b ? a : b) are safe. */
16051 && ((! rtx_equal_p (op0, false_cond) && ! rtx_equal_p (op1, false_cond))
16052 || (! rtx_equal_p (op0, true_cond)
16053 && ! rtx_equal_p (op1, true_cond))))
16054 return 0;
16056 /* At this point we know we can use fsel. */
16058 /* Reduce the comparison to a comparison against zero. */
16059 if (! is_against_zero)
16061 temp = gen_reg_rtx (compare_mode);
16062 emit_insn (gen_rtx_SET (VOIDmode, temp,
16063 gen_rtx_MINUS (compare_mode, op0, op1)));
16064 op0 = temp;
16065 op1 = CONST0_RTX (compare_mode);
16068 /* If we don't care about NaNs we can reduce some of the comparisons
16069 down to faster ones. */
16070 if (! HONOR_NANS (compare_mode))
16071 switch (code)
16073 case GT:
16074 code = LE;
16075 temp = true_cond;
16076 true_cond = false_cond;
16077 false_cond = temp;
16078 break;
16079 case UNGE:
16080 code = GE;
16081 break;
16082 case UNEQ:
16083 code = EQ;
16084 break;
16085 default:
16086 break;
16089 /* Now, reduce everything down to a GE. */
16090 switch (code)
16092 case GE:
16093 break;
16095 case LE:
16096 temp = gen_reg_rtx (compare_mode);
16097 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
16098 op0 = temp;
16099 break;
16101 case ORDERED:
16102 temp = gen_reg_rtx (compare_mode);
16103 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_ABS (compare_mode, op0)));
16104 op0 = temp;
16105 break;
16107 case EQ:
16108 temp = gen_reg_rtx (compare_mode);
16109 emit_insn (gen_rtx_SET (VOIDmode, temp,
16110 gen_rtx_NEG (compare_mode,
16111 gen_rtx_ABS (compare_mode, op0))));
16112 op0 = temp;
16113 break;
16115 case UNGE:
16116 /* a UNGE 0 <-> (a GE 0 || -a UNLT 0) */
16117 temp = gen_reg_rtx (result_mode);
16118 emit_insn (gen_rtx_SET (VOIDmode, temp,
16119 gen_rtx_IF_THEN_ELSE (result_mode,
16120 gen_rtx_GE (VOIDmode,
16121 op0, op1),
16122 true_cond, false_cond)));
16123 false_cond = true_cond;
16124 true_cond = temp;
16126 temp = gen_reg_rtx (compare_mode);
16127 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
16128 op0 = temp;
16129 break;
16131 case GT:
16132 /* a GT 0 <-> (a GE 0 && -a UNLT 0) */
16133 temp = gen_reg_rtx (result_mode);
16134 emit_insn (gen_rtx_SET (VOIDmode, temp,
16135 gen_rtx_IF_THEN_ELSE (result_mode,
16136 gen_rtx_GE (VOIDmode,
16137 op0, op1),
16138 true_cond, false_cond)));
16139 true_cond = false_cond;
16140 false_cond = temp;
16142 temp = gen_reg_rtx (compare_mode);
16143 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
16144 op0 = temp;
16145 break;
16147 default:
16148 gcc_unreachable ();
16151 emit_insn (gen_rtx_SET (VOIDmode, dest,
16152 gen_rtx_IF_THEN_ELSE (result_mode,
16153 gen_rtx_GE (VOIDmode,
16154 op0, op1),
16155 true_cond, false_cond)));
16156 return 1;
16159 /* Same as above, but for ints (isel). */
16161 static int
16162 rs6000_emit_int_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
16164 rtx condition_rtx, cr;
16165 enum machine_mode mode = GET_MODE (dest);
16167 if (mode != SImode && (!TARGET_POWERPC64 || mode != DImode))
16168 return 0;
16170 /* We still have to do the compare, because isel doesn't do a
16171 compare, it just looks at the CRx bits set by a previous compare
16172 instruction. */
16173 condition_rtx = rs6000_generate_compare (op, mode);
16174 cr = XEXP (condition_rtx, 0);
16176 if (mode == SImode)
16178 if (GET_MODE (cr) == CCmode)
16179 emit_insn (gen_isel_signed_si (dest, condition_rtx,
16180 true_cond, false_cond, cr));
16181 else
16182 emit_insn (gen_isel_unsigned_si (dest, condition_rtx,
16183 true_cond, false_cond, cr));
16185 else
16187 if (GET_MODE (cr) == CCmode)
16188 emit_insn (gen_isel_signed_di (dest, condition_rtx,
16189 true_cond, false_cond, cr));
16190 else
16191 emit_insn (gen_isel_unsigned_di (dest, condition_rtx,
16192 true_cond, false_cond, cr));
16195 return 1;
16198 const char *
16199 output_isel (rtx *operands)
16201 enum rtx_code code;
16203 code = GET_CODE (operands[1]);
16204 if (code == GE || code == GEU || code == LE || code == LEU || code == NE)
16206 PUT_CODE (operands[1], reverse_condition (code));
16207 return "isel %0,%3,%2,%j1";
16209 else
16210 return "isel %0,%2,%3,%j1";
16213 void
16214 rs6000_emit_minmax (rtx dest, enum rtx_code code, rtx op0, rtx op1)
16216 enum machine_mode mode = GET_MODE (op0);
16217 enum rtx_code c;
16218 rtx target;
16220 /* VSX/altivec have direct min/max insns. */
16221 if ((code == SMAX || code == SMIN) && VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode))
16223 emit_insn (gen_rtx_SET (VOIDmode,
16224 dest,
16225 gen_rtx_fmt_ee (code, mode, op0, op1)));
16226 return;
16229 if (code == SMAX || code == SMIN)
16230 c = GE;
16231 else
16232 c = GEU;
16234 if (code == SMAX || code == UMAX)
16235 target = emit_conditional_move (dest, c, op0, op1, mode,
16236 op0, op1, mode, 0);
16237 else
16238 target = emit_conditional_move (dest, c, op0, op1, mode,
16239 op1, op0, mode, 0);
16240 gcc_assert (target);
16241 if (target != dest)
16242 emit_move_insn (dest, target);
16245 /* Emit instructions to perform a load-reserved/store-conditional operation.
16246 The operation performed is an atomic
16247 (set M (CODE:MODE M OP))
16248 If not NULL, BEFORE is atomically set to M before the operation, and
16249 AFTER is set to M after the operation (that is, (CODE:MODE M OP)).
16250 If SYNC_P then a memory barrier is emitted before the operation.
16251 Either OP or M may be wrapped in a NOT operation. */
16253 void
16254 rs6000_emit_sync (enum rtx_code code, enum machine_mode mode,
16255 rtx m, rtx op, rtx before_param, rtx after_param,
16256 bool sync_p)
16258 enum machine_mode used_mode;
16259 rtx the_op, set_before, set_after, set_atomic, cc_scratch, before, after;
16260 rtx used_m;
16261 rtvec vec;
16262 HOST_WIDE_INT imask = GET_MODE_MASK (mode);
16263 rtx shift = NULL_RTX;
16265 if (sync_p)
16266 emit_insn (gen_lwsync ());
16268 used_m = m;
16270 /* If this is smaller than SImode, we'll have to use SImode with
16271 adjustments. */
16272 if (mode == QImode || mode == HImode)
16274 rtx newop, oldop;
16276 if (MEM_ALIGN (used_m) >= 32)
16278 int ishift = 0;
16279 if (BYTES_BIG_ENDIAN)
16280 ishift = GET_MODE_BITSIZE (SImode) - GET_MODE_BITSIZE (mode);
16282 shift = GEN_INT (ishift);
16283 used_m = change_address (used_m, SImode, 0);
16285 else
16287 rtx addrSI, aligned_addr;
16288 int shift_mask = mode == QImode ? 0x18 : 0x10;
16290 addrSI = gen_lowpart_common (SImode,
16291 force_reg (Pmode, XEXP (used_m, 0)));
16292 addrSI = force_reg (SImode, addrSI);
16293 shift = gen_reg_rtx (SImode);
16295 emit_insn (gen_rlwinm (shift, addrSI, GEN_INT (3),
16296 GEN_INT (shift_mask)));
16297 emit_insn (gen_xorsi3 (shift, shift, GEN_INT (shift_mask)));
16299 aligned_addr = expand_binop (Pmode, and_optab,
16300 XEXP (used_m, 0),
16301 GEN_INT (-4), NULL_RTX,
16302 1, OPTAB_LIB_WIDEN);
16303 used_m = change_address (used_m, SImode, aligned_addr);
16304 set_mem_align (used_m, 32);
16306 /* It's safe to keep the old alias set of USED_M, because
16307 the operation is atomic and only affects the original
16308 USED_M. */
16309 m = used_m;
16311 if (GET_CODE (op) == NOT)
16313 oldop = lowpart_subreg (SImode, XEXP (op, 0), mode);
16314 oldop = gen_rtx_NOT (SImode, oldop);
16316 else
16317 oldop = lowpart_subreg (SImode, op, mode);
16319 switch (code)
16321 case IOR:
16322 case XOR:
16323 newop = expand_binop (SImode, and_optab,
16324 oldop, GEN_INT (imask), NULL_RTX,
16325 1, OPTAB_LIB_WIDEN);
16326 emit_insn (gen_ashlsi3 (newop, newop, shift));
16327 break;
16329 case NOT: /* NAND */
16330 newop = expand_binop (SImode, ior_optab,
16331 oldop, GEN_INT (~imask), NULL_RTX,
16332 1, OPTAB_LIB_WIDEN);
16333 emit_insn (gen_rotlsi3 (newop, newop, shift));
16334 break;
16336 case AND:
16337 newop = expand_binop (SImode, ior_optab,
16338 oldop, GEN_INT (~imask), NULL_RTX,
16339 1, OPTAB_LIB_WIDEN);
16340 emit_insn (gen_rotlsi3 (newop, newop, shift));
16341 break;
16343 case PLUS:
16344 case MINUS:
16346 rtx mask;
16348 newop = expand_binop (SImode, and_optab,
16349 oldop, GEN_INT (imask), NULL_RTX,
16350 1, OPTAB_LIB_WIDEN);
16351 emit_insn (gen_ashlsi3 (newop, newop, shift));
16353 mask = gen_reg_rtx (SImode);
16354 emit_move_insn (mask, GEN_INT (imask));
16355 emit_insn (gen_ashlsi3 (mask, mask, shift));
16357 if (code == PLUS)
16358 newop = gen_rtx_PLUS (SImode, m, newop);
16359 else
16360 newop = gen_rtx_MINUS (SImode, m, newop);
16361 newop = gen_rtx_AND (SImode, newop, mask);
16362 newop = gen_rtx_IOR (SImode, newop,
16363 gen_rtx_AND (SImode,
16364 gen_rtx_NOT (SImode, mask),
16365 m));
16366 break;
16369 default:
16370 gcc_unreachable ();
16373 op = newop;
16374 used_mode = SImode;
16375 before = gen_reg_rtx (used_mode);
16376 after = gen_reg_rtx (used_mode);
16378 else
16380 used_mode = mode;
16381 before = before_param;
16382 after = after_param;
16384 if (before == NULL_RTX)
16385 before = gen_reg_rtx (used_mode);
16386 if (after == NULL_RTX)
16387 after = gen_reg_rtx (used_mode);
16390 if ((code == PLUS || code == MINUS)
16391 && used_mode != mode)
16392 the_op = op; /* Computed above. */
16393 else if (GET_CODE (op) == NOT && GET_CODE (m) != NOT)
16394 the_op = gen_rtx_fmt_ee (code, used_mode, op, m);
16395 else if (code == NOT)
16396 the_op = gen_rtx_fmt_ee (IOR, used_mode,
16397 gen_rtx_NOT (used_mode, m),
16398 gen_rtx_NOT (used_mode, op));
16399 else
16400 the_op = gen_rtx_fmt_ee (code, used_mode, m, op);
16402 set_after = gen_rtx_SET (VOIDmode, after, the_op);
16403 set_before = gen_rtx_SET (VOIDmode, before, used_m);
16404 set_atomic = gen_rtx_SET (VOIDmode, used_m,
16405 gen_rtx_UNSPEC (used_mode,
16406 gen_rtvec (1, the_op),
16407 UNSPEC_SYNC_OP));
16408 cc_scratch = gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (CCmode));
16410 if ((code == PLUS || code == MINUS) && used_mode != mode)
16411 vec = gen_rtvec (5, set_after, set_before, set_atomic, cc_scratch,
16412 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (SImode)));
16413 else
16414 vec = gen_rtvec (4, set_after, set_before, set_atomic, cc_scratch);
16415 emit_insn (gen_rtx_PARALLEL (VOIDmode, vec));
16417 /* Shift and mask the return values properly. */
16418 if (used_mode != mode && before_param)
16420 emit_insn (gen_lshrsi3 (before, before, shift));
16421 convert_move (before_param, before, 1);
16424 if (used_mode != mode && after_param)
16426 emit_insn (gen_lshrsi3 (after, after, shift));
16427 convert_move (after_param, after, 1);
16430 /* The previous sequence will end with a branch that's dependent on
16431 the conditional store, so placing an isync will ensure that no
16432 other instructions (especially, no load or store instructions)
16433 can start before the atomic operation completes. */
16434 if (sync_p)
16435 emit_insn (gen_isync ());
16438 /* A subroutine of the atomic operation splitters. Jump to LABEL if
16439 COND is true. Mark the jump as unlikely to be taken. */
16441 static void
16442 emit_unlikely_jump (rtx cond, rtx label)
16444 rtx very_unlikely = GEN_INT (REG_BR_PROB_BASE / 100 - 1);
16445 rtx x;
16447 x = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, label, pc_rtx);
16448 x = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, x));
16449 add_reg_note (x, REG_BR_PROB, very_unlikely);
16452 /* A subroutine of the atomic operation splitters. Emit a load-locked
16453 instruction in MODE. */
16455 static void
16456 emit_load_locked (enum machine_mode mode, rtx reg, rtx mem)
16458 rtx (*fn) (rtx, rtx) = NULL;
16459 if (mode == SImode)
16460 fn = gen_load_locked_si;
16461 else if (mode == DImode)
16462 fn = gen_load_locked_di;
16463 emit_insn (fn (reg, mem));
16466 /* A subroutine of the atomic operation splitters. Emit a store-conditional
16467 instruction in MODE. */
16469 static void
16470 emit_store_conditional (enum machine_mode mode, rtx res, rtx mem, rtx val)
16472 rtx (*fn) (rtx, rtx, rtx) = NULL;
16473 if (mode == SImode)
16474 fn = gen_store_conditional_si;
16475 else if (mode == DImode)
16476 fn = gen_store_conditional_di;
16478 /* Emit sync before stwcx. to address PPC405 Erratum. */
16479 if (PPC405_ERRATUM77)
16480 emit_insn (gen_memory_barrier ());
16482 emit_insn (fn (res, mem, val));
16485 /* Expand an atomic fetch-and-operate pattern. CODE is the binary operation
16486 to perform. MEM is the memory on which to operate. VAL is the second
16487 operand of the binary operator. BEFORE and AFTER are optional locations to
16488 return the value of MEM either before of after the operation. SCRATCH is
16489 a scratch register. */
16491 void
16492 rs6000_split_atomic_op (enum rtx_code code, rtx mem, rtx val,
16493 rtx before, rtx after, rtx scratch)
16495 enum machine_mode mode = GET_MODE (mem);
16496 rtx label, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
16498 emit_insn (gen_lwsync ());
16500 label = gen_label_rtx ();
16501 emit_label (label);
16502 label = gen_rtx_LABEL_REF (VOIDmode, label);
16504 if (before == NULL_RTX)
16505 before = scratch;
16506 emit_load_locked (mode, before, mem);
16508 if (code == NOT)
16509 x = gen_rtx_IOR (mode,
16510 gen_rtx_NOT (mode, before),
16511 gen_rtx_NOT (mode, val));
16512 else if (code == AND)
16513 x = gen_rtx_UNSPEC (mode, gen_rtvec (2, before, val), UNSPEC_AND);
16514 else
16515 x = gen_rtx_fmt_ee (code, mode, before, val);
16517 if (after != NULL_RTX)
16518 emit_insn (gen_rtx_SET (VOIDmode, after, copy_rtx (x)));
16519 emit_insn (gen_rtx_SET (VOIDmode, scratch, x));
16521 emit_store_conditional (mode, cond, mem, scratch);
16523 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
16524 emit_unlikely_jump (x, label);
16526 emit_insn (gen_isync ());
16529 /* Expand an atomic compare and swap operation. MEM is the memory on which
16530 to operate. OLDVAL is the old value to be compared. NEWVAL is the new
16531 value to be stored. SCRATCH is a scratch GPR. */
16533 void
16534 rs6000_split_compare_and_swap (rtx retval, rtx mem, rtx oldval, rtx newval,
16535 rtx scratch)
16537 enum machine_mode mode = GET_MODE (mem);
16538 rtx label1, label2, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
16540 emit_insn (gen_lwsync ());
16542 label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
16543 label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
16544 emit_label (XEXP (label1, 0));
16546 emit_load_locked (mode, retval, mem);
16548 x = gen_rtx_COMPARE (CCmode, retval, oldval);
16549 emit_insn (gen_rtx_SET (VOIDmode, cond, x));
16551 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
16552 emit_unlikely_jump (x, label2);
16554 emit_move_insn (scratch, newval);
16555 emit_store_conditional (mode, cond, mem, scratch);
16557 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
16558 emit_unlikely_jump (x, label1);
16560 emit_insn (gen_isync ());
16561 emit_label (XEXP (label2, 0));
16564 /* Expand an atomic test and set operation. MEM is the memory on which
16565 to operate. VAL is the value set. SCRATCH is a scratch GPR. */
16567 void
16568 rs6000_split_lock_test_and_set (rtx retval, rtx mem, rtx val, rtx scratch)
16570 enum machine_mode mode = GET_MODE (mem);
16571 rtx label, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
16573 label = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
16574 emit_label (XEXP (label, 0));
16576 emit_load_locked (mode, retval, mem);
16577 emit_move_insn (scratch, val);
16578 emit_store_conditional (mode, cond, mem, scratch);
16580 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
16581 emit_unlikely_jump (x, label);
16583 emit_insn (gen_isync ());
16586 void
16587 rs6000_expand_compare_and_swapqhi (rtx dst, rtx mem, rtx oldval, rtx newval)
16589 enum machine_mode mode = GET_MODE (mem);
16590 rtx addrSI, align, wdst, shift, mask;
16591 HOST_WIDE_INT shift_mask = mode == QImode ? 0x18 : 0x10;
16592 HOST_WIDE_INT imask = GET_MODE_MASK (mode);
16594 /* Shift amount for subword relative to aligned word. */
16595 addrSI = force_reg (GET_MODE (XEXP (mem, 0)), XEXP (mem, 0));
16596 addrSI = force_reg (SImode, gen_lowpart_common (SImode, addrSI));
16597 shift = gen_reg_rtx (SImode);
16598 emit_insn (gen_rlwinm (shift, addrSI, GEN_INT (3),
16599 GEN_INT (shift_mask)));
16600 emit_insn (gen_xorsi3 (shift, shift, GEN_INT (shift_mask)));
16602 /* Shift and mask old value into position within word. */
16603 oldval = convert_modes (SImode, mode, oldval, 1);
16604 oldval = expand_binop (SImode, and_optab,
16605 oldval, GEN_INT (imask), NULL_RTX,
16606 1, OPTAB_LIB_WIDEN);
16607 emit_insn (gen_ashlsi3 (oldval, oldval, shift));
16609 /* Shift and mask new value into position within word. */
16610 newval = convert_modes (SImode, mode, newval, 1);
16611 newval = expand_binop (SImode, and_optab,
16612 newval, GEN_INT (imask), NULL_RTX,
16613 1, OPTAB_LIB_WIDEN);
16614 emit_insn (gen_ashlsi3 (newval, newval, shift));
16616 /* Mask for insertion. */
16617 mask = gen_reg_rtx (SImode);
16618 emit_move_insn (mask, GEN_INT (imask));
16619 emit_insn (gen_ashlsi3 (mask, mask, shift));
16621 /* Address of aligned word containing subword. */
16622 align = expand_binop (Pmode, and_optab, XEXP (mem, 0), GEN_INT (-4),
16623 NULL_RTX, 1, OPTAB_LIB_WIDEN);
16624 mem = change_address (mem, SImode, align);
16625 set_mem_align (mem, 32);
16626 MEM_VOLATILE_P (mem) = 1;
16628 wdst = gen_reg_rtx (SImode);
16629 emit_insn (gen_sync_compare_and_swapqhi_internal (wdst, mask,
16630 oldval, newval, mem));
16632 /* Shift the result back. */
16633 emit_insn (gen_lshrsi3 (wdst, wdst, shift));
16635 emit_move_insn (dst, gen_lowpart (mode, wdst));
16638 void
16639 rs6000_split_compare_and_swapqhi (rtx dest, rtx mask,
16640 rtx oldval, rtx newval, rtx mem,
16641 rtx scratch)
16643 rtx label1, label2, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
16645 emit_insn (gen_lwsync ());
16646 label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
16647 label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
16648 emit_label (XEXP (label1, 0));
16650 emit_load_locked (SImode, scratch, mem);
16652 /* Mask subword within loaded value for comparison with oldval.
16653 Use UNSPEC_AND to avoid clobber.*/
16654 emit_insn (gen_rtx_SET (SImode, dest,
16655 gen_rtx_UNSPEC (SImode,
16656 gen_rtvec (2, scratch, mask),
16657 UNSPEC_AND)));
16659 x = gen_rtx_COMPARE (CCmode, dest, oldval);
16660 emit_insn (gen_rtx_SET (VOIDmode, cond, x));
16662 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
16663 emit_unlikely_jump (x, label2);
16665 /* Clear subword within loaded value for insertion of new value. */
16666 emit_insn (gen_rtx_SET (SImode, scratch,
16667 gen_rtx_AND (SImode,
16668 gen_rtx_NOT (SImode, mask), scratch)));
16669 emit_insn (gen_iorsi3 (scratch, scratch, newval));
16670 emit_store_conditional (SImode, cond, mem, scratch);
16672 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
16673 emit_unlikely_jump (x, label1);
16675 emit_insn (gen_isync ());
16676 emit_label (XEXP (label2, 0));
16680 /* Emit instructions to move SRC to DST. Called by splitters for
16681 multi-register moves. It will emit at most one instruction for
16682 each register that is accessed; that is, it won't emit li/lis pairs
16683 (or equivalent for 64-bit code). One of SRC or DST must be a hard
16684 register. */
16686 void
16687 rs6000_split_multireg_move (rtx dst, rtx src)
16689 /* The register number of the first register being moved. */
16690 int reg;
16691 /* The mode that is to be moved. */
16692 enum machine_mode mode;
16693 /* The mode that the move is being done in, and its size. */
16694 enum machine_mode reg_mode;
16695 int reg_mode_size;
16696 /* The number of registers that will be moved. */
16697 int nregs;
16699 reg = REG_P (dst) ? REGNO (dst) : REGNO (src);
16700 mode = GET_MODE (dst);
16701 nregs = hard_regno_nregs[reg][mode];
16702 if (FP_REGNO_P (reg))
16703 reg_mode = DECIMAL_FLOAT_MODE_P (mode) ? DDmode :
16704 ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? DFmode : SFmode);
16705 else if (ALTIVEC_REGNO_P (reg))
16706 reg_mode = V16QImode;
16707 else if (TARGET_E500_DOUBLE && mode == TFmode)
16708 reg_mode = DFmode;
16709 else
16710 reg_mode = word_mode;
16711 reg_mode_size = GET_MODE_SIZE (reg_mode);
16713 gcc_assert (reg_mode_size * nregs == GET_MODE_SIZE (mode));
16715 if (REG_P (src) && REG_P (dst) && (REGNO (src) < REGNO (dst)))
16717 /* Move register range backwards, if we might have destructive
16718 overlap. */
16719 int i;
16720 for (i = nregs - 1; i >= 0; i--)
16721 emit_insn (gen_rtx_SET (VOIDmode,
16722 simplify_gen_subreg (reg_mode, dst, mode,
16723 i * reg_mode_size),
16724 simplify_gen_subreg (reg_mode, src, mode,
16725 i * reg_mode_size)));
16727 else
16729 int i;
16730 int j = -1;
16731 bool used_update = false;
16732 rtx restore_basereg = NULL_RTX;
16734 if (MEM_P (src) && INT_REGNO_P (reg))
16736 rtx breg;
16738 if (GET_CODE (XEXP (src, 0)) == PRE_INC
16739 || GET_CODE (XEXP (src, 0)) == PRE_DEC)
16741 rtx delta_rtx;
16742 breg = XEXP (XEXP (src, 0), 0);
16743 delta_rtx = (GET_CODE (XEXP (src, 0)) == PRE_INC
16744 ? GEN_INT (GET_MODE_SIZE (GET_MODE (src)))
16745 : GEN_INT (-GET_MODE_SIZE (GET_MODE (src))));
16746 emit_insn (gen_add3_insn (breg, breg, delta_rtx));
16747 src = replace_equiv_address (src, breg);
16749 else if (! rs6000_offsettable_memref_p (src))
16751 if (GET_CODE (XEXP (src, 0)) == PRE_MODIFY)
16753 rtx basereg = XEXP (XEXP (src, 0), 0);
16754 if (TARGET_UPDATE)
16756 rtx ndst = simplify_gen_subreg (reg_mode, dst, mode, 0);
16757 emit_insn (gen_rtx_SET (VOIDmode, ndst,
16758 gen_rtx_MEM (reg_mode, XEXP (src, 0))));
16759 used_update = true;
16761 else
16762 emit_insn (gen_rtx_SET (VOIDmode, basereg,
16763 XEXP (XEXP (src, 0), 1)));
16764 src = replace_equiv_address (src, basereg);
16766 else
16768 rtx basereg = gen_rtx_REG (Pmode, reg);
16769 emit_insn (gen_rtx_SET (VOIDmode, basereg, XEXP (src, 0)));
16770 src = replace_equiv_address (src, basereg);
16774 breg = XEXP (src, 0);
16775 if (GET_CODE (breg) == PLUS || GET_CODE (breg) == LO_SUM)
16776 breg = XEXP (breg, 0);
16778 /* If the base register we are using to address memory is
16779 also a destination reg, then change that register last. */
16780 if (REG_P (breg)
16781 && REGNO (breg) >= REGNO (dst)
16782 && REGNO (breg) < REGNO (dst) + nregs)
16783 j = REGNO (breg) - REGNO (dst);
16785 else if (MEM_P (dst) && INT_REGNO_P (reg))
16787 rtx breg;
16789 if (GET_CODE (XEXP (dst, 0)) == PRE_INC
16790 || GET_CODE (XEXP (dst, 0)) == PRE_DEC)
16792 rtx delta_rtx;
16793 breg = XEXP (XEXP (dst, 0), 0);
16794 delta_rtx = (GET_CODE (XEXP (dst, 0)) == PRE_INC
16795 ? GEN_INT (GET_MODE_SIZE (GET_MODE (dst)))
16796 : GEN_INT (-GET_MODE_SIZE (GET_MODE (dst))));
16798 /* We have to update the breg before doing the store.
16799 Use store with update, if available. */
16801 if (TARGET_UPDATE)
16803 rtx nsrc = simplify_gen_subreg (reg_mode, src, mode, 0);
16804 emit_insn (TARGET_32BIT
16805 ? (TARGET_POWERPC64
16806 ? gen_movdi_si_update (breg, breg, delta_rtx, nsrc)
16807 : gen_movsi_update (breg, breg, delta_rtx, nsrc))
16808 : gen_movdi_di_update (breg, breg, delta_rtx, nsrc));
16809 used_update = true;
16811 else
16812 emit_insn (gen_add3_insn (breg, breg, delta_rtx));
16813 dst = replace_equiv_address (dst, breg);
16815 else if (!rs6000_offsettable_memref_p (dst)
16816 && GET_CODE (XEXP (dst, 0)) != LO_SUM)
16818 if (GET_CODE (XEXP (dst, 0)) == PRE_MODIFY)
16820 rtx basereg = XEXP (XEXP (dst, 0), 0);
16821 if (TARGET_UPDATE)
16823 rtx nsrc = simplify_gen_subreg (reg_mode, src, mode, 0);
16824 emit_insn (gen_rtx_SET (VOIDmode,
16825 gen_rtx_MEM (reg_mode, XEXP (dst, 0)), nsrc));
16826 used_update = true;
16828 else
16829 emit_insn (gen_rtx_SET (VOIDmode, basereg,
16830 XEXP (XEXP (dst, 0), 1)));
16831 dst = replace_equiv_address (dst, basereg);
16833 else
16835 rtx basereg = XEXP (XEXP (dst, 0), 0);
16836 rtx offsetreg = XEXP (XEXP (dst, 0), 1);
16837 gcc_assert (GET_CODE (XEXP (dst, 0)) == PLUS
16838 && REG_P (basereg)
16839 && REG_P (offsetreg)
16840 && REGNO (basereg) != REGNO (offsetreg));
16841 if (REGNO (basereg) == 0)
16843 rtx tmp = offsetreg;
16844 offsetreg = basereg;
16845 basereg = tmp;
16847 emit_insn (gen_add3_insn (basereg, basereg, offsetreg));
16848 restore_basereg = gen_sub3_insn (basereg, basereg, offsetreg);
16849 dst = replace_equiv_address (dst, basereg);
16852 else if (GET_CODE (XEXP (dst, 0)) != LO_SUM)
16853 gcc_assert (rs6000_offsettable_memref_p (dst));
16856 for (i = 0; i < nregs; i++)
16858 /* Calculate index to next subword. */
16859 ++j;
16860 if (j == nregs)
16861 j = 0;
16863 /* If compiler already emitted move of first word by
16864 store with update, no need to do anything. */
16865 if (j == 0 && used_update)
16866 continue;
16868 emit_insn (gen_rtx_SET (VOIDmode,
16869 simplify_gen_subreg (reg_mode, dst, mode,
16870 j * reg_mode_size),
16871 simplify_gen_subreg (reg_mode, src, mode,
16872 j * reg_mode_size)));
16874 if (restore_basereg != NULL_RTX)
16875 emit_insn (restore_basereg);
16880 /* This page contains routines that are used to determine what the
16881 function prologue and epilogue code will do and write them out. */
16883 /* Return the first fixed-point register that is required to be
16884 saved. 32 if none. */
16887 first_reg_to_save (void)
16889 int first_reg;
16891 /* Find lowest numbered live register. */
16892 for (first_reg = 13; first_reg <= 31; first_reg++)
16893 if (df_regs_ever_live_p (first_reg)
16894 && (! call_used_regs[first_reg]
16895 || (first_reg == RS6000_PIC_OFFSET_TABLE_REGNUM
16896 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
16897 || (DEFAULT_ABI == ABI_DARWIN && flag_pic)
16898 || (TARGET_TOC && TARGET_MINIMAL_TOC)))))
16899 break;
16901 #if TARGET_MACHO
16902 if (flag_pic
16903 && crtl->uses_pic_offset_table
16904 && first_reg > RS6000_PIC_OFFSET_TABLE_REGNUM)
16905 return RS6000_PIC_OFFSET_TABLE_REGNUM;
16906 #endif
16908 return first_reg;
16911 /* Similar, for FP regs. */
16914 first_fp_reg_to_save (void)
16916 int first_reg;
16918 /* Find lowest numbered live register. */
16919 for (first_reg = 14 + 32; first_reg <= 63; first_reg++)
16920 if (df_regs_ever_live_p (first_reg))
16921 break;
16923 return first_reg;
16926 /* Similar, for AltiVec regs. */
16928 static int
16929 first_altivec_reg_to_save (void)
16931 int i;
16933 /* Stack frame remains as is unless we are in AltiVec ABI. */
16934 if (! TARGET_ALTIVEC_ABI)
16935 return LAST_ALTIVEC_REGNO + 1;
16937 /* On Darwin, the unwind routines are compiled without
16938 TARGET_ALTIVEC, and use save_world to save/restore the
16939 altivec registers when necessary. */
16940 if (DEFAULT_ABI == ABI_DARWIN && crtl->calls_eh_return
16941 && ! TARGET_ALTIVEC)
16942 return FIRST_ALTIVEC_REGNO + 20;
16944 /* Find lowest numbered live register. */
16945 for (i = FIRST_ALTIVEC_REGNO + 20; i <= LAST_ALTIVEC_REGNO; ++i)
16946 if (df_regs_ever_live_p (i))
16947 break;
16949 return i;
16952 /* Return a 32-bit mask of the AltiVec registers we need to set in
16953 VRSAVE. Bit n of the return value is 1 if Vn is live. The MSB in
16954 the 32-bit word is 0. */
16956 static unsigned int
16957 compute_vrsave_mask (void)
16959 unsigned int i, mask = 0;
16961 /* On Darwin, the unwind routines are compiled without
16962 TARGET_ALTIVEC, and use save_world to save/restore the
16963 call-saved altivec registers when necessary. */
16964 if (DEFAULT_ABI == ABI_DARWIN && crtl->calls_eh_return
16965 && ! TARGET_ALTIVEC)
16966 mask |= 0xFFF;
16968 /* First, find out if we use _any_ altivec registers. */
16969 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
16970 if (df_regs_ever_live_p (i))
16971 mask |= ALTIVEC_REG_BIT (i);
16973 if (mask == 0)
16974 return mask;
16976 /* Next, remove the argument registers from the set. These must
16977 be in the VRSAVE mask set by the caller, so we don't need to add
16978 them in again. More importantly, the mask we compute here is
16979 used to generate CLOBBERs in the set_vrsave insn, and we do not
16980 wish the argument registers to die. */
16981 for (i = crtl->args.info.vregno - 1; i >= ALTIVEC_ARG_MIN_REG; --i)
16982 mask &= ~ALTIVEC_REG_BIT (i);
16984 /* Similarly, remove the return value from the set. */
16986 bool yes = false;
16987 diddle_return_value (is_altivec_return_reg, &yes);
16988 if (yes)
16989 mask &= ~ALTIVEC_REG_BIT (ALTIVEC_ARG_RETURN);
16992 return mask;
16995 /* For a very restricted set of circumstances, we can cut down the
16996 size of prologues/epilogues by calling our own save/restore-the-world
16997 routines. */
16999 static void
17000 compute_save_world_info (rs6000_stack_t *info_ptr)
17002 info_ptr->world_save_p = 1;
17003 info_ptr->world_save_p
17004 = (WORLD_SAVE_P (info_ptr)
17005 && DEFAULT_ABI == ABI_DARWIN
17006 && ! (cfun->calls_setjmp && flag_exceptions)
17007 && info_ptr->first_fp_reg_save == FIRST_SAVED_FP_REGNO
17008 && info_ptr->first_gp_reg_save == FIRST_SAVED_GP_REGNO
17009 && info_ptr->first_altivec_reg_save == FIRST_SAVED_ALTIVEC_REGNO
17010 && info_ptr->cr_save_p);
17012 /* This will not work in conjunction with sibcalls. Make sure there
17013 are none. (This check is expensive, but seldom executed.) */
17014 if (WORLD_SAVE_P (info_ptr))
17016 rtx insn;
17017 for ( insn = get_last_insn_anywhere (); insn; insn = PREV_INSN (insn))
17018 if ( GET_CODE (insn) == CALL_INSN
17019 && SIBLING_CALL_P (insn))
17021 info_ptr->world_save_p = 0;
17022 break;
17026 if (WORLD_SAVE_P (info_ptr))
17028 /* Even if we're not touching VRsave, make sure there's room on the
17029 stack for it, if it looks like we're calling SAVE_WORLD, which
17030 will attempt to save it. */
17031 info_ptr->vrsave_size = 4;
17033 /* If we are going to save the world, we need to save the link register too. */
17034 info_ptr->lr_save_p = 1;
17036 /* "Save" the VRsave register too if we're saving the world. */
17037 if (info_ptr->vrsave_mask == 0)
17038 info_ptr->vrsave_mask = compute_vrsave_mask ();
17040 /* Because the Darwin register save/restore routines only handle
17041 F14 .. F31 and V20 .. V31 as per the ABI, perform a consistency
17042 check. */
17043 gcc_assert (info_ptr->first_fp_reg_save >= FIRST_SAVED_FP_REGNO
17044 && (info_ptr->first_altivec_reg_save
17045 >= FIRST_SAVED_ALTIVEC_REGNO));
17047 return;
17051 static void
17052 is_altivec_return_reg (rtx reg, void *xyes)
17054 bool *yes = (bool *) xyes;
17055 if (REGNO (reg) == ALTIVEC_ARG_RETURN)
17056 *yes = true;
17060 /* Calculate the stack information for the current function. This is
17061 complicated by having two separate calling sequences, the AIX calling
17062 sequence and the V.4 calling sequence.
17064 AIX (and Darwin/Mac OS X) stack frames look like:
17065 32-bit 64-bit
17066 SP----> +---------------------------------------+
17067 | back chain to caller | 0 0
17068 +---------------------------------------+
17069 | saved CR | 4 8 (8-11)
17070 +---------------------------------------+
17071 | saved LR | 8 16
17072 +---------------------------------------+
17073 | reserved for compilers | 12 24
17074 +---------------------------------------+
17075 | reserved for binders | 16 32
17076 +---------------------------------------+
17077 | saved TOC pointer | 20 40
17078 +---------------------------------------+
17079 | Parameter save area (P) | 24 48
17080 +---------------------------------------+
17081 | Alloca space (A) | 24+P etc.
17082 +---------------------------------------+
17083 | Local variable space (L) | 24+P+A
17084 +---------------------------------------+
17085 | Float/int conversion temporary (X) | 24+P+A+L
17086 +---------------------------------------+
17087 | Save area for AltiVec registers (W) | 24+P+A+L+X
17088 +---------------------------------------+
17089 | AltiVec alignment padding (Y) | 24+P+A+L+X+W
17090 +---------------------------------------+
17091 | Save area for VRSAVE register (Z) | 24+P+A+L+X+W+Y
17092 +---------------------------------------+
17093 | Save area for GP registers (G) | 24+P+A+X+L+X+W+Y+Z
17094 +---------------------------------------+
17095 | Save area for FP registers (F) | 24+P+A+X+L+X+W+Y+Z+G
17096 +---------------------------------------+
17097 old SP->| back chain to caller's caller |
17098 +---------------------------------------+
17100 The required alignment for AIX configurations is two words (i.e., 8
17101 or 16 bytes).
17104 V.4 stack frames look like:
17106 SP----> +---------------------------------------+
17107 | back chain to caller | 0
17108 +---------------------------------------+
17109 | caller's saved LR | 4
17110 +---------------------------------------+
17111 | Parameter save area (P) | 8
17112 +---------------------------------------+
17113 | Alloca space (A) | 8+P
17114 +---------------------------------------+
17115 | Varargs save area (V) | 8+P+A
17116 +---------------------------------------+
17117 | Local variable space (L) | 8+P+A+V
17118 +---------------------------------------+
17119 | Float/int conversion temporary (X) | 8+P+A+V+L
17120 +---------------------------------------+
17121 | Save area for AltiVec registers (W) | 8+P+A+V+L+X
17122 +---------------------------------------+
17123 | AltiVec alignment padding (Y) | 8+P+A+V+L+X+W
17124 +---------------------------------------+
17125 | Save area for VRSAVE register (Z) | 8+P+A+V+L+X+W+Y
17126 +---------------------------------------+
17127 | SPE: area for 64-bit GP registers |
17128 +---------------------------------------+
17129 | SPE alignment padding |
17130 +---------------------------------------+
17131 | saved CR (C) | 8+P+A+V+L+X+W+Y+Z
17132 +---------------------------------------+
17133 | Save area for GP registers (G) | 8+P+A+V+L+X+W+Y+Z+C
17134 +---------------------------------------+
17135 | Save area for FP registers (F) | 8+P+A+V+L+X+W+Y+Z+C+G
17136 +---------------------------------------+
17137 old SP->| back chain to caller's caller |
17138 +---------------------------------------+
17140 The required alignment for V.4 is 16 bytes, or 8 bytes if -meabi is
17141 given. (But note below and in sysv4.h that we require only 8 and
17142 may round up the size of our stack frame anyways. The historical
17143 reason is early versions of powerpc-linux which didn't properly
17144 align the stack at program startup. A happy side-effect is that
17145 -mno-eabi libraries can be used with -meabi programs.)
17147 The EABI configuration defaults to the V.4 layout. However,
17148 the stack alignment requirements may differ. If -mno-eabi is not
17149 given, the required stack alignment is 8 bytes; if -mno-eabi is
17150 given, the required alignment is 16 bytes. (But see V.4 comment
17151 above.) */
17153 #ifndef ABI_STACK_BOUNDARY
17154 #define ABI_STACK_BOUNDARY STACK_BOUNDARY
17155 #endif
17157 static rs6000_stack_t *
17158 rs6000_stack_info (void)
17160 static rs6000_stack_t info;
17161 rs6000_stack_t *info_ptr = &info;
17162 int reg_size = TARGET_32BIT ? 4 : 8;
17163 int ehrd_size;
17164 int save_align;
17165 int first_gp;
17166 HOST_WIDE_INT non_fixed_size;
17168 memset (&info, 0, sizeof (info));
17170 if (TARGET_SPE)
17172 /* Cache value so we don't rescan instruction chain over and over. */
17173 if (cfun->machine->insn_chain_scanned_p == 0)
17174 cfun->machine->insn_chain_scanned_p
17175 = spe_func_has_64bit_regs_p () + 1;
17176 info_ptr->spe_64bit_regs_used = cfun->machine->insn_chain_scanned_p - 1;
17179 /* Select which calling sequence. */
17180 info_ptr->abi = DEFAULT_ABI;
17182 /* Calculate which registers need to be saved & save area size. */
17183 info_ptr->first_gp_reg_save = first_reg_to_save ();
17184 /* Assume that we will have to save RS6000_PIC_OFFSET_TABLE_REGNUM,
17185 even if it currently looks like we won't. Reload may need it to
17186 get at a constant; if so, it will have already created a constant
17187 pool entry for it. */
17188 if (((TARGET_TOC && TARGET_MINIMAL_TOC)
17189 || (flag_pic == 1 && DEFAULT_ABI == ABI_V4)
17190 || (flag_pic && DEFAULT_ABI == ABI_DARWIN))
17191 && crtl->uses_const_pool
17192 && info_ptr->first_gp_reg_save > RS6000_PIC_OFFSET_TABLE_REGNUM)
17193 first_gp = RS6000_PIC_OFFSET_TABLE_REGNUM;
17194 else
17195 first_gp = info_ptr->first_gp_reg_save;
17197 info_ptr->gp_size = reg_size * (32 - first_gp);
17199 /* For the SPE, we have an additional upper 32-bits on each GPR.
17200 Ideally we should save the entire 64-bits only when the upper
17201 half is used in SIMD instructions. Since we only record
17202 registers live (not the size they are used in), this proves
17203 difficult because we'd have to traverse the instruction chain at
17204 the right time, taking reload into account. This is a real pain,
17205 so we opt to save the GPRs in 64-bits always if but one register
17206 gets used in 64-bits. Otherwise, all the registers in the frame
17207 get saved in 32-bits.
17209 So... since when we save all GPRs (except the SP) in 64-bits, the
17210 traditional GP save area will be empty. */
17211 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
17212 info_ptr->gp_size = 0;
17214 info_ptr->first_fp_reg_save = first_fp_reg_to_save ();
17215 info_ptr->fp_size = 8 * (64 - info_ptr->first_fp_reg_save);
17217 info_ptr->first_altivec_reg_save = first_altivec_reg_to_save ();
17218 info_ptr->altivec_size = 16 * (LAST_ALTIVEC_REGNO + 1
17219 - info_ptr->first_altivec_reg_save);
17221 /* Does this function call anything? */
17222 info_ptr->calls_p = (! current_function_is_leaf
17223 || cfun->machine->ra_needs_full_frame);
17225 /* Determine if we need to save the link register. */
17226 if ((DEFAULT_ABI == ABI_AIX
17227 && crtl->profile
17228 && !TARGET_PROFILE_KERNEL)
17229 #ifdef TARGET_RELOCATABLE
17230 || (TARGET_RELOCATABLE && (get_pool_size () != 0))
17231 #endif
17232 || (info_ptr->first_fp_reg_save != 64
17233 && !FP_SAVE_INLINE (info_ptr->first_fp_reg_save))
17234 || (DEFAULT_ABI == ABI_V4 && cfun->calls_alloca)
17235 || info_ptr->calls_p
17236 || rs6000_ra_ever_killed ())
17238 info_ptr->lr_save_p = 1;
17239 df_set_regs_ever_live (LR_REGNO, true);
17242 /* Determine if we need to save the condition code registers. */
17243 if (df_regs_ever_live_p (CR2_REGNO)
17244 || df_regs_ever_live_p (CR3_REGNO)
17245 || df_regs_ever_live_p (CR4_REGNO))
17247 info_ptr->cr_save_p = 1;
17248 if (DEFAULT_ABI == ABI_V4)
17249 info_ptr->cr_size = reg_size;
17252 /* If the current function calls __builtin_eh_return, then we need
17253 to allocate stack space for registers that will hold data for
17254 the exception handler. */
17255 if (crtl->calls_eh_return)
17257 unsigned int i;
17258 for (i = 0; EH_RETURN_DATA_REGNO (i) != INVALID_REGNUM; ++i)
17259 continue;
17261 /* SPE saves EH registers in 64-bits. */
17262 ehrd_size = i * (TARGET_SPE_ABI
17263 && info_ptr->spe_64bit_regs_used != 0
17264 ? UNITS_PER_SPE_WORD : UNITS_PER_WORD);
17266 else
17267 ehrd_size = 0;
17269 /* Determine various sizes. */
17270 info_ptr->reg_size = reg_size;
17271 info_ptr->fixed_size = RS6000_SAVE_AREA;
17272 info_ptr->vars_size = RS6000_ALIGN (get_frame_size (), 8);
17273 info_ptr->parm_size = RS6000_ALIGN (crtl->outgoing_args_size,
17274 TARGET_ALTIVEC ? 16 : 8);
17275 if (FRAME_GROWS_DOWNWARD)
17276 info_ptr->vars_size
17277 += RS6000_ALIGN (info_ptr->fixed_size + info_ptr->vars_size
17278 + info_ptr->parm_size,
17279 ABI_STACK_BOUNDARY / BITS_PER_UNIT)
17280 - (info_ptr->fixed_size + info_ptr->vars_size
17281 + info_ptr->parm_size);
17283 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
17284 info_ptr->spe_gp_size = 8 * (32 - first_gp);
17285 else
17286 info_ptr->spe_gp_size = 0;
17288 if (TARGET_ALTIVEC_ABI)
17289 info_ptr->vrsave_mask = compute_vrsave_mask ();
17290 else
17291 info_ptr->vrsave_mask = 0;
17293 if (TARGET_ALTIVEC_VRSAVE && info_ptr->vrsave_mask)
17294 info_ptr->vrsave_size = 4;
17295 else
17296 info_ptr->vrsave_size = 0;
17298 compute_save_world_info (info_ptr);
17300 /* Calculate the offsets. */
17301 switch (DEFAULT_ABI)
17303 case ABI_NONE:
17304 default:
17305 gcc_unreachable ();
17307 case ABI_AIX:
17308 case ABI_DARWIN:
17309 info_ptr->fp_save_offset = - info_ptr->fp_size;
17310 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
17312 if (TARGET_ALTIVEC_ABI)
17314 info_ptr->vrsave_save_offset
17315 = info_ptr->gp_save_offset - info_ptr->vrsave_size;
17317 /* Align stack so vector save area is on a quadword boundary.
17318 The padding goes above the vectors. */
17319 if (info_ptr->altivec_size != 0)
17320 info_ptr->altivec_padding_size
17321 = info_ptr->vrsave_save_offset & 0xF;
17322 else
17323 info_ptr->altivec_padding_size = 0;
17325 info_ptr->altivec_save_offset
17326 = info_ptr->vrsave_save_offset
17327 - info_ptr->altivec_padding_size
17328 - info_ptr->altivec_size;
17329 gcc_assert (info_ptr->altivec_size == 0
17330 || info_ptr->altivec_save_offset % 16 == 0);
17332 /* Adjust for AltiVec case. */
17333 info_ptr->ehrd_offset = info_ptr->altivec_save_offset - ehrd_size;
17335 else
17336 info_ptr->ehrd_offset = info_ptr->gp_save_offset - ehrd_size;
17337 info_ptr->cr_save_offset = reg_size; /* first word when 64-bit. */
17338 info_ptr->lr_save_offset = 2*reg_size;
17339 break;
17341 case ABI_V4:
17342 info_ptr->fp_save_offset = - info_ptr->fp_size;
17343 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
17344 info_ptr->cr_save_offset = info_ptr->gp_save_offset - info_ptr->cr_size;
17346 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
17348 /* Align stack so SPE GPR save area is aligned on a
17349 double-word boundary. */
17350 if (info_ptr->spe_gp_size != 0 && info_ptr->cr_save_offset != 0)
17351 info_ptr->spe_padding_size
17352 = 8 - (-info_ptr->cr_save_offset % 8);
17353 else
17354 info_ptr->spe_padding_size = 0;
17356 info_ptr->spe_gp_save_offset
17357 = info_ptr->cr_save_offset
17358 - info_ptr->spe_padding_size
17359 - info_ptr->spe_gp_size;
17361 /* Adjust for SPE case. */
17362 info_ptr->ehrd_offset = info_ptr->spe_gp_save_offset;
17364 else if (TARGET_ALTIVEC_ABI)
17366 info_ptr->vrsave_save_offset
17367 = info_ptr->cr_save_offset - info_ptr->vrsave_size;
17369 /* Align stack so vector save area is on a quadword boundary. */
17370 if (info_ptr->altivec_size != 0)
17371 info_ptr->altivec_padding_size
17372 = 16 - (-info_ptr->vrsave_save_offset % 16);
17373 else
17374 info_ptr->altivec_padding_size = 0;
17376 info_ptr->altivec_save_offset
17377 = info_ptr->vrsave_save_offset
17378 - info_ptr->altivec_padding_size
17379 - info_ptr->altivec_size;
17381 /* Adjust for AltiVec case. */
17382 info_ptr->ehrd_offset = info_ptr->altivec_save_offset;
17384 else
17385 info_ptr->ehrd_offset = info_ptr->cr_save_offset;
17386 info_ptr->ehrd_offset -= ehrd_size;
17387 info_ptr->lr_save_offset = reg_size;
17388 break;
17391 save_align = (TARGET_ALTIVEC_ABI || DEFAULT_ABI == ABI_DARWIN) ? 16 : 8;
17392 info_ptr->save_size = RS6000_ALIGN (info_ptr->fp_size
17393 + info_ptr->gp_size
17394 + info_ptr->altivec_size
17395 + info_ptr->altivec_padding_size
17396 + info_ptr->spe_gp_size
17397 + info_ptr->spe_padding_size
17398 + ehrd_size
17399 + info_ptr->cr_size
17400 + info_ptr->vrsave_size,
17401 save_align);
17403 non_fixed_size = (info_ptr->vars_size
17404 + info_ptr->parm_size
17405 + info_ptr->save_size);
17407 info_ptr->total_size = RS6000_ALIGN (non_fixed_size + info_ptr->fixed_size,
17408 ABI_STACK_BOUNDARY / BITS_PER_UNIT);
17410 /* Determine if we need to allocate any stack frame:
17412 For AIX we need to push the stack if a frame pointer is needed
17413 (because the stack might be dynamically adjusted), if we are
17414 debugging, if we make calls, or if the sum of fp_save, gp_save,
17415 and local variables are more than the space needed to save all
17416 non-volatile registers: 32-bit: 18*8 + 19*4 = 220 or 64-bit: 18*8
17417 + 18*8 = 288 (GPR13 reserved).
17419 For V.4 we don't have the stack cushion that AIX uses, but assume
17420 that the debugger can handle stackless frames. */
17422 if (info_ptr->calls_p)
17423 info_ptr->push_p = 1;
17425 else if (DEFAULT_ABI == ABI_V4)
17426 info_ptr->push_p = non_fixed_size != 0;
17428 else if (frame_pointer_needed)
17429 info_ptr->push_p = 1;
17431 else if (TARGET_XCOFF && write_symbols != NO_DEBUG)
17432 info_ptr->push_p = 1;
17434 else
17435 info_ptr->push_p = non_fixed_size > (TARGET_32BIT ? 220 : 288);
17437 /* Zero offsets if we're not saving those registers. */
17438 if (info_ptr->fp_size == 0)
17439 info_ptr->fp_save_offset = 0;
17441 if (info_ptr->gp_size == 0)
17442 info_ptr->gp_save_offset = 0;
17444 if (! TARGET_ALTIVEC_ABI || info_ptr->altivec_size == 0)
17445 info_ptr->altivec_save_offset = 0;
17447 if (! TARGET_ALTIVEC_ABI || info_ptr->vrsave_mask == 0)
17448 info_ptr->vrsave_save_offset = 0;
17450 if (! TARGET_SPE_ABI
17451 || info_ptr->spe_64bit_regs_used == 0
17452 || info_ptr->spe_gp_size == 0)
17453 info_ptr->spe_gp_save_offset = 0;
17455 if (! info_ptr->lr_save_p)
17456 info_ptr->lr_save_offset = 0;
17458 if (! info_ptr->cr_save_p)
17459 info_ptr->cr_save_offset = 0;
17461 return info_ptr;
17464 /* Return true if the current function uses any GPRs in 64-bit SIMD
17465 mode. */
17467 static bool
17468 spe_func_has_64bit_regs_p (void)
17470 rtx insns, insn;
17472 /* Functions that save and restore all the call-saved registers will
17473 need to save/restore the registers in 64-bits. */
17474 if (crtl->calls_eh_return
17475 || cfun->calls_setjmp
17476 || crtl->has_nonlocal_goto)
17477 return true;
17479 insns = get_insns ();
17481 for (insn = NEXT_INSN (insns); insn != NULL_RTX; insn = NEXT_INSN (insn))
17483 if (INSN_P (insn))
17485 rtx i;
17487 /* FIXME: This should be implemented with attributes...
17489 (set_attr "spe64" "true")....then,
17490 if (get_spe64(insn)) return true;
17492 It's the only reliable way to do the stuff below. */
17494 i = PATTERN (insn);
17495 if (GET_CODE (i) == SET)
17497 enum machine_mode mode = GET_MODE (SET_SRC (i));
17499 if (SPE_VECTOR_MODE (mode))
17500 return true;
17501 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode))
17502 return true;
17507 return false;
17510 static void
17511 debug_stack_info (rs6000_stack_t *info)
17513 const char *abi_string;
17515 if (! info)
17516 info = rs6000_stack_info ();
17518 fprintf (stderr, "\nStack information for function %s:\n",
17519 ((current_function_decl && DECL_NAME (current_function_decl))
17520 ? IDENTIFIER_POINTER (DECL_NAME (current_function_decl))
17521 : "<unknown>"));
17523 switch (info->abi)
17525 default: abi_string = "Unknown"; break;
17526 case ABI_NONE: abi_string = "NONE"; break;
17527 case ABI_AIX: abi_string = "AIX"; break;
17528 case ABI_DARWIN: abi_string = "Darwin"; break;
17529 case ABI_V4: abi_string = "V.4"; break;
17532 fprintf (stderr, "\tABI = %5s\n", abi_string);
17534 if (TARGET_ALTIVEC_ABI)
17535 fprintf (stderr, "\tALTIVEC ABI extensions enabled.\n");
17537 if (TARGET_SPE_ABI)
17538 fprintf (stderr, "\tSPE ABI extensions enabled.\n");
17540 if (info->first_gp_reg_save != 32)
17541 fprintf (stderr, "\tfirst_gp_reg_save = %5d\n", info->first_gp_reg_save);
17543 if (info->first_fp_reg_save != 64)
17544 fprintf (stderr, "\tfirst_fp_reg_save = %5d\n", info->first_fp_reg_save);
17546 if (info->first_altivec_reg_save <= LAST_ALTIVEC_REGNO)
17547 fprintf (stderr, "\tfirst_altivec_reg_save = %5d\n",
17548 info->first_altivec_reg_save);
17550 if (info->lr_save_p)
17551 fprintf (stderr, "\tlr_save_p = %5d\n", info->lr_save_p);
17553 if (info->cr_save_p)
17554 fprintf (stderr, "\tcr_save_p = %5d\n", info->cr_save_p);
17556 if (info->vrsave_mask)
17557 fprintf (stderr, "\tvrsave_mask = 0x%x\n", info->vrsave_mask);
17559 if (info->push_p)
17560 fprintf (stderr, "\tpush_p = %5d\n", info->push_p);
17562 if (info->calls_p)
17563 fprintf (stderr, "\tcalls_p = %5d\n", info->calls_p);
17565 if (info->gp_save_offset)
17566 fprintf (stderr, "\tgp_save_offset = %5d\n", info->gp_save_offset);
17568 if (info->fp_save_offset)
17569 fprintf (stderr, "\tfp_save_offset = %5d\n", info->fp_save_offset);
17571 if (info->altivec_save_offset)
17572 fprintf (stderr, "\taltivec_save_offset = %5d\n",
17573 info->altivec_save_offset);
17575 if (info->spe_gp_save_offset)
17576 fprintf (stderr, "\tspe_gp_save_offset = %5d\n",
17577 info->spe_gp_save_offset);
17579 if (info->vrsave_save_offset)
17580 fprintf (stderr, "\tvrsave_save_offset = %5d\n",
17581 info->vrsave_save_offset);
17583 if (info->lr_save_offset)
17584 fprintf (stderr, "\tlr_save_offset = %5d\n", info->lr_save_offset);
17586 if (info->cr_save_offset)
17587 fprintf (stderr, "\tcr_save_offset = %5d\n", info->cr_save_offset);
17589 if (info->varargs_save_offset)
17590 fprintf (stderr, "\tvarargs_save_offset = %5d\n", info->varargs_save_offset);
17592 if (info->total_size)
17593 fprintf (stderr, "\ttotal_size = "HOST_WIDE_INT_PRINT_DEC"\n",
17594 info->total_size);
17596 if (info->vars_size)
17597 fprintf (stderr, "\tvars_size = "HOST_WIDE_INT_PRINT_DEC"\n",
17598 info->vars_size);
17600 if (info->parm_size)
17601 fprintf (stderr, "\tparm_size = %5d\n", info->parm_size);
17603 if (info->fixed_size)
17604 fprintf (stderr, "\tfixed_size = %5d\n", info->fixed_size);
17606 if (info->gp_size)
17607 fprintf (stderr, "\tgp_size = %5d\n", info->gp_size);
17609 if (info->spe_gp_size)
17610 fprintf (stderr, "\tspe_gp_size = %5d\n", info->spe_gp_size);
17612 if (info->fp_size)
17613 fprintf (stderr, "\tfp_size = %5d\n", info->fp_size);
17615 if (info->altivec_size)
17616 fprintf (stderr, "\taltivec_size = %5d\n", info->altivec_size);
17618 if (info->vrsave_size)
17619 fprintf (stderr, "\tvrsave_size = %5d\n", info->vrsave_size);
17621 if (info->altivec_padding_size)
17622 fprintf (stderr, "\taltivec_padding_size= %5d\n",
17623 info->altivec_padding_size);
17625 if (info->spe_padding_size)
17626 fprintf (stderr, "\tspe_padding_size = %5d\n",
17627 info->spe_padding_size);
17629 if (info->cr_size)
17630 fprintf (stderr, "\tcr_size = %5d\n", info->cr_size);
17632 if (info->save_size)
17633 fprintf (stderr, "\tsave_size = %5d\n", info->save_size);
17635 if (info->reg_size != 4)
17636 fprintf (stderr, "\treg_size = %5d\n", info->reg_size);
17638 fprintf (stderr, "\n");
17642 rs6000_return_addr (int count, rtx frame)
17644 /* Currently we don't optimize very well between prolog and body
17645 code and for PIC code the code can be actually quite bad, so
17646 don't try to be too clever here. */
17647 if (count != 0 || (DEFAULT_ABI != ABI_AIX && flag_pic))
17649 cfun->machine->ra_needs_full_frame = 1;
17651 return
17652 gen_rtx_MEM
17653 (Pmode,
17654 memory_address
17655 (Pmode,
17656 plus_constant (copy_to_reg
17657 (gen_rtx_MEM (Pmode,
17658 memory_address (Pmode, frame))),
17659 RETURN_ADDRESS_OFFSET)));
17662 cfun->machine->ra_need_lr = 1;
17663 return get_hard_reg_initial_val (Pmode, LR_REGNO);
17666 /* Say whether a function is a candidate for sibcall handling or not.
17667 We do not allow indirect calls to be optimized into sibling calls.
17668 Also, we can't do it if there are any vector parameters; there's
17669 nowhere to put the VRsave code so it works; note that functions with
17670 vector parameters are required to have a prototype, so the argument
17671 type info must be available here. (The tail recursion case can work
17672 with vector parameters, but there's no way to distinguish here.) */
17673 static bool
17674 rs6000_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED)
17676 tree type;
17677 if (decl)
17679 if (TARGET_ALTIVEC_VRSAVE)
17681 for (type = TYPE_ARG_TYPES (TREE_TYPE (decl));
17682 type; type = TREE_CHAIN (type))
17684 if (TREE_CODE (TREE_VALUE (type)) == VECTOR_TYPE)
17685 return false;
17688 if (DEFAULT_ABI == ABI_DARWIN
17689 || ((*targetm.binds_local_p) (decl)
17690 && (DEFAULT_ABI != ABI_AIX || !DECL_EXTERNAL (decl))))
17692 tree attr_list = TYPE_ATTRIBUTES (TREE_TYPE (decl));
17694 if (!lookup_attribute ("longcall", attr_list)
17695 || lookup_attribute ("shortcall", attr_list))
17696 return true;
17699 return false;
17702 /* NULL if INSN insn is valid within a low-overhead loop.
17703 Otherwise return why doloop cannot be applied.
17704 PowerPC uses the COUNT register for branch on table instructions. */
17706 static const char *
17707 rs6000_invalid_within_doloop (const_rtx insn)
17709 if (CALL_P (insn))
17710 return "Function call in the loop.";
17712 if (JUMP_P (insn)
17713 && (GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC
17714 || GET_CODE (PATTERN (insn)) == ADDR_VEC))
17715 return "Computed branch in the loop.";
17717 return NULL;
17720 static int
17721 rs6000_ra_ever_killed (void)
17723 rtx top;
17724 rtx reg;
17725 rtx insn;
17727 if (cfun->is_thunk)
17728 return 0;
17730 /* regs_ever_live has LR marked as used if any sibcalls are present,
17731 but this should not force saving and restoring in the
17732 pro/epilogue. Likewise, reg_set_between_p thinks a sibcall
17733 clobbers LR, so that is inappropriate. */
17735 /* Also, the prologue can generate a store into LR that
17736 doesn't really count, like this:
17738 move LR->R0
17739 bcl to set PIC register
17740 move LR->R31
17741 move R0->LR
17743 When we're called from the epilogue, we need to avoid counting
17744 this as a store. */
17746 push_topmost_sequence ();
17747 top = get_insns ();
17748 pop_topmost_sequence ();
17749 reg = gen_rtx_REG (Pmode, LR_REGNO);
17751 for (insn = NEXT_INSN (top); insn != NULL_RTX; insn = NEXT_INSN (insn))
17753 if (INSN_P (insn))
17755 if (CALL_P (insn))
17757 if (!SIBLING_CALL_P (insn))
17758 return 1;
17760 else if (find_regno_note (insn, REG_INC, LR_REGNO))
17761 return 1;
17762 else if (set_of (reg, insn) != NULL_RTX
17763 && !prologue_epilogue_contains (insn))
17764 return 1;
17767 return 0;
17770 /* Emit instructions needed to load the TOC register.
17771 This is only needed when TARGET_TOC, TARGET_MINIMAL_TOC, and there is
17772 a constant pool; or for SVR4 -fpic. */
17774 void
17775 rs6000_emit_load_toc_table (int fromprolog)
17777 rtx dest;
17778 dest = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
17780 if (TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI != ABI_AIX && flag_pic)
17782 char buf[30];
17783 rtx lab, tmp1, tmp2, got;
17785 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
17786 lab = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
17787 if (flag_pic == 2)
17788 got = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
17789 else
17790 got = rs6000_got_sym ();
17791 tmp1 = tmp2 = dest;
17792 if (!fromprolog)
17794 tmp1 = gen_reg_rtx (Pmode);
17795 tmp2 = gen_reg_rtx (Pmode);
17797 emit_insn (gen_load_toc_v4_PIC_1 (lab));
17798 emit_move_insn (tmp1,
17799 gen_rtx_REG (Pmode, LR_REGNO));
17800 emit_insn (gen_load_toc_v4_PIC_3b (tmp2, tmp1, got, lab));
17801 emit_insn (gen_load_toc_v4_PIC_3c (dest, tmp2, got, lab));
17803 else if (TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 1)
17805 emit_insn (gen_load_toc_v4_pic_si ());
17806 emit_move_insn (dest, gen_rtx_REG (Pmode, LR_REGNO));
17808 else if (TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2)
17810 char buf[30];
17811 rtx temp0 = (fromprolog
17812 ? gen_rtx_REG (Pmode, 0)
17813 : gen_reg_rtx (Pmode));
17815 if (fromprolog)
17817 rtx symF, symL;
17819 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
17820 symF = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
17822 ASM_GENERATE_INTERNAL_LABEL (buf, "LCL", rs6000_pic_labelno);
17823 symL = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
17825 emit_insn (gen_load_toc_v4_PIC_1 (symF));
17826 emit_move_insn (dest,
17827 gen_rtx_REG (Pmode, LR_REGNO));
17828 emit_insn (gen_load_toc_v4_PIC_2 (temp0, dest, symL, symF));
17830 else
17832 rtx tocsym;
17834 tocsym = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
17835 emit_insn (gen_load_toc_v4_PIC_1b (tocsym));
17836 emit_move_insn (dest,
17837 gen_rtx_REG (Pmode, LR_REGNO));
17838 emit_move_insn (temp0, gen_rtx_MEM (Pmode, dest));
17840 emit_insn (gen_addsi3 (dest, temp0, dest));
17842 else if (TARGET_ELF && !TARGET_AIX && flag_pic == 0 && TARGET_MINIMAL_TOC)
17844 /* This is for AIX code running in non-PIC ELF32. */
17845 char buf[30];
17846 rtx realsym;
17847 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
17848 realsym = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
17850 emit_insn (gen_elf_high (dest, realsym));
17851 emit_insn (gen_elf_low (dest, dest, realsym));
17853 else
17855 gcc_assert (DEFAULT_ABI == ABI_AIX);
17857 if (TARGET_32BIT)
17858 emit_insn (gen_load_toc_aix_si (dest));
17859 else
17860 emit_insn (gen_load_toc_aix_di (dest));
17864 /* Emit instructions to restore the link register after determining where
17865 its value has been stored. */
17867 void
17868 rs6000_emit_eh_reg_restore (rtx source, rtx scratch)
17870 rs6000_stack_t *info = rs6000_stack_info ();
17871 rtx operands[2];
17873 operands[0] = source;
17874 operands[1] = scratch;
17876 if (info->lr_save_p)
17878 rtx frame_rtx = stack_pointer_rtx;
17879 HOST_WIDE_INT sp_offset = 0;
17880 rtx tmp;
17882 if (frame_pointer_needed
17883 || cfun->calls_alloca
17884 || info->total_size > 32767)
17886 tmp = gen_frame_mem (Pmode, frame_rtx);
17887 emit_move_insn (operands[1], tmp);
17888 frame_rtx = operands[1];
17890 else if (info->push_p)
17891 sp_offset = info->total_size;
17893 tmp = plus_constant (frame_rtx, info->lr_save_offset + sp_offset);
17894 tmp = gen_frame_mem (Pmode, tmp);
17895 emit_move_insn (tmp, operands[0]);
17897 else
17898 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO), operands[0]);
17901 static GTY(()) alias_set_type set = -1;
17903 alias_set_type
17904 get_TOC_alias_set (void)
17906 if (set == -1)
17907 set = new_alias_set ();
17908 return set;
17911 /* This returns nonzero if the current function uses the TOC. This is
17912 determined by the presence of (use (unspec ... UNSPEC_TOC)), which
17913 is generated by the ABI_V4 load_toc_* patterns. */
17914 #if TARGET_ELF
17915 static int
17916 uses_TOC (void)
17918 rtx insn;
17920 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
17921 if (INSN_P (insn))
17923 rtx pat = PATTERN (insn);
17924 int i;
17926 if (GET_CODE (pat) == PARALLEL)
17927 for (i = 0; i < XVECLEN (pat, 0); i++)
17929 rtx sub = XVECEXP (pat, 0, i);
17930 if (GET_CODE (sub) == USE)
17932 sub = XEXP (sub, 0);
17933 if (GET_CODE (sub) == UNSPEC
17934 && XINT (sub, 1) == UNSPEC_TOC)
17935 return 1;
17939 return 0;
17941 #endif
17944 create_TOC_reference (rtx symbol)
17946 if (TARGET_DEBUG_ADDR)
17948 if (GET_CODE (symbol) == SYMBOL_REF)
17949 fprintf (stderr, "\ncreate_TOC_reference, (symbol_ref %s)\n",
17950 XSTR (symbol, 0));
17951 else
17953 fprintf (stderr, "\ncreate_TOC_reference, code %s:\n",
17954 GET_RTX_NAME (GET_CODE (symbol)));
17955 debug_rtx (symbol);
17959 if (!can_create_pseudo_p ())
17960 df_set_regs_ever_live (TOC_REGISTER, true);
17961 return gen_rtx_PLUS (Pmode,
17962 gen_rtx_REG (Pmode, TOC_REGISTER),
17963 gen_rtx_CONST (Pmode,
17964 gen_rtx_UNSPEC (Pmode, gen_rtvec (1, symbol), UNSPEC_TOCREL)));
17967 /* Issue assembly directives that create a reference to the given DWARF
17968 FRAME_TABLE_LABEL from the current function section. */
17969 void
17970 rs6000_aix_asm_output_dwarf_table_ref (char * frame_table_label)
17972 fprintf (asm_out_file, "\t.ref %s\n",
17973 TARGET_STRIP_NAME_ENCODING (frame_table_label));
17976 /* If _Unwind_* has been called from within the same module,
17977 toc register is not guaranteed to be saved to 40(1) on function
17978 entry. Save it there in that case. */
17980 void
17981 rs6000_aix_emit_builtin_unwind_init (void)
17983 rtx mem;
17984 rtx stack_top = gen_reg_rtx (Pmode);
17985 rtx opcode_addr = gen_reg_rtx (Pmode);
17986 rtx opcode = gen_reg_rtx (SImode);
17987 rtx tocompare = gen_reg_rtx (SImode);
17988 rtx no_toc_save_needed = gen_label_rtx ();
17990 mem = gen_frame_mem (Pmode, hard_frame_pointer_rtx);
17991 emit_move_insn (stack_top, mem);
17993 mem = gen_frame_mem (Pmode,
17994 gen_rtx_PLUS (Pmode, stack_top,
17995 GEN_INT (2 * GET_MODE_SIZE (Pmode))));
17996 emit_move_insn (opcode_addr, mem);
17997 emit_move_insn (opcode, gen_rtx_MEM (SImode, opcode_addr));
17998 emit_move_insn (tocompare, gen_int_mode (TARGET_32BIT ? 0x80410014
17999 : 0xE8410028, SImode));
18001 do_compare_rtx_and_jump (opcode, tocompare, EQ, 1,
18002 SImode, NULL_RTX, NULL_RTX,
18003 no_toc_save_needed, -1);
18005 mem = gen_frame_mem (Pmode,
18006 gen_rtx_PLUS (Pmode, stack_top,
18007 GEN_INT (5 * GET_MODE_SIZE (Pmode))));
18008 emit_move_insn (mem, gen_rtx_REG (Pmode, 2));
18009 emit_label (no_toc_save_needed);
18012 /* This ties together stack memory (MEM with an alias set of frame_alias_set)
18013 and the change to the stack pointer. */
18015 static void
18016 rs6000_emit_stack_tie (void)
18018 rtx mem = gen_frame_mem (BLKmode,
18019 gen_rtx_REG (Pmode, STACK_POINTER_REGNUM));
18021 emit_insn (gen_stack_tie (mem));
18024 /* Emit the correct code for allocating stack space, as insns.
18025 If COPY_R12, make sure a copy of the old frame is left in r12.
18026 If COPY_R11, make sure a copy of the old frame is left in r11,
18027 in preference to r12 if COPY_R12.
18028 The generated code may use hard register 0 as a temporary. */
18030 static void
18031 rs6000_emit_allocate_stack (HOST_WIDE_INT size, int copy_r12, int copy_r11)
18033 rtx insn;
18034 rtx stack_reg = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
18035 rtx tmp_reg = gen_rtx_REG (Pmode, 0);
18036 rtx todec = gen_int_mode (-size, Pmode);
18037 rtx par, set, mem;
18039 if (INTVAL (todec) != -size)
18041 warning (0, "stack frame too large");
18042 emit_insn (gen_trap ());
18043 return;
18046 if (crtl->limit_stack)
18048 if (REG_P (stack_limit_rtx)
18049 && REGNO (stack_limit_rtx) > 1
18050 && REGNO (stack_limit_rtx) <= 31)
18052 emit_insn (gen_add3_insn (tmp_reg, stack_limit_rtx, GEN_INT (size)));
18053 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
18054 const0_rtx));
18056 else if (GET_CODE (stack_limit_rtx) == SYMBOL_REF
18057 && TARGET_32BIT
18058 && DEFAULT_ABI == ABI_V4)
18060 rtx toload = gen_rtx_CONST (VOIDmode,
18061 gen_rtx_PLUS (Pmode,
18062 stack_limit_rtx,
18063 GEN_INT (size)));
18065 emit_insn (gen_elf_high (tmp_reg, toload));
18066 emit_insn (gen_elf_low (tmp_reg, tmp_reg, toload));
18067 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
18068 const0_rtx));
18070 else
18071 warning (0, "stack limit expression is not supported");
18074 if (copy_r12 || copy_r11)
18075 emit_move_insn (copy_r11
18076 ? gen_rtx_REG (Pmode, 11)
18077 : gen_rtx_REG (Pmode, 12),
18078 stack_reg);
18080 if (size > 32767)
18082 /* Need a note here so that try_split doesn't get confused. */
18083 if (get_last_insn () == NULL_RTX)
18084 emit_note (NOTE_INSN_DELETED);
18085 insn = emit_move_insn (tmp_reg, todec);
18086 try_split (PATTERN (insn), insn, 0);
18087 todec = tmp_reg;
18090 insn = emit_insn (TARGET_32BIT
18091 ? gen_movsi_update_stack (stack_reg, stack_reg,
18092 todec, stack_reg)
18093 : gen_movdi_di_update_stack (stack_reg, stack_reg,
18094 todec, stack_reg));
18095 /* Since we didn't use gen_frame_mem to generate the MEM, grab
18096 it now and set the alias set/attributes. The above gen_*_update
18097 calls will generate a PARALLEL with the MEM set being the first
18098 operation. */
18099 par = PATTERN (insn);
18100 gcc_assert (GET_CODE (par) == PARALLEL);
18101 set = XVECEXP (par, 0, 0);
18102 gcc_assert (GET_CODE (set) == SET);
18103 mem = SET_DEST (set);
18104 gcc_assert (MEM_P (mem));
18105 MEM_NOTRAP_P (mem) = 1;
18106 set_mem_alias_set (mem, get_frame_alias_set ());
18108 RTX_FRAME_RELATED_P (insn) = 1;
18109 add_reg_note (insn, REG_FRAME_RELATED_EXPR,
18110 gen_rtx_SET (VOIDmode, stack_reg,
18111 gen_rtx_PLUS (Pmode, stack_reg,
18112 GEN_INT (-size))));
18115 /* Add to 'insn' a note which is PATTERN (INSN) but with REG replaced
18116 with (plus:P (reg 1) VAL), and with REG2 replaced with RREG if REG2
18117 is not NULL. It would be nice if dwarf2out_frame_debug_expr could
18118 deduce these equivalences by itself so it wasn't necessary to hold
18119 its hand so much. */
18121 static void
18122 rs6000_frame_related (rtx insn, rtx reg, HOST_WIDE_INT val,
18123 rtx reg2, rtx rreg)
18125 rtx real, temp;
18127 /* copy_rtx will not make unique copies of registers, so we need to
18128 ensure we don't have unwanted sharing here. */
18129 if (reg == reg2)
18130 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
18132 if (reg == rreg)
18133 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
18135 real = copy_rtx (PATTERN (insn));
18137 if (reg2 != NULL_RTX)
18138 real = replace_rtx (real, reg2, rreg);
18140 real = replace_rtx (real, reg,
18141 gen_rtx_PLUS (Pmode, gen_rtx_REG (Pmode,
18142 STACK_POINTER_REGNUM),
18143 GEN_INT (val)));
18145 /* We expect that 'real' is either a SET or a PARALLEL containing
18146 SETs (and possibly other stuff). In a PARALLEL, all the SETs
18147 are important so they all have to be marked RTX_FRAME_RELATED_P. */
18149 if (GET_CODE (real) == SET)
18151 rtx set = real;
18153 temp = simplify_rtx (SET_SRC (set));
18154 if (temp)
18155 SET_SRC (set) = temp;
18156 temp = simplify_rtx (SET_DEST (set));
18157 if (temp)
18158 SET_DEST (set) = temp;
18159 if (GET_CODE (SET_DEST (set)) == MEM)
18161 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
18162 if (temp)
18163 XEXP (SET_DEST (set), 0) = temp;
18166 else
18168 int i;
18170 gcc_assert (GET_CODE (real) == PARALLEL);
18171 for (i = 0; i < XVECLEN (real, 0); i++)
18172 if (GET_CODE (XVECEXP (real, 0, i)) == SET)
18174 rtx set = XVECEXP (real, 0, i);
18176 temp = simplify_rtx (SET_SRC (set));
18177 if (temp)
18178 SET_SRC (set) = temp;
18179 temp = simplify_rtx (SET_DEST (set));
18180 if (temp)
18181 SET_DEST (set) = temp;
18182 if (GET_CODE (SET_DEST (set)) == MEM)
18184 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
18185 if (temp)
18186 XEXP (SET_DEST (set), 0) = temp;
18188 RTX_FRAME_RELATED_P (set) = 1;
18192 RTX_FRAME_RELATED_P (insn) = 1;
18193 add_reg_note (insn, REG_FRAME_RELATED_EXPR, real);
18196 /* Returns an insn that has a vrsave set operation with the
18197 appropriate CLOBBERs. */
18199 static rtx
18200 generate_set_vrsave (rtx reg, rs6000_stack_t *info, int epiloguep)
18202 int nclobs, i;
18203 rtx insn, clobs[TOTAL_ALTIVEC_REGS + 1];
18204 rtx vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
18206 clobs[0]
18207 = gen_rtx_SET (VOIDmode,
18208 vrsave,
18209 gen_rtx_UNSPEC_VOLATILE (SImode,
18210 gen_rtvec (2, reg, vrsave),
18211 UNSPECV_SET_VRSAVE));
18213 nclobs = 1;
18215 /* We need to clobber the registers in the mask so the scheduler
18216 does not move sets to VRSAVE before sets of AltiVec registers.
18218 However, if the function receives nonlocal gotos, reload will set
18219 all call saved registers live. We will end up with:
18221 (set (reg 999) (mem))
18222 (parallel [ (set (reg vrsave) (unspec blah))
18223 (clobber (reg 999))])
18225 The clobber will cause the store into reg 999 to be dead, and
18226 flow will attempt to delete an epilogue insn. In this case, we
18227 need an unspec use/set of the register. */
18229 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
18230 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
18232 if (!epiloguep || call_used_regs [i])
18233 clobs[nclobs++] = gen_rtx_CLOBBER (VOIDmode,
18234 gen_rtx_REG (V4SImode, i));
18235 else
18237 rtx reg = gen_rtx_REG (V4SImode, i);
18239 clobs[nclobs++]
18240 = gen_rtx_SET (VOIDmode,
18241 reg,
18242 gen_rtx_UNSPEC (V4SImode,
18243 gen_rtvec (1, reg), 27));
18247 insn = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (nclobs));
18249 for (i = 0; i < nclobs; ++i)
18250 XVECEXP (insn, 0, i) = clobs[i];
18252 return insn;
18255 /* Save a register into the frame, and emit RTX_FRAME_RELATED_P notes.
18256 Save REGNO into [FRAME_REG + OFFSET] in mode MODE. */
18258 static void
18259 emit_frame_save (rtx frame_reg, rtx frame_ptr, enum machine_mode mode,
18260 unsigned int regno, int offset, HOST_WIDE_INT total_size)
18262 rtx reg, offset_rtx, insn, mem, addr, int_rtx;
18263 rtx replacea, replaceb;
18265 int_rtx = GEN_INT (offset);
18267 /* Some cases that need register indexed addressing. */
18268 if ((TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
18269 || (TARGET_VSX && VSX_VECTOR_MODE (mode))
18270 || (TARGET_E500_DOUBLE && mode == DFmode)
18271 || (TARGET_SPE_ABI
18272 && SPE_VECTOR_MODE (mode)
18273 && !SPE_CONST_OFFSET_OK (offset)))
18275 /* Whomever calls us must make sure r11 is available in the
18276 flow path of instructions in the prologue. */
18277 offset_rtx = gen_rtx_REG (Pmode, 11);
18278 emit_move_insn (offset_rtx, int_rtx);
18280 replacea = offset_rtx;
18281 replaceb = int_rtx;
18283 else
18285 offset_rtx = int_rtx;
18286 replacea = NULL_RTX;
18287 replaceb = NULL_RTX;
18290 reg = gen_rtx_REG (mode, regno);
18291 addr = gen_rtx_PLUS (Pmode, frame_reg, offset_rtx);
18292 mem = gen_frame_mem (mode, addr);
18294 insn = emit_move_insn (mem, reg);
18296 rs6000_frame_related (insn, frame_ptr, total_size, replacea, replaceb);
18299 /* Emit an offset memory reference suitable for a frame store, while
18300 converting to a valid addressing mode. */
18302 static rtx
18303 gen_frame_mem_offset (enum machine_mode mode, rtx reg, int offset)
18305 rtx int_rtx, offset_rtx;
18307 int_rtx = GEN_INT (offset);
18309 if ((TARGET_SPE_ABI && SPE_VECTOR_MODE (mode))
18310 || (TARGET_E500_DOUBLE && mode == DFmode))
18312 offset_rtx = gen_rtx_REG (Pmode, FIXED_SCRATCH);
18313 emit_move_insn (offset_rtx, int_rtx);
18315 else
18316 offset_rtx = int_rtx;
18318 return gen_frame_mem (mode, gen_rtx_PLUS (Pmode, reg, offset_rtx));
18321 /* Look for user-defined global regs. We should not save and restore these,
18322 and cannot use stmw/lmw if there are any in its range. */
18324 static bool
18325 no_global_regs_above (int first, bool gpr)
18327 int i;
18328 int last = gpr ? 32 : 64;
18329 for (i = first; i < last; i++)
18330 if (global_regs[i])
18331 return false;
18332 return true;
18335 #ifndef TARGET_FIX_AND_CONTINUE
18336 #define TARGET_FIX_AND_CONTINUE 0
18337 #endif
18339 /* It's really GPR 13 and FPR 14, but we need the smaller of the two. */
18340 #define FIRST_SAVRES_REGISTER FIRST_SAVED_GP_REGNO
18341 #define LAST_SAVRES_REGISTER 31
18342 #define N_SAVRES_REGISTERS (LAST_SAVRES_REGISTER - FIRST_SAVRES_REGISTER + 1)
18344 static GTY(()) rtx savres_routine_syms[N_SAVRES_REGISTERS][8];
18346 /* Temporary holding space for an out-of-line register save/restore
18347 routine name. */
18348 static char savres_routine_name[30];
18350 /* Return the name for an out-of-line register save/restore routine.
18351 We are saving/restoring GPRs if GPR is true. */
18353 static char *
18354 rs6000_savres_routine_name (rs6000_stack_t *info, int regno,
18355 bool savep, bool gpr, bool lr)
18357 const char *prefix = "";
18358 const char *suffix = "";
18360 /* Different targets are supposed to define
18361 {SAVE,RESTORE}_FP_{PREFIX,SUFFIX} with the idea that the needed
18362 routine name could be defined with:
18364 sprintf (name, "%s%d%s", SAVE_FP_PREFIX, regno, SAVE_FP_SUFFIX)
18366 This is a nice idea in practice, but in reality, things are
18367 complicated in several ways:
18369 - ELF targets have save/restore routines for GPRs.
18371 - SPE targets use different prefixes for 32/64-bit registers, and
18372 neither of them fit neatly in the FOO_{PREFIX,SUFFIX} regimen.
18374 - PPC64 ELF targets have routines for save/restore of GPRs that
18375 differ in what they do with the link register, so having a set
18376 prefix doesn't work. (We only use one of the save routines at
18377 the moment, though.)
18379 - PPC32 elf targets have "exit" versions of the restore routines
18380 that restore the link register and can save some extra space.
18381 These require an extra suffix. (There are also "tail" versions
18382 of the restore routines and "GOT" versions of the save routines,
18383 but we don't generate those at present. Same problems apply,
18384 though.)
18386 We deal with all this by synthesizing our own prefix/suffix and
18387 using that for the simple sprintf call shown above. */
18388 if (TARGET_SPE)
18390 /* No floating point saves on the SPE. */
18391 gcc_assert (gpr);
18393 if (savep)
18394 prefix = info->spe_64bit_regs_used ? "_save64gpr_" : "_save32gpr_";
18395 else
18396 prefix = info->spe_64bit_regs_used ? "_rest64gpr_" : "_rest32gpr_";
18398 if (lr)
18399 suffix = "_x";
18401 else if (DEFAULT_ABI == ABI_V4)
18403 if (TARGET_64BIT)
18404 goto aix_names;
18406 if (gpr)
18407 prefix = savep ? "_savegpr_" : "_restgpr_";
18408 else
18409 prefix = savep ? "_savefpr_" : "_restfpr_";
18411 if (lr)
18412 suffix = "_x";
18414 else if (DEFAULT_ABI == ABI_AIX)
18416 #ifndef POWERPC_LINUX
18417 /* No out-of-line save/restore routines for GPRs on AIX. */
18418 gcc_assert (!TARGET_AIX || !gpr);
18419 #endif
18421 aix_names:
18422 if (gpr)
18423 prefix = (savep
18424 ? (lr ? "_savegpr0_" : "_savegpr1_")
18425 : (lr ? "_restgpr0_" : "_restgpr1_"));
18426 #ifdef POWERPC_LINUX
18427 else if (lr)
18428 prefix = (savep ? "_savefpr_" : "_restfpr_");
18429 #endif
18430 else
18432 prefix = savep ? SAVE_FP_PREFIX : RESTORE_FP_PREFIX;
18433 suffix = savep ? SAVE_FP_SUFFIX : RESTORE_FP_SUFFIX;
18436 else if (DEFAULT_ABI == ABI_DARWIN)
18437 sorry ("Out-of-line save/restore routines not supported on Darwin");
18439 sprintf (savres_routine_name, "%s%d%s", prefix, regno, suffix);
18441 return savres_routine_name;
18444 /* Return an RTL SYMBOL_REF for an out-of-line register save/restore routine.
18445 We are saving/restoring GPRs if GPR is true. */
18447 static rtx
18448 rs6000_savres_routine_sym (rs6000_stack_t *info, bool savep,
18449 bool gpr, bool lr)
18451 int regno = gpr ? info->first_gp_reg_save : (info->first_fp_reg_save - 32);
18452 rtx sym;
18453 int select = ((savep ? 1 : 0) << 2
18454 | ((TARGET_SPE_ABI
18455 /* On the SPE, we never have any FPRs, but we do have
18456 32/64-bit versions of the routines. */
18457 ? (info->spe_64bit_regs_used ? 1 : 0)
18458 : (gpr ? 1 : 0)) << 1)
18459 | (lr ? 1: 0));
18461 /* Don't generate bogus routine names. */
18462 gcc_assert (FIRST_SAVRES_REGISTER <= regno
18463 && regno <= LAST_SAVRES_REGISTER);
18465 sym = savres_routine_syms[regno-FIRST_SAVRES_REGISTER][select];
18467 if (sym == NULL)
18469 char *name;
18471 name = rs6000_savres_routine_name (info, regno, savep, gpr, lr);
18473 sym = savres_routine_syms[regno-FIRST_SAVRES_REGISTER][select]
18474 = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (name));
18475 SYMBOL_REF_FLAGS (sym) |= SYMBOL_FLAG_FUNCTION;
18478 return sym;
18481 /* Emit a sequence of insns, including a stack tie if needed, for
18482 resetting the stack pointer. If SAVRES is true, then don't reset the
18483 stack pointer, but move the base of the frame into r11 for use by
18484 out-of-line register restore routines. */
18486 static rtx
18487 rs6000_emit_stack_reset (rs6000_stack_t *info,
18488 rtx sp_reg_rtx, rtx frame_reg_rtx,
18489 int sp_offset, bool savres)
18491 /* This blockage is needed so that sched doesn't decide to move
18492 the sp change before the register restores. */
18493 if (frame_reg_rtx != sp_reg_rtx
18494 || (TARGET_SPE_ABI
18495 && info->spe_64bit_regs_used != 0
18496 && info->first_gp_reg_save != 32))
18497 rs6000_emit_stack_tie ();
18499 if (frame_reg_rtx != sp_reg_rtx)
18501 if (sp_offset != 0)
18503 rtx dest_reg = savres ? gen_rtx_REG (Pmode, 11) : sp_reg_rtx;
18504 return emit_insn (gen_add3_insn (dest_reg, frame_reg_rtx,
18505 GEN_INT (sp_offset)));
18507 else if (!savres)
18508 return emit_move_insn (sp_reg_rtx, frame_reg_rtx);
18510 else if (sp_offset != 0)
18512 /* If we are restoring registers out-of-line, we will be using the
18513 "exit" variants of the restore routines, which will reset the
18514 stack for us. But we do need to point r11 into the right place
18515 for those routines. */
18516 rtx dest_reg = (savres
18517 ? gen_rtx_REG (Pmode, 11)
18518 : sp_reg_rtx);
18520 rtx insn = emit_insn (gen_add3_insn (dest_reg, sp_reg_rtx,
18521 GEN_INT (sp_offset)));
18522 if (!savres)
18523 return insn;
18525 return NULL_RTX;
18528 /* Construct a parallel rtx describing the effect of a call to an
18529 out-of-line register save/restore routine. */
18531 static rtx
18532 rs6000_make_savres_rtx (rs6000_stack_t *info,
18533 rtx frame_reg_rtx, int save_area_offset,
18534 enum machine_mode reg_mode,
18535 bool savep, bool gpr, bool lr)
18537 int i;
18538 int offset, start_reg, end_reg, n_regs;
18539 int reg_size = GET_MODE_SIZE (reg_mode);
18540 rtx sym;
18541 rtvec p;
18543 offset = 0;
18544 start_reg = (gpr
18545 ? info->first_gp_reg_save
18546 : info->first_fp_reg_save);
18547 end_reg = gpr ? 32 : 64;
18548 n_regs = end_reg - start_reg;
18549 p = rtvec_alloc ((lr ? 4 : 3) + n_regs);
18551 if (!savep && lr)
18552 RTVEC_ELT (p, offset++) = gen_rtx_RETURN (VOIDmode);
18554 RTVEC_ELT (p, offset++)
18555 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 65));
18557 sym = rs6000_savres_routine_sym (info, savep, gpr, lr);
18558 RTVEC_ELT (p, offset++) = gen_rtx_USE (VOIDmode, sym);
18559 RTVEC_ELT (p, offset++)
18560 = gen_rtx_USE (VOIDmode,
18561 gen_rtx_REG (Pmode, DEFAULT_ABI != ABI_AIX ? 11
18562 : gpr && !lr ? 12
18563 : 1));
18565 for (i = 0; i < end_reg - start_reg; i++)
18567 rtx addr, reg, mem;
18568 reg = gen_rtx_REG (reg_mode, start_reg + i);
18569 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18570 GEN_INT (save_area_offset + reg_size*i));
18571 mem = gen_frame_mem (reg_mode, addr);
18573 RTVEC_ELT (p, i + offset) = gen_rtx_SET (VOIDmode,
18574 savep ? mem : reg,
18575 savep ? reg : mem);
18578 if (savep && lr)
18580 rtx addr, reg, mem;
18581 reg = gen_rtx_REG (Pmode, 0);
18582 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18583 GEN_INT (info->lr_save_offset));
18584 mem = gen_frame_mem (Pmode, addr);
18585 RTVEC_ELT (p, i + offset) = gen_rtx_SET (VOIDmode, mem, reg);
18588 return gen_rtx_PARALLEL (VOIDmode, p);
18591 /* Determine whether the gp REG is really used. */
18593 static bool
18594 rs6000_reg_live_or_pic_offset_p (int reg)
18596 return ((df_regs_ever_live_p (reg)
18597 && (!call_used_regs[reg]
18598 || (reg == RS6000_PIC_OFFSET_TABLE_REGNUM
18599 && TARGET_TOC && TARGET_MINIMAL_TOC)))
18600 || (reg == RS6000_PIC_OFFSET_TABLE_REGNUM
18601 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
18602 || (DEFAULT_ABI == ABI_DARWIN && flag_pic))));
18605 enum {
18606 SAVRES_MULTIPLE = 0x1,
18607 SAVRES_INLINE_FPRS = 0x2,
18608 SAVRES_INLINE_GPRS = 0x4,
18609 SAVRES_NOINLINE_GPRS_SAVES_LR = 0x8,
18610 SAVRES_NOINLINE_FPRS_SAVES_LR = 0x10,
18611 SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR = 0x20
18614 /* Determine the strategy for savings/restoring registers. */
18616 static int
18617 rs6000_savres_strategy (rs6000_stack_t *info, bool savep,
18618 int using_static_chain_p, int sibcall)
18620 bool using_multiple_p;
18621 bool common;
18622 bool savres_fprs_inline;
18623 bool savres_gprs_inline;
18624 bool noclobber_global_gprs
18625 = no_global_regs_above (info->first_gp_reg_save, /*gpr=*/true);
18626 int strategy;
18628 using_multiple_p = (TARGET_MULTIPLE && ! TARGET_POWERPC64
18629 && (!TARGET_SPE_ABI
18630 || info->spe_64bit_regs_used == 0)
18631 && info->first_gp_reg_save < 31
18632 && noclobber_global_gprs);
18633 /* Don't bother to try to save things out-of-line if r11 is occupied
18634 by the static chain. It would require too much fiddling and the
18635 static chain is rarely used anyway. */
18636 common = (using_static_chain_p
18637 || sibcall
18638 || crtl->calls_eh_return
18639 || !info->lr_save_p
18640 || cfun->machine->ra_need_lr
18641 || info->total_size > 32767);
18642 savres_fprs_inline = (common
18643 || info->first_fp_reg_save == 64
18644 || !no_global_regs_above (info->first_fp_reg_save,
18645 /*gpr=*/false)
18646 /* The out-of-line FP routines use
18647 double-precision stores; we can't use those
18648 routines if we don't have such stores. */
18649 || (TARGET_HARD_FLOAT && !TARGET_DOUBLE_FLOAT)
18650 || FP_SAVE_INLINE (info->first_fp_reg_save));
18651 savres_gprs_inline = (common
18652 /* Saving CR interferes with the exit routines
18653 used on the SPE, so just punt here. */
18654 || (!savep
18655 && TARGET_SPE_ABI
18656 && info->spe_64bit_regs_used != 0
18657 && info->cr_save_p != 0)
18658 || info->first_gp_reg_save == 32
18659 || !noclobber_global_gprs
18660 || GP_SAVE_INLINE (info->first_gp_reg_save));
18662 if (savep)
18663 /* If we are going to use store multiple, then don't even bother
18664 with the out-of-line routines, since the store-multiple instruction
18665 will always be smaller. */
18666 savres_gprs_inline = savres_gprs_inline || using_multiple_p;
18667 else
18669 /* The situation is more complicated with load multiple. We'd
18670 prefer to use the out-of-line routines for restores, since the
18671 "exit" out-of-line routines can handle the restore of LR and
18672 the frame teardown. But we can only use the out-of-line
18673 routines if we know that we've used store multiple or
18674 out-of-line routines in the prologue, i.e. if we've saved all
18675 the registers from first_gp_reg_save. Otherwise, we risk
18676 loading garbage from the stack. Furthermore, we can only use
18677 the "exit" out-of-line gpr restore if we haven't saved any
18678 fprs. */
18679 bool saved_all = !savres_gprs_inline || using_multiple_p;
18681 if (saved_all && info->first_fp_reg_save != 64)
18682 /* We can't use the exit routine; use load multiple if it's
18683 available. */
18684 savres_gprs_inline = savres_gprs_inline || using_multiple_p;
18687 strategy = (using_multiple_p
18688 | (savres_fprs_inline << 1)
18689 | (savres_gprs_inline << 2));
18690 #ifdef POWERPC_LINUX
18691 if (TARGET_64BIT)
18693 if (!savres_fprs_inline)
18694 strategy |= SAVRES_NOINLINE_FPRS_SAVES_LR;
18695 else if (!savres_gprs_inline && info->first_fp_reg_save == 64)
18696 strategy |= SAVRES_NOINLINE_GPRS_SAVES_LR;
18698 #else
18699 if (TARGET_AIX && !savres_fprs_inline)
18700 strategy |= SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR;
18701 #endif
18702 return strategy;
18705 /* Emit function prologue as insns. */
18707 void
18708 rs6000_emit_prologue (void)
18710 rs6000_stack_t *info = rs6000_stack_info ();
18711 enum machine_mode reg_mode = Pmode;
18712 int reg_size = TARGET_32BIT ? 4 : 8;
18713 rtx sp_reg_rtx = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
18714 rtx frame_ptr_rtx = gen_rtx_REG (Pmode, 12);
18715 rtx frame_reg_rtx = sp_reg_rtx;
18716 rtx cr_save_rtx = NULL_RTX;
18717 rtx insn;
18718 int strategy;
18719 int saving_FPRs_inline;
18720 int saving_GPRs_inline;
18721 int using_store_multiple;
18722 int using_static_chain_p = (cfun->static_chain_decl != NULL_TREE
18723 && df_regs_ever_live_p (STATIC_CHAIN_REGNUM)
18724 && call_used_regs[STATIC_CHAIN_REGNUM]);
18725 HOST_WIDE_INT sp_offset = 0;
18727 if (TARGET_FIX_AND_CONTINUE)
18729 /* gdb on darwin arranges to forward a function from the old
18730 address by modifying the first 5 instructions of the function
18731 to branch to the overriding function. This is necessary to
18732 permit function pointers that point to the old function to
18733 actually forward to the new function. */
18734 emit_insn (gen_nop ());
18735 emit_insn (gen_nop ());
18736 emit_insn (gen_nop ());
18737 emit_insn (gen_nop ());
18738 emit_insn (gen_nop ());
18741 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
18743 reg_mode = V2SImode;
18744 reg_size = 8;
18747 strategy = rs6000_savres_strategy (info, /*savep=*/true,
18748 /*static_chain_p=*/using_static_chain_p,
18749 /*sibcall=*/0);
18750 using_store_multiple = strategy & SAVRES_MULTIPLE;
18751 saving_FPRs_inline = strategy & SAVRES_INLINE_FPRS;
18752 saving_GPRs_inline = strategy & SAVRES_INLINE_GPRS;
18754 /* For V.4, update stack before we do any saving and set back pointer. */
18755 if (! WORLD_SAVE_P (info)
18756 && info->push_p
18757 && (DEFAULT_ABI == ABI_V4
18758 || crtl->calls_eh_return))
18760 bool need_r11 = (TARGET_SPE
18761 ? (!saving_GPRs_inline
18762 && info->spe_64bit_regs_used == 0)
18763 : (!saving_FPRs_inline || !saving_GPRs_inline));
18764 if (info->total_size < 32767)
18765 sp_offset = info->total_size;
18766 else
18767 frame_reg_rtx = (need_r11
18768 ? gen_rtx_REG (Pmode, 11)
18769 : frame_ptr_rtx);
18770 rs6000_emit_allocate_stack (info->total_size,
18771 (frame_reg_rtx != sp_reg_rtx
18772 && (info->cr_save_p
18773 || info->lr_save_p
18774 || info->first_fp_reg_save < 64
18775 || info->first_gp_reg_save < 32
18777 need_r11);
18778 if (frame_reg_rtx != sp_reg_rtx)
18779 rs6000_emit_stack_tie ();
18782 /* Handle world saves specially here. */
18783 if (WORLD_SAVE_P (info))
18785 int i, j, sz;
18786 rtx treg;
18787 rtvec p;
18788 rtx reg0;
18790 /* save_world expects lr in r0. */
18791 reg0 = gen_rtx_REG (Pmode, 0);
18792 if (info->lr_save_p)
18794 insn = emit_move_insn (reg0,
18795 gen_rtx_REG (Pmode, LR_REGNO));
18796 RTX_FRAME_RELATED_P (insn) = 1;
18799 /* The SAVE_WORLD and RESTORE_WORLD routines make a number of
18800 assumptions about the offsets of various bits of the stack
18801 frame. */
18802 gcc_assert (info->gp_save_offset == -220
18803 && info->fp_save_offset == -144
18804 && info->lr_save_offset == 8
18805 && info->cr_save_offset == 4
18806 && info->push_p
18807 && info->lr_save_p
18808 && (!crtl->calls_eh_return
18809 || info->ehrd_offset == -432)
18810 && info->vrsave_save_offset == -224
18811 && info->altivec_save_offset == -416);
18813 treg = gen_rtx_REG (SImode, 11);
18814 emit_move_insn (treg, GEN_INT (-info->total_size));
18816 /* SAVE_WORLD takes the caller's LR in R0 and the frame size
18817 in R11. It also clobbers R12, so beware! */
18819 /* Preserve CR2 for save_world prologues */
18820 sz = 5;
18821 sz += 32 - info->first_gp_reg_save;
18822 sz += 64 - info->first_fp_reg_save;
18823 sz += LAST_ALTIVEC_REGNO - info->first_altivec_reg_save + 1;
18824 p = rtvec_alloc (sz);
18825 j = 0;
18826 RTVEC_ELT (p, j++) = gen_rtx_CLOBBER (VOIDmode,
18827 gen_rtx_REG (SImode,
18828 LR_REGNO));
18829 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
18830 gen_rtx_SYMBOL_REF (Pmode,
18831 "*save_world"));
18832 /* We do floats first so that the instruction pattern matches
18833 properly. */
18834 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
18836 rtx reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
18837 ? DFmode : SFmode),
18838 info->first_fp_reg_save + i);
18839 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18840 GEN_INT (info->fp_save_offset
18841 + sp_offset + 8 * i));
18842 rtx mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
18843 ? DFmode : SFmode), addr);
18845 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
18847 for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++)
18849 rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i);
18850 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18851 GEN_INT (info->altivec_save_offset
18852 + sp_offset + 16 * i));
18853 rtx mem = gen_frame_mem (V4SImode, addr);
18855 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
18857 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
18859 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
18860 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18861 GEN_INT (info->gp_save_offset
18862 + sp_offset + reg_size * i));
18863 rtx mem = gen_frame_mem (reg_mode, addr);
18865 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
18869 /* CR register traditionally saved as CR2. */
18870 rtx reg = gen_rtx_REG (reg_mode, CR2_REGNO);
18871 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18872 GEN_INT (info->cr_save_offset
18873 + sp_offset));
18874 rtx mem = gen_frame_mem (reg_mode, addr);
18876 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
18878 /* Explain about use of R0. */
18879 if (info->lr_save_p)
18881 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18882 GEN_INT (info->lr_save_offset
18883 + sp_offset));
18884 rtx mem = gen_frame_mem (reg_mode, addr);
18886 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg0);
18888 /* Explain what happens to the stack pointer. */
18890 rtx newval = gen_rtx_PLUS (Pmode, sp_reg_rtx, treg);
18891 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, sp_reg_rtx, newval);
18894 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
18895 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
18896 treg, GEN_INT (-info->total_size));
18897 sp_offset = info->total_size;
18900 /* If we use the link register, get it into r0. */
18901 if (!WORLD_SAVE_P (info) && info->lr_save_p)
18903 rtx addr, reg, mem;
18905 insn = emit_move_insn (gen_rtx_REG (Pmode, 0),
18906 gen_rtx_REG (Pmode, LR_REGNO));
18907 RTX_FRAME_RELATED_P (insn) = 1;
18909 if (!(strategy & (SAVRES_NOINLINE_GPRS_SAVES_LR
18910 | SAVRES_NOINLINE_FPRS_SAVES_LR)))
18912 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18913 GEN_INT (info->lr_save_offset + sp_offset));
18914 reg = gen_rtx_REG (Pmode, 0);
18915 mem = gen_rtx_MEM (Pmode, addr);
18916 /* This should not be of rs6000_sr_alias_set, because of
18917 __builtin_return_address. */
18919 insn = emit_move_insn (mem, reg);
18920 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
18921 NULL_RTX, NULL_RTX);
18925 /* If we need to save CR, put it into r12 or r11. */
18926 if (!WORLD_SAVE_P (info) && info->cr_save_p && frame_reg_rtx != frame_ptr_rtx)
18928 rtx set;
18930 cr_save_rtx
18931 = gen_rtx_REG (SImode, DEFAULT_ABI == ABI_AIX && !saving_GPRs_inline
18932 ? 11 : 12);
18933 insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
18934 RTX_FRAME_RELATED_P (insn) = 1;
18935 /* Now, there's no way that dwarf2out_frame_debug_expr is going
18936 to understand '(unspec:SI [(reg:CC 68) ...] UNSPEC_MOVESI_FROM_CR)'.
18937 But that's OK. All we have to do is specify that _one_ condition
18938 code register is saved in this stack slot. The thrower's epilogue
18939 will then restore all the call-saved registers.
18940 We use CR2_REGNO (70) to be compatible with gcc-2.95 on Linux. */
18941 set = gen_rtx_SET (VOIDmode, cr_save_rtx,
18942 gen_rtx_REG (SImode, CR2_REGNO));
18943 add_reg_note (insn, REG_FRAME_RELATED_EXPR, set);
18946 /* Do any required saving of fpr's. If only one or two to save, do
18947 it ourselves. Otherwise, call function. */
18948 if (!WORLD_SAVE_P (info) && saving_FPRs_inline)
18950 int i;
18951 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
18952 if ((df_regs_ever_live_p (info->first_fp_reg_save+i)
18953 && ! call_used_regs[info->first_fp_reg_save+i]))
18954 emit_frame_save (frame_reg_rtx, frame_ptr_rtx,
18955 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
18956 ? DFmode : SFmode,
18957 info->first_fp_reg_save + i,
18958 info->fp_save_offset + sp_offset + 8 * i,
18959 info->total_size);
18961 else if (!WORLD_SAVE_P (info) && info->first_fp_reg_save != 64)
18963 rtx par;
18965 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
18966 info->fp_save_offset + sp_offset,
18967 DFmode,
18968 /*savep=*/true, /*gpr=*/false,
18969 /*lr=*/(strategy
18970 & SAVRES_NOINLINE_FPRS_SAVES_LR)
18971 != 0);
18972 insn = emit_insn (par);
18973 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
18974 NULL_RTX, NULL_RTX);
18977 /* Save GPRs. This is done as a PARALLEL if we are using
18978 the store-multiple instructions. */
18979 if (!WORLD_SAVE_P (info)
18980 && TARGET_SPE_ABI
18981 && info->spe_64bit_regs_used != 0
18982 && info->first_gp_reg_save != 32)
18984 int i;
18985 rtx spe_save_area_ptr;
18987 /* Determine whether we can address all of the registers that need
18988 to be saved with an offset from the stack pointer that fits in
18989 the small const field for SPE memory instructions. */
18990 int spe_regs_addressable_via_sp
18991 = (SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset
18992 + (32 - info->first_gp_reg_save - 1) * reg_size)
18993 && saving_GPRs_inline);
18994 int spe_offset;
18996 if (spe_regs_addressable_via_sp)
18998 spe_save_area_ptr = frame_reg_rtx;
18999 spe_offset = info->spe_gp_save_offset + sp_offset;
19001 else
19003 /* Make r11 point to the start of the SPE save area. We need
19004 to be careful here if r11 is holding the static chain. If
19005 it is, then temporarily save it in r0. We would use r0 as
19006 our base register here, but using r0 as a base register in
19007 loads and stores means something different from what we
19008 would like. */
19009 int ool_adjust = (saving_GPRs_inline
19011 : (info->first_gp_reg_save
19012 - (FIRST_SAVRES_REGISTER+1))*8);
19013 HOST_WIDE_INT offset = (info->spe_gp_save_offset
19014 + sp_offset - ool_adjust);
19016 if (using_static_chain_p)
19018 rtx r0 = gen_rtx_REG (Pmode, 0);
19019 gcc_assert (info->first_gp_reg_save > 11);
19021 emit_move_insn (r0, gen_rtx_REG (Pmode, 11));
19024 spe_save_area_ptr = gen_rtx_REG (Pmode, 11);
19025 insn = emit_insn (gen_addsi3 (spe_save_area_ptr,
19026 frame_reg_rtx,
19027 GEN_INT (offset)));
19028 /* We need to make sure the move to r11 gets noted for
19029 properly outputting unwind information. */
19030 if (!saving_GPRs_inline)
19031 rs6000_frame_related (insn, frame_reg_rtx, offset,
19032 NULL_RTX, NULL_RTX);
19033 spe_offset = 0;
19036 if (saving_GPRs_inline)
19038 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
19039 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
19041 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
19042 rtx offset, addr, mem;
19044 /* We're doing all this to ensure that the offset fits into
19045 the immediate offset of 'evstdd'. */
19046 gcc_assert (SPE_CONST_OFFSET_OK (reg_size * i + spe_offset));
19048 offset = GEN_INT (reg_size * i + spe_offset);
19049 addr = gen_rtx_PLUS (Pmode, spe_save_area_ptr, offset);
19050 mem = gen_rtx_MEM (V2SImode, addr);
19052 insn = emit_move_insn (mem, reg);
19054 rs6000_frame_related (insn, spe_save_area_ptr,
19055 info->spe_gp_save_offset
19056 + sp_offset + reg_size * i,
19057 offset, const0_rtx);
19060 else
19062 rtx par;
19064 par = rs6000_make_savres_rtx (info, gen_rtx_REG (Pmode, 11),
19065 0, reg_mode,
19066 /*savep=*/true, /*gpr=*/true,
19067 /*lr=*/false);
19068 insn = emit_insn (par);
19069 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19070 NULL_RTX, NULL_RTX);
19074 /* Move the static chain pointer back. */
19075 if (using_static_chain_p && !spe_regs_addressable_via_sp)
19076 emit_move_insn (gen_rtx_REG (Pmode, 11), gen_rtx_REG (Pmode, 0));
19078 else if (!WORLD_SAVE_P (info) && !saving_GPRs_inline)
19080 rtx par;
19082 /* Need to adjust r11 (r12) if we saved any FPRs. */
19083 if (info->first_fp_reg_save != 64)
19085 rtx dest_reg = gen_rtx_REG (reg_mode, DEFAULT_ABI == ABI_AIX
19086 ? 12 : 11);
19087 rtx offset = GEN_INT (sp_offset
19088 + (-8 * (64-info->first_fp_reg_save)));
19089 emit_insn (gen_add3_insn (dest_reg, frame_reg_rtx, offset));
19092 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
19093 info->gp_save_offset + sp_offset,
19094 reg_mode,
19095 /*savep=*/true, /*gpr=*/true,
19096 /*lr=*/(strategy
19097 & SAVRES_NOINLINE_GPRS_SAVES_LR)
19098 != 0);
19099 insn = emit_insn (par);
19100 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19101 NULL_RTX, NULL_RTX);
19103 else if (!WORLD_SAVE_P (info) && using_store_multiple)
19105 rtvec p;
19106 int i;
19107 p = rtvec_alloc (32 - info->first_gp_reg_save);
19108 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
19110 rtx addr, reg, mem;
19111 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
19112 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19113 GEN_INT (info->gp_save_offset
19114 + sp_offset
19115 + reg_size * i));
19116 mem = gen_frame_mem (reg_mode, addr);
19118 RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, mem, reg);
19120 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
19121 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19122 NULL_RTX, NULL_RTX);
19124 else if (!WORLD_SAVE_P (info))
19126 int i;
19127 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
19128 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
19130 rtx addr, reg, mem;
19131 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
19133 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19134 GEN_INT (info->gp_save_offset
19135 + sp_offset
19136 + reg_size * i));
19137 mem = gen_frame_mem (reg_mode, addr);
19139 insn = emit_move_insn (mem, reg);
19140 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19141 NULL_RTX, NULL_RTX);
19145 /* ??? There's no need to emit actual instructions here, but it's the
19146 easiest way to get the frame unwind information emitted. */
19147 if (crtl->calls_eh_return)
19149 unsigned int i, regno;
19151 /* In AIX ABI we need to pretend we save r2 here. */
19152 if (TARGET_AIX)
19154 rtx addr, reg, mem;
19156 reg = gen_rtx_REG (reg_mode, 2);
19157 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19158 GEN_INT (sp_offset + 5 * reg_size));
19159 mem = gen_frame_mem (reg_mode, addr);
19161 insn = emit_move_insn (mem, reg);
19162 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19163 NULL_RTX, NULL_RTX);
19164 PATTERN (insn) = gen_blockage ();
19167 for (i = 0; ; ++i)
19169 regno = EH_RETURN_DATA_REGNO (i);
19170 if (regno == INVALID_REGNUM)
19171 break;
19173 emit_frame_save (frame_reg_rtx, frame_ptr_rtx, reg_mode, regno,
19174 info->ehrd_offset + sp_offset
19175 + reg_size * (int) i,
19176 info->total_size);
19180 /* Save CR if we use any that must be preserved. */
19181 if (!WORLD_SAVE_P (info) && info->cr_save_p)
19183 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19184 GEN_INT (info->cr_save_offset + sp_offset));
19185 rtx mem = gen_frame_mem (SImode, addr);
19186 /* See the large comment above about why CR2_REGNO is used. */
19187 rtx magic_eh_cr_reg = gen_rtx_REG (SImode, CR2_REGNO);
19189 /* If r12 was used to hold the original sp, copy cr into r0 now
19190 that it's free. */
19191 if (REGNO (frame_reg_rtx) == 12)
19193 rtx set;
19195 cr_save_rtx = gen_rtx_REG (SImode, 0);
19196 insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
19197 RTX_FRAME_RELATED_P (insn) = 1;
19198 set = gen_rtx_SET (VOIDmode, cr_save_rtx, magic_eh_cr_reg);
19199 add_reg_note (insn, REG_FRAME_RELATED_EXPR, set);
19201 insn = emit_move_insn (mem, cr_save_rtx);
19203 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19204 NULL_RTX, NULL_RTX);
19207 /* Update stack and set back pointer unless this is V.4,
19208 for which it was done previously. */
19209 if (!WORLD_SAVE_P (info) && info->push_p
19210 && !(DEFAULT_ABI == ABI_V4 || crtl->calls_eh_return))
19212 if (info->total_size < 32767)
19213 sp_offset = info->total_size;
19214 else
19215 frame_reg_rtx = frame_ptr_rtx;
19216 rs6000_emit_allocate_stack (info->total_size,
19217 (frame_reg_rtx != sp_reg_rtx
19218 && ((info->altivec_size != 0)
19219 || (info->vrsave_mask != 0)
19221 FALSE);
19222 if (frame_reg_rtx != sp_reg_rtx)
19223 rs6000_emit_stack_tie ();
19226 /* Set frame pointer, if needed. */
19227 if (frame_pointer_needed)
19229 insn = emit_move_insn (gen_rtx_REG (Pmode, HARD_FRAME_POINTER_REGNUM),
19230 sp_reg_rtx);
19231 RTX_FRAME_RELATED_P (insn) = 1;
19234 /* Save AltiVec registers if needed. Save here because the red zone does
19235 not include AltiVec registers. */
19236 if (!WORLD_SAVE_P (info) && TARGET_ALTIVEC_ABI && info->altivec_size != 0)
19238 int i;
19240 /* There should be a non inline version of this, for when we
19241 are saving lots of vector registers. */
19242 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
19243 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
19245 rtx areg, savereg, mem;
19246 int offset;
19248 offset = info->altivec_save_offset + sp_offset
19249 + 16 * (i - info->first_altivec_reg_save);
19251 savereg = gen_rtx_REG (V4SImode, i);
19253 areg = gen_rtx_REG (Pmode, 0);
19254 emit_move_insn (areg, GEN_INT (offset));
19256 /* AltiVec addressing mode is [reg+reg]. */
19257 mem = gen_frame_mem (V4SImode,
19258 gen_rtx_PLUS (Pmode, frame_reg_rtx, areg));
19260 insn = emit_move_insn (mem, savereg);
19262 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19263 areg, GEN_INT (offset));
19267 /* VRSAVE is a bit vector representing which AltiVec registers
19268 are used. The OS uses this to determine which vector
19269 registers to save on a context switch. We need to save
19270 VRSAVE on the stack frame, add whatever AltiVec registers we
19271 used in this function, and do the corresponding magic in the
19272 epilogue. */
19274 if (TARGET_ALTIVEC && TARGET_ALTIVEC_VRSAVE
19275 && info->vrsave_mask != 0)
19277 rtx reg, mem, vrsave;
19278 int offset;
19280 /* Get VRSAVE onto a GPR. Note that ABI_V4 might be using r12
19281 as frame_reg_rtx and r11 as the static chain pointer for
19282 nested functions. */
19283 reg = gen_rtx_REG (SImode, 0);
19284 vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
19285 if (TARGET_MACHO)
19286 emit_insn (gen_get_vrsave_internal (reg));
19287 else
19288 emit_insn (gen_rtx_SET (VOIDmode, reg, vrsave));
19290 if (!WORLD_SAVE_P (info))
19292 /* Save VRSAVE. */
19293 offset = info->vrsave_save_offset + sp_offset;
19294 mem = gen_frame_mem (SImode,
19295 gen_rtx_PLUS (Pmode, frame_reg_rtx,
19296 GEN_INT (offset)));
19297 insn = emit_move_insn (mem, reg);
19300 /* Include the registers in the mask. */
19301 emit_insn (gen_iorsi3 (reg, reg, GEN_INT ((int) info->vrsave_mask)));
19303 insn = emit_insn (generate_set_vrsave (reg, info, 0));
19306 /* If we are using RS6000_PIC_OFFSET_TABLE_REGNUM, we need to set it up. */
19307 if ((TARGET_TOC && TARGET_MINIMAL_TOC && get_pool_size () != 0)
19308 || (DEFAULT_ABI == ABI_V4
19309 && (flag_pic == 1 || (flag_pic && TARGET_SECURE_PLT))
19310 && df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM)))
19312 /* If emit_load_toc_table will use the link register, we need to save
19313 it. We use R12 for this purpose because emit_load_toc_table
19314 can use register 0. This allows us to use a plain 'blr' to return
19315 from the procedure more often. */
19316 int save_LR_around_toc_setup = (TARGET_ELF
19317 && DEFAULT_ABI != ABI_AIX
19318 && flag_pic
19319 && ! info->lr_save_p
19320 && EDGE_COUNT (EXIT_BLOCK_PTR->preds) > 0);
19321 if (save_LR_around_toc_setup)
19323 rtx lr = gen_rtx_REG (Pmode, LR_REGNO);
19325 insn = emit_move_insn (frame_ptr_rtx, lr);
19326 RTX_FRAME_RELATED_P (insn) = 1;
19328 rs6000_emit_load_toc_table (TRUE);
19330 insn = emit_move_insn (lr, frame_ptr_rtx);
19331 RTX_FRAME_RELATED_P (insn) = 1;
19333 else
19334 rs6000_emit_load_toc_table (TRUE);
19337 #if TARGET_MACHO
19338 if (DEFAULT_ABI == ABI_DARWIN
19339 && flag_pic && crtl->uses_pic_offset_table)
19341 rtx lr = gen_rtx_REG (Pmode, LR_REGNO);
19342 rtx src = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
19344 /* Save and restore LR locally around this call (in R0). */
19345 if (!info->lr_save_p)
19346 emit_move_insn (gen_rtx_REG (Pmode, 0), lr);
19348 emit_insn (gen_load_macho_picbase (src));
19350 emit_move_insn (gen_rtx_REG (Pmode,
19351 RS6000_PIC_OFFSET_TABLE_REGNUM),
19352 lr);
19354 if (!info->lr_save_p)
19355 emit_move_insn (lr, gen_rtx_REG (Pmode, 0));
19357 #endif
19360 /* Write function prologue. */
19362 static void
19363 rs6000_output_function_prologue (FILE *file,
19364 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
19366 rs6000_stack_t *info = rs6000_stack_info ();
19368 if (TARGET_DEBUG_STACK)
19369 debug_stack_info (info);
19371 /* Write .extern for any function we will call to save and restore
19372 fp values. */
19373 if (info->first_fp_reg_save < 64
19374 && !FP_SAVE_INLINE (info->first_fp_reg_save))
19376 char *name;
19377 int regno = info->first_fp_reg_save - 32;
19379 name = rs6000_savres_routine_name (info, regno, /*savep=*/true,
19380 /*gpr=*/false, /*lr=*/false);
19381 fprintf (file, "\t.extern %s\n", name);
19383 name = rs6000_savres_routine_name (info, regno, /*savep=*/false,
19384 /*gpr=*/false, /*lr=*/true);
19385 fprintf (file, "\t.extern %s\n", name);
19388 /* Write .extern for AIX common mode routines, if needed. */
19389 if (! TARGET_POWER && ! TARGET_POWERPC && ! common_mode_defined)
19391 fputs ("\t.extern __mulh\n", file);
19392 fputs ("\t.extern __mull\n", file);
19393 fputs ("\t.extern __divss\n", file);
19394 fputs ("\t.extern __divus\n", file);
19395 fputs ("\t.extern __quoss\n", file);
19396 fputs ("\t.extern __quous\n", file);
19397 common_mode_defined = 1;
19400 if (! HAVE_prologue)
19402 rtx prologue;
19404 start_sequence ();
19406 /* A NOTE_INSN_DELETED is supposed to be at the start and end of
19407 the "toplevel" insn chain. */
19408 emit_note (NOTE_INSN_DELETED);
19409 rs6000_emit_prologue ();
19410 emit_note (NOTE_INSN_DELETED);
19412 /* Expand INSN_ADDRESSES so final() doesn't crash. */
19414 rtx insn;
19415 unsigned addr = 0;
19416 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
19418 INSN_ADDRESSES_NEW (insn, addr);
19419 addr += 4;
19423 prologue = get_insns ();
19424 end_sequence ();
19426 if (TARGET_DEBUG_STACK)
19427 debug_rtx_list (prologue, 100);
19429 emit_insn_before_noloc (prologue, BB_HEAD (ENTRY_BLOCK_PTR->next_bb),
19430 ENTRY_BLOCK_PTR);
19433 rs6000_pic_labelno++;
19436 /* Non-zero if vmx regs are restored before the frame pop, zero if
19437 we restore after the pop when possible. */
19438 #define ALWAYS_RESTORE_ALTIVEC_BEFORE_POP 0
19440 /* Reload CR from REG. */
19442 static void
19443 rs6000_restore_saved_cr (rtx reg, int using_mfcr_multiple)
19445 int count = 0;
19446 int i;
19448 if (using_mfcr_multiple)
19450 for (i = 0; i < 8; i++)
19451 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
19452 count++;
19453 gcc_assert (count);
19456 if (using_mfcr_multiple && count > 1)
19458 rtvec p;
19459 int ndx;
19461 p = rtvec_alloc (count);
19463 ndx = 0;
19464 for (i = 0; i < 8; i++)
19465 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
19467 rtvec r = rtvec_alloc (2);
19468 RTVEC_ELT (r, 0) = reg;
19469 RTVEC_ELT (r, 1) = GEN_INT (1 << (7-i));
19470 RTVEC_ELT (p, ndx) =
19471 gen_rtx_SET (VOIDmode, gen_rtx_REG (CCmode, CR0_REGNO+i),
19472 gen_rtx_UNSPEC (CCmode, r, UNSPEC_MOVESI_TO_CR));
19473 ndx++;
19475 emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
19476 gcc_assert (ndx == count);
19478 else
19479 for (i = 0; i < 8; i++)
19480 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
19482 emit_insn (gen_movsi_to_cr_one (gen_rtx_REG (CCmode,
19483 CR0_REGNO+i),
19484 reg));
19488 /* Return true if OFFSET from stack pointer can be clobbered by signals.
19489 V.4 doesn't have any stack cushion, AIX ABIs have 220 or 288 bytes
19490 below stack pointer not cloberred by signals. */
19492 static inline bool
19493 offset_below_red_zone_p (HOST_WIDE_INT offset)
19495 return offset < (DEFAULT_ABI == ABI_V4
19497 : TARGET_32BIT ? -220 : -288);
19500 /* Emit function epilogue as insns. */
19502 void
19503 rs6000_emit_epilogue (int sibcall)
19505 rs6000_stack_t *info;
19506 int restoring_GPRs_inline;
19507 int restoring_FPRs_inline;
19508 int using_load_multiple;
19509 int using_mtcr_multiple;
19510 int use_backchain_to_restore_sp;
19511 int restore_lr;
19512 int strategy;
19513 int sp_offset = 0;
19514 rtx sp_reg_rtx = gen_rtx_REG (Pmode, 1);
19515 rtx frame_reg_rtx = sp_reg_rtx;
19516 rtx cfa_restores = NULL_RTX;
19517 rtx insn;
19518 rtx cr_save_reg = NULL_RTX;
19519 enum machine_mode reg_mode = Pmode;
19520 int reg_size = TARGET_32BIT ? 4 : 8;
19521 int i;
19523 info = rs6000_stack_info ();
19525 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
19527 reg_mode = V2SImode;
19528 reg_size = 8;
19531 strategy = rs6000_savres_strategy (info, /*savep=*/false,
19532 /*static_chain_p=*/0, sibcall);
19533 using_load_multiple = strategy & SAVRES_MULTIPLE;
19534 restoring_FPRs_inline = strategy & SAVRES_INLINE_FPRS;
19535 restoring_GPRs_inline = strategy & SAVRES_INLINE_GPRS;
19536 using_mtcr_multiple = (rs6000_cpu == PROCESSOR_PPC601
19537 || rs6000_cpu == PROCESSOR_PPC603
19538 || rs6000_cpu == PROCESSOR_PPC750
19539 || optimize_size);
19540 /* Restore via the backchain when we have a large frame, since this
19541 is more efficient than an addis, addi pair. The second condition
19542 here will not trigger at the moment; We don't actually need a
19543 frame pointer for alloca, but the generic parts of the compiler
19544 give us one anyway. */
19545 use_backchain_to_restore_sp = (info->total_size > 32767
19546 || info->total_size
19547 + (info->lr_save_p ? info->lr_save_offset : 0)
19548 > 32767
19549 || (cfun->calls_alloca
19550 && !frame_pointer_needed));
19551 restore_lr = (info->lr_save_p
19552 && (restoring_FPRs_inline
19553 || (strategy & SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR))
19554 && (restoring_GPRs_inline
19555 || info->first_fp_reg_save < 64));
19557 if (WORLD_SAVE_P (info))
19559 int i, j;
19560 char rname[30];
19561 const char *alloc_rname;
19562 rtvec p;
19564 /* eh_rest_world_r10 will return to the location saved in the LR
19565 stack slot (which is not likely to be our caller.)
19566 Input: R10 -- stack adjustment. Clobbers R0, R11, R12, R7, R8.
19567 rest_world is similar, except any R10 parameter is ignored.
19568 The exception-handling stuff that was here in 2.95 is no
19569 longer necessary. */
19571 p = rtvec_alloc (9
19573 + 32 - info->first_gp_reg_save
19574 + LAST_ALTIVEC_REGNO + 1 - info->first_altivec_reg_save
19575 + 63 + 1 - info->first_fp_reg_save);
19577 strcpy (rname, ((crtl->calls_eh_return) ?
19578 "*eh_rest_world_r10" : "*rest_world"));
19579 alloc_rname = ggc_strdup (rname);
19581 j = 0;
19582 RTVEC_ELT (p, j++) = gen_rtx_RETURN (VOIDmode);
19583 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
19584 gen_rtx_REG (Pmode,
19585 LR_REGNO));
19586 RTVEC_ELT (p, j++)
19587 = gen_rtx_USE (VOIDmode, gen_rtx_SYMBOL_REF (Pmode, alloc_rname));
19588 /* The instruction pattern requires a clobber here;
19589 it is shared with the restVEC helper. */
19590 RTVEC_ELT (p, j++)
19591 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 11));
19594 /* CR register traditionally saved as CR2. */
19595 rtx reg = gen_rtx_REG (reg_mode, CR2_REGNO);
19596 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19597 GEN_INT (info->cr_save_offset));
19598 rtx mem = gen_frame_mem (reg_mode, addr);
19600 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
19603 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
19605 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
19606 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19607 GEN_INT (info->gp_save_offset
19608 + reg_size * i));
19609 rtx mem = gen_frame_mem (reg_mode, addr);
19611 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
19613 for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++)
19615 rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i);
19616 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19617 GEN_INT (info->altivec_save_offset
19618 + 16 * i));
19619 rtx mem = gen_frame_mem (V4SImode, addr);
19621 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
19623 for (i = 0; info->first_fp_reg_save + i <= 63; i++)
19625 rtx reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
19626 ? DFmode : SFmode),
19627 info->first_fp_reg_save + i);
19628 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19629 GEN_INT (info->fp_save_offset
19630 + 8 * i));
19631 rtx mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
19632 ? DFmode : SFmode), addr);
19634 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
19636 RTVEC_ELT (p, j++)
19637 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 0));
19638 RTVEC_ELT (p, j++)
19639 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 12));
19640 RTVEC_ELT (p, j++)
19641 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 7));
19642 RTVEC_ELT (p, j++)
19643 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 8));
19644 RTVEC_ELT (p, j++)
19645 = gen_rtx_USE (VOIDmode, gen_rtx_REG (SImode, 10));
19646 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
19648 return;
19651 /* frame_reg_rtx + sp_offset points to the top of this stack frame. */
19652 if (info->push_p)
19653 sp_offset = info->total_size;
19655 /* Restore AltiVec registers if we must do so before adjusting the
19656 stack. */
19657 if (TARGET_ALTIVEC_ABI
19658 && info->altivec_size != 0
19659 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
19660 || (DEFAULT_ABI != ABI_V4
19661 && offset_below_red_zone_p (info->altivec_save_offset))))
19663 int i;
19665 if (use_backchain_to_restore_sp)
19667 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
19668 emit_move_insn (frame_reg_rtx,
19669 gen_rtx_MEM (Pmode, sp_reg_rtx));
19670 sp_offset = 0;
19672 else if (frame_pointer_needed)
19673 frame_reg_rtx = hard_frame_pointer_rtx;
19675 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
19676 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
19678 rtx addr, areg, mem, reg;
19680 areg = gen_rtx_REG (Pmode, 0);
19681 emit_move_insn
19682 (areg, GEN_INT (info->altivec_save_offset
19683 + sp_offset
19684 + 16 * (i - info->first_altivec_reg_save)));
19686 /* AltiVec addressing mode is [reg+reg]. */
19687 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
19688 mem = gen_frame_mem (V4SImode, addr);
19690 reg = gen_rtx_REG (V4SImode, i);
19691 emit_move_insn (reg, mem);
19692 if (offset_below_red_zone_p (info->altivec_save_offset
19693 + (i - info->first_altivec_reg_save)
19694 * 16))
19695 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
19696 cfa_restores);
19700 /* Restore VRSAVE if we must do so before adjusting the stack. */
19701 if (TARGET_ALTIVEC
19702 && TARGET_ALTIVEC_VRSAVE
19703 && info->vrsave_mask != 0
19704 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
19705 || (DEFAULT_ABI != ABI_V4
19706 && offset_below_red_zone_p (info->vrsave_save_offset))))
19708 rtx addr, mem, reg;
19710 if (frame_reg_rtx == sp_reg_rtx)
19712 if (use_backchain_to_restore_sp)
19714 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
19715 emit_move_insn (frame_reg_rtx,
19716 gen_rtx_MEM (Pmode, sp_reg_rtx));
19717 sp_offset = 0;
19719 else if (frame_pointer_needed)
19720 frame_reg_rtx = hard_frame_pointer_rtx;
19723 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19724 GEN_INT (info->vrsave_save_offset + sp_offset));
19725 mem = gen_frame_mem (SImode, addr);
19726 reg = gen_rtx_REG (SImode, 12);
19727 emit_move_insn (reg, mem);
19729 emit_insn (generate_set_vrsave (reg, info, 1));
19732 insn = NULL_RTX;
19733 /* If we have a large stack frame, restore the old stack pointer
19734 using the backchain. */
19735 if (use_backchain_to_restore_sp)
19737 if (frame_reg_rtx == sp_reg_rtx)
19739 /* Under V.4, don't reset the stack pointer until after we're done
19740 loading the saved registers. */
19741 if (DEFAULT_ABI == ABI_V4)
19742 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
19744 insn = emit_move_insn (frame_reg_rtx,
19745 gen_rtx_MEM (Pmode, sp_reg_rtx));
19746 sp_offset = 0;
19748 else if (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
19749 && DEFAULT_ABI == ABI_V4)
19750 /* frame_reg_rtx has been set up by the altivec restore. */
19752 else
19754 insn = emit_move_insn (sp_reg_rtx, frame_reg_rtx);
19755 frame_reg_rtx = sp_reg_rtx;
19758 /* If we have a frame pointer, we can restore the old stack pointer
19759 from it. */
19760 else if (frame_pointer_needed)
19762 frame_reg_rtx = sp_reg_rtx;
19763 if (DEFAULT_ABI == ABI_V4)
19764 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
19766 insn = emit_insn (gen_add3_insn (frame_reg_rtx, hard_frame_pointer_rtx,
19767 GEN_INT (info->total_size)));
19768 sp_offset = 0;
19770 else if (info->push_p
19771 && DEFAULT_ABI != ABI_V4
19772 && !crtl->calls_eh_return)
19774 insn = emit_insn (gen_add3_insn (sp_reg_rtx, sp_reg_rtx,
19775 GEN_INT (info->total_size)));
19776 sp_offset = 0;
19778 if (insn && frame_reg_rtx == sp_reg_rtx)
19780 if (cfa_restores)
19782 REG_NOTES (insn) = cfa_restores;
19783 cfa_restores = NULL_RTX;
19785 add_reg_note (insn, REG_CFA_DEF_CFA, sp_reg_rtx);
19786 RTX_FRAME_RELATED_P (insn) = 1;
19789 /* Restore AltiVec registers if we have not done so already. */
19790 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
19791 && TARGET_ALTIVEC_ABI
19792 && info->altivec_size != 0
19793 && (DEFAULT_ABI == ABI_V4
19794 || !offset_below_red_zone_p (info->altivec_save_offset)))
19796 int i;
19798 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
19799 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
19801 rtx addr, areg, mem, reg;
19803 areg = gen_rtx_REG (Pmode, 0);
19804 emit_move_insn
19805 (areg, GEN_INT (info->altivec_save_offset
19806 + sp_offset
19807 + 16 * (i - info->first_altivec_reg_save)));
19809 /* AltiVec addressing mode is [reg+reg]. */
19810 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
19811 mem = gen_frame_mem (V4SImode, addr);
19813 reg = gen_rtx_REG (V4SImode, i);
19814 emit_move_insn (reg, mem);
19815 if (DEFAULT_ABI == ABI_V4)
19816 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
19817 cfa_restores);
19821 /* Restore VRSAVE if we have not done so already. */
19822 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
19823 && TARGET_ALTIVEC
19824 && TARGET_ALTIVEC_VRSAVE
19825 && info->vrsave_mask != 0
19826 && (DEFAULT_ABI == ABI_V4
19827 || !offset_below_red_zone_p (info->vrsave_save_offset)))
19829 rtx addr, mem, reg;
19831 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19832 GEN_INT (info->vrsave_save_offset + sp_offset));
19833 mem = gen_frame_mem (SImode, addr);
19834 reg = gen_rtx_REG (SImode, 12);
19835 emit_move_insn (reg, mem);
19837 emit_insn (generate_set_vrsave (reg, info, 1));
19840 /* Get the old lr if we saved it. If we are restoring registers
19841 out-of-line, then the out-of-line routines can do this for us. */
19842 if (restore_lr && restoring_GPRs_inline)
19844 rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
19845 info->lr_save_offset + sp_offset);
19847 emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
19850 /* Get the old cr if we saved it. */
19851 if (info->cr_save_p)
19853 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19854 GEN_INT (info->cr_save_offset + sp_offset));
19855 rtx mem = gen_frame_mem (SImode, addr);
19857 cr_save_reg = gen_rtx_REG (SImode,
19858 DEFAULT_ABI == ABI_AIX
19859 && !restoring_GPRs_inline
19860 && info->first_fp_reg_save < 64
19861 ? 11 : 12);
19862 emit_move_insn (cr_save_reg, mem);
19865 /* Set LR here to try to overlap restores below. LR is always saved
19866 above incoming stack, so it never needs REG_CFA_RESTORE. */
19867 if (restore_lr && restoring_GPRs_inline)
19868 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO),
19869 gen_rtx_REG (Pmode, 0));
19871 /* Load exception handler data registers, if needed. */
19872 if (crtl->calls_eh_return)
19874 unsigned int i, regno;
19876 if (TARGET_AIX)
19878 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19879 GEN_INT (sp_offset + 5 * reg_size));
19880 rtx mem = gen_frame_mem (reg_mode, addr);
19882 emit_move_insn (gen_rtx_REG (reg_mode, 2), mem);
19885 for (i = 0; ; ++i)
19887 rtx mem;
19889 regno = EH_RETURN_DATA_REGNO (i);
19890 if (regno == INVALID_REGNUM)
19891 break;
19893 mem = gen_frame_mem_offset (reg_mode, frame_reg_rtx,
19894 info->ehrd_offset + sp_offset
19895 + reg_size * (int) i);
19897 emit_move_insn (gen_rtx_REG (reg_mode, regno), mem);
19901 /* Restore GPRs. This is done as a PARALLEL if we are using
19902 the load-multiple instructions. */
19903 if (TARGET_SPE_ABI
19904 && info->spe_64bit_regs_used != 0
19905 && info->first_gp_reg_save != 32)
19907 /* Determine whether we can address all of the registers that need
19908 to be saved with an offset from the stack pointer that fits in
19909 the small const field for SPE memory instructions. */
19910 int spe_regs_addressable_via_sp
19911 = (SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset
19912 + (32 - info->first_gp_reg_save - 1) * reg_size)
19913 && restoring_GPRs_inline);
19914 int spe_offset;
19916 if (spe_regs_addressable_via_sp)
19917 spe_offset = info->spe_gp_save_offset + sp_offset;
19918 else
19920 rtx old_frame_reg_rtx = frame_reg_rtx;
19921 /* Make r11 point to the start of the SPE save area. We worried about
19922 not clobbering it when we were saving registers in the prologue.
19923 There's no need to worry here because the static chain is passed
19924 anew to every function. */
19925 int ool_adjust = (restoring_GPRs_inline
19927 : (info->first_gp_reg_save
19928 - (FIRST_SAVRES_REGISTER+1))*8);
19930 if (frame_reg_rtx == sp_reg_rtx)
19931 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
19932 emit_insn (gen_addsi3 (frame_reg_rtx, old_frame_reg_rtx,
19933 GEN_INT (info->spe_gp_save_offset
19934 + sp_offset
19935 - ool_adjust)));
19936 /* Keep the invariant that frame_reg_rtx + sp_offset points
19937 at the top of the stack frame. */
19938 sp_offset = -info->spe_gp_save_offset;
19940 spe_offset = 0;
19943 if (restoring_GPRs_inline)
19945 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
19946 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
19948 rtx offset, addr, mem, reg;
19950 /* We're doing all this to ensure that the immediate offset
19951 fits into the immediate field of 'evldd'. */
19952 gcc_assert (SPE_CONST_OFFSET_OK (spe_offset + reg_size * i));
19954 offset = GEN_INT (spe_offset + reg_size * i);
19955 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, offset);
19956 mem = gen_rtx_MEM (V2SImode, addr);
19957 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
19959 insn = emit_move_insn (reg, mem);
19960 if (DEFAULT_ABI == ABI_V4)
19962 if (frame_pointer_needed
19963 && info->first_gp_reg_save + i
19964 == HARD_FRAME_POINTER_REGNUM)
19966 add_reg_note (insn, REG_CFA_DEF_CFA,
19967 plus_constant (frame_reg_rtx,
19968 sp_offset));
19969 RTX_FRAME_RELATED_P (insn) = 1;
19972 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
19973 cfa_restores);
19977 else
19979 rtx par;
19981 par = rs6000_make_savres_rtx (info, gen_rtx_REG (Pmode, 11),
19982 0, reg_mode,
19983 /*savep=*/false, /*gpr=*/true,
19984 /*lr=*/true);
19985 emit_jump_insn (par);
19986 /* We don't want anybody else emitting things after we jumped
19987 back. */
19988 return;
19991 else if (!restoring_GPRs_inline)
19993 /* We are jumping to an out-of-line function. */
19994 bool can_use_exit = info->first_fp_reg_save == 64;
19995 rtx par;
19997 /* Emit stack reset code if we need it. */
19998 if (can_use_exit)
19999 rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx,
20000 sp_offset, can_use_exit);
20001 else
20003 emit_insn (gen_add3_insn (gen_rtx_REG (Pmode, DEFAULT_ABI == ABI_AIX
20004 ? 12 : 11),
20005 frame_reg_rtx,
20006 GEN_INT (sp_offset - info->fp_size)));
20007 if (REGNO (frame_reg_rtx) == 11)
20008 sp_offset += info->fp_size;
20011 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
20012 info->gp_save_offset, reg_mode,
20013 /*savep=*/false, /*gpr=*/true,
20014 /*lr=*/can_use_exit);
20016 if (can_use_exit)
20018 if (info->cr_save_p)
20020 rs6000_restore_saved_cr (cr_save_reg, using_mtcr_multiple);
20021 if (DEFAULT_ABI == ABI_V4)
20022 cfa_restores
20023 = alloc_reg_note (REG_CFA_RESTORE,
20024 gen_rtx_REG (SImode, CR2_REGNO),
20025 cfa_restores);
20028 emit_jump_insn (par);
20030 /* We don't want anybody else emitting things after we jumped
20031 back. */
20032 return;
20035 insn = emit_insn (par);
20036 if (DEFAULT_ABI == ABI_V4)
20038 if (frame_pointer_needed)
20040 add_reg_note (insn, REG_CFA_DEF_CFA,
20041 plus_constant (frame_reg_rtx, sp_offset));
20042 RTX_FRAME_RELATED_P (insn) = 1;
20045 for (i = info->first_gp_reg_save; i < 32; i++)
20046 cfa_restores
20047 = alloc_reg_note (REG_CFA_RESTORE,
20048 gen_rtx_REG (reg_mode, i), cfa_restores);
20051 else if (using_load_multiple)
20053 rtvec p;
20054 p = rtvec_alloc (32 - info->first_gp_reg_save);
20055 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20057 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20058 GEN_INT (info->gp_save_offset
20059 + sp_offset
20060 + reg_size * i));
20061 rtx mem = gen_frame_mem (reg_mode, addr);
20062 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20064 RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, reg, mem);
20065 if (DEFAULT_ABI == ABI_V4)
20066 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
20067 cfa_restores);
20069 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
20070 if (DEFAULT_ABI == ABI_V4 && frame_pointer_needed)
20072 add_reg_note (insn, REG_CFA_DEF_CFA,
20073 plus_constant (frame_reg_rtx, sp_offset));
20074 RTX_FRAME_RELATED_P (insn) = 1;
20077 else
20079 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20080 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
20082 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20083 GEN_INT (info->gp_save_offset
20084 + sp_offset
20085 + reg_size * i));
20086 rtx mem = gen_frame_mem (reg_mode, addr);
20087 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20089 insn = emit_move_insn (reg, mem);
20090 if (DEFAULT_ABI == ABI_V4)
20092 if (frame_pointer_needed
20093 && info->first_gp_reg_save + i
20094 == HARD_FRAME_POINTER_REGNUM)
20096 add_reg_note (insn, REG_CFA_DEF_CFA,
20097 plus_constant (frame_reg_rtx, sp_offset));
20098 RTX_FRAME_RELATED_P (insn) = 1;
20101 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
20102 cfa_restores);
20107 if (restore_lr && !restoring_GPRs_inline)
20109 rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
20110 info->lr_save_offset + sp_offset);
20112 emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
20113 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO),
20114 gen_rtx_REG (Pmode, 0));
20117 /* Restore fpr's if we need to do it without calling a function. */
20118 if (restoring_FPRs_inline)
20119 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
20120 if ((df_regs_ever_live_p (info->first_fp_reg_save+i)
20121 && ! call_used_regs[info->first_fp_reg_save+i]))
20123 rtx addr, mem, reg;
20124 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20125 GEN_INT (info->fp_save_offset
20126 + sp_offset
20127 + 8 * i));
20128 mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20129 ? DFmode : SFmode), addr);
20130 reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20131 ? DFmode : SFmode),
20132 info->first_fp_reg_save + i);
20134 emit_move_insn (reg, mem);
20135 if (DEFAULT_ABI == ABI_V4)
20136 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
20137 cfa_restores);
20140 /* If we saved cr, restore it here. Just those that were used. */
20141 if (info->cr_save_p)
20143 rs6000_restore_saved_cr (cr_save_reg, using_mtcr_multiple);
20144 if (DEFAULT_ABI == ABI_V4)
20145 cfa_restores
20146 = alloc_reg_note (REG_CFA_RESTORE, gen_rtx_REG (SImode, CR2_REGNO),
20147 cfa_restores);
20150 /* If this is V.4, unwind the stack pointer after all of the loads
20151 have been done. */
20152 insn = rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx,
20153 sp_offset, !restoring_FPRs_inline);
20154 if (insn)
20156 if (cfa_restores)
20158 REG_NOTES (insn) = cfa_restores;
20159 cfa_restores = NULL_RTX;
20161 add_reg_note (insn, REG_CFA_DEF_CFA, sp_reg_rtx);
20162 RTX_FRAME_RELATED_P (insn) = 1;
20165 if (crtl->calls_eh_return)
20167 rtx sa = EH_RETURN_STACKADJ_RTX;
20168 emit_insn (gen_add3_insn (sp_reg_rtx, sp_reg_rtx, sa));
20171 if (!sibcall)
20173 rtvec p;
20174 bool lr = (strategy & SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR) == 0;
20175 if (! restoring_FPRs_inline)
20176 p = rtvec_alloc (4 + 64 - info->first_fp_reg_save);
20177 else
20178 p = rtvec_alloc (2);
20180 RTVEC_ELT (p, 0) = gen_rtx_RETURN (VOIDmode);
20181 RTVEC_ELT (p, 1) = ((restoring_FPRs_inline || !lr)
20182 ? gen_rtx_USE (VOIDmode, gen_rtx_REG (Pmode, 65))
20183 : gen_rtx_CLOBBER (VOIDmode,
20184 gen_rtx_REG (Pmode, 65)));
20186 /* If we have to restore more than two FP registers, branch to the
20187 restore function. It will return to our caller. */
20188 if (! restoring_FPRs_inline)
20190 int i;
20191 rtx sym;
20193 sym = rs6000_savres_routine_sym (info,
20194 /*savep=*/false,
20195 /*gpr=*/false,
20196 /*lr=*/lr);
20197 RTVEC_ELT (p, 2) = gen_rtx_USE (VOIDmode, sym);
20198 RTVEC_ELT (p, 3) = gen_rtx_USE (VOIDmode,
20199 gen_rtx_REG (Pmode,
20200 DEFAULT_ABI == ABI_AIX
20201 ? 1 : 11));
20202 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
20204 rtx addr, mem;
20205 addr = gen_rtx_PLUS (Pmode, sp_reg_rtx,
20206 GEN_INT (info->fp_save_offset + 8*i));
20207 mem = gen_frame_mem (DFmode, addr);
20209 RTVEC_ELT (p, i+4) =
20210 gen_rtx_SET (VOIDmode,
20211 gen_rtx_REG (DFmode, info->first_fp_reg_save + i),
20212 mem);
20216 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
20220 /* Write function epilogue. */
20222 static void
20223 rs6000_output_function_epilogue (FILE *file,
20224 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
20226 if (! HAVE_epilogue)
20228 rtx insn = get_last_insn ();
20229 /* If the last insn was a BARRIER, we don't have to write anything except
20230 the trace table. */
20231 if (GET_CODE (insn) == NOTE)
20232 insn = prev_nonnote_insn (insn);
20233 if (insn == 0 || GET_CODE (insn) != BARRIER)
20235 /* This is slightly ugly, but at least we don't have two
20236 copies of the epilogue-emitting code. */
20237 start_sequence ();
20239 /* A NOTE_INSN_DELETED is supposed to be at the start
20240 and end of the "toplevel" insn chain. */
20241 emit_note (NOTE_INSN_DELETED);
20242 rs6000_emit_epilogue (FALSE);
20243 emit_note (NOTE_INSN_DELETED);
20245 /* Expand INSN_ADDRESSES so final() doesn't crash. */
20247 rtx insn;
20248 unsigned addr = 0;
20249 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
20251 INSN_ADDRESSES_NEW (insn, addr);
20252 addr += 4;
20256 if (TARGET_DEBUG_STACK)
20257 debug_rtx_list (get_insns (), 100);
20258 final (get_insns (), file, FALSE);
20259 end_sequence ();
20263 #if TARGET_MACHO
20264 macho_branch_islands ();
20265 /* Mach-O doesn't support labels at the end of objects, so if
20266 it looks like we might want one, insert a NOP. */
20268 rtx insn = get_last_insn ();
20269 while (insn
20270 && NOTE_P (insn)
20271 && NOTE_KIND (insn) != NOTE_INSN_DELETED_LABEL)
20272 insn = PREV_INSN (insn);
20273 if (insn
20274 && (LABEL_P (insn)
20275 || (NOTE_P (insn)
20276 && NOTE_KIND (insn) == NOTE_INSN_DELETED_LABEL)))
20277 fputs ("\tnop\n", file);
20279 #endif
20281 /* Output a traceback table here. See /usr/include/sys/debug.h for info
20282 on its format.
20284 We don't output a traceback table if -finhibit-size-directive was
20285 used. The documentation for -finhibit-size-directive reads
20286 ``don't output a @code{.size} assembler directive, or anything
20287 else that would cause trouble if the function is split in the
20288 middle, and the two halves are placed at locations far apart in
20289 memory.'' The traceback table has this property, since it
20290 includes the offset from the start of the function to the
20291 traceback table itself.
20293 System V.4 Powerpc's (and the embedded ABI derived from it) use a
20294 different traceback table. */
20295 if (DEFAULT_ABI == ABI_AIX && ! flag_inhibit_size_directive
20296 && rs6000_traceback != traceback_none && !cfun->is_thunk)
20298 const char *fname = NULL;
20299 const char *language_string = lang_hooks.name;
20300 int fixed_parms = 0, float_parms = 0, parm_info = 0;
20301 int i;
20302 int optional_tbtab;
20303 rs6000_stack_t *info = rs6000_stack_info ();
20305 if (rs6000_traceback == traceback_full)
20306 optional_tbtab = 1;
20307 else if (rs6000_traceback == traceback_part)
20308 optional_tbtab = 0;
20309 else
20310 optional_tbtab = !optimize_size && !TARGET_ELF;
20312 if (optional_tbtab)
20314 fname = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0);
20315 while (*fname == '.') /* V.4 encodes . in the name */
20316 fname++;
20318 /* Need label immediately before tbtab, so we can compute
20319 its offset from the function start. */
20320 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
20321 ASM_OUTPUT_LABEL (file, fname);
20324 /* The .tbtab pseudo-op can only be used for the first eight
20325 expressions, since it can't handle the possibly variable
20326 length fields that follow. However, if you omit the optional
20327 fields, the assembler outputs zeros for all optional fields
20328 anyways, giving each variable length field is minimum length
20329 (as defined in sys/debug.h). Thus we can not use the .tbtab
20330 pseudo-op at all. */
20332 /* An all-zero word flags the start of the tbtab, for debuggers
20333 that have to find it by searching forward from the entry
20334 point or from the current pc. */
20335 fputs ("\t.long 0\n", file);
20337 /* Tbtab format type. Use format type 0. */
20338 fputs ("\t.byte 0,", file);
20340 /* Language type. Unfortunately, there does not seem to be any
20341 official way to discover the language being compiled, so we
20342 use language_string.
20343 C is 0. Fortran is 1. Pascal is 2. Ada is 3. C++ is 9.
20344 Java is 13. Objective-C is 14. Objective-C++ isn't assigned
20345 a number, so for now use 9. LTO isn't assigned a number either,
20346 so for now use 0. */
20347 if (! strcmp (language_string, "GNU C")
20348 || ! strcmp (language_string, "GNU GIMPLE"))
20349 i = 0;
20350 else if (! strcmp (language_string, "GNU F77")
20351 || ! strcmp (language_string, "GNU Fortran"))
20352 i = 1;
20353 else if (! strcmp (language_string, "GNU Pascal"))
20354 i = 2;
20355 else if (! strcmp (language_string, "GNU Ada"))
20356 i = 3;
20357 else if (! strcmp (language_string, "GNU C++")
20358 || ! strcmp (language_string, "GNU Objective-C++"))
20359 i = 9;
20360 else if (! strcmp (language_string, "GNU Java"))
20361 i = 13;
20362 else if (! strcmp (language_string, "GNU Objective-C"))
20363 i = 14;
20364 else
20365 gcc_unreachable ();
20366 fprintf (file, "%d,", i);
20368 /* 8 single bit fields: global linkage (not set for C extern linkage,
20369 apparently a PL/I convention?), out-of-line epilogue/prologue, offset
20370 from start of procedure stored in tbtab, internal function, function
20371 has controlled storage, function has no toc, function uses fp,
20372 function logs/aborts fp operations. */
20373 /* Assume that fp operations are used if any fp reg must be saved. */
20374 fprintf (file, "%d,",
20375 (optional_tbtab << 5) | ((info->first_fp_reg_save != 64) << 1));
20377 /* 6 bitfields: function is interrupt handler, name present in
20378 proc table, function calls alloca, on condition directives
20379 (controls stack walks, 3 bits), saves condition reg, saves
20380 link reg. */
20381 /* The `function calls alloca' bit seems to be set whenever reg 31 is
20382 set up as a frame pointer, even when there is no alloca call. */
20383 fprintf (file, "%d,",
20384 ((optional_tbtab << 6)
20385 | ((optional_tbtab & frame_pointer_needed) << 5)
20386 | (info->cr_save_p << 1)
20387 | (info->lr_save_p)));
20389 /* 3 bitfields: saves backchain, fixup code, number of fpr saved
20390 (6 bits). */
20391 fprintf (file, "%d,",
20392 (info->push_p << 7) | (64 - info->first_fp_reg_save));
20394 /* 2 bitfields: spare bits (2 bits), number of gpr saved (6 bits). */
20395 fprintf (file, "%d,", (32 - first_reg_to_save ()));
20397 if (optional_tbtab)
20399 /* Compute the parameter info from the function decl argument
20400 list. */
20401 tree decl;
20402 int next_parm_info_bit = 31;
20404 for (decl = DECL_ARGUMENTS (current_function_decl);
20405 decl; decl = TREE_CHAIN (decl))
20407 rtx parameter = DECL_INCOMING_RTL (decl);
20408 enum machine_mode mode = GET_MODE (parameter);
20410 if (GET_CODE (parameter) == REG)
20412 if (SCALAR_FLOAT_MODE_P (mode))
20414 int bits;
20416 float_parms++;
20418 switch (mode)
20420 case SFmode:
20421 case SDmode:
20422 bits = 0x2;
20423 break;
20425 case DFmode:
20426 case DDmode:
20427 case TFmode:
20428 case TDmode:
20429 bits = 0x3;
20430 break;
20432 default:
20433 gcc_unreachable ();
20436 /* If only one bit will fit, don't or in this entry. */
20437 if (next_parm_info_bit > 0)
20438 parm_info |= (bits << (next_parm_info_bit - 1));
20439 next_parm_info_bit -= 2;
20441 else
20443 fixed_parms += ((GET_MODE_SIZE (mode)
20444 + (UNITS_PER_WORD - 1))
20445 / UNITS_PER_WORD);
20446 next_parm_info_bit -= 1;
20452 /* Number of fixed point parameters. */
20453 /* This is actually the number of words of fixed point parameters; thus
20454 an 8 byte struct counts as 2; and thus the maximum value is 8. */
20455 fprintf (file, "%d,", fixed_parms);
20457 /* 2 bitfields: number of floating point parameters (7 bits), parameters
20458 all on stack. */
20459 /* This is actually the number of fp registers that hold parameters;
20460 and thus the maximum value is 13. */
20461 /* Set parameters on stack bit if parameters are not in their original
20462 registers, regardless of whether they are on the stack? Xlc
20463 seems to set the bit when not optimizing. */
20464 fprintf (file, "%d\n", ((float_parms << 1) | (! optimize)));
20466 if (! optional_tbtab)
20467 return;
20469 /* Optional fields follow. Some are variable length. */
20471 /* Parameter types, left adjusted bit fields: 0 fixed, 10 single float,
20472 11 double float. */
20473 /* There is an entry for each parameter in a register, in the order that
20474 they occur in the parameter list. Any intervening arguments on the
20475 stack are ignored. If the list overflows a long (max possible length
20476 34 bits) then completely leave off all elements that don't fit. */
20477 /* Only emit this long if there was at least one parameter. */
20478 if (fixed_parms || float_parms)
20479 fprintf (file, "\t.long %d\n", parm_info);
20481 /* Offset from start of code to tb table. */
20482 fputs ("\t.long ", file);
20483 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
20484 if (TARGET_AIX)
20485 RS6000_OUTPUT_BASENAME (file, fname);
20486 else
20487 assemble_name (file, fname);
20488 putc ('-', file);
20489 rs6000_output_function_entry (file, fname);
20490 putc ('\n', file);
20492 /* Interrupt handler mask. */
20493 /* Omit this long, since we never set the interrupt handler bit
20494 above. */
20496 /* Number of CTL (controlled storage) anchors. */
20497 /* Omit this long, since the has_ctl bit is never set above. */
20499 /* Displacement into stack of each CTL anchor. */
20500 /* Omit this list of longs, because there are no CTL anchors. */
20502 /* Length of function name. */
20503 if (*fname == '*')
20504 ++fname;
20505 fprintf (file, "\t.short %d\n", (int) strlen (fname));
20507 /* Function name. */
20508 assemble_string (fname, strlen (fname));
20510 /* Register for alloca automatic storage; this is always reg 31.
20511 Only emit this if the alloca bit was set above. */
20512 if (frame_pointer_needed)
20513 fputs ("\t.byte 31\n", file);
20515 fputs ("\t.align 2\n", file);
20519 /* A C compound statement that outputs the assembler code for a thunk
20520 function, used to implement C++ virtual function calls with
20521 multiple inheritance. The thunk acts as a wrapper around a virtual
20522 function, adjusting the implicit object parameter before handing
20523 control off to the real function.
20525 First, emit code to add the integer DELTA to the location that
20526 contains the incoming first argument. Assume that this argument
20527 contains a pointer, and is the one used to pass the `this' pointer
20528 in C++. This is the incoming argument *before* the function
20529 prologue, e.g. `%o0' on a sparc. The addition must preserve the
20530 values of all other incoming arguments.
20532 After the addition, emit code to jump to FUNCTION, which is a
20533 `FUNCTION_DECL'. This is a direct pure jump, not a call, and does
20534 not touch the return address. Hence returning from FUNCTION will
20535 return to whoever called the current `thunk'.
20537 The effect must be as if FUNCTION had been called directly with the
20538 adjusted first argument. This macro is responsible for emitting
20539 all of the code for a thunk function; output_function_prologue()
20540 and output_function_epilogue() are not invoked.
20542 The THUNK_FNDECL is redundant. (DELTA and FUNCTION have already
20543 been extracted from it.) It might possibly be useful on some
20544 targets, but probably not.
20546 If you do not define this macro, the target-independent code in the
20547 C++ frontend will generate a less efficient heavyweight thunk that
20548 calls FUNCTION instead of jumping to it. The generic approach does
20549 not support varargs. */
20551 static void
20552 rs6000_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
20553 HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
20554 tree function)
20556 rtx this_rtx, insn, funexp;
20558 reload_completed = 1;
20559 epilogue_completed = 1;
20561 /* Mark the end of the (empty) prologue. */
20562 emit_note (NOTE_INSN_PROLOGUE_END);
20564 /* Find the "this" pointer. If the function returns a structure,
20565 the structure return pointer is in r3. */
20566 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function))
20567 this_rtx = gen_rtx_REG (Pmode, 4);
20568 else
20569 this_rtx = gen_rtx_REG (Pmode, 3);
20571 /* Apply the constant offset, if required. */
20572 if (delta)
20573 emit_insn (gen_add3_insn (this_rtx, this_rtx, GEN_INT (delta)));
20575 /* Apply the offset from the vtable, if required. */
20576 if (vcall_offset)
20578 rtx vcall_offset_rtx = GEN_INT (vcall_offset);
20579 rtx tmp = gen_rtx_REG (Pmode, 12);
20581 emit_move_insn (tmp, gen_rtx_MEM (Pmode, this_rtx));
20582 if (((unsigned HOST_WIDE_INT) vcall_offset) + 0x8000 >= 0x10000)
20584 emit_insn (gen_add3_insn (tmp, tmp, vcall_offset_rtx));
20585 emit_move_insn (tmp, gen_rtx_MEM (Pmode, tmp));
20587 else
20589 rtx loc = gen_rtx_PLUS (Pmode, tmp, vcall_offset_rtx);
20591 emit_move_insn (tmp, gen_rtx_MEM (Pmode, loc));
20593 emit_insn (gen_add3_insn (this_rtx, this_rtx, tmp));
20596 /* Generate a tail call to the target function. */
20597 if (!TREE_USED (function))
20599 assemble_external (function);
20600 TREE_USED (function) = 1;
20602 funexp = XEXP (DECL_RTL (function), 0);
20603 funexp = gen_rtx_MEM (FUNCTION_MODE, funexp);
20605 #if TARGET_MACHO
20606 if (MACHOPIC_INDIRECT)
20607 funexp = machopic_indirect_call_target (funexp);
20608 #endif
20610 /* gen_sibcall expects reload to convert scratch pseudo to LR so we must
20611 generate sibcall RTL explicitly. */
20612 insn = emit_call_insn (
20613 gen_rtx_PARALLEL (VOIDmode,
20614 gen_rtvec (4,
20615 gen_rtx_CALL (VOIDmode,
20616 funexp, const0_rtx),
20617 gen_rtx_USE (VOIDmode, const0_rtx),
20618 gen_rtx_USE (VOIDmode,
20619 gen_rtx_REG (SImode,
20620 LR_REGNO)),
20621 gen_rtx_RETURN (VOIDmode))));
20622 SIBLING_CALL_P (insn) = 1;
20623 emit_barrier ();
20625 /* Run just enough of rest_of_compilation to get the insns emitted.
20626 There's not really enough bulk here to make other passes such as
20627 instruction scheduling worth while. Note that use_thunk calls
20628 assemble_start_function and assemble_end_function. */
20629 insn = get_insns ();
20630 insn_locators_alloc ();
20631 shorten_branches (insn);
20632 final_start_function (insn, file, 1);
20633 final (insn, file, 1);
20634 final_end_function ();
20636 reload_completed = 0;
20637 epilogue_completed = 0;
20640 /* A quick summary of the various types of 'constant-pool tables'
20641 under PowerPC:
20643 Target Flags Name One table per
20644 AIX (none) AIX TOC object file
20645 AIX -mfull-toc AIX TOC object file
20646 AIX -mminimal-toc AIX minimal TOC translation unit
20647 SVR4/EABI (none) SVR4 SDATA object file
20648 SVR4/EABI -fpic SVR4 pic object file
20649 SVR4/EABI -fPIC SVR4 PIC translation unit
20650 SVR4/EABI -mrelocatable EABI TOC function
20651 SVR4/EABI -maix AIX TOC object file
20652 SVR4/EABI -maix -mminimal-toc
20653 AIX minimal TOC translation unit
20655 Name Reg. Set by entries contains:
20656 made by addrs? fp? sum?
20658 AIX TOC 2 crt0 as Y option option
20659 AIX minimal TOC 30 prolog gcc Y Y option
20660 SVR4 SDATA 13 crt0 gcc N Y N
20661 SVR4 pic 30 prolog ld Y not yet N
20662 SVR4 PIC 30 prolog gcc Y option option
20663 EABI TOC 30 prolog gcc Y option option
20667 /* Hash functions for the hash table. */
20669 static unsigned
20670 rs6000_hash_constant (rtx k)
20672 enum rtx_code code = GET_CODE (k);
20673 enum machine_mode mode = GET_MODE (k);
20674 unsigned result = (code << 3) ^ mode;
20675 const char *format;
20676 int flen, fidx;
20678 format = GET_RTX_FORMAT (code);
20679 flen = strlen (format);
20680 fidx = 0;
20682 switch (code)
20684 case LABEL_REF:
20685 return result * 1231 + (unsigned) INSN_UID (XEXP (k, 0));
20687 case CONST_DOUBLE:
20688 if (mode != VOIDmode)
20689 return real_hash (CONST_DOUBLE_REAL_VALUE (k)) * result;
20690 flen = 2;
20691 break;
20693 case CODE_LABEL:
20694 fidx = 3;
20695 break;
20697 default:
20698 break;
20701 for (; fidx < flen; fidx++)
20702 switch (format[fidx])
20704 case 's':
20706 unsigned i, len;
20707 const char *str = XSTR (k, fidx);
20708 len = strlen (str);
20709 result = result * 613 + len;
20710 for (i = 0; i < len; i++)
20711 result = result * 613 + (unsigned) str[i];
20712 break;
20714 case 'u':
20715 case 'e':
20716 result = result * 1231 + rs6000_hash_constant (XEXP (k, fidx));
20717 break;
20718 case 'i':
20719 case 'n':
20720 result = result * 613 + (unsigned) XINT (k, fidx);
20721 break;
20722 case 'w':
20723 if (sizeof (unsigned) >= sizeof (HOST_WIDE_INT))
20724 result = result * 613 + (unsigned) XWINT (k, fidx);
20725 else
20727 size_t i;
20728 for (i = 0; i < sizeof (HOST_WIDE_INT) / sizeof (unsigned); i++)
20729 result = result * 613 + (unsigned) (XWINT (k, fidx)
20730 >> CHAR_BIT * i);
20732 break;
20733 case '0':
20734 break;
20735 default:
20736 gcc_unreachable ();
20739 return result;
20742 static unsigned
20743 toc_hash_function (const void *hash_entry)
20745 const struct toc_hash_struct *thc =
20746 (const struct toc_hash_struct *) hash_entry;
20747 return rs6000_hash_constant (thc->key) ^ thc->key_mode;
20750 /* Compare H1 and H2 for equivalence. */
20752 static int
20753 toc_hash_eq (const void *h1, const void *h2)
20755 rtx r1 = ((const struct toc_hash_struct *) h1)->key;
20756 rtx r2 = ((const struct toc_hash_struct *) h2)->key;
20758 if (((const struct toc_hash_struct *) h1)->key_mode
20759 != ((const struct toc_hash_struct *) h2)->key_mode)
20760 return 0;
20762 return rtx_equal_p (r1, r2);
20765 /* These are the names given by the C++ front-end to vtables, and
20766 vtable-like objects. Ideally, this logic should not be here;
20767 instead, there should be some programmatic way of inquiring as
20768 to whether or not an object is a vtable. */
20770 #define VTABLE_NAME_P(NAME) \
20771 (strncmp ("_vt.", name, strlen ("_vt.")) == 0 \
20772 || strncmp ("_ZTV", name, strlen ("_ZTV")) == 0 \
20773 || strncmp ("_ZTT", name, strlen ("_ZTT")) == 0 \
20774 || strncmp ("_ZTI", name, strlen ("_ZTI")) == 0 \
20775 || strncmp ("_ZTC", name, strlen ("_ZTC")) == 0)
20777 #ifdef NO_DOLLAR_IN_LABEL
20778 /* Return a GGC-allocated character string translating dollar signs in
20779 input NAME to underscores. Used by XCOFF ASM_OUTPUT_LABELREF. */
20781 const char *
20782 rs6000_xcoff_strip_dollar (const char *name)
20784 char *strip, *p;
20785 int len;
20787 p = strchr (name, '$');
20789 if (p == 0 || p == name)
20790 return name;
20792 len = strlen (name);
20793 strip = (char *) alloca (len + 1);
20794 strcpy (strip, name);
20795 p = strchr (strip, '$');
20796 while (p)
20798 *p = '_';
20799 p = strchr (p + 1, '$');
20802 return ggc_alloc_string (strip, len);
20804 #endif
20806 void
20807 rs6000_output_symbol_ref (FILE *file, rtx x)
20809 /* Currently C++ toc references to vtables can be emitted before it
20810 is decided whether the vtable is public or private. If this is
20811 the case, then the linker will eventually complain that there is
20812 a reference to an unknown section. Thus, for vtables only,
20813 we emit the TOC reference to reference the symbol and not the
20814 section. */
20815 const char *name = XSTR (x, 0);
20817 if (VTABLE_NAME_P (name))
20819 RS6000_OUTPUT_BASENAME (file, name);
20821 else
20822 assemble_name (file, name);
20825 /* Output a TOC entry. We derive the entry name from what is being
20826 written. */
20828 void
20829 output_toc (FILE *file, rtx x, int labelno, enum machine_mode mode)
20831 char buf[256];
20832 const char *name = buf;
20833 rtx base = x;
20834 HOST_WIDE_INT offset = 0;
20836 gcc_assert (!TARGET_NO_TOC);
20838 /* When the linker won't eliminate them, don't output duplicate
20839 TOC entries (this happens on AIX if there is any kind of TOC,
20840 and on SVR4 under -fPIC or -mrelocatable). Don't do this for
20841 CODE_LABELs. */
20842 if (TARGET_TOC && GET_CODE (x) != LABEL_REF)
20844 struct toc_hash_struct *h;
20845 void * * found;
20847 /* Create toc_hash_table. This can't be done at OVERRIDE_OPTIONS
20848 time because GGC is not initialized at that point. */
20849 if (toc_hash_table == NULL)
20850 toc_hash_table = htab_create_ggc (1021, toc_hash_function,
20851 toc_hash_eq, NULL);
20853 h = GGC_NEW (struct toc_hash_struct);
20854 h->key = x;
20855 h->key_mode = mode;
20856 h->labelno = labelno;
20858 found = htab_find_slot (toc_hash_table, h, INSERT);
20859 if (*found == NULL)
20860 *found = h;
20861 else /* This is indeed a duplicate.
20862 Set this label equal to that label. */
20864 fputs ("\t.set ", file);
20865 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
20866 fprintf (file, "%d,", labelno);
20867 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
20868 fprintf (file, "%d\n", ((*(const struct toc_hash_struct **)
20869 found)->labelno));
20870 return;
20874 /* If we're going to put a double constant in the TOC, make sure it's
20875 aligned properly when strict alignment is on. */
20876 if (GET_CODE (x) == CONST_DOUBLE
20877 && STRICT_ALIGNMENT
20878 && GET_MODE_BITSIZE (mode) >= 64
20879 && ! (TARGET_NO_FP_IN_TOC && ! TARGET_MINIMAL_TOC)) {
20880 ASM_OUTPUT_ALIGN (file, 3);
20883 (*targetm.asm_out.internal_label) (file, "LC", labelno);
20885 /* Handle FP constants specially. Note that if we have a minimal
20886 TOC, things we put here aren't actually in the TOC, so we can allow
20887 FP constants. */
20888 if (GET_CODE (x) == CONST_DOUBLE &&
20889 (GET_MODE (x) == TFmode || GET_MODE (x) == TDmode))
20891 REAL_VALUE_TYPE rv;
20892 long k[4];
20894 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
20895 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
20896 REAL_VALUE_TO_TARGET_DECIMAL128 (rv, k);
20897 else
20898 REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv, k);
20900 if (TARGET_64BIT)
20902 if (TARGET_MINIMAL_TOC)
20903 fputs (DOUBLE_INT_ASM_OP, file);
20904 else
20905 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
20906 k[0] & 0xffffffff, k[1] & 0xffffffff,
20907 k[2] & 0xffffffff, k[3] & 0xffffffff);
20908 fprintf (file, "0x%lx%08lx,0x%lx%08lx\n",
20909 k[0] & 0xffffffff, k[1] & 0xffffffff,
20910 k[2] & 0xffffffff, k[3] & 0xffffffff);
20911 return;
20913 else
20915 if (TARGET_MINIMAL_TOC)
20916 fputs ("\t.long ", file);
20917 else
20918 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
20919 k[0] & 0xffffffff, k[1] & 0xffffffff,
20920 k[2] & 0xffffffff, k[3] & 0xffffffff);
20921 fprintf (file, "0x%lx,0x%lx,0x%lx,0x%lx\n",
20922 k[0] & 0xffffffff, k[1] & 0xffffffff,
20923 k[2] & 0xffffffff, k[3] & 0xffffffff);
20924 return;
20927 else if (GET_CODE (x) == CONST_DOUBLE &&
20928 (GET_MODE (x) == DFmode || GET_MODE (x) == DDmode))
20930 REAL_VALUE_TYPE rv;
20931 long k[2];
20933 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
20935 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
20936 REAL_VALUE_TO_TARGET_DECIMAL64 (rv, k);
20937 else
20938 REAL_VALUE_TO_TARGET_DOUBLE (rv, k);
20940 if (TARGET_64BIT)
20942 if (TARGET_MINIMAL_TOC)
20943 fputs (DOUBLE_INT_ASM_OP, file);
20944 else
20945 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
20946 k[0] & 0xffffffff, k[1] & 0xffffffff);
20947 fprintf (file, "0x%lx%08lx\n",
20948 k[0] & 0xffffffff, k[1] & 0xffffffff);
20949 return;
20951 else
20953 if (TARGET_MINIMAL_TOC)
20954 fputs ("\t.long ", file);
20955 else
20956 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
20957 k[0] & 0xffffffff, k[1] & 0xffffffff);
20958 fprintf (file, "0x%lx,0x%lx\n",
20959 k[0] & 0xffffffff, k[1] & 0xffffffff);
20960 return;
20963 else if (GET_CODE (x) == CONST_DOUBLE &&
20964 (GET_MODE (x) == SFmode || GET_MODE (x) == SDmode))
20966 REAL_VALUE_TYPE rv;
20967 long l;
20969 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
20970 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
20971 REAL_VALUE_TO_TARGET_DECIMAL32 (rv, l);
20972 else
20973 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
20975 if (TARGET_64BIT)
20977 if (TARGET_MINIMAL_TOC)
20978 fputs (DOUBLE_INT_ASM_OP, file);
20979 else
20980 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
20981 fprintf (file, "0x%lx00000000\n", l & 0xffffffff);
20982 return;
20984 else
20986 if (TARGET_MINIMAL_TOC)
20987 fputs ("\t.long ", file);
20988 else
20989 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
20990 fprintf (file, "0x%lx\n", l & 0xffffffff);
20991 return;
20994 else if (GET_MODE (x) == VOIDmode
20995 && (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE))
20997 unsigned HOST_WIDE_INT low;
20998 HOST_WIDE_INT high;
21000 if (GET_CODE (x) == CONST_DOUBLE)
21002 low = CONST_DOUBLE_LOW (x);
21003 high = CONST_DOUBLE_HIGH (x);
21005 else
21006 #if HOST_BITS_PER_WIDE_INT == 32
21008 low = INTVAL (x);
21009 high = (low & 0x80000000) ? ~0 : 0;
21011 #else
21013 low = INTVAL (x) & 0xffffffff;
21014 high = (HOST_WIDE_INT) INTVAL (x) >> 32;
21016 #endif
21018 /* TOC entries are always Pmode-sized, but since this
21019 is a bigendian machine then if we're putting smaller
21020 integer constants in the TOC we have to pad them.
21021 (This is still a win over putting the constants in
21022 a separate constant pool, because then we'd have
21023 to have both a TOC entry _and_ the actual constant.)
21025 For a 32-bit target, CONST_INT values are loaded and shifted
21026 entirely within `low' and can be stored in one TOC entry. */
21028 /* It would be easy to make this work, but it doesn't now. */
21029 gcc_assert (!TARGET_64BIT || POINTER_SIZE >= GET_MODE_BITSIZE (mode));
21031 if (POINTER_SIZE > GET_MODE_BITSIZE (mode))
21033 #if HOST_BITS_PER_WIDE_INT == 32
21034 lshift_double (low, high, POINTER_SIZE - GET_MODE_BITSIZE (mode),
21035 POINTER_SIZE, &low, &high, 0);
21036 #else
21037 low |= high << 32;
21038 low <<= POINTER_SIZE - GET_MODE_BITSIZE (mode);
21039 high = (HOST_WIDE_INT) low >> 32;
21040 low &= 0xffffffff;
21041 #endif
21044 if (TARGET_64BIT)
21046 if (TARGET_MINIMAL_TOC)
21047 fputs (DOUBLE_INT_ASM_OP, file);
21048 else
21049 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
21050 (long) high & 0xffffffff, (long) low & 0xffffffff);
21051 fprintf (file, "0x%lx%08lx\n",
21052 (long) high & 0xffffffff, (long) low & 0xffffffff);
21053 return;
21055 else
21057 if (POINTER_SIZE < GET_MODE_BITSIZE (mode))
21059 if (TARGET_MINIMAL_TOC)
21060 fputs ("\t.long ", file);
21061 else
21062 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
21063 (long) high & 0xffffffff, (long) low & 0xffffffff);
21064 fprintf (file, "0x%lx,0x%lx\n",
21065 (long) high & 0xffffffff, (long) low & 0xffffffff);
21067 else
21069 if (TARGET_MINIMAL_TOC)
21070 fputs ("\t.long ", file);
21071 else
21072 fprintf (file, "\t.tc IS_%lx[TC],", (long) low & 0xffffffff);
21073 fprintf (file, "0x%lx\n", (long) low & 0xffffffff);
21075 return;
21079 if (GET_CODE (x) == CONST)
21081 gcc_assert (GET_CODE (XEXP (x, 0)) == PLUS
21082 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT);
21084 base = XEXP (XEXP (x, 0), 0);
21085 offset = INTVAL (XEXP (XEXP (x, 0), 1));
21088 switch (GET_CODE (base))
21090 case SYMBOL_REF:
21091 name = XSTR (base, 0);
21092 break;
21094 case LABEL_REF:
21095 ASM_GENERATE_INTERNAL_LABEL (buf, "L",
21096 CODE_LABEL_NUMBER (XEXP (base, 0)));
21097 break;
21099 case CODE_LABEL:
21100 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (base));
21101 break;
21103 default:
21104 gcc_unreachable ();
21107 if (TARGET_MINIMAL_TOC)
21108 fputs (TARGET_32BIT ? "\t.long " : DOUBLE_INT_ASM_OP, file);
21109 else
21111 fputs ("\t.tc ", file);
21112 RS6000_OUTPUT_BASENAME (file, name);
21114 if (offset < 0)
21115 fprintf (file, ".N" HOST_WIDE_INT_PRINT_UNSIGNED, - offset);
21116 else if (offset)
21117 fprintf (file, ".P" HOST_WIDE_INT_PRINT_UNSIGNED, offset);
21119 fputs ("[TC],", file);
21122 /* Currently C++ toc references to vtables can be emitted before it
21123 is decided whether the vtable is public or private. If this is
21124 the case, then the linker will eventually complain that there is
21125 a TOC reference to an unknown section. Thus, for vtables only,
21126 we emit the TOC reference to reference the symbol and not the
21127 section. */
21128 if (VTABLE_NAME_P (name))
21130 RS6000_OUTPUT_BASENAME (file, name);
21131 if (offset < 0)
21132 fprintf (file, HOST_WIDE_INT_PRINT_DEC, offset);
21133 else if (offset > 0)
21134 fprintf (file, "+" HOST_WIDE_INT_PRINT_DEC, offset);
21136 else
21137 output_addr_const (file, x);
21138 putc ('\n', file);
21141 /* Output an assembler pseudo-op to write an ASCII string of N characters
21142 starting at P to FILE.
21144 On the RS/6000, we have to do this using the .byte operation and
21145 write out special characters outside the quoted string.
21146 Also, the assembler is broken; very long strings are truncated,
21147 so we must artificially break them up early. */
21149 void
21150 output_ascii (FILE *file, const char *p, int n)
21152 char c;
21153 int i, count_string;
21154 const char *for_string = "\t.byte \"";
21155 const char *for_decimal = "\t.byte ";
21156 const char *to_close = NULL;
21158 count_string = 0;
21159 for (i = 0; i < n; i++)
21161 c = *p++;
21162 if (c >= ' ' && c < 0177)
21164 if (for_string)
21165 fputs (for_string, file);
21166 putc (c, file);
21168 /* Write two quotes to get one. */
21169 if (c == '"')
21171 putc (c, file);
21172 ++count_string;
21175 for_string = NULL;
21176 for_decimal = "\"\n\t.byte ";
21177 to_close = "\"\n";
21178 ++count_string;
21180 if (count_string >= 512)
21182 fputs (to_close, file);
21184 for_string = "\t.byte \"";
21185 for_decimal = "\t.byte ";
21186 to_close = NULL;
21187 count_string = 0;
21190 else
21192 if (for_decimal)
21193 fputs (for_decimal, file);
21194 fprintf (file, "%d", c);
21196 for_string = "\n\t.byte \"";
21197 for_decimal = ", ";
21198 to_close = "\n";
21199 count_string = 0;
21203 /* Now close the string if we have written one. Then end the line. */
21204 if (to_close)
21205 fputs (to_close, file);
21208 /* Generate a unique section name for FILENAME for a section type
21209 represented by SECTION_DESC. Output goes into BUF.
21211 SECTION_DESC can be any string, as long as it is different for each
21212 possible section type.
21214 We name the section in the same manner as xlc. The name begins with an
21215 underscore followed by the filename (after stripping any leading directory
21216 names) with the last period replaced by the string SECTION_DESC. If
21217 FILENAME does not contain a period, SECTION_DESC is appended to the end of
21218 the name. */
21220 void
21221 rs6000_gen_section_name (char **buf, const char *filename,
21222 const char *section_desc)
21224 const char *q, *after_last_slash, *last_period = 0;
21225 char *p;
21226 int len;
21228 after_last_slash = filename;
21229 for (q = filename; *q; q++)
21231 if (*q == '/')
21232 after_last_slash = q + 1;
21233 else if (*q == '.')
21234 last_period = q;
21237 len = strlen (after_last_slash) + strlen (section_desc) + 2;
21238 *buf = (char *) xmalloc (len);
21240 p = *buf;
21241 *p++ = '_';
21243 for (q = after_last_slash; *q; q++)
21245 if (q == last_period)
21247 strcpy (p, section_desc);
21248 p += strlen (section_desc);
21249 break;
21252 else if (ISALNUM (*q))
21253 *p++ = *q;
21256 if (last_period == 0)
21257 strcpy (p, section_desc);
21258 else
21259 *p = '\0';
21262 /* Emit profile function. */
21264 void
21265 output_profile_hook (int labelno ATTRIBUTE_UNUSED)
21267 /* Non-standard profiling for kernels, which just saves LR then calls
21268 _mcount without worrying about arg saves. The idea is to change
21269 the function prologue as little as possible as it isn't easy to
21270 account for arg save/restore code added just for _mcount. */
21271 if (TARGET_PROFILE_KERNEL)
21272 return;
21274 if (DEFAULT_ABI == ABI_AIX)
21276 #ifndef NO_PROFILE_COUNTERS
21277 # define NO_PROFILE_COUNTERS 0
21278 #endif
21279 if (NO_PROFILE_COUNTERS)
21280 emit_library_call (init_one_libfunc (RS6000_MCOUNT),
21281 LCT_NORMAL, VOIDmode, 0);
21282 else
21284 char buf[30];
21285 const char *label_name;
21286 rtx fun;
21288 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
21289 label_name = (*targetm.strip_name_encoding) (ggc_strdup (buf));
21290 fun = gen_rtx_SYMBOL_REF (Pmode, label_name);
21292 emit_library_call (init_one_libfunc (RS6000_MCOUNT),
21293 LCT_NORMAL, VOIDmode, 1, fun, Pmode);
21296 else if (DEFAULT_ABI == ABI_DARWIN)
21298 const char *mcount_name = RS6000_MCOUNT;
21299 int caller_addr_regno = LR_REGNO;
21301 /* Be conservative and always set this, at least for now. */
21302 crtl->uses_pic_offset_table = 1;
21304 #if TARGET_MACHO
21305 /* For PIC code, set up a stub and collect the caller's address
21306 from r0, which is where the prologue puts it. */
21307 if (MACHOPIC_INDIRECT
21308 && crtl->uses_pic_offset_table)
21309 caller_addr_regno = 0;
21310 #endif
21311 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, mcount_name),
21312 LCT_NORMAL, VOIDmode, 1,
21313 gen_rtx_REG (Pmode, caller_addr_regno), Pmode);
21317 /* Write function profiler code. */
21319 void
21320 output_function_profiler (FILE *file, int labelno)
21322 char buf[100];
21324 switch (DEFAULT_ABI)
21326 default:
21327 gcc_unreachable ();
21329 case ABI_V4:
21330 if (!TARGET_32BIT)
21332 warning (0, "no profiling of 64-bit code for this ABI");
21333 return;
21335 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
21336 fprintf (file, "\tmflr %s\n", reg_names[0]);
21337 if (NO_PROFILE_COUNTERS)
21339 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
21340 reg_names[0], reg_names[1]);
21342 else if (TARGET_SECURE_PLT && flag_pic)
21344 asm_fprintf (file, "\tbcl 20,31,1f\n1:\n\t{st|stw} %s,4(%s)\n",
21345 reg_names[0], reg_names[1]);
21346 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
21347 asm_fprintf (file, "\t{cau|addis} %s,%s,",
21348 reg_names[12], reg_names[12]);
21349 assemble_name (file, buf);
21350 asm_fprintf (file, "-1b@ha\n\t{cal|la} %s,", reg_names[0]);
21351 assemble_name (file, buf);
21352 asm_fprintf (file, "-1b@l(%s)\n", reg_names[12]);
21354 else if (flag_pic == 1)
21356 fputs ("\tbl _GLOBAL_OFFSET_TABLE_@local-4\n", file);
21357 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
21358 reg_names[0], reg_names[1]);
21359 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
21360 asm_fprintf (file, "\t{l|lwz} %s,", reg_names[0]);
21361 assemble_name (file, buf);
21362 asm_fprintf (file, "@got(%s)\n", reg_names[12]);
21364 else if (flag_pic > 1)
21366 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
21367 reg_names[0], reg_names[1]);
21368 /* Now, we need to get the address of the label. */
21369 fputs ("\tbcl 20,31,1f\n\t.long ", file);
21370 assemble_name (file, buf);
21371 fputs ("-.\n1:", file);
21372 asm_fprintf (file, "\tmflr %s\n", reg_names[11]);
21373 asm_fprintf (file, "\t{l|lwz} %s,0(%s)\n",
21374 reg_names[0], reg_names[11]);
21375 asm_fprintf (file, "\t{cax|add} %s,%s,%s\n",
21376 reg_names[0], reg_names[0], reg_names[11]);
21378 else
21380 asm_fprintf (file, "\t{liu|lis} %s,", reg_names[12]);
21381 assemble_name (file, buf);
21382 fputs ("@ha\n", file);
21383 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
21384 reg_names[0], reg_names[1]);
21385 asm_fprintf (file, "\t{cal|la} %s,", reg_names[0]);
21386 assemble_name (file, buf);
21387 asm_fprintf (file, "@l(%s)\n", reg_names[12]);
21390 /* ABI_V4 saves the static chain reg with ASM_OUTPUT_REG_PUSH. */
21391 fprintf (file, "\tbl %s%s\n",
21392 RS6000_MCOUNT, flag_pic ? "@plt" : "");
21393 break;
21395 case ABI_AIX:
21396 case ABI_DARWIN:
21397 if (!TARGET_PROFILE_KERNEL)
21399 /* Don't do anything, done in output_profile_hook (). */
21401 else
21403 gcc_assert (!TARGET_32BIT);
21405 asm_fprintf (file, "\tmflr %s\n", reg_names[0]);
21406 asm_fprintf (file, "\tstd %s,16(%s)\n", reg_names[0], reg_names[1]);
21408 if (cfun->static_chain_decl != NULL)
21410 asm_fprintf (file, "\tstd %s,24(%s)\n",
21411 reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
21412 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
21413 asm_fprintf (file, "\tld %s,24(%s)\n",
21414 reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
21416 else
21417 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
21419 break;
21425 /* The following variable value is the last issued insn. */
21427 static rtx last_scheduled_insn;
21429 /* The following variable helps to balance issuing of load and
21430 store instructions */
21432 static int load_store_pendulum;
21434 /* Power4 load update and store update instructions are cracked into a
21435 load or store and an integer insn which are executed in the same cycle.
21436 Branches have their own dispatch slot which does not count against the
21437 GCC issue rate, but it changes the program flow so there are no other
21438 instructions to issue in this cycle. */
21440 static int
21441 rs6000_variable_issue_1 (rtx insn, int more)
21443 last_scheduled_insn = insn;
21444 if (GET_CODE (PATTERN (insn)) == USE
21445 || GET_CODE (PATTERN (insn)) == CLOBBER)
21447 cached_can_issue_more = more;
21448 return cached_can_issue_more;
21451 if (insn_terminates_group_p (insn, current_group))
21453 cached_can_issue_more = 0;
21454 return cached_can_issue_more;
21457 /* If no reservation, but reach here */
21458 if (recog_memoized (insn) < 0)
21459 return more;
21461 if (rs6000_sched_groups)
21463 if (is_microcoded_insn (insn))
21464 cached_can_issue_more = 0;
21465 else if (is_cracked_insn (insn))
21466 cached_can_issue_more = more > 2 ? more - 2 : 0;
21467 else
21468 cached_can_issue_more = more - 1;
21470 return cached_can_issue_more;
21473 if (rs6000_cpu_attr == CPU_CELL && is_nonpipeline_insn (insn))
21474 return 0;
21476 cached_can_issue_more = more - 1;
21477 return cached_can_issue_more;
21480 static int
21481 rs6000_variable_issue (FILE *stream, int verbose, rtx insn, int more)
21483 int r = rs6000_variable_issue_1 (insn, more);
21484 if (verbose)
21485 fprintf (stream, "// rs6000_variable_issue (more = %d) = %d\n", more, r);
21486 return r;
21489 /* Adjust the cost of a scheduling dependency. Return the new cost of
21490 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
21492 static int
21493 rs6000_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
21495 enum attr_type attr_type;
21497 if (! recog_memoized (insn))
21498 return 0;
21500 switch (REG_NOTE_KIND (link))
21502 case REG_DEP_TRUE:
21504 /* Data dependency; DEP_INSN writes a register that INSN reads
21505 some cycles later. */
21507 /* Separate a load from a narrower, dependent store. */
21508 if (rs6000_sched_groups
21509 && GET_CODE (PATTERN (insn)) == SET
21510 && GET_CODE (PATTERN (dep_insn)) == SET
21511 && GET_CODE (XEXP (PATTERN (insn), 1)) == MEM
21512 && GET_CODE (XEXP (PATTERN (dep_insn), 0)) == MEM
21513 && (GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (insn), 1)))
21514 > GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (dep_insn), 0)))))
21515 return cost + 14;
21517 attr_type = get_attr_type (insn);
21519 switch (attr_type)
21521 case TYPE_JMPREG:
21522 /* Tell the first scheduling pass about the latency between
21523 a mtctr and bctr (and mtlr and br/blr). The first
21524 scheduling pass will not know about this latency since
21525 the mtctr instruction, which has the latency associated
21526 to it, will be generated by reload. */
21527 return TARGET_POWER ? 5 : 4;
21528 case TYPE_BRANCH:
21529 /* Leave some extra cycles between a compare and its
21530 dependent branch, to inhibit expensive mispredicts. */
21531 if ((rs6000_cpu_attr == CPU_PPC603
21532 || rs6000_cpu_attr == CPU_PPC604
21533 || rs6000_cpu_attr == CPU_PPC604E
21534 || rs6000_cpu_attr == CPU_PPC620
21535 || rs6000_cpu_attr == CPU_PPC630
21536 || rs6000_cpu_attr == CPU_PPC750
21537 || rs6000_cpu_attr == CPU_PPC7400
21538 || rs6000_cpu_attr == CPU_PPC7450
21539 || rs6000_cpu_attr == CPU_POWER4
21540 || rs6000_cpu_attr == CPU_POWER5
21541 || rs6000_cpu_attr == CPU_POWER7
21542 || rs6000_cpu_attr == CPU_CELL)
21543 && recog_memoized (dep_insn)
21544 && (INSN_CODE (dep_insn) >= 0))
21546 switch (get_attr_type (dep_insn))
21548 case TYPE_CMP:
21549 case TYPE_COMPARE:
21550 case TYPE_DELAYED_COMPARE:
21551 case TYPE_IMUL_COMPARE:
21552 case TYPE_LMUL_COMPARE:
21553 case TYPE_FPCOMPARE:
21554 case TYPE_CR_LOGICAL:
21555 case TYPE_DELAYED_CR:
21556 return cost + 2;
21557 default:
21558 break;
21560 break;
21562 case TYPE_STORE:
21563 case TYPE_STORE_U:
21564 case TYPE_STORE_UX:
21565 case TYPE_FPSTORE:
21566 case TYPE_FPSTORE_U:
21567 case TYPE_FPSTORE_UX:
21568 if ((rs6000_cpu == PROCESSOR_POWER6)
21569 && recog_memoized (dep_insn)
21570 && (INSN_CODE (dep_insn) >= 0))
21573 if (GET_CODE (PATTERN (insn)) != SET)
21574 /* If this happens, we have to extend this to schedule
21575 optimally. Return default for now. */
21576 return cost;
21578 /* Adjust the cost for the case where the value written
21579 by a fixed point operation is used as the address
21580 gen value on a store. */
21581 switch (get_attr_type (dep_insn))
21583 case TYPE_LOAD:
21584 case TYPE_LOAD_U:
21585 case TYPE_LOAD_UX:
21586 case TYPE_CNTLZ:
21588 if (! store_data_bypass_p (dep_insn, insn))
21589 return 4;
21590 break;
21592 case TYPE_LOAD_EXT:
21593 case TYPE_LOAD_EXT_U:
21594 case TYPE_LOAD_EXT_UX:
21595 case TYPE_VAR_SHIFT_ROTATE:
21596 case TYPE_VAR_DELAYED_COMPARE:
21598 if (! store_data_bypass_p (dep_insn, insn))
21599 return 6;
21600 break;
21602 case TYPE_INTEGER:
21603 case TYPE_COMPARE:
21604 case TYPE_FAST_COMPARE:
21605 case TYPE_EXTS:
21606 case TYPE_SHIFT:
21607 case TYPE_INSERT_WORD:
21608 case TYPE_INSERT_DWORD:
21609 case TYPE_FPLOAD_U:
21610 case TYPE_FPLOAD_UX:
21611 case TYPE_STORE_U:
21612 case TYPE_STORE_UX:
21613 case TYPE_FPSTORE_U:
21614 case TYPE_FPSTORE_UX:
21616 if (! store_data_bypass_p (dep_insn, insn))
21617 return 3;
21618 break;
21620 case TYPE_IMUL:
21621 case TYPE_IMUL2:
21622 case TYPE_IMUL3:
21623 case TYPE_LMUL:
21624 case TYPE_IMUL_COMPARE:
21625 case TYPE_LMUL_COMPARE:
21627 if (! store_data_bypass_p (dep_insn, insn))
21628 return 17;
21629 break;
21631 case TYPE_IDIV:
21633 if (! store_data_bypass_p (dep_insn, insn))
21634 return 45;
21635 break;
21637 case TYPE_LDIV:
21639 if (! store_data_bypass_p (dep_insn, insn))
21640 return 57;
21641 break;
21643 default:
21644 break;
21647 break;
21649 case TYPE_LOAD:
21650 case TYPE_LOAD_U:
21651 case TYPE_LOAD_UX:
21652 case TYPE_LOAD_EXT:
21653 case TYPE_LOAD_EXT_U:
21654 case TYPE_LOAD_EXT_UX:
21655 if ((rs6000_cpu == PROCESSOR_POWER6)
21656 && recog_memoized (dep_insn)
21657 && (INSN_CODE (dep_insn) >= 0))
21660 /* Adjust the cost for the case where the value written
21661 by a fixed point instruction is used within the address
21662 gen portion of a subsequent load(u)(x) */
21663 switch (get_attr_type (dep_insn))
21665 case TYPE_LOAD:
21666 case TYPE_LOAD_U:
21667 case TYPE_LOAD_UX:
21668 case TYPE_CNTLZ:
21670 if (set_to_load_agen (dep_insn, insn))
21671 return 4;
21672 break;
21674 case TYPE_LOAD_EXT:
21675 case TYPE_LOAD_EXT_U:
21676 case TYPE_LOAD_EXT_UX:
21677 case TYPE_VAR_SHIFT_ROTATE:
21678 case TYPE_VAR_DELAYED_COMPARE:
21680 if (set_to_load_agen (dep_insn, insn))
21681 return 6;
21682 break;
21684 case TYPE_INTEGER:
21685 case TYPE_COMPARE:
21686 case TYPE_FAST_COMPARE:
21687 case TYPE_EXTS:
21688 case TYPE_SHIFT:
21689 case TYPE_INSERT_WORD:
21690 case TYPE_INSERT_DWORD:
21691 case TYPE_FPLOAD_U:
21692 case TYPE_FPLOAD_UX:
21693 case TYPE_STORE_U:
21694 case TYPE_STORE_UX:
21695 case TYPE_FPSTORE_U:
21696 case TYPE_FPSTORE_UX:
21698 if (set_to_load_agen (dep_insn, insn))
21699 return 3;
21700 break;
21702 case TYPE_IMUL:
21703 case TYPE_IMUL2:
21704 case TYPE_IMUL3:
21705 case TYPE_LMUL:
21706 case TYPE_IMUL_COMPARE:
21707 case TYPE_LMUL_COMPARE:
21709 if (set_to_load_agen (dep_insn, insn))
21710 return 17;
21711 break;
21713 case TYPE_IDIV:
21715 if (set_to_load_agen (dep_insn, insn))
21716 return 45;
21717 break;
21719 case TYPE_LDIV:
21721 if (set_to_load_agen (dep_insn, insn))
21722 return 57;
21723 break;
21725 default:
21726 break;
21729 break;
21731 case TYPE_FPLOAD:
21732 if ((rs6000_cpu == PROCESSOR_POWER6)
21733 && recog_memoized (dep_insn)
21734 && (INSN_CODE (dep_insn) >= 0)
21735 && (get_attr_type (dep_insn) == TYPE_MFFGPR))
21736 return 2;
21738 default:
21739 break;
21742 /* Fall out to return default cost. */
21744 break;
21746 case REG_DEP_OUTPUT:
21747 /* Output dependency; DEP_INSN writes a register that INSN writes some
21748 cycles later. */
21749 if ((rs6000_cpu == PROCESSOR_POWER6)
21750 && recog_memoized (dep_insn)
21751 && (INSN_CODE (dep_insn) >= 0))
21753 attr_type = get_attr_type (insn);
21755 switch (attr_type)
21757 case TYPE_FP:
21758 if (get_attr_type (dep_insn) == TYPE_FP)
21759 return 1;
21760 break;
21761 case TYPE_FPLOAD:
21762 if (get_attr_type (dep_insn) == TYPE_MFFGPR)
21763 return 2;
21764 break;
21765 default:
21766 break;
21769 case REG_DEP_ANTI:
21770 /* Anti dependency; DEP_INSN reads a register that INSN writes some
21771 cycles later. */
21772 return 0;
21774 default:
21775 gcc_unreachable ();
21778 return cost;
21781 /* Debug version of rs6000_adjust_cost. */
21783 static int
21784 rs6000_debug_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
21786 int ret = rs6000_adjust_cost (insn, link, dep_insn, cost);
21788 if (ret != cost)
21790 const char *dep;
21792 switch (REG_NOTE_KIND (link))
21794 default: dep = "unknown depencency"; break;
21795 case REG_DEP_TRUE: dep = "data dependency"; break;
21796 case REG_DEP_OUTPUT: dep = "output dependency"; break;
21797 case REG_DEP_ANTI: dep = "anti depencency"; break;
21800 fprintf (stderr,
21801 "\nrs6000_adjust_cost, final cost = %d, orig cost = %d, "
21802 "%s, insn:\n", ret, cost, dep);
21804 debug_rtx (insn);
21807 return ret;
21810 /* The function returns a true if INSN is microcoded.
21811 Return false otherwise. */
21813 static bool
21814 is_microcoded_insn (rtx insn)
21816 if (!insn || !NONDEBUG_INSN_P (insn)
21817 || GET_CODE (PATTERN (insn)) == USE
21818 || GET_CODE (PATTERN (insn)) == CLOBBER)
21819 return false;
21821 if (rs6000_cpu_attr == CPU_CELL)
21822 return get_attr_cell_micro (insn) == CELL_MICRO_ALWAYS;
21824 if (rs6000_sched_groups)
21826 enum attr_type type = get_attr_type (insn);
21827 if (type == TYPE_LOAD_EXT_U
21828 || type == TYPE_LOAD_EXT_UX
21829 || type == TYPE_LOAD_UX
21830 || type == TYPE_STORE_UX
21831 || type == TYPE_MFCR)
21832 return true;
21835 return false;
21838 /* The function returns true if INSN is cracked into 2 instructions
21839 by the processor (and therefore occupies 2 issue slots). */
21841 static bool
21842 is_cracked_insn (rtx insn)
21844 if (!insn || !NONDEBUG_INSN_P (insn)
21845 || GET_CODE (PATTERN (insn)) == USE
21846 || GET_CODE (PATTERN (insn)) == CLOBBER)
21847 return false;
21849 if (rs6000_sched_groups)
21851 enum attr_type type = get_attr_type (insn);
21852 if (type == TYPE_LOAD_U || type == TYPE_STORE_U
21853 || type == TYPE_FPLOAD_U || type == TYPE_FPSTORE_U
21854 || type == TYPE_FPLOAD_UX || type == TYPE_FPSTORE_UX
21855 || type == TYPE_LOAD_EXT || type == TYPE_DELAYED_CR
21856 || type == TYPE_COMPARE || type == TYPE_DELAYED_COMPARE
21857 || type == TYPE_IMUL_COMPARE || type == TYPE_LMUL_COMPARE
21858 || type == TYPE_IDIV || type == TYPE_LDIV
21859 || type == TYPE_INSERT_WORD)
21860 return true;
21863 return false;
21866 /* The function returns true if INSN can be issued only from
21867 the branch slot. */
21869 static bool
21870 is_branch_slot_insn (rtx insn)
21872 if (!insn || !NONDEBUG_INSN_P (insn)
21873 || GET_CODE (PATTERN (insn)) == USE
21874 || GET_CODE (PATTERN (insn)) == CLOBBER)
21875 return false;
21877 if (rs6000_sched_groups)
21879 enum attr_type type = get_attr_type (insn);
21880 if (type == TYPE_BRANCH || type == TYPE_JMPREG)
21881 return true;
21882 return false;
21885 return false;
21888 /* The function returns true if out_inst sets a value that is
21889 used in the address generation computation of in_insn */
21890 static bool
21891 set_to_load_agen (rtx out_insn, rtx in_insn)
21893 rtx out_set, in_set;
21895 /* For performance reasons, only handle the simple case where
21896 both loads are a single_set. */
21897 out_set = single_set (out_insn);
21898 if (out_set)
21900 in_set = single_set (in_insn);
21901 if (in_set)
21902 return reg_mentioned_p (SET_DEST (out_set), SET_SRC (in_set));
21905 return false;
21908 /* The function returns true if the target storage location of
21909 out_insn is adjacent to the target storage location of in_insn */
21910 /* Return 1 if memory locations are adjacent. */
21912 static bool
21913 adjacent_mem_locations (rtx insn1, rtx insn2)
21916 rtx a = get_store_dest (PATTERN (insn1));
21917 rtx b = get_store_dest (PATTERN (insn2));
21919 if ((GET_CODE (XEXP (a, 0)) == REG
21920 || (GET_CODE (XEXP (a, 0)) == PLUS
21921 && GET_CODE (XEXP (XEXP (a, 0), 1)) == CONST_INT))
21922 && (GET_CODE (XEXP (b, 0)) == REG
21923 || (GET_CODE (XEXP (b, 0)) == PLUS
21924 && GET_CODE (XEXP (XEXP (b, 0), 1)) == CONST_INT)))
21926 HOST_WIDE_INT val0 = 0, val1 = 0, val_diff;
21927 rtx reg0, reg1;
21929 if (GET_CODE (XEXP (a, 0)) == PLUS)
21931 reg0 = XEXP (XEXP (a, 0), 0);
21932 val0 = INTVAL (XEXP (XEXP (a, 0), 1));
21934 else
21935 reg0 = XEXP (a, 0);
21937 if (GET_CODE (XEXP (b, 0)) == PLUS)
21939 reg1 = XEXP (XEXP (b, 0), 0);
21940 val1 = INTVAL (XEXP (XEXP (b, 0), 1));
21942 else
21943 reg1 = XEXP (b, 0);
21945 val_diff = val1 - val0;
21947 return ((REGNO (reg0) == REGNO (reg1))
21948 && ((MEM_SIZE (a) && val_diff == INTVAL (MEM_SIZE (a)))
21949 || (MEM_SIZE (b) && val_diff == -INTVAL (MEM_SIZE (b)))));
21952 return false;
21955 /* A C statement (sans semicolon) to update the integer scheduling
21956 priority INSN_PRIORITY (INSN). Increase the priority to execute the
21957 INSN earlier, reduce the priority to execute INSN later. Do not
21958 define this macro if you do not need to adjust the scheduling
21959 priorities of insns. */
21961 static int
21962 rs6000_adjust_priority (rtx insn ATTRIBUTE_UNUSED, int priority)
21964 /* On machines (like the 750) which have asymmetric integer units,
21965 where one integer unit can do multiply and divides and the other
21966 can't, reduce the priority of multiply/divide so it is scheduled
21967 before other integer operations. */
21969 #if 0
21970 if (! INSN_P (insn))
21971 return priority;
21973 if (GET_CODE (PATTERN (insn)) == USE)
21974 return priority;
21976 switch (rs6000_cpu_attr) {
21977 case CPU_PPC750:
21978 switch (get_attr_type (insn))
21980 default:
21981 break;
21983 case TYPE_IMUL:
21984 case TYPE_IDIV:
21985 fprintf (stderr, "priority was %#x (%d) before adjustment\n",
21986 priority, priority);
21987 if (priority >= 0 && priority < 0x01000000)
21988 priority >>= 3;
21989 break;
21992 #endif
21994 if (insn_must_be_first_in_group (insn)
21995 && reload_completed
21996 && current_sched_info->sched_max_insns_priority
21997 && rs6000_sched_restricted_insns_priority)
22000 /* Prioritize insns that can be dispatched only in the first
22001 dispatch slot. */
22002 if (rs6000_sched_restricted_insns_priority == 1)
22003 /* Attach highest priority to insn. This means that in
22004 haifa-sched.c:ready_sort(), dispatch-slot restriction considerations
22005 precede 'priority' (critical path) considerations. */
22006 return current_sched_info->sched_max_insns_priority;
22007 else if (rs6000_sched_restricted_insns_priority == 2)
22008 /* Increase priority of insn by a minimal amount. This means that in
22009 haifa-sched.c:ready_sort(), only 'priority' (critical path)
22010 considerations precede dispatch-slot restriction considerations. */
22011 return (priority + 1);
22014 if (rs6000_cpu == PROCESSOR_POWER6
22015 && ((load_store_pendulum == -2 && is_load_insn (insn))
22016 || (load_store_pendulum == 2 && is_store_insn (insn))))
22017 /* Attach highest priority to insn if the scheduler has just issued two
22018 stores and this instruction is a load, or two loads and this instruction
22019 is a store. Power6 wants loads and stores scheduled alternately
22020 when possible */
22021 return current_sched_info->sched_max_insns_priority;
22023 return priority;
22026 /* Return true if the instruction is nonpipelined on the Cell. */
22027 static bool
22028 is_nonpipeline_insn (rtx insn)
22030 enum attr_type type;
22031 if (!insn || !NONDEBUG_INSN_P (insn)
22032 || GET_CODE (PATTERN (insn)) == USE
22033 || GET_CODE (PATTERN (insn)) == CLOBBER)
22034 return false;
22036 type = get_attr_type (insn);
22037 if (type == TYPE_IMUL
22038 || type == TYPE_IMUL2
22039 || type == TYPE_IMUL3
22040 || type == TYPE_LMUL
22041 || type == TYPE_IDIV
22042 || type == TYPE_LDIV
22043 || type == TYPE_SDIV
22044 || type == TYPE_DDIV
22045 || type == TYPE_SSQRT
22046 || type == TYPE_DSQRT
22047 || type == TYPE_MFCR
22048 || type == TYPE_MFCRF
22049 || type == TYPE_MFJMPR)
22051 return true;
22053 return false;
22057 /* Return how many instructions the machine can issue per cycle. */
22059 static int
22060 rs6000_issue_rate (void)
22062 /* Unless scheduling for register pressure, use issue rate of 1 for
22063 first scheduling pass to decrease degradation. */
22064 if (!reload_completed && !flag_sched_pressure)
22065 return 1;
22067 switch (rs6000_cpu_attr) {
22068 case CPU_RIOS1: /* ? */
22069 case CPU_RS64A:
22070 case CPU_PPC601: /* ? */
22071 case CPU_PPC7450:
22072 return 3;
22073 case CPU_PPC440:
22074 case CPU_PPC603:
22075 case CPU_PPC750:
22076 case CPU_PPC7400:
22077 case CPU_PPC8540:
22078 case CPU_CELL:
22079 case CPU_PPCE300C2:
22080 case CPU_PPCE300C3:
22081 case CPU_PPCE500MC:
22082 case CPU_PPCE500MC64:
22083 return 2;
22084 case CPU_RIOS2:
22085 case CPU_PPC476:
22086 case CPU_PPC604:
22087 case CPU_PPC604E:
22088 case CPU_PPC620:
22089 case CPU_PPC630:
22090 return 4;
22091 case CPU_POWER4:
22092 case CPU_POWER5:
22093 case CPU_POWER6:
22094 case CPU_POWER7:
22095 return 5;
22096 default:
22097 return 1;
22101 /* Return how many instructions to look ahead for better insn
22102 scheduling. */
22104 static int
22105 rs6000_use_sched_lookahead (void)
22107 if (rs6000_cpu_attr == CPU_PPC8540)
22108 return 4;
22109 if (rs6000_cpu_attr == CPU_CELL)
22110 return (reload_completed ? 8 : 0);
22111 return 0;
22114 /* We are choosing insn from the ready queue. Return nonzero if INSN can be chosen. */
22115 static int
22116 rs6000_use_sched_lookahead_guard (rtx insn)
22118 if (rs6000_cpu_attr != CPU_CELL)
22119 return 1;
22121 if (insn == NULL_RTX || !INSN_P (insn))
22122 abort ();
22124 if (!reload_completed
22125 || is_nonpipeline_insn (insn)
22126 || is_microcoded_insn (insn))
22127 return 0;
22129 return 1;
22132 /* Determine is PAT refers to memory. */
22134 static bool
22135 is_mem_ref (rtx pat)
22137 const char * fmt;
22138 int i, j;
22139 bool ret = false;
22141 /* stack_tie does not produce any real memory traffic. */
22142 if (GET_CODE (pat) == UNSPEC
22143 && XINT (pat, 1) == UNSPEC_TIE)
22144 return false;
22146 if (GET_CODE (pat) == MEM)
22147 return true;
22149 /* Recursively process the pattern. */
22150 fmt = GET_RTX_FORMAT (GET_CODE (pat));
22152 for (i = GET_RTX_LENGTH (GET_CODE (pat)) - 1; i >= 0 && !ret; i--)
22154 if (fmt[i] == 'e')
22155 ret |= is_mem_ref (XEXP (pat, i));
22156 else if (fmt[i] == 'E')
22157 for (j = XVECLEN (pat, i) - 1; j >= 0; j--)
22158 ret |= is_mem_ref (XVECEXP (pat, i, j));
22161 return ret;
22164 /* Determine if PAT is a PATTERN of a load insn. */
22166 static bool
22167 is_load_insn1 (rtx pat)
22169 if (!pat || pat == NULL_RTX)
22170 return false;
22172 if (GET_CODE (pat) == SET)
22173 return is_mem_ref (SET_SRC (pat));
22175 if (GET_CODE (pat) == PARALLEL)
22177 int i;
22179 for (i = 0; i < XVECLEN (pat, 0); i++)
22180 if (is_load_insn1 (XVECEXP (pat, 0, i)))
22181 return true;
22184 return false;
22187 /* Determine if INSN loads from memory. */
22189 static bool
22190 is_load_insn (rtx insn)
22192 if (!insn || !INSN_P (insn))
22193 return false;
22195 if (GET_CODE (insn) == CALL_INSN)
22196 return false;
22198 return is_load_insn1 (PATTERN (insn));
22201 /* Determine if PAT is a PATTERN of a store insn. */
22203 static bool
22204 is_store_insn1 (rtx pat)
22206 if (!pat || pat == NULL_RTX)
22207 return false;
22209 if (GET_CODE (pat) == SET)
22210 return is_mem_ref (SET_DEST (pat));
22212 if (GET_CODE (pat) == PARALLEL)
22214 int i;
22216 for (i = 0; i < XVECLEN (pat, 0); i++)
22217 if (is_store_insn1 (XVECEXP (pat, 0, i)))
22218 return true;
22221 return false;
22224 /* Determine if INSN stores to memory. */
22226 static bool
22227 is_store_insn (rtx insn)
22229 if (!insn || !INSN_P (insn))
22230 return false;
22232 return is_store_insn1 (PATTERN (insn));
22235 /* Return the dest of a store insn. */
22237 static rtx
22238 get_store_dest (rtx pat)
22240 gcc_assert (is_store_insn1 (pat));
22242 if (GET_CODE (pat) == SET)
22243 return SET_DEST (pat);
22244 else if (GET_CODE (pat) == PARALLEL)
22246 int i;
22248 for (i = 0; i < XVECLEN (pat, 0); i++)
22250 rtx inner_pat = XVECEXP (pat, 0, i);
22251 if (GET_CODE (inner_pat) == SET
22252 && is_mem_ref (SET_DEST (inner_pat)))
22253 return inner_pat;
22256 /* We shouldn't get here, because we should have either a simple
22257 store insn or a store with update which are covered above. */
22258 gcc_unreachable();
22261 /* Returns whether the dependence between INSN and NEXT is considered
22262 costly by the given target. */
22264 static bool
22265 rs6000_is_costly_dependence (dep_t dep, int cost, int distance)
22267 rtx insn;
22268 rtx next;
22270 /* If the flag is not enabled - no dependence is considered costly;
22271 allow all dependent insns in the same group.
22272 This is the most aggressive option. */
22273 if (rs6000_sched_costly_dep == no_dep_costly)
22274 return false;
22276 /* If the flag is set to 1 - a dependence is always considered costly;
22277 do not allow dependent instructions in the same group.
22278 This is the most conservative option. */
22279 if (rs6000_sched_costly_dep == all_deps_costly)
22280 return true;
22282 insn = DEP_PRO (dep);
22283 next = DEP_CON (dep);
22285 if (rs6000_sched_costly_dep == store_to_load_dep_costly
22286 && is_load_insn (next)
22287 && is_store_insn (insn))
22288 /* Prevent load after store in the same group. */
22289 return true;
22291 if (rs6000_sched_costly_dep == true_store_to_load_dep_costly
22292 && is_load_insn (next)
22293 && is_store_insn (insn)
22294 && DEP_TYPE (dep) == REG_DEP_TRUE)
22295 /* Prevent load after store in the same group if it is a true
22296 dependence. */
22297 return true;
22299 /* The flag is set to X; dependences with latency >= X are considered costly,
22300 and will not be scheduled in the same group. */
22301 if (rs6000_sched_costly_dep <= max_dep_latency
22302 && ((cost - distance) >= (int)rs6000_sched_costly_dep))
22303 return true;
22305 return false;
22308 /* Return the next insn after INSN that is found before TAIL is reached,
22309 skipping any "non-active" insns - insns that will not actually occupy
22310 an issue slot. Return NULL_RTX if such an insn is not found. */
22312 static rtx
22313 get_next_active_insn (rtx insn, rtx tail)
22315 if (insn == NULL_RTX || insn == tail)
22316 return NULL_RTX;
22318 while (1)
22320 insn = NEXT_INSN (insn);
22321 if (insn == NULL_RTX || insn == tail)
22322 return NULL_RTX;
22324 if (CALL_P (insn)
22325 || JUMP_P (insn)
22326 || (NONJUMP_INSN_P (insn)
22327 && GET_CODE (PATTERN (insn)) != USE
22328 && GET_CODE (PATTERN (insn)) != CLOBBER
22329 && INSN_CODE (insn) != CODE_FOR_stack_tie))
22330 break;
22332 return insn;
22335 /* We are about to begin issuing insns for this clock cycle. */
22337 static int
22338 rs6000_sched_reorder (FILE *dump ATTRIBUTE_UNUSED, int sched_verbose,
22339 rtx *ready ATTRIBUTE_UNUSED,
22340 int *pn_ready ATTRIBUTE_UNUSED,
22341 int clock_var ATTRIBUTE_UNUSED)
22343 int n_ready = *pn_ready;
22345 if (sched_verbose)
22346 fprintf (dump, "// rs6000_sched_reorder :\n");
22348 /* Reorder the ready list, if the second to last ready insn
22349 is a nonepipeline insn. */
22350 if (rs6000_cpu_attr == CPU_CELL && n_ready > 1)
22352 if (is_nonpipeline_insn (ready[n_ready - 1])
22353 && (recog_memoized (ready[n_ready - 2]) > 0))
22354 /* Simply swap first two insns. */
22356 rtx tmp = ready[n_ready - 1];
22357 ready[n_ready - 1] = ready[n_ready - 2];
22358 ready[n_ready - 2] = tmp;
22362 if (rs6000_cpu == PROCESSOR_POWER6)
22363 load_store_pendulum = 0;
22365 return rs6000_issue_rate ();
22368 /* Like rs6000_sched_reorder, but called after issuing each insn. */
22370 static int
22371 rs6000_sched_reorder2 (FILE *dump, int sched_verbose, rtx *ready,
22372 int *pn_ready, int clock_var ATTRIBUTE_UNUSED)
22374 if (sched_verbose)
22375 fprintf (dump, "// rs6000_sched_reorder2 :\n");
22377 /* For Power6, we need to handle some special cases to try and keep the
22378 store queue from overflowing and triggering expensive flushes.
22380 This code monitors how load and store instructions are being issued
22381 and skews the ready list one way or the other to increase the likelihood
22382 that a desired instruction is issued at the proper time.
22384 A couple of things are done. First, we maintain a "load_store_pendulum"
22385 to track the current state of load/store issue.
22387 - If the pendulum is at zero, then no loads or stores have been
22388 issued in the current cycle so we do nothing.
22390 - If the pendulum is 1, then a single load has been issued in this
22391 cycle and we attempt to locate another load in the ready list to
22392 issue with it.
22394 - If the pendulum is -2, then two stores have already been
22395 issued in this cycle, so we increase the priority of the first load
22396 in the ready list to increase it's likelihood of being chosen first
22397 in the next cycle.
22399 - If the pendulum is -1, then a single store has been issued in this
22400 cycle and we attempt to locate another store in the ready list to
22401 issue with it, preferring a store to an adjacent memory location to
22402 facilitate store pairing in the store queue.
22404 - If the pendulum is 2, then two loads have already been
22405 issued in this cycle, so we increase the priority of the first store
22406 in the ready list to increase it's likelihood of being chosen first
22407 in the next cycle.
22409 - If the pendulum < -2 or > 2, then do nothing.
22411 Note: This code covers the most common scenarios. There exist non
22412 load/store instructions which make use of the LSU and which
22413 would need to be accounted for to strictly model the behavior
22414 of the machine. Those instructions are currently unaccounted
22415 for to help minimize compile time overhead of this code.
22417 if (rs6000_cpu == PROCESSOR_POWER6 && last_scheduled_insn)
22419 int pos;
22420 int i;
22421 rtx tmp;
22423 if (is_store_insn (last_scheduled_insn))
22424 /* Issuing a store, swing the load_store_pendulum to the left */
22425 load_store_pendulum--;
22426 else if (is_load_insn (last_scheduled_insn))
22427 /* Issuing a load, swing the load_store_pendulum to the right */
22428 load_store_pendulum++;
22429 else
22430 return cached_can_issue_more;
22432 /* If the pendulum is balanced, or there is only one instruction on
22433 the ready list, then all is well, so return. */
22434 if ((load_store_pendulum == 0) || (*pn_ready <= 1))
22435 return cached_can_issue_more;
22437 if (load_store_pendulum == 1)
22439 /* A load has been issued in this cycle. Scan the ready list
22440 for another load to issue with it */
22441 pos = *pn_ready-1;
22443 while (pos >= 0)
22445 if (is_load_insn (ready[pos]))
22447 /* Found a load. Move it to the head of the ready list,
22448 and adjust it's priority so that it is more likely to
22449 stay there */
22450 tmp = ready[pos];
22451 for (i=pos; i<*pn_ready-1; i++)
22452 ready[i] = ready[i + 1];
22453 ready[*pn_ready-1] = tmp;
22455 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
22456 INSN_PRIORITY (tmp)++;
22457 break;
22459 pos--;
22462 else if (load_store_pendulum == -2)
22464 /* Two stores have been issued in this cycle. Increase the
22465 priority of the first load in the ready list to favor it for
22466 issuing in the next cycle. */
22467 pos = *pn_ready-1;
22469 while (pos >= 0)
22471 if (is_load_insn (ready[pos])
22472 && !sel_sched_p ()
22473 && INSN_PRIORITY_KNOWN (ready[pos]))
22475 INSN_PRIORITY (ready[pos])++;
22477 /* Adjust the pendulum to account for the fact that a load
22478 was found and increased in priority. This is to prevent
22479 increasing the priority of multiple loads */
22480 load_store_pendulum--;
22482 break;
22484 pos--;
22487 else if (load_store_pendulum == -1)
22489 /* A store has been issued in this cycle. Scan the ready list for
22490 another store to issue with it, preferring a store to an adjacent
22491 memory location */
22492 int first_store_pos = -1;
22494 pos = *pn_ready-1;
22496 while (pos >= 0)
22498 if (is_store_insn (ready[pos]))
22500 /* Maintain the index of the first store found on the
22501 list */
22502 if (first_store_pos == -1)
22503 first_store_pos = pos;
22505 if (is_store_insn (last_scheduled_insn)
22506 && adjacent_mem_locations (last_scheduled_insn,ready[pos]))
22508 /* Found an adjacent store. Move it to the head of the
22509 ready list, and adjust it's priority so that it is
22510 more likely to stay there */
22511 tmp = ready[pos];
22512 for (i=pos; i<*pn_ready-1; i++)
22513 ready[i] = ready[i + 1];
22514 ready[*pn_ready-1] = tmp;
22516 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
22517 INSN_PRIORITY (tmp)++;
22519 first_store_pos = -1;
22521 break;
22524 pos--;
22527 if (first_store_pos >= 0)
22529 /* An adjacent store wasn't found, but a non-adjacent store was,
22530 so move the non-adjacent store to the front of the ready
22531 list, and adjust its priority so that it is more likely to
22532 stay there. */
22533 tmp = ready[first_store_pos];
22534 for (i=first_store_pos; i<*pn_ready-1; i++)
22535 ready[i] = ready[i + 1];
22536 ready[*pn_ready-1] = tmp;
22537 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
22538 INSN_PRIORITY (tmp)++;
22541 else if (load_store_pendulum == 2)
22543 /* Two loads have been issued in this cycle. Increase the priority
22544 of the first store in the ready list to favor it for issuing in
22545 the next cycle. */
22546 pos = *pn_ready-1;
22548 while (pos >= 0)
22550 if (is_store_insn (ready[pos])
22551 && !sel_sched_p ()
22552 && INSN_PRIORITY_KNOWN (ready[pos]))
22554 INSN_PRIORITY (ready[pos])++;
22556 /* Adjust the pendulum to account for the fact that a store
22557 was found and increased in priority. This is to prevent
22558 increasing the priority of multiple stores */
22559 load_store_pendulum++;
22561 break;
22563 pos--;
22568 return cached_can_issue_more;
22571 /* Return whether the presence of INSN causes a dispatch group termination
22572 of group WHICH_GROUP.
22574 If WHICH_GROUP == current_group, this function will return true if INSN
22575 causes the termination of the current group (i.e, the dispatch group to
22576 which INSN belongs). This means that INSN will be the last insn in the
22577 group it belongs to.
22579 If WHICH_GROUP == previous_group, this function will return true if INSN
22580 causes the termination of the previous group (i.e, the dispatch group that
22581 precedes the group to which INSN belongs). This means that INSN will be
22582 the first insn in the group it belongs to). */
22584 static bool
22585 insn_terminates_group_p (rtx insn, enum group_termination which_group)
22587 bool first, last;
22589 if (! insn)
22590 return false;
22592 first = insn_must_be_first_in_group (insn);
22593 last = insn_must_be_last_in_group (insn);
22595 if (first && last)
22596 return true;
22598 if (which_group == current_group)
22599 return last;
22600 else if (which_group == previous_group)
22601 return first;
22603 return false;
22607 static bool
22608 insn_must_be_first_in_group (rtx insn)
22610 enum attr_type type;
22612 if (!insn
22613 || GET_CODE (insn) == NOTE
22614 || DEBUG_INSN_P (insn)
22615 || GET_CODE (PATTERN (insn)) == USE
22616 || GET_CODE (PATTERN (insn)) == CLOBBER)
22617 return false;
22619 switch (rs6000_cpu)
22621 case PROCESSOR_POWER5:
22622 if (is_cracked_insn (insn))
22623 return true;
22624 case PROCESSOR_POWER4:
22625 if (is_microcoded_insn (insn))
22626 return true;
22628 if (!rs6000_sched_groups)
22629 return false;
22631 type = get_attr_type (insn);
22633 switch (type)
22635 case TYPE_MFCR:
22636 case TYPE_MFCRF:
22637 case TYPE_MTCR:
22638 case TYPE_DELAYED_CR:
22639 case TYPE_CR_LOGICAL:
22640 case TYPE_MTJMPR:
22641 case TYPE_MFJMPR:
22642 case TYPE_IDIV:
22643 case TYPE_LDIV:
22644 case TYPE_LOAD_L:
22645 case TYPE_STORE_C:
22646 case TYPE_ISYNC:
22647 case TYPE_SYNC:
22648 return true;
22649 default:
22650 break;
22652 break;
22653 case PROCESSOR_POWER6:
22654 type = get_attr_type (insn);
22656 switch (type)
22658 case TYPE_INSERT_DWORD:
22659 case TYPE_EXTS:
22660 case TYPE_CNTLZ:
22661 case TYPE_SHIFT:
22662 case TYPE_VAR_SHIFT_ROTATE:
22663 case TYPE_TRAP:
22664 case TYPE_IMUL:
22665 case TYPE_IMUL2:
22666 case TYPE_IMUL3:
22667 case TYPE_LMUL:
22668 case TYPE_IDIV:
22669 case TYPE_INSERT_WORD:
22670 case TYPE_DELAYED_COMPARE:
22671 case TYPE_IMUL_COMPARE:
22672 case TYPE_LMUL_COMPARE:
22673 case TYPE_FPCOMPARE:
22674 case TYPE_MFCR:
22675 case TYPE_MTCR:
22676 case TYPE_MFJMPR:
22677 case TYPE_MTJMPR:
22678 case TYPE_ISYNC:
22679 case TYPE_SYNC:
22680 case TYPE_LOAD_L:
22681 case TYPE_STORE_C:
22682 case TYPE_LOAD_U:
22683 case TYPE_LOAD_UX:
22684 case TYPE_LOAD_EXT_UX:
22685 case TYPE_STORE_U:
22686 case TYPE_STORE_UX:
22687 case TYPE_FPLOAD_U:
22688 case TYPE_FPLOAD_UX:
22689 case TYPE_FPSTORE_U:
22690 case TYPE_FPSTORE_UX:
22691 return true;
22692 default:
22693 break;
22695 break;
22696 case PROCESSOR_POWER7:
22697 type = get_attr_type (insn);
22699 switch (type)
22701 case TYPE_CR_LOGICAL:
22702 case TYPE_MFCR:
22703 case TYPE_MFCRF:
22704 case TYPE_MTCR:
22705 case TYPE_IDIV:
22706 case TYPE_LDIV:
22707 case TYPE_COMPARE:
22708 case TYPE_DELAYED_COMPARE:
22709 case TYPE_VAR_DELAYED_COMPARE:
22710 case TYPE_ISYNC:
22711 case TYPE_LOAD_L:
22712 case TYPE_STORE_C:
22713 case TYPE_LOAD_U:
22714 case TYPE_LOAD_UX:
22715 case TYPE_LOAD_EXT:
22716 case TYPE_LOAD_EXT_U:
22717 case TYPE_LOAD_EXT_UX:
22718 case TYPE_STORE_U:
22719 case TYPE_STORE_UX:
22720 case TYPE_FPLOAD_U:
22721 case TYPE_FPLOAD_UX:
22722 case TYPE_FPSTORE_U:
22723 case TYPE_FPSTORE_UX:
22724 case TYPE_MFJMPR:
22725 case TYPE_MTJMPR:
22726 return true;
22727 default:
22728 break;
22730 break;
22731 default:
22732 break;
22735 return false;
22738 static bool
22739 insn_must_be_last_in_group (rtx insn)
22741 enum attr_type type;
22743 if (!insn
22744 || GET_CODE (insn) == NOTE
22745 || DEBUG_INSN_P (insn)
22746 || GET_CODE (PATTERN (insn)) == USE
22747 || GET_CODE (PATTERN (insn)) == CLOBBER)
22748 return false;
22750 switch (rs6000_cpu) {
22751 case PROCESSOR_POWER4:
22752 case PROCESSOR_POWER5:
22753 if (is_microcoded_insn (insn))
22754 return true;
22756 if (is_branch_slot_insn (insn))
22757 return true;
22759 break;
22760 case PROCESSOR_POWER6:
22761 type = get_attr_type (insn);
22763 switch (type)
22765 case TYPE_EXTS:
22766 case TYPE_CNTLZ:
22767 case TYPE_SHIFT:
22768 case TYPE_VAR_SHIFT_ROTATE:
22769 case TYPE_TRAP:
22770 case TYPE_IMUL:
22771 case TYPE_IMUL2:
22772 case TYPE_IMUL3:
22773 case TYPE_LMUL:
22774 case TYPE_IDIV:
22775 case TYPE_DELAYED_COMPARE:
22776 case TYPE_IMUL_COMPARE:
22777 case TYPE_LMUL_COMPARE:
22778 case TYPE_FPCOMPARE:
22779 case TYPE_MFCR:
22780 case TYPE_MTCR:
22781 case TYPE_MFJMPR:
22782 case TYPE_MTJMPR:
22783 case TYPE_ISYNC:
22784 case TYPE_SYNC:
22785 case TYPE_LOAD_L:
22786 case TYPE_STORE_C:
22787 return true;
22788 default:
22789 break;
22791 break;
22792 case PROCESSOR_POWER7:
22793 type = get_attr_type (insn);
22795 switch (type)
22797 case TYPE_ISYNC:
22798 case TYPE_SYNC:
22799 case TYPE_LOAD_L:
22800 case TYPE_STORE_C:
22801 case TYPE_LOAD_EXT_U:
22802 case TYPE_LOAD_EXT_UX:
22803 case TYPE_STORE_UX:
22804 return true;
22805 default:
22806 break;
22808 break;
22809 default:
22810 break;
22813 return false;
22816 /* Return true if it is recommended to keep NEXT_INSN "far" (in a separate
22817 dispatch group) from the insns in GROUP_INSNS. Return false otherwise. */
22819 static bool
22820 is_costly_group (rtx *group_insns, rtx next_insn)
22822 int i;
22823 int issue_rate = rs6000_issue_rate ();
22825 for (i = 0; i < issue_rate; i++)
22827 sd_iterator_def sd_it;
22828 dep_t dep;
22829 rtx insn = group_insns[i];
22831 if (!insn)
22832 continue;
22834 FOR_EACH_DEP (insn, SD_LIST_FORW, sd_it, dep)
22836 rtx next = DEP_CON (dep);
22838 if (next == next_insn
22839 && rs6000_is_costly_dependence (dep, dep_cost (dep), 0))
22840 return true;
22844 return false;
22847 /* Utility of the function redefine_groups.
22848 Check if it is too costly to schedule NEXT_INSN together with GROUP_INSNS
22849 in the same dispatch group. If so, insert nops before NEXT_INSN, in order
22850 to keep it "far" (in a separate group) from GROUP_INSNS, following
22851 one of the following schemes, depending on the value of the flag
22852 -minsert_sched_nops = X:
22853 (1) X == sched_finish_regroup_exact: insert exactly as many nops as needed
22854 in order to force NEXT_INSN into a separate group.
22855 (2) X < sched_finish_regroup_exact: insert exactly X nops.
22856 GROUP_END, CAN_ISSUE_MORE and GROUP_COUNT record the state after nop
22857 insertion (has a group just ended, how many vacant issue slots remain in the
22858 last group, and how many dispatch groups were encountered so far). */
22860 static int
22861 force_new_group (int sched_verbose, FILE *dump, rtx *group_insns,
22862 rtx next_insn, bool *group_end, int can_issue_more,
22863 int *group_count)
22865 rtx nop;
22866 bool force;
22867 int issue_rate = rs6000_issue_rate ();
22868 bool end = *group_end;
22869 int i;
22871 if (next_insn == NULL_RTX || DEBUG_INSN_P (next_insn))
22872 return can_issue_more;
22874 if (rs6000_sched_insert_nops > sched_finish_regroup_exact)
22875 return can_issue_more;
22877 force = is_costly_group (group_insns, next_insn);
22878 if (!force)
22879 return can_issue_more;
22881 if (sched_verbose > 6)
22882 fprintf (dump,"force: group count = %d, can_issue_more = %d\n",
22883 *group_count ,can_issue_more);
22885 if (rs6000_sched_insert_nops == sched_finish_regroup_exact)
22887 if (*group_end)
22888 can_issue_more = 0;
22890 /* Since only a branch can be issued in the last issue_slot, it is
22891 sufficient to insert 'can_issue_more - 1' nops if next_insn is not
22892 a branch. If next_insn is a branch, we insert 'can_issue_more' nops;
22893 in this case the last nop will start a new group and the branch
22894 will be forced to the new group. */
22895 if (can_issue_more && !is_branch_slot_insn (next_insn))
22896 can_issue_more--;
22898 while (can_issue_more > 0)
22900 nop = gen_nop ();
22901 emit_insn_before (nop, next_insn);
22902 can_issue_more--;
22905 *group_end = true;
22906 return 0;
22909 if (rs6000_sched_insert_nops < sched_finish_regroup_exact)
22911 int n_nops = rs6000_sched_insert_nops;
22913 /* Nops can't be issued from the branch slot, so the effective
22914 issue_rate for nops is 'issue_rate - 1'. */
22915 if (can_issue_more == 0)
22916 can_issue_more = issue_rate;
22917 can_issue_more--;
22918 if (can_issue_more == 0)
22920 can_issue_more = issue_rate - 1;
22921 (*group_count)++;
22922 end = true;
22923 for (i = 0; i < issue_rate; i++)
22925 group_insns[i] = 0;
22929 while (n_nops > 0)
22931 nop = gen_nop ();
22932 emit_insn_before (nop, next_insn);
22933 if (can_issue_more == issue_rate - 1) /* new group begins */
22934 end = false;
22935 can_issue_more--;
22936 if (can_issue_more == 0)
22938 can_issue_more = issue_rate - 1;
22939 (*group_count)++;
22940 end = true;
22941 for (i = 0; i < issue_rate; i++)
22943 group_insns[i] = 0;
22946 n_nops--;
22949 /* Scale back relative to 'issue_rate' (instead of 'issue_rate - 1'). */
22950 can_issue_more++;
22952 /* Is next_insn going to start a new group? */
22953 *group_end
22954 = (end
22955 || (can_issue_more == 1 && !is_branch_slot_insn (next_insn))
22956 || (can_issue_more <= 2 && is_cracked_insn (next_insn))
22957 || (can_issue_more < issue_rate &&
22958 insn_terminates_group_p (next_insn, previous_group)));
22959 if (*group_end && end)
22960 (*group_count)--;
22962 if (sched_verbose > 6)
22963 fprintf (dump, "done force: group count = %d, can_issue_more = %d\n",
22964 *group_count, can_issue_more);
22965 return can_issue_more;
22968 return can_issue_more;
22971 /* This function tries to synch the dispatch groups that the compiler "sees"
22972 with the dispatch groups that the processor dispatcher is expected to
22973 form in practice. It tries to achieve this synchronization by forcing the
22974 estimated processor grouping on the compiler (as opposed to the function
22975 'pad_goups' which tries to force the scheduler's grouping on the processor).
22977 The function scans the insn sequence between PREV_HEAD_INSN and TAIL and
22978 examines the (estimated) dispatch groups that will be formed by the processor
22979 dispatcher. It marks these group boundaries to reflect the estimated
22980 processor grouping, overriding the grouping that the scheduler had marked.
22981 Depending on the value of the flag '-minsert-sched-nops' this function can
22982 force certain insns into separate groups or force a certain distance between
22983 them by inserting nops, for example, if there exists a "costly dependence"
22984 between the insns.
22986 The function estimates the group boundaries that the processor will form as
22987 follows: It keeps track of how many vacant issue slots are available after
22988 each insn. A subsequent insn will start a new group if one of the following
22989 4 cases applies:
22990 - no more vacant issue slots remain in the current dispatch group.
22991 - only the last issue slot, which is the branch slot, is vacant, but the next
22992 insn is not a branch.
22993 - only the last 2 or less issue slots, including the branch slot, are vacant,
22994 which means that a cracked insn (which occupies two issue slots) can't be
22995 issued in this group.
22996 - less than 'issue_rate' slots are vacant, and the next insn always needs to
22997 start a new group. */
22999 static int
23000 redefine_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail)
23002 rtx insn, next_insn;
23003 int issue_rate;
23004 int can_issue_more;
23005 int slot, i;
23006 bool group_end;
23007 int group_count = 0;
23008 rtx *group_insns;
23010 /* Initialize. */
23011 issue_rate = rs6000_issue_rate ();
23012 group_insns = XALLOCAVEC (rtx, issue_rate);
23013 for (i = 0; i < issue_rate; i++)
23015 group_insns[i] = 0;
23017 can_issue_more = issue_rate;
23018 slot = 0;
23019 insn = get_next_active_insn (prev_head_insn, tail);
23020 group_end = false;
23022 while (insn != NULL_RTX)
23024 slot = (issue_rate - can_issue_more);
23025 group_insns[slot] = insn;
23026 can_issue_more =
23027 rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more);
23028 if (insn_terminates_group_p (insn, current_group))
23029 can_issue_more = 0;
23031 next_insn = get_next_active_insn (insn, tail);
23032 if (next_insn == NULL_RTX)
23033 return group_count + 1;
23035 /* Is next_insn going to start a new group? */
23036 group_end
23037 = (can_issue_more == 0
23038 || (can_issue_more == 1 && !is_branch_slot_insn (next_insn))
23039 || (can_issue_more <= 2 && is_cracked_insn (next_insn))
23040 || (can_issue_more < issue_rate &&
23041 insn_terminates_group_p (next_insn, previous_group)));
23043 can_issue_more = force_new_group (sched_verbose, dump, group_insns,
23044 next_insn, &group_end, can_issue_more,
23045 &group_count);
23047 if (group_end)
23049 group_count++;
23050 can_issue_more = 0;
23051 for (i = 0; i < issue_rate; i++)
23053 group_insns[i] = 0;
23057 if (GET_MODE (next_insn) == TImode && can_issue_more)
23058 PUT_MODE (next_insn, VOIDmode);
23059 else if (!can_issue_more && GET_MODE (next_insn) != TImode)
23060 PUT_MODE (next_insn, TImode);
23062 insn = next_insn;
23063 if (can_issue_more == 0)
23064 can_issue_more = issue_rate;
23065 } /* while */
23067 return group_count;
23070 /* Scan the insn sequence between PREV_HEAD_INSN and TAIL and examine the
23071 dispatch group boundaries that the scheduler had marked. Pad with nops
23072 any dispatch groups which have vacant issue slots, in order to force the
23073 scheduler's grouping on the processor dispatcher. The function
23074 returns the number of dispatch groups found. */
23076 static int
23077 pad_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail)
23079 rtx insn, next_insn;
23080 rtx nop;
23081 int issue_rate;
23082 int can_issue_more;
23083 int group_end;
23084 int group_count = 0;
23086 /* Initialize issue_rate. */
23087 issue_rate = rs6000_issue_rate ();
23088 can_issue_more = issue_rate;
23090 insn = get_next_active_insn (prev_head_insn, tail);
23091 next_insn = get_next_active_insn (insn, tail);
23093 while (insn != NULL_RTX)
23095 can_issue_more =
23096 rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more);
23098 group_end = (next_insn == NULL_RTX || GET_MODE (next_insn) == TImode);
23100 if (next_insn == NULL_RTX)
23101 break;
23103 if (group_end)
23105 /* If the scheduler had marked group termination at this location
23106 (between insn and next_insn), and neither insn nor next_insn will
23107 force group termination, pad the group with nops to force group
23108 termination. */
23109 if (can_issue_more
23110 && (rs6000_sched_insert_nops == sched_finish_pad_groups)
23111 && !insn_terminates_group_p (insn, current_group)
23112 && !insn_terminates_group_p (next_insn, previous_group))
23114 if (!is_branch_slot_insn (next_insn))
23115 can_issue_more--;
23117 while (can_issue_more)
23119 nop = gen_nop ();
23120 emit_insn_before (nop, next_insn);
23121 can_issue_more--;
23125 can_issue_more = issue_rate;
23126 group_count++;
23129 insn = next_insn;
23130 next_insn = get_next_active_insn (insn, tail);
23133 return group_count;
23136 /* We're beginning a new block. Initialize data structures as necessary. */
23138 static void
23139 rs6000_sched_init (FILE *dump ATTRIBUTE_UNUSED,
23140 int sched_verbose ATTRIBUTE_UNUSED,
23141 int max_ready ATTRIBUTE_UNUSED)
23143 last_scheduled_insn = NULL_RTX;
23144 load_store_pendulum = 0;
23147 /* The following function is called at the end of scheduling BB.
23148 After reload, it inserts nops at insn group bundling. */
23150 static void
23151 rs6000_sched_finish (FILE *dump, int sched_verbose)
23153 int n_groups;
23155 if (sched_verbose)
23156 fprintf (dump, "=== Finishing schedule.\n");
23158 if (reload_completed && rs6000_sched_groups)
23160 /* Do not run sched_finish hook when selective scheduling enabled. */
23161 if (sel_sched_p ())
23162 return;
23164 if (rs6000_sched_insert_nops == sched_finish_none)
23165 return;
23167 if (rs6000_sched_insert_nops == sched_finish_pad_groups)
23168 n_groups = pad_groups (dump, sched_verbose,
23169 current_sched_info->prev_head,
23170 current_sched_info->next_tail);
23171 else
23172 n_groups = redefine_groups (dump, sched_verbose,
23173 current_sched_info->prev_head,
23174 current_sched_info->next_tail);
23176 if (sched_verbose >= 6)
23178 fprintf (dump, "ngroups = %d\n", n_groups);
23179 print_rtl (dump, current_sched_info->prev_head);
23180 fprintf (dump, "Done finish_sched\n");
23185 struct _rs6000_sched_context
23187 short cached_can_issue_more;
23188 rtx last_scheduled_insn;
23189 int load_store_pendulum;
23192 typedef struct _rs6000_sched_context rs6000_sched_context_def;
23193 typedef rs6000_sched_context_def *rs6000_sched_context_t;
23195 /* Allocate store for new scheduling context. */
23196 static void *
23197 rs6000_alloc_sched_context (void)
23199 return xmalloc (sizeof (rs6000_sched_context_def));
23202 /* If CLEAN_P is true then initializes _SC with clean data,
23203 and from the global context otherwise. */
23204 static void
23205 rs6000_init_sched_context (void *_sc, bool clean_p)
23207 rs6000_sched_context_t sc = (rs6000_sched_context_t) _sc;
23209 if (clean_p)
23211 sc->cached_can_issue_more = 0;
23212 sc->last_scheduled_insn = NULL_RTX;
23213 sc->load_store_pendulum = 0;
23215 else
23217 sc->cached_can_issue_more = cached_can_issue_more;
23218 sc->last_scheduled_insn = last_scheduled_insn;
23219 sc->load_store_pendulum = load_store_pendulum;
23223 /* Sets the global scheduling context to the one pointed to by _SC. */
23224 static void
23225 rs6000_set_sched_context (void *_sc)
23227 rs6000_sched_context_t sc = (rs6000_sched_context_t) _sc;
23229 gcc_assert (sc != NULL);
23231 cached_can_issue_more = sc->cached_can_issue_more;
23232 last_scheduled_insn = sc->last_scheduled_insn;
23233 load_store_pendulum = sc->load_store_pendulum;
23236 /* Free _SC. */
23237 static void
23238 rs6000_free_sched_context (void *_sc)
23240 gcc_assert (_sc != NULL);
23242 free (_sc);
23246 /* Length in units of the trampoline for entering a nested function. */
23249 rs6000_trampoline_size (void)
23251 int ret = 0;
23253 switch (DEFAULT_ABI)
23255 default:
23256 gcc_unreachable ();
23258 case ABI_AIX:
23259 ret = (TARGET_32BIT) ? 12 : 24;
23260 break;
23262 case ABI_DARWIN:
23263 case ABI_V4:
23264 ret = (TARGET_32BIT) ? 40 : 48;
23265 break;
23268 return ret;
23271 /* Emit RTL insns to initialize the variable parts of a trampoline.
23272 FNADDR is an RTX for the address of the function's pure code.
23273 CXT is an RTX for the static chain value for the function. */
23275 static void
23276 rs6000_trampoline_init (rtx m_tramp, tree fndecl, rtx cxt)
23278 int regsize = (TARGET_32BIT) ? 4 : 8;
23279 rtx fnaddr = XEXP (DECL_RTL (fndecl), 0);
23280 rtx ctx_reg = force_reg (Pmode, cxt);
23281 rtx addr = force_reg (Pmode, XEXP (m_tramp, 0));
23283 switch (DEFAULT_ABI)
23285 default:
23286 gcc_unreachable ();
23288 /* Under AIX, just build the 3 word function descriptor */
23289 case ABI_AIX:
23291 rtx fnmem = gen_const_mem (Pmode, force_reg (Pmode, fnaddr));
23292 rtx fn_reg = gen_reg_rtx (Pmode);
23293 rtx toc_reg = gen_reg_rtx (Pmode);
23295 /* Macro to shorten the code expansions below. */
23296 # define MEM_PLUS(MEM, OFFSET) adjust_address (MEM, Pmode, OFFSET)
23298 m_tramp = replace_equiv_address (m_tramp, addr);
23300 emit_move_insn (fn_reg, MEM_PLUS (fnmem, 0));
23301 emit_move_insn (toc_reg, MEM_PLUS (fnmem, regsize));
23302 emit_move_insn (MEM_PLUS (m_tramp, 0), fn_reg);
23303 emit_move_insn (MEM_PLUS (m_tramp, regsize), toc_reg);
23304 emit_move_insn (MEM_PLUS (m_tramp, 2*regsize), ctx_reg);
23306 # undef MEM_PLUS
23308 break;
23310 /* Under V.4/eabi/darwin, __trampoline_setup does the real work. */
23311 case ABI_DARWIN:
23312 case ABI_V4:
23313 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__trampoline_setup"),
23314 LCT_NORMAL, VOIDmode, 4,
23315 addr, Pmode,
23316 GEN_INT (rs6000_trampoline_size ()), SImode,
23317 fnaddr, Pmode,
23318 ctx_reg, Pmode);
23319 break;
23324 /* Handle the "altivec" attribute. The attribute may have
23325 arguments as follows:
23327 __attribute__((altivec(vector__)))
23328 __attribute__((altivec(pixel__))) (always followed by 'unsigned short')
23329 __attribute__((altivec(bool__))) (always followed by 'unsigned')
23331 and may appear more than once (e.g., 'vector bool char') in a
23332 given declaration. */
23334 static tree
23335 rs6000_handle_altivec_attribute (tree *node,
23336 tree name ATTRIBUTE_UNUSED,
23337 tree args,
23338 int flags ATTRIBUTE_UNUSED,
23339 bool *no_add_attrs)
23341 tree type = *node, result = NULL_TREE;
23342 enum machine_mode mode;
23343 int unsigned_p;
23344 char altivec_type
23345 = ((args && TREE_CODE (args) == TREE_LIST && TREE_VALUE (args)
23346 && TREE_CODE (TREE_VALUE (args)) == IDENTIFIER_NODE)
23347 ? *IDENTIFIER_POINTER (TREE_VALUE (args))
23348 : '?');
23350 while (POINTER_TYPE_P (type)
23351 || TREE_CODE (type) == FUNCTION_TYPE
23352 || TREE_CODE (type) == METHOD_TYPE
23353 || TREE_CODE (type) == ARRAY_TYPE)
23354 type = TREE_TYPE (type);
23356 mode = TYPE_MODE (type);
23358 /* Check for invalid AltiVec type qualifiers. */
23359 if (type == long_double_type_node)
23360 error ("use of %<long double%> in AltiVec types is invalid");
23361 else if (type == boolean_type_node)
23362 error ("use of boolean types in AltiVec types is invalid");
23363 else if (TREE_CODE (type) == COMPLEX_TYPE)
23364 error ("use of %<complex%> in AltiVec types is invalid");
23365 else if (DECIMAL_FLOAT_MODE_P (mode))
23366 error ("use of decimal floating point types in AltiVec types is invalid");
23367 else if (!TARGET_VSX)
23369 if (type == long_unsigned_type_node || type == long_integer_type_node)
23371 if (TARGET_64BIT)
23372 error ("use of %<long%> in AltiVec types is invalid for "
23373 "64-bit code without -mvsx");
23374 else if (rs6000_warn_altivec_long)
23375 warning (0, "use of %<long%> in AltiVec types is deprecated; "
23376 "use %<int%>");
23378 else if (type == long_long_unsigned_type_node
23379 || type == long_long_integer_type_node)
23380 error ("use of %<long long%> in AltiVec types is invalid without "
23381 "-mvsx");
23382 else if (type == double_type_node)
23383 error ("use of %<double%> in AltiVec types is invalid without -mvsx");
23386 switch (altivec_type)
23388 case 'v':
23389 unsigned_p = TYPE_UNSIGNED (type);
23390 switch (mode)
23392 case DImode:
23393 result = (unsigned_p ? unsigned_V2DI_type_node : V2DI_type_node);
23394 break;
23395 case SImode:
23396 result = (unsigned_p ? unsigned_V4SI_type_node : V4SI_type_node);
23397 break;
23398 case HImode:
23399 result = (unsigned_p ? unsigned_V8HI_type_node : V8HI_type_node);
23400 break;
23401 case QImode:
23402 result = (unsigned_p ? unsigned_V16QI_type_node : V16QI_type_node);
23403 break;
23404 case SFmode: result = V4SF_type_node; break;
23405 case DFmode: result = V2DF_type_node; break;
23406 /* If the user says 'vector int bool', we may be handed the 'bool'
23407 attribute _before_ the 'vector' attribute, and so select the
23408 proper type in the 'b' case below. */
23409 case V4SImode: case V8HImode: case V16QImode: case V4SFmode:
23410 case V2DImode: case V2DFmode:
23411 result = type;
23412 default: break;
23414 break;
23415 case 'b':
23416 switch (mode)
23418 case DImode: case V2DImode: result = bool_V2DI_type_node; break;
23419 case SImode: case V4SImode: result = bool_V4SI_type_node; break;
23420 case HImode: case V8HImode: result = bool_V8HI_type_node; break;
23421 case QImode: case V16QImode: result = bool_V16QI_type_node;
23422 default: break;
23424 break;
23425 case 'p':
23426 switch (mode)
23428 case V8HImode: result = pixel_V8HI_type_node;
23429 default: break;
23431 default: break;
23434 /* Propagate qualifiers attached to the element type
23435 onto the vector type. */
23436 if (result && result != type && TYPE_QUALS (type))
23437 result = build_qualified_type (result, TYPE_QUALS (type));
23439 *no_add_attrs = true; /* No need to hang on to the attribute. */
23441 if (result)
23442 *node = lang_hooks.types.reconstruct_complex_type (*node, result);
23444 return NULL_TREE;
23447 /* AltiVec defines four built-in scalar types that serve as vector
23448 elements; we must teach the compiler how to mangle them. */
23450 static const char *
23451 rs6000_mangle_type (const_tree type)
23453 type = TYPE_MAIN_VARIANT (type);
23455 if (TREE_CODE (type) != VOID_TYPE && TREE_CODE (type) != BOOLEAN_TYPE
23456 && TREE_CODE (type) != INTEGER_TYPE && TREE_CODE (type) != REAL_TYPE)
23457 return NULL;
23459 if (type == bool_char_type_node) return "U6__boolc";
23460 if (type == bool_short_type_node) return "U6__bools";
23461 if (type == pixel_type_node) return "u7__pixel";
23462 if (type == bool_int_type_node) return "U6__booli";
23463 if (type == bool_long_type_node) return "U6__booll";
23465 /* Mangle IBM extended float long double as `g' (__float128) on
23466 powerpc*-linux where long-double-64 previously was the default. */
23467 if (TYPE_MAIN_VARIANT (type) == long_double_type_node
23468 && TARGET_ELF
23469 && TARGET_LONG_DOUBLE_128
23470 && !TARGET_IEEEQUAD)
23471 return "g";
23473 /* For all other types, use normal C++ mangling. */
23474 return NULL;
23477 /* Handle a "longcall" or "shortcall" attribute; arguments as in
23478 struct attribute_spec.handler. */
23480 static tree
23481 rs6000_handle_longcall_attribute (tree *node, tree name,
23482 tree args ATTRIBUTE_UNUSED,
23483 int flags ATTRIBUTE_UNUSED,
23484 bool *no_add_attrs)
23486 if (TREE_CODE (*node) != FUNCTION_TYPE
23487 && TREE_CODE (*node) != FIELD_DECL
23488 && TREE_CODE (*node) != TYPE_DECL)
23490 warning (OPT_Wattributes, "%qE attribute only applies to functions",
23491 name);
23492 *no_add_attrs = true;
23495 return NULL_TREE;
23498 /* Set longcall attributes on all functions declared when
23499 rs6000_default_long_calls is true. */
23500 static void
23501 rs6000_set_default_type_attributes (tree type)
23503 if (rs6000_default_long_calls
23504 && (TREE_CODE (type) == FUNCTION_TYPE
23505 || TREE_CODE (type) == METHOD_TYPE))
23506 TYPE_ATTRIBUTES (type) = tree_cons (get_identifier ("longcall"),
23507 NULL_TREE,
23508 TYPE_ATTRIBUTES (type));
23510 #if TARGET_MACHO
23511 darwin_set_default_type_attributes (type);
23512 #endif
23515 /* Return a reference suitable for calling a function with the
23516 longcall attribute. */
23519 rs6000_longcall_ref (rtx call_ref)
23521 const char *call_name;
23522 tree node;
23524 if (GET_CODE (call_ref) != SYMBOL_REF)
23525 return call_ref;
23527 /* System V adds '.' to the internal name, so skip them. */
23528 call_name = XSTR (call_ref, 0);
23529 if (*call_name == '.')
23531 while (*call_name == '.')
23532 call_name++;
23534 node = get_identifier (call_name);
23535 call_ref = gen_rtx_SYMBOL_REF (VOIDmode, IDENTIFIER_POINTER (node));
23538 return force_reg (Pmode, call_ref);
23541 #ifndef TARGET_USE_MS_BITFIELD_LAYOUT
23542 #define TARGET_USE_MS_BITFIELD_LAYOUT 0
23543 #endif
23545 /* Handle a "ms_struct" or "gcc_struct" attribute; arguments as in
23546 struct attribute_spec.handler. */
23547 static tree
23548 rs6000_handle_struct_attribute (tree *node, tree name,
23549 tree args ATTRIBUTE_UNUSED,
23550 int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
23552 tree *type = NULL;
23553 if (DECL_P (*node))
23555 if (TREE_CODE (*node) == TYPE_DECL)
23556 type = &TREE_TYPE (*node);
23558 else
23559 type = node;
23561 if (!(type && (TREE_CODE (*type) == RECORD_TYPE
23562 || TREE_CODE (*type) == UNION_TYPE)))
23564 warning (OPT_Wattributes, "%qE attribute ignored", name);
23565 *no_add_attrs = true;
23568 else if ((is_attribute_p ("ms_struct", name)
23569 && lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (*type)))
23570 || ((is_attribute_p ("gcc_struct", name)
23571 && lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (*type)))))
23573 warning (OPT_Wattributes, "%qE incompatible attribute ignored",
23574 name);
23575 *no_add_attrs = true;
23578 return NULL_TREE;
23581 static bool
23582 rs6000_ms_bitfield_layout_p (const_tree record_type)
23584 return (TARGET_USE_MS_BITFIELD_LAYOUT &&
23585 !lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (record_type)))
23586 || lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (record_type));
23589 #ifdef USING_ELFOS_H
23591 /* A get_unnamed_section callback, used for switching to toc_section. */
23593 static void
23594 rs6000_elf_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
23596 if (DEFAULT_ABI == ABI_AIX
23597 && TARGET_MINIMAL_TOC
23598 && !TARGET_RELOCATABLE)
23600 if (!toc_initialized)
23602 toc_initialized = 1;
23603 fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);
23604 (*targetm.asm_out.internal_label) (asm_out_file, "LCTOC", 0);
23605 fprintf (asm_out_file, "\t.tc ");
23606 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1[TC],");
23607 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
23608 fprintf (asm_out_file, "\n");
23610 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
23611 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
23612 fprintf (asm_out_file, " = .+32768\n");
23614 else
23615 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
23617 else if (DEFAULT_ABI == ABI_AIX && !TARGET_RELOCATABLE)
23618 fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);
23619 else
23621 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
23622 if (!toc_initialized)
23624 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
23625 fprintf (asm_out_file, " = .+32768\n");
23626 toc_initialized = 1;
23631 /* Implement TARGET_ASM_INIT_SECTIONS. */
23633 static void
23634 rs6000_elf_asm_init_sections (void)
23636 toc_section
23637 = get_unnamed_section (0, rs6000_elf_output_toc_section_asm_op, NULL);
23639 sdata2_section
23640 = get_unnamed_section (SECTION_WRITE, output_section_asm_op,
23641 SDATA2_SECTION_ASM_OP);
23644 /* Implement TARGET_SELECT_RTX_SECTION. */
23646 static section *
23647 rs6000_elf_select_rtx_section (enum machine_mode mode, rtx x,
23648 unsigned HOST_WIDE_INT align)
23650 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
23651 return toc_section;
23652 else
23653 return default_elf_select_rtx_section (mode, x, align);
23656 /* For a SYMBOL_REF, set generic flags and then perform some
23657 target-specific processing.
23659 When the AIX ABI is requested on a non-AIX system, replace the
23660 function name with the real name (with a leading .) rather than the
23661 function descriptor name. This saves a lot of overriding code to
23662 read the prefixes. */
23664 static void
23665 rs6000_elf_encode_section_info (tree decl, rtx rtl, int first)
23667 default_encode_section_info (decl, rtl, first);
23669 if (first
23670 && TREE_CODE (decl) == FUNCTION_DECL
23671 && !TARGET_AIX
23672 && DEFAULT_ABI == ABI_AIX)
23674 rtx sym_ref = XEXP (rtl, 0);
23675 size_t len = strlen (XSTR (sym_ref, 0));
23676 char *str = XALLOCAVEC (char, len + 2);
23677 str[0] = '.';
23678 memcpy (str + 1, XSTR (sym_ref, 0), len + 1);
23679 XSTR (sym_ref, 0) = ggc_alloc_string (str, len + 1);
23683 static inline bool
23684 compare_section_name (const char *section, const char *templ)
23686 int len;
23688 len = strlen (templ);
23689 return (strncmp (section, templ, len) == 0
23690 && (section[len] == 0 || section[len] == '.'));
23693 bool
23694 rs6000_elf_in_small_data_p (const_tree decl)
23696 if (rs6000_sdata == SDATA_NONE)
23697 return false;
23699 /* We want to merge strings, so we never consider them small data. */
23700 if (TREE_CODE (decl) == STRING_CST)
23701 return false;
23703 /* Functions are never in the small data area. */
23704 if (TREE_CODE (decl) == FUNCTION_DECL)
23705 return false;
23707 if (TREE_CODE (decl) == VAR_DECL && DECL_SECTION_NAME (decl))
23709 const char *section = TREE_STRING_POINTER (DECL_SECTION_NAME (decl));
23710 if (compare_section_name (section, ".sdata")
23711 || compare_section_name (section, ".sdata2")
23712 || compare_section_name (section, ".gnu.linkonce.s")
23713 || compare_section_name (section, ".sbss")
23714 || compare_section_name (section, ".sbss2")
23715 || compare_section_name (section, ".gnu.linkonce.sb")
23716 || strcmp (section, ".PPC.EMB.sdata0") == 0
23717 || strcmp (section, ".PPC.EMB.sbss0") == 0)
23718 return true;
23720 else
23722 HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (decl));
23724 if (size > 0
23725 && (unsigned HOST_WIDE_INT) size <= g_switch_value
23726 /* If it's not public, and we're not going to reference it there,
23727 there's no need to put it in the small data section. */
23728 && (rs6000_sdata != SDATA_DATA || TREE_PUBLIC (decl)))
23729 return true;
23732 return false;
23735 #endif /* USING_ELFOS_H */
23737 /* Implement TARGET_USE_BLOCKS_FOR_CONSTANT_P. */
23739 static bool
23740 rs6000_use_blocks_for_constant_p (enum machine_mode mode, const_rtx x)
23742 return !ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode);
23745 /* Return a REG that occurs in ADDR with coefficient 1.
23746 ADDR can be effectively incremented by incrementing REG.
23748 r0 is special and we must not select it as an address
23749 register by this routine since our caller will try to
23750 increment the returned register via an "la" instruction. */
23753 find_addr_reg (rtx addr)
23755 while (GET_CODE (addr) == PLUS)
23757 if (GET_CODE (XEXP (addr, 0)) == REG
23758 && REGNO (XEXP (addr, 0)) != 0)
23759 addr = XEXP (addr, 0);
23760 else if (GET_CODE (XEXP (addr, 1)) == REG
23761 && REGNO (XEXP (addr, 1)) != 0)
23762 addr = XEXP (addr, 1);
23763 else if (CONSTANT_P (XEXP (addr, 0)))
23764 addr = XEXP (addr, 1);
23765 else if (CONSTANT_P (XEXP (addr, 1)))
23766 addr = XEXP (addr, 0);
23767 else
23768 gcc_unreachable ();
23770 gcc_assert (GET_CODE (addr) == REG && REGNO (addr) != 0);
23771 return addr;
23774 void
23775 rs6000_fatal_bad_address (rtx op)
23777 fatal_insn ("bad address", op);
23780 #if TARGET_MACHO
23782 static tree branch_island_list = 0;
23784 /* Remember to generate a branch island for far calls to the given
23785 function. */
23787 static void
23788 add_compiler_branch_island (tree label_name, tree function_name,
23789 int line_number)
23791 tree branch_island = build_tree_list (function_name, label_name);
23792 TREE_TYPE (branch_island) = build_int_cst (NULL_TREE, line_number);
23793 TREE_CHAIN (branch_island) = branch_island_list;
23794 branch_island_list = branch_island;
23797 #define BRANCH_ISLAND_LABEL_NAME(BRANCH_ISLAND) TREE_VALUE (BRANCH_ISLAND)
23798 #define BRANCH_ISLAND_FUNCTION_NAME(BRANCH_ISLAND) TREE_PURPOSE (BRANCH_ISLAND)
23799 #define BRANCH_ISLAND_LINE_NUMBER(BRANCH_ISLAND) \
23800 TREE_INT_CST_LOW (TREE_TYPE (BRANCH_ISLAND))
23802 /* Generate far-jump branch islands for everything on the
23803 branch_island_list. Invoked immediately after the last instruction
23804 of the epilogue has been emitted; the branch-islands must be
23805 appended to, and contiguous with, the function body. Mach-O stubs
23806 are generated in machopic_output_stub(). */
23808 static void
23809 macho_branch_islands (void)
23811 char tmp_buf[512];
23812 tree branch_island;
23814 for (branch_island = branch_island_list;
23815 branch_island;
23816 branch_island = TREE_CHAIN (branch_island))
23818 const char *label =
23819 IDENTIFIER_POINTER (BRANCH_ISLAND_LABEL_NAME (branch_island));
23820 const char *name =
23821 IDENTIFIER_POINTER (BRANCH_ISLAND_FUNCTION_NAME (branch_island));
23822 char name_buf[512];
23823 /* Cheap copy of the details from the Darwin ASM_OUTPUT_LABELREF(). */
23824 if (name[0] == '*' || name[0] == '&')
23825 strcpy (name_buf, name+1);
23826 else
23828 name_buf[0] = '_';
23829 strcpy (name_buf+1, name);
23831 strcpy (tmp_buf, "\n");
23832 strcat (tmp_buf, label);
23833 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
23834 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
23835 dbxout_stabd (N_SLINE, BRANCH_ISLAND_LINE_NUMBER (branch_island));
23836 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
23837 if (flag_pic)
23839 strcat (tmp_buf, ":\n\tmflr r0\n\tbcl 20,31,");
23840 strcat (tmp_buf, label);
23841 strcat (tmp_buf, "_pic\n");
23842 strcat (tmp_buf, label);
23843 strcat (tmp_buf, "_pic:\n\tmflr r11\n");
23845 strcat (tmp_buf, "\taddis r11,r11,ha16(");
23846 strcat (tmp_buf, name_buf);
23847 strcat (tmp_buf, " - ");
23848 strcat (tmp_buf, label);
23849 strcat (tmp_buf, "_pic)\n");
23851 strcat (tmp_buf, "\tmtlr r0\n");
23853 strcat (tmp_buf, "\taddi r12,r11,lo16(");
23854 strcat (tmp_buf, name_buf);
23855 strcat (tmp_buf, " - ");
23856 strcat (tmp_buf, label);
23857 strcat (tmp_buf, "_pic)\n");
23859 strcat (tmp_buf, "\tmtctr r12\n\tbctr\n");
23861 else
23863 strcat (tmp_buf, ":\nlis r12,hi16(");
23864 strcat (tmp_buf, name_buf);
23865 strcat (tmp_buf, ")\n\tori r12,r12,lo16(");
23866 strcat (tmp_buf, name_buf);
23867 strcat (tmp_buf, ")\n\tmtctr r12\n\tbctr");
23869 output_asm_insn (tmp_buf, 0);
23870 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
23871 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
23872 dbxout_stabd (N_SLINE, BRANCH_ISLAND_LINE_NUMBER (branch_island));
23873 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
23876 branch_island_list = 0;
23879 /* NO_PREVIOUS_DEF checks in the link list whether the function name is
23880 already there or not. */
23882 static int
23883 no_previous_def (tree function_name)
23885 tree branch_island;
23886 for (branch_island = branch_island_list;
23887 branch_island;
23888 branch_island = TREE_CHAIN (branch_island))
23889 if (function_name == BRANCH_ISLAND_FUNCTION_NAME (branch_island))
23890 return 0;
23891 return 1;
23894 /* GET_PREV_LABEL gets the label name from the previous definition of
23895 the function. */
23897 static tree
23898 get_prev_label (tree function_name)
23900 tree branch_island;
23901 for (branch_island = branch_island_list;
23902 branch_island;
23903 branch_island = TREE_CHAIN (branch_island))
23904 if (function_name == BRANCH_ISLAND_FUNCTION_NAME (branch_island))
23905 return BRANCH_ISLAND_LABEL_NAME (branch_island);
23906 return 0;
23909 #ifndef DARWIN_LINKER_GENERATES_ISLANDS
23910 #define DARWIN_LINKER_GENERATES_ISLANDS 0
23911 #endif
23913 /* KEXTs still need branch islands. */
23914 #define DARWIN_GENERATE_ISLANDS (!DARWIN_LINKER_GENERATES_ISLANDS \
23915 || flag_mkernel || flag_apple_kext)
23917 /* INSN is either a function call or a millicode call. It may have an
23918 unconditional jump in its delay slot.
23920 CALL_DEST is the routine we are calling. */
23922 char *
23923 output_call (rtx insn, rtx *operands, int dest_operand_number,
23924 int cookie_operand_number)
23926 static char buf[256];
23927 if (DARWIN_GENERATE_ISLANDS
23928 && GET_CODE (operands[dest_operand_number]) == SYMBOL_REF
23929 && (INTVAL (operands[cookie_operand_number]) & CALL_LONG))
23931 tree labelname;
23932 tree funname = get_identifier (XSTR (operands[dest_operand_number], 0));
23934 if (no_previous_def (funname))
23936 rtx label_rtx = gen_label_rtx ();
23937 char *label_buf, temp_buf[256];
23938 ASM_GENERATE_INTERNAL_LABEL (temp_buf, "L",
23939 CODE_LABEL_NUMBER (label_rtx));
23940 label_buf = temp_buf[0] == '*' ? temp_buf + 1 : temp_buf;
23941 labelname = get_identifier (label_buf);
23942 add_compiler_branch_island (labelname, funname, insn_line (insn));
23944 else
23945 labelname = get_prev_label (funname);
23947 /* "jbsr foo, L42" is Mach-O for "Link as 'bl foo' if a 'bl'
23948 instruction will reach 'foo', otherwise link as 'bl L42'".
23949 "L42" should be a 'branch island', that will do a far jump to
23950 'foo'. Branch islands are generated in
23951 macho_branch_islands(). */
23952 sprintf (buf, "jbsr %%z%d,%.246s",
23953 dest_operand_number, IDENTIFIER_POINTER (labelname));
23955 else
23956 sprintf (buf, "bl %%z%d", dest_operand_number);
23957 return buf;
23960 /* Generate PIC and indirect symbol stubs. */
23962 void
23963 machopic_output_stub (FILE *file, const char *symb, const char *stub)
23965 unsigned int length;
23966 char *symbol_name, *lazy_ptr_name;
23967 char *local_label_0;
23968 static int label = 0;
23970 /* Lose our funky encoding stuff so it doesn't contaminate the stub. */
23971 symb = (*targetm.strip_name_encoding) (symb);
23974 length = strlen (symb);
23975 symbol_name = XALLOCAVEC (char, length + 32);
23976 GEN_SYMBOL_NAME_FOR_SYMBOL (symbol_name, symb, length);
23978 lazy_ptr_name = XALLOCAVEC (char, length + 32);
23979 GEN_LAZY_PTR_NAME_FOR_SYMBOL (lazy_ptr_name, symb, length);
23981 if (flag_pic == 2)
23982 switch_to_section (darwin_sections[machopic_picsymbol_stub1_section]);
23983 else
23984 switch_to_section (darwin_sections[machopic_symbol_stub1_section]);
23986 if (flag_pic == 2)
23988 fprintf (file, "\t.align 5\n");
23990 fprintf (file, "%s:\n", stub);
23991 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
23993 label++;
23994 local_label_0 = XALLOCAVEC (char, sizeof ("\"L00000000000$spb\""));
23995 sprintf (local_label_0, "\"L%011d$spb\"", label);
23997 fprintf (file, "\tmflr r0\n");
23998 fprintf (file, "\tbcl 20,31,%s\n", local_label_0);
23999 fprintf (file, "%s:\n\tmflr r11\n", local_label_0);
24000 fprintf (file, "\taddis r11,r11,ha16(%s-%s)\n",
24001 lazy_ptr_name, local_label_0);
24002 fprintf (file, "\tmtlr r0\n");
24003 fprintf (file, "\t%s r12,lo16(%s-%s)(r11)\n",
24004 (TARGET_64BIT ? "ldu" : "lwzu"),
24005 lazy_ptr_name, local_label_0);
24006 fprintf (file, "\tmtctr r12\n");
24007 fprintf (file, "\tbctr\n");
24009 else
24011 fprintf (file, "\t.align 4\n");
24013 fprintf (file, "%s:\n", stub);
24014 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
24016 fprintf (file, "\tlis r11,ha16(%s)\n", lazy_ptr_name);
24017 fprintf (file, "\t%s r12,lo16(%s)(r11)\n",
24018 (TARGET_64BIT ? "ldu" : "lwzu"),
24019 lazy_ptr_name);
24020 fprintf (file, "\tmtctr r12\n");
24021 fprintf (file, "\tbctr\n");
24024 switch_to_section (darwin_sections[machopic_lazy_symbol_ptr_section]);
24025 fprintf (file, "%s:\n", lazy_ptr_name);
24026 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
24027 fprintf (file, "%sdyld_stub_binding_helper\n",
24028 (TARGET_64BIT ? DOUBLE_INT_ASM_OP : "\t.long\t"));
24031 /* Legitimize PIC addresses. If the address is already
24032 position-independent, we return ORIG. Newly generated
24033 position-independent addresses go into a reg. This is REG if non
24034 zero, otherwise we allocate register(s) as necessary. */
24036 #define SMALL_INT(X) ((UINTVAL (X) + 0x8000) < 0x10000)
24039 rs6000_machopic_legitimize_pic_address (rtx orig, enum machine_mode mode,
24040 rtx reg)
24042 rtx base, offset;
24044 if (reg == NULL && ! reload_in_progress && ! reload_completed)
24045 reg = gen_reg_rtx (Pmode);
24047 if (GET_CODE (orig) == CONST)
24049 rtx reg_temp;
24051 if (GET_CODE (XEXP (orig, 0)) == PLUS
24052 && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx)
24053 return orig;
24055 gcc_assert (GET_CODE (XEXP (orig, 0)) == PLUS);
24057 /* Use a different reg for the intermediate value, as
24058 it will be marked UNCHANGING. */
24059 reg_temp = !can_create_pseudo_p () ? reg : gen_reg_rtx (Pmode);
24060 base = rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 0),
24061 Pmode, reg_temp);
24062 offset =
24063 rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 1),
24064 Pmode, reg);
24066 if (GET_CODE (offset) == CONST_INT)
24068 if (SMALL_INT (offset))
24069 return plus_constant (base, INTVAL (offset));
24070 else if (! reload_in_progress && ! reload_completed)
24071 offset = force_reg (Pmode, offset);
24072 else
24074 rtx mem = force_const_mem (Pmode, orig);
24075 return machopic_legitimize_pic_address (mem, Pmode, reg);
24078 return gen_rtx_PLUS (Pmode, base, offset);
24081 /* Fall back on generic machopic code. */
24082 return machopic_legitimize_pic_address (orig, mode, reg);
24085 /* Output a .machine directive for the Darwin assembler, and call
24086 the generic start_file routine. */
24088 static void
24089 rs6000_darwin_file_start (void)
24091 static const struct
24093 const char *arg;
24094 const char *name;
24095 int if_set;
24096 } mapping[] = {
24097 { "ppc64", "ppc64", MASK_64BIT },
24098 { "970", "ppc970", MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64 },
24099 { "power4", "ppc970", 0 },
24100 { "G5", "ppc970", 0 },
24101 { "7450", "ppc7450", 0 },
24102 { "7400", "ppc7400", MASK_ALTIVEC },
24103 { "G4", "ppc7400", 0 },
24104 { "750", "ppc750", 0 },
24105 { "740", "ppc750", 0 },
24106 { "G3", "ppc750", 0 },
24107 { "604e", "ppc604e", 0 },
24108 { "604", "ppc604", 0 },
24109 { "603e", "ppc603", 0 },
24110 { "603", "ppc603", 0 },
24111 { "601", "ppc601", 0 },
24112 { NULL, "ppc", 0 } };
24113 const char *cpu_id = "";
24114 size_t i;
24116 rs6000_file_start ();
24117 darwin_file_start ();
24119 /* Determine the argument to -mcpu=. Default to G3 if not specified. */
24120 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
24121 if (rs6000_select[i].set_arch_p && rs6000_select[i].string
24122 && rs6000_select[i].string[0] != '\0')
24123 cpu_id = rs6000_select[i].string;
24125 /* Look through the mapping array. Pick the first name that either
24126 matches the argument, has a bit set in IF_SET that is also set
24127 in the target flags, or has a NULL name. */
24129 i = 0;
24130 while (mapping[i].arg != NULL
24131 && strcmp (mapping[i].arg, cpu_id) != 0
24132 && (mapping[i].if_set & target_flags) == 0)
24133 i++;
24135 fprintf (asm_out_file, "\t.machine %s\n", mapping[i].name);
24138 #endif /* TARGET_MACHO */
24140 #if TARGET_ELF
24141 static int
24142 rs6000_elf_reloc_rw_mask (void)
24144 if (flag_pic)
24145 return 3;
24146 else if (DEFAULT_ABI == ABI_AIX)
24147 return 2;
24148 else
24149 return 0;
24152 /* Record an element in the table of global constructors. SYMBOL is
24153 a SYMBOL_REF of the function to be called; PRIORITY is a number
24154 between 0 and MAX_INIT_PRIORITY.
24156 This differs from default_named_section_asm_out_constructor in
24157 that we have special handling for -mrelocatable. */
24159 static void
24160 rs6000_elf_asm_out_constructor (rtx symbol, int priority)
24162 const char *section = ".ctors";
24163 char buf[16];
24165 if (priority != DEFAULT_INIT_PRIORITY)
24167 sprintf (buf, ".ctors.%.5u",
24168 /* Invert the numbering so the linker puts us in the proper
24169 order; constructors are run from right to left, and the
24170 linker sorts in increasing order. */
24171 MAX_INIT_PRIORITY - priority);
24172 section = buf;
24175 switch_to_section (get_section (section, SECTION_WRITE, NULL));
24176 assemble_align (POINTER_SIZE);
24178 if (TARGET_RELOCATABLE)
24180 fputs ("\t.long (", asm_out_file);
24181 output_addr_const (asm_out_file, symbol);
24182 fputs (")@fixup\n", asm_out_file);
24184 else
24185 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
24188 static void
24189 rs6000_elf_asm_out_destructor (rtx symbol, int priority)
24191 const char *section = ".dtors";
24192 char buf[16];
24194 if (priority != DEFAULT_INIT_PRIORITY)
24196 sprintf (buf, ".dtors.%.5u",
24197 /* Invert the numbering so the linker puts us in the proper
24198 order; constructors are run from right to left, and the
24199 linker sorts in increasing order. */
24200 MAX_INIT_PRIORITY - priority);
24201 section = buf;
24204 switch_to_section (get_section (section, SECTION_WRITE, NULL));
24205 assemble_align (POINTER_SIZE);
24207 if (TARGET_RELOCATABLE)
24209 fputs ("\t.long (", asm_out_file);
24210 output_addr_const (asm_out_file, symbol);
24211 fputs (")@fixup\n", asm_out_file);
24213 else
24214 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
24217 void
24218 rs6000_elf_declare_function_name (FILE *file, const char *name, tree decl)
24220 if (TARGET_64BIT)
24222 fputs ("\t.section\t\".opd\",\"aw\"\n\t.align 3\n", file);
24223 ASM_OUTPUT_LABEL (file, name);
24224 fputs (DOUBLE_INT_ASM_OP, file);
24225 rs6000_output_function_entry (file, name);
24226 fputs (",.TOC.@tocbase,0\n\t.previous\n", file);
24227 if (DOT_SYMBOLS)
24229 fputs ("\t.size\t", file);
24230 assemble_name (file, name);
24231 fputs (",24\n\t.type\t.", file);
24232 assemble_name (file, name);
24233 fputs (",@function\n", file);
24234 if (TREE_PUBLIC (decl) && ! DECL_WEAK (decl))
24236 fputs ("\t.globl\t.", file);
24237 assemble_name (file, name);
24238 putc ('\n', file);
24241 else
24242 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
24243 ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
24244 rs6000_output_function_entry (file, name);
24245 fputs (":\n", file);
24246 return;
24249 if (TARGET_RELOCATABLE
24250 && !TARGET_SECURE_PLT
24251 && (get_pool_size () != 0 || crtl->profile)
24252 && uses_TOC ())
24254 char buf[256];
24256 (*targetm.asm_out.internal_label) (file, "LCL", rs6000_pic_labelno);
24258 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
24259 fprintf (file, "\t.long ");
24260 assemble_name (file, buf);
24261 putc ('-', file);
24262 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
24263 assemble_name (file, buf);
24264 putc ('\n', file);
24267 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
24268 ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
24270 if (DEFAULT_ABI == ABI_AIX)
24272 const char *desc_name, *orig_name;
24274 orig_name = (*targetm.strip_name_encoding) (name);
24275 desc_name = orig_name;
24276 while (*desc_name == '.')
24277 desc_name++;
24279 if (TREE_PUBLIC (decl))
24280 fprintf (file, "\t.globl %s\n", desc_name);
24282 fprintf (file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
24283 fprintf (file, "%s:\n", desc_name);
24284 fprintf (file, "\t.long %s\n", orig_name);
24285 fputs ("\t.long _GLOBAL_OFFSET_TABLE_\n", file);
24286 if (DEFAULT_ABI == ABI_AIX)
24287 fputs ("\t.long 0\n", file);
24288 fprintf (file, "\t.previous\n");
24290 ASM_OUTPUT_LABEL (file, name);
24293 static void
24294 rs6000_elf_end_indicate_exec_stack (void)
24296 if (TARGET_32BIT)
24297 file_end_indicate_exec_stack ();
24299 #endif
24301 #if TARGET_XCOFF
24302 static void
24303 rs6000_xcoff_asm_output_anchor (rtx symbol)
24305 char buffer[100];
24307 sprintf (buffer, "$ + " HOST_WIDE_INT_PRINT_DEC,
24308 SYMBOL_REF_BLOCK_OFFSET (symbol));
24309 ASM_OUTPUT_DEF (asm_out_file, XSTR (symbol, 0), buffer);
24312 static void
24313 rs6000_xcoff_asm_globalize_label (FILE *stream, const char *name)
24315 fputs (GLOBAL_ASM_OP, stream);
24316 RS6000_OUTPUT_BASENAME (stream, name);
24317 putc ('\n', stream);
24320 /* A get_unnamed_decl callback, used for read-only sections. PTR
24321 points to the section string variable. */
24323 static void
24324 rs6000_xcoff_output_readonly_section_asm_op (const void *directive)
24326 fprintf (asm_out_file, "\t.csect %s[RO],%s\n",
24327 *(const char *const *) directive,
24328 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR);
24331 /* Likewise for read-write sections. */
24333 static void
24334 rs6000_xcoff_output_readwrite_section_asm_op (const void *directive)
24336 fprintf (asm_out_file, "\t.csect %s[RW],%s\n",
24337 *(const char *const *) directive,
24338 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR);
24341 /* A get_unnamed_section callback, used for switching to toc_section. */
24343 static void
24344 rs6000_xcoff_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
24346 if (TARGET_MINIMAL_TOC)
24348 /* toc_section is always selected at least once from
24349 rs6000_xcoff_file_start, so this is guaranteed to
24350 always be defined once and only once in each file. */
24351 if (!toc_initialized)
24353 fputs ("\t.toc\nLCTOC..1:\n", asm_out_file);
24354 fputs ("\t.tc toc_table[TC],toc_table[RW]\n", asm_out_file);
24355 toc_initialized = 1;
24357 fprintf (asm_out_file, "\t.csect toc_table[RW]%s\n",
24358 (TARGET_32BIT ? "" : ",3"));
24360 else
24361 fputs ("\t.toc\n", asm_out_file);
24364 /* Implement TARGET_ASM_INIT_SECTIONS. */
24366 static void
24367 rs6000_xcoff_asm_init_sections (void)
24369 read_only_data_section
24370 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
24371 &xcoff_read_only_section_name);
24373 private_data_section
24374 = get_unnamed_section (SECTION_WRITE,
24375 rs6000_xcoff_output_readwrite_section_asm_op,
24376 &xcoff_private_data_section_name);
24378 read_only_private_data_section
24379 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
24380 &xcoff_private_data_section_name);
24382 toc_section
24383 = get_unnamed_section (0, rs6000_xcoff_output_toc_section_asm_op, NULL);
24385 readonly_data_section = read_only_data_section;
24386 exception_section = data_section;
24389 static int
24390 rs6000_xcoff_reloc_rw_mask (void)
24392 return 3;
24395 static void
24396 rs6000_xcoff_asm_named_section (const char *name, unsigned int flags,
24397 tree decl ATTRIBUTE_UNUSED)
24399 int smclass;
24400 static const char * const suffix[3] = { "PR", "RO", "RW" };
24402 if (flags & SECTION_CODE)
24403 smclass = 0;
24404 else if (flags & SECTION_WRITE)
24405 smclass = 2;
24406 else
24407 smclass = 1;
24409 fprintf (asm_out_file, "\t.csect %s%s[%s],%u\n",
24410 (flags & SECTION_CODE) ? "." : "",
24411 name, suffix[smclass], flags & SECTION_ENTSIZE);
24414 static section *
24415 rs6000_xcoff_select_section (tree decl, int reloc,
24416 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
24418 if (decl_readonly_section (decl, reloc))
24420 if (TREE_PUBLIC (decl))
24421 return read_only_data_section;
24422 else
24423 return read_only_private_data_section;
24425 else
24427 if (TREE_PUBLIC (decl))
24428 return data_section;
24429 else
24430 return private_data_section;
24434 static void
24435 rs6000_xcoff_unique_section (tree decl, int reloc ATTRIBUTE_UNUSED)
24437 const char *name;
24439 /* Use select_section for private and uninitialized data. */
24440 if (!TREE_PUBLIC (decl)
24441 || DECL_COMMON (decl)
24442 || DECL_INITIAL (decl) == NULL_TREE
24443 || DECL_INITIAL (decl) == error_mark_node
24444 || (flag_zero_initialized_in_bss
24445 && initializer_zerop (DECL_INITIAL (decl))))
24446 return;
24448 name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
24449 name = (*targetm.strip_name_encoding) (name);
24450 DECL_SECTION_NAME (decl) = build_string (strlen (name), name);
24453 /* Select section for constant in constant pool.
24455 On RS/6000, all constants are in the private read-only data area.
24456 However, if this is being placed in the TOC it must be output as a
24457 toc entry. */
24459 static section *
24460 rs6000_xcoff_select_rtx_section (enum machine_mode mode, rtx x,
24461 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
24463 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
24464 return toc_section;
24465 else
24466 return read_only_private_data_section;
24469 /* Remove any trailing [DS] or the like from the symbol name. */
24471 static const char *
24472 rs6000_xcoff_strip_name_encoding (const char *name)
24474 size_t len;
24475 if (*name == '*')
24476 name++;
24477 len = strlen (name);
24478 if (name[len - 1] == ']')
24479 return ggc_alloc_string (name, len - 4);
24480 else
24481 return name;
24484 /* Section attributes. AIX is always PIC. */
24486 static unsigned int
24487 rs6000_xcoff_section_type_flags (tree decl, const char *name, int reloc)
24489 unsigned int align;
24490 unsigned int flags = default_section_type_flags (decl, name, reloc);
24492 /* Align to at least UNIT size. */
24493 if (flags & SECTION_CODE)
24494 align = MIN_UNITS_PER_WORD;
24495 else
24496 /* Increase alignment of large objects if not already stricter. */
24497 align = MAX ((DECL_ALIGN (decl) / BITS_PER_UNIT),
24498 int_size_in_bytes (TREE_TYPE (decl)) > MIN_UNITS_PER_WORD
24499 ? UNITS_PER_FP_WORD : MIN_UNITS_PER_WORD);
24501 return flags | (exact_log2 (align) & SECTION_ENTSIZE);
24504 /* Output at beginning of assembler file.
24506 Initialize the section names for the RS/6000 at this point.
24508 Specify filename, including full path, to assembler.
24510 We want to go into the TOC section so at least one .toc will be emitted.
24511 Also, in order to output proper .bs/.es pairs, we need at least one static
24512 [RW] section emitted.
24514 Finally, declare mcount when profiling to make the assembler happy. */
24516 static void
24517 rs6000_xcoff_file_start (void)
24519 rs6000_gen_section_name (&xcoff_bss_section_name,
24520 main_input_filename, ".bss_");
24521 rs6000_gen_section_name (&xcoff_private_data_section_name,
24522 main_input_filename, ".rw_");
24523 rs6000_gen_section_name (&xcoff_read_only_section_name,
24524 main_input_filename, ".ro_");
24526 fputs ("\t.file\t", asm_out_file);
24527 output_quoted_string (asm_out_file, main_input_filename);
24528 fputc ('\n', asm_out_file);
24529 if (write_symbols != NO_DEBUG)
24530 switch_to_section (private_data_section);
24531 switch_to_section (text_section);
24532 if (profile_flag)
24533 fprintf (asm_out_file, "\t.extern %s\n", RS6000_MCOUNT);
24534 rs6000_file_start ();
24537 /* Output at end of assembler file.
24538 On the RS/6000, referencing data should automatically pull in text. */
24540 static void
24541 rs6000_xcoff_file_end (void)
24543 switch_to_section (text_section);
24544 fputs ("_section_.text:\n", asm_out_file);
24545 switch_to_section (data_section);
24546 fputs (TARGET_32BIT
24547 ? "\t.long _section_.text\n" : "\t.llong _section_.text\n",
24548 asm_out_file);
24550 #endif /* TARGET_XCOFF */
24552 /* Compute a (partial) cost for rtx X. Return true if the complete
24553 cost has been computed, and false if subexpressions should be
24554 scanned. In either case, *TOTAL contains the cost result. */
24556 static bool
24557 rs6000_rtx_costs (rtx x, int code, int outer_code, int *total,
24558 bool speed)
24560 enum machine_mode mode = GET_MODE (x);
24562 switch (code)
24564 /* On the RS/6000, if it is valid in the insn, it is free. */
24565 case CONST_INT:
24566 if (((outer_code == SET
24567 || outer_code == PLUS
24568 || outer_code == MINUS)
24569 && (satisfies_constraint_I (x)
24570 || satisfies_constraint_L (x)))
24571 || (outer_code == AND
24572 && (satisfies_constraint_K (x)
24573 || (mode == SImode
24574 ? satisfies_constraint_L (x)
24575 : satisfies_constraint_J (x))
24576 || mask_operand (x, mode)
24577 || (mode == DImode
24578 && mask64_operand (x, DImode))))
24579 || ((outer_code == IOR || outer_code == XOR)
24580 && (satisfies_constraint_K (x)
24581 || (mode == SImode
24582 ? satisfies_constraint_L (x)
24583 : satisfies_constraint_J (x))))
24584 || outer_code == ASHIFT
24585 || outer_code == ASHIFTRT
24586 || outer_code == LSHIFTRT
24587 || outer_code == ROTATE
24588 || outer_code == ROTATERT
24589 || outer_code == ZERO_EXTRACT
24590 || (outer_code == MULT
24591 && satisfies_constraint_I (x))
24592 || ((outer_code == DIV || outer_code == UDIV
24593 || outer_code == MOD || outer_code == UMOD)
24594 && exact_log2 (INTVAL (x)) >= 0)
24595 || (outer_code == COMPARE
24596 && (satisfies_constraint_I (x)
24597 || satisfies_constraint_K (x)))
24598 || (outer_code == EQ
24599 && (satisfies_constraint_I (x)
24600 || satisfies_constraint_K (x)
24601 || (mode == SImode
24602 ? satisfies_constraint_L (x)
24603 : satisfies_constraint_J (x))))
24604 || (outer_code == GTU
24605 && satisfies_constraint_I (x))
24606 || (outer_code == LTU
24607 && satisfies_constraint_P (x)))
24609 *total = 0;
24610 return true;
24612 else if ((outer_code == PLUS
24613 && reg_or_add_cint_operand (x, VOIDmode))
24614 || (outer_code == MINUS
24615 && reg_or_sub_cint_operand (x, VOIDmode))
24616 || ((outer_code == SET
24617 || outer_code == IOR
24618 || outer_code == XOR)
24619 && (INTVAL (x)
24620 & ~ (unsigned HOST_WIDE_INT) 0xffffffff) == 0))
24622 *total = COSTS_N_INSNS (1);
24623 return true;
24625 /* FALLTHRU */
24627 case CONST_DOUBLE:
24628 if (mode == DImode && code == CONST_DOUBLE)
24630 if ((outer_code == IOR || outer_code == XOR)
24631 && CONST_DOUBLE_HIGH (x) == 0
24632 && (CONST_DOUBLE_LOW (x)
24633 & ~ (unsigned HOST_WIDE_INT) 0xffff) == 0)
24635 *total = 0;
24636 return true;
24638 else if ((outer_code == AND && and64_2_operand (x, DImode))
24639 || ((outer_code == SET
24640 || outer_code == IOR
24641 || outer_code == XOR)
24642 && CONST_DOUBLE_HIGH (x) == 0))
24644 *total = COSTS_N_INSNS (1);
24645 return true;
24648 /* FALLTHRU */
24650 case CONST:
24651 case HIGH:
24652 case SYMBOL_REF:
24653 case MEM:
24654 /* When optimizing for size, MEM should be slightly more expensive
24655 than generating address, e.g., (plus (reg) (const)).
24656 L1 cache latency is about two instructions. */
24657 *total = !speed ? COSTS_N_INSNS (1) + 1 : COSTS_N_INSNS (2);
24658 return true;
24660 case LABEL_REF:
24661 *total = 0;
24662 return true;
24664 case PLUS:
24665 if (mode == DFmode)
24667 if (GET_CODE (XEXP (x, 0)) == MULT)
24669 /* FNMA accounted in outer NEG. */
24670 if (outer_code == NEG)
24671 *total = rs6000_cost->dmul - rs6000_cost->fp;
24672 else
24673 *total = rs6000_cost->dmul;
24675 else
24676 *total = rs6000_cost->fp;
24678 else if (mode == SFmode)
24680 /* FNMA accounted in outer NEG. */
24681 if (outer_code == NEG && GET_CODE (XEXP (x, 0)) == MULT)
24682 *total = 0;
24683 else
24684 *total = rs6000_cost->fp;
24686 else
24687 *total = COSTS_N_INSNS (1);
24688 return false;
24690 case MINUS:
24691 if (mode == DFmode)
24693 if (GET_CODE (XEXP (x, 0)) == MULT
24694 || GET_CODE (XEXP (x, 1)) == MULT)
24696 /* FNMA accounted in outer NEG. */
24697 if (outer_code == NEG)
24698 *total = rs6000_cost->dmul - rs6000_cost->fp;
24699 else
24700 *total = rs6000_cost->dmul;
24702 else
24703 *total = rs6000_cost->fp;
24705 else if (mode == SFmode)
24707 /* FNMA accounted in outer NEG. */
24708 if (outer_code == NEG && GET_CODE (XEXP (x, 0)) == MULT)
24709 *total = 0;
24710 else
24711 *total = rs6000_cost->fp;
24713 else
24714 *total = COSTS_N_INSNS (1);
24715 return false;
24717 case MULT:
24718 if (GET_CODE (XEXP (x, 1)) == CONST_INT
24719 && satisfies_constraint_I (XEXP (x, 1)))
24721 if (INTVAL (XEXP (x, 1)) >= -256
24722 && INTVAL (XEXP (x, 1)) <= 255)
24723 *total = rs6000_cost->mulsi_const9;
24724 else
24725 *total = rs6000_cost->mulsi_const;
24727 /* FMA accounted in outer PLUS/MINUS. */
24728 else if ((mode == DFmode || mode == SFmode)
24729 && (outer_code == PLUS || outer_code == MINUS))
24730 *total = 0;
24731 else if (mode == DFmode)
24732 *total = rs6000_cost->dmul;
24733 else if (mode == SFmode)
24734 *total = rs6000_cost->fp;
24735 else if (mode == DImode)
24736 *total = rs6000_cost->muldi;
24737 else
24738 *total = rs6000_cost->mulsi;
24739 return false;
24741 case DIV:
24742 case MOD:
24743 if (FLOAT_MODE_P (mode))
24745 *total = mode == DFmode ? rs6000_cost->ddiv
24746 : rs6000_cost->sdiv;
24747 return false;
24749 /* FALLTHRU */
24751 case UDIV:
24752 case UMOD:
24753 if (GET_CODE (XEXP (x, 1)) == CONST_INT
24754 && exact_log2 (INTVAL (XEXP (x, 1))) >= 0)
24756 if (code == DIV || code == MOD)
24757 /* Shift, addze */
24758 *total = COSTS_N_INSNS (2);
24759 else
24760 /* Shift */
24761 *total = COSTS_N_INSNS (1);
24763 else
24765 if (GET_MODE (XEXP (x, 1)) == DImode)
24766 *total = rs6000_cost->divdi;
24767 else
24768 *total = rs6000_cost->divsi;
24770 /* Add in shift and subtract for MOD. */
24771 if (code == MOD || code == UMOD)
24772 *total += COSTS_N_INSNS (2);
24773 return false;
24775 case CTZ:
24776 case FFS:
24777 *total = COSTS_N_INSNS (4);
24778 return false;
24780 case POPCOUNT:
24781 *total = COSTS_N_INSNS (6);
24782 return false;
24784 case NOT:
24785 if (outer_code == AND || outer_code == IOR || outer_code == XOR)
24787 *total = 0;
24788 return false;
24790 /* FALLTHRU */
24792 case AND:
24793 case CLZ:
24794 case IOR:
24795 case XOR:
24796 case ZERO_EXTRACT:
24797 *total = COSTS_N_INSNS (1);
24798 return false;
24800 case ASHIFT:
24801 case ASHIFTRT:
24802 case LSHIFTRT:
24803 case ROTATE:
24804 case ROTATERT:
24805 /* Handle mul_highpart. */
24806 if (outer_code == TRUNCATE
24807 && GET_CODE (XEXP (x, 0)) == MULT)
24809 if (mode == DImode)
24810 *total = rs6000_cost->muldi;
24811 else
24812 *total = rs6000_cost->mulsi;
24813 return true;
24815 else if (outer_code == AND)
24816 *total = 0;
24817 else
24818 *total = COSTS_N_INSNS (1);
24819 return false;
24821 case SIGN_EXTEND:
24822 case ZERO_EXTEND:
24823 if (GET_CODE (XEXP (x, 0)) == MEM)
24824 *total = 0;
24825 else
24826 *total = COSTS_N_INSNS (1);
24827 return false;
24829 case COMPARE:
24830 case NEG:
24831 case ABS:
24832 if (!FLOAT_MODE_P (mode))
24834 *total = COSTS_N_INSNS (1);
24835 return false;
24837 /* FALLTHRU */
24839 case FLOAT:
24840 case UNSIGNED_FLOAT:
24841 case FIX:
24842 case UNSIGNED_FIX:
24843 case FLOAT_TRUNCATE:
24844 *total = rs6000_cost->fp;
24845 return false;
24847 case FLOAT_EXTEND:
24848 if (mode == DFmode)
24849 *total = 0;
24850 else
24851 *total = rs6000_cost->fp;
24852 return false;
24854 case UNSPEC:
24855 switch (XINT (x, 1))
24857 case UNSPEC_FRSP:
24858 *total = rs6000_cost->fp;
24859 return true;
24861 default:
24862 break;
24864 break;
24866 case CALL:
24867 case IF_THEN_ELSE:
24868 if (!speed)
24870 *total = COSTS_N_INSNS (1);
24871 return true;
24873 else if (FLOAT_MODE_P (mode)
24874 && TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS)
24876 *total = rs6000_cost->fp;
24877 return false;
24879 break;
24881 case EQ:
24882 case GTU:
24883 case LTU:
24884 /* Carry bit requires mode == Pmode.
24885 NEG or PLUS already counted so only add one. */
24886 if (mode == Pmode
24887 && (outer_code == NEG || outer_code == PLUS))
24889 *total = COSTS_N_INSNS (1);
24890 return true;
24892 if (outer_code == SET)
24894 if (XEXP (x, 1) == const0_rtx)
24896 if (TARGET_ISEL && !TARGET_MFCRF)
24897 *total = COSTS_N_INSNS (8);
24898 else
24899 *total = COSTS_N_INSNS (2);
24900 return true;
24902 else if (mode == Pmode)
24904 *total = COSTS_N_INSNS (3);
24905 return false;
24908 /* FALLTHRU */
24910 case GT:
24911 case LT:
24912 case UNORDERED:
24913 if (outer_code == SET && (XEXP (x, 1) == const0_rtx))
24915 if (TARGET_ISEL && !TARGET_MFCRF)
24916 *total = COSTS_N_INSNS (8);
24917 else
24918 *total = COSTS_N_INSNS (2);
24919 return true;
24921 /* CC COMPARE. */
24922 if (outer_code == COMPARE)
24924 *total = 0;
24925 return true;
24927 break;
24929 default:
24930 break;
24933 return false;
24936 /* Debug form of r6000_rtx_costs that is selected if -mdebug=cost. */
24938 static bool
24939 rs6000_debug_rtx_costs (rtx x, int code, int outer_code, int *total,
24940 bool speed)
24942 bool ret = rs6000_rtx_costs (x, code, outer_code, total, speed);
24944 fprintf (stderr,
24945 "\nrs6000_rtx_costs, return = %s, code = %s, outer_code = %s, "
24946 "total = %d, speed = %s, x:\n",
24947 ret ? "complete" : "scan inner",
24948 GET_RTX_NAME (code),
24949 GET_RTX_NAME (outer_code),
24950 *total,
24951 speed ? "true" : "false");
24953 debug_rtx (x);
24955 return ret;
24958 /* Debug form of ADDRESS_COST that is selected if -mdebug=cost. */
24960 static int
24961 rs6000_debug_address_cost (rtx x, bool speed)
24963 int ret = TARGET_ADDRESS_COST (x, speed);
24965 fprintf (stderr, "\nrs6000_address_cost, return = %d, speed = %s, x:\n",
24966 ret, speed ? "true" : "false");
24967 debug_rtx (x);
24969 return ret;
24973 /* A C expression returning the cost of moving data from a register of class
24974 CLASS1 to one of CLASS2. */
24977 rs6000_register_move_cost (enum machine_mode mode,
24978 enum reg_class from, enum reg_class to)
24980 int ret;
24982 /* Moves from/to GENERAL_REGS. */
24983 if (reg_classes_intersect_p (to, GENERAL_REGS)
24984 || reg_classes_intersect_p (from, GENERAL_REGS))
24986 if (! reg_classes_intersect_p (to, GENERAL_REGS))
24987 from = to;
24989 if (from == FLOAT_REGS || from == ALTIVEC_REGS || from == VSX_REGS)
24990 ret = (rs6000_memory_move_cost (mode, from, 0)
24991 + rs6000_memory_move_cost (mode, GENERAL_REGS, 0));
24993 /* It's more expensive to move CR_REGS than CR0_REGS because of the
24994 shift. */
24995 else if (from == CR_REGS)
24996 ret = 4;
24998 /* Power6 has slower LR/CTR moves so make them more expensive than
24999 memory in order to bias spills to memory .*/
25000 else if (rs6000_cpu == PROCESSOR_POWER6
25001 && reg_classes_intersect_p (from, LINK_OR_CTR_REGS))
25002 ret = 6 * hard_regno_nregs[0][mode];
25004 else
25005 /* A move will cost one instruction per GPR moved. */
25006 ret = 2 * hard_regno_nregs[0][mode];
25009 /* If we have VSX, we can easily move between FPR or Altivec registers. */
25010 else if (VECTOR_UNIT_VSX_P (mode)
25011 && reg_classes_intersect_p (to, VSX_REGS)
25012 && reg_classes_intersect_p (from, VSX_REGS))
25013 ret = 2 * hard_regno_nregs[32][mode];
25015 /* Moving between two similar registers is just one instruction. */
25016 else if (reg_classes_intersect_p (to, from))
25017 ret = (mode == TFmode || mode == TDmode) ? 4 : 2;
25019 /* Everything else has to go through GENERAL_REGS. */
25020 else
25021 ret = (rs6000_register_move_cost (mode, GENERAL_REGS, to)
25022 + rs6000_register_move_cost (mode, from, GENERAL_REGS));
25024 if (TARGET_DEBUG_COST)
25025 fprintf (stderr,
25026 "rs6000_register_move_cost:, ret=%d, mode=%s, from=%s, to=%s\n",
25027 ret, GET_MODE_NAME (mode), reg_class_names[from],
25028 reg_class_names[to]);
25030 return ret;
25033 /* A C expressions returning the cost of moving data of MODE from a register to
25034 or from memory. */
25037 rs6000_memory_move_cost (enum machine_mode mode, enum reg_class rclass,
25038 int in ATTRIBUTE_UNUSED)
25040 int ret;
25042 if (reg_classes_intersect_p (rclass, GENERAL_REGS))
25043 ret = 4 * hard_regno_nregs[0][mode];
25044 else if (reg_classes_intersect_p (rclass, FLOAT_REGS))
25045 ret = 4 * hard_regno_nregs[32][mode];
25046 else if (reg_classes_intersect_p (rclass, ALTIVEC_REGS))
25047 ret = 4 * hard_regno_nregs[FIRST_ALTIVEC_REGNO][mode];
25048 else
25049 ret = 4 + rs6000_register_move_cost (mode, rclass, GENERAL_REGS);
25051 if (TARGET_DEBUG_COST)
25052 fprintf (stderr,
25053 "rs6000_memory_move_cost: ret=%d, mode=%s, rclass=%s, in=%d\n",
25054 ret, GET_MODE_NAME (mode), reg_class_names[rclass], in);
25056 return ret;
25059 /* Returns a code for a target-specific builtin that implements
25060 reciprocal of the function, or NULL_TREE if not available. */
25062 static tree
25063 rs6000_builtin_reciprocal (unsigned int fn, bool md_fn,
25064 bool sqrt ATTRIBUTE_UNUSED)
25066 if (! (TARGET_RECIP && TARGET_PPC_GFXOPT && !optimize_size
25067 && flag_finite_math_only && !flag_trapping_math
25068 && flag_unsafe_math_optimizations))
25069 return NULL_TREE;
25071 if (md_fn)
25072 return NULL_TREE;
25073 else
25074 switch (fn)
25076 case BUILT_IN_SQRTF:
25077 return rs6000_builtin_decls[RS6000_BUILTIN_RSQRTF];
25079 default:
25080 return NULL_TREE;
25084 /* Newton-Raphson approximation of single-precision floating point divide n/d.
25085 Assumes no trapping math and finite arguments. */
25087 void
25088 rs6000_emit_swdivsf (rtx dst, rtx n, rtx d)
25090 rtx x0, e0, e1, y1, u0, v0, one;
25092 x0 = gen_reg_rtx (SFmode);
25093 e0 = gen_reg_rtx (SFmode);
25094 e1 = gen_reg_rtx (SFmode);
25095 y1 = gen_reg_rtx (SFmode);
25096 u0 = gen_reg_rtx (SFmode);
25097 v0 = gen_reg_rtx (SFmode);
25098 one = force_reg (SFmode, CONST_DOUBLE_FROM_REAL_VALUE (dconst1, SFmode));
25100 /* x0 = 1./d estimate */
25101 emit_insn (gen_rtx_SET (VOIDmode, x0,
25102 gen_rtx_UNSPEC (SFmode, gen_rtvec (1, d),
25103 UNSPEC_FRES)));
25104 /* e0 = 1. - d * x0 */
25105 emit_insn (gen_rtx_SET (VOIDmode, e0,
25106 gen_rtx_MINUS (SFmode, one,
25107 gen_rtx_MULT (SFmode, d, x0))));
25108 /* e1 = e0 + e0 * e0 */
25109 emit_insn (gen_rtx_SET (VOIDmode, e1,
25110 gen_rtx_PLUS (SFmode,
25111 gen_rtx_MULT (SFmode, e0, e0), e0)));
25112 /* y1 = x0 + e1 * x0 */
25113 emit_insn (gen_rtx_SET (VOIDmode, y1,
25114 gen_rtx_PLUS (SFmode,
25115 gen_rtx_MULT (SFmode, e1, x0), x0)));
25116 /* u0 = n * y1 */
25117 emit_insn (gen_rtx_SET (VOIDmode, u0,
25118 gen_rtx_MULT (SFmode, n, y1)));
25119 /* v0 = n - d * u0 */
25120 emit_insn (gen_rtx_SET (VOIDmode, v0,
25121 gen_rtx_MINUS (SFmode, n,
25122 gen_rtx_MULT (SFmode, d, u0))));
25123 /* dst = u0 + v0 * y1 */
25124 emit_insn (gen_rtx_SET (VOIDmode, dst,
25125 gen_rtx_PLUS (SFmode,
25126 gen_rtx_MULT (SFmode, v0, y1), u0)));
25129 /* Newton-Raphson approximation of double-precision floating point divide n/d.
25130 Assumes no trapping math and finite arguments. */
25132 void
25133 rs6000_emit_swdivdf (rtx dst, rtx n, rtx d)
25135 rtx x0, e0, e1, e2, y1, y2, y3, u0, v0, one;
25137 x0 = gen_reg_rtx (DFmode);
25138 e0 = gen_reg_rtx (DFmode);
25139 e1 = gen_reg_rtx (DFmode);
25140 e2 = gen_reg_rtx (DFmode);
25141 y1 = gen_reg_rtx (DFmode);
25142 y2 = gen_reg_rtx (DFmode);
25143 y3 = gen_reg_rtx (DFmode);
25144 u0 = gen_reg_rtx (DFmode);
25145 v0 = gen_reg_rtx (DFmode);
25146 one = force_reg (DFmode, CONST_DOUBLE_FROM_REAL_VALUE (dconst1, DFmode));
25148 /* x0 = 1./d estimate */
25149 emit_insn (gen_rtx_SET (VOIDmode, x0,
25150 gen_rtx_UNSPEC (DFmode, gen_rtvec (1, d),
25151 UNSPEC_FRES)));
25152 /* e0 = 1. - d * x0 */
25153 emit_insn (gen_rtx_SET (VOIDmode, e0,
25154 gen_rtx_MINUS (DFmode, one,
25155 gen_rtx_MULT (SFmode, d, x0))));
25156 /* y1 = x0 + e0 * x0 */
25157 emit_insn (gen_rtx_SET (VOIDmode, y1,
25158 gen_rtx_PLUS (DFmode,
25159 gen_rtx_MULT (DFmode, e0, x0), x0)));
25160 /* e1 = e0 * e0 */
25161 emit_insn (gen_rtx_SET (VOIDmode, e1,
25162 gen_rtx_MULT (DFmode, e0, e0)));
25163 /* y2 = y1 + e1 * y1 */
25164 emit_insn (gen_rtx_SET (VOIDmode, y2,
25165 gen_rtx_PLUS (DFmode,
25166 gen_rtx_MULT (DFmode, e1, y1), y1)));
25167 /* e2 = e1 * e1 */
25168 emit_insn (gen_rtx_SET (VOIDmode, e2,
25169 gen_rtx_MULT (DFmode, e1, e1)));
25170 /* y3 = y2 + e2 * y2 */
25171 emit_insn (gen_rtx_SET (VOIDmode, y3,
25172 gen_rtx_PLUS (DFmode,
25173 gen_rtx_MULT (DFmode, e2, y2), y2)));
25174 /* u0 = n * y3 */
25175 emit_insn (gen_rtx_SET (VOIDmode, u0,
25176 gen_rtx_MULT (DFmode, n, y3)));
25177 /* v0 = n - d * u0 */
25178 emit_insn (gen_rtx_SET (VOIDmode, v0,
25179 gen_rtx_MINUS (DFmode, n,
25180 gen_rtx_MULT (DFmode, d, u0))));
25181 /* dst = u0 + v0 * y3 */
25182 emit_insn (gen_rtx_SET (VOIDmode, dst,
25183 gen_rtx_PLUS (DFmode,
25184 gen_rtx_MULT (DFmode, v0, y3), u0)));
25188 /* Newton-Raphson approximation of single-precision floating point rsqrt.
25189 Assumes no trapping math and finite arguments. */
25191 void
25192 rs6000_emit_swrsqrtsf (rtx dst, rtx src)
25194 rtx x0, x1, x2, y1, u0, u1, u2, v0, v1, v2, t0,
25195 half, one, halfthree, c1, cond, label;
25197 x0 = gen_reg_rtx (SFmode);
25198 x1 = gen_reg_rtx (SFmode);
25199 x2 = gen_reg_rtx (SFmode);
25200 y1 = gen_reg_rtx (SFmode);
25201 u0 = gen_reg_rtx (SFmode);
25202 u1 = gen_reg_rtx (SFmode);
25203 u2 = gen_reg_rtx (SFmode);
25204 v0 = gen_reg_rtx (SFmode);
25205 v1 = gen_reg_rtx (SFmode);
25206 v2 = gen_reg_rtx (SFmode);
25207 t0 = gen_reg_rtx (SFmode);
25208 halfthree = gen_reg_rtx (SFmode);
25209 cond = gen_rtx_REG (CCFPmode, CR1_REGNO);
25210 label = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
25212 /* check 0.0, 1.0, NaN, Inf by testing src * src = src */
25213 emit_insn (gen_rtx_SET (VOIDmode, t0,
25214 gen_rtx_MULT (SFmode, src, src)));
25216 emit_insn (gen_rtx_SET (VOIDmode, cond,
25217 gen_rtx_COMPARE (CCFPmode, t0, src)));
25218 c1 = gen_rtx_EQ (VOIDmode, cond, const0_rtx);
25219 emit_unlikely_jump (c1, label);
25221 half = force_reg (SFmode, CONST_DOUBLE_FROM_REAL_VALUE (dconsthalf, SFmode));
25222 one = force_reg (SFmode, CONST_DOUBLE_FROM_REAL_VALUE (dconst1, SFmode));
25224 /* halfthree = 1.5 = 1.0 + 0.5 */
25225 emit_insn (gen_rtx_SET (VOIDmode, halfthree,
25226 gen_rtx_PLUS (SFmode, one, half)));
25228 /* x0 = rsqrt estimate */
25229 emit_insn (gen_rtx_SET (VOIDmode, x0,
25230 gen_rtx_UNSPEC (SFmode, gen_rtvec (1, src),
25231 UNSPEC_RSQRT)));
25233 /* y1 = 0.5 * src = 1.5 * src - src -> fewer constants */
25234 emit_insn (gen_rtx_SET (VOIDmode, y1,
25235 gen_rtx_MINUS (SFmode,
25236 gen_rtx_MULT (SFmode, src, halfthree),
25237 src)));
25239 /* x1 = x0 * (1.5 - y1 * (x0 * x0)) */
25240 emit_insn (gen_rtx_SET (VOIDmode, u0,
25241 gen_rtx_MULT (SFmode, x0, x0)));
25242 emit_insn (gen_rtx_SET (VOIDmode, v0,
25243 gen_rtx_MINUS (SFmode,
25244 halfthree,
25245 gen_rtx_MULT (SFmode, y1, u0))));
25246 emit_insn (gen_rtx_SET (VOIDmode, x1,
25247 gen_rtx_MULT (SFmode, x0, v0)));
25249 /* x2 = x1 * (1.5 - y1 * (x1 * x1)) */
25250 emit_insn (gen_rtx_SET (VOIDmode, u1,
25251 gen_rtx_MULT (SFmode, x1, x1)));
25252 emit_insn (gen_rtx_SET (VOIDmode, v1,
25253 gen_rtx_MINUS (SFmode,
25254 halfthree,
25255 gen_rtx_MULT (SFmode, y1, u1))));
25256 emit_insn (gen_rtx_SET (VOIDmode, x2,
25257 gen_rtx_MULT (SFmode, x1, v1)));
25259 /* dst = x2 * (1.5 - y1 * (x2 * x2)) */
25260 emit_insn (gen_rtx_SET (VOIDmode, u2,
25261 gen_rtx_MULT (SFmode, x2, x2)));
25262 emit_insn (gen_rtx_SET (VOIDmode, v2,
25263 gen_rtx_MINUS (SFmode,
25264 halfthree,
25265 gen_rtx_MULT (SFmode, y1, u2))));
25266 emit_insn (gen_rtx_SET (VOIDmode, dst,
25267 gen_rtx_MULT (SFmode, x2, v2)));
25269 emit_label (XEXP (label, 0));
25272 /* Emit popcount intrinsic on TARGET_POPCNTB (Power5) and TARGET_POPCNTD
25273 (Power7) targets. DST is the target, and SRC is the argument operand. */
25275 void
25276 rs6000_emit_popcount (rtx dst, rtx src)
25278 enum machine_mode mode = GET_MODE (dst);
25279 rtx tmp1, tmp2;
25281 /* Use the PPC ISA 2.06 popcnt{w,d} instruction if we can. */
25282 if (TARGET_POPCNTD)
25284 if (mode == SImode)
25285 emit_insn (gen_popcntwsi2 (dst, src));
25286 else
25287 emit_insn (gen_popcntddi2 (dst, src));
25288 return;
25291 tmp1 = gen_reg_rtx (mode);
25293 if (mode == SImode)
25295 emit_insn (gen_popcntbsi2 (tmp1, src));
25296 tmp2 = expand_mult (SImode, tmp1, GEN_INT (0x01010101),
25297 NULL_RTX, 0);
25298 tmp2 = force_reg (SImode, tmp2);
25299 emit_insn (gen_lshrsi3 (dst, tmp2, GEN_INT (24)));
25301 else
25303 emit_insn (gen_popcntbdi2 (tmp1, src));
25304 tmp2 = expand_mult (DImode, tmp1,
25305 GEN_INT ((HOST_WIDE_INT)
25306 0x01010101 << 32 | 0x01010101),
25307 NULL_RTX, 0);
25308 tmp2 = force_reg (DImode, tmp2);
25309 emit_insn (gen_lshrdi3 (dst, tmp2, GEN_INT (56)));
25314 /* Emit parity intrinsic on TARGET_POPCNTB targets. DST is the
25315 target, and SRC is the argument operand. */
25317 void
25318 rs6000_emit_parity (rtx dst, rtx src)
25320 enum machine_mode mode = GET_MODE (dst);
25321 rtx tmp;
25323 tmp = gen_reg_rtx (mode);
25324 if (mode == SImode)
25326 /* Is mult+shift >= shift+xor+shift+xor? */
25327 if (rs6000_cost->mulsi_const >= COSTS_N_INSNS (3))
25329 rtx tmp1, tmp2, tmp3, tmp4;
25331 tmp1 = gen_reg_rtx (SImode);
25332 emit_insn (gen_popcntbsi2 (tmp1, src));
25334 tmp2 = gen_reg_rtx (SImode);
25335 emit_insn (gen_lshrsi3 (tmp2, tmp1, GEN_INT (16)));
25336 tmp3 = gen_reg_rtx (SImode);
25337 emit_insn (gen_xorsi3 (tmp3, tmp1, tmp2));
25339 tmp4 = gen_reg_rtx (SImode);
25340 emit_insn (gen_lshrsi3 (tmp4, tmp3, GEN_INT (8)));
25341 emit_insn (gen_xorsi3 (tmp, tmp3, tmp4));
25343 else
25344 rs6000_emit_popcount (tmp, src);
25345 emit_insn (gen_andsi3 (dst, tmp, const1_rtx));
25347 else
25349 /* Is mult+shift >= shift+xor+shift+xor+shift+xor? */
25350 if (rs6000_cost->muldi >= COSTS_N_INSNS (5))
25352 rtx tmp1, tmp2, tmp3, tmp4, tmp5, tmp6;
25354 tmp1 = gen_reg_rtx (DImode);
25355 emit_insn (gen_popcntbdi2 (tmp1, src));
25357 tmp2 = gen_reg_rtx (DImode);
25358 emit_insn (gen_lshrdi3 (tmp2, tmp1, GEN_INT (32)));
25359 tmp3 = gen_reg_rtx (DImode);
25360 emit_insn (gen_xordi3 (tmp3, tmp1, tmp2));
25362 tmp4 = gen_reg_rtx (DImode);
25363 emit_insn (gen_lshrdi3 (tmp4, tmp3, GEN_INT (16)));
25364 tmp5 = gen_reg_rtx (DImode);
25365 emit_insn (gen_xordi3 (tmp5, tmp3, tmp4));
25367 tmp6 = gen_reg_rtx (DImode);
25368 emit_insn (gen_lshrdi3 (tmp6, tmp5, GEN_INT (8)));
25369 emit_insn (gen_xordi3 (tmp, tmp5, tmp6));
25371 else
25372 rs6000_emit_popcount (tmp, src);
25373 emit_insn (gen_anddi3 (dst, tmp, const1_rtx));
25377 /* Return an RTX representing where to find the function value of a
25378 function returning MODE. */
25379 static rtx
25380 rs6000_complex_function_value (enum machine_mode mode)
25382 unsigned int regno;
25383 rtx r1, r2;
25384 enum machine_mode inner = GET_MODE_INNER (mode);
25385 unsigned int inner_bytes = GET_MODE_SIZE (inner);
25387 if (FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
25388 regno = FP_ARG_RETURN;
25389 else
25391 regno = GP_ARG_RETURN;
25393 /* 32-bit is OK since it'll go in r3/r4. */
25394 if (TARGET_32BIT && inner_bytes >= 4)
25395 return gen_rtx_REG (mode, regno);
25398 if (inner_bytes >= 8)
25399 return gen_rtx_REG (mode, regno);
25401 r1 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno),
25402 const0_rtx);
25403 r2 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno + 1),
25404 GEN_INT (inner_bytes));
25405 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
25408 /* Target hook for TARGET_FUNCTION_VALUE.
25410 On the SPE, both FPs and vectors are returned in r3.
25412 On RS/6000 an integer value is in r3 and a floating-point value is in
25413 fp1, unless -msoft-float. */
25416 rs6000_function_value (const_tree valtype,
25417 const_tree fn_decl_or_type ATTRIBUTE_UNUSED,
25418 bool outgoing ATTRIBUTE_UNUSED)
25420 enum machine_mode mode;
25421 unsigned int regno;
25423 /* Special handling for structs in darwin64. */
25424 if (rs6000_darwin64_abi
25425 && TYPE_MODE (valtype) == BLKmode
25426 && TREE_CODE (valtype) == RECORD_TYPE
25427 && int_size_in_bytes (valtype) > 0)
25429 CUMULATIVE_ARGS valcum;
25430 rtx valret;
25432 valcum.words = 0;
25433 valcum.fregno = FP_ARG_MIN_REG;
25434 valcum.vregno = ALTIVEC_ARG_MIN_REG;
25435 /* Do a trial code generation as if this were going to be passed as
25436 an argument; if any part goes in memory, we return NULL. */
25437 valret = rs6000_darwin64_record_arg (&valcum, valtype, 1, true);
25438 if (valret)
25439 return valret;
25440 /* Otherwise fall through to standard ABI rules. */
25443 if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DImode)
25445 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
25446 return gen_rtx_PARALLEL (DImode,
25447 gen_rtvec (2,
25448 gen_rtx_EXPR_LIST (VOIDmode,
25449 gen_rtx_REG (SImode, GP_ARG_RETURN),
25450 const0_rtx),
25451 gen_rtx_EXPR_LIST (VOIDmode,
25452 gen_rtx_REG (SImode,
25453 GP_ARG_RETURN + 1),
25454 GEN_INT (4))));
25456 if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DCmode)
25458 return gen_rtx_PARALLEL (DCmode,
25459 gen_rtvec (4,
25460 gen_rtx_EXPR_LIST (VOIDmode,
25461 gen_rtx_REG (SImode, GP_ARG_RETURN),
25462 const0_rtx),
25463 gen_rtx_EXPR_LIST (VOIDmode,
25464 gen_rtx_REG (SImode,
25465 GP_ARG_RETURN + 1),
25466 GEN_INT (4)),
25467 gen_rtx_EXPR_LIST (VOIDmode,
25468 gen_rtx_REG (SImode,
25469 GP_ARG_RETURN + 2),
25470 GEN_INT (8)),
25471 gen_rtx_EXPR_LIST (VOIDmode,
25472 gen_rtx_REG (SImode,
25473 GP_ARG_RETURN + 3),
25474 GEN_INT (12))));
25477 mode = TYPE_MODE (valtype);
25478 if ((INTEGRAL_TYPE_P (valtype) && GET_MODE_BITSIZE (mode) < BITS_PER_WORD)
25479 || POINTER_TYPE_P (valtype))
25480 mode = TARGET_32BIT ? SImode : DImode;
25482 if (DECIMAL_FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
25483 /* _Decimal128 must use an even/odd register pair. */
25484 regno = (mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN;
25485 else if (SCALAR_FLOAT_TYPE_P (valtype) && TARGET_HARD_FLOAT && TARGET_FPRS
25486 && ((TARGET_SINGLE_FLOAT && (mode == SFmode)) || TARGET_DOUBLE_FLOAT))
25487 regno = FP_ARG_RETURN;
25488 else if (TREE_CODE (valtype) == COMPLEX_TYPE
25489 && targetm.calls.split_complex_arg)
25490 return rs6000_complex_function_value (mode);
25491 else if (TREE_CODE (valtype) == VECTOR_TYPE
25492 && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI
25493 && ALTIVEC_VECTOR_MODE (mode))
25494 regno = ALTIVEC_ARG_RETURN;
25495 else if (TREE_CODE (valtype) == VECTOR_TYPE
25496 && TARGET_VSX && TARGET_ALTIVEC_ABI
25497 && VSX_VECTOR_MODE (mode))
25498 regno = ALTIVEC_ARG_RETURN;
25499 else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
25500 && (mode == DFmode || mode == DCmode
25501 || mode == TFmode || mode == TCmode))
25502 return spe_build_register_parallel (mode, GP_ARG_RETURN);
25503 else
25504 regno = GP_ARG_RETURN;
25506 return gen_rtx_REG (mode, regno);
25509 /* Define how to find the value returned by a library function
25510 assuming the value has mode MODE. */
25512 rs6000_libcall_value (enum machine_mode mode)
25514 unsigned int regno;
25516 if (TARGET_32BIT && TARGET_POWERPC64 && mode == DImode)
25518 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
25519 return gen_rtx_PARALLEL (DImode,
25520 gen_rtvec (2,
25521 gen_rtx_EXPR_LIST (VOIDmode,
25522 gen_rtx_REG (SImode, GP_ARG_RETURN),
25523 const0_rtx),
25524 gen_rtx_EXPR_LIST (VOIDmode,
25525 gen_rtx_REG (SImode,
25526 GP_ARG_RETURN + 1),
25527 GEN_INT (4))));
25530 if (DECIMAL_FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
25531 /* _Decimal128 must use an even/odd register pair. */
25532 regno = (mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN;
25533 else if (SCALAR_FLOAT_MODE_P (mode)
25534 && TARGET_HARD_FLOAT && TARGET_FPRS
25535 && ((TARGET_SINGLE_FLOAT && mode == SFmode) || TARGET_DOUBLE_FLOAT))
25536 regno = FP_ARG_RETURN;
25537 else if (ALTIVEC_VECTOR_MODE (mode)
25538 && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI)
25539 regno = ALTIVEC_ARG_RETURN;
25540 else if (VSX_VECTOR_MODE (mode)
25541 && TARGET_VSX && TARGET_ALTIVEC_ABI)
25542 regno = ALTIVEC_ARG_RETURN;
25543 else if (COMPLEX_MODE_P (mode) && targetm.calls.split_complex_arg)
25544 return rs6000_complex_function_value (mode);
25545 else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
25546 && (mode == DFmode || mode == DCmode
25547 || mode == TFmode || mode == TCmode))
25548 return spe_build_register_parallel (mode, GP_ARG_RETURN);
25549 else
25550 regno = GP_ARG_RETURN;
25552 return gen_rtx_REG (mode, regno);
25556 /* Given FROM and TO register numbers, say whether this elimination is allowed.
25557 Frame pointer elimination is automatically handled.
25559 For the RS/6000, if frame pointer elimination is being done, we would like
25560 to convert ap into fp, not sp.
25562 We need r30 if -mminimal-toc was specified, and there are constant pool
25563 references. */
25565 bool
25566 rs6000_can_eliminate (const int from, const int to)
25568 return (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM
25569 ? ! frame_pointer_needed
25570 : from == RS6000_PIC_OFFSET_TABLE_REGNUM
25571 ? ! TARGET_MINIMAL_TOC || TARGET_NO_TOC || get_pool_size () == 0
25572 : true);
25575 /* Define the offset between two registers, FROM to be eliminated and its
25576 replacement TO, at the start of a routine. */
25577 HOST_WIDE_INT
25578 rs6000_initial_elimination_offset (int from, int to)
25580 rs6000_stack_t *info = rs6000_stack_info ();
25581 HOST_WIDE_INT offset;
25583 if (from == HARD_FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
25584 offset = info->push_p ? 0 : -info->total_size;
25585 else if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
25587 offset = info->push_p ? 0 : -info->total_size;
25588 if (FRAME_GROWS_DOWNWARD)
25589 offset += info->fixed_size + info->vars_size + info->parm_size;
25591 else if (from == FRAME_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
25592 offset = FRAME_GROWS_DOWNWARD
25593 ? info->fixed_size + info->vars_size + info->parm_size
25594 : 0;
25595 else if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
25596 offset = info->total_size;
25597 else if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
25598 offset = info->push_p ? info->total_size : 0;
25599 else if (from == RS6000_PIC_OFFSET_TABLE_REGNUM)
25600 offset = 0;
25601 else
25602 gcc_unreachable ();
25604 return offset;
25607 static rtx
25608 rs6000_dwarf_register_span (rtx reg)
25610 rtx parts[8];
25611 int i, words;
25612 unsigned regno = REGNO (reg);
25613 enum machine_mode mode = GET_MODE (reg);
25615 if (TARGET_SPE
25616 && regno < 32
25617 && (SPE_VECTOR_MODE (GET_MODE (reg))
25618 || (TARGET_E500_DOUBLE && FLOAT_MODE_P (mode)
25619 && mode != SFmode && mode != SDmode && mode != SCmode)))
25621 else
25622 return NULL_RTX;
25624 regno = REGNO (reg);
25626 /* The duality of the SPE register size wreaks all kinds of havoc.
25627 This is a way of distinguishing r0 in 32-bits from r0 in
25628 64-bits. */
25629 words = (GET_MODE_SIZE (mode) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD;
25630 gcc_assert (words <= 4);
25631 for (i = 0; i < words; i++, regno++)
25633 if (BYTES_BIG_ENDIAN)
25635 parts[2 * i] = gen_rtx_REG (SImode, regno + 1200);
25636 parts[2 * i + 1] = gen_rtx_REG (SImode, regno);
25638 else
25640 parts[2 * i] = gen_rtx_REG (SImode, regno);
25641 parts[2 * i + 1] = gen_rtx_REG (SImode, regno + 1200);
25645 return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (words * 2, parts));
25648 /* Fill in sizes for SPE register high parts in table used by unwinder. */
25650 static void
25651 rs6000_init_dwarf_reg_sizes_extra (tree address)
25653 if (TARGET_SPE)
25655 int i;
25656 enum machine_mode mode = TYPE_MODE (char_type_node);
25657 rtx addr = expand_expr (address, NULL_RTX, VOIDmode, EXPAND_NORMAL);
25658 rtx mem = gen_rtx_MEM (BLKmode, addr);
25659 rtx value = gen_int_mode (4, mode);
25661 for (i = 1201; i < 1232; i++)
25663 int column = DWARF_REG_TO_UNWIND_COLUMN (i);
25664 HOST_WIDE_INT offset
25665 = DWARF_FRAME_REGNUM (column) * GET_MODE_SIZE (mode);
25667 emit_move_insn (adjust_address (mem, mode, offset), value);
25672 /* Map internal gcc register numbers to DWARF2 register numbers. */
25674 unsigned int
25675 rs6000_dbx_register_number (unsigned int regno)
25677 if (regno <= 63 || write_symbols != DWARF2_DEBUG)
25678 return regno;
25679 if (regno == MQ_REGNO)
25680 return 100;
25681 if (regno == LR_REGNO)
25682 return 108;
25683 if (regno == CTR_REGNO)
25684 return 109;
25685 if (CR_REGNO_P (regno))
25686 return regno - CR0_REGNO + 86;
25687 if (regno == XER_REGNO)
25688 return 101;
25689 if (ALTIVEC_REGNO_P (regno))
25690 return regno - FIRST_ALTIVEC_REGNO + 1124;
25691 if (regno == VRSAVE_REGNO)
25692 return 356;
25693 if (regno == VSCR_REGNO)
25694 return 67;
25695 if (regno == SPE_ACC_REGNO)
25696 return 99;
25697 if (regno == SPEFSCR_REGNO)
25698 return 612;
25699 /* SPE high reg number. We get these values of regno from
25700 rs6000_dwarf_register_span. */
25701 gcc_assert (regno >= 1200 && regno < 1232);
25702 return regno;
25705 /* target hook eh_return_filter_mode */
25706 static enum machine_mode
25707 rs6000_eh_return_filter_mode (void)
25709 return TARGET_32BIT ? SImode : word_mode;
25712 /* Target hook for scalar_mode_supported_p. */
25713 static bool
25714 rs6000_scalar_mode_supported_p (enum machine_mode mode)
25716 if (DECIMAL_FLOAT_MODE_P (mode))
25717 return default_decimal_float_supported_p ();
25718 else
25719 return default_scalar_mode_supported_p (mode);
25722 /* Target hook for vector_mode_supported_p. */
25723 static bool
25724 rs6000_vector_mode_supported_p (enum machine_mode mode)
25727 if (TARGET_PAIRED_FLOAT && PAIRED_VECTOR_MODE (mode))
25728 return true;
25730 if (TARGET_SPE && SPE_VECTOR_MODE (mode))
25731 return true;
25733 else if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode))
25734 return true;
25736 else
25737 return false;
25740 /* Target hook for invalid_arg_for_unprototyped_fn. */
25741 static const char *
25742 invalid_arg_for_unprototyped_fn (const_tree typelist, const_tree funcdecl, const_tree val)
25744 return (!rs6000_darwin64_abi
25745 && typelist == 0
25746 && TREE_CODE (TREE_TYPE (val)) == VECTOR_TYPE
25747 && (funcdecl == NULL_TREE
25748 || (TREE_CODE (funcdecl) == FUNCTION_DECL
25749 && DECL_BUILT_IN_CLASS (funcdecl) != BUILT_IN_MD)))
25750 ? N_("AltiVec argument passed to unprototyped function")
25751 : NULL;
25754 /* For TARGET_SECURE_PLT 32-bit PIC code we can save PIC register
25755 setup by using __stack_chk_fail_local hidden function instead of
25756 calling __stack_chk_fail directly. Otherwise it is better to call
25757 __stack_chk_fail directly. */
25759 static tree
25760 rs6000_stack_protect_fail (void)
25762 return (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
25763 ? default_hidden_stack_protect_fail ()
25764 : default_external_stack_protect_fail ();
25767 void
25768 rs6000_final_prescan_insn (rtx insn, rtx *operand ATTRIBUTE_UNUSED,
25769 int num_operands ATTRIBUTE_UNUSED)
25771 if (rs6000_warn_cell_microcode)
25773 const char *temp;
25774 int insn_code_number = recog_memoized (insn);
25775 location_t location = locator_location (INSN_LOCATOR (insn));
25777 /* Punt on insns we cannot recognize. */
25778 if (insn_code_number < 0)
25779 return;
25781 temp = get_insn_template (insn_code_number, insn);
25783 if (get_attr_cell_micro (insn) == CELL_MICRO_ALWAYS)
25784 warning_at (location, OPT_mwarn_cell_microcode,
25785 "emitting microcode insn %s\t[%s] #%d",
25786 temp, insn_data[INSN_CODE (insn)].name, INSN_UID (insn));
25787 else if (get_attr_cell_micro (insn) == CELL_MICRO_CONDITIONAL)
25788 warning_at (location, OPT_mwarn_cell_microcode,
25789 "emitting conditional microcode insn %s\t[%s] #%d",
25790 temp, insn_data[INSN_CODE (insn)].name, INSN_UID (insn));
25794 #include "gt-rs6000.h"