Fix PR target/43154
[official-gcc.git] / gcc / config / rs6000 / rs6000.c
blob7bcc0866887ea72f5f6dba6b1d841b11cb7e49c6
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 (unsigned int, 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 #define SET_PROFILE_KERNEL(N)
1273 #else
1274 #define SET_PROFILE_KERNEL(N) TARGET_PROFILE_KERNEL = (N)
1275 #endif
1277 /* The VRSAVE bitmask puts bit %v0 as the most significant bit. */
1278 #define ALTIVEC_REG_BIT(REGNO) (0x80000000 >> ((REGNO) - FIRST_ALTIVEC_REGNO))
1280 /* Initialize the GCC target structure. */
1281 #undef TARGET_ATTRIBUTE_TABLE
1282 #define TARGET_ATTRIBUTE_TABLE rs6000_attribute_table
1283 #undef TARGET_SET_DEFAULT_TYPE_ATTRIBUTES
1284 #define TARGET_SET_DEFAULT_TYPE_ATTRIBUTES rs6000_set_default_type_attributes
1286 #undef TARGET_ASM_ALIGNED_DI_OP
1287 #define TARGET_ASM_ALIGNED_DI_OP DOUBLE_INT_ASM_OP
1289 /* Default unaligned ops are only provided for ELF. Find the ops needed
1290 for non-ELF systems. */
1291 #ifndef OBJECT_FORMAT_ELF
1292 #if TARGET_XCOFF
1293 /* For XCOFF. rs6000_assemble_integer will handle unaligned DIs on
1294 64-bit targets. */
1295 #undef TARGET_ASM_UNALIGNED_HI_OP
1296 #define TARGET_ASM_UNALIGNED_HI_OP "\t.vbyte\t2,"
1297 #undef TARGET_ASM_UNALIGNED_SI_OP
1298 #define TARGET_ASM_UNALIGNED_SI_OP "\t.vbyte\t4,"
1299 #undef TARGET_ASM_UNALIGNED_DI_OP
1300 #define TARGET_ASM_UNALIGNED_DI_OP "\t.vbyte\t8,"
1301 #else
1302 /* For Darwin. */
1303 #undef TARGET_ASM_UNALIGNED_HI_OP
1304 #define TARGET_ASM_UNALIGNED_HI_OP "\t.short\t"
1305 #undef TARGET_ASM_UNALIGNED_SI_OP
1306 #define TARGET_ASM_UNALIGNED_SI_OP "\t.long\t"
1307 #undef TARGET_ASM_UNALIGNED_DI_OP
1308 #define TARGET_ASM_UNALIGNED_DI_OP "\t.quad\t"
1309 #undef TARGET_ASM_ALIGNED_DI_OP
1310 #define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t"
1311 #endif
1312 #endif
1314 /* This hook deals with fixups for relocatable code and DI-mode objects
1315 in 64-bit code. */
1316 #undef TARGET_ASM_INTEGER
1317 #define TARGET_ASM_INTEGER rs6000_assemble_integer
1319 #ifdef HAVE_GAS_HIDDEN
1320 #undef TARGET_ASM_ASSEMBLE_VISIBILITY
1321 #define TARGET_ASM_ASSEMBLE_VISIBILITY rs6000_assemble_visibility
1322 #endif
1324 #undef TARGET_HAVE_TLS
1325 #define TARGET_HAVE_TLS HAVE_AS_TLS
1327 #undef TARGET_CANNOT_FORCE_CONST_MEM
1328 #define TARGET_CANNOT_FORCE_CONST_MEM rs6000_tls_referenced_p
1330 #undef TARGET_DELEGITIMIZE_ADDRESS
1331 #define TARGET_DELEGITIMIZE_ADDRESS rs6000_delegitimize_address
1333 #undef TARGET_ASM_FUNCTION_PROLOGUE
1334 #define TARGET_ASM_FUNCTION_PROLOGUE rs6000_output_function_prologue
1335 #undef TARGET_ASM_FUNCTION_EPILOGUE
1336 #define TARGET_ASM_FUNCTION_EPILOGUE rs6000_output_function_epilogue
1338 #undef TARGET_LEGITIMIZE_ADDRESS
1339 #define TARGET_LEGITIMIZE_ADDRESS rs6000_legitimize_address
1341 #undef TARGET_SCHED_VARIABLE_ISSUE
1342 #define TARGET_SCHED_VARIABLE_ISSUE rs6000_variable_issue
1344 #undef TARGET_SCHED_ISSUE_RATE
1345 #define TARGET_SCHED_ISSUE_RATE rs6000_issue_rate
1346 #undef TARGET_SCHED_ADJUST_COST
1347 #define TARGET_SCHED_ADJUST_COST rs6000_adjust_cost
1348 #undef TARGET_SCHED_ADJUST_PRIORITY
1349 #define TARGET_SCHED_ADJUST_PRIORITY rs6000_adjust_priority
1350 #undef TARGET_SCHED_IS_COSTLY_DEPENDENCE
1351 #define TARGET_SCHED_IS_COSTLY_DEPENDENCE rs6000_is_costly_dependence
1352 #undef TARGET_SCHED_INIT
1353 #define TARGET_SCHED_INIT rs6000_sched_init
1354 #undef TARGET_SCHED_FINISH
1355 #define TARGET_SCHED_FINISH rs6000_sched_finish
1356 #undef TARGET_SCHED_REORDER
1357 #define TARGET_SCHED_REORDER rs6000_sched_reorder
1358 #undef TARGET_SCHED_REORDER2
1359 #define TARGET_SCHED_REORDER2 rs6000_sched_reorder2
1361 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
1362 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD rs6000_use_sched_lookahead
1364 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD
1365 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD rs6000_use_sched_lookahead_guard
1367 #undef TARGET_SCHED_ALLOC_SCHED_CONTEXT
1368 #define TARGET_SCHED_ALLOC_SCHED_CONTEXT rs6000_alloc_sched_context
1369 #undef TARGET_SCHED_INIT_SCHED_CONTEXT
1370 #define TARGET_SCHED_INIT_SCHED_CONTEXT rs6000_init_sched_context
1371 #undef TARGET_SCHED_SET_SCHED_CONTEXT
1372 #define TARGET_SCHED_SET_SCHED_CONTEXT rs6000_set_sched_context
1373 #undef TARGET_SCHED_FREE_SCHED_CONTEXT
1374 #define TARGET_SCHED_FREE_SCHED_CONTEXT rs6000_free_sched_context
1376 #undef TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD
1377 #define TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD rs6000_builtin_mask_for_load
1378 #undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN
1379 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN rs6000_builtin_mul_widen_even
1380 #undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD
1381 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD rs6000_builtin_mul_widen_odd
1382 #undef TARGET_VECTORIZE_BUILTIN_CONVERSION
1383 #define TARGET_VECTORIZE_BUILTIN_CONVERSION rs6000_builtin_conversion
1384 #undef TARGET_VECTORIZE_BUILTIN_VEC_PERM
1385 #define TARGET_VECTORIZE_BUILTIN_VEC_PERM rs6000_builtin_vec_perm
1386 #undef TARGET_SUPPORT_VECTOR_MISALIGNMENT
1387 #define TARGET_SUPPORT_VECTOR_MISALIGNMENT \
1388 rs6000_builtin_support_vector_misalignment
1389 #undef TARGET_VECTOR_ALIGNMENT_REACHABLE
1390 #define TARGET_VECTOR_ALIGNMENT_REACHABLE rs6000_vector_alignment_reachable
1392 #undef TARGET_INIT_BUILTINS
1393 #define TARGET_INIT_BUILTINS rs6000_init_builtins
1394 #undef TARGET_BUILTIN_DECL
1395 #define TARGET_BUILTIN_DECL rs6000_builtin_decl
1397 #undef TARGET_EXPAND_BUILTIN
1398 #define TARGET_EXPAND_BUILTIN rs6000_expand_builtin
1400 #undef TARGET_MANGLE_TYPE
1401 #define TARGET_MANGLE_TYPE rs6000_mangle_type
1403 #undef TARGET_INIT_LIBFUNCS
1404 #define TARGET_INIT_LIBFUNCS rs6000_init_libfuncs
1406 #if TARGET_MACHO
1407 #undef TARGET_BINDS_LOCAL_P
1408 #define TARGET_BINDS_LOCAL_P darwin_binds_local_p
1409 #endif
1411 #undef TARGET_MS_BITFIELD_LAYOUT_P
1412 #define TARGET_MS_BITFIELD_LAYOUT_P rs6000_ms_bitfield_layout_p
1414 #undef TARGET_ASM_OUTPUT_MI_THUNK
1415 #define TARGET_ASM_OUTPUT_MI_THUNK rs6000_output_mi_thunk
1417 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
1418 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true
1420 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
1421 #define TARGET_FUNCTION_OK_FOR_SIBCALL rs6000_function_ok_for_sibcall
1423 #undef TARGET_INVALID_WITHIN_DOLOOP
1424 #define TARGET_INVALID_WITHIN_DOLOOP rs6000_invalid_within_doloop
1426 #undef TARGET_RTX_COSTS
1427 #define TARGET_RTX_COSTS rs6000_rtx_costs
1428 #undef TARGET_ADDRESS_COST
1429 #define TARGET_ADDRESS_COST hook_int_rtx_bool_0
1431 #undef TARGET_DWARF_REGISTER_SPAN
1432 #define TARGET_DWARF_REGISTER_SPAN rs6000_dwarf_register_span
1434 #undef TARGET_INIT_DWARF_REG_SIZES_EXTRA
1435 #define TARGET_INIT_DWARF_REG_SIZES_EXTRA rs6000_init_dwarf_reg_sizes_extra
1437 /* On rs6000, function arguments are promoted, as are function return
1438 values. */
1439 #undef TARGET_PROMOTE_FUNCTION_MODE
1440 #define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote
1442 #undef TARGET_RETURN_IN_MEMORY
1443 #define TARGET_RETURN_IN_MEMORY rs6000_return_in_memory
1445 #undef TARGET_SETUP_INCOMING_VARARGS
1446 #define TARGET_SETUP_INCOMING_VARARGS setup_incoming_varargs
1448 /* Always strict argument naming on rs6000. */
1449 #undef TARGET_STRICT_ARGUMENT_NAMING
1450 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
1451 #undef TARGET_PRETEND_OUTGOING_VARARGS_NAMED
1452 #define TARGET_PRETEND_OUTGOING_VARARGS_NAMED hook_bool_CUMULATIVE_ARGS_true
1453 #undef TARGET_SPLIT_COMPLEX_ARG
1454 #define TARGET_SPLIT_COMPLEX_ARG hook_bool_const_tree_true
1455 #undef TARGET_MUST_PASS_IN_STACK
1456 #define TARGET_MUST_PASS_IN_STACK rs6000_must_pass_in_stack
1457 #undef TARGET_PASS_BY_REFERENCE
1458 #define TARGET_PASS_BY_REFERENCE rs6000_pass_by_reference
1459 #undef TARGET_ARG_PARTIAL_BYTES
1460 #define TARGET_ARG_PARTIAL_BYTES rs6000_arg_partial_bytes
1462 #undef TARGET_BUILD_BUILTIN_VA_LIST
1463 #define TARGET_BUILD_BUILTIN_VA_LIST rs6000_build_builtin_va_list
1465 #undef TARGET_EXPAND_BUILTIN_VA_START
1466 #define TARGET_EXPAND_BUILTIN_VA_START rs6000_va_start
1468 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
1469 #define TARGET_GIMPLIFY_VA_ARG_EXPR rs6000_gimplify_va_arg
1471 #undef TARGET_EH_RETURN_FILTER_MODE
1472 #define TARGET_EH_RETURN_FILTER_MODE rs6000_eh_return_filter_mode
1474 #undef TARGET_SCALAR_MODE_SUPPORTED_P
1475 #define TARGET_SCALAR_MODE_SUPPORTED_P rs6000_scalar_mode_supported_p
1477 #undef TARGET_VECTOR_MODE_SUPPORTED_P
1478 #define TARGET_VECTOR_MODE_SUPPORTED_P rs6000_vector_mode_supported_p
1480 #undef TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN
1481 #define TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN invalid_arg_for_unprototyped_fn
1483 #undef TARGET_HANDLE_OPTION
1484 #define TARGET_HANDLE_OPTION rs6000_handle_option
1486 #undef TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION
1487 #define TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION \
1488 rs6000_builtin_vectorized_function
1490 #undef TARGET_DEFAULT_TARGET_FLAGS
1491 #define TARGET_DEFAULT_TARGET_FLAGS \
1492 (TARGET_DEFAULT)
1494 #undef TARGET_STACK_PROTECT_FAIL
1495 #define TARGET_STACK_PROTECT_FAIL rs6000_stack_protect_fail
1497 /* MPC604EUM 3.5.2 Weak Consistency between Multiple Processors
1498 The PowerPC architecture requires only weak consistency among
1499 processors--that is, memory accesses between processors need not be
1500 sequentially consistent and memory accesses among processors can occur
1501 in any order. The ability to order memory accesses weakly provides
1502 opportunities for more efficient use of the system bus. Unless a
1503 dependency exists, the 604e allows read operations to precede store
1504 operations. */
1505 #undef TARGET_RELAXED_ORDERING
1506 #define TARGET_RELAXED_ORDERING true
1508 #ifdef HAVE_AS_TLS
1509 #undef TARGET_ASM_OUTPUT_DWARF_DTPREL
1510 #define TARGET_ASM_OUTPUT_DWARF_DTPREL rs6000_output_dwarf_dtprel
1511 #endif
1513 /* Use a 32-bit anchor range. This leads to sequences like:
1515 addis tmp,anchor,high
1516 add dest,tmp,low
1518 where tmp itself acts as an anchor, and can be shared between
1519 accesses to the same 64k page. */
1520 #undef TARGET_MIN_ANCHOR_OFFSET
1521 #define TARGET_MIN_ANCHOR_OFFSET -0x7fffffff - 1
1522 #undef TARGET_MAX_ANCHOR_OFFSET
1523 #define TARGET_MAX_ANCHOR_OFFSET 0x7fffffff
1524 #undef TARGET_USE_BLOCKS_FOR_CONSTANT_P
1525 #define TARGET_USE_BLOCKS_FOR_CONSTANT_P rs6000_use_blocks_for_constant_p
1527 #undef TARGET_BUILTIN_RECIPROCAL
1528 #define TARGET_BUILTIN_RECIPROCAL rs6000_builtin_reciprocal
1530 #undef TARGET_EXPAND_TO_RTL_HOOK
1531 #define TARGET_EXPAND_TO_RTL_HOOK rs6000_alloc_sdmode_stack_slot
1533 #undef TARGET_INSTANTIATE_DECLS
1534 #define TARGET_INSTANTIATE_DECLS rs6000_instantiate_decls
1536 #undef TARGET_SECONDARY_RELOAD
1537 #define TARGET_SECONDARY_RELOAD rs6000_secondary_reload
1539 #undef TARGET_IRA_COVER_CLASSES
1540 #define TARGET_IRA_COVER_CLASSES rs6000_ira_cover_classes
1542 #undef TARGET_LEGITIMATE_ADDRESS_P
1543 #define TARGET_LEGITIMATE_ADDRESS_P rs6000_legitimate_address_p
1545 #undef TARGET_CAN_ELIMINATE
1546 #define TARGET_CAN_ELIMINATE rs6000_can_eliminate
1548 #undef TARGET_TRAMPOLINE_INIT
1549 #define TARGET_TRAMPOLINE_INIT rs6000_trampoline_init
1551 #undef TARGET_FUNCTION_VALUE
1552 #define TARGET_FUNCTION_VALUE rs6000_function_value
1554 struct gcc_target targetm = TARGET_INITIALIZER;
1556 /* Return number of consecutive hard regs needed starting at reg REGNO
1557 to hold something of mode MODE.
1558 This is ordinarily the length in words of a value of mode MODE
1559 but can be less for certain modes in special long registers.
1561 For the SPE, GPRs are 64 bits but only 32 bits are visible in
1562 scalar instructions. The upper 32 bits are only available to the
1563 SIMD instructions.
1565 POWER and PowerPC GPRs hold 32 bits worth;
1566 PowerPC64 GPRs and FPRs point register holds 64 bits worth. */
1568 static int
1569 rs6000_hard_regno_nregs_internal (int regno, enum machine_mode mode)
1571 unsigned HOST_WIDE_INT reg_size;
1573 if (FP_REGNO_P (regno))
1574 reg_size = (VECTOR_MEM_VSX_P (mode)
1575 ? UNITS_PER_VSX_WORD
1576 : UNITS_PER_FP_WORD);
1578 else if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode))
1579 reg_size = UNITS_PER_SPE_WORD;
1581 else if (ALTIVEC_REGNO_P (regno))
1582 reg_size = UNITS_PER_ALTIVEC_WORD;
1584 /* The value returned for SCmode in the E500 double case is 2 for
1585 ABI compatibility; storing an SCmode value in a single register
1586 would require function_arg and rs6000_spe_function_arg to handle
1587 SCmode so as to pass the value correctly in a pair of
1588 registers. */
1589 else if (TARGET_E500_DOUBLE && FLOAT_MODE_P (mode) && mode != SCmode
1590 && !DECIMAL_FLOAT_MODE_P (mode))
1591 reg_size = UNITS_PER_FP_WORD;
1593 else
1594 reg_size = UNITS_PER_WORD;
1596 return (GET_MODE_SIZE (mode) + reg_size - 1) / reg_size;
1599 /* Value is 1 if hard register REGNO can hold a value of machine-mode
1600 MODE. */
1601 static int
1602 rs6000_hard_regno_mode_ok (int regno, enum machine_mode mode)
1604 int last_regno = regno + rs6000_hard_regno_nregs[mode][regno] - 1;
1606 /* VSX registers that overlap the FPR registers are larger than for non-VSX
1607 implementations. Don't allow an item to be split between a FP register
1608 and an Altivec register. */
1609 if (VECTOR_MEM_VSX_P (mode))
1611 if (FP_REGNO_P (regno))
1612 return FP_REGNO_P (last_regno);
1614 if (ALTIVEC_REGNO_P (regno))
1615 return ALTIVEC_REGNO_P (last_regno);
1618 /* The GPRs can hold any mode, but values bigger than one register
1619 cannot go past R31. */
1620 if (INT_REGNO_P (regno))
1621 return INT_REGNO_P (last_regno);
1623 /* The float registers (except for VSX vector modes) can only hold floating
1624 modes and DImode. This excludes the 32-bit decimal float mode for
1625 now. */
1626 if (FP_REGNO_P (regno))
1628 if (SCALAR_FLOAT_MODE_P (mode)
1629 && (mode != TDmode || (regno % 2) == 0)
1630 && FP_REGNO_P (last_regno))
1631 return 1;
1633 if (GET_MODE_CLASS (mode) == MODE_INT
1634 && GET_MODE_SIZE (mode) == UNITS_PER_FP_WORD)
1635 return 1;
1637 if (PAIRED_SIMD_REGNO_P (regno) && TARGET_PAIRED_FLOAT
1638 && PAIRED_VECTOR_MODE (mode))
1639 return 1;
1641 return 0;
1644 /* The CR register can only hold CC modes. */
1645 if (CR_REGNO_P (regno))
1646 return GET_MODE_CLASS (mode) == MODE_CC;
1648 if (XER_REGNO_P (regno))
1649 return mode == PSImode;
1651 /* AltiVec only in AldyVec registers. */
1652 if (ALTIVEC_REGNO_P (regno))
1653 return VECTOR_MEM_ALTIVEC_OR_VSX_P (mode);
1655 /* ...but GPRs can hold SIMD data on the SPE in one register. */
1656 if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode))
1657 return 1;
1659 /* We cannot put TImode anywhere except general register and it must be able
1660 to fit within the register set. In the future, allow TImode in the
1661 Altivec or VSX registers. */
1663 return GET_MODE_SIZE (mode) <= UNITS_PER_WORD;
1666 /* Print interesting facts about registers. */
1667 static void
1668 rs6000_debug_reg_print (int first_regno, int last_regno, const char *reg_name)
1670 int r, m;
1672 for (r = first_regno; r <= last_regno; ++r)
1674 const char *comma = "";
1675 int len;
1677 if (first_regno == last_regno)
1678 fprintf (stderr, "%s:\t", reg_name);
1679 else
1680 fprintf (stderr, "%s%d:\t", reg_name, r - first_regno);
1682 len = 8;
1683 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1684 if (rs6000_hard_regno_mode_ok_p[m][r] && rs6000_hard_regno_nregs[m][r])
1686 if (len > 70)
1688 fprintf (stderr, ",\n\t");
1689 len = 8;
1690 comma = "";
1693 if (rs6000_hard_regno_nregs[m][r] > 1)
1694 len += fprintf (stderr, "%s%s/%d", comma, GET_MODE_NAME (m),
1695 rs6000_hard_regno_nregs[m][r]);
1696 else
1697 len += fprintf (stderr, "%s%s", comma, GET_MODE_NAME (m));
1699 comma = ", ";
1702 if (call_used_regs[r])
1704 if (len > 70)
1706 fprintf (stderr, ",\n\t");
1707 len = 8;
1708 comma = "";
1711 len += fprintf (stderr, "%s%s", comma, "call-used");
1712 comma = ", ";
1715 if (fixed_regs[r])
1717 if (len > 70)
1719 fprintf (stderr, ",\n\t");
1720 len = 8;
1721 comma = "";
1724 len += fprintf (stderr, "%s%s", comma, "fixed");
1725 comma = ", ";
1728 if (len > 70)
1730 fprintf (stderr, ",\n\t");
1731 comma = "";
1734 fprintf (stderr, "%sregno = %d\n", comma, r);
1738 /* Print various interesting information with -mdebug=reg. */
1739 static void
1740 rs6000_debug_reg_global (void)
1742 const char *nl = (const char *)0;
1743 int m;
1744 char costly_num[20];
1745 char nop_num[20];
1746 const char *costly_str;
1747 const char *nop_str;
1749 /* Map enum rs6000_vector to string. */
1750 static const char *rs6000_debug_vector_unit[] = {
1751 "none",
1752 "altivec",
1753 "vsx",
1754 "paired",
1755 "spe",
1756 "other"
1759 fprintf (stderr, "Register information: (last virtual reg = %d)\n",
1760 LAST_VIRTUAL_REGISTER);
1761 rs6000_debug_reg_print (0, 31, "gr");
1762 rs6000_debug_reg_print (32, 63, "fp");
1763 rs6000_debug_reg_print (FIRST_ALTIVEC_REGNO,
1764 LAST_ALTIVEC_REGNO,
1765 "vs");
1766 rs6000_debug_reg_print (LR_REGNO, LR_REGNO, "lr");
1767 rs6000_debug_reg_print (CTR_REGNO, CTR_REGNO, "ctr");
1768 rs6000_debug_reg_print (CR0_REGNO, CR7_REGNO, "cr");
1769 rs6000_debug_reg_print (MQ_REGNO, MQ_REGNO, "mq");
1770 rs6000_debug_reg_print (XER_REGNO, XER_REGNO, "xer");
1771 rs6000_debug_reg_print (VRSAVE_REGNO, VRSAVE_REGNO, "vrsave");
1772 rs6000_debug_reg_print (VSCR_REGNO, VSCR_REGNO, "vscr");
1773 rs6000_debug_reg_print (SPE_ACC_REGNO, SPE_ACC_REGNO, "spe_a");
1774 rs6000_debug_reg_print (SPEFSCR_REGNO, SPEFSCR_REGNO, "spe_f");
1776 fprintf (stderr,
1777 "\n"
1778 "d reg_class = %s\n"
1779 "f reg_class = %s\n"
1780 "v reg_class = %s\n"
1781 "wa reg_class = %s\n"
1782 "wd reg_class = %s\n"
1783 "wf reg_class = %s\n"
1784 "ws reg_class = %s\n\n",
1785 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_d]],
1786 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_f]],
1787 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_v]],
1788 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wa]],
1789 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wd]],
1790 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wf]],
1791 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_ws]]);
1793 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1794 if (rs6000_vector_unit[m] || rs6000_vector_mem[m])
1796 nl = "\n";
1797 fprintf (stderr, "Vector mode: %-5s arithmetic: %-8s move: %-8s\n",
1798 GET_MODE_NAME (m),
1799 rs6000_debug_vector_unit[ rs6000_vector_unit[m] ],
1800 rs6000_debug_vector_unit[ rs6000_vector_mem[m] ]);
1803 if (nl)
1804 fputs (nl, stderr);
1806 switch (rs6000_sched_costly_dep)
1808 case max_dep_latency:
1809 costly_str = "max_dep_latency";
1810 break;
1812 case no_dep_costly:
1813 costly_str = "no_dep_costly";
1814 break;
1816 case all_deps_costly:
1817 costly_str = "all_deps_costly";
1818 break;
1820 case true_store_to_load_dep_costly:
1821 costly_str = "true_store_to_load_dep_costly";
1822 break;
1824 case store_to_load_dep_costly:
1825 costly_str = "store_to_load_dep_costly";
1826 break;
1828 default:
1829 costly_str = costly_num;
1830 sprintf (costly_num, "%d", (int)rs6000_sched_costly_dep);
1831 break;
1834 switch (rs6000_sched_insert_nops)
1836 case sched_finish_regroup_exact:
1837 nop_str = "sched_finish_regroup_exact";
1838 break;
1840 case sched_finish_pad_groups:
1841 nop_str = "sched_finish_pad_groups";
1842 break;
1844 case sched_finish_none:
1845 nop_str = "sched_finish_none";
1846 break;
1848 default:
1849 nop_str = nop_num;
1850 sprintf (nop_num, "%d", (int)rs6000_sched_insert_nops);
1851 break;
1854 fprintf (stderr,
1855 "always_hint = %s\n"
1856 "align_branch_targets = %s\n"
1857 "sched_restricted_insns_priority = %d\n"
1858 "sched_costly_dep = %s\n"
1859 "sched_insert_nops = %s\n\n",
1860 rs6000_always_hint ? "true" : "false",
1861 rs6000_align_branch_targets ? "true" : "false",
1862 (int)rs6000_sched_restricted_insns_priority,
1863 costly_str, nop_str);
1866 /* Initialize the various global tables that are based on register size. */
1867 static void
1868 rs6000_init_hard_regno_mode_ok (void)
1870 int r, m, c;
1871 int align64;
1872 int align32;
1874 /* Precalculate REGNO_REG_CLASS. */
1875 rs6000_regno_regclass[0] = GENERAL_REGS;
1876 for (r = 1; r < 32; ++r)
1877 rs6000_regno_regclass[r] = BASE_REGS;
1879 for (r = 32; r < 64; ++r)
1880 rs6000_regno_regclass[r] = FLOAT_REGS;
1882 for (r = 64; r < FIRST_PSEUDO_REGISTER; ++r)
1883 rs6000_regno_regclass[r] = NO_REGS;
1885 for (r = FIRST_ALTIVEC_REGNO; r <= LAST_ALTIVEC_REGNO; ++r)
1886 rs6000_regno_regclass[r] = ALTIVEC_REGS;
1888 rs6000_regno_regclass[CR0_REGNO] = CR0_REGS;
1889 for (r = CR1_REGNO; r <= CR7_REGNO; ++r)
1890 rs6000_regno_regclass[r] = CR_REGS;
1892 rs6000_regno_regclass[MQ_REGNO] = MQ_REGS;
1893 rs6000_regno_regclass[LR_REGNO] = LINK_REGS;
1894 rs6000_regno_regclass[CTR_REGNO] = CTR_REGS;
1895 rs6000_regno_regclass[XER_REGNO] = XER_REGS;
1896 rs6000_regno_regclass[VRSAVE_REGNO] = VRSAVE_REGS;
1897 rs6000_regno_regclass[VSCR_REGNO] = VRSAVE_REGS;
1898 rs6000_regno_regclass[SPE_ACC_REGNO] = SPE_ACC_REGS;
1899 rs6000_regno_regclass[SPEFSCR_REGNO] = SPEFSCR_REGS;
1900 rs6000_regno_regclass[ARG_POINTER_REGNUM] = BASE_REGS;
1901 rs6000_regno_regclass[FRAME_POINTER_REGNUM] = BASE_REGS;
1903 /* Precalculate vector information, this must be set up before the
1904 rs6000_hard_regno_nregs_internal below. */
1905 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1907 rs6000_vector_unit[m] = rs6000_vector_mem[m] = VECTOR_NONE;
1908 rs6000_vector_reload[m][0] = CODE_FOR_nothing;
1909 rs6000_vector_reload[m][1] = CODE_FOR_nothing;
1912 for (c = 0; c < (int)(int)RS6000_CONSTRAINT_MAX; c++)
1913 rs6000_constraints[c] = NO_REGS;
1915 /* The VSX hardware allows native alignment for vectors, but control whether the compiler
1916 believes it can use native alignment or still uses 128-bit alignment. */
1917 if (TARGET_VSX && !TARGET_VSX_ALIGN_128)
1919 align64 = 64;
1920 align32 = 32;
1922 else
1924 align64 = 128;
1925 align32 = 128;
1928 /* V2DF mode, VSX only. */
1929 if (TARGET_VSX)
1931 rs6000_vector_unit[V2DFmode] = VECTOR_VSX;
1932 rs6000_vector_mem[V2DFmode] = VECTOR_VSX;
1933 rs6000_vector_align[V2DFmode] = align64;
1936 /* V4SF mode, either VSX or Altivec. */
1937 if (TARGET_VSX)
1939 rs6000_vector_unit[V4SFmode] = VECTOR_VSX;
1940 rs6000_vector_mem[V4SFmode] = VECTOR_VSX;
1941 rs6000_vector_align[V4SFmode] = align32;
1943 else if (TARGET_ALTIVEC)
1945 rs6000_vector_unit[V4SFmode] = VECTOR_ALTIVEC;
1946 rs6000_vector_mem[V4SFmode] = VECTOR_ALTIVEC;
1947 rs6000_vector_align[V4SFmode] = align32;
1950 /* V16QImode, V8HImode, V4SImode are Altivec only, but possibly do VSX loads
1951 and stores. */
1952 if (TARGET_ALTIVEC)
1954 rs6000_vector_unit[V4SImode] = VECTOR_ALTIVEC;
1955 rs6000_vector_unit[V8HImode] = VECTOR_ALTIVEC;
1956 rs6000_vector_unit[V16QImode] = VECTOR_ALTIVEC;
1957 rs6000_vector_align[V4SImode] = align32;
1958 rs6000_vector_align[V8HImode] = align32;
1959 rs6000_vector_align[V16QImode] = align32;
1961 if (TARGET_VSX)
1963 rs6000_vector_mem[V4SImode] = VECTOR_VSX;
1964 rs6000_vector_mem[V8HImode] = VECTOR_VSX;
1965 rs6000_vector_mem[V16QImode] = VECTOR_VSX;
1967 else
1969 rs6000_vector_mem[V4SImode] = VECTOR_ALTIVEC;
1970 rs6000_vector_mem[V8HImode] = VECTOR_ALTIVEC;
1971 rs6000_vector_mem[V16QImode] = VECTOR_ALTIVEC;
1975 /* V2DImode, only allow under VSX, which can do V2DI insert/splat/extract.
1976 Altivec doesn't have 64-bit support. */
1977 if (TARGET_VSX)
1979 rs6000_vector_mem[V2DImode] = VECTOR_VSX;
1980 rs6000_vector_unit[V2DImode] = VECTOR_NONE;
1981 rs6000_vector_align[V2DImode] = align64;
1984 /* DFmode, see if we want to use the VSX unit. */
1985 if (TARGET_VSX && TARGET_VSX_SCALAR_DOUBLE)
1987 rs6000_vector_unit[DFmode] = VECTOR_VSX;
1988 rs6000_vector_mem[DFmode]
1989 = (TARGET_VSX_SCALAR_MEMORY ? VECTOR_VSX : VECTOR_NONE);
1990 rs6000_vector_align[DFmode] = align64;
1993 /* TODO add SPE and paired floating point vector support. */
1995 /* Register class constaints for the constraints that depend on compile
1996 switches. */
1997 if (TARGET_HARD_FLOAT && TARGET_FPRS)
1998 rs6000_constraints[RS6000_CONSTRAINT_f] = FLOAT_REGS;
2000 if (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
2001 rs6000_constraints[RS6000_CONSTRAINT_d] = FLOAT_REGS;
2003 if (TARGET_VSX)
2005 /* At present, we just use VSX_REGS, but we have different constraints
2006 based on the use, in case we want to fine tune the default register
2007 class used. wa = any VSX register, wf = register class to use for
2008 V4SF, wd = register class to use for V2DF, and ws = register classs to
2009 use for DF scalars. */
2010 rs6000_constraints[RS6000_CONSTRAINT_wa] = VSX_REGS;
2011 rs6000_constraints[RS6000_CONSTRAINT_wf] = VSX_REGS;
2012 rs6000_constraints[RS6000_CONSTRAINT_wd] = VSX_REGS;
2013 if (TARGET_VSX_SCALAR_DOUBLE)
2014 rs6000_constraints[RS6000_CONSTRAINT_ws] = VSX_REGS;
2017 if (TARGET_ALTIVEC)
2018 rs6000_constraints[RS6000_CONSTRAINT_v] = ALTIVEC_REGS;
2020 /* Set up the reload helper functions. */
2021 if (TARGET_VSX || TARGET_ALTIVEC)
2023 if (TARGET_64BIT)
2025 rs6000_vector_reload[V16QImode][0] = CODE_FOR_reload_v16qi_di_store;
2026 rs6000_vector_reload[V16QImode][1] = CODE_FOR_reload_v16qi_di_load;
2027 rs6000_vector_reload[V8HImode][0] = CODE_FOR_reload_v8hi_di_store;
2028 rs6000_vector_reload[V8HImode][1] = CODE_FOR_reload_v8hi_di_load;
2029 rs6000_vector_reload[V4SImode][0] = CODE_FOR_reload_v4si_di_store;
2030 rs6000_vector_reload[V4SImode][1] = CODE_FOR_reload_v4si_di_load;
2031 rs6000_vector_reload[V2DImode][0] = CODE_FOR_reload_v2di_di_store;
2032 rs6000_vector_reload[V2DImode][1] = CODE_FOR_reload_v2di_di_load;
2033 rs6000_vector_reload[V4SFmode][0] = CODE_FOR_reload_v4sf_di_store;
2034 rs6000_vector_reload[V4SFmode][1] = CODE_FOR_reload_v4sf_di_load;
2035 rs6000_vector_reload[V2DFmode][0] = CODE_FOR_reload_v2df_di_store;
2036 rs6000_vector_reload[V2DFmode][1] = CODE_FOR_reload_v2df_di_load;
2038 else
2040 rs6000_vector_reload[V16QImode][0] = CODE_FOR_reload_v16qi_si_store;
2041 rs6000_vector_reload[V16QImode][1] = CODE_FOR_reload_v16qi_si_load;
2042 rs6000_vector_reload[V8HImode][0] = CODE_FOR_reload_v8hi_si_store;
2043 rs6000_vector_reload[V8HImode][1] = CODE_FOR_reload_v8hi_si_load;
2044 rs6000_vector_reload[V4SImode][0] = CODE_FOR_reload_v4si_si_store;
2045 rs6000_vector_reload[V4SImode][1] = CODE_FOR_reload_v4si_si_load;
2046 rs6000_vector_reload[V2DImode][0] = CODE_FOR_reload_v2di_si_store;
2047 rs6000_vector_reload[V2DImode][1] = CODE_FOR_reload_v2di_si_load;
2048 rs6000_vector_reload[V4SFmode][0] = CODE_FOR_reload_v4sf_si_store;
2049 rs6000_vector_reload[V4SFmode][1] = CODE_FOR_reload_v4sf_si_load;
2050 rs6000_vector_reload[V2DFmode][0] = CODE_FOR_reload_v2df_si_store;
2051 rs6000_vector_reload[V2DFmode][1] = CODE_FOR_reload_v2df_si_load;
2055 /* Precalculate HARD_REGNO_NREGS. */
2056 for (r = 0; r < FIRST_PSEUDO_REGISTER; ++r)
2057 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2058 rs6000_hard_regno_nregs[m][r]
2059 = rs6000_hard_regno_nregs_internal (r, (enum machine_mode)m);
2061 /* Precalculate HARD_REGNO_MODE_OK. */
2062 for (r = 0; r < FIRST_PSEUDO_REGISTER; ++r)
2063 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2064 if (rs6000_hard_regno_mode_ok (r, (enum machine_mode)m))
2065 rs6000_hard_regno_mode_ok_p[m][r] = true;
2067 /* Precalculate CLASS_MAX_NREGS sizes. */
2068 for (c = 0; c < LIM_REG_CLASSES; ++c)
2070 int reg_size;
2072 if (TARGET_VSX && VSX_REG_CLASS_P (c))
2073 reg_size = UNITS_PER_VSX_WORD;
2075 else if (c == ALTIVEC_REGS)
2076 reg_size = UNITS_PER_ALTIVEC_WORD;
2078 else if (c == FLOAT_REGS)
2079 reg_size = UNITS_PER_FP_WORD;
2081 else
2082 reg_size = UNITS_PER_WORD;
2084 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2085 rs6000_class_max_nregs[m][c]
2086 = (GET_MODE_SIZE (m) + reg_size - 1) / reg_size;
2089 if (TARGET_E500_DOUBLE)
2090 rs6000_class_max_nregs[DFmode][GENERAL_REGS] = 1;
2092 if (TARGET_DEBUG_REG)
2093 rs6000_debug_reg_global ();
2096 #if TARGET_MACHO
2097 /* The Darwin version of SUBTARGET_OVERRIDE_OPTIONS. */
2099 static void
2100 darwin_rs6000_override_options (void)
2102 /* The Darwin ABI always includes AltiVec, can't be (validly) turned
2103 off. */
2104 rs6000_altivec_abi = 1;
2105 TARGET_ALTIVEC_VRSAVE = 1;
2106 if (DEFAULT_ABI == ABI_DARWIN)
2108 if (MACHO_DYNAMIC_NO_PIC_P)
2110 if (flag_pic)
2111 warning (0, "-mdynamic-no-pic overrides -fpic or -fPIC");
2112 flag_pic = 0;
2114 else if (flag_pic == 1)
2116 flag_pic = 2;
2119 if (TARGET_64BIT && ! TARGET_POWERPC64)
2121 target_flags |= MASK_POWERPC64;
2122 warning (0, "-m64 requires PowerPC64 architecture, enabling");
2124 if (flag_mkernel)
2126 rs6000_default_long_calls = 1;
2127 target_flags |= MASK_SOFT_FLOAT;
2130 /* Make -m64 imply -maltivec. Darwin's 64-bit ABI includes
2131 Altivec. */
2132 if (!flag_mkernel && !flag_apple_kext
2133 && TARGET_64BIT
2134 && ! (target_flags_explicit & MASK_ALTIVEC))
2135 target_flags |= MASK_ALTIVEC;
2137 /* Unless the user (not the configurer) has explicitly overridden
2138 it with -mcpu=G3 or -mno-altivec, then 10.5+ targets default to
2139 G4 unless targetting the kernel. */
2140 if (!flag_mkernel
2141 && !flag_apple_kext
2142 && strverscmp (darwin_macosx_version_min, "10.5") >= 0
2143 && ! (target_flags_explicit & MASK_ALTIVEC)
2144 && ! rs6000_select[1].string)
2146 target_flags |= MASK_ALTIVEC;
2149 #endif
2151 /* If not otherwise specified by a target, make 'long double' equivalent to
2152 'double'. */
2154 #ifndef RS6000_DEFAULT_LONG_DOUBLE_SIZE
2155 #define RS6000_DEFAULT_LONG_DOUBLE_SIZE 64
2156 #endif
2158 /* Override command line options. Mostly we process the processor
2159 type and sometimes adjust other TARGET_ options. */
2161 void
2162 rs6000_override_options (const char *default_cpu)
2164 size_t i, j;
2165 struct rs6000_cpu_select *ptr;
2166 int set_masks;
2168 /* Simplifications for entries below. */
2170 enum {
2171 POWERPC_BASE_MASK = MASK_POWERPC | MASK_NEW_MNEMONICS,
2172 POWERPC_7400_MASK = POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_ALTIVEC
2175 /* This table occasionally claims that a processor does not support
2176 a particular feature even though it does, but the feature is slower
2177 than the alternative. Thus, it shouldn't be relied on as a
2178 complete description of the processor's support.
2180 Please keep this list in order, and don't forget to update the
2181 documentation in invoke.texi when adding a new processor or
2182 flag. */
2183 static struct ptt
2185 const char *const name; /* Canonical processor name. */
2186 const enum processor_type processor; /* Processor type enum value. */
2187 const int target_enable; /* Target flags to enable. */
2188 } const processor_target_table[]
2189 = {{"401", PROCESSOR_PPC403, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2190 {"403", PROCESSOR_PPC403,
2191 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_STRICT_ALIGN},
2192 {"405", PROCESSOR_PPC405,
2193 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
2194 {"405fp", PROCESSOR_PPC405,
2195 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
2196 {"440", PROCESSOR_PPC440,
2197 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
2198 {"440fp", PROCESSOR_PPC440,
2199 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
2200 {"464", PROCESSOR_PPC440,
2201 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
2202 {"464fp", PROCESSOR_PPC440,
2203 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
2204 {"476", PROCESSOR_PPC476,
2205 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_PPC_GFXOPT | MASK_MFCRF
2206 | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_MULHW | MASK_DLMZB},
2207 {"476fp", PROCESSOR_PPC476,
2208 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_MFCRF | MASK_POPCNTB
2209 | MASK_FPRND | MASK_CMPB | MASK_MULHW | MASK_DLMZB},
2210 {"505", PROCESSOR_MPCCORE, POWERPC_BASE_MASK},
2211 {"601", PROCESSOR_PPC601,
2212 MASK_POWER | POWERPC_BASE_MASK | MASK_MULTIPLE | MASK_STRING},
2213 {"602", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2214 {"603", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2215 {"603e", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2216 {"604", PROCESSOR_PPC604, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2217 {"604e", PROCESSOR_PPC604e, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2218 {"620", PROCESSOR_PPC620,
2219 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
2220 {"630", PROCESSOR_PPC630,
2221 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
2222 {"740", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2223 {"7400", PROCESSOR_PPC7400, POWERPC_7400_MASK},
2224 {"7450", PROCESSOR_PPC7450, POWERPC_7400_MASK},
2225 {"750", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2226 {"801", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2227 {"821", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2228 {"823", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2229 {"8540", PROCESSOR_PPC8540, POWERPC_BASE_MASK | MASK_STRICT_ALIGN
2230 | MASK_ISEL},
2231 /* 8548 has a dummy entry for now. */
2232 {"8548", PROCESSOR_PPC8540, POWERPC_BASE_MASK | MASK_STRICT_ALIGN
2233 | MASK_ISEL},
2234 {"a2", PROCESSOR_PPCA2,
2235 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64 | MASK_POPCNTB
2236 | MASK_CMPB | MASK_NO_UPDATE },
2237 {"e300c2", PROCESSOR_PPCE300C2, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2238 {"e300c3", PROCESSOR_PPCE300C3, POWERPC_BASE_MASK},
2239 {"e500mc", PROCESSOR_PPCE500MC, POWERPC_BASE_MASK | MASK_PPC_GFXOPT
2240 | MASK_ISEL},
2241 {"e500mc64", PROCESSOR_PPCE500MC64, POWERPC_BASE_MASK | MASK_POWERPC64
2242 | MASK_PPC_GFXOPT | MASK_ISEL},
2243 {"860", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2244 {"970", PROCESSOR_POWER4,
2245 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
2246 {"cell", PROCESSOR_CELL,
2247 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
2248 {"common", PROCESSOR_COMMON, MASK_NEW_MNEMONICS},
2249 {"ec603e", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2250 {"G3", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2251 {"G4", PROCESSOR_PPC7450, POWERPC_7400_MASK},
2252 {"G5", PROCESSOR_POWER4,
2253 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
2254 {"power", PROCESSOR_POWER, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2255 {"power2", PROCESSOR_POWER,
2256 MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING},
2257 {"power3", PROCESSOR_PPC630,
2258 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
2259 {"power4", PROCESSOR_POWER4,
2260 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2261 | MASK_MFCRF},
2262 {"power5", PROCESSOR_POWER5,
2263 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2264 | MASK_MFCRF | MASK_POPCNTB},
2265 {"power5+", PROCESSOR_POWER5,
2266 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2267 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND},
2268 {"power6", 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 {"power6x", PROCESSOR_POWER6,
2272 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2273 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP
2274 | MASK_MFPGPR},
2275 {"power7", PROCESSOR_POWER7,
2276 POWERPC_7400_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_MFCRF
2277 | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP | MASK_POPCNTD
2278 | MASK_VSX}, /* Don't add MASK_ISEL by default */
2279 {"powerpc", PROCESSOR_POWERPC, POWERPC_BASE_MASK},
2280 {"powerpc64", PROCESSOR_POWERPC64,
2281 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
2282 {"rios", PROCESSOR_RIOS1, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2283 {"rios1", PROCESSOR_RIOS1, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2284 {"rios2", PROCESSOR_RIOS2,
2285 MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING},
2286 {"rsc", PROCESSOR_PPC601, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2287 {"rsc1", PROCESSOR_PPC601, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2288 {"rs64", PROCESSOR_RS64A,
2289 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64}
2292 const size_t ptt_size = ARRAY_SIZE (processor_target_table);
2294 /* Some OSs don't support saving the high part of 64-bit registers on
2295 context switch. Other OSs don't support saving Altivec registers.
2296 On those OSs, we don't touch the MASK_POWERPC64 or MASK_ALTIVEC
2297 settings; if the user wants either, the user must explicitly specify
2298 them and we won't interfere with the user's specification. */
2300 enum {
2301 POWER_MASKS = MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING,
2302 POWERPC_MASKS = (POWERPC_BASE_MASK | MASK_PPC_GPOPT | MASK_STRICT_ALIGN
2303 | MASK_PPC_GFXOPT | MASK_POWERPC64 | MASK_ALTIVEC
2304 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_MULHW
2305 | MASK_DLMZB | MASK_CMPB | MASK_MFPGPR | MASK_DFP
2306 | MASK_POPCNTD | MASK_VSX | MASK_ISEL | MASK_NO_UPDATE)
2309 /* Numerous experiment shows that IRA based loop pressure
2310 calculation works better for RTL loop invariant motion on targets
2311 with enough (>= 32) registers. It is an expensive optimization.
2312 So it is on only for peak performance. */
2313 if (optimize >= 3)
2314 flag_ira_loop_pressure = 1;
2316 /* Set the pointer size. */
2317 if (TARGET_64BIT)
2319 rs6000_pmode = (int)DImode;
2320 rs6000_pointer_size = 64;
2322 else
2324 rs6000_pmode = (int)SImode;
2325 rs6000_pointer_size = 32;
2328 set_masks = POWER_MASKS | POWERPC_MASKS | MASK_SOFT_FLOAT;
2329 #ifdef OS_MISSING_POWERPC64
2330 if (OS_MISSING_POWERPC64)
2331 set_masks &= ~MASK_POWERPC64;
2332 #endif
2333 #ifdef OS_MISSING_ALTIVEC
2334 if (OS_MISSING_ALTIVEC)
2335 set_masks &= ~MASK_ALTIVEC;
2336 #endif
2338 /* Don't override by the processor default if given explicitly. */
2339 set_masks &= ~target_flags_explicit;
2341 /* Identify the processor type. */
2342 rs6000_select[0].string = default_cpu;
2343 rs6000_cpu = TARGET_POWERPC64 ? PROCESSOR_DEFAULT64 : PROCESSOR_DEFAULT;
2345 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
2347 ptr = &rs6000_select[i];
2348 if (ptr->string != (char *)0 && ptr->string[0] != '\0')
2350 for (j = 0; j < ptt_size; j++)
2351 if (! strcmp (ptr->string, processor_target_table[j].name))
2353 if (ptr->set_tune_p)
2354 rs6000_cpu = processor_target_table[j].processor;
2356 if (ptr->set_arch_p)
2358 target_flags &= ~set_masks;
2359 target_flags |= (processor_target_table[j].target_enable
2360 & set_masks);
2362 break;
2365 if (j == ptt_size)
2366 error ("bad value (%s) for %s switch", ptr->string, ptr->name);
2370 if (rs6000_cpu == PROCESSOR_PPCE300C2 || rs6000_cpu == PROCESSOR_PPCE300C3
2371 || rs6000_cpu == PROCESSOR_PPCE500MC || rs6000_cpu == PROCESSOR_PPCE500MC64)
2373 if (TARGET_ALTIVEC)
2374 error ("AltiVec not supported in this target");
2375 if (TARGET_SPE)
2376 error ("Spe not supported in this target");
2379 /* Disable Cell microcode if we are optimizing for the Cell
2380 and not optimizing for size. */
2381 if (rs6000_gen_cell_microcode == -1)
2382 rs6000_gen_cell_microcode = !(rs6000_cpu == PROCESSOR_CELL
2383 && !optimize_size);
2385 /* If we are optimizing big endian systems for space and it's OK to
2386 use instructions that would be microcoded on the Cell, use the
2387 load/store multiple and string instructions. */
2388 if (BYTES_BIG_ENDIAN && optimize_size && rs6000_gen_cell_microcode)
2389 target_flags |= ~target_flags_explicit & (MASK_MULTIPLE | MASK_STRING);
2391 /* Don't allow -mmultiple or -mstring on little endian systems
2392 unless the cpu is a 750, because the hardware doesn't support the
2393 instructions used in little endian mode, and causes an alignment
2394 trap. The 750 does not cause an alignment trap (except when the
2395 target is unaligned). */
2397 if (!BYTES_BIG_ENDIAN && rs6000_cpu != PROCESSOR_PPC750)
2399 if (TARGET_MULTIPLE)
2401 target_flags &= ~MASK_MULTIPLE;
2402 if ((target_flags_explicit & MASK_MULTIPLE) != 0)
2403 warning (0, "-mmultiple is not supported on little endian systems");
2406 if (TARGET_STRING)
2408 target_flags &= ~MASK_STRING;
2409 if ((target_flags_explicit & MASK_STRING) != 0)
2410 warning (0, "-mstring is not supported on little endian systems");
2414 /* Add some warnings for VSX. */
2415 if (TARGET_VSX)
2417 const char *msg = NULL;
2418 if (!TARGET_HARD_FLOAT || !TARGET_FPRS
2419 || !TARGET_SINGLE_FLOAT || !TARGET_DOUBLE_FLOAT)
2421 if (target_flags_explicit & MASK_VSX)
2422 msg = N_("-mvsx requires hardware floating point");
2423 else
2424 target_flags &= ~ MASK_VSX;
2426 else if (TARGET_PAIRED_FLOAT)
2427 msg = N_("-mvsx and -mpaired are incompatible");
2428 /* The hardware will allow VSX and little endian, but until we make sure
2429 things like vector select, etc. work don't allow VSX on little endian
2430 systems at this point. */
2431 else if (!BYTES_BIG_ENDIAN)
2432 msg = N_("-mvsx used with little endian code");
2433 else if (TARGET_AVOID_XFORM > 0)
2434 msg = N_("-mvsx needs indexed addressing");
2435 else if (!TARGET_ALTIVEC && (target_flags_explicit & MASK_ALTIVEC))
2437 if (target_flags_explicit & MASK_VSX)
2438 msg = N_("-mvsx and -mno-altivec are incompatible");
2439 else
2440 msg = N_("-mno-altivec disables vsx");
2443 if (msg)
2445 warning (0, msg);
2446 target_flags &= ~ MASK_VSX;
2448 else if (TARGET_VSX && !TARGET_ALTIVEC)
2449 target_flags |= MASK_ALTIVEC;
2452 /* Set debug flags */
2453 if (rs6000_debug_name)
2455 if (! strcmp (rs6000_debug_name, "all"))
2456 rs6000_debug_stack = rs6000_debug_arg = rs6000_debug_reg
2457 = rs6000_debug_addr = rs6000_debug_cost = 1;
2458 else if (! strcmp (rs6000_debug_name, "stack"))
2459 rs6000_debug_stack = 1;
2460 else if (! strcmp (rs6000_debug_name, "arg"))
2461 rs6000_debug_arg = 1;
2462 else if (! strcmp (rs6000_debug_name, "reg"))
2463 rs6000_debug_reg = 1;
2464 else if (! strcmp (rs6000_debug_name, "addr"))
2465 rs6000_debug_addr = 1;
2466 else if (! strcmp (rs6000_debug_name, "cost"))
2467 rs6000_debug_cost = 1;
2468 else
2469 error ("unknown -mdebug-%s switch", rs6000_debug_name);
2471 /* If the appropriate debug option is enabled, replace the target hooks
2472 with debug versions that call the real version and then prints
2473 debugging information. */
2474 if (TARGET_DEBUG_COST)
2476 targetm.rtx_costs = rs6000_debug_rtx_costs;
2477 targetm.address_cost = rs6000_debug_address_cost;
2478 targetm.sched.adjust_cost = rs6000_debug_adjust_cost;
2481 if (TARGET_DEBUG_ADDR)
2483 targetm.legitimate_address_p = rs6000_debug_legitimate_address_p;
2484 targetm.legitimize_address = rs6000_debug_legitimize_address;
2485 rs6000_secondary_reload_class_ptr
2486 = rs6000_debug_secondary_reload_class;
2487 rs6000_secondary_memory_needed_ptr
2488 = rs6000_debug_secondary_memory_needed;
2489 rs6000_cannot_change_mode_class_ptr
2490 = rs6000_debug_cannot_change_mode_class;
2491 rs6000_preferred_reload_class_ptr
2492 = rs6000_debug_preferred_reload_class;
2493 rs6000_legitimize_reload_address_ptr
2494 = rs6000_debug_legitimize_reload_address;
2495 rs6000_mode_dependent_address_ptr
2496 = rs6000_debug_mode_dependent_address;
2500 if (rs6000_traceback_name)
2502 if (! strncmp (rs6000_traceback_name, "full", 4))
2503 rs6000_traceback = traceback_full;
2504 else if (! strncmp (rs6000_traceback_name, "part", 4))
2505 rs6000_traceback = traceback_part;
2506 else if (! strncmp (rs6000_traceback_name, "no", 2))
2507 rs6000_traceback = traceback_none;
2508 else
2509 error ("unknown -mtraceback arg %qs; expecting %<full%>, %<partial%> or %<none%>",
2510 rs6000_traceback_name);
2513 if (!rs6000_explicit_options.long_double)
2514 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
2516 #ifndef POWERPC_LINUX
2517 if (!rs6000_explicit_options.ieee)
2518 rs6000_ieeequad = 1;
2519 #endif
2521 /* Enable Altivec ABI for AIX -maltivec. */
2522 if (TARGET_XCOFF && (TARGET_ALTIVEC || TARGET_VSX))
2523 rs6000_altivec_abi = 1;
2525 /* The AltiVec ABI is the default for PowerPC-64 GNU/Linux. For
2526 PowerPC-32 GNU/Linux, -maltivec implies the AltiVec ABI. It can
2527 be explicitly overridden in either case. */
2528 if (TARGET_ELF)
2530 if (!rs6000_explicit_options.altivec_abi
2531 && (TARGET_64BIT || TARGET_ALTIVEC || TARGET_VSX))
2532 rs6000_altivec_abi = 1;
2534 /* Enable VRSAVE for AltiVec ABI, unless explicitly overridden. */
2535 if (!rs6000_explicit_options.vrsave)
2536 TARGET_ALTIVEC_VRSAVE = rs6000_altivec_abi;
2539 /* Set the Darwin64 ABI as default for 64-bit Darwin. */
2540 if (DEFAULT_ABI == ABI_DARWIN && TARGET_64BIT)
2542 rs6000_darwin64_abi = 1;
2543 #if TARGET_MACHO
2544 darwin_one_byte_bool = 1;
2545 #endif
2546 /* Default to natural alignment, for better performance. */
2547 rs6000_alignment_flags = MASK_ALIGN_NATURAL;
2550 /* Place FP constants in the constant pool instead of TOC
2551 if section anchors enabled. */
2552 if (flag_section_anchors)
2553 TARGET_NO_FP_IN_TOC = 1;
2555 /* Handle -mtls-size option. */
2556 rs6000_parse_tls_size_option ();
2558 #ifdef SUBTARGET_OVERRIDE_OPTIONS
2559 SUBTARGET_OVERRIDE_OPTIONS;
2560 #endif
2561 #ifdef SUBSUBTARGET_OVERRIDE_OPTIONS
2562 SUBSUBTARGET_OVERRIDE_OPTIONS;
2563 #endif
2564 #ifdef SUB3TARGET_OVERRIDE_OPTIONS
2565 SUB3TARGET_OVERRIDE_OPTIONS;
2566 #endif
2568 if (TARGET_E500 || rs6000_cpu == PROCESSOR_PPCE500MC
2569 || rs6000_cpu == PROCESSOR_PPCE500MC64)
2571 /* The e500 and e500mc do not have string instructions, and we set
2572 MASK_STRING above when optimizing for size. */
2573 if ((target_flags & MASK_STRING) != 0)
2574 target_flags = target_flags & ~MASK_STRING;
2576 else if (rs6000_select[1].string != NULL)
2578 /* For the powerpc-eabispe configuration, we set all these by
2579 default, so let's unset them if we manually set another
2580 CPU that is not the E500. */
2581 if (!rs6000_explicit_options.spe_abi)
2582 rs6000_spe_abi = 0;
2583 if (!rs6000_explicit_options.spe)
2584 rs6000_spe = 0;
2585 if (!rs6000_explicit_options.float_gprs)
2586 rs6000_float_gprs = 0;
2587 if (!(target_flags_explicit & MASK_ISEL))
2588 target_flags &= ~MASK_ISEL;
2591 /* Detect invalid option combinations with E500. */
2592 CHECK_E500_OPTIONS;
2594 rs6000_always_hint = (rs6000_cpu != PROCESSOR_POWER4
2595 && rs6000_cpu != PROCESSOR_POWER5
2596 && rs6000_cpu != PROCESSOR_POWER6
2597 && rs6000_cpu != PROCESSOR_POWER7
2598 && rs6000_cpu != PROCESSOR_PPCA2
2599 && rs6000_cpu != PROCESSOR_CELL);
2600 rs6000_sched_groups = (rs6000_cpu == PROCESSOR_POWER4
2601 || rs6000_cpu == PROCESSOR_POWER5
2602 || rs6000_cpu == PROCESSOR_POWER7);
2603 rs6000_align_branch_targets = (rs6000_cpu == PROCESSOR_POWER4
2604 || rs6000_cpu == PROCESSOR_POWER5
2605 || rs6000_cpu == PROCESSOR_POWER6
2606 || rs6000_cpu == PROCESSOR_POWER7
2607 || rs6000_cpu == PROCESSOR_PPCE500MC
2608 || rs6000_cpu == PROCESSOR_PPCE500MC64);
2610 /* Allow debug switches to override the above settings. */
2611 if (TARGET_ALWAYS_HINT > 0)
2612 rs6000_always_hint = TARGET_ALWAYS_HINT;
2614 if (TARGET_SCHED_GROUPS > 0)
2615 rs6000_sched_groups = TARGET_SCHED_GROUPS;
2617 if (TARGET_ALIGN_BRANCH_TARGETS > 0)
2618 rs6000_align_branch_targets = TARGET_ALIGN_BRANCH_TARGETS;
2620 rs6000_sched_restricted_insns_priority
2621 = (rs6000_sched_groups ? 1 : 0);
2623 /* Handle -msched-costly-dep option. */
2624 rs6000_sched_costly_dep
2625 = (rs6000_sched_groups ? store_to_load_dep_costly : no_dep_costly);
2627 if (rs6000_sched_costly_dep_str)
2629 if (! strcmp (rs6000_sched_costly_dep_str, "no"))
2630 rs6000_sched_costly_dep = no_dep_costly;
2631 else if (! strcmp (rs6000_sched_costly_dep_str, "all"))
2632 rs6000_sched_costly_dep = all_deps_costly;
2633 else if (! strcmp (rs6000_sched_costly_dep_str, "true_store_to_load"))
2634 rs6000_sched_costly_dep = true_store_to_load_dep_costly;
2635 else if (! strcmp (rs6000_sched_costly_dep_str, "store_to_load"))
2636 rs6000_sched_costly_dep = store_to_load_dep_costly;
2637 else
2638 rs6000_sched_costly_dep = ((enum rs6000_dependence_cost)
2639 atoi (rs6000_sched_costly_dep_str));
2642 /* Handle -minsert-sched-nops option. */
2643 rs6000_sched_insert_nops
2644 = (rs6000_sched_groups ? sched_finish_regroup_exact : sched_finish_none);
2646 if (rs6000_sched_insert_nops_str)
2648 if (! strcmp (rs6000_sched_insert_nops_str, "no"))
2649 rs6000_sched_insert_nops = sched_finish_none;
2650 else if (! strcmp (rs6000_sched_insert_nops_str, "pad"))
2651 rs6000_sched_insert_nops = sched_finish_pad_groups;
2652 else if (! strcmp (rs6000_sched_insert_nops_str, "regroup_exact"))
2653 rs6000_sched_insert_nops = sched_finish_regroup_exact;
2654 else
2655 rs6000_sched_insert_nops = ((enum rs6000_nop_insertion)
2656 atoi (rs6000_sched_insert_nops_str));
2659 #ifdef TARGET_REGNAMES
2660 /* If the user desires alternate register names, copy in the
2661 alternate names now. */
2662 if (TARGET_REGNAMES)
2663 memcpy (rs6000_reg_names, alt_reg_names, sizeof (rs6000_reg_names));
2664 #endif
2666 /* Set aix_struct_return last, after the ABI is determined.
2667 If -maix-struct-return or -msvr4-struct-return was explicitly
2668 used, don't override with the ABI default. */
2669 if (!rs6000_explicit_options.aix_struct_ret)
2670 aix_struct_return = (DEFAULT_ABI != ABI_V4 || DRAFT_V4_STRUCT_RET);
2672 if (TARGET_LONG_DOUBLE_128 && !TARGET_IEEEQUAD)
2673 REAL_MODE_FORMAT (TFmode) = &ibm_extended_format;
2675 if (TARGET_TOC)
2676 ASM_GENERATE_INTERNAL_LABEL (toc_label_name, "LCTOC", 1);
2678 /* We can only guarantee the availability of DI pseudo-ops when
2679 assembling for 64-bit targets. */
2680 if (!TARGET_64BIT)
2682 targetm.asm_out.aligned_op.di = NULL;
2683 targetm.asm_out.unaligned_op.di = NULL;
2686 /* Set branch target alignment, if not optimizing for size. */
2687 if (!optimize_size)
2689 /* Cell wants to be aligned 8byte for dual issue. */
2690 if (rs6000_cpu == PROCESSOR_CELL)
2692 if (align_functions <= 0)
2693 align_functions = 8;
2694 if (align_jumps <= 0)
2695 align_jumps = 8;
2696 if (align_loops <= 0)
2697 align_loops = 8;
2699 if (rs6000_align_branch_targets)
2701 if (align_functions <= 0)
2702 align_functions = 16;
2703 if (align_jumps <= 0)
2704 align_jumps = 16;
2705 if (align_loops <= 0)
2706 align_loops = 16;
2708 if (align_jumps_max_skip <= 0)
2709 align_jumps_max_skip = 15;
2710 if (align_loops_max_skip <= 0)
2711 align_loops_max_skip = 15;
2714 /* Arrange to save and restore machine status around nested functions. */
2715 init_machine_status = rs6000_init_machine_status;
2717 /* We should always be splitting complex arguments, but we can't break
2718 Linux and Darwin ABIs at the moment. For now, only AIX is fixed. */
2719 if (DEFAULT_ABI != ABI_AIX)
2720 targetm.calls.split_complex_arg = NULL;
2722 /* Initialize rs6000_cost with the appropriate target costs. */
2723 if (optimize_size)
2724 rs6000_cost = TARGET_POWERPC64 ? &size64_cost : &size32_cost;
2725 else
2726 switch (rs6000_cpu)
2728 case PROCESSOR_RIOS1:
2729 rs6000_cost = &rios1_cost;
2730 break;
2732 case PROCESSOR_RIOS2:
2733 rs6000_cost = &rios2_cost;
2734 break;
2736 case PROCESSOR_RS64A:
2737 rs6000_cost = &rs64a_cost;
2738 break;
2740 case PROCESSOR_MPCCORE:
2741 rs6000_cost = &mpccore_cost;
2742 break;
2744 case PROCESSOR_PPC403:
2745 rs6000_cost = &ppc403_cost;
2746 break;
2748 case PROCESSOR_PPC405:
2749 rs6000_cost = &ppc405_cost;
2750 break;
2752 case PROCESSOR_PPC440:
2753 rs6000_cost = &ppc440_cost;
2754 break;
2756 case PROCESSOR_PPC476:
2757 rs6000_cost = &ppc476_cost;
2758 break;
2760 case PROCESSOR_PPC601:
2761 rs6000_cost = &ppc601_cost;
2762 break;
2764 case PROCESSOR_PPC603:
2765 rs6000_cost = &ppc603_cost;
2766 break;
2768 case PROCESSOR_PPC604:
2769 rs6000_cost = &ppc604_cost;
2770 break;
2772 case PROCESSOR_PPC604e:
2773 rs6000_cost = &ppc604e_cost;
2774 break;
2776 case PROCESSOR_PPC620:
2777 rs6000_cost = &ppc620_cost;
2778 break;
2780 case PROCESSOR_PPC630:
2781 rs6000_cost = &ppc630_cost;
2782 break;
2784 case PROCESSOR_CELL:
2785 rs6000_cost = &ppccell_cost;
2786 break;
2788 case PROCESSOR_PPC750:
2789 case PROCESSOR_PPC7400:
2790 rs6000_cost = &ppc750_cost;
2791 break;
2793 case PROCESSOR_PPC7450:
2794 rs6000_cost = &ppc7450_cost;
2795 break;
2797 case PROCESSOR_PPC8540:
2798 rs6000_cost = &ppc8540_cost;
2799 break;
2801 case PROCESSOR_PPCE300C2:
2802 case PROCESSOR_PPCE300C3:
2803 rs6000_cost = &ppce300c2c3_cost;
2804 break;
2806 case PROCESSOR_PPCE500MC:
2807 rs6000_cost = &ppce500mc_cost;
2808 break;
2810 case PROCESSOR_PPCE500MC64:
2811 rs6000_cost = &ppce500mc64_cost;
2812 break;
2814 case PROCESSOR_POWER4:
2815 case PROCESSOR_POWER5:
2816 rs6000_cost = &power4_cost;
2817 break;
2819 case PROCESSOR_POWER6:
2820 rs6000_cost = &power6_cost;
2821 break;
2823 case PROCESSOR_POWER7:
2824 rs6000_cost = &power7_cost;
2825 break;
2827 case PROCESSOR_PPCA2:
2828 rs6000_cost = &ppca2_cost;
2829 break;
2831 default:
2832 gcc_unreachable ();
2835 if (!PARAM_SET_P (PARAM_SIMULTANEOUS_PREFETCHES))
2836 set_param_value ("simultaneous-prefetches",
2837 rs6000_cost->simultaneous_prefetches);
2838 if (!PARAM_SET_P (PARAM_L1_CACHE_SIZE))
2839 set_param_value ("l1-cache-size", rs6000_cost->l1_cache_size);
2840 if (!PARAM_SET_P (PARAM_L1_CACHE_LINE_SIZE))
2841 set_param_value ("l1-cache-line-size", rs6000_cost->cache_line_size);
2842 if (!PARAM_SET_P (PARAM_L2_CACHE_SIZE))
2843 set_param_value ("l2-cache-size", rs6000_cost->l2_cache_size);
2845 /* If using typedef char *va_list, signal that __builtin_va_start (&ap, 0)
2846 can be optimized to ap = __builtin_next_arg (0). */
2847 if (DEFAULT_ABI != ABI_V4)
2848 targetm.expand_builtin_va_start = NULL;
2850 /* Set up single/double float flags.
2851 If TARGET_HARD_FLOAT is set, but neither single or double is set,
2852 then set both flags. */
2853 if (TARGET_HARD_FLOAT && TARGET_FPRS
2854 && rs6000_single_float == 0 && rs6000_double_float == 0)
2855 rs6000_single_float = rs6000_double_float = 1;
2857 /* Reset single and double FP flags if target is E500. */
2858 if (TARGET_E500)
2860 rs6000_single_float = rs6000_double_float = 0;
2861 if (TARGET_E500_SINGLE)
2862 rs6000_single_float = 1;
2863 if (TARGET_E500_DOUBLE)
2864 rs6000_single_float = rs6000_double_float = 1;
2867 /* If not explicitly specified via option, decide whether to generate indexed
2868 load/store instructions. */
2869 if (TARGET_AVOID_XFORM == -1)
2870 /* Avoid indexed addressing when targeting Power6 in order to avoid
2871 the DERAT mispredict penalty. */
2872 TARGET_AVOID_XFORM = (rs6000_cpu == PROCESSOR_POWER6 && TARGET_CMPB);
2874 rs6000_init_hard_regno_mode_ok ();
2877 /* Implement targetm.vectorize.builtin_mask_for_load. */
2878 static tree
2879 rs6000_builtin_mask_for_load (void)
2881 if (TARGET_ALTIVEC || TARGET_VSX)
2882 return altivec_builtin_mask_for_load;
2883 else
2884 return 0;
2887 /* Implement targetm.vectorize.builtin_conversion.
2888 Returns a decl of a function that implements conversion of an integer vector
2889 into a floating-point vector, or vice-versa. TYPE is the type of the integer
2890 side of the conversion.
2891 Return NULL_TREE if it is not available. */
2892 static tree
2893 rs6000_builtin_conversion (unsigned int tcode, tree type)
2895 enum tree_code code = (enum tree_code) tcode;
2897 switch (code)
2899 case FIX_TRUNC_EXPR:
2900 switch (TYPE_MODE (type))
2902 case V2DImode:
2903 if (!VECTOR_UNIT_VSX_P (V2DFmode))
2904 return NULL_TREE;
2906 return TYPE_UNSIGNED (type)
2907 ? rs6000_builtin_decls[VSX_BUILTIN_XVCVDPUXDS_UNS]
2908 : rs6000_builtin_decls[VSX_BUILTIN_XVCVDPSXDS];
2910 case V4SImode:
2911 if (VECTOR_UNIT_NONE_P (V4SImode) || VECTOR_UNIT_NONE_P (V4SFmode))
2912 return NULL_TREE;
2914 return TYPE_UNSIGNED (type)
2915 ? rs6000_builtin_decls[VECTOR_BUILTIN_FIXUNS_V4SF_V4SI]
2916 : rs6000_builtin_decls[VECTOR_BUILTIN_FIX_V4SF_V4SI];
2918 default:
2919 return NULL_TREE;
2922 case FLOAT_EXPR:
2923 switch (TYPE_MODE (type))
2925 case V2DImode:
2926 if (!VECTOR_UNIT_VSX_P (V2DFmode))
2927 return NULL_TREE;
2929 return TYPE_UNSIGNED (type)
2930 ? rs6000_builtin_decls[VSX_BUILTIN_XVCVUXDDP]
2931 : rs6000_builtin_decls[VSX_BUILTIN_XVCVSXDDP];
2933 case V4SImode:
2934 if (VECTOR_UNIT_NONE_P (V4SImode) || VECTOR_UNIT_NONE_P (V4SFmode))
2935 return NULL_TREE;
2937 return TYPE_UNSIGNED (type)
2938 ? rs6000_builtin_decls[VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF]
2939 : rs6000_builtin_decls[VECTOR_BUILTIN_FLOAT_V4SI_V4SF];
2941 default:
2942 return NULL_TREE;
2945 default:
2946 return NULL_TREE;
2950 /* Implement targetm.vectorize.builtin_mul_widen_even. */
2951 static tree
2952 rs6000_builtin_mul_widen_even (tree type)
2954 if (!TARGET_ALTIVEC)
2955 return NULL_TREE;
2957 switch (TYPE_MODE (type))
2959 case V8HImode:
2960 return TYPE_UNSIGNED (type)
2961 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULEUH_UNS]
2962 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULESH];
2964 case V16QImode:
2965 return TYPE_UNSIGNED (type)
2966 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULEUB_UNS]
2967 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULESB];
2968 default:
2969 return NULL_TREE;
2973 /* Implement targetm.vectorize.builtin_mul_widen_odd. */
2974 static tree
2975 rs6000_builtin_mul_widen_odd (tree type)
2977 if (!TARGET_ALTIVEC)
2978 return NULL_TREE;
2980 switch (TYPE_MODE (type))
2982 case V8HImode:
2983 return TYPE_UNSIGNED (type)
2984 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOUH_UNS]
2985 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOSH];
2987 case V16QImode:
2988 return TYPE_UNSIGNED (type)
2989 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOUB_UNS]
2990 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOSB];
2991 default:
2992 return NULL_TREE;
2997 /* Return true iff, data reference of TYPE can reach vector alignment (16)
2998 after applying N number of iterations. This routine does not determine
2999 how may iterations are required to reach desired alignment. */
3001 static bool
3002 rs6000_vector_alignment_reachable (const_tree type ATTRIBUTE_UNUSED, bool is_packed)
3004 if (is_packed)
3005 return false;
3007 if (TARGET_32BIT)
3009 if (rs6000_alignment_flags == MASK_ALIGN_NATURAL)
3010 return true;
3012 if (rs6000_alignment_flags == MASK_ALIGN_POWER)
3013 return true;
3015 return false;
3017 else
3019 if (TARGET_MACHO)
3020 return false;
3022 /* Assuming that all other types are naturally aligned. CHECKME! */
3023 return true;
3027 /* Return true if the vector misalignment factor is supported by the
3028 target. */
3029 bool
3030 rs6000_builtin_support_vector_misalignment (enum machine_mode mode,
3031 const_tree type,
3032 int misalignment,
3033 bool is_packed)
3035 if (TARGET_VSX)
3037 /* Return if movmisalign pattern is not supported for this mode. */
3038 if (optab_handler (movmisalign_optab, mode)->insn_code ==
3039 CODE_FOR_nothing)
3040 return false;
3042 if (misalignment == -1)
3044 /* misalignment factor is unknown at compile time but we know
3045 it's word aligned. */
3046 if (rs6000_vector_alignment_reachable (type, is_packed))
3047 return true;
3048 return false;
3050 /* VSX supports word-aligned vector. */
3051 if (misalignment % 4 == 0)
3052 return true;
3054 return false;
3057 /* Implement targetm.vectorize.builtin_vec_perm. */
3058 tree
3059 rs6000_builtin_vec_perm (tree type, tree *mask_element_type)
3061 tree inner_type = TREE_TYPE (type);
3062 bool uns_p = TYPE_UNSIGNED (inner_type);
3063 tree d;
3065 *mask_element_type = unsigned_char_type_node;
3067 switch (TYPE_MODE (type))
3069 case V16QImode:
3070 d = (uns_p
3071 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_16QI_UNS]
3072 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_16QI]);
3073 break;
3075 case V8HImode:
3076 d = (uns_p
3077 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_8HI_UNS]
3078 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_8HI]);
3079 break;
3081 case V4SImode:
3082 d = (uns_p
3083 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SI_UNS]
3084 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SI]);
3085 break;
3087 case V4SFmode:
3088 d = rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SF];
3089 break;
3091 case V2DFmode:
3092 if (!TARGET_ALLOW_DF_PERMUTE)
3093 return NULL_TREE;
3095 d = rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DF];
3096 break;
3098 case V2DImode:
3099 if (!TARGET_ALLOW_DF_PERMUTE)
3100 return NULL_TREE;
3102 d = (uns_p
3103 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DI_UNS]
3104 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DI]);
3105 break;
3107 default:
3108 return NULL_TREE;
3111 gcc_assert (d);
3112 return d;
3115 /* Handle generic options of the form -mfoo=yes/no.
3116 NAME is the option name.
3117 VALUE is the option value.
3118 FLAG is the pointer to the flag where to store a 1 or 0, depending on
3119 whether the option value is 'yes' or 'no' respectively. */
3120 static void
3121 rs6000_parse_yes_no_option (const char *name, const char *value, int *flag)
3123 if (value == 0)
3124 return;
3125 else if (!strcmp (value, "yes"))
3126 *flag = 1;
3127 else if (!strcmp (value, "no"))
3128 *flag = 0;
3129 else
3130 error ("unknown -m%s= option specified: '%s'", name, value);
3133 /* Validate and record the size specified with the -mtls-size option. */
3135 static void
3136 rs6000_parse_tls_size_option (void)
3138 if (rs6000_tls_size_string == 0)
3139 return;
3140 else if (strcmp (rs6000_tls_size_string, "16") == 0)
3141 rs6000_tls_size = 16;
3142 else if (strcmp (rs6000_tls_size_string, "32") == 0)
3143 rs6000_tls_size = 32;
3144 else if (strcmp (rs6000_tls_size_string, "64") == 0)
3145 rs6000_tls_size = 64;
3146 else
3147 error ("bad value %qs for -mtls-size switch", rs6000_tls_size_string);
3150 void
3151 optimization_options (int level ATTRIBUTE_UNUSED, int size ATTRIBUTE_UNUSED)
3153 if (DEFAULT_ABI == ABI_DARWIN)
3154 /* The Darwin libraries never set errno, so we might as well
3155 avoid calling them when that's the only reason we would. */
3156 flag_errno_math = 0;
3158 /* Double growth factor to counter reduced min jump length. */
3159 set_param_value ("max-grow-copy-bb-insns", 16);
3161 /* Enable section anchors by default.
3162 Skip section anchors for Objective C and Objective C++
3163 until front-ends fixed. */
3164 if (!TARGET_MACHO && lang_hooks.name[4] != 'O')
3165 flag_section_anchors = 2;
3168 static enum fpu_type_t
3169 rs6000_parse_fpu_option (const char *option)
3171 if (!strcmp("none", option)) return FPU_NONE;
3172 if (!strcmp("sp_lite", option)) return FPU_SF_LITE;
3173 if (!strcmp("dp_lite", option)) return FPU_DF_LITE;
3174 if (!strcmp("sp_full", option)) return FPU_SF_FULL;
3175 if (!strcmp("dp_full", option)) return FPU_DF_FULL;
3176 error("unknown value %s for -mfpu", option);
3177 return FPU_NONE;
3180 /* Returns a function decl for a vectorized version of the builtin function
3181 with builtin function code FN and the result vector type TYPE, or NULL_TREE
3182 if it is not available. */
3184 static tree
3185 rs6000_builtin_vectorized_function (unsigned int fn, tree type_out,
3186 tree type_in)
3188 enum machine_mode in_mode, out_mode;
3189 int in_n, out_n;
3191 if (TREE_CODE (type_out) != VECTOR_TYPE
3192 || TREE_CODE (type_in) != VECTOR_TYPE
3193 || !TARGET_VECTORIZE_BUILTINS)
3194 return NULL_TREE;
3196 out_mode = TYPE_MODE (TREE_TYPE (type_out));
3197 out_n = TYPE_VECTOR_SUBPARTS (type_out);
3198 in_mode = TYPE_MODE (TREE_TYPE (type_in));
3199 in_n = TYPE_VECTOR_SUBPARTS (type_in);
3201 switch (fn)
3203 case BUILT_IN_COPYSIGN:
3204 if (VECTOR_UNIT_VSX_P (V2DFmode)
3205 && out_mode == DFmode && out_n == 2
3206 && in_mode == DFmode && in_n == 2)
3207 return rs6000_builtin_decls[VSX_BUILTIN_CPSGNDP];
3208 break;
3209 case BUILT_IN_COPYSIGNF:
3210 if (out_mode != SFmode || out_n != 4
3211 || in_mode != SFmode || in_n != 4)
3212 break;
3213 if (VECTOR_UNIT_VSX_P (V4SFmode))
3214 return rs6000_builtin_decls[VSX_BUILTIN_CPSGNSP];
3215 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3216 return rs6000_builtin_decls[ALTIVEC_BUILTIN_COPYSIGN_V4SF];
3217 break;
3218 case BUILT_IN_SQRT:
3219 if (VECTOR_UNIT_VSX_P (V2DFmode)
3220 && out_mode == DFmode && out_n == 2
3221 && in_mode == DFmode && in_n == 2)
3222 return rs6000_builtin_decls[VSX_BUILTIN_XVSQRTDP];
3223 break;
3224 case BUILT_IN_SQRTF:
3225 if (VECTOR_UNIT_VSX_P (V4SFmode)
3226 && out_mode == SFmode && out_n == 4
3227 && in_mode == SFmode && in_n == 4)
3228 return rs6000_builtin_decls[VSX_BUILTIN_XVSQRTSP];
3229 break;
3230 case BUILT_IN_CEIL:
3231 if (VECTOR_UNIT_VSX_P (V2DFmode)
3232 && out_mode == DFmode && out_n == 2
3233 && in_mode == DFmode && in_n == 2)
3234 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIP];
3235 break;
3236 case BUILT_IN_CEILF:
3237 if (out_mode != SFmode || out_n != 4
3238 || in_mode != SFmode || in_n != 4)
3239 break;
3240 if (VECTOR_UNIT_VSX_P (V4SFmode))
3241 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIP];
3242 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3243 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIP];
3244 break;
3245 case BUILT_IN_FLOOR:
3246 if (VECTOR_UNIT_VSX_P (V2DFmode)
3247 && out_mode == DFmode && out_n == 2
3248 && in_mode == DFmode && in_n == 2)
3249 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIM];
3250 break;
3251 case BUILT_IN_FLOORF:
3252 if (out_mode != SFmode || out_n != 4
3253 || in_mode != SFmode || in_n != 4)
3254 break;
3255 if (VECTOR_UNIT_VSX_P (V4SFmode))
3256 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIM];
3257 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3258 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIM];
3259 break;
3260 case BUILT_IN_TRUNC:
3261 if (VECTOR_UNIT_VSX_P (V2DFmode)
3262 && out_mode == DFmode && out_n == 2
3263 && in_mode == DFmode && in_n == 2)
3264 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIZ];
3265 break;
3266 case BUILT_IN_TRUNCF:
3267 if (out_mode != SFmode || out_n != 4
3268 || in_mode != SFmode || in_n != 4)
3269 break;
3270 if (VECTOR_UNIT_VSX_P (V4SFmode))
3271 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIZ];
3272 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3273 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIZ];
3274 break;
3275 case BUILT_IN_NEARBYINT:
3276 if (VECTOR_UNIT_VSX_P (V2DFmode)
3277 && flag_unsafe_math_optimizations
3278 && out_mode == DFmode && out_n == 2
3279 && in_mode == DFmode && in_n == 2)
3280 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPI];
3281 break;
3282 case BUILT_IN_NEARBYINTF:
3283 if (VECTOR_UNIT_VSX_P (V4SFmode)
3284 && flag_unsafe_math_optimizations
3285 && out_mode == SFmode && out_n == 4
3286 && in_mode == SFmode && in_n == 4)
3287 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPI];
3288 break;
3289 case BUILT_IN_RINT:
3290 if (VECTOR_UNIT_VSX_P (V2DFmode)
3291 && !flag_trapping_math
3292 && out_mode == DFmode && out_n == 2
3293 && in_mode == DFmode && in_n == 2)
3294 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIC];
3295 break;
3296 case BUILT_IN_RINTF:
3297 if (VECTOR_UNIT_VSX_P (V4SFmode)
3298 && !flag_trapping_math
3299 && out_mode == SFmode && out_n == 4
3300 && in_mode == SFmode && in_n == 4)
3301 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIC];
3302 break;
3303 default:
3304 break;
3306 return NULL_TREE;
3310 /* Implement TARGET_HANDLE_OPTION. */
3312 static bool
3313 rs6000_handle_option (size_t code, const char *arg, int value)
3315 enum fpu_type_t fpu_type = FPU_NONE;
3316 int isel;
3318 switch (code)
3320 case OPT_mno_power:
3321 target_flags &= ~(MASK_POWER | MASK_POWER2
3322 | MASK_MULTIPLE | MASK_STRING);
3323 target_flags_explicit |= (MASK_POWER | MASK_POWER2
3324 | MASK_MULTIPLE | MASK_STRING);
3325 break;
3326 case OPT_mno_powerpc:
3327 target_flags &= ~(MASK_POWERPC | MASK_PPC_GPOPT
3328 | MASK_PPC_GFXOPT | MASK_POWERPC64);
3329 target_flags_explicit |= (MASK_POWERPC | MASK_PPC_GPOPT
3330 | MASK_PPC_GFXOPT | MASK_POWERPC64);
3331 break;
3332 case OPT_mfull_toc:
3333 target_flags &= ~MASK_MINIMAL_TOC;
3334 TARGET_NO_FP_IN_TOC = 0;
3335 TARGET_NO_SUM_IN_TOC = 0;
3336 target_flags_explicit |= MASK_MINIMAL_TOC;
3337 #ifdef TARGET_USES_SYSV4_OPT
3338 /* Note, V.4 no longer uses a normal TOC, so make -mfull-toc, be
3339 just the same as -mminimal-toc. */
3340 target_flags |= MASK_MINIMAL_TOC;
3341 target_flags_explicit |= MASK_MINIMAL_TOC;
3342 #endif
3343 break;
3345 #ifdef TARGET_USES_SYSV4_OPT
3346 case OPT_mtoc:
3347 /* Make -mtoc behave like -mminimal-toc. */
3348 target_flags |= MASK_MINIMAL_TOC;
3349 target_flags_explicit |= MASK_MINIMAL_TOC;
3350 break;
3351 #endif
3353 #ifdef TARGET_USES_AIX64_OPT
3354 case OPT_maix64:
3355 #else
3356 case OPT_m64:
3357 #endif
3358 target_flags |= MASK_POWERPC64 | MASK_POWERPC;
3359 target_flags |= ~target_flags_explicit & MASK_PPC_GFXOPT;
3360 target_flags_explicit |= MASK_POWERPC64 | MASK_POWERPC;
3361 break;
3363 #ifdef TARGET_USES_AIX64_OPT
3364 case OPT_maix32:
3365 #else
3366 case OPT_m32:
3367 #endif
3368 target_flags &= ~MASK_POWERPC64;
3369 target_flags_explicit |= MASK_POWERPC64;
3370 break;
3372 case OPT_minsert_sched_nops_:
3373 rs6000_sched_insert_nops_str = arg;
3374 break;
3376 case OPT_mminimal_toc:
3377 if (value == 1)
3379 TARGET_NO_FP_IN_TOC = 0;
3380 TARGET_NO_SUM_IN_TOC = 0;
3382 break;
3384 case OPT_mpower:
3385 if (value == 1)
3387 target_flags |= (MASK_MULTIPLE | MASK_STRING);
3388 target_flags_explicit |= (MASK_MULTIPLE | MASK_STRING);
3390 break;
3392 case OPT_mpower2:
3393 if (value == 1)
3395 target_flags |= (MASK_POWER | MASK_MULTIPLE | MASK_STRING);
3396 target_flags_explicit |= (MASK_POWER | MASK_MULTIPLE | MASK_STRING);
3398 break;
3400 case OPT_mpowerpc_gpopt:
3401 case OPT_mpowerpc_gfxopt:
3402 if (value == 1)
3404 target_flags |= MASK_POWERPC;
3405 target_flags_explicit |= MASK_POWERPC;
3407 break;
3409 case OPT_maix_struct_return:
3410 case OPT_msvr4_struct_return:
3411 rs6000_explicit_options.aix_struct_ret = true;
3412 break;
3414 case OPT_mvrsave:
3415 rs6000_explicit_options.vrsave = true;
3416 TARGET_ALTIVEC_VRSAVE = value;
3417 break;
3419 case OPT_mvrsave_:
3420 rs6000_explicit_options.vrsave = true;
3421 rs6000_parse_yes_no_option ("vrsave", arg, &(TARGET_ALTIVEC_VRSAVE));
3422 break;
3424 case OPT_misel_:
3425 target_flags_explicit |= MASK_ISEL;
3426 isel = 0;
3427 rs6000_parse_yes_no_option ("isel", arg, &isel);
3428 if (isel)
3429 target_flags |= MASK_ISEL;
3430 else
3431 target_flags &= ~MASK_ISEL;
3432 break;
3434 case OPT_mspe:
3435 rs6000_explicit_options.spe = true;
3436 rs6000_spe = value;
3437 break;
3439 case OPT_mspe_:
3440 rs6000_explicit_options.spe = true;
3441 rs6000_parse_yes_no_option ("spe", arg, &(rs6000_spe));
3442 break;
3444 case OPT_mdebug_:
3445 rs6000_debug_name = arg;
3446 break;
3448 #ifdef TARGET_USES_SYSV4_OPT
3449 case OPT_mcall_:
3450 rs6000_abi_name = arg;
3451 break;
3453 case OPT_msdata_:
3454 rs6000_sdata_name = arg;
3455 break;
3457 case OPT_mtls_size_:
3458 rs6000_tls_size_string = arg;
3459 break;
3461 case OPT_mrelocatable:
3462 if (value == 1)
3464 target_flags |= MASK_MINIMAL_TOC;
3465 target_flags_explicit |= MASK_MINIMAL_TOC;
3466 TARGET_NO_FP_IN_TOC = 1;
3468 break;
3470 case OPT_mrelocatable_lib:
3471 if (value == 1)
3473 target_flags |= MASK_RELOCATABLE | MASK_MINIMAL_TOC;
3474 target_flags_explicit |= MASK_RELOCATABLE | MASK_MINIMAL_TOC;
3475 TARGET_NO_FP_IN_TOC = 1;
3477 else
3479 target_flags &= ~MASK_RELOCATABLE;
3480 target_flags_explicit |= MASK_RELOCATABLE;
3482 break;
3483 #endif
3485 case OPT_mabi_:
3486 if (!strcmp (arg, "altivec"))
3488 rs6000_explicit_options.altivec_abi = true;
3489 rs6000_altivec_abi = 1;
3491 /* Enabling the AltiVec ABI turns off the SPE ABI. */
3492 rs6000_spe_abi = 0;
3494 else if (! strcmp (arg, "no-altivec"))
3496 rs6000_explicit_options.altivec_abi = true;
3497 rs6000_altivec_abi = 0;
3499 else if (! strcmp (arg, "spe"))
3501 rs6000_explicit_options.spe_abi = true;
3502 rs6000_spe_abi = 1;
3503 rs6000_altivec_abi = 0;
3504 if (!TARGET_SPE_ABI)
3505 error ("not configured for ABI: '%s'", arg);
3507 else if (! strcmp (arg, "no-spe"))
3509 rs6000_explicit_options.spe_abi = true;
3510 rs6000_spe_abi = 0;
3513 /* These are here for testing during development only, do not
3514 document in the manual please. */
3515 else if (! strcmp (arg, "d64"))
3517 rs6000_darwin64_abi = 1;
3518 warning (0, "Using darwin64 ABI");
3520 else if (! strcmp (arg, "d32"))
3522 rs6000_darwin64_abi = 0;
3523 warning (0, "Using old darwin ABI");
3526 else if (! strcmp (arg, "ibmlongdouble"))
3528 rs6000_explicit_options.ieee = true;
3529 rs6000_ieeequad = 0;
3530 warning (0, "Using IBM extended precision long double");
3532 else if (! strcmp (arg, "ieeelongdouble"))
3534 rs6000_explicit_options.ieee = true;
3535 rs6000_ieeequad = 1;
3536 warning (0, "Using IEEE extended precision long double");
3539 else
3541 error ("unknown ABI specified: '%s'", arg);
3542 return false;
3544 break;
3546 case OPT_mcpu_:
3547 rs6000_select[1].string = arg;
3548 break;
3550 case OPT_mtune_:
3551 rs6000_select[2].string = arg;
3552 break;
3554 case OPT_mtraceback_:
3555 rs6000_traceback_name = arg;
3556 break;
3558 case OPT_mfloat_gprs_:
3559 rs6000_explicit_options.float_gprs = true;
3560 if (! strcmp (arg, "yes") || ! strcmp (arg, "single"))
3561 rs6000_float_gprs = 1;
3562 else if (! strcmp (arg, "double"))
3563 rs6000_float_gprs = 2;
3564 else if (! strcmp (arg, "no"))
3565 rs6000_float_gprs = 0;
3566 else
3568 error ("invalid option for -mfloat-gprs: '%s'", arg);
3569 return false;
3571 break;
3573 case OPT_mlong_double_:
3574 rs6000_explicit_options.long_double = true;
3575 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
3576 if (value != 64 && value != 128)
3578 error ("Unknown switch -mlong-double-%s", arg);
3579 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
3580 return false;
3582 else
3583 rs6000_long_double_type_size = value;
3584 break;
3586 case OPT_msched_costly_dep_:
3587 rs6000_sched_costly_dep_str = arg;
3588 break;
3590 case OPT_malign_:
3591 rs6000_explicit_options.alignment = true;
3592 if (! strcmp (arg, "power"))
3594 /* On 64-bit Darwin, power alignment is ABI-incompatible with
3595 some C library functions, so warn about it. The flag may be
3596 useful for performance studies from time to time though, so
3597 don't disable it entirely. */
3598 if (DEFAULT_ABI == ABI_DARWIN && TARGET_64BIT)
3599 warning (0, "-malign-power is not supported for 64-bit Darwin;"
3600 " it is incompatible with the installed C and C++ libraries");
3601 rs6000_alignment_flags = MASK_ALIGN_POWER;
3603 else if (! strcmp (arg, "natural"))
3604 rs6000_alignment_flags = MASK_ALIGN_NATURAL;
3605 else
3607 error ("unknown -malign-XXXXX option specified: '%s'", arg);
3608 return false;
3610 break;
3612 case OPT_msingle_float:
3613 if (!TARGET_SINGLE_FPU)
3614 warning (0, "-msingle-float option equivalent to -mhard-float");
3615 /* -msingle-float implies -mno-double-float and TARGET_HARD_FLOAT. */
3616 rs6000_double_float = 0;
3617 target_flags &= ~MASK_SOFT_FLOAT;
3618 target_flags_explicit |= MASK_SOFT_FLOAT;
3619 break;
3621 case OPT_mdouble_float:
3622 /* -mdouble-float implies -msingle-float and TARGET_HARD_FLOAT. */
3623 rs6000_single_float = 1;
3624 target_flags &= ~MASK_SOFT_FLOAT;
3625 target_flags_explicit |= MASK_SOFT_FLOAT;
3626 break;
3628 case OPT_msimple_fpu:
3629 if (!TARGET_SINGLE_FPU)
3630 warning (0, "-msimple-fpu option ignored");
3631 break;
3633 case OPT_mhard_float:
3634 /* -mhard_float implies -msingle-float and -mdouble-float. */
3635 rs6000_single_float = rs6000_double_float = 1;
3636 break;
3638 case OPT_msoft_float:
3639 /* -msoft_float implies -mnosingle-float and -mnodouble-float. */
3640 rs6000_single_float = rs6000_double_float = 0;
3641 break;
3643 case OPT_mfpu_:
3644 fpu_type = rs6000_parse_fpu_option(arg);
3645 if (fpu_type != FPU_NONE)
3646 /* If -mfpu is not none, then turn off SOFT_FLOAT, turn on HARD_FLOAT. */
3648 target_flags &= ~MASK_SOFT_FLOAT;
3649 target_flags_explicit |= MASK_SOFT_FLOAT;
3650 rs6000_xilinx_fpu = 1;
3651 if (fpu_type == FPU_SF_LITE || fpu_type == FPU_SF_FULL)
3652 rs6000_single_float = 1;
3653 if (fpu_type == FPU_DF_LITE || fpu_type == FPU_DF_FULL)
3654 rs6000_single_float = rs6000_double_float = 1;
3655 if (fpu_type == FPU_SF_LITE || fpu_type == FPU_DF_LITE)
3656 rs6000_simple_fpu = 1;
3658 else
3660 /* -mfpu=none is equivalent to -msoft-float */
3661 target_flags |= MASK_SOFT_FLOAT;
3662 target_flags_explicit |= MASK_SOFT_FLOAT;
3663 rs6000_single_float = rs6000_double_float = 0;
3665 break;
3667 return true;
3670 /* Do anything needed at the start of the asm file. */
3672 static void
3673 rs6000_file_start (void)
3675 size_t i;
3676 char buffer[80];
3677 const char *start = buffer;
3678 struct rs6000_cpu_select *ptr;
3679 const char *default_cpu = TARGET_CPU_DEFAULT;
3680 FILE *file = asm_out_file;
3682 default_file_start ();
3684 #ifdef TARGET_BI_ARCH
3685 if ((TARGET_DEFAULT ^ target_flags) & MASK_64BIT)
3686 default_cpu = 0;
3687 #endif
3689 if (flag_verbose_asm)
3691 sprintf (buffer, "\n%s rs6000/powerpc options:", ASM_COMMENT_START);
3692 rs6000_select[0].string = default_cpu;
3694 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
3696 ptr = &rs6000_select[i];
3697 if (ptr->string != (char *)0 && ptr->string[0] != '\0')
3699 fprintf (file, "%s %s%s", start, ptr->name, ptr->string);
3700 start = "";
3704 if (PPC405_ERRATUM77)
3706 fprintf (file, "%s PPC405CR_ERRATUM77", start);
3707 start = "";
3710 #ifdef USING_ELFOS_H
3711 switch (rs6000_sdata)
3713 case SDATA_NONE: fprintf (file, "%s -msdata=none", start); start = ""; break;
3714 case SDATA_DATA: fprintf (file, "%s -msdata=data", start); start = ""; break;
3715 case SDATA_SYSV: fprintf (file, "%s -msdata=sysv", start); start = ""; break;
3716 case SDATA_EABI: fprintf (file, "%s -msdata=eabi", start); start = ""; break;
3719 if (rs6000_sdata && g_switch_value)
3721 fprintf (file, "%s -G " HOST_WIDE_INT_PRINT_UNSIGNED, start,
3722 g_switch_value);
3723 start = "";
3725 #endif
3727 if (*start == '\0')
3728 putc ('\n', file);
3731 #ifdef HAVE_AS_GNU_ATTRIBUTE
3732 if (TARGET_32BIT && DEFAULT_ABI == ABI_V4)
3734 fprintf (file, "\t.gnu_attribute 4, %d\n",
3735 ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT) ? 1
3736 : (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT) ? 3
3737 : 2));
3738 fprintf (file, "\t.gnu_attribute 8, %d\n",
3739 (TARGET_ALTIVEC_ABI ? 2
3740 : TARGET_SPE_ABI ? 3
3741 : 1));
3742 fprintf (file, "\t.gnu_attribute 12, %d\n",
3743 aix_struct_return ? 2 : 1);
3746 #endif
3748 if (DEFAULT_ABI == ABI_AIX || (TARGET_ELF && flag_pic == 2))
3750 switch_to_section (toc_section);
3751 switch_to_section (text_section);
3756 /* Return nonzero if this function is known to have a null epilogue. */
3759 direct_return (void)
3761 if (reload_completed)
3763 rs6000_stack_t *info = rs6000_stack_info ();
3765 if (info->first_gp_reg_save == 32
3766 && info->first_fp_reg_save == 64
3767 && info->first_altivec_reg_save == LAST_ALTIVEC_REGNO + 1
3768 && ! info->lr_save_p
3769 && ! info->cr_save_p
3770 && info->vrsave_mask == 0
3771 && ! info->push_p)
3772 return 1;
3775 return 0;
3778 /* Return the number of instructions it takes to form a constant in an
3779 integer register. */
3782 num_insns_constant_wide (HOST_WIDE_INT value)
3784 /* signed constant loadable with {cal|addi} */
3785 if ((unsigned HOST_WIDE_INT) (value + 0x8000) < 0x10000)
3786 return 1;
3788 /* constant loadable with {cau|addis} */
3789 else if ((value & 0xffff) == 0
3790 && (value >> 31 == -1 || value >> 31 == 0))
3791 return 1;
3793 #if HOST_BITS_PER_WIDE_INT == 64
3794 else if (TARGET_POWERPC64)
3796 HOST_WIDE_INT low = ((value & 0xffffffff) ^ 0x80000000) - 0x80000000;
3797 HOST_WIDE_INT high = value >> 31;
3799 if (high == 0 || high == -1)
3800 return 2;
3802 high >>= 1;
3804 if (low == 0)
3805 return num_insns_constant_wide (high) + 1;
3806 else if (high == 0)
3807 return num_insns_constant_wide (low) + 1;
3808 else
3809 return (num_insns_constant_wide (high)
3810 + num_insns_constant_wide (low) + 1);
3812 #endif
3814 else
3815 return 2;
3819 num_insns_constant (rtx op, enum machine_mode mode)
3821 HOST_WIDE_INT low, high;
3823 switch (GET_CODE (op))
3825 case CONST_INT:
3826 #if HOST_BITS_PER_WIDE_INT == 64
3827 if ((INTVAL (op) >> 31) != 0 && (INTVAL (op) >> 31) != -1
3828 && mask64_operand (op, mode))
3829 return 2;
3830 else
3831 #endif
3832 return num_insns_constant_wide (INTVAL (op));
3834 case CONST_DOUBLE:
3835 if (mode == SFmode || mode == SDmode)
3837 long l;
3838 REAL_VALUE_TYPE rv;
3840 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
3841 if (DECIMAL_FLOAT_MODE_P (mode))
3842 REAL_VALUE_TO_TARGET_DECIMAL32 (rv, l);
3843 else
3844 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
3845 return num_insns_constant_wide ((HOST_WIDE_INT) l);
3848 if (mode == VOIDmode || mode == DImode)
3850 high = CONST_DOUBLE_HIGH (op);
3851 low = CONST_DOUBLE_LOW (op);
3853 else
3855 long l[2];
3856 REAL_VALUE_TYPE rv;
3858 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
3859 if (DECIMAL_FLOAT_MODE_P (mode))
3860 REAL_VALUE_TO_TARGET_DECIMAL64 (rv, l);
3861 else
3862 REAL_VALUE_TO_TARGET_DOUBLE (rv, l);
3863 high = l[WORDS_BIG_ENDIAN == 0];
3864 low = l[WORDS_BIG_ENDIAN != 0];
3867 if (TARGET_32BIT)
3868 return (num_insns_constant_wide (low)
3869 + num_insns_constant_wide (high));
3870 else
3872 if ((high == 0 && low >= 0)
3873 || (high == -1 && low < 0))
3874 return num_insns_constant_wide (low);
3876 else if (mask64_operand (op, mode))
3877 return 2;
3879 else if (low == 0)
3880 return num_insns_constant_wide (high) + 1;
3882 else
3883 return (num_insns_constant_wide (high)
3884 + num_insns_constant_wide (low) + 1);
3887 default:
3888 gcc_unreachable ();
3892 /* Interpret element ELT of the CONST_VECTOR OP as an integer value.
3893 If the mode of OP is MODE_VECTOR_INT, this simply returns the
3894 corresponding element of the vector, but for V4SFmode and V2SFmode,
3895 the corresponding "float" is interpreted as an SImode integer. */
3897 HOST_WIDE_INT
3898 const_vector_elt_as_int (rtx op, unsigned int elt)
3900 rtx tmp = CONST_VECTOR_ELT (op, elt);
3901 if (GET_MODE (op) == V4SFmode
3902 || GET_MODE (op) == V2SFmode)
3903 tmp = gen_lowpart (SImode, tmp);
3904 return INTVAL (tmp);
3907 /* Return true if OP can be synthesized with a particular vspltisb, vspltish
3908 or vspltisw instruction. OP is a CONST_VECTOR. Which instruction is used
3909 depends on STEP and COPIES, one of which will be 1. If COPIES > 1,
3910 all items are set to the same value and contain COPIES replicas of the
3911 vsplt's operand; if STEP > 1, one in STEP elements is set to the vsplt's
3912 operand and the others are set to the value of the operand's msb. */
3914 static bool
3915 vspltis_constant (rtx op, unsigned step, unsigned copies)
3917 enum machine_mode mode = GET_MODE (op);
3918 enum machine_mode inner = GET_MODE_INNER (mode);
3920 unsigned i;
3921 unsigned nunits = GET_MODE_NUNITS (mode);
3922 unsigned bitsize = GET_MODE_BITSIZE (inner);
3923 unsigned mask = GET_MODE_MASK (inner);
3925 HOST_WIDE_INT val = const_vector_elt_as_int (op, nunits - 1);
3926 HOST_WIDE_INT splat_val = val;
3927 HOST_WIDE_INT msb_val = val > 0 ? 0 : -1;
3929 /* Construct the value to be splatted, if possible. If not, return 0. */
3930 for (i = 2; i <= copies; i *= 2)
3932 HOST_WIDE_INT small_val;
3933 bitsize /= 2;
3934 small_val = splat_val >> bitsize;
3935 mask >>= bitsize;
3936 if (splat_val != ((small_val << bitsize) | (small_val & mask)))
3937 return false;
3938 splat_val = small_val;
3941 /* Check if SPLAT_VAL can really be the operand of a vspltis[bhw]. */
3942 if (EASY_VECTOR_15 (splat_val))
3945 /* Also check if we can splat, and then add the result to itself. Do so if
3946 the value is positive, of if the splat instruction is using OP's mode;
3947 for splat_val < 0, the splat and the add should use the same mode. */
3948 else if (EASY_VECTOR_15_ADD_SELF (splat_val)
3949 && (splat_val >= 0 || (step == 1 && copies == 1)))
3952 /* Also check if are loading up the most significant bit which can be done by
3953 loading up -1 and shifting the value left by -1. */
3954 else if (EASY_VECTOR_MSB (splat_val, inner))
3957 else
3958 return false;
3960 /* Check if VAL is present in every STEP-th element, and the
3961 other elements are filled with its most significant bit. */
3962 for (i = 0; i < nunits - 1; ++i)
3964 HOST_WIDE_INT desired_val;
3965 if (((i + 1) & (step - 1)) == 0)
3966 desired_val = val;
3967 else
3968 desired_val = msb_val;
3970 if (desired_val != const_vector_elt_as_int (op, i))
3971 return false;
3974 return true;
3978 /* Return true if OP is of the given MODE and can be synthesized
3979 with a vspltisb, vspltish or vspltisw. */
3981 bool
3982 easy_altivec_constant (rtx op, enum machine_mode mode)
3984 unsigned step, copies;
3986 if (mode == VOIDmode)
3987 mode = GET_MODE (op);
3988 else if (mode != GET_MODE (op))
3989 return false;
3991 /* Start with a vspltisw. */
3992 step = GET_MODE_NUNITS (mode) / 4;
3993 copies = 1;
3995 if (vspltis_constant (op, step, copies))
3996 return true;
3998 /* Then try with a vspltish. */
3999 if (step == 1)
4000 copies <<= 1;
4001 else
4002 step >>= 1;
4004 if (vspltis_constant (op, step, copies))
4005 return true;
4007 /* And finally a vspltisb. */
4008 if (step == 1)
4009 copies <<= 1;
4010 else
4011 step >>= 1;
4013 if (vspltis_constant (op, step, copies))
4014 return true;
4016 return false;
4019 /* Generate a VEC_DUPLICATE representing a vspltis[bhw] instruction whose
4020 result is OP. Abort if it is not possible. */
4023 gen_easy_altivec_constant (rtx op)
4025 enum machine_mode mode = GET_MODE (op);
4026 int nunits = GET_MODE_NUNITS (mode);
4027 rtx last = CONST_VECTOR_ELT (op, nunits - 1);
4028 unsigned step = nunits / 4;
4029 unsigned copies = 1;
4031 /* Start with a vspltisw. */
4032 if (vspltis_constant (op, step, copies))
4033 return gen_rtx_VEC_DUPLICATE (V4SImode, gen_lowpart (SImode, last));
4035 /* Then try with a vspltish. */
4036 if (step == 1)
4037 copies <<= 1;
4038 else
4039 step >>= 1;
4041 if (vspltis_constant (op, step, copies))
4042 return gen_rtx_VEC_DUPLICATE (V8HImode, gen_lowpart (HImode, last));
4044 /* And finally a vspltisb. */
4045 if (step == 1)
4046 copies <<= 1;
4047 else
4048 step >>= 1;
4050 if (vspltis_constant (op, step, copies))
4051 return gen_rtx_VEC_DUPLICATE (V16QImode, gen_lowpart (QImode, last));
4053 gcc_unreachable ();
4056 const char *
4057 output_vec_const_move (rtx *operands)
4059 int cst, cst2;
4060 enum machine_mode mode;
4061 rtx dest, vec;
4063 dest = operands[0];
4064 vec = operands[1];
4065 mode = GET_MODE (dest);
4067 if (TARGET_VSX && zero_constant (vec, mode))
4068 return "xxlxor %x0,%x0,%x0";
4070 if (TARGET_ALTIVEC)
4072 rtx splat_vec;
4073 if (zero_constant (vec, mode))
4074 return "vxor %0,%0,%0";
4076 splat_vec = gen_easy_altivec_constant (vec);
4077 gcc_assert (GET_CODE (splat_vec) == VEC_DUPLICATE);
4078 operands[1] = XEXP (splat_vec, 0);
4079 if (!EASY_VECTOR_15 (INTVAL (operands[1])))
4080 return "#";
4082 switch (GET_MODE (splat_vec))
4084 case V4SImode:
4085 return "vspltisw %0,%1";
4087 case V8HImode:
4088 return "vspltish %0,%1";
4090 case V16QImode:
4091 return "vspltisb %0,%1";
4093 default:
4094 gcc_unreachable ();
4098 gcc_assert (TARGET_SPE);
4100 /* Vector constant 0 is handled as a splitter of V2SI, and in the
4101 pattern of V1DI, V4HI, and V2SF.
4103 FIXME: We should probably return # and add post reload
4104 splitters for these, but this way is so easy ;-). */
4105 cst = INTVAL (CONST_VECTOR_ELT (vec, 0));
4106 cst2 = INTVAL (CONST_VECTOR_ELT (vec, 1));
4107 operands[1] = CONST_VECTOR_ELT (vec, 0);
4108 operands[2] = CONST_VECTOR_ELT (vec, 1);
4109 if (cst == cst2)
4110 return "li %0,%1\n\tevmergelo %0,%0,%0";
4111 else
4112 return "li %0,%1\n\tevmergelo %0,%0,%0\n\tli %0,%2";
4115 /* Initialize TARGET of vector PAIRED to VALS. */
4117 void
4118 paired_expand_vector_init (rtx target, rtx vals)
4120 enum machine_mode mode = GET_MODE (target);
4121 int n_elts = GET_MODE_NUNITS (mode);
4122 int n_var = 0;
4123 rtx x, new_rtx, tmp, constant_op, op1, op2;
4124 int i;
4126 for (i = 0; i < n_elts; ++i)
4128 x = XVECEXP (vals, 0, i);
4129 if (!CONSTANT_P (x))
4130 ++n_var;
4132 if (n_var == 0)
4134 /* Load from constant pool. */
4135 emit_move_insn (target, gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0)));
4136 return;
4139 if (n_var == 2)
4141 /* The vector is initialized only with non-constants. */
4142 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, XVECEXP (vals, 0, 0),
4143 XVECEXP (vals, 0, 1));
4145 emit_move_insn (target, new_rtx);
4146 return;
4149 /* One field is non-constant and the other one is a constant. Load the
4150 constant from the constant pool and use ps_merge instruction to
4151 construct the whole vector. */
4152 op1 = XVECEXP (vals, 0, 0);
4153 op2 = XVECEXP (vals, 0, 1);
4155 constant_op = (CONSTANT_P (op1)) ? op1 : op2;
4157 tmp = gen_reg_rtx (GET_MODE (constant_op));
4158 emit_move_insn (tmp, constant_op);
4160 if (CONSTANT_P (op1))
4161 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, tmp, op2);
4162 else
4163 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, op1, tmp);
4165 emit_move_insn (target, new_rtx);
4168 void
4169 paired_expand_vector_move (rtx operands[])
4171 rtx op0 = operands[0], op1 = operands[1];
4173 emit_move_insn (op0, op1);
4176 /* Emit vector compare for code RCODE. DEST is destination, OP1 and
4177 OP2 are two VEC_COND_EXPR operands, CC_OP0 and CC_OP1 are the two
4178 operands for the relation operation COND. This is a recursive
4179 function. */
4181 static void
4182 paired_emit_vector_compare (enum rtx_code rcode,
4183 rtx dest, rtx op0, rtx op1,
4184 rtx cc_op0, rtx cc_op1)
4186 rtx tmp = gen_reg_rtx (V2SFmode);
4187 rtx tmp1, max, min, equal_zero;
4189 gcc_assert (TARGET_PAIRED_FLOAT);
4190 gcc_assert (GET_MODE (op0) == GET_MODE (op1));
4192 switch (rcode)
4194 case LT:
4195 case LTU:
4196 paired_emit_vector_compare (GE, dest, op1, op0, cc_op0, cc_op1);
4197 return;
4198 case GE:
4199 case GEU:
4200 emit_insn (gen_subv2sf3 (tmp, cc_op0, cc_op1));
4201 emit_insn (gen_selv2sf4 (dest, tmp, op0, op1, CONST0_RTX (SFmode)));
4202 return;
4203 case LE:
4204 case LEU:
4205 paired_emit_vector_compare (GE, dest, op0, op1, cc_op1, cc_op0);
4206 return;
4207 case GT:
4208 paired_emit_vector_compare (LE, dest, op1, op0, cc_op0, cc_op1);
4209 return;
4210 case EQ:
4211 tmp1 = gen_reg_rtx (V2SFmode);
4212 max = gen_reg_rtx (V2SFmode);
4213 min = gen_reg_rtx (V2SFmode);
4214 equal_zero = gen_reg_rtx (V2SFmode);
4216 emit_insn (gen_subv2sf3 (tmp, cc_op0, cc_op1));
4217 emit_insn (gen_selv2sf4
4218 (max, tmp, cc_op0, cc_op1, CONST0_RTX (SFmode)));
4219 emit_insn (gen_subv2sf3 (tmp, cc_op1, cc_op0));
4220 emit_insn (gen_selv2sf4
4221 (min, tmp, cc_op0, cc_op1, CONST0_RTX (SFmode)));
4222 emit_insn (gen_subv2sf3 (tmp1, min, max));
4223 emit_insn (gen_selv2sf4 (dest, tmp1, op0, op1, CONST0_RTX (SFmode)));
4224 return;
4225 case NE:
4226 paired_emit_vector_compare (EQ, dest, op1, op0, cc_op0, cc_op1);
4227 return;
4228 case UNLE:
4229 paired_emit_vector_compare (LE, dest, op1, op0, cc_op0, cc_op1);
4230 return;
4231 case UNLT:
4232 paired_emit_vector_compare (LT, dest, op1, op0, cc_op0, cc_op1);
4233 return;
4234 case UNGE:
4235 paired_emit_vector_compare (GE, dest, op1, op0, cc_op0, cc_op1);
4236 return;
4237 case UNGT:
4238 paired_emit_vector_compare (GT, dest, op1, op0, cc_op0, cc_op1);
4239 return;
4240 default:
4241 gcc_unreachable ();
4244 return;
4247 /* Emit vector conditional expression.
4248 DEST is destination. OP1 and OP2 are two VEC_COND_EXPR operands.
4249 CC_OP0 and CC_OP1 are the two operands for the relation operation COND. */
4252 paired_emit_vector_cond_expr (rtx dest, rtx op1, rtx op2,
4253 rtx cond, rtx cc_op0, rtx cc_op1)
4255 enum rtx_code rcode = GET_CODE (cond);
4257 if (!TARGET_PAIRED_FLOAT)
4258 return 0;
4260 paired_emit_vector_compare (rcode, dest, op1, op2, cc_op0, cc_op1);
4262 return 1;
4265 /* Initialize vector TARGET to VALS. */
4267 void
4268 rs6000_expand_vector_init (rtx target, rtx vals)
4270 enum machine_mode mode = GET_MODE (target);
4271 enum machine_mode inner_mode = GET_MODE_INNER (mode);
4272 int n_elts = GET_MODE_NUNITS (mode);
4273 int n_var = 0, one_var = -1;
4274 bool all_same = true, all_const_zero = true;
4275 rtx x, mem;
4276 int i;
4278 for (i = 0; i < n_elts; ++i)
4280 x = XVECEXP (vals, 0, i);
4281 if (!CONSTANT_P (x))
4282 ++n_var, one_var = i;
4283 else if (x != CONST0_RTX (inner_mode))
4284 all_const_zero = false;
4286 if (i > 0 && !rtx_equal_p (x, XVECEXP (vals, 0, 0)))
4287 all_same = false;
4290 if (n_var == 0)
4292 rtx const_vec = gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0));
4293 bool int_vector_p = (GET_MODE_CLASS (mode) == MODE_VECTOR_INT);
4294 if ((int_vector_p || TARGET_VSX) && all_const_zero)
4296 /* Zero register. */
4297 emit_insn (gen_rtx_SET (VOIDmode, target,
4298 gen_rtx_XOR (mode, target, target)));
4299 return;
4301 else if (int_vector_p && easy_vector_constant (const_vec, mode))
4303 /* Splat immediate. */
4304 emit_insn (gen_rtx_SET (VOIDmode, target, const_vec));
4305 return;
4307 else
4309 /* Load from constant pool. */
4310 emit_move_insn (target, const_vec);
4311 return;
4315 /* Double word values on VSX can use xxpermdi or lxvdsx. */
4316 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
4318 if (all_same)
4320 rtx element = XVECEXP (vals, 0, 0);
4321 if (mode == V2DFmode)
4322 emit_insn (gen_vsx_splat_v2df (target, element));
4323 else
4324 emit_insn (gen_vsx_splat_v2di (target, element));
4326 else
4328 rtx op0 = copy_to_reg (XVECEXP (vals, 0, 0));
4329 rtx op1 = copy_to_reg (XVECEXP (vals, 0, 1));
4330 if (mode == V2DFmode)
4331 emit_insn (gen_vsx_concat_v2df (target, op0, op1));
4332 else
4333 emit_insn (gen_vsx_concat_v2di (target, op0, op1));
4335 return;
4338 /* With single precision floating point on VSX, know that internally single
4339 precision is actually represented as a double, and either make 2 V2DF
4340 vectors, and convert these vectors to single precision, or do one
4341 conversion, and splat the result to the other elements. */
4342 if (mode == V4SFmode && VECTOR_MEM_VSX_P (mode))
4344 if (all_same)
4346 rtx freg = gen_reg_rtx (V4SFmode);
4347 rtx sreg = copy_to_reg (XVECEXP (vals, 0, 0));
4349 emit_insn (gen_vsx_xscvdpsp_scalar (freg, sreg));
4350 emit_insn (gen_vsx_xxspltw_v4sf (target, freg, const0_rtx));
4352 else
4354 rtx dbl_even = gen_reg_rtx (V2DFmode);
4355 rtx dbl_odd = gen_reg_rtx (V2DFmode);
4356 rtx flt_even = gen_reg_rtx (V4SFmode);
4357 rtx flt_odd = gen_reg_rtx (V4SFmode);
4359 emit_insn (gen_vsx_concat_v2sf (dbl_even,
4360 copy_to_reg (XVECEXP (vals, 0, 0)),
4361 copy_to_reg (XVECEXP (vals, 0, 1))));
4362 emit_insn (gen_vsx_concat_v2sf (dbl_odd,
4363 copy_to_reg (XVECEXP (vals, 0, 2)),
4364 copy_to_reg (XVECEXP (vals, 0, 3))));
4365 emit_insn (gen_vsx_xvcvdpsp (flt_even, dbl_even));
4366 emit_insn (gen_vsx_xvcvdpsp (flt_odd, dbl_odd));
4367 emit_insn (gen_vec_extract_evenv4sf (target, flt_even, flt_odd));
4369 return;
4372 /* Store value to stack temp. Load vector element. Splat. However, splat
4373 of 64-bit items is not supported on Altivec. */
4374 if (all_same && GET_MODE_SIZE (mode) <= 4)
4376 mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0);
4377 emit_move_insn (adjust_address_nv (mem, inner_mode, 0),
4378 XVECEXP (vals, 0, 0));
4379 x = gen_rtx_UNSPEC (VOIDmode,
4380 gen_rtvec (1, const0_rtx), UNSPEC_LVE);
4381 emit_insn (gen_rtx_PARALLEL (VOIDmode,
4382 gen_rtvec (2,
4383 gen_rtx_SET (VOIDmode,
4384 target, mem),
4385 x)));
4386 x = gen_rtx_VEC_SELECT (inner_mode, target,
4387 gen_rtx_PARALLEL (VOIDmode,
4388 gen_rtvec (1, const0_rtx)));
4389 emit_insn (gen_rtx_SET (VOIDmode, target,
4390 gen_rtx_VEC_DUPLICATE (mode, x)));
4391 return;
4394 /* One field is non-constant. Load constant then overwrite
4395 varying field. */
4396 if (n_var == 1)
4398 rtx copy = copy_rtx (vals);
4400 /* Load constant part of vector, substitute neighboring value for
4401 varying element. */
4402 XVECEXP (copy, 0, one_var) = XVECEXP (vals, 0, (one_var + 1) % n_elts);
4403 rs6000_expand_vector_init (target, copy);
4405 /* Insert variable. */
4406 rs6000_expand_vector_set (target, XVECEXP (vals, 0, one_var), one_var);
4407 return;
4410 /* Construct the vector in memory one field at a time
4411 and load the whole vector. */
4412 mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
4413 for (i = 0; i < n_elts; i++)
4414 emit_move_insn (adjust_address_nv (mem, inner_mode,
4415 i * GET_MODE_SIZE (inner_mode)),
4416 XVECEXP (vals, 0, i));
4417 emit_move_insn (target, mem);
4420 /* Set field ELT of TARGET to VAL. */
4422 void
4423 rs6000_expand_vector_set (rtx target, rtx val, int elt)
4425 enum machine_mode mode = GET_MODE (target);
4426 enum machine_mode inner_mode = GET_MODE_INNER (mode);
4427 rtx reg = gen_reg_rtx (mode);
4428 rtx mask, mem, x;
4429 int width = GET_MODE_SIZE (inner_mode);
4430 int i;
4432 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
4434 rtx (*set_func) (rtx, rtx, rtx, rtx)
4435 = ((mode == V2DFmode) ? gen_vsx_set_v2df : gen_vsx_set_v2di);
4436 emit_insn (set_func (target, target, val, GEN_INT (elt)));
4437 return;
4440 /* Load single variable value. */
4441 mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0);
4442 emit_move_insn (adjust_address_nv (mem, inner_mode, 0), val);
4443 x = gen_rtx_UNSPEC (VOIDmode,
4444 gen_rtvec (1, const0_rtx), UNSPEC_LVE);
4445 emit_insn (gen_rtx_PARALLEL (VOIDmode,
4446 gen_rtvec (2,
4447 gen_rtx_SET (VOIDmode,
4448 reg, mem),
4449 x)));
4451 /* Linear sequence. */
4452 mask = gen_rtx_PARALLEL (V16QImode, rtvec_alloc (16));
4453 for (i = 0; i < 16; ++i)
4454 XVECEXP (mask, 0, i) = GEN_INT (i);
4456 /* Set permute mask to insert element into target. */
4457 for (i = 0; i < width; ++i)
4458 XVECEXP (mask, 0, elt*width + i)
4459 = GEN_INT (i + 0x10);
4460 x = gen_rtx_CONST_VECTOR (V16QImode, XVEC (mask, 0));
4461 x = gen_rtx_UNSPEC (mode,
4462 gen_rtvec (3, target, reg,
4463 force_reg (V16QImode, x)),
4464 UNSPEC_VPERM);
4465 emit_insn (gen_rtx_SET (VOIDmode, target, x));
4468 /* Extract field ELT from VEC into TARGET. */
4470 void
4471 rs6000_expand_vector_extract (rtx target, rtx vec, int elt)
4473 enum machine_mode mode = GET_MODE (vec);
4474 enum machine_mode inner_mode = GET_MODE_INNER (mode);
4475 rtx mem, x;
4477 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
4479 rtx (*extract_func) (rtx, rtx, rtx)
4480 = ((mode == V2DFmode) ? gen_vsx_extract_v2df : gen_vsx_extract_v2di);
4481 emit_insn (extract_func (target, vec, GEN_INT (elt)));
4482 return;
4485 /* Allocate mode-sized buffer. */
4486 mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
4488 /* Add offset to field within buffer matching vector element. */
4489 mem = adjust_address_nv (mem, mode, elt * GET_MODE_SIZE (inner_mode));
4491 /* Store single field into mode-sized buffer. */
4492 x = gen_rtx_UNSPEC (VOIDmode,
4493 gen_rtvec (1, const0_rtx), UNSPEC_STVE);
4494 emit_insn (gen_rtx_PARALLEL (VOIDmode,
4495 gen_rtvec (2,
4496 gen_rtx_SET (VOIDmode,
4497 mem, vec),
4498 x)));
4499 emit_move_insn (target, adjust_address_nv (mem, inner_mode, 0));
4502 /* Generates shifts and masks for a pair of rldicl or rldicr insns to
4503 implement ANDing by the mask IN. */
4504 void
4505 build_mask64_2_operands (rtx in, rtx *out)
4507 #if HOST_BITS_PER_WIDE_INT >= 64
4508 unsigned HOST_WIDE_INT c, lsb, m1, m2;
4509 int shift;
4511 gcc_assert (GET_CODE (in) == CONST_INT);
4513 c = INTVAL (in);
4514 if (c & 1)
4516 /* Assume c initially something like 0x00fff000000fffff. The idea
4517 is to rotate the word so that the middle ^^^^^^ group of zeros
4518 is at the MS end and can be cleared with an rldicl mask. We then
4519 rotate back and clear off the MS ^^ group of zeros with a
4520 second rldicl. */
4521 c = ~c; /* c == 0xff000ffffff00000 */
4522 lsb = c & -c; /* lsb == 0x0000000000100000 */
4523 m1 = -lsb; /* m1 == 0xfffffffffff00000 */
4524 c = ~c; /* c == 0x00fff000000fffff */
4525 c &= -lsb; /* c == 0x00fff00000000000 */
4526 lsb = c & -c; /* lsb == 0x0000100000000000 */
4527 c = ~c; /* c == 0xff000fffffffffff */
4528 c &= -lsb; /* c == 0xff00000000000000 */
4529 shift = 0;
4530 while ((lsb >>= 1) != 0)
4531 shift++; /* shift == 44 on exit from loop */
4532 m1 <<= 64 - shift; /* m1 == 0xffffff0000000000 */
4533 m1 = ~m1; /* m1 == 0x000000ffffffffff */
4534 m2 = ~c; /* m2 == 0x00ffffffffffffff */
4536 else
4538 /* Assume c initially something like 0xff000f0000000000. The idea
4539 is to rotate the word so that the ^^^ middle group of zeros
4540 is at the LS end and can be cleared with an rldicr mask. We then
4541 rotate back and clear off the LS group of ^^^^^^^^^^ zeros with
4542 a second rldicr. */
4543 lsb = c & -c; /* lsb == 0x0000010000000000 */
4544 m2 = -lsb; /* m2 == 0xffffff0000000000 */
4545 c = ~c; /* c == 0x00fff0ffffffffff */
4546 c &= -lsb; /* c == 0x00fff00000000000 */
4547 lsb = c & -c; /* lsb == 0x0000100000000000 */
4548 c = ~c; /* c == 0xff000fffffffffff */
4549 c &= -lsb; /* c == 0xff00000000000000 */
4550 shift = 0;
4551 while ((lsb >>= 1) != 0)
4552 shift++; /* shift == 44 on exit from loop */
4553 m1 = ~c; /* m1 == 0x00ffffffffffffff */
4554 m1 >>= shift; /* m1 == 0x0000000000000fff */
4555 m1 = ~m1; /* m1 == 0xfffffffffffff000 */
4558 /* Note that when we only have two 0->1 and 1->0 transitions, one of the
4559 masks will be all 1's. We are guaranteed more than one transition. */
4560 out[0] = GEN_INT (64 - shift);
4561 out[1] = GEN_INT (m1);
4562 out[2] = GEN_INT (shift);
4563 out[3] = GEN_INT (m2);
4564 #else
4565 (void)in;
4566 (void)out;
4567 gcc_unreachable ();
4568 #endif
4571 /* Return TRUE if OP is an invalid SUBREG operation on the e500. */
4573 bool
4574 invalid_e500_subreg (rtx op, enum machine_mode mode)
4576 if (TARGET_E500_DOUBLE)
4578 /* Reject (subreg:SI (reg:DF)); likewise with subreg:DI or
4579 subreg:TI and reg:TF. Decimal float modes are like integer
4580 modes (only low part of each register used) for this
4581 purpose. */
4582 if (GET_CODE (op) == SUBREG
4583 && (mode == SImode || mode == DImode || mode == TImode
4584 || mode == DDmode || mode == TDmode)
4585 && REG_P (SUBREG_REG (op))
4586 && (GET_MODE (SUBREG_REG (op)) == DFmode
4587 || GET_MODE (SUBREG_REG (op)) == TFmode))
4588 return true;
4590 /* Reject (subreg:DF (reg:DI)); likewise with subreg:TF and
4591 reg:TI. */
4592 if (GET_CODE (op) == SUBREG
4593 && (mode == DFmode || mode == TFmode)
4594 && REG_P (SUBREG_REG (op))
4595 && (GET_MODE (SUBREG_REG (op)) == DImode
4596 || GET_MODE (SUBREG_REG (op)) == TImode
4597 || GET_MODE (SUBREG_REG (op)) == DDmode
4598 || GET_MODE (SUBREG_REG (op)) == TDmode))
4599 return true;
4602 if (TARGET_SPE
4603 && GET_CODE (op) == SUBREG
4604 && mode == SImode
4605 && REG_P (SUBREG_REG (op))
4606 && SPE_VECTOR_MODE (GET_MODE (SUBREG_REG (op))))
4607 return true;
4609 return false;
4612 /* AIX increases natural record alignment to doubleword if the first
4613 field is an FP double while the FP fields remain word aligned. */
4615 unsigned int
4616 rs6000_special_round_type_align (tree type, unsigned int computed,
4617 unsigned int specified)
4619 unsigned int align = MAX (computed, specified);
4620 tree field = TYPE_FIELDS (type);
4622 /* Skip all non field decls */
4623 while (field != NULL && TREE_CODE (field) != FIELD_DECL)
4624 field = TREE_CHAIN (field);
4626 if (field != NULL && field != type)
4628 type = TREE_TYPE (field);
4629 while (TREE_CODE (type) == ARRAY_TYPE)
4630 type = TREE_TYPE (type);
4632 if (type != error_mark_node && TYPE_MODE (type) == DFmode)
4633 align = MAX (align, 64);
4636 return align;
4639 /* Darwin increases record alignment to the natural alignment of
4640 the first field. */
4642 unsigned int
4643 darwin_rs6000_special_round_type_align (tree type, unsigned int computed,
4644 unsigned int specified)
4646 unsigned int align = MAX (computed, specified);
4648 if (TYPE_PACKED (type))
4649 return align;
4651 /* Find the first field, looking down into aggregates. */
4652 do {
4653 tree field = TYPE_FIELDS (type);
4654 /* Skip all non field decls */
4655 while (field != NULL && TREE_CODE (field) != FIELD_DECL)
4656 field = TREE_CHAIN (field);
4657 if (! field)
4658 break;
4659 type = TREE_TYPE (field);
4660 while (TREE_CODE (type) == ARRAY_TYPE)
4661 type = TREE_TYPE (type);
4662 } while (AGGREGATE_TYPE_P (type));
4664 if (! AGGREGATE_TYPE_P (type) && type != error_mark_node)
4665 align = MAX (align, TYPE_ALIGN (type));
4667 return align;
4670 /* Return 1 for an operand in small memory on V.4/eabi. */
4673 small_data_operand (rtx op ATTRIBUTE_UNUSED,
4674 enum machine_mode mode ATTRIBUTE_UNUSED)
4676 #if TARGET_ELF
4677 rtx sym_ref;
4679 if (rs6000_sdata == SDATA_NONE || rs6000_sdata == SDATA_DATA)
4680 return 0;
4682 if (DEFAULT_ABI != ABI_V4)
4683 return 0;
4685 /* Vector and float memory instructions have a limited offset on the
4686 SPE, so using a vector or float variable directly as an operand is
4687 not useful. */
4688 if (TARGET_SPE
4689 && (SPE_VECTOR_MODE (mode) || FLOAT_MODE_P (mode)))
4690 return 0;
4692 if (GET_CODE (op) == SYMBOL_REF)
4693 sym_ref = op;
4695 else if (GET_CODE (op) != CONST
4696 || GET_CODE (XEXP (op, 0)) != PLUS
4697 || GET_CODE (XEXP (XEXP (op, 0), 0)) != SYMBOL_REF
4698 || GET_CODE (XEXP (XEXP (op, 0), 1)) != CONST_INT)
4699 return 0;
4701 else
4703 rtx sum = XEXP (op, 0);
4704 HOST_WIDE_INT summand;
4706 /* We have to be careful here, because it is the referenced address
4707 that must be 32k from _SDA_BASE_, not just the symbol. */
4708 summand = INTVAL (XEXP (sum, 1));
4709 if (summand < 0 || (unsigned HOST_WIDE_INT) summand > g_switch_value)
4710 return 0;
4712 sym_ref = XEXP (sum, 0);
4715 return SYMBOL_REF_SMALL_P (sym_ref);
4716 #else
4717 return 0;
4718 #endif
4721 /* Return true if either operand is a general purpose register. */
4723 bool
4724 gpr_or_gpr_p (rtx op0, rtx op1)
4726 return ((REG_P (op0) && INT_REGNO_P (REGNO (op0)))
4727 || (REG_P (op1) && INT_REGNO_P (REGNO (op1))));
4731 /* Subroutines of rs6000_legitimize_address and rs6000_legitimate_address_p. */
4733 static bool
4734 reg_offset_addressing_ok_p (enum machine_mode mode)
4736 switch (mode)
4738 case V16QImode:
4739 case V8HImode:
4740 case V4SFmode:
4741 case V4SImode:
4742 case V2DFmode:
4743 case V2DImode:
4744 /* AltiVec/VSX vector modes. Only reg+reg addressing is valid. */
4745 if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode))
4746 return false;
4747 break;
4749 case V4HImode:
4750 case V2SImode:
4751 case V1DImode:
4752 case V2SFmode:
4753 /* Paired vector modes. Only reg+reg addressing is valid. */
4754 if (TARGET_PAIRED_FLOAT)
4755 return false;
4756 break;
4758 default:
4759 break;
4762 return true;
4765 static bool
4766 virtual_stack_registers_memory_p (rtx op)
4768 int regnum;
4770 if (GET_CODE (op) == REG)
4771 regnum = REGNO (op);
4773 else if (GET_CODE (op) == PLUS
4774 && GET_CODE (XEXP (op, 0)) == REG
4775 && GET_CODE (XEXP (op, 1)) == CONST_INT)
4776 regnum = REGNO (XEXP (op, 0));
4778 else
4779 return false;
4781 return (regnum >= FIRST_VIRTUAL_REGISTER
4782 && regnum <= LAST_VIRTUAL_REGISTER);
4785 static bool
4786 constant_pool_expr_p (rtx op)
4788 rtx base, offset;
4790 split_const (op, &base, &offset);
4791 return (GET_CODE (base) == SYMBOL_REF
4792 && CONSTANT_POOL_ADDRESS_P (base)
4793 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (base), Pmode));
4796 bool
4797 toc_relative_expr_p (rtx op)
4799 rtx base, offset;
4801 if (GET_CODE (op) != CONST)
4802 return false;
4804 split_const (op, &base, &offset);
4805 return (GET_CODE (base) == UNSPEC
4806 && XINT (base, 1) == UNSPEC_TOCREL);
4809 bool
4810 legitimate_constant_pool_address_p (rtx x)
4812 return (TARGET_TOC
4813 && GET_CODE (x) == PLUS
4814 && GET_CODE (XEXP (x, 0)) == REG
4815 && (TARGET_MINIMAL_TOC || REGNO (XEXP (x, 0)) == TOC_REGISTER)
4816 && toc_relative_expr_p (XEXP (x, 1)));
4819 static bool
4820 legitimate_small_data_p (enum machine_mode mode, rtx x)
4822 return (DEFAULT_ABI == ABI_V4
4823 && !flag_pic && !TARGET_TOC
4824 && (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST)
4825 && small_data_operand (x, mode));
4828 /* SPE offset addressing is limited to 5-bits worth of double words. */
4829 #define SPE_CONST_OFFSET_OK(x) (((x) & ~0xf8) == 0)
4831 bool
4832 rs6000_legitimate_offset_address_p (enum machine_mode mode, rtx x, int strict)
4834 unsigned HOST_WIDE_INT offset, extra;
4836 if (GET_CODE (x) != PLUS)
4837 return false;
4838 if (GET_CODE (XEXP (x, 0)) != REG)
4839 return false;
4840 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
4841 return false;
4842 if (!reg_offset_addressing_ok_p (mode))
4843 return virtual_stack_registers_memory_p (x);
4844 if (legitimate_constant_pool_address_p (x))
4845 return true;
4846 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
4847 return false;
4849 offset = INTVAL (XEXP (x, 1));
4850 extra = 0;
4851 switch (mode)
4853 case V4HImode:
4854 case V2SImode:
4855 case V1DImode:
4856 case V2SFmode:
4857 /* SPE vector modes. */
4858 return SPE_CONST_OFFSET_OK (offset);
4860 case DFmode:
4861 if (TARGET_E500_DOUBLE)
4862 return SPE_CONST_OFFSET_OK (offset);
4864 /* If we are using VSX scalar loads, restrict ourselves to reg+reg
4865 addressing. */
4866 if (VECTOR_MEM_VSX_P (DFmode))
4867 return false;
4869 case DDmode:
4870 case DImode:
4871 /* On e500v2, we may have:
4873 (subreg:DF (mem:DI (plus (reg) (const_int))) 0).
4875 Which gets addressed with evldd instructions. */
4876 if (TARGET_E500_DOUBLE)
4877 return SPE_CONST_OFFSET_OK (offset);
4879 if (mode == DFmode || mode == DDmode || !TARGET_POWERPC64)
4880 extra = 4;
4881 else if (offset & 3)
4882 return false;
4883 break;
4885 case TFmode:
4886 if (TARGET_E500_DOUBLE)
4887 return (SPE_CONST_OFFSET_OK (offset)
4888 && SPE_CONST_OFFSET_OK (offset + 8));
4890 case TDmode:
4891 case TImode:
4892 if (mode == TFmode || mode == TDmode || !TARGET_POWERPC64)
4893 extra = 12;
4894 else if (offset & 3)
4895 return false;
4896 else
4897 extra = 8;
4898 break;
4900 default:
4901 break;
4904 offset += 0x8000;
4905 return (offset < 0x10000) && (offset + extra < 0x10000);
4908 bool
4909 legitimate_indexed_address_p (rtx x, int strict)
4911 rtx op0, op1;
4913 if (GET_CODE (x) != PLUS)
4914 return false;
4916 op0 = XEXP (x, 0);
4917 op1 = XEXP (x, 1);
4919 /* Recognize the rtl generated by reload which we know will later be
4920 replaced with proper base and index regs. */
4921 if (!strict
4922 && reload_in_progress
4923 && (REG_P (op0) || GET_CODE (op0) == PLUS)
4924 && REG_P (op1))
4925 return true;
4927 return (REG_P (op0) && REG_P (op1)
4928 && ((INT_REG_OK_FOR_BASE_P (op0, strict)
4929 && INT_REG_OK_FOR_INDEX_P (op1, strict))
4930 || (INT_REG_OK_FOR_BASE_P (op1, strict)
4931 && INT_REG_OK_FOR_INDEX_P (op0, strict))));
4934 bool
4935 avoiding_indexed_address_p (enum machine_mode mode)
4937 /* Avoid indexed addressing for modes that have non-indexed
4938 load/store instruction forms. */
4939 return (TARGET_AVOID_XFORM && VECTOR_MEM_NONE_P (mode));
4942 inline bool
4943 legitimate_indirect_address_p (rtx x, int strict)
4945 return GET_CODE (x) == REG && INT_REG_OK_FOR_BASE_P (x, strict);
4948 bool
4949 macho_lo_sum_memory_operand (rtx x, enum machine_mode mode)
4951 if (!TARGET_MACHO || !flag_pic
4952 || mode != SImode || GET_CODE (x) != MEM)
4953 return false;
4954 x = XEXP (x, 0);
4956 if (GET_CODE (x) != LO_SUM)
4957 return false;
4958 if (GET_CODE (XEXP (x, 0)) != REG)
4959 return false;
4960 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 0))
4961 return false;
4962 x = XEXP (x, 1);
4964 return CONSTANT_P (x);
4967 static bool
4968 legitimate_lo_sum_address_p (enum machine_mode mode, rtx x, int strict)
4970 if (GET_CODE (x) != LO_SUM)
4971 return false;
4972 if (GET_CODE (XEXP (x, 0)) != REG)
4973 return false;
4974 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
4975 return false;
4976 /* Restrict addressing for DI because of our SUBREG hackery. */
4977 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
4978 || mode == DDmode || mode == TDmode
4979 || mode == DImode))
4980 return false;
4981 x = XEXP (x, 1);
4983 if (TARGET_ELF || TARGET_MACHO)
4985 if (DEFAULT_ABI != ABI_AIX && DEFAULT_ABI != ABI_DARWIN && flag_pic)
4986 return false;
4987 if (TARGET_TOC)
4988 return false;
4989 if (GET_MODE_NUNITS (mode) != 1)
4990 return false;
4991 if (GET_MODE_BITSIZE (mode) > 64
4992 || (GET_MODE_BITSIZE (mode) > 32 && !TARGET_POWERPC64
4993 && !(TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
4994 && (mode == DFmode || mode == DDmode))))
4995 return false;
4997 return CONSTANT_P (x);
5000 return false;
5004 /* Try machine-dependent ways of modifying an illegitimate address
5005 to be legitimate. If we find one, return the new, valid address.
5006 This is used from only one place: `memory_address' in explow.c.
5008 OLDX is the address as it was before break_out_memory_refs was
5009 called. In some cases it is useful to look at this to decide what
5010 needs to be done.
5012 It is always safe for this function to do nothing. It exists to
5013 recognize opportunities to optimize the output.
5015 On RS/6000, first check for the sum of a register with a constant
5016 integer that is out of range. If so, generate code to add the
5017 constant with the low-order 16 bits masked to the register and force
5018 this result into another register (this can be done with `cau').
5019 Then generate an address of REG+(CONST&0xffff), allowing for the
5020 possibility of bit 16 being a one.
5022 Then check for the sum of a register and something not constant, try to
5023 load the other things into a register and return the sum. */
5025 static rtx
5026 rs6000_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
5027 enum machine_mode mode)
5029 unsigned int extra = 0;
5031 if (!reg_offset_addressing_ok_p (mode))
5033 if (virtual_stack_registers_memory_p (x))
5034 return x;
5036 /* In theory we should not be seeing addresses of the form reg+0,
5037 but just in case it is generated, optimize it away. */
5038 if (GET_CODE (x) == PLUS && XEXP (x, 1) == const0_rtx)
5039 return force_reg (Pmode, XEXP (x, 0));
5041 /* Make sure both operands are registers. */
5042 else if (GET_CODE (x) == PLUS)
5043 return gen_rtx_PLUS (Pmode,
5044 force_reg (Pmode, XEXP (x, 0)),
5045 force_reg (Pmode, XEXP (x, 1)));
5046 else
5047 return force_reg (Pmode, x);
5049 if (GET_CODE (x) == SYMBOL_REF)
5051 enum tls_model model = SYMBOL_REF_TLS_MODEL (x);
5052 if (model != 0)
5053 return rs6000_legitimize_tls_address (x, model);
5056 switch (mode)
5058 case DFmode:
5059 case DDmode:
5060 extra = 4;
5061 break;
5062 case DImode:
5063 if (!TARGET_POWERPC64)
5064 extra = 4;
5065 break;
5066 case TFmode:
5067 case TDmode:
5068 extra = 12;
5069 break;
5070 case TImode:
5071 extra = TARGET_POWERPC64 ? 8 : 12;
5072 break;
5073 default:
5074 break;
5077 if (GET_CODE (x) == PLUS
5078 && GET_CODE (XEXP (x, 0)) == REG
5079 && GET_CODE (XEXP (x, 1)) == CONST_INT
5080 && ((unsigned HOST_WIDE_INT) (INTVAL (XEXP (x, 1)) + 0x8000)
5081 >= 0x10000 - extra)
5082 && !((TARGET_POWERPC64
5083 && (mode == DImode || mode == TImode)
5084 && (INTVAL (XEXP (x, 1)) & 3) != 0)
5085 || SPE_VECTOR_MODE (mode)
5086 || (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
5087 || mode == DImode || mode == DDmode
5088 || mode == TDmode))))
5090 HOST_WIDE_INT high_int, low_int;
5091 rtx sum;
5092 low_int = ((INTVAL (XEXP (x, 1)) & 0xffff) ^ 0x8000) - 0x8000;
5093 if (low_int >= 0x8000 - extra)
5094 low_int = 0;
5095 high_int = INTVAL (XEXP (x, 1)) - low_int;
5096 sum = force_operand (gen_rtx_PLUS (Pmode, XEXP (x, 0),
5097 GEN_INT (high_int)), 0);
5098 return plus_constant (sum, low_int);
5100 else if (GET_CODE (x) == PLUS
5101 && GET_CODE (XEXP (x, 0)) == REG
5102 && GET_CODE (XEXP (x, 1)) != CONST_INT
5103 && GET_MODE_NUNITS (mode) == 1
5104 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5105 || TARGET_POWERPC64
5106 || ((mode != DImode && mode != DFmode && mode != DDmode)
5107 || (TARGET_E500_DOUBLE && mode != DDmode)))
5108 && (TARGET_POWERPC64 || mode != DImode)
5109 && !avoiding_indexed_address_p (mode)
5110 && mode != TImode
5111 && mode != TFmode
5112 && mode != TDmode)
5114 return gen_rtx_PLUS (Pmode, XEXP (x, 0),
5115 force_reg (Pmode, force_operand (XEXP (x, 1), 0)));
5117 else if (SPE_VECTOR_MODE (mode)
5118 || (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
5119 || mode == DDmode || mode == TDmode
5120 || mode == DImode)))
5122 if (mode == DImode)
5123 return x;
5124 /* We accept [reg + reg] and [reg + OFFSET]. */
5126 if (GET_CODE (x) == PLUS)
5128 rtx op1 = XEXP (x, 0);
5129 rtx op2 = XEXP (x, 1);
5130 rtx y;
5132 op1 = force_reg (Pmode, op1);
5134 if (GET_CODE (op2) != REG
5135 && (GET_CODE (op2) != CONST_INT
5136 || !SPE_CONST_OFFSET_OK (INTVAL (op2))
5137 || (GET_MODE_SIZE (mode) > 8
5138 && !SPE_CONST_OFFSET_OK (INTVAL (op2) + 8))))
5139 op2 = force_reg (Pmode, op2);
5141 /* We can't always do [reg + reg] for these, because [reg +
5142 reg + offset] is not a legitimate addressing mode. */
5143 y = gen_rtx_PLUS (Pmode, op1, op2);
5145 if ((GET_MODE_SIZE (mode) > 8 || mode == DDmode) && REG_P (op2))
5146 return force_reg (Pmode, y);
5147 else
5148 return y;
5151 return force_reg (Pmode, x);
5153 else if (TARGET_ELF
5154 && TARGET_32BIT
5155 && TARGET_NO_TOC
5156 && ! flag_pic
5157 && GET_CODE (x) != CONST_INT
5158 && GET_CODE (x) != CONST_DOUBLE
5159 && CONSTANT_P (x)
5160 && GET_MODE_NUNITS (mode) == 1
5161 && (GET_MODE_BITSIZE (mode) <= 32
5162 || ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5163 && (mode == DFmode || mode == DDmode))))
5165 rtx reg = gen_reg_rtx (Pmode);
5166 emit_insn (gen_elf_high (reg, x));
5167 return gen_rtx_LO_SUM (Pmode, reg, x);
5169 else if (TARGET_MACHO && TARGET_32BIT && TARGET_NO_TOC
5170 && ! flag_pic
5171 #if TARGET_MACHO
5172 && ! MACHO_DYNAMIC_NO_PIC_P
5173 #endif
5174 && GET_CODE (x) != CONST_INT
5175 && GET_CODE (x) != CONST_DOUBLE
5176 && CONSTANT_P (x)
5177 && GET_MODE_NUNITS (mode) == 1
5178 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5179 || (mode != DFmode && mode != DDmode))
5180 && mode != DImode
5181 && mode != TImode)
5183 rtx reg = gen_reg_rtx (Pmode);
5184 emit_insn (gen_macho_high (reg, x));
5185 return gen_rtx_LO_SUM (Pmode, reg, x);
5187 else if (TARGET_TOC
5188 && GET_CODE (x) == SYMBOL_REF
5189 && constant_pool_expr_p (x)
5190 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), Pmode))
5192 return create_TOC_reference (x);
5194 else
5195 return x;
5198 /* Debug version of rs6000_legitimize_address. */
5199 static rtx
5200 rs6000_debug_legitimize_address (rtx x, rtx oldx, enum machine_mode mode)
5202 rtx ret;
5203 rtx insns;
5205 start_sequence ();
5206 ret = rs6000_legitimize_address (x, oldx, mode);
5207 insns = get_insns ();
5208 end_sequence ();
5210 if (ret != x)
5212 fprintf (stderr,
5213 "\nrs6000_legitimize_address: mode %s, old code %s, "
5214 "new code %s, modified\n",
5215 GET_MODE_NAME (mode), GET_RTX_NAME (GET_CODE (x)),
5216 GET_RTX_NAME (GET_CODE (ret)));
5218 fprintf (stderr, "Original address:\n");
5219 debug_rtx (x);
5221 fprintf (stderr, "oldx:\n");
5222 debug_rtx (oldx);
5224 fprintf (stderr, "New address:\n");
5225 debug_rtx (ret);
5227 if (insns)
5229 fprintf (stderr, "Insns added:\n");
5230 debug_rtx_list (insns, 20);
5233 else
5235 fprintf (stderr,
5236 "\nrs6000_legitimize_address: mode %s, code %s, no change:\n",
5237 GET_MODE_NAME (mode), GET_RTX_NAME (GET_CODE (x)));
5239 debug_rtx (x);
5242 if (insns)
5243 emit_insn (insns);
5245 return ret;
5248 /* This is called from dwarf2out.c via TARGET_ASM_OUTPUT_DWARF_DTPREL.
5249 We need to emit DTP-relative relocations. */
5251 static void
5252 rs6000_output_dwarf_dtprel (FILE *file, int size, rtx x)
5254 switch (size)
5256 case 4:
5257 fputs ("\t.long\t", file);
5258 break;
5259 case 8:
5260 fputs (DOUBLE_INT_ASM_OP, file);
5261 break;
5262 default:
5263 gcc_unreachable ();
5265 output_addr_const (file, x);
5266 fputs ("@dtprel+0x8000", file);
5269 /* In the name of slightly smaller debug output, and to cater to
5270 general assembler lossage, recognize various UNSPEC sequences
5271 and turn them back into a direct symbol reference. */
5273 static rtx
5274 rs6000_delegitimize_address (rtx orig_x)
5276 rtx x, y;
5278 orig_x = delegitimize_mem_from_attrs (orig_x);
5279 x = orig_x;
5280 if (MEM_P (x))
5281 x = XEXP (x, 0);
5283 if (GET_CODE (x) == PLUS
5284 && GET_CODE (XEXP (x, 1)) == CONST
5285 && GET_CODE (XEXP (x, 0)) == REG
5286 && REGNO (XEXP (x, 0)) == TOC_REGISTER)
5288 y = XEXP (XEXP (x, 1), 0);
5289 if (GET_CODE (y) == UNSPEC
5290 && XINT (y, 1) == UNSPEC_TOCREL)
5292 y = XVECEXP (y, 0, 0);
5293 if (!MEM_P (orig_x))
5294 return y;
5295 else
5296 return replace_equiv_address_nv (orig_x, y);
5298 return orig_x;
5301 return orig_x;
5304 /* Construct the SYMBOL_REF for the tls_get_addr function. */
5306 static GTY(()) rtx rs6000_tls_symbol;
5307 static rtx
5308 rs6000_tls_get_addr (void)
5310 if (!rs6000_tls_symbol)
5311 rs6000_tls_symbol = init_one_libfunc ("__tls_get_addr");
5313 return rs6000_tls_symbol;
5316 /* Construct the SYMBOL_REF for TLS GOT references. */
5318 static GTY(()) rtx rs6000_got_symbol;
5319 static rtx
5320 rs6000_got_sym (void)
5322 if (!rs6000_got_symbol)
5324 rs6000_got_symbol = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
5325 SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_LOCAL;
5326 SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_EXTERNAL;
5329 return rs6000_got_symbol;
5332 /* ADDR contains a thread-local SYMBOL_REF. Generate code to compute
5333 this (thread-local) address. */
5335 static rtx
5336 rs6000_legitimize_tls_address (rtx addr, enum tls_model model)
5338 rtx dest, insn;
5340 dest = gen_reg_rtx (Pmode);
5341 if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 16)
5343 rtx tlsreg;
5345 if (TARGET_64BIT)
5347 tlsreg = gen_rtx_REG (Pmode, 13);
5348 insn = gen_tls_tprel_64 (dest, tlsreg, addr);
5350 else
5352 tlsreg = gen_rtx_REG (Pmode, 2);
5353 insn = gen_tls_tprel_32 (dest, tlsreg, addr);
5355 emit_insn (insn);
5357 else if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 32)
5359 rtx tlsreg, tmp;
5361 tmp = gen_reg_rtx (Pmode);
5362 if (TARGET_64BIT)
5364 tlsreg = gen_rtx_REG (Pmode, 13);
5365 insn = gen_tls_tprel_ha_64 (tmp, tlsreg, addr);
5367 else
5369 tlsreg = gen_rtx_REG (Pmode, 2);
5370 insn = gen_tls_tprel_ha_32 (tmp, tlsreg, addr);
5372 emit_insn (insn);
5373 if (TARGET_64BIT)
5374 insn = gen_tls_tprel_lo_64 (dest, tmp, addr);
5375 else
5376 insn = gen_tls_tprel_lo_32 (dest, tmp, addr);
5377 emit_insn (insn);
5379 else
5381 rtx r3, got, tga, tmp1, tmp2, eqv;
5383 /* We currently use relocations like @got@tlsgd for tls, which
5384 means the linker will handle allocation of tls entries, placing
5385 them in the .got section. So use a pointer to the .got section,
5386 not one to secondary TOC sections used by 64-bit -mminimal-toc,
5387 or to secondary GOT sections used by 32-bit -fPIC. */
5388 if (TARGET_64BIT)
5389 got = gen_rtx_REG (Pmode, 2);
5390 else
5392 if (flag_pic == 1)
5393 got = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
5394 else
5396 rtx gsym = rs6000_got_sym ();
5397 got = gen_reg_rtx (Pmode);
5398 if (flag_pic == 0)
5399 rs6000_emit_move (got, gsym, Pmode);
5400 else
5402 rtx tmp3, mem;
5403 rtx first, last;
5405 tmp1 = gen_reg_rtx (Pmode);
5406 tmp2 = gen_reg_rtx (Pmode);
5407 tmp3 = gen_reg_rtx (Pmode);
5408 mem = gen_const_mem (Pmode, tmp1);
5410 first = emit_insn (gen_load_toc_v4_PIC_1b (gsym));
5411 emit_move_insn (tmp1,
5412 gen_rtx_REG (Pmode, LR_REGNO));
5413 emit_move_insn (tmp2, mem);
5414 emit_insn (gen_addsi3 (tmp3, tmp1, tmp2));
5415 last = emit_move_insn (got, tmp3);
5416 set_unique_reg_note (last, REG_EQUAL, gsym);
5421 if (model == TLS_MODEL_GLOBAL_DYNAMIC)
5423 r3 = gen_rtx_REG (Pmode, 3);
5424 tga = rs6000_tls_get_addr ();
5426 if (DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
5427 insn = gen_tls_gd_aix64 (r3, got, addr, tga, const0_rtx);
5428 else if (DEFAULT_ABI == ABI_AIX && !TARGET_64BIT)
5429 insn = gen_tls_gd_aix32 (r3, got, addr, tga, const0_rtx);
5430 else if (DEFAULT_ABI == ABI_V4)
5431 insn = gen_tls_gd_sysvsi (r3, got, addr, tga, const0_rtx);
5432 else
5433 gcc_unreachable ();
5435 start_sequence ();
5436 insn = emit_call_insn (insn);
5437 RTL_CONST_CALL_P (insn) = 1;
5438 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), r3);
5439 if (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
5440 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), pic_offset_table_rtx);
5441 insn = get_insns ();
5442 end_sequence ();
5443 emit_libcall_block (insn, dest, r3, addr);
5445 else if (model == TLS_MODEL_LOCAL_DYNAMIC)
5447 r3 = gen_rtx_REG (Pmode, 3);
5448 tga = rs6000_tls_get_addr ();
5450 if (DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
5451 insn = gen_tls_ld_aix64 (r3, got, tga, const0_rtx);
5452 else if (DEFAULT_ABI == ABI_AIX && !TARGET_64BIT)
5453 insn = gen_tls_ld_aix32 (r3, got, tga, const0_rtx);
5454 else if (DEFAULT_ABI == ABI_V4)
5455 insn = gen_tls_ld_sysvsi (r3, got, tga, const0_rtx);
5456 else
5457 gcc_unreachable ();
5459 start_sequence ();
5460 insn = emit_call_insn (insn);
5461 RTL_CONST_CALL_P (insn) = 1;
5462 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), r3);
5463 if (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
5464 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), pic_offset_table_rtx);
5465 insn = get_insns ();
5466 end_sequence ();
5467 tmp1 = gen_reg_rtx (Pmode);
5468 eqv = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
5469 UNSPEC_TLSLD);
5470 emit_libcall_block (insn, tmp1, r3, eqv);
5471 if (rs6000_tls_size == 16)
5473 if (TARGET_64BIT)
5474 insn = gen_tls_dtprel_64 (dest, tmp1, addr);
5475 else
5476 insn = gen_tls_dtprel_32 (dest, tmp1, addr);
5478 else if (rs6000_tls_size == 32)
5480 tmp2 = gen_reg_rtx (Pmode);
5481 if (TARGET_64BIT)
5482 insn = gen_tls_dtprel_ha_64 (tmp2, tmp1, addr);
5483 else
5484 insn = gen_tls_dtprel_ha_32 (tmp2, tmp1, addr);
5485 emit_insn (insn);
5486 if (TARGET_64BIT)
5487 insn = gen_tls_dtprel_lo_64 (dest, tmp2, addr);
5488 else
5489 insn = gen_tls_dtprel_lo_32 (dest, tmp2, addr);
5491 else
5493 tmp2 = gen_reg_rtx (Pmode);
5494 if (TARGET_64BIT)
5495 insn = gen_tls_got_dtprel_64 (tmp2, got, addr);
5496 else
5497 insn = gen_tls_got_dtprel_32 (tmp2, got, addr);
5498 emit_insn (insn);
5499 insn = gen_rtx_SET (Pmode, dest,
5500 gen_rtx_PLUS (Pmode, tmp2, tmp1));
5502 emit_insn (insn);
5504 else
5506 /* IE, or 64-bit offset LE. */
5507 tmp2 = gen_reg_rtx (Pmode);
5508 if (TARGET_64BIT)
5509 insn = gen_tls_got_tprel_64 (tmp2, got, addr);
5510 else
5511 insn = gen_tls_got_tprel_32 (tmp2, got, addr);
5512 emit_insn (insn);
5513 if (TARGET_64BIT)
5514 insn = gen_tls_tls_64 (dest, tmp2, addr);
5515 else
5516 insn = gen_tls_tls_32 (dest, tmp2, addr);
5517 emit_insn (insn);
5521 return dest;
5524 /* Return 1 if X contains a thread-local symbol. */
5526 bool
5527 rs6000_tls_referenced_p (rtx x)
5529 if (! TARGET_HAVE_TLS)
5530 return false;
5532 return for_each_rtx (&x, &rs6000_tls_symbol_ref_1, 0);
5535 /* Return 1 if *X is a thread-local symbol. This is the same as
5536 rs6000_tls_symbol_ref except for the type of the unused argument. */
5538 static int
5539 rs6000_tls_symbol_ref_1 (rtx *x, void *data ATTRIBUTE_UNUSED)
5541 return RS6000_SYMBOL_REF_TLS_P (*x);
5544 /* Our implementation of LEGITIMIZE_RELOAD_ADDRESS. Returns a value to
5545 replace the input X, or the original X if no replacement is called for.
5546 The output parameter *WIN is 1 if the calling macro should goto WIN,
5547 0 if it should not.
5549 For RS/6000, we wish to handle large displacements off a base
5550 register by splitting the addend across an addiu/addis and the mem insn.
5551 This cuts number of extra insns needed from 3 to 1.
5553 On Darwin, we use this to generate code for floating point constants.
5554 A movsf_low is generated so we wind up with 2 instructions rather than 3.
5555 The Darwin code is inside #if TARGET_MACHO because only then are the
5556 machopic_* functions defined. */
5557 static rtx
5558 rs6000_legitimize_reload_address (rtx x, enum machine_mode mode,
5559 int opnum, int type,
5560 int ind_levels ATTRIBUTE_UNUSED, int *win)
5562 bool reg_offset_p = reg_offset_addressing_ok_p (mode);
5564 /* We must recognize output that we have already generated ourselves. */
5565 if (GET_CODE (x) == PLUS
5566 && GET_CODE (XEXP (x, 0)) == PLUS
5567 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
5568 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
5569 && GET_CODE (XEXP (x, 1)) == CONST_INT)
5571 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
5572 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
5573 opnum, (enum reload_type)type);
5574 *win = 1;
5575 return x;
5578 #if TARGET_MACHO
5579 if (DEFAULT_ABI == ABI_DARWIN && flag_pic
5580 && GET_CODE (x) == LO_SUM
5581 && GET_CODE (XEXP (x, 0)) == PLUS
5582 && XEXP (XEXP (x, 0), 0) == pic_offset_table_rtx
5583 && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH
5584 && XEXP (XEXP (XEXP (x, 0), 1), 0) == XEXP (x, 1)
5585 && machopic_operand_p (XEXP (x, 1)))
5587 /* Result of previous invocation of this function on Darwin
5588 floating point constant. */
5589 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
5590 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
5591 opnum, (enum reload_type)type);
5592 *win = 1;
5593 return x;
5595 #endif
5597 /* Force ld/std non-word aligned offset into base register by wrapping
5598 in offset 0. */
5599 if (GET_CODE (x) == PLUS
5600 && GET_CODE (XEXP (x, 0)) == REG
5601 && REGNO (XEXP (x, 0)) < 32
5602 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 1)
5603 && GET_CODE (XEXP (x, 1)) == CONST_INT
5604 && reg_offset_p
5605 && (INTVAL (XEXP (x, 1)) & 3) != 0
5606 && VECTOR_MEM_NONE_P (mode)
5607 && GET_MODE_SIZE (mode) >= UNITS_PER_WORD
5608 && TARGET_POWERPC64)
5610 x = gen_rtx_PLUS (GET_MODE (x), x, GEN_INT (0));
5611 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
5612 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
5613 opnum, (enum reload_type) type);
5614 *win = 1;
5615 return x;
5618 if (GET_CODE (x) == PLUS
5619 && GET_CODE (XEXP (x, 0)) == REG
5620 && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER
5621 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 1)
5622 && GET_CODE (XEXP (x, 1)) == CONST_INT
5623 && reg_offset_p
5624 && !SPE_VECTOR_MODE (mode)
5625 && !(TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
5626 || mode == DDmode || mode == TDmode
5627 || mode == DImode))
5628 && VECTOR_MEM_NONE_P (mode))
5630 HOST_WIDE_INT val = INTVAL (XEXP (x, 1));
5631 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
5632 HOST_WIDE_INT high
5633 = (((val - low) & 0xffffffff) ^ 0x80000000) - 0x80000000;
5635 /* Check for 32-bit overflow. */
5636 if (high + low != val)
5638 *win = 0;
5639 return x;
5642 /* Reload the high part into a base reg; leave the low part
5643 in the mem directly. */
5645 x = gen_rtx_PLUS (GET_MODE (x),
5646 gen_rtx_PLUS (GET_MODE (x), XEXP (x, 0),
5647 GEN_INT (high)),
5648 GEN_INT (low));
5650 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
5651 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
5652 opnum, (enum reload_type)type);
5653 *win = 1;
5654 return x;
5657 if (GET_CODE (x) == SYMBOL_REF
5658 && reg_offset_p
5659 && VECTOR_MEM_NONE_P (mode)
5660 && !SPE_VECTOR_MODE (mode)
5661 #if TARGET_MACHO
5662 && DEFAULT_ABI == ABI_DARWIN
5663 && (flag_pic || MACHO_DYNAMIC_NO_PIC_P)
5664 #else
5665 && DEFAULT_ABI == ABI_V4
5666 && !flag_pic
5667 #endif
5668 /* Don't do this for TFmode or TDmode, since the result isn't offsettable.
5669 The same goes for DImode without 64-bit gprs and DFmode and DDmode
5670 without fprs. */
5671 && mode != TFmode
5672 && mode != TDmode
5673 && (mode != DImode || TARGET_POWERPC64)
5674 && ((mode != DFmode && mode != DDmode) || TARGET_POWERPC64
5675 || (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)))
5677 #if TARGET_MACHO
5678 if (flag_pic)
5680 rtx offset = machopic_gen_offset (x);
5681 x = gen_rtx_LO_SUM (GET_MODE (x),
5682 gen_rtx_PLUS (Pmode, pic_offset_table_rtx,
5683 gen_rtx_HIGH (Pmode, offset)), offset);
5685 else
5686 #endif
5687 x = gen_rtx_LO_SUM (GET_MODE (x),
5688 gen_rtx_HIGH (Pmode, x), x);
5690 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
5691 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
5692 opnum, (enum reload_type)type);
5693 *win = 1;
5694 return x;
5697 /* Reload an offset address wrapped by an AND that represents the
5698 masking of the lower bits. Strip the outer AND and let reload
5699 convert the offset address into an indirect address. For VSX,
5700 force reload to create the address with an AND in a separate
5701 register, because we can't guarantee an altivec register will
5702 be used. */
5703 if (VECTOR_MEM_ALTIVEC_P (mode)
5704 && GET_CODE (x) == AND
5705 && GET_CODE (XEXP (x, 0)) == PLUS
5706 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
5707 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
5708 && GET_CODE (XEXP (x, 1)) == CONST_INT
5709 && INTVAL (XEXP (x, 1)) == -16)
5711 x = XEXP (x, 0);
5712 *win = 1;
5713 return x;
5716 if (TARGET_TOC
5717 && reg_offset_p
5718 && GET_CODE (x) == SYMBOL_REF
5719 && constant_pool_expr_p (x)
5720 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), mode))
5722 x = create_TOC_reference (x);
5723 *win = 1;
5724 return x;
5726 *win = 0;
5727 return x;
5730 /* Debug version of rs6000_legitimize_reload_address. */
5731 static rtx
5732 rs6000_debug_legitimize_reload_address (rtx x, enum machine_mode mode,
5733 int opnum, int type,
5734 int ind_levels, int *win)
5736 rtx ret = rs6000_legitimize_reload_address (x, mode, opnum, type,
5737 ind_levels, win);
5738 fprintf (stderr,
5739 "\nrs6000_legitimize_reload_address: mode = %s, opnum = %d, "
5740 "type = %d, ind_levels = %d, win = %d, original addr:\n",
5741 GET_MODE_NAME (mode), opnum, type, ind_levels, *win);
5742 debug_rtx (x);
5744 if (x == ret)
5745 fprintf (stderr, "Same address returned\n");
5746 else if (!ret)
5747 fprintf (stderr, "NULL returned\n");
5748 else
5750 fprintf (stderr, "New address:\n");
5751 debug_rtx (ret);
5754 return ret;
5757 /* TARGET_LEGITIMATE_ADDRESS_P recognizes an RTL expression
5758 that is a valid memory address for an instruction.
5759 The MODE argument is the machine mode for the MEM expression
5760 that wants to use this address.
5762 On the RS/6000, there are four valid address: a SYMBOL_REF that
5763 refers to a constant pool entry of an address (or the sum of it
5764 plus a constant), a short (16-bit signed) constant plus a register,
5765 the sum of two registers, or a register indirect, possibly with an
5766 auto-increment. For DFmode, DDmode and DImode with a constant plus
5767 register, we must ensure that both words are addressable or PowerPC64
5768 with offset word aligned.
5770 For modes spanning multiple registers (DFmode and DDmode in 32-bit GPRs,
5771 32-bit DImode, TImode, TFmode, TDmode), indexed addressing cannot be used
5772 because adjacent memory cells are accessed by adding word-sized offsets
5773 during assembly output. */
5774 bool
5775 rs6000_legitimate_address_p (enum machine_mode mode, rtx x, bool reg_ok_strict)
5777 bool reg_offset_p = reg_offset_addressing_ok_p (mode);
5779 /* If this is an unaligned stvx/ldvx type address, discard the outer AND. */
5780 if (VECTOR_MEM_ALTIVEC_P (mode)
5781 && GET_CODE (x) == AND
5782 && GET_CODE (XEXP (x, 1)) == CONST_INT
5783 && INTVAL (XEXP (x, 1)) == -16)
5784 x = XEXP (x, 0);
5786 if (RS6000_SYMBOL_REF_TLS_P (x))
5787 return 0;
5788 if (legitimate_indirect_address_p (x, reg_ok_strict))
5789 return 1;
5790 if ((GET_CODE (x) == PRE_INC || GET_CODE (x) == PRE_DEC)
5791 && !VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)
5792 && !SPE_VECTOR_MODE (mode)
5793 && mode != TFmode
5794 && mode != TDmode
5795 /* Restrict addressing for DI because of our SUBREG hackery. */
5796 && !(TARGET_E500_DOUBLE
5797 && (mode == DFmode || mode == DDmode || mode == DImode))
5798 && TARGET_UPDATE
5799 && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict))
5800 return 1;
5801 if (virtual_stack_registers_memory_p (x))
5802 return 1;
5803 if (reg_offset_p && legitimate_small_data_p (mode, x))
5804 return 1;
5805 if (reg_offset_p && legitimate_constant_pool_address_p (x))
5806 return 1;
5807 /* If not REG_OK_STRICT (before reload) let pass any stack offset. */
5808 if (! reg_ok_strict
5809 && reg_offset_p
5810 && GET_CODE (x) == PLUS
5811 && GET_CODE (XEXP (x, 0)) == REG
5812 && (XEXP (x, 0) == virtual_stack_vars_rtx
5813 || XEXP (x, 0) == arg_pointer_rtx)
5814 && GET_CODE (XEXP (x, 1)) == CONST_INT)
5815 return 1;
5816 if (rs6000_legitimate_offset_address_p (mode, x, reg_ok_strict))
5817 return 1;
5818 if (mode != TImode
5819 && mode != TFmode
5820 && mode != TDmode
5821 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5822 || TARGET_POWERPC64
5823 || (mode != DFmode && mode != DDmode)
5824 || (TARGET_E500_DOUBLE && mode != DDmode))
5825 && (TARGET_POWERPC64 || mode != DImode)
5826 && !avoiding_indexed_address_p (mode)
5827 && legitimate_indexed_address_p (x, reg_ok_strict))
5828 return 1;
5829 if (GET_CODE (x) == PRE_MODIFY
5830 && 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) || TARGET_E500_DOUBLE))
5836 && (TARGET_POWERPC64 || mode != DImode)
5837 && !VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)
5838 && !SPE_VECTOR_MODE (mode)
5839 /* Restrict addressing for DI because of our SUBREG hackery. */
5840 && !(TARGET_E500_DOUBLE
5841 && (mode == DFmode || mode == DDmode || mode == DImode))
5842 && TARGET_UPDATE
5843 && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict)
5844 && (rs6000_legitimate_offset_address_p (mode, XEXP (x, 1), reg_ok_strict)
5845 || (!avoiding_indexed_address_p (mode)
5846 && legitimate_indexed_address_p (XEXP (x, 1), reg_ok_strict)))
5847 && rtx_equal_p (XEXP (XEXP (x, 1), 0), XEXP (x, 0)))
5848 return 1;
5849 if (reg_offset_p && legitimate_lo_sum_address_p (mode, x, reg_ok_strict))
5850 return 1;
5851 return 0;
5854 /* Debug version of rs6000_legitimate_address_p. */
5855 static bool
5856 rs6000_debug_legitimate_address_p (enum machine_mode mode, rtx x,
5857 bool reg_ok_strict)
5859 bool ret = rs6000_legitimate_address_p (mode, x, reg_ok_strict);
5860 fprintf (stderr,
5861 "\nrs6000_legitimate_address_p: return = %s, mode = %s, "
5862 "strict = %d, code = %s\n",
5863 ret ? "true" : "false",
5864 GET_MODE_NAME (mode),
5865 reg_ok_strict,
5866 GET_RTX_NAME (GET_CODE (x)));
5867 debug_rtx (x);
5869 return ret;
5872 /* Go to LABEL if ADDR (a legitimate address expression)
5873 has an effect that depends on the machine mode it is used for.
5875 On the RS/6000 this is true of all integral offsets (since AltiVec
5876 and VSX modes don't allow them) or is a pre-increment or decrement.
5878 ??? Except that due to conceptual problems in offsettable_address_p
5879 we can't really report the problems of integral offsets. So leave
5880 this assuming that the adjustable offset must be valid for the
5881 sub-words of a TFmode operand, which is what we had before. */
5883 static bool
5884 rs6000_mode_dependent_address (rtx addr)
5886 switch (GET_CODE (addr))
5888 case PLUS:
5889 /* Any offset from virtual_stack_vars_rtx and arg_pointer_rtx
5890 is considered a legitimate address before reload, so there
5891 are no offset restrictions in that case. Note that this
5892 condition is safe in strict mode because any address involving
5893 virtual_stack_vars_rtx or arg_pointer_rtx would already have
5894 been rejected as illegitimate. */
5895 if (XEXP (addr, 0) != virtual_stack_vars_rtx
5896 && XEXP (addr, 0) != arg_pointer_rtx
5897 && GET_CODE (XEXP (addr, 1)) == CONST_INT)
5899 unsigned HOST_WIDE_INT val = INTVAL (XEXP (addr, 1));
5900 return val + 12 + 0x8000 >= 0x10000;
5902 break;
5904 case LO_SUM:
5905 return true;
5907 /* Auto-increment cases are now treated generically in recog.c. */
5908 case PRE_MODIFY:
5909 return TARGET_UPDATE;
5911 /* AND is only allowed in Altivec loads. */
5912 case AND:
5913 return true;
5915 default:
5916 break;
5919 return false;
5922 /* Debug version of rs6000_mode_dependent_address. */
5923 static bool
5924 rs6000_debug_mode_dependent_address (rtx addr)
5926 bool ret = rs6000_mode_dependent_address (addr);
5928 fprintf (stderr, "\nrs6000_mode_dependent_address: ret = %s\n",
5929 ret ? "true" : "false");
5930 debug_rtx (addr);
5932 return ret;
5935 /* Implement FIND_BASE_TERM. */
5938 rs6000_find_base_term (rtx op)
5940 rtx base, offset;
5942 split_const (op, &base, &offset);
5943 if (GET_CODE (base) == UNSPEC)
5944 switch (XINT (base, 1))
5946 case UNSPEC_TOCREL:
5947 case UNSPEC_MACHOPIC_OFFSET:
5948 /* OP represents SYM [+ OFFSET] - ANCHOR. SYM is the base term
5949 for aliasing purposes. */
5950 return XVECEXP (base, 0, 0);
5953 return op;
5956 /* More elaborate version of recog's offsettable_memref_p predicate
5957 that works around the ??? note of rs6000_mode_dependent_address.
5958 In particular it accepts
5960 (mem:DI (plus:SI (reg/f:SI 31 31) (const_int 32760 [0x7ff8])))
5962 in 32-bit mode, that the recog predicate rejects. */
5964 bool
5965 rs6000_offsettable_memref_p (rtx op)
5967 if (!MEM_P (op))
5968 return false;
5970 /* First mimic offsettable_memref_p. */
5971 if (offsettable_address_p (1, GET_MODE (op), XEXP (op, 0)))
5972 return true;
5974 /* offsettable_address_p invokes rs6000_mode_dependent_address, but
5975 the latter predicate knows nothing about the mode of the memory
5976 reference and, therefore, assumes that it is the largest supported
5977 mode (TFmode). As a consequence, legitimate offsettable memory
5978 references are rejected. rs6000_legitimate_offset_address_p contains
5979 the correct logic for the PLUS case of rs6000_mode_dependent_address. */
5980 return rs6000_legitimate_offset_address_p (GET_MODE (op), XEXP (op, 0), 1);
5983 /* Change register usage conditional on target flags. */
5984 void
5985 rs6000_conditional_register_usage (void)
5987 int i;
5989 /* Set MQ register fixed (already call_used) if not POWER
5990 architecture (RIOS1, RIOS2, RSC, and PPC601) so that it will not
5991 be allocated. */
5992 if (! TARGET_POWER)
5993 fixed_regs[64] = 1;
5995 /* 64-bit AIX and Linux reserve GPR13 for thread-private data. */
5996 if (TARGET_64BIT)
5997 fixed_regs[13] = call_used_regs[13]
5998 = call_really_used_regs[13] = 1;
6000 /* Conditionally disable FPRs. */
6001 if (TARGET_SOFT_FLOAT || !TARGET_FPRS)
6002 for (i = 32; i < 64; i++)
6003 fixed_regs[i] = call_used_regs[i]
6004 = call_really_used_regs[i] = 1;
6006 /* The TOC register is not killed across calls in a way that is
6007 visible to the compiler. */
6008 if (DEFAULT_ABI == ABI_AIX)
6009 call_really_used_regs[2] = 0;
6011 if (DEFAULT_ABI == ABI_V4
6012 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
6013 && flag_pic == 2)
6014 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
6016 if (DEFAULT_ABI == ABI_V4
6017 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
6018 && flag_pic == 1)
6019 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6020 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6021 = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
6023 if (DEFAULT_ABI == ABI_DARWIN
6024 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM)
6025 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6026 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6027 = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
6029 if (TARGET_TOC && TARGET_MINIMAL_TOC)
6030 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6031 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
6033 if (TARGET_SPE)
6035 global_regs[SPEFSCR_REGNO] = 1;
6036 /* We used to use r14 as FIXED_SCRATCH to address SPE 64-bit
6037 registers in prologues and epilogues. We no longer use r14
6038 for FIXED_SCRATCH, but we're keeping r14 out of the allocation
6039 pool for link-compatibility with older versions of GCC. Once
6040 "old" code has died out, we can return r14 to the allocation
6041 pool. */
6042 fixed_regs[14]
6043 = call_used_regs[14]
6044 = call_really_used_regs[14] = 1;
6047 if (!TARGET_ALTIVEC && !TARGET_VSX)
6049 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
6050 fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1;
6051 call_really_used_regs[VRSAVE_REGNO] = 1;
6054 if (TARGET_ALTIVEC || TARGET_VSX)
6055 global_regs[VSCR_REGNO] = 1;
6057 if (TARGET_ALTIVEC_ABI)
6059 for (i = FIRST_ALTIVEC_REGNO; i < FIRST_ALTIVEC_REGNO + 20; ++i)
6060 call_used_regs[i] = call_really_used_regs[i] = 1;
6062 /* AIX reserves VR20:31 in non-extended ABI mode. */
6063 if (TARGET_XCOFF)
6064 for (i = FIRST_ALTIVEC_REGNO + 20; i < FIRST_ALTIVEC_REGNO + 32; ++i)
6065 fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1;
6069 /* Try to output insns to set TARGET equal to the constant C if it can
6070 be done in less than N insns. Do all computations in MODE.
6071 Returns the place where the output has been placed if it can be
6072 done and the insns have been emitted. If it would take more than N
6073 insns, zero is returned and no insns and emitted. */
6076 rs6000_emit_set_const (rtx dest, enum machine_mode mode,
6077 rtx source, int n ATTRIBUTE_UNUSED)
6079 rtx result, insn, set;
6080 HOST_WIDE_INT c0, c1;
6082 switch (mode)
6084 case QImode:
6085 case HImode:
6086 if (dest == NULL)
6087 dest = gen_reg_rtx (mode);
6088 emit_insn (gen_rtx_SET (VOIDmode, dest, source));
6089 return dest;
6091 case SImode:
6092 result = !can_create_pseudo_p () ? dest : gen_reg_rtx (SImode);
6094 emit_insn (gen_rtx_SET (VOIDmode, copy_rtx (result),
6095 GEN_INT (INTVAL (source)
6096 & (~ (HOST_WIDE_INT) 0xffff))));
6097 emit_insn (gen_rtx_SET (VOIDmode, dest,
6098 gen_rtx_IOR (SImode, copy_rtx (result),
6099 GEN_INT (INTVAL (source) & 0xffff))));
6100 result = dest;
6101 break;
6103 case DImode:
6104 switch (GET_CODE (source))
6106 case CONST_INT:
6107 c0 = INTVAL (source);
6108 c1 = -(c0 < 0);
6109 break;
6111 case CONST_DOUBLE:
6112 #if HOST_BITS_PER_WIDE_INT >= 64
6113 c0 = CONST_DOUBLE_LOW (source);
6114 c1 = -(c0 < 0);
6115 #else
6116 c0 = CONST_DOUBLE_LOW (source);
6117 c1 = CONST_DOUBLE_HIGH (source);
6118 #endif
6119 break;
6121 default:
6122 gcc_unreachable ();
6125 result = rs6000_emit_set_long_const (dest, c0, c1);
6126 break;
6128 default:
6129 gcc_unreachable ();
6132 insn = get_last_insn ();
6133 set = single_set (insn);
6134 if (! CONSTANT_P (SET_SRC (set)))
6135 set_unique_reg_note (insn, REG_EQUAL, source);
6137 return result;
6140 /* Having failed to find a 3 insn sequence in rs6000_emit_set_const,
6141 fall back to a straight forward decomposition. We do this to avoid
6142 exponential run times encountered when looking for longer sequences
6143 with rs6000_emit_set_const. */
6144 static rtx
6145 rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c1, HOST_WIDE_INT c2)
6147 if (!TARGET_POWERPC64)
6149 rtx operand1, operand2;
6151 operand1 = operand_subword_force (dest, WORDS_BIG_ENDIAN == 0,
6152 DImode);
6153 operand2 = operand_subword_force (copy_rtx (dest), WORDS_BIG_ENDIAN != 0,
6154 DImode);
6155 emit_move_insn (operand1, GEN_INT (c1));
6156 emit_move_insn (operand2, GEN_INT (c2));
6158 else
6160 HOST_WIDE_INT ud1, ud2, ud3, ud4;
6162 ud1 = c1 & 0xffff;
6163 ud2 = (c1 & 0xffff0000) >> 16;
6164 #if HOST_BITS_PER_WIDE_INT >= 64
6165 c2 = c1 >> 32;
6166 #endif
6167 ud3 = c2 & 0xffff;
6168 ud4 = (c2 & 0xffff0000) >> 16;
6170 if ((ud4 == 0xffff && ud3 == 0xffff && ud2 == 0xffff && (ud1 & 0x8000))
6171 || (ud4 == 0 && ud3 == 0 && ud2 == 0 && ! (ud1 & 0x8000)))
6173 if (ud1 & 0x8000)
6174 emit_move_insn (dest, GEN_INT (((ud1 ^ 0x8000) - 0x8000)));
6175 else
6176 emit_move_insn (dest, GEN_INT (ud1));
6179 else if ((ud4 == 0xffff && ud3 == 0xffff && (ud2 & 0x8000))
6180 || (ud4 == 0 && ud3 == 0 && ! (ud2 & 0x8000)))
6182 if (ud2 & 0x8000)
6183 emit_move_insn (dest, GEN_INT (((ud2 << 16) ^ 0x80000000)
6184 - 0x80000000));
6185 else
6186 emit_move_insn (dest, GEN_INT (ud2 << 16));
6187 if (ud1 != 0)
6188 emit_move_insn (copy_rtx (dest),
6189 gen_rtx_IOR (DImode, copy_rtx (dest),
6190 GEN_INT (ud1)));
6192 else if (ud3 == 0 && ud4 == 0)
6194 gcc_assert (ud2 & 0x8000);
6195 emit_move_insn (dest, GEN_INT (((ud2 << 16) ^ 0x80000000)
6196 - 0x80000000));
6197 if (ud1 != 0)
6198 emit_move_insn (copy_rtx (dest),
6199 gen_rtx_IOR (DImode, copy_rtx (dest),
6200 GEN_INT (ud1)));
6201 emit_move_insn (copy_rtx (dest),
6202 gen_rtx_ZERO_EXTEND (DImode,
6203 gen_lowpart (SImode,
6204 copy_rtx (dest))));
6206 else if ((ud4 == 0xffff && (ud3 & 0x8000))
6207 || (ud4 == 0 && ! (ud3 & 0x8000)))
6209 if (ud3 & 0x8000)
6210 emit_move_insn (dest, GEN_INT (((ud3 << 16) ^ 0x80000000)
6211 - 0x80000000));
6212 else
6213 emit_move_insn (dest, GEN_INT (ud3 << 16));
6215 if (ud2 != 0)
6216 emit_move_insn (copy_rtx (dest),
6217 gen_rtx_IOR (DImode, copy_rtx (dest),
6218 GEN_INT (ud2)));
6219 emit_move_insn (copy_rtx (dest),
6220 gen_rtx_ASHIFT (DImode, copy_rtx (dest),
6221 GEN_INT (16)));
6222 if (ud1 != 0)
6223 emit_move_insn (copy_rtx (dest),
6224 gen_rtx_IOR (DImode, copy_rtx (dest),
6225 GEN_INT (ud1)));
6227 else
6229 if (ud4 & 0x8000)
6230 emit_move_insn (dest, GEN_INT (((ud4 << 16) ^ 0x80000000)
6231 - 0x80000000));
6232 else
6233 emit_move_insn (dest, GEN_INT (ud4 << 16));
6235 if (ud3 != 0)
6236 emit_move_insn (copy_rtx (dest),
6237 gen_rtx_IOR (DImode, copy_rtx (dest),
6238 GEN_INT (ud3)));
6240 emit_move_insn (copy_rtx (dest),
6241 gen_rtx_ASHIFT (DImode, copy_rtx (dest),
6242 GEN_INT (32)));
6243 if (ud2 != 0)
6244 emit_move_insn (copy_rtx (dest),
6245 gen_rtx_IOR (DImode, copy_rtx (dest),
6246 GEN_INT (ud2 << 16)));
6247 if (ud1 != 0)
6248 emit_move_insn (copy_rtx (dest),
6249 gen_rtx_IOR (DImode, copy_rtx (dest), GEN_INT (ud1)));
6252 return dest;
6255 /* Helper for the following. Get rid of [r+r] memory refs
6256 in cases where it won't work (TImode, TFmode, TDmode). */
6258 static void
6259 rs6000_eliminate_indexed_memrefs (rtx operands[2])
6261 if (GET_CODE (operands[0]) == MEM
6262 && GET_CODE (XEXP (operands[0], 0)) != REG
6263 && ! legitimate_constant_pool_address_p (XEXP (operands[0], 0))
6264 && ! reload_in_progress)
6265 operands[0]
6266 = replace_equiv_address (operands[0],
6267 copy_addr_to_reg (XEXP (operands[0], 0)));
6269 if (GET_CODE (operands[1]) == MEM
6270 && GET_CODE (XEXP (operands[1], 0)) != REG
6271 && ! legitimate_constant_pool_address_p (XEXP (operands[1], 0))
6272 && ! reload_in_progress)
6273 operands[1]
6274 = replace_equiv_address (operands[1],
6275 copy_addr_to_reg (XEXP (operands[1], 0)));
6278 /* Emit a move from SOURCE to DEST in mode MODE. */
6279 void
6280 rs6000_emit_move (rtx dest, rtx source, enum machine_mode mode)
6282 rtx operands[2];
6283 operands[0] = dest;
6284 operands[1] = source;
6286 if (TARGET_DEBUG_ADDR)
6288 fprintf (stderr,
6289 "\nrs6000_emit_move: mode = %s, reload_in_progress = %d, "
6290 "reload_completed = %d, can_create_pseudos = %d.\ndest:\n",
6291 GET_MODE_NAME (mode),
6292 reload_in_progress,
6293 reload_completed,
6294 can_create_pseudo_p ());
6295 debug_rtx (dest);
6296 fprintf (stderr, "source:\n");
6297 debug_rtx (source);
6300 /* Sanity checks. Check that we get CONST_DOUBLE only when we should. */
6301 if (GET_CODE (operands[1]) == CONST_DOUBLE
6302 && ! FLOAT_MODE_P (mode)
6303 && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
6305 /* FIXME. This should never happen. */
6306 /* Since it seems that it does, do the safe thing and convert
6307 to a CONST_INT. */
6308 operands[1] = gen_int_mode (CONST_DOUBLE_LOW (operands[1]), mode);
6310 gcc_assert (GET_CODE (operands[1]) != CONST_DOUBLE
6311 || FLOAT_MODE_P (mode)
6312 || ((CONST_DOUBLE_HIGH (operands[1]) != 0
6313 || CONST_DOUBLE_LOW (operands[1]) < 0)
6314 && (CONST_DOUBLE_HIGH (operands[1]) != -1
6315 || CONST_DOUBLE_LOW (operands[1]) >= 0)));
6317 /* Check if GCC is setting up a block move that will end up using FP
6318 registers as temporaries. We must make sure this is acceptable. */
6319 if (GET_CODE (operands[0]) == MEM
6320 && GET_CODE (operands[1]) == MEM
6321 && mode == DImode
6322 && (SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[0]))
6323 || SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[1])))
6324 && ! (SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[0]) > 32
6325 ? 32 : MEM_ALIGN (operands[0])))
6326 || SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[1]) > 32
6327 ? 32
6328 : MEM_ALIGN (operands[1]))))
6329 && ! MEM_VOLATILE_P (operands [0])
6330 && ! MEM_VOLATILE_P (operands [1]))
6332 emit_move_insn (adjust_address (operands[0], SImode, 0),
6333 adjust_address (operands[1], SImode, 0));
6334 emit_move_insn (adjust_address (copy_rtx (operands[0]), SImode, 4),
6335 adjust_address (copy_rtx (operands[1]), SImode, 4));
6336 return;
6339 /* Fix up invalid (const (plus (symbol_ref) (reg))) that seems to be created
6340 in the secondary_reload phase, which evidently overwrites the CONST_INT
6341 with a register. */
6342 if (GET_CODE (source) == CONST && GET_CODE (XEXP (source, 0)) == PLUS
6343 && mode == Pmode)
6345 rtx add_op0 = XEXP (XEXP (source, 0), 0);
6346 rtx add_op1 = XEXP (XEXP (source, 0), 1);
6348 if (GET_CODE (add_op0) == SYMBOL_REF && GET_CODE (add_op1) == REG)
6350 rtx tmp = (can_create_pseudo_p ()) ? gen_reg_rtx (Pmode) : dest;
6352 if (TARGET_DEBUG_ADDR)
6354 fprintf (stderr, "\nrs6000_emit_move: bad source\n");
6355 debug_rtx (source);
6358 rs6000_emit_move (tmp, add_op0, Pmode);
6359 emit_insn (gen_rtx_SET (VOIDmode, dest,
6360 gen_rtx_PLUS (Pmode, tmp, add_op1)));
6361 return;
6365 if (can_create_pseudo_p () && GET_CODE (operands[0]) == MEM
6366 && !gpc_reg_operand (operands[1], mode))
6367 operands[1] = force_reg (mode, operands[1]);
6369 if (mode == SFmode && ! TARGET_POWERPC
6370 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
6371 && GET_CODE (operands[0]) == MEM)
6373 int regnum;
6375 if (reload_in_progress || reload_completed)
6376 regnum = true_regnum (operands[1]);
6377 else if (GET_CODE (operands[1]) == REG)
6378 regnum = REGNO (operands[1]);
6379 else
6380 regnum = -1;
6382 /* If operands[1] is a register, on POWER it may have
6383 double-precision data in it, so truncate it to single
6384 precision. */
6385 if (FP_REGNO_P (regnum) || regnum >= FIRST_PSEUDO_REGISTER)
6387 rtx newreg;
6388 newreg = (!can_create_pseudo_p () ? copy_rtx (operands[1])
6389 : gen_reg_rtx (mode));
6390 emit_insn (gen_aux_truncdfsf2 (newreg, operands[1]));
6391 operands[1] = newreg;
6395 /* Recognize the case where operand[1] is a reference to thread-local
6396 data and load its address to a register. */
6397 if (rs6000_tls_referenced_p (operands[1]))
6399 enum tls_model model;
6400 rtx tmp = operands[1];
6401 rtx addend = NULL;
6403 if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
6405 addend = XEXP (XEXP (tmp, 0), 1);
6406 tmp = XEXP (XEXP (tmp, 0), 0);
6409 gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
6410 model = SYMBOL_REF_TLS_MODEL (tmp);
6411 gcc_assert (model != 0);
6413 tmp = rs6000_legitimize_tls_address (tmp, model);
6414 if (addend)
6416 tmp = gen_rtx_PLUS (mode, tmp, addend);
6417 tmp = force_operand (tmp, operands[0]);
6419 operands[1] = tmp;
6422 /* Handle the case where reload calls us with an invalid address. */
6423 if (reload_in_progress && mode == Pmode
6424 && (! general_operand (operands[1], mode)
6425 || ! nonimmediate_operand (operands[0], mode)))
6426 goto emit_set;
6428 /* 128-bit constant floating-point values on Darwin should really be
6429 loaded as two parts. */
6430 if (!TARGET_IEEEQUAD && TARGET_LONG_DOUBLE_128
6431 && mode == TFmode && GET_CODE (operands[1]) == CONST_DOUBLE)
6433 /* DImode is used, not DFmode, because simplify_gen_subreg doesn't
6434 know how to get a DFmode SUBREG of a TFmode. */
6435 enum machine_mode imode = (TARGET_E500_DOUBLE ? DFmode : DImode);
6436 rs6000_emit_move (simplify_gen_subreg (imode, operands[0], mode, 0),
6437 simplify_gen_subreg (imode, operands[1], mode, 0),
6438 imode);
6439 rs6000_emit_move (simplify_gen_subreg (imode, operands[0], mode,
6440 GET_MODE_SIZE (imode)),
6441 simplify_gen_subreg (imode, operands[1], mode,
6442 GET_MODE_SIZE (imode)),
6443 imode);
6444 return;
6447 if (reload_in_progress && cfun->machine->sdmode_stack_slot != NULL_RTX)
6448 cfun->machine->sdmode_stack_slot =
6449 eliminate_regs (cfun->machine->sdmode_stack_slot, VOIDmode, NULL_RTX);
6451 if (reload_in_progress
6452 && mode == SDmode
6453 && MEM_P (operands[0])
6454 && rtx_equal_p (operands[0], cfun->machine->sdmode_stack_slot)
6455 && REG_P (operands[1]))
6457 if (FP_REGNO_P (REGNO (operands[1])))
6459 rtx mem = adjust_address_nv (operands[0], DDmode, 0);
6460 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
6461 emit_insn (gen_movsd_store (mem, operands[1]));
6463 else if (INT_REGNO_P (REGNO (operands[1])))
6465 rtx mem = adjust_address_nv (operands[0], mode, 4);
6466 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
6467 emit_insn (gen_movsd_hardfloat (mem, operands[1]));
6469 else
6470 gcc_unreachable();
6471 return;
6473 if (reload_in_progress
6474 && mode == SDmode
6475 && REG_P (operands[0])
6476 && MEM_P (operands[1])
6477 && rtx_equal_p (operands[1], cfun->machine->sdmode_stack_slot))
6479 if (FP_REGNO_P (REGNO (operands[0])))
6481 rtx mem = adjust_address_nv (operands[1], DDmode, 0);
6482 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
6483 emit_insn (gen_movsd_load (operands[0], mem));
6485 else if (INT_REGNO_P (REGNO (operands[0])))
6487 rtx mem = adjust_address_nv (operands[1], mode, 4);
6488 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
6489 emit_insn (gen_movsd_hardfloat (operands[0], mem));
6491 else
6492 gcc_unreachable();
6493 return;
6496 /* FIXME: In the long term, this switch statement should go away
6497 and be replaced by a sequence of tests based on things like
6498 mode == Pmode. */
6499 switch (mode)
6501 case HImode:
6502 case QImode:
6503 if (CONSTANT_P (operands[1])
6504 && GET_CODE (operands[1]) != CONST_INT)
6505 operands[1] = force_const_mem (mode, operands[1]);
6506 break;
6508 case TFmode:
6509 case TDmode:
6510 rs6000_eliminate_indexed_memrefs (operands);
6511 /* fall through */
6513 case DFmode:
6514 case DDmode:
6515 case SFmode:
6516 case SDmode:
6517 if (CONSTANT_P (operands[1])
6518 && ! easy_fp_constant (operands[1], mode))
6519 operands[1] = force_const_mem (mode, operands[1]);
6520 break;
6522 case V16QImode:
6523 case V8HImode:
6524 case V4SFmode:
6525 case V4SImode:
6526 case V4HImode:
6527 case V2SFmode:
6528 case V2SImode:
6529 case V1DImode:
6530 case V2DFmode:
6531 case V2DImode:
6532 if (CONSTANT_P (operands[1])
6533 && !easy_vector_constant (operands[1], mode))
6534 operands[1] = force_const_mem (mode, operands[1]);
6535 break;
6537 case SImode:
6538 case DImode:
6539 /* Use default pattern for address of ELF small data */
6540 if (TARGET_ELF
6541 && mode == Pmode
6542 && DEFAULT_ABI == ABI_V4
6543 && (GET_CODE (operands[1]) == SYMBOL_REF
6544 || GET_CODE (operands[1]) == CONST)
6545 && small_data_operand (operands[1], mode))
6547 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
6548 return;
6551 if (DEFAULT_ABI == ABI_V4
6552 && mode == Pmode && mode == SImode
6553 && flag_pic == 1 && got_operand (operands[1], mode))
6555 emit_insn (gen_movsi_got (operands[0], operands[1]));
6556 return;
6559 if ((TARGET_ELF || DEFAULT_ABI == ABI_DARWIN)
6560 && TARGET_NO_TOC
6561 && ! flag_pic
6562 && mode == Pmode
6563 && CONSTANT_P (operands[1])
6564 && GET_CODE (operands[1]) != HIGH
6565 && GET_CODE (operands[1]) != CONST_INT)
6567 rtx target = (!can_create_pseudo_p ()
6568 ? operands[0]
6569 : gen_reg_rtx (mode));
6571 /* If this is a function address on -mcall-aixdesc,
6572 convert it to the address of the descriptor. */
6573 if (DEFAULT_ABI == ABI_AIX
6574 && GET_CODE (operands[1]) == SYMBOL_REF
6575 && XSTR (operands[1], 0)[0] == '.')
6577 const char *name = XSTR (operands[1], 0);
6578 rtx new_ref;
6579 while (*name == '.')
6580 name++;
6581 new_ref = gen_rtx_SYMBOL_REF (Pmode, name);
6582 CONSTANT_POOL_ADDRESS_P (new_ref)
6583 = CONSTANT_POOL_ADDRESS_P (operands[1]);
6584 SYMBOL_REF_FLAGS (new_ref) = SYMBOL_REF_FLAGS (operands[1]);
6585 SYMBOL_REF_USED (new_ref) = SYMBOL_REF_USED (operands[1]);
6586 SYMBOL_REF_DATA (new_ref) = SYMBOL_REF_DATA (operands[1]);
6587 operands[1] = new_ref;
6590 if (DEFAULT_ABI == ABI_DARWIN)
6592 #if TARGET_MACHO
6593 if (MACHO_DYNAMIC_NO_PIC_P)
6595 /* Take care of any required data indirection. */
6596 operands[1] = rs6000_machopic_legitimize_pic_address (
6597 operands[1], mode, operands[0]);
6598 if (operands[0] != operands[1])
6599 emit_insn (gen_rtx_SET (VOIDmode,
6600 operands[0], operands[1]));
6601 return;
6603 #endif
6604 emit_insn (gen_macho_high (target, operands[1]));
6605 emit_insn (gen_macho_low (operands[0], target, operands[1]));
6606 return;
6609 emit_insn (gen_elf_high (target, operands[1]));
6610 emit_insn (gen_elf_low (operands[0], target, operands[1]));
6611 return;
6614 /* If this is a SYMBOL_REF that refers to a constant pool entry,
6615 and we have put it in the TOC, we just need to make a TOC-relative
6616 reference to it. */
6617 if (TARGET_TOC
6618 && GET_CODE (operands[1]) == SYMBOL_REF
6619 && constant_pool_expr_p (operands[1])
6620 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (operands[1]),
6621 get_pool_mode (operands[1])))
6623 operands[1] = create_TOC_reference (operands[1]);
6625 else if (mode == Pmode
6626 && CONSTANT_P (operands[1])
6627 && ((GET_CODE (operands[1]) != CONST_INT
6628 && ! easy_fp_constant (operands[1], mode))
6629 || (GET_CODE (operands[1]) == CONST_INT
6630 && num_insns_constant (operands[1], mode) > 2)
6631 || (GET_CODE (operands[0]) == REG
6632 && FP_REGNO_P (REGNO (operands[0]))))
6633 && GET_CODE (operands[1]) != HIGH
6634 && ! legitimate_constant_pool_address_p (operands[1])
6635 && ! toc_relative_expr_p (operands[1]))
6638 #if TARGET_MACHO
6639 /* Darwin uses a special PIC legitimizer. */
6640 if (DEFAULT_ABI == ABI_DARWIN && MACHOPIC_INDIRECT)
6642 operands[1] =
6643 rs6000_machopic_legitimize_pic_address (operands[1], mode,
6644 operands[0]);
6645 if (operands[0] != operands[1])
6646 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
6647 return;
6649 #endif
6651 /* If we are to limit the number of things we put in the TOC and
6652 this is a symbol plus a constant we can add in one insn,
6653 just put the symbol in the TOC and add the constant. Don't do
6654 this if reload is in progress. */
6655 if (GET_CODE (operands[1]) == CONST
6656 && TARGET_NO_SUM_IN_TOC && ! reload_in_progress
6657 && GET_CODE (XEXP (operands[1], 0)) == PLUS
6658 && add_operand (XEXP (XEXP (operands[1], 0), 1), mode)
6659 && (GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == LABEL_REF
6660 || GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == SYMBOL_REF)
6661 && ! side_effects_p (operands[0]))
6663 rtx sym =
6664 force_const_mem (mode, XEXP (XEXP (operands[1], 0), 0));
6665 rtx other = XEXP (XEXP (operands[1], 0), 1);
6667 sym = force_reg (mode, sym);
6668 emit_insn (gen_add3_insn (operands[0], sym, other));
6669 return;
6672 operands[1] = force_const_mem (mode, operands[1]);
6674 if (TARGET_TOC
6675 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
6676 && constant_pool_expr_p (XEXP (operands[1], 0))
6677 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (
6678 get_pool_constant (XEXP (operands[1], 0)),
6679 get_pool_mode (XEXP (operands[1], 0))))
6681 operands[1]
6682 = gen_const_mem (mode,
6683 create_TOC_reference (XEXP (operands[1], 0)));
6684 set_mem_alias_set (operands[1], get_TOC_alias_set ());
6687 break;
6689 case TImode:
6690 rs6000_eliminate_indexed_memrefs (operands);
6692 if (TARGET_POWER)
6694 emit_insn (gen_rtx_PARALLEL (VOIDmode,
6695 gen_rtvec (2,
6696 gen_rtx_SET (VOIDmode,
6697 operands[0], operands[1]),
6698 gen_rtx_CLOBBER (VOIDmode,
6699 gen_rtx_SCRATCH (SImode)))));
6700 return;
6702 break;
6704 default:
6705 fatal_insn ("bad move", gen_rtx_SET (VOIDmode, dest, source));
6708 /* Above, we may have called force_const_mem which may have returned
6709 an invalid address. If we can, fix this up; otherwise, reload will
6710 have to deal with it. */
6711 if (GET_CODE (operands[1]) == MEM && ! reload_in_progress)
6712 operands[1] = validize_mem (operands[1]);
6714 emit_set:
6715 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
6718 /* Nonzero if we can use a floating-point register to pass this arg. */
6719 #define USE_FP_FOR_ARG_P(CUM,MODE,TYPE) \
6720 (SCALAR_FLOAT_MODE_P (MODE) \
6721 && (CUM)->fregno <= FP_ARG_MAX_REG \
6722 && TARGET_HARD_FLOAT && TARGET_FPRS)
6724 /* Nonzero if we can use an AltiVec register to pass this arg. */
6725 #define USE_ALTIVEC_FOR_ARG_P(CUM,MODE,TYPE,NAMED) \
6726 ((ALTIVEC_VECTOR_MODE (MODE) || VSX_VECTOR_MODE (MODE)) \
6727 && (CUM)->vregno <= ALTIVEC_ARG_MAX_REG \
6728 && TARGET_ALTIVEC_ABI \
6729 && (NAMED))
6731 /* Return a nonzero value to say to return the function value in
6732 memory, just as large structures are always returned. TYPE will be
6733 the data type of the value, and FNTYPE will be the type of the
6734 function doing the returning, or @code{NULL} for libcalls.
6736 The AIX ABI for the RS/6000 specifies that all structures are
6737 returned in memory. The Darwin ABI does the same. The SVR4 ABI
6738 specifies that structures <= 8 bytes are returned in r3/r4, but a
6739 draft put them in memory, and GCC used to implement the draft
6740 instead of the final standard. Therefore, aix_struct_return
6741 controls this instead of DEFAULT_ABI; V.4 targets needing backward
6742 compatibility can change DRAFT_V4_STRUCT_RET to override the
6743 default, and -m switches get the final word. See
6744 rs6000_override_options for more details.
6746 The PPC32 SVR4 ABI uses IEEE double extended for long double, if 128-bit
6747 long double support is enabled. These values are returned in memory.
6749 int_size_in_bytes returns -1 for variable size objects, which go in
6750 memory always. The cast to unsigned makes -1 > 8. */
6752 static bool
6753 rs6000_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
6755 /* In the darwin64 abi, try to use registers for larger structs
6756 if possible. */
6757 if (rs6000_darwin64_abi
6758 && TREE_CODE (type) == RECORD_TYPE
6759 && int_size_in_bytes (type) > 0)
6761 CUMULATIVE_ARGS valcum;
6762 rtx valret;
6764 valcum.words = 0;
6765 valcum.fregno = FP_ARG_MIN_REG;
6766 valcum.vregno = ALTIVEC_ARG_MIN_REG;
6767 /* Do a trial code generation as if this were going to be passed
6768 as an argument; if any part goes in memory, we return NULL. */
6769 valret = rs6000_darwin64_record_arg (&valcum, type, 1, true);
6770 if (valret)
6771 return false;
6772 /* Otherwise fall through to more conventional ABI rules. */
6775 if (AGGREGATE_TYPE_P (type)
6776 && (aix_struct_return
6777 || (unsigned HOST_WIDE_INT) int_size_in_bytes (type) > 8))
6778 return true;
6780 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
6781 modes only exist for GCC vector types if -maltivec. */
6782 if (TARGET_32BIT && !TARGET_ALTIVEC_ABI
6783 && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
6784 return false;
6786 /* Return synthetic vectors in memory. */
6787 if (TREE_CODE (type) == VECTOR_TYPE
6788 && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
6790 static bool warned_for_return_big_vectors = false;
6791 if (!warned_for_return_big_vectors)
6793 warning (0, "GCC vector returned by reference: "
6794 "non-standard ABI extension with no compatibility guarantee");
6795 warned_for_return_big_vectors = true;
6797 return true;
6800 if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && TYPE_MODE (type) == TFmode)
6801 return true;
6803 return false;
6806 /* Initialize a variable CUM of type CUMULATIVE_ARGS
6807 for a call to a function whose data type is FNTYPE.
6808 For a library call, FNTYPE is 0.
6810 For incoming args we set the number of arguments in the prototype large
6811 so we never return a PARALLEL. */
6813 void
6814 init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype,
6815 rtx libname ATTRIBUTE_UNUSED, int incoming,
6816 int libcall, int n_named_args)
6818 static CUMULATIVE_ARGS zero_cumulative;
6820 *cum = zero_cumulative;
6821 cum->words = 0;
6822 cum->fregno = FP_ARG_MIN_REG;
6823 cum->vregno = ALTIVEC_ARG_MIN_REG;
6824 cum->prototype = (fntype && TYPE_ARG_TYPES (fntype));
6825 cum->call_cookie = ((DEFAULT_ABI == ABI_V4 && libcall)
6826 ? CALL_LIBCALL : CALL_NORMAL);
6827 cum->sysv_gregno = GP_ARG_MIN_REG;
6828 cum->stdarg = fntype
6829 && (TYPE_ARG_TYPES (fntype) != 0
6830 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
6831 != void_type_node));
6833 cum->nargs_prototype = 0;
6834 if (incoming || cum->prototype)
6835 cum->nargs_prototype = n_named_args;
6837 /* Check for a longcall attribute. */
6838 if ((!fntype && rs6000_default_long_calls)
6839 || (fntype
6840 && lookup_attribute ("longcall", TYPE_ATTRIBUTES (fntype))
6841 && !lookup_attribute ("shortcall", TYPE_ATTRIBUTES (fntype))))
6842 cum->call_cookie |= CALL_LONG;
6844 if (TARGET_DEBUG_ARG)
6846 fprintf (stderr, "\ninit_cumulative_args:");
6847 if (fntype)
6849 tree ret_type = TREE_TYPE (fntype);
6850 fprintf (stderr, " ret code = %s,",
6851 tree_code_name[ (int)TREE_CODE (ret_type) ]);
6854 if (cum->call_cookie & CALL_LONG)
6855 fprintf (stderr, " longcall,");
6857 fprintf (stderr, " proto = %d, nargs = %d\n",
6858 cum->prototype, cum->nargs_prototype);
6861 if (fntype
6862 && !TARGET_ALTIVEC
6863 && TARGET_ALTIVEC_ABI
6864 && ALTIVEC_VECTOR_MODE (TYPE_MODE (TREE_TYPE (fntype))))
6866 error ("cannot return value in vector register because"
6867 " altivec instructions are disabled, use -maltivec"
6868 " to enable them");
6872 /* Return true if TYPE must be passed on the stack and not in registers. */
6874 static bool
6875 rs6000_must_pass_in_stack (enum machine_mode mode, const_tree type)
6877 if (DEFAULT_ABI == ABI_AIX || TARGET_64BIT)
6878 return must_pass_in_stack_var_size (mode, type);
6879 else
6880 return must_pass_in_stack_var_size_or_pad (mode, type);
6883 /* If defined, a C expression which determines whether, and in which
6884 direction, to pad out an argument with extra space. The value
6885 should be of type `enum direction': either `upward' to pad above
6886 the argument, `downward' to pad below, or `none' to inhibit
6887 padding.
6889 For the AIX ABI structs are always stored left shifted in their
6890 argument slot. */
6892 enum direction
6893 function_arg_padding (enum machine_mode mode, const_tree type)
6895 #ifndef AGGREGATE_PADDING_FIXED
6896 #define AGGREGATE_PADDING_FIXED 0
6897 #endif
6898 #ifndef AGGREGATES_PAD_UPWARD_ALWAYS
6899 #define AGGREGATES_PAD_UPWARD_ALWAYS 0
6900 #endif
6902 if (!AGGREGATE_PADDING_FIXED)
6904 /* GCC used to pass structures of the same size as integer types as
6905 if they were in fact integers, ignoring FUNCTION_ARG_PADDING.
6906 i.e. Structures of size 1 or 2 (or 4 when TARGET_64BIT) were
6907 passed padded downward, except that -mstrict-align further
6908 muddied the water in that multi-component structures of 2 and 4
6909 bytes in size were passed padded upward.
6911 The following arranges for best compatibility with previous
6912 versions of gcc, but removes the -mstrict-align dependency. */
6913 if (BYTES_BIG_ENDIAN)
6915 HOST_WIDE_INT size = 0;
6917 if (mode == BLKmode)
6919 if (type && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST)
6920 size = int_size_in_bytes (type);
6922 else
6923 size = GET_MODE_SIZE (mode);
6925 if (size == 1 || size == 2 || size == 4)
6926 return downward;
6928 return upward;
6931 if (AGGREGATES_PAD_UPWARD_ALWAYS)
6933 if (type != 0 && AGGREGATE_TYPE_P (type))
6934 return upward;
6937 /* Fall back to the default. */
6938 return DEFAULT_FUNCTION_ARG_PADDING (mode, type);
6941 /* If defined, a C expression that gives the alignment boundary, in bits,
6942 of an argument with the specified mode and type. If it is not defined,
6943 PARM_BOUNDARY is used for all arguments.
6945 V.4 wants long longs and doubles to be double word aligned. Just
6946 testing the mode size is a boneheaded way to do this as it means
6947 that other types such as complex int are also double word aligned.
6948 However, we're stuck with this because changing the ABI might break
6949 existing library interfaces.
6951 Doubleword align SPE vectors.
6952 Quadword align Altivec vectors.
6953 Quadword align large synthetic vector types. */
6956 function_arg_boundary (enum machine_mode mode, tree type)
6958 if (DEFAULT_ABI == ABI_V4
6959 && (GET_MODE_SIZE (mode) == 8
6960 || (TARGET_HARD_FLOAT
6961 && TARGET_FPRS
6962 && (mode == TFmode || mode == TDmode))))
6963 return 64;
6964 else if (SPE_VECTOR_MODE (mode)
6965 || (type && TREE_CODE (type) == VECTOR_TYPE
6966 && int_size_in_bytes (type) >= 8
6967 && int_size_in_bytes (type) < 16))
6968 return 64;
6969 else if ((ALTIVEC_VECTOR_MODE (mode) || VSX_VECTOR_MODE (mode))
6970 || (type && TREE_CODE (type) == VECTOR_TYPE
6971 && int_size_in_bytes (type) >= 16))
6972 return 128;
6973 else if (rs6000_darwin64_abi && mode == BLKmode
6974 && type && TYPE_ALIGN (type) > 64)
6975 return 128;
6976 else
6977 return PARM_BOUNDARY;
6980 /* For a function parm of MODE and TYPE, return the starting word in
6981 the parameter area. NWORDS of the parameter area are already used. */
6983 static unsigned int
6984 rs6000_parm_start (enum machine_mode mode, tree type, unsigned int nwords)
6986 unsigned int align;
6987 unsigned int parm_offset;
6989 align = function_arg_boundary (mode, type) / PARM_BOUNDARY - 1;
6990 parm_offset = DEFAULT_ABI == ABI_V4 ? 2 : 6;
6991 return nwords + (-(parm_offset + nwords) & align);
6994 /* Compute the size (in words) of a function argument. */
6996 static unsigned long
6997 rs6000_arg_size (enum machine_mode mode, tree type)
6999 unsigned long size;
7001 if (mode != BLKmode)
7002 size = GET_MODE_SIZE (mode);
7003 else
7004 size = int_size_in_bytes (type);
7006 if (TARGET_32BIT)
7007 return (size + 3) >> 2;
7008 else
7009 return (size + 7) >> 3;
7012 /* Use this to flush pending int fields. */
7014 static void
7015 rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS *cum,
7016 HOST_WIDE_INT bitpos)
7018 unsigned int startbit, endbit;
7019 int intregs, intoffset;
7020 enum machine_mode mode;
7022 if (cum->intoffset == -1)
7023 return;
7025 intoffset = cum->intoffset;
7026 cum->intoffset = -1;
7028 if (intoffset % BITS_PER_WORD != 0)
7030 mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD,
7031 MODE_INT, 0);
7032 if (mode == BLKmode)
7034 /* We couldn't find an appropriate mode, which happens,
7035 e.g., in packed structs when there are 3 bytes to load.
7036 Back intoffset back to the beginning of the word in this
7037 case. */
7038 intoffset = intoffset & -BITS_PER_WORD;
7042 startbit = intoffset & -BITS_PER_WORD;
7043 endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD;
7044 intregs = (endbit - startbit) / BITS_PER_WORD;
7045 cum->words += intregs;
7048 /* The darwin64 ABI calls for us to recurse down through structs,
7049 looking for elements passed in registers. Unfortunately, we have
7050 to track int register count here also because of misalignments
7051 in powerpc alignment mode. */
7053 static void
7054 rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS *cum,
7055 tree type,
7056 HOST_WIDE_INT startbitpos)
7058 tree f;
7060 for (f = TYPE_FIELDS (type); f ; f = TREE_CHAIN (f))
7061 if (TREE_CODE (f) == FIELD_DECL)
7063 HOST_WIDE_INT bitpos = startbitpos;
7064 tree ftype = TREE_TYPE (f);
7065 enum machine_mode mode;
7066 if (ftype == error_mark_node)
7067 continue;
7068 mode = TYPE_MODE (ftype);
7070 if (DECL_SIZE (f) != 0
7071 && host_integerp (bit_position (f), 1))
7072 bitpos += int_bit_position (f);
7074 /* ??? FIXME: else assume zero offset. */
7076 if (TREE_CODE (ftype) == RECORD_TYPE)
7077 rs6000_darwin64_record_arg_advance_recurse (cum, ftype, bitpos);
7078 else if (USE_FP_FOR_ARG_P (cum, mode, ftype))
7080 rs6000_darwin64_record_arg_advance_flush (cum, bitpos);
7081 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
7082 cum->words += (GET_MODE_SIZE (mode) + 7) >> 3;
7084 else if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, 1))
7086 rs6000_darwin64_record_arg_advance_flush (cum, bitpos);
7087 cum->vregno++;
7088 cum->words += 2;
7090 else if (cum->intoffset == -1)
7091 cum->intoffset = bitpos;
7095 /* Update the data in CUM to advance over an argument
7096 of mode MODE and data type TYPE.
7097 (TYPE is null for libcalls where that information may not be available.)
7099 Note that for args passed by reference, function_arg will be called
7100 with MODE and TYPE set to that of the pointer to the arg, not the arg
7101 itself. */
7103 void
7104 function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
7105 tree type, int named, int depth)
7107 int size;
7109 /* Only tick off an argument if we're not recursing. */
7110 if (depth == 0)
7111 cum->nargs_prototype--;
7113 if (TARGET_ALTIVEC_ABI
7114 && (ALTIVEC_VECTOR_MODE (mode)
7115 || VSX_VECTOR_MODE (mode)
7116 || (type && TREE_CODE (type) == VECTOR_TYPE
7117 && int_size_in_bytes (type) == 16)))
7119 bool stack = false;
7121 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
7123 cum->vregno++;
7124 if (!TARGET_ALTIVEC)
7125 error ("cannot pass argument in vector register because"
7126 " altivec instructions are disabled, use -maltivec"
7127 " to enable them");
7129 /* PowerPC64 Linux and AIX allocate GPRs for a vector argument
7130 even if it is going to be passed in a vector register.
7131 Darwin does the same for variable-argument functions. */
7132 if ((DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
7133 || (cum->stdarg && DEFAULT_ABI != ABI_V4))
7134 stack = true;
7136 else
7137 stack = true;
7139 if (stack)
7141 int align;
7143 /* Vector parameters must be 16-byte aligned. This places
7144 them at 2 mod 4 in terms of words in 32-bit mode, since
7145 the parameter save area starts at offset 24 from the
7146 stack. In 64-bit mode, they just have to start on an
7147 even word, since the parameter save area is 16-byte
7148 aligned. Space for GPRs is reserved even if the argument
7149 will be passed in memory. */
7150 if (TARGET_32BIT)
7151 align = (2 - cum->words) & 3;
7152 else
7153 align = cum->words & 1;
7154 cum->words += align + rs6000_arg_size (mode, type);
7156 if (TARGET_DEBUG_ARG)
7158 fprintf (stderr, "function_adv: words = %2d, align=%d, ",
7159 cum->words, align);
7160 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s\n",
7161 cum->nargs_prototype, cum->prototype,
7162 GET_MODE_NAME (mode));
7166 else if (TARGET_SPE_ABI && TARGET_SPE && SPE_VECTOR_MODE (mode)
7167 && !cum->stdarg
7168 && cum->sysv_gregno <= GP_ARG_MAX_REG)
7169 cum->sysv_gregno++;
7171 else if (rs6000_darwin64_abi
7172 && mode == BLKmode
7173 && TREE_CODE (type) == RECORD_TYPE
7174 && (size = int_size_in_bytes (type)) > 0)
7176 /* Variable sized types have size == -1 and are
7177 treated as if consisting entirely of ints.
7178 Pad to 16 byte boundary if needed. */
7179 if (TYPE_ALIGN (type) >= 2 * BITS_PER_WORD
7180 && (cum->words % 2) != 0)
7181 cum->words++;
7182 /* For varargs, we can just go up by the size of the struct. */
7183 if (!named)
7184 cum->words += (size + 7) / 8;
7185 else
7187 /* It is tempting to say int register count just goes up by
7188 sizeof(type)/8, but this is wrong in a case such as
7189 { int; double; int; } [powerpc alignment]. We have to
7190 grovel through the fields for these too. */
7191 cum->intoffset = 0;
7192 rs6000_darwin64_record_arg_advance_recurse (cum, type, 0);
7193 rs6000_darwin64_record_arg_advance_flush (cum,
7194 size * BITS_PER_UNIT);
7197 else if (DEFAULT_ABI == ABI_V4)
7199 if (TARGET_HARD_FLOAT && TARGET_FPRS
7200 && ((TARGET_SINGLE_FLOAT && mode == SFmode)
7201 || (TARGET_DOUBLE_FLOAT && mode == DFmode)
7202 || (mode == TFmode && !TARGET_IEEEQUAD)
7203 || mode == SDmode || mode == DDmode || mode == TDmode))
7205 /* _Decimal128 must use an even/odd register pair. This assumes
7206 that the register number is odd when fregno is odd. */
7207 if (mode == TDmode && (cum->fregno % 2) == 1)
7208 cum->fregno++;
7210 if (cum->fregno + (mode == TFmode || mode == TDmode ? 1 : 0)
7211 <= FP_ARG_V4_MAX_REG)
7212 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
7213 else
7215 cum->fregno = FP_ARG_V4_MAX_REG + 1;
7216 if (mode == DFmode || mode == TFmode
7217 || mode == DDmode || mode == TDmode)
7218 cum->words += cum->words & 1;
7219 cum->words += rs6000_arg_size (mode, type);
7222 else
7224 int n_words = rs6000_arg_size (mode, type);
7225 int gregno = cum->sysv_gregno;
7227 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
7228 (r7,r8) or (r9,r10). As does any other 2 word item such
7229 as complex int due to a historical mistake. */
7230 if (n_words == 2)
7231 gregno += (1 - gregno) & 1;
7233 /* Multi-reg args are not split between registers and stack. */
7234 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
7236 /* Long long and SPE vectors are aligned on the stack.
7237 So are other 2 word items such as complex int due to
7238 a historical mistake. */
7239 if (n_words == 2)
7240 cum->words += cum->words & 1;
7241 cum->words += n_words;
7244 /* Note: continuing to accumulate gregno past when we've started
7245 spilling to the stack indicates the fact that we've started
7246 spilling to the stack to expand_builtin_saveregs. */
7247 cum->sysv_gregno = gregno + n_words;
7250 if (TARGET_DEBUG_ARG)
7252 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
7253 cum->words, cum->fregno);
7254 fprintf (stderr, "gregno = %2d, nargs = %4d, proto = %d, ",
7255 cum->sysv_gregno, cum->nargs_prototype, cum->prototype);
7256 fprintf (stderr, "mode = %4s, named = %d\n",
7257 GET_MODE_NAME (mode), named);
7260 else
7262 int n_words = rs6000_arg_size (mode, type);
7263 int start_words = cum->words;
7264 int align_words = rs6000_parm_start (mode, type, start_words);
7266 cum->words = align_words + n_words;
7268 if (SCALAR_FLOAT_MODE_P (mode)
7269 && TARGET_HARD_FLOAT && TARGET_FPRS)
7271 /* _Decimal128 must be passed in an even/odd float register pair.
7272 This assumes that the register number is odd when fregno is
7273 odd. */
7274 if (mode == TDmode && (cum->fregno % 2) == 1)
7275 cum->fregno++;
7276 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
7279 if (TARGET_DEBUG_ARG)
7281 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
7282 cum->words, cum->fregno);
7283 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s, ",
7284 cum->nargs_prototype, cum->prototype, GET_MODE_NAME (mode));
7285 fprintf (stderr, "named = %d, align = %d, depth = %d\n",
7286 named, align_words - start_words, depth);
7291 static rtx
7292 spe_build_register_parallel (enum machine_mode mode, int gregno)
7294 rtx r1, r3, r5, r7;
7296 switch (mode)
7298 case DFmode:
7299 r1 = gen_rtx_REG (DImode, gregno);
7300 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
7301 return gen_rtx_PARALLEL (mode, gen_rtvec (1, r1));
7303 case DCmode:
7304 case TFmode:
7305 r1 = gen_rtx_REG (DImode, gregno);
7306 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
7307 r3 = gen_rtx_REG (DImode, gregno + 2);
7308 r3 = gen_rtx_EXPR_LIST (VOIDmode, r3, GEN_INT (8));
7309 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r3));
7311 case TCmode:
7312 r1 = gen_rtx_REG (DImode, gregno);
7313 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
7314 r3 = gen_rtx_REG (DImode, gregno + 2);
7315 r3 = gen_rtx_EXPR_LIST (VOIDmode, r3, GEN_INT (8));
7316 r5 = gen_rtx_REG (DImode, gregno + 4);
7317 r5 = gen_rtx_EXPR_LIST (VOIDmode, r5, GEN_INT (16));
7318 r7 = gen_rtx_REG (DImode, gregno + 6);
7319 r7 = gen_rtx_EXPR_LIST (VOIDmode, r7, GEN_INT (24));
7320 return gen_rtx_PARALLEL (mode, gen_rtvec (4, r1, r3, r5, r7));
7322 default:
7323 gcc_unreachable ();
7327 /* Determine where to put a SIMD argument on the SPE. */
7328 static rtx
7329 rs6000_spe_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
7330 tree type)
7332 int gregno = cum->sysv_gregno;
7334 /* On E500 v2, double arithmetic is done on the full 64-bit GPR, but
7335 are passed and returned in a pair of GPRs for ABI compatibility. */
7336 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
7337 || mode == DCmode || mode == TCmode))
7339 int n_words = rs6000_arg_size (mode, type);
7341 /* Doubles go in an odd/even register pair (r5/r6, etc). */
7342 if (mode == DFmode)
7343 gregno += (1 - gregno) & 1;
7345 /* Multi-reg args are not split between registers and stack. */
7346 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
7347 return NULL_RTX;
7349 return spe_build_register_parallel (mode, gregno);
7351 if (cum->stdarg)
7353 int n_words = rs6000_arg_size (mode, type);
7355 /* SPE vectors are put in odd registers. */
7356 if (n_words == 2 && (gregno & 1) == 0)
7357 gregno += 1;
7359 if (gregno + n_words - 1 <= GP_ARG_MAX_REG)
7361 rtx r1, r2;
7362 enum machine_mode m = SImode;
7364 r1 = gen_rtx_REG (m, gregno);
7365 r1 = gen_rtx_EXPR_LIST (m, r1, const0_rtx);
7366 r2 = gen_rtx_REG (m, gregno + 1);
7367 r2 = gen_rtx_EXPR_LIST (m, r2, GEN_INT (4));
7368 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
7370 else
7371 return NULL_RTX;
7373 else
7375 if (gregno <= GP_ARG_MAX_REG)
7376 return gen_rtx_REG (mode, gregno);
7377 else
7378 return NULL_RTX;
7382 /* A subroutine of rs6000_darwin64_record_arg. Assign the bits of the
7383 structure between cum->intoffset and bitpos to integer registers. */
7385 static void
7386 rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS *cum,
7387 HOST_WIDE_INT bitpos, rtx rvec[], int *k)
7389 enum machine_mode mode;
7390 unsigned int regno;
7391 unsigned int startbit, endbit;
7392 int this_regno, intregs, intoffset;
7393 rtx reg;
7395 if (cum->intoffset == -1)
7396 return;
7398 intoffset = cum->intoffset;
7399 cum->intoffset = -1;
7401 /* If this is the trailing part of a word, try to only load that
7402 much into the register. Otherwise load the whole register. Note
7403 that in the latter case we may pick up unwanted bits. It's not a
7404 problem at the moment but may wish to revisit. */
7406 if (intoffset % BITS_PER_WORD != 0)
7408 mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD,
7409 MODE_INT, 0);
7410 if (mode == BLKmode)
7412 /* We couldn't find an appropriate mode, which happens,
7413 e.g., in packed structs when there are 3 bytes to load.
7414 Back intoffset back to the beginning of the word in this
7415 case. */
7416 intoffset = intoffset & -BITS_PER_WORD;
7417 mode = word_mode;
7420 else
7421 mode = word_mode;
7423 startbit = intoffset & -BITS_PER_WORD;
7424 endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD;
7425 intregs = (endbit - startbit) / BITS_PER_WORD;
7426 this_regno = cum->words + intoffset / BITS_PER_WORD;
7428 if (intregs > 0 && intregs > GP_ARG_NUM_REG - this_regno)
7429 cum->use_stack = 1;
7431 intregs = MIN (intregs, GP_ARG_NUM_REG - this_regno);
7432 if (intregs <= 0)
7433 return;
7435 intoffset /= BITS_PER_UNIT;
7438 regno = GP_ARG_MIN_REG + this_regno;
7439 reg = gen_rtx_REG (mode, regno);
7440 rvec[(*k)++] =
7441 gen_rtx_EXPR_LIST (VOIDmode, reg, GEN_INT (intoffset));
7443 this_regno += 1;
7444 intoffset = (intoffset | (UNITS_PER_WORD-1)) + 1;
7445 mode = word_mode;
7446 intregs -= 1;
7448 while (intregs > 0);
7451 /* Recursive workhorse for the following. */
7453 static void
7454 rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *cum, const_tree type,
7455 HOST_WIDE_INT startbitpos, rtx rvec[],
7456 int *k)
7458 tree f;
7460 for (f = TYPE_FIELDS (type); f ; f = TREE_CHAIN (f))
7461 if (TREE_CODE (f) == FIELD_DECL)
7463 HOST_WIDE_INT bitpos = startbitpos;
7464 tree ftype = TREE_TYPE (f);
7465 enum machine_mode mode;
7466 if (ftype == error_mark_node)
7467 continue;
7468 mode = TYPE_MODE (ftype);
7470 if (DECL_SIZE (f) != 0
7471 && host_integerp (bit_position (f), 1))
7472 bitpos += int_bit_position (f);
7474 /* ??? FIXME: else assume zero offset. */
7476 if (TREE_CODE (ftype) == RECORD_TYPE)
7477 rs6000_darwin64_record_arg_recurse (cum, ftype, bitpos, rvec, k);
7478 else if (cum->named && USE_FP_FOR_ARG_P (cum, mode, ftype))
7480 #if 0
7481 switch (mode)
7483 case SCmode: mode = SFmode; break;
7484 case DCmode: mode = DFmode; break;
7485 case TCmode: mode = TFmode; break;
7486 default: break;
7488 #endif
7489 rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
7490 rvec[(*k)++]
7491 = gen_rtx_EXPR_LIST (VOIDmode,
7492 gen_rtx_REG (mode, cum->fregno++),
7493 GEN_INT (bitpos / BITS_PER_UNIT));
7494 if (mode == TFmode || mode == TDmode)
7495 cum->fregno++;
7497 else if (cum->named && USE_ALTIVEC_FOR_ARG_P (cum, mode, ftype, 1))
7499 rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
7500 rvec[(*k)++]
7501 = gen_rtx_EXPR_LIST (VOIDmode,
7502 gen_rtx_REG (mode, cum->vregno++),
7503 GEN_INT (bitpos / BITS_PER_UNIT));
7505 else if (cum->intoffset == -1)
7506 cum->intoffset = bitpos;
7510 /* For the darwin64 ABI, we want to construct a PARALLEL consisting of
7511 the register(s) to be used for each field and subfield of a struct
7512 being passed by value, along with the offset of where the
7513 register's value may be found in the block. FP fields go in FP
7514 register, vector fields go in vector registers, and everything
7515 else goes in int registers, packed as in memory.
7517 This code is also used for function return values. RETVAL indicates
7518 whether this is the case.
7520 Much of this is taken from the SPARC V9 port, which has a similar
7521 calling convention. */
7523 static rtx
7524 rs6000_darwin64_record_arg (CUMULATIVE_ARGS *orig_cum, const_tree type,
7525 int named, bool retval)
7527 rtx rvec[FIRST_PSEUDO_REGISTER];
7528 int k = 1, kbase = 1;
7529 HOST_WIDE_INT typesize = int_size_in_bytes (type);
7530 /* This is a copy; modifications are not visible to our caller. */
7531 CUMULATIVE_ARGS copy_cum = *orig_cum;
7532 CUMULATIVE_ARGS *cum = &copy_cum;
7534 /* Pad to 16 byte boundary if needed. */
7535 if (!retval && TYPE_ALIGN (type) >= 2 * BITS_PER_WORD
7536 && (cum->words % 2) != 0)
7537 cum->words++;
7539 cum->intoffset = 0;
7540 cum->use_stack = 0;
7541 cum->named = named;
7543 /* Put entries into rvec[] for individual FP and vector fields, and
7544 for the chunks of memory that go in int regs. Note we start at
7545 element 1; 0 is reserved for an indication of using memory, and
7546 may or may not be filled in below. */
7547 rs6000_darwin64_record_arg_recurse (cum, type, 0, rvec, &k);
7548 rs6000_darwin64_record_arg_flush (cum, typesize * BITS_PER_UNIT, rvec, &k);
7550 /* If any part of the struct went on the stack put all of it there.
7551 This hack is because the generic code for
7552 FUNCTION_ARG_PARTIAL_NREGS cannot handle cases where the register
7553 parts of the struct are not at the beginning. */
7554 if (cum->use_stack)
7556 if (retval)
7557 return NULL_RTX; /* doesn't go in registers at all */
7558 kbase = 0;
7559 rvec[0] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
7561 if (k > 1 || cum->use_stack)
7562 return gen_rtx_PARALLEL (BLKmode, gen_rtvec_v (k - kbase, &rvec[kbase]));
7563 else
7564 return NULL_RTX;
7567 /* Determine where to place an argument in 64-bit mode with 32-bit ABI. */
7569 static rtx
7570 rs6000_mixed_function_arg (enum machine_mode mode, tree type, int align_words)
7572 int n_units;
7573 int i, k;
7574 rtx rvec[GP_ARG_NUM_REG + 1];
7576 if (align_words >= GP_ARG_NUM_REG)
7577 return NULL_RTX;
7579 n_units = rs6000_arg_size (mode, type);
7581 /* Optimize the simple case where the arg fits in one gpr, except in
7582 the case of BLKmode due to assign_parms assuming that registers are
7583 BITS_PER_WORD wide. */
7584 if (n_units == 0
7585 || (n_units == 1 && mode != BLKmode))
7586 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
7588 k = 0;
7589 if (align_words + n_units > GP_ARG_NUM_REG)
7590 /* Not all of the arg fits in gprs. Say that it goes in memory too,
7591 using a magic NULL_RTX component.
7592 This is not strictly correct. Only some of the arg belongs in
7593 memory, not all of it. However, the normal scheme using
7594 function_arg_partial_nregs can result in unusual subregs, eg.
7595 (subreg:SI (reg:DF) 4), which are not handled well. The code to
7596 store the whole arg to memory is often more efficient than code
7597 to store pieces, and we know that space is available in the right
7598 place for the whole arg. */
7599 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
7601 i = 0;
7604 rtx r = gen_rtx_REG (SImode, GP_ARG_MIN_REG + align_words);
7605 rtx off = GEN_INT (i++ * 4);
7606 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
7608 while (++align_words < GP_ARG_NUM_REG && --n_units != 0);
7610 return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
7613 /* Determine where to put an argument to a function.
7614 Value is zero to push the argument on the stack,
7615 or a hard register in which to store the argument.
7617 MODE is the argument's machine mode.
7618 TYPE is the data type of the argument (as a tree).
7619 This is null for libcalls where that information may
7620 not be available.
7621 CUM is a variable of type CUMULATIVE_ARGS which gives info about
7622 the preceding args and about the function being called. It is
7623 not modified in this routine.
7624 NAMED is nonzero if this argument is a named parameter
7625 (otherwise it is an extra parameter matching an ellipsis).
7627 On RS/6000 the first eight words of non-FP are normally in registers
7628 and the rest are pushed. Under AIX, the first 13 FP args are in registers.
7629 Under V.4, the first 8 FP args are in registers.
7631 If this is floating-point and no prototype is specified, we use
7632 both an FP and integer register (or possibly FP reg and stack). Library
7633 functions (when CALL_LIBCALL is set) always have the proper types for args,
7634 so we can pass the FP value just in one register. emit_library_function
7635 doesn't support PARALLEL anyway.
7637 Note that for args passed by reference, function_arg will be called
7638 with MODE and TYPE set to that of the pointer to the arg, not the arg
7639 itself. */
7642 function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
7643 tree type, int named)
7645 enum rs6000_abi abi = DEFAULT_ABI;
7647 /* Return a marker to indicate whether CR1 needs to set or clear the
7648 bit that V.4 uses to say fp args were passed in registers.
7649 Assume that we don't need the marker for software floating point,
7650 or compiler generated library calls. */
7651 if (mode == VOIDmode)
7653 if (abi == ABI_V4
7654 && (cum->call_cookie & CALL_LIBCALL) == 0
7655 && (cum->stdarg
7656 || (cum->nargs_prototype < 0
7657 && (cum->prototype || TARGET_NO_PROTOTYPE))))
7659 /* For the SPE, we need to crxor CR6 always. */
7660 if (TARGET_SPE_ABI)
7661 return GEN_INT (cum->call_cookie | CALL_V4_SET_FP_ARGS);
7662 else if (TARGET_HARD_FLOAT && TARGET_FPRS)
7663 return GEN_INT (cum->call_cookie
7664 | ((cum->fregno == FP_ARG_MIN_REG)
7665 ? CALL_V4_SET_FP_ARGS
7666 : CALL_V4_CLEAR_FP_ARGS));
7669 return GEN_INT (cum->call_cookie);
7672 if (rs6000_darwin64_abi && mode == BLKmode
7673 && TREE_CODE (type) == RECORD_TYPE)
7675 rtx rslt = rs6000_darwin64_record_arg (cum, type, named, false);
7676 if (rslt != NULL_RTX)
7677 return rslt;
7678 /* Else fall through to usual handling. */
7681 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
7682 if (TARGET_64BIT && ! cum->prototype)
7684 /* Vector parameters get passed in vector register
7685 and also in GPRs or memory, in absence of prototype. */
7686 int align_words;
7687 rtx slot;
7688 align_words = (cum->words + 1) & ~1;
7690 if (align_words >= GP_ARG_NUM_REG)
7692 slot = NULL_RTX;
7694 else
7696 slot = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
7698 return gen_rtx_PARALLEL (mode,
7699 gen_rtvec (2,
7700 gen_rtx_EXPR_LIST (VOIDmode,
7701 slot, const0_rtx),
7702 gen_rtx_EXPR_LIST (VOIDmode,
7703 gen_rtx_REG (mode, cum->vregno),
7704 const0_rtx)));
7706 else
7707 return gen_rtx_REG (mode, cum->vregno);
7708 else if (TARGET_ALTIVEC_ABI
7709 && (ALTIVEC_VECTOR_MODE (mode)
7710 || VSX_VECTOR_MODE (mode)
7711 || (type && TREE_CODE (type) == VECTOR_TYPE
7712 && int_size_in_bytes (type) == 16)))
7714 if (named || abi == ABI_V4)
7715 return NULL_RTX;
7716 else
7718 /* Vector parameters to varargs functions under AIX or Darwin
7719 get passed in memory and possibly also in GPRs. */
7720 int align, align_words, n_words;
7721 enum machine_mode part_mode;
7723 /* Vector parameters must be 16-byte aligned. This places them at
7724 2 mod 4 in terms of words in 32-bit mode, since the parameter
7725 save area starts at offset 24 from the stack. In 64-bit mode,
7726 they just have to start on an even word, since the parameter
7727 save area is 16-byte aligned. */
7728 if (TARGET_32BIT)
7729 align = (2 - cum->words) & 3;
7730 else
7731 align = cum->words & 1;
7732 align_words = cum->words + align;
7734 /* Out of registers? Memory, then. */
7735 if (align_words >= GP_ARG_NUM_REG)
7736 return NULL_RTX;
7738 if (TARGET_32BIT && TARGET_POWERPC64)
7739 return rs6000_mixed_function_arg (mode, type, align_words);
7741 /* The vector value goes in GPRs. Only the part of the
7742 value in GPRs is reported here. */
7743 part_mode = mode;
7744 n_words = rs6000_arg_size (mode, type);
7745 if (align_words + n_words > GP_ARG_NUM_REG)
7746 /* Fortunately, there are only two possibilities, the value
7747 is either wholly in GPRs or half in GPRs and half not. */
7748 part_mode = DImode;
7750 return gen_rtx_REG (part_mode, GP_ARG_MIN_REG + align_words);
7753 else if (TARGET_SPE_ABI && TARGET_SPE
7754 && (SPE_VECTOR_MODE (mode)
7755 || (TARGET_E500_DOUBLE && (mode == DFmode
7756 || mode == DCmode
7757 || mode == TFmode
7758 || mode == TCmode))))
7759 return rs6000_spe_function_arg (cum, mode, type);
7761 else if (abi == ABI_V4)
7763 if (TARGET_HARD_FLOAT && TARGET_FPRS
7764 && ((TARGET_SINGLE_FLOAT && mode == SFmode)
7765 || (TARGET_DOUBLE_FLOAT && mode == DFmode)
7766 || (mode == TFmode && !TARGET_IEEEQUAD)
7767 || mode == SDmode || mode == DDmode || mode == TDmode))
7769 /* _Decimal128 must use an even/odd register pair. This assumes
7770 that the register number is odd when fregno is odd. */
7771 if (mode == TDmode && (cum->fregno % 2) == 1)
7772 cum->fregno++;
7774 if (cum->fregno + (mode == TFmode || mode == TDmode ? 1 : 0)
7775 <= FP_ARG_V4_MAX_REG)
7776 return gen_rtx_REG (mode, cum->fregno);
7777 else
7778 return NULL_RTX;
7780 else
7782 int n_words = rs6000_arg_size (mode, type);
7783 int gregno = cum->sysv_gregno;
7785 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
7786 (r7,r8) or (r9,r10). As does any other 2 word item such
7787 as complex int due to a historical mistake. */
7788 if (n_words == 2)
7789 gregno += (1 - gregno) & 1;
7791 /* Multi-reg args are not split between registers and stack. */
7792 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
7793 return NULL_RTX;
7795 if (TARGET_32BIT && TARGET_POWERPC64)
7796 return rs6000_mixed_function_arg (mode, type,
7797 gregno - GP_ARG_MIN_REG);
7798 return gen_rtx_REG (mode, gregno);
7801 else
7803 int align_words = rs6000_parm_start (mode, type, cum->words);
7805 /* _Decimal128 must be passed in an even/odd float register pair.
7806 This assumes that the register number is odd when fregno is odd. */
7807 if (mode == TDmode && (cum->fregno % 2) == 1)
7808 cum->fregno++;
7810 if (USE_FP_FOR_ARG_P (cum, mode, type))
7812 rtx rvec[GP_ARG_NUM_REG + 1];
7813 rtx r;
7814 int k;
7815 bool needs_psave;
7816 enum machine_mode fmode = mode;
7817 unsigned long n_fpreg = (GET_MODE_SIZE (mode) + 7) >> 3;
7819 if (cum->fregno + n_fpreg > FP_ARG_MAX_REG + 1)
7821 /* Currently, we only ever need one reg here because complex
7822 doubles are split. */
7823 gcc_assert (cum->fregno == FP_ARG_MAX_REG
7824 && (fmode == TFmode || fmode == TDmode));
7826 /* Long double or _Decimal128 split over regs and memory. */
7827 fmode = DECIMAL_FLOAT_MODE_P (fmode) ? DDmode : DFmode;
7830 /* Do we also need to pass this arg in the parameter save
7831 area? */
7832 needs_psave = (type
7833 && (cum->nargs_prototype <= 0
7834 || (DEFAULT_ABI == ABI_AIX
7835 && TARGET_XL_COMPAT
7836 && align_words >= GP_ARG_NUM_REG)));
7838 if (!needs_psave && mode == fmode)
7839 return gen_rtx_REG (fmode, cum->fregno);
7841 k = 0;
7842 if (needs_psave)
7844 /* Describe the part that goes in gprs or the stack.
7845 This piece must come first, before the fprs. */
7846 if (align_words < GP_ARG_NUM_REG)
7848 unsigned long n_words = rs6000_arg_size (mode, type);
7850 if (align_words + n_words > GP_ARG_NUM_REG
7851 || (TARGET_32BIT && TARGET_POWERPC64))
7853 /* If this is partially on the stack, then we only
7854 include the portion actually in registers here. */
7855 enum machine_mode rmode = TARGET_32BIT ? SImode : DImode;
7856 rtx off;
7857 int i = 0;
7858 if (align_words + n_words > GP_ARG_NUM_REG)
7859 /* Not all of the arg fits in gprs. Say that it
7860 goes in memory too, using a magic NULL_RTX
7861 component. Also see comment in
7862 rs6000_mixed_function_arg for why the normal
7863 function_arg_partial_nregs scheme doesn't work
7864 in this case. */
7865 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX,
7866 const0_rtx);
7869 r = gen_rtx_REG (rmode,
7870 GP_ARG_MIN_REG + align_words);
7871 off = GEN_INT (i++ * GET_MODE_SIZE (rmode));
7872 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
7874 while (++align_words < GP_ARG_NUM_REG && --n_words != 0);
7876 else
7878 /* The whole arg fits in gprs. */
7879 r = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
7880 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
7883 else
7884 /* It's entirely in memory. */
7885 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
7888 /* Describe where this piece goes in the fprs. */
7889 r = gen_rtx_REG (fmode, cum->fregno);
7890 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
7892 return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
7894 else if (align_words < GP_ARG_NUM_REG)
7896 if (TARGET_32BIT && TARGET_POWERPC64)
7897 return rs6000_mixed_function_arg (mode, type, align_words);
7899 if (mode == BLKmode)
7900 mode = Pmode;
7902 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
7904 else
7905 return NULL_RTX;
7909 /* For an arg passed partly in registers and partly in memory, this is
7910 the number of bytes passed in registers. For args passed entirely in
7911 registers or entirely in memory, zero. When an arg is described by a
7912 PARALLEL, perhaps using more than one register type, this function
7913 returns the number of bytes used by the first element of the PARALLEL. */
7915 static int
7916 rs6000_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode,
7917 tree type, bool named)
7919 int ret = 0;
7920 int align_words;
7922 if (DEFAULT_ABI == ABI_V4)
7923 return 0;
7925 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named)
7926 && cum->nargs_prototype >= 0)
7927 return 0;
7929 /* In this complicated case we just disable the partial_nregs code. */
7930 if (rs6000_darwin64_abi && mode == BLKmode
7931 && TREE_CODE (type) == RECORD_TYPE
7932 && int_size_in_bytes (type) > 0)
7933 return 0;
7935 align_words = rs6000_parm_start (mode, type, cum->words);
7937 if (USE_FP_FOR_ARG_P (cum, mode, type))
7939 /* If we are passing this arg in the fixed parameter save area
7940 (gprs or memory) as well as fprs, then this function should
7941 return the number of partial bytes passed in the parameter
7942 save area rather than partial bytes passed in fprs. */
7943 if (type
7944 && (cum->nargs_prototype <= 0
7945 || (DEFAULT_ABI == ABI_AIX
7946 && TARGET_XL_COMPAT
7947 && align_words >= GP_ARG_NUM_REG)))
7948 return 0;
7949 else if (cum->fregno + ((GET_MODE_SIZE (mode) + 7) >> 3)
7950 > FP_ARG_MAX_REG + 1)
7951 ret = (FP_ARG_MAX_REG + 1 - cum->fregno) * 8;
7952 else if (cum->nargs_prototype >= 0)
7953 return 0;
7956 if (align_words < GP_ARG_NUM_REG
7957 && GP_ARG_NUM_REG < align_words + rs6000_arg_size (mode, type))
7958 ret = (GP_ARG_NUM_REG - align_words) * (TARGET_32BIT ? 4 : 8);
7960 if (ret != 0 && TARGET_DEBUG_ARG)
7961 fprintf (stderr, "rs6000_arg_partial_bytes: %d\n", ret);
7963 return ret;
7966 /* A C expression that indicates when an argument must be passed by
7967 reference. If nonzero for an argument, a copy of that argument is
7968 made in memory and a pointer to the argument is passed instead of
7969 the argument itself. The pointer is passed in whatever way is
7970 appropriate for passing a pointer to that type.
7972 Under V.4, aggregates and long double are passed by reference.
7974 As an extension to all 32-bit ABIs, AltiVec vectors are passed by
7975 reference unless the AltiVec vector extension ABI is in force.
7977 As an extension to all ABIs, variable sized types are passed by
7978 reference. */
7980 static bool
7981 rs6000_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
7982 enum machine_mode mode, const_tree type,
7983 bool named ATTRIBUTE_UNUSED)
7985 if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && mode == TFmode)
7987 if (TARGET_DEBUG_ARG)
7988 fprintf (stderr, "function_arg_pass_by_reference: V4 long double\n");
7989 return 1;
7992 if (!type)
7993 return 0;
7995 if (DEFAULT_ABI == ABI_V4 && AGGREGATE_TYPE_P (type))
7997 if (TARGET_DEBUG_ARG)
7998 fprintf (stderr, "function_arg_pass_by_reference: V4 aggregate\n");
7999 return 1;
8002 if (int_size_in_bytes (type) < 0)
8004 if (TARGET_DEBUG_ARG)
8005 fprintf (stderr, "function_arg_pass_by_reference: variable size\n");
8006 return 1;
8009 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
8010 modes only exist for GCC vector types if -maltivec. */
8011 if (TARGET_32BIT && !TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
8013 if (TARGET_DEBUG_ARG)
8014 fprintf (stderr, "function_arg_pass_by_reference: AltiVec\n");
8015 return 1;
8018 /* Pass synthetic vectors in memory. */
8019 if (TREE_CODE (type) == VECTOR_TYPE
8020 && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
8022 static bool warned_for_pass_big_vectors = false;
8023 if (TARGET_DEBUG_ARG)
8024 fprintf (stderr, "function_arg_pass_by_reference: synthetic vector\n");
8025 if (!warned_for_pass_big_vectors)
8027 warning (0, "GCC vector passed by reference: "
8028 "non-standard ABI extension with no compatibility guarantee");
8029 warned_for_pass_big_vectors = true;
8031 return 1;
8034 return 0;
8037 static void
8038 rs6000_move_block_from_reg (int regno, rtx x, int nregs)
8040 int i;
8041 enum machine_mode reg_mode = TARGET_32BIT ? SImode : DImode;
8043 if (nregs == 0)
8044 return;
8046 for (i = 0; i < nregs; i++)
8048 rtx tem = adjust_address_nv (x, reg_mode, i * GET_MODE_SIZE (reg_mode));
8049 if (reload_completed)
8051 if (! strict_memory_address_p (reg_mode, XEXP (tem, 0)))
8052 tem = NULL_RTX;
8053 else
8054 tem = simplify_gen_subreg (reg_mode, x, BLKmode,
8055 i * GET_MODE_SIZE (reg_mode));
8057 else
8058 tem = replace_equiv_address (tem, XEXP (tem, 0));
8060 gcc_assert (tem);
8062 emit_move_insn (tem, gen_rtx_REG (reg_mode, regno + i));
8066 /* Perform any needed actions needed for a function that is receiving a
8067 variable number of arguments.
8069 CUM is as above.
8071 MODE and TYPE are the mode and type of the current parameter.
8073 PRETEND_SIZE is a variable that should be set to the amount of stack
8074 that must be pushed by the prolog to pretend that our caller pushed
8077 Normally, this macro will push all remaining incoming registers on the
8078 stack and set PRETEND_SIZE to the length of the registers pushed. */
8080 static void
8081 setup_incoming_varargs (CUMULATIVE_ARGS *cum, enum machine_mode mode,
8082 tree type, int *pretend_size ATTRIBUTE_UNUSED,
8083 int no_rtl)
8085 CUMULATIVE_ARGS next_cum;
8086 int reg_size = TARGET_32BIT ? 4 : 8;
8087 rtx save_area = NULL_RTX, mem;
8088 int first_reg_offset;
8089 alias_set_type set;
8091 /* Skip the last named argument. */
8092 next_cum = *cum;
8093 function_arg_advance (&next_cum, mode, type, 1, 0);
8095 if (DEFAULT_ABI == ABI_V4)
8097 first_reg_offset = next_cum.sysv_gregno - GP_ARG_MIN_REG;
8099 if (! no_rtl)
8101 int gpr_reg_num = 0, gpr_size = 0, fpr_size = 0;
8102 HOST_WIDE_INT offset = 0;
8104 /* Try to optimize the size of the varargs save area.
8105 The ABI requires that ap.reg_save_area is doubleword
8106 aligned, but we don't need to allocate space for all
8107 the bytes, only those to which we actually will save
8108 anything. */
8109 if (cfun->va_list_gpr_size && first_reg_offset < GP_ARG_NUM_REG)
8110 gpr_reg_num = GP_ARG_NUM_REG - first_reg_offset;
8111 if (TARGET_HARD_FLOAT && TARGET_FPRS
8112 && next_cum.fregno <= FP_ARG_V4_MAX_REG
8113 && cfun->va_list_fpr_size)
8115 if (gpr_reg_num)
8116 fpr_size = (next_cum.fregno - FP_ARG_MIN_REG)
8117 * UNITS_PER_FP_WORD;
8118 if (cfun->va_list_fpr_size
8119 < FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
8120 fpr_size += cfun->va_list_fpr_size * UNITS_PER_FP_WORD;
8121 else
8122 fpr_size += (FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
8123 * UNITS_PER_FP_WORD;
8125 if (gpr_reg_num)
8127 offset = -((first_reg_offset * reg_size) & ~7);
8128 if (!fpr_size && gpr_reg_num > cfun->va_list_gpr_size)
8130 gpr_reg_num = cfun->va_list_gpr_size;
8131 if (reg_size == 4 && (first_reg_offset & 1))
8132 gpr_reg_num++;
8134 gpr_size = (gpr_reg_num * reg_size + 7) & ~7;
8136 else if (fpr_size)
8137 offset = - (int) (next_cum.fregno - FP_ARG_MIN_REG)
8138 * UNITS_PER_FP_WORD
8139 - (int) (GP_ARG_NUM_REG * reg_size);
8141 if (gpr_size + fpr_size)
8143 rtx reg_save_area
8144 = assign_stack_local (BLKmode, gpr_size + fpr_size, 64);
8145 gcc_assert (GET_CODE (reg_save_area) == MEM);
8146 reg_save_area = XEXP (reg_save_area, 0);
8147 if (GET_CODE (reg_save_area) == PLUS)
8149 gcc_assert (XEXP (reg_save_area, 0)
8150 == virtual_stack_vars_rtx);
8151 gcc_assert (GET_CODE (XEXP (reg_save_area, 1)) == CONST_INT);
8152 offset += INTVAL (XEXP (reg_save_area, 1));
8154 else
8155 gcc_assert (reg_save_area == virtual_stack_vars_rtx);
8158 cfun->machine->varargs_save_offset = offset;
8159 save_area = plus_constant (virtual_stack_vars_rtx, offset);
8162 else
8164 first_reg_offset = next_cum.words;
8165 save_area = virtual_incoming_args_rtx;
8167 if (targetm.calls.must_pass_in_stack (mode, type))
8168 first_reg_offset += rs6000_arg_size (TYPE_MODE (type), type);
8171 set = get_varargs_alias_set ();
8172 if (! no_rtl && first_reg_offset < GP_ARG_NUM_REG
8173 && cfun->va_list_gpr_size)
8175 int nregs = GP_ARG_NUM_REG - first_reg_offset;
8177 if (va_list_gpr_counter_field)
8179 /* V4 va_list_gpr_size counts number of registers needed. */
8180 if (nregs > cfun->va_list_gpr_size)
8181 nregs = cfun->va_list_gpr_size;
8183 else
8185 /* char * va_list instead counts number of bytes needed. */
8186 if (nregs > cfun->va_list_gpr_size / reg_size)
8187 nregs = cfun->va_list_gpr_size / reg_size;
8190 mem = gen_rtx_MEM (BLKmode,
8191 plus_constant (save_area,
8192 first_reg_offset * reg_size));
8193 MEM_NOTRAP_P (mem) = 1;
8194 set_mem_alias_set (mem, set);
8195 set_mem_align (mem, BITS_PER_WORD);
8197 rs6000_move_block_from_reg (GP_ARG_MIN_REG + first_reg_offset, mem,
8198 nregs);
8201 /* Save FP registers if needed. */
8202 if (DEFAULT_ABI == ABI_V4
8203 && TARGET_HARD_FLOAT && TARGET_FPRS
8204 && ! no_rtl
8205 && next_cum.fregno <= FP_ARG_V4_MAX_REG
8206 && cfun->va_list_fpr_size)
8208 int fregno = next_cum.fregno, nregs;
8209 rtx cr1 = gen_rtx_REG (CCmode, CR1_REGNO);
8210 rtx lab = gen_label_rtx ();
8211 int off = (GP_ARG_NUM_REG * reg_size) + ((fregno - FP_ARG_MIN_REG)
8212 * UNITS_PER_FP_WORD);
8214 emit_jump_insn
8215 (gen_rtx_SET (VOIDmode,
8216 pc_rtx,
8217 gen_rtx_IF_THEN_ELSE (VOIDmode,
8218 gen_rtx_NE (VOIDmode, cr1,
8219 const0_rtx),
8220 gen_rtx_LABEL_REF (VOIDmode, lab),
8221 pc_rtx)));
8223 for (nregs = 0;
8224 fregno <= FP_ARG_V4_MAX_REG && nregs < cfun->va_list_fpr_size;
8225 fregno++, off += UNITS_PER_FP_WORD, nregs++)
8227 mem = gen_rtx_MEM ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
8228 ? DFmode : SFmode,
8229 plus_constant (save_area, off));
8230 MEM_NOTRAP_P (mem) = 1;
8231 set_mem_alias_set (mem, set);
8232 set_mem_align (mem, GET_MODE_ALIGNMENT (
8233 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
8234 ? DFmode : SFmode));
8235 emit_move_insn (mem, gen_rtx_REG (
8236 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
8237 ? DFmode : SFmode, fregno));
8240 emit_label (lab);
8244 /* Create the va_list data type. */
8246 static tree
8247 rs6000_build_builtin_va_list (void)
8249 tree f_gpr, f_fpr, f_res, f_ovf, f_sav, record, type_decl;
8251 /* For AIX, prefer 'char *' because that's what the system
8252 header files like. */
8253 if (DEFAULT_ABI != ABI_V4)
8254 return build_pointer_type (char_type_node);
8256 record = (*lang_hooks.types.make_type) (RECORD_TYPE);
8257 type_decl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
8258 get_identifier ("__va_list_tag"), record);
8260 f_gpr = build_decl (BUILTINS_LOCATION, FIELD_DECL, get_identifier ("gpr"),
8261 unsigned_char_type_node);
8262 f_fpr = build_decl (BUILTINS_LOCATION, FIELD_DECL, get_identifier ("fpr"),
8263 unsigned_char_type_node);
8264 /* Give the two bytes of padding a name, so that -Wpadded won't warn on
8265 every user file. */
8266 f_res = build_decl (BUILTINS_LOCATION, FIELD_DECL,
8267 get_identifier ("reserved"), short_unsigned_type_node);
8268 f_ovf = build_decl (BUILTINS_LOCATION, FIELD_DECL,
8269 get_identifier ("overflow_arg_area"),
8270 ptr_type_node);
8271 f_sav = build_decl (BUILTINS_LOCATION, FIELD_DECL,
8272 get_identifier ("reg_save_area"),
8273 ptr_type_node);
8275 va_list_gpr_counter_field = f_gpr;
8276 va_list_fpr_counter_field = f_fpr;
8278 DECL_FIELD_CONTEXT (f_gpr) = record;
8279 DECL_FIELD_CONTEXT (f_fpr) = record;
8280 DECL_FIELD_CONTEXT (f_res) = record;
8281 DECL_FIELD_CONTEXT (f_ovf) = record;
8282 DECL_FIELD_CONTEXT (f_sav) = record;
8284 TREE_CHAIN (record) = type_decl;
8285 TYPE_NAME (record) = type_decl;
8286 TYPE_FIELDS (record) = f_gpr;
8287 TREE_CHAIN (f_gpr) = f_fpr;
8288 TREE_CHAIN (f_fpr) = f_res;
8289 TREE_CHAIN (f_res) = f_ovf;
8290 TREE_CHAIN (f_ovf) = f_sav;
8292 layout_type (record);
8294 /* The correct type is an array type of one element. */
8295 return build_array_type (record, build_index_type (size_zero_node));
8298 /* Implement va_start. */
8300 static void
8301 rs6000_va_start (tree valist, rtx nextarg)
8303 HOST_WIDE_INT words, n_gpr, n_fpr;
8304 tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
8305 tree gpr, fpr, ovf, sav, t;
8307 /* Only SVR4 needs something special. */
8308 if (DEFAULT_ABI != ABI_V4)
8310 std_expand_builtin_va_start (valist, nextarg);
8311 return;
8314 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
8315 f_fpr = TREE_CHAIN (f_gpr);
8316 f_res = TREE_CHAIN (f_fpr);
8317 f_ovf = TREE_CHAIN (f_res);
8318 f_sav = TREE_CHAIN (f_ovf);
8320 valist = build_va_arg_indirect_ref (valist);
8321 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
8322 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), unshare_expr (valist),
8323 f_fpr, NULL_TREE);
8324 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), unshare_expr (valist),
8325 f_ovf, NULL_TREE);
8326 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), unshare_expr (valist),
8327 f_sav, NULL_TREE);
8329 /* Count number of gp and fp argument registers used. */
8330 words = crtl->args.info.words;
8331 n_gpr = MIN (crtl->args.info.sysv_gregno - GP_ARG_MIN_REG,
8332 GP_ARG_NUM_REG);
8333 n_fpr = MIN (crtl->args.info.fregno - FP_ARG_MIN_REG,
8334 FP_ARG_NUM_REG);
8336 if (TARGET_DEBUG_ARG)
8337 fprintf (stderr, "va_start: words = "HOST_WIDE_INT_PRINT_DEC", n_gpr = "
8338 HOST_WIDE_INT_PRINT_DEC", n_fpr = "HOST_WIDE_INT_PRINT_DEC"\n",
8339 words, n_gpr, n_fpr);
8341 if (cfun->va_list_gpr_size)
8343 t = build2 (MODIFY_EXPR, TREE_TYPE (gpr), gpr,
8344 build_int_cst (NULL_TREE, n_gpr));
8345 TREE_SIDE_EFFECTS (t) = 1;
8346 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
8349 if (cfun->va_list_fpr_size)
8351 t = build2 (MODIFY_EXPR, TREE_TYPE (fpr), fpr,
8352 build_int_cst (NULL_TREE, n_fpr));
8353 TREE_SIDE_EFFECTS (t) = 1;
8354 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
8357 /* Find the overflow area. */
8358 t = make_tree (TREE_TYPE (ovf), virtual_incoming_args_rtx);
8359 if (words != 0)
8360 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (ovf), t,
8361 size_int (words * UNITS_PER_WORD));
8362 t = build2 (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
8363 TREE_SIDE_EFFECTS (t) = 1;
8364 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
8366 /* If there were no va_arg invocations, don't set up the register
8367 save area. */
8368 if (!cfun->va_list_gpr_size
8369 && !cfun->va_list_fpr_size
8370 && n_gpr < GP_ARG_NUM_REG
8371 && n_fpr < FP_ARG_V4_MAX_REG)
8372 return;
8374 /* Find the register save area. */
8375 t = make_tree (TREE_TYPE (sav), virtual_stack_vars_rtx);
8376 if (cfun->machine->varargs_save_offset)
8377 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (sav), t,
8378 size_int (cfun->machine->varargs_save_offset));
8379 t = build2 (MODIFY_EXPR, TREE_TYPE (sav), sav, t);
8380 TREE_SIDE_EFFECTS (t) = 1;
8381 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
8384 /* Implement va_arg. */
8386 tree
8387 rs6000_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
8388 gimple_seq *post_p)
8390 tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
8391 tree gpr, fpr, ovf, sav, reg, t, u;
8392 int size, rsize, n_reg, sav_ofs, sav_scale;
8393 tree lab_false, lab_over, addr;
8394 int align;
8395 tree ptrtype = build_pointer_type_for_mode (type, ptr_mode, true);
8396 int regalign = 0;
8397 gimple stmt;
8399 if (pass_by_reference (NULL, TYPE_MODE (type), type, false))
8401 t = rs6000_gimplify_va_arg (valist, ptrtype, pre_p, post_p);
8402 return build_va_arg_indirect_ref (t);
8405 if (DEFAULT_ABI != ABI_V4)
8407 if (targetm.calls.split_complex_arg && TREE_CODE (type) == COMPLEX_TYPE)
8409 tree elem_type = TREE_TYPE (type);
8410 enum machine_mode elem_mode = TYPE_MODE (elem_type);
8411 int elem_size = GET_MODE_SIZE (elem_mode);
8413 if (elem_size < UNITS_PER_WORD)
8415 tree real_part, imag_part;
8416 gimple_seq post = NULL;
8418 real_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
8419 &post);
8420 /* Copy the value into a temporary, lest the formal temporary
8421 be reused out from under us. */
8422 real_part = get_initialized_tmp_var (real_part, pre_p, &post);
8423 gimple_seq_add_seq (pre_p, post);
8425 imag_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
8426 post_p);
8428 return build2 (COMPLEX_EXPR, type, real_part, imag_part);
8432 return std_gimplify_va_arg_expr (valist, type, pre_p, post_p);
8435 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
8436 f_fpr = TREE_CHAIN (f_gpr);
8437 f_res = TREE_CHAIN (f_fpr);
8438 f_ovf = TREE_CHAIN (f_res);
8439 f_sav = TREE_CHAIN (f_ovf);
8441 valist = build_va_arg_indirect_ref (valist);
8442 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
8443 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), unshare_expr (valist),
8444 f_fpr, NULL_TREE);
8445 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), unshare_expr (valist),
8446 f_ovf, NULL_TREE);
8447 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), unshare_expr (valist),
8448 f_sav, NULL_TREE);
8450 size = int_size_in_bytes (type);
8451 rsize = (size + 3) / 4;
8452 align = 1;
8454 if (TARGET_HARD_FLOAT && TARGET_FPRS
8455 && ((TARGET_SINGLE_FLOAT && TYPE_MODE (type) == SFmode)
8456 || (TARGET_DOUBLE_FLOAT
8457 && (TYPE_MODE (type) == DFmode
8458 || TYPE_MODE (type) == TFmode
8459 || TYPE_MODE (type) == SDmode
8460 || TYPE_MODE (type) == DDmode
8461 || TYPE_MODE (type) == TDmode))))
8463 /* FP args go in FP registers, if present. */
8464 reg = fpr;
8465 n_reg = (size + 7) / 8;
8466 sav_ofs = ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? 8 : 4) * 4;
8467 sav_scale = ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? 8 : 4);
8468 if (TYPE_MODE (type) != SFmode && TYPE_MODE (type) != SDmode)
8469 align = 8;
8471 else
8473 /* Otherwise into GP registers. */
8474 reg = gpr;
8475 n_reg = rsize;
8476 sav_ofs = 0;
8477 sav_scale = 4;
8478 if (n_reg == 2)
8479 align = 8;
8482 /* Pull the value out of the saved registers.... */
8484 lab_over = NULL;
8485 addr = create_tmp_var (ptr_type_node, "addr");
8487 /* AltiVec vectors never go in registers when -mabi=altivec. */
8488 if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
8489 align = 16;
8490 else
8492 lab_false = create_artificial_label (input_location);
8493 lab_over = create_artificial_label (input_location);
8495 /* Long long and SPE vectors are aligned in the registers.
8496 As are any other 2 gpr item such as complex int due to a
8497 historical mistake. */
8498 u = reg;
8499 if (n_reg == 2 && reg == gpr)
8501 regalign = 1;
8502 u = build2 (BIT_AND_EXPR, TREE_TYPE (reg), unshare_expr (reg),
8503 build_int_cst (TREE_TYPE (reg), n_reg - 1));
8504 u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg),
8505 unshare_expr (reg), u);
8507 /* _Decimal128 is passed in even/odd fpr pairs; the stored
8508 reg number is 0 for f1, so we want to make it odd. */
8509 else if (reg == fpr && TYPE_MODE (type) == TDmode)
8511 t = build2 (BIT_IOR_EXPR, TREE_TYPE (reg), unshare_expr (reg),
8512 build_int_cst (TREE_TYPE (reg), 1));
8513 u = build2 (MODIFY_EXPR, void_type_node, unshare_expr (reg), t);
8516 t = fold_convert (TREE_TYPE (reg), size_int (8 - n_reg + 1));
8517 t = build2 (GE_EXPR, boolean_type_node, u, t);
8518 u = build1 (GOTO_EXPR, void_type_node, lab_false);
8519 t = build3 (COND_EXPR, void_type_node, t, u, NULL_TREE);
8520 gimplify_and_add (t, pre_p);
8522 t = sav;
8523 if (sav_ofs)
8524 t = build2 (POINTER_PLUS_EXPR, ptr_type_node, sav, size_int (sav_ofs));
8526 u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg), unshare_expr (reg),
8527 build_int_cst (TREE_TYPE (reg), n_reg));
8528 u = fold_convert (sizetype, u);
8529 u = build2 (MULT_EXPR, sizetype, u, size_int (sav_scale));
8530 t = build2 (POINTER_PLUS_EXPR, ptr_type_node, t, u);
8532 /* _Decimal32 varargs are located in the second word of the 64-bit
8533 FP register for 32-bit binaries. */
8534 if (!TARGET_POWERPC64
8535 && TARGET_HARD_FLOAT && TARGET_FPRS
8536 && TYPE_MODE (type) == SDmode)
8537 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (size));
8539 gimplify_assign (addr, t, pre_p);
8541 gimple_seq_add_stmt (pre_p, gimple_build_goto (lab_over));
8543 stmt = gimple_build_label (lab_false);
8544 gimple_seq_add_stmt (pre_p, stmt);
8546 if ((n_reg == 2 && !regalign) || n_reg > 2)
8548 /* Ensure that we don't find any more args in regs.
8549 Alignment has taken care of for special cases. */
8550 gimplify_assign (reg, build_int_cst (TREE_TYPE (reg), 8), pre_p);
8554 /* ... otherwise out of the overflow area. */
8556 /* Care for on-stack alignment if needed. */
8557 t = ovf;
8558 if (align != 1)
8560 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (align - 1));
8561 t = fold_convert (sizetype, t);
8562 t = build2 (BIT_AND_EXPR, TREE_TYPE (t), t,
8563 size_int (-align));
8564 t = fold_convert (TREE_TYPE (ovf), t);
8566 gimplify_expr (&t, pre_p, NULL, is_gimple_val, fb_rvalue);
8568 gimplify_assign (unshare_expr (addr), t, pre_p);
8570 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (size));
8571 gimplify_assign (unshare_expr (ovf), t, pre_p);
8573 if (lab_over)
8575 stmt = gimple_build_label (lab_over);
8576 gimple_seq_add_stmt (pre_p, stmt);
8579 if (STRICT_ALIGNMENT
8580 && (TYPE_ALIGN (type)
8581 > (unsigned) BITS_PER_UNIT * (align < 4 ? 4 : align)))
8583 /* The value (of type complex double, for example) may not be
8584 aligned in memory in the saved registers, so copy via a
8585 temporary. (This is the same code as used for SPARC.) */
8586 tree tmp = create_tmp_var (type, "va_arg_tmp");
8587 tree dest_addr = build_fold_addr_expr (tmp);
8589 tree copy = build_call_expr (implicit_built_in_decls[BUILT_IN_MEMCPY],
8590 3, dest_addr, addr, size_int (rsize * 4));
8592 gimplify_and_add (copy, pre_p);
8593 addr = dest_addr;
8596 addr = fold_convert (ptrtype, addr);
8597 return build_va_arg_indirect_ref (addr);
8600 /* Builtins. */
8602 static void
8603 def_builtin (int mask, const char *name, tree type, int code)
8605 if ((mask & target_flags) || TARGET_PAIRED_FLOAT)
8607 tree t;
8608 if (rs6000_builtin_decls[code])
8609 fatal_error ("internal error: builtin function to %s already processed.",
8610 name);
8612 rs6000_builtin_decls[code] = t =
8613 add_builtin_function (name, type, code, BUILT_IN_MD,
8614 NULL, NULL_TREE);
8616 gcc_assert (code >= 0 && code < (int)RS6000_BUILTIN_COUNT);
8617 switch (builtin_classify[code])
8619 default:
8620 gcc_unreachable ();
8622 /* assume builtin can do anything. */
8623 case RS6000_BTC_MISC:
8624 break;
8626 /* const function, function only depends on the inputs. */
8627 case RS6000_BTC_CONST:
8628 TREE_READONLY (t) = 1;
8629 TREE_NOTHROW (t) = 1;
8630 break;
8632 /* pure function, function can read global memory. */
8633 case RS6000_BTC_PURE:
8634 DECL_PURE_P (t) = 1;
8635 TREE_NOTHROW (t) = 1;
8636 break;
8638 /* Function is a math function. If rounding mode is on, then treat
8639 the function as not reading global memory, but it can have
8640 arbitrary side effects. If it is off, then assume the function is
8641 a const function. This mimics the ATTR_MATHFN_FPROUNDING
8642 attribute in builtin-attribute.def that is used for the math
8643 functions. */
8644 case RS6000_BTC_FP_PURE:
8645 TREE_NOTHROW (t) = 1;
8646 if (flag_rounding_math)
8648 DECL_PURE_P (t) = 1;
8649 DECL_IS_NOVOPS (t) = 1;
8651 else
8652 TREE_READONLY (t) = 1;
8653 break;
8658 /* Simple ternary operations: VECd = foo (VECa, VECb, VECc). */
8660 static const struct builtin_description bdesc_3arg[] =
8662 { MASK_ALTIVEC, CODE_FOR_altivec_vmaddfp, "__builtin_altivec_vmaddfp", ALTIVEC_BUILTIN_VMADDFP },
8663 { MASK_ALTIVEC, CODE_FOR_altivec_vmhaddshs, "__builtin_altivec_vmhaddshs", ALTIVEC_BUILTIN_VMHADDSHS },
8664 { MASK_ALTIVEC, CODE_FOR_altivec_vmhraddshs, "__builtin_altivec_vmhraddshs", ALTIVEC_BUILTIN_VMHRADDSHS },
8665 { MASK_ALTIVEC, CODE_FOR_altivec_vmladduhm, "__builtin_altivec_vmladduhm", ALTIVEC_BUILTIN_VMLADDUHM},
8666 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumubm, "__builtin_altivec_vmsumubm", ALTIVEC_BUILTIN_VMSUMUBM },
8667 { MASK_ALTIVEC, CODE_FOR_altivec_vmsummbm, "__builtin_altivec_vmsummbm", ALTIVEC_BUILTIN_VMSUMMBM },
8668 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhm, "__builtin_altivec_vmsumuhm", ALTIVEC_BUILTIN_VMSUMUHM },
8669 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshm, "__builtin_altivec_vmsumshm", ALTIVEC_BUILTIN_VMSUMSHM },
8670 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhs, "__builtin_altivec_vmsumuhs", ALTIVEC_BUILTIN_VMSUMUHS },
8671 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshs, "__builtin_altivec_vmsumshs", ALTIVEC_BUILTIN_VMSUMSHS },
8672 { MASK_ALTIVEC, CODE_FOR_altivec_vnmsubfp, "__builtin_altivec_vnmsubfp", ALTIVEC_BUILTIN_VNMSUBFP },
8673 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2df, "__builtin_altivec_vperm_2df", ALTIVEC_BUILTIN_VPERM_2DF },
8674 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2di, "__builtin_altivec_vperm_2di", ALTIVEC_BUILTIN_VPERM_2DI },
8675 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4sf, "__builtin_altivec_vperm_4sf", ALTIVEC_BUILTIN_VPERM_4SF },
8676 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4si, "__builtin_altivec_vperm_4si", ALTIVEC_BUILTIN_VPERM_4SI },
8677 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v8hi, "__builtin_altivec_vperm_8hi", ALTIVEC_BUILTIN_VPERM_8HI },
8678 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_altivec_vperm_16qi", ALTIVEC_BUILTIN_VPERM_16QI },
8679 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2di_uns, "__builtin_altivec_vperm_2di_uns", ALTIVEC_BUILTIN_VPERM_2DI_UNS },
8680 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4si_uns, "__builtin_altivec_vperm_4si_uns", ALTIVEC_BUILTIN_VPERM_4SI_UNS },
8681 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v8hi_uns, "__builtin_altivec_vperm_8hi_uns", ALTIVEC_BUILTIN_VPERM_8HI_UNS },
8682 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_altivec_vperm_16qi_uns", ALTIVEC_BUILTIN_VPERM_16QI_UNS },
8683 { MASK_ALTIVEC, CODE_FOR_vector_select_v4sf, "__builtin_altivec_vsel_4sf", ALTIVEC_BUILTIN_VSEL_4SF },
8684 { MASK_ALTIVEC, CODE_FOR_vector_select_v4si, "__builtin_altivec_vsel_4si", ALTIVEC_BUILTIN_VSEL_4SI },
8685 { MASK_ALTIVEC, CODE_FOR_vector_select_v8hi, "__builtin_altivec_vsel_8hi", ALTIVEC_BUILTIN_VSEL_8HI },
8686 { MASK_ALTIVEC, CODE_FOR_vector_select_v16qi, "__builtin_altivec_vsel_16qi", ALTIVEC_BUILTIN_VSEL_16QI },
8687 { MASK_ALTIVEC, CODE_FOR_vector_select_v2df, "__builtin_altivec_vsel_2df", ALTIVEC_BUILTIN_VSEL_2DF },
8688 { MASK_ALTIVEC, CODE_FOR_vector_select_v2di, "__builtin_altivec_vsel_2di", ALTIVEC_BUILTIN_VSEL_2DI },
8689 { MASK_ALTIVEC, CODE_FOR_vector_select_v4si_uns, "__builtin_altivec_vsel_4si_uns", ALTIVEC_BUILTIN_VSEL_4SI_UNS },
8690 { MASK_ALTIVEC, CODE_FOR_vector_select_v8hi_uns, "__builtin_altivec_vsel_8hi_uns", ALTIVEC_BUILTIN_VSEL_8HI_UNS },
8691 { MASK_ALTIVEC, CODE_FOR_vector_select_v16qi_uns, "__builtin_altivec_vsel_16qi_uns", ALTIVEC_BUILTIN_VSEL_16QI_UNS },
8692 { MASK_ALTIVEC, CODE_FOR_vector_select_v2di_uns, "__builtin_altivec_vsel_2di_uns", ALTIVEC_BUILTIN_VSEL_2DI_UNS },
8693 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v16qi, "__builtin_altivec_vsldoi_16qi", ALTIVEC_BUILTIN_VSLDOI_16QI },
8694 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v8hi, "__builtin_altivec_vsldoi_8hi", ALTIVEC_BUILTIN_VSLDOI_8HI },
8695 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v4si, "__builtin_altivec_vsldoi_4si", ALTIVEC_BUILTIN_VSLDOI_4SI },
8696 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v4sf, "__builtin_altivec_vsldoi_4sf", ALTIVEC_BUILTIN_VSLDOI_4SF },
8698 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_madd", ALTIVEC_BUILTIN_VEC_MADD },
8699 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_madds", ALTIVEC_BUILTIN_VEC_MADDS },
8700 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mladd", ALTIVEC_BUILTIN_VEC_MLADD },
8701 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mradds", ALTIVEC_BUILTIN_VEC_MRADDS },
8702 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msum", ALTIVEC_BUILTIN_VEC_MSUM },
8703 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumshm", ALTIVEC_BUILTIN_VEC_VMSUMSHM },
8704 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumuhm", ALTIVEC_BUILTIN_VEC_VMSUMUHM },
8705 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsummbm", ALTIVEC_BUILTIN_VEC_VMSUMMBM },
8706 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumubm", ALTIVEC_BUILTIN_VEC_VMSUMUBM },
8707 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msums", ALTIVEC_BUILTIN_VEC_MSUMS },
8708 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumshs", ALTIVEC_BUILTIN_VEC_VMSUMSHS },
8709 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumuhs", ALTIVEC_BUILTIN_VEC_VMSUMUHS },
8710 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nmsub", ALTIVEC_BUILTIN_VEC_NMSUB },
8711 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_perm", ALTIVEC_BUILTIN_VEC_PERM },
8712 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sel", ALTIVEC_BUILTIN_VEC_SEL },
8714 { MASK_VSX, CODE_FOR_vsx_fmaddv2df4, "__builtin_vsx_xvmadddp", VSX_BUILTIN_XVMADDDP },
8715 { MASK_VSX, CODE_FOR_vsx_fmsubv2df4, "__builtin_vsx_xvmsubdp", VSX_BUILTIN_XVMSUBDP },
8716 { MASK_VSX, CODE_FOR_vsx_fnmaddv2df4, "__builtin_vsx_xvnmadddp", VSX_BUILTIN_XVNMADDDP },
8717 { MASK_VSX, CODE_FOR_vsx_fnmsubv2df4, "__builtin_vsx_xvnmsubdp", VSX_BUILTIN_XVNMSUBDP },
8719 { MASK_VSX, CODE_FOR_vsx_fmaddv4sf4, "__builtin_vsx_xvmaddsp", VSX_BUILTIN_XVMADDSP },
8720 { MASK_VSX, CODE_FOR_vsx_fmsubv4sf4, "__builtin_vsx_xvmsubsp", VSX_BUILTIN_XVMSUBSP },
8721 { MASK_VSX, CODE_FOR_vsx_fnmaddv4sf4, "__builtin_vsx_xvnmaddsp", VSX_BUILTIN_XVNMADDSP },
8722 { MASK_VSX, CODE_FOR_vsx_fnmsubv4sf4, "__builtin_vsx_xvnmsubsp", VSX_BUILTIN_XVNMSUBSP },
8724 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msub", VSX_BUILTIN_VEC_MSUB },
8725 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nmadd", VSX_BUILTIN_VEC_NMADD },
8727 { MASK_VSX, CODE_FOR_vector_select_v2di, "__builtin_vsx_xxsel_2di", VSX_BUILTIN_XXSEL_2DI },
8728 { MASK_VSX, CODE_FOR_vector_select_v2df, "__builtin_vsx_xxsel_2df", VSX_BUILTIN_XXSEL_2DF },
8729 { MASK_VSX, CODE_FOR_vector_select_v4sf, "__builtin_vsx_xxsel_4sf", VSX_BUILTIN_XXSEL_4SF },
8730 { MASK_VSX, CODE_FOR_vector_select_v4si, "__builtin_vsx_xxsel_4si", VSX_BUILTIN_XXSEL_4SI },
8731 { MASK_VSX, CODE_FOR_vector_select_v8hi, "__builtin_vsx_xxsel_8hi", VSX_BUILTIN_XXSEL_8HI },
8732 { MASK_VSX, CODE_FOR_vector_select_v16qi, "__builtin_vsx_xxsel_16qi", VSX_BUILTIN_XXSEL_16QI },
8733 { MASK_VSX, CODE_FOR_vector_select_v2di_uns, "__builtin_vsx_xxsel_2di_uns", VSX_BUILTIN_XXSEL_2DI_UNS },
8734 { MASK_VSX, CODE_FOR_vector_select_v4si_uns, "__builtin_vsx_xxsel_4si_uns", VSX_BUILTIN_XXSEL_4SI_UNS },
8735 { MASK_VSX, CODE_FOR_vector_select_v8hi_uns, "__builtin_vsx_xxsel_8hi_uns", VSX_BUILTIN_XXSEL_8HI_UNS },
8736 { MASK_VSX, CODE_FOR_vector_select_v16qi_uns, "__builtin_vsx_xxsel_16qi_uns", VSX_BUILTIN_XXSEL_16QI_UNS },
8738 { MASK_VSX, CODE_FOR_altivec_vperm_v2di, "__builtin_vsx_vperm_2di", VSX_BUILTIN_VPERM_2DI },
8739 { MASK_VSX, CODE_FOR_altivec_vperm_v2df, "__builtin_vsx_vperm_2df", VSX_BUILTIN_VPERM_2DF },
8740 { MASK_VSX, CODE_FOR_altivec_vperm_v4sf, "__builtin_vsx_vperm_4sf", VSX_BUILTIN_VPERM_4SF },
8741 { MASK_VSX, CODE_FOR_altivec_vperm_v4si, "__builtin_vsx_vperm_4si", VSX_BUILTIN_VPERM_4SI },
8742 { MASK_VSX, CODE_FOR_altivec_vperm_v8hi, "__builtin_vsx_vperm_8hi", VSX_BUILTIN_VPERM_8HI },
8743 { MASK_VSX, CODE_FOR_altivec_vperm_v16qi, "__builtin_vsx_vperm_16qi", VSX_BUILTIN_VPERM_16QI },
8744 { MASK_VSX, CODE_FOR_altivec_vperm_v2di_uns, "__builtin_vsx_vperm_2di_uns", VSX_BUILTIN_VPERM_2DI_UNS },
8745 { MASK_VSX, CODE_FOR_altivec_vperm_v4si_uns, "__builtin_vsx_vperm_4si_uns", VSX_BUILTIN_VPERM_4SI_UNS },
8746 { MASK_VSX, CODE_FOR_altivec_vperm_v8hi_uns, "__builtin_vsx_vperm_8hi_uns", VSX_BUILTIN_VPERM_8HI_UNS },
8747 { MASK_VSX, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_vsx_vperm_16qi_uns", VSX_BUILTIN_VPERM_16QI_UNS },
8749 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v2df, "__builtin_vsx_xxpermdi_2df", VSX_BUILTIN_XXPERMDI_2DF },
8750 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v2di, "__builtin_vsx_xxpermdi_2di", VSX_BUILTIN_XXPERMDI_2DI },
8751 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v4sf, "__builtin_vsx_xxpermdi_4sf", VSX_BUILTIN_XXPERMDI_4SF },
8752 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v4si, "__builtin_vsx_xxpermdi_4si", VSX_BUILTIN_XXPERMDI_4SI },
8753 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v8hi, "__builtin_vsx_xxpermdi_8hi", VSX_BUILTIN_XXPERMDI_8HI },
8754 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v16qi, "__builtin_vsx_xxpermdi_16qi", VSX_BUILTIN_XXPERMDI_16QI },
8755 { MASK_VSX, CODE_FOR_nothing, "__builtin_vsx_xxpermdi", VSX_BUILTIN_VEC_XXPERMDI },
8756 { MASK_VSX, CODE_FOR_vsx_set_v2df, "__builtin_vsx_set_2df", VSX_BUILTIN_SET_2DF },
8757 { MASK_VSX, CODE_FOR_vsx_set_v2di, "__builtin_vsx_set_2di", VSX_BUILTIN_SET_2DI },
8759 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v2di, "__builtin_vsx_xxsldwi_2di", VSX_BUILTIN_XXSLDWI_2DI },
8760 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v2df, "__builtin_vsx_xxsldwi_2df", VSX_BUILTIN_XXSLDWI_2DF },
8761 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v4sf, "__builtin_vsx_xxsldwi_4sf", VSX_BUILTIN_XXSLDWI_4SF },
8762 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v4si, "__builtin_vsx_xxsldwi_4si", VSX_BUILTIN_XXSLDWI_4SI },
8763 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v8hi, "__builtin_vsx_xxsldwi_8hi", VSX_BUILTIN_XXSLDWI_8HI },
8764 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v16qi, "__builtin_vsx_xxsldwi_16qi", VSX_BUILTIN_XXSLDWI_16QI },
8765 { MASK_VSX, CODE_FOR_nothing, "__builtin_vsx_xxsldwi", VSX_BUILTIN_VEC_XXSLDWI },
8767 { 0, CODE_FOR_paired_msub, "__builtin_paired_msub", PAIRED_BUILTIN_MSUB },
8768 { 0, CODE_FOR_paired_madd, "__builtin_paired_madd", PAIRED_BUILTIN_MADD },
8769 { 0, CODE_FOR_paired_madds0, "__builtin_paired_madds0", PAIRED_BUILTIN_MADDS0 },
8770 { 0, CODE_FOR_paired_madds1, "__builtin_paired_madds1", PAIRED_BUILTIN_MADDS1 },
8771 { 0, CODE_FOR_paired_nmsub, "__builtin_paired_nmsub", PAIRED_BUILTIN_NMSUB },
8772 { 0, CODE_FOR_paired_nmadd, "__builtin_paired_nmadd", PAIRED_BUILTIN_NMADD },
8773 { 0, CODE_FOR_paired_sum0, "__builtin_paired_sum0", PAIRED_BUILTIN_SUM0 },
8774 { 0, CODE_FOR_paired_sum1, "__builtin_paired_sum1", PAIRED_BUILTIN_SUM1 },
8775 { 0, CODE_FOR_selv2sf4, "__builtin_paired_selv2sf4", PAIRED_BUILTIN_SELV2SF4 },
8778 /* DST operations: void foo (void *, const int, const char). */
8780 static const struct builtin_description bdesc_dst[] =
8782 { MASK_ALTIVEC, CODE_FOR_altivec_dst, "__builtin_altivec_dst", ALTIVEC_BUILTIN_DST },
8783 { MASK_ALTIVEC, CODE_FOR_altivec_dstt, "__builtin_altivec_dstt", ALTIVEC_BUILTIN_DSTT },
8784 { MASK_ALTIVEC, CODE_FOR_altivec_dstst, "__builtin_altivec_dstst", ALTIVEC_BUILTIN_DSTST },
8785 { MASK_ALTIVEC, CODE_FOR_altivec_dststt, "__builtin_altivec_dststt", ALTIVEC_BUILTIN_DSTSTT },
8787 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dst", ALTIVEC_BUILTIN_VEC_DST },
8788 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dstt", ALTIVEC_BUILTIN_VEC_DSTT },
8789 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dstst", ALTIVEC_BUILTIN_VEC_DSTST },
8790 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dststt", ALTIVEC_BUILTIN_VEC_DSTSTT }
8793 /* Simple binary operations: VECc = foo (VECa, VECb). */
8795 static struct builtin_description bdesc_2arg[] =
8797 { MASK_ALTIVEC, CODE_FOR_addv16qi3, "__builtin_altivec_vaddubm", ALTIVEC_BUILTIN_VADDUBM },
8798 { MASK_ALTIVEC, CODE_FOR_addv8hi3, "__builtin_altivec_vadduhm", ALTIVEC_BUILTIN_VADDUHM },
8799 { MASK_ALTIVEC, CODE_FOR_addv4si3, "__builtin_altivec_vadduwm", ALTIVEC_BUILTIN_VADDUWM },
8800 { MASK_ALTIVEC, CODE_FOR_addv4sf3, "__builtin_altivec_vaddfp", ALTIVEC_BUILTIN_VADDFP },
8801 { MASK_ALTIVEC, CODE_FOR_altivec_vaddcuw, "__builtin_altivec_vaddcuw", ALTIVEC_BUILTIN_VADDCUW },
8802 { MASK_ALTIVEC, CODE_FOR_altivec_vaddubs, "__builtin_altivec_vaddubs", ALTIVEC_BUILTIN_VADDUBS },
8803 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsbs, "__builtin_altivec_vaddsbs", ALTIVEC_BUILTIN_VADDSBS },
8804 { MASK_ALTIVEC, CODE_FOR_altivec_vadduhs, "__builtin_altivec_vadduhs", ALTIVEC_BUILTIN_VADDUHS },
8805 { MASK_ALTIVEC, CODE_FOR_altivec_vaddshs, "__builtin_altivec_vaddshs", ALTIVEC_BUILTIN_VADDSHS },
8806 { MASK_ALTIVEC, CODE_FOR_altivec_vadduws, "__builtin_altivec_vadduws", ALTIVEC_BUILTIN_VADDUWS },
8807 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsws, "__builtin_altivec_vaddsws", ALTIVEC_BUILTIN_VADDSWS },
8808 { MASK_ALTIVEC, CODE_FOR_andv4si3, "__builtin_altivec_vand", ALTIVEC_BUILTIN_VAND },
8809 { MASK_ALTIVEC, CODE_FOR_andcv4si3, "__builtin_altivec_vandc", ALTIVEC_BUILTIN_VANDC },
8810 { MASK_ALTIVEC, CODE_FOR_altivec_vavgub, "__builtin_altivec_vavgub", ALTIVEC_BUILTIN_VAVGUB },
8811 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsb, "__builtin_altivec_vavgsb", ALTIVEC_BUILTIN_VAVGSB },
8812 { MASK_ALTIVEC, CODE_FOR_altivec_vavguh, "__builtin_altivec_vavguh", ALTIVEC_BUILTIN_VAVGUH },
8813 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsh, "__builtin_altivec_vavgsh", ALTIVEC_BUILTIN_VAVGSH },
8814 { MASK_ALTIVEC, CODE_FOR_altivec_vavguw, "__builtin_altivec_vavguw", ALTIVEC_BUILTIN_VAVGUW },
8815 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsw, "__builtin_altivec_vavgsw", ALTIVEC_BUILTIN_VAVGSW },
8816 { MASK_ALTIVEC, CODE_FOR_altivec_vcfux, "__builtin_altivec_vcfux", ALTIVEC_BUILTIN_VCFUX },
8817 { MASK_ALTIVEC, CODE_FOR_altivec_vcfsx, "__builtin_altivec_vcfsx", ALTIVEC_BUILTIN_VCFSX },
8818 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpbfp, "__builtin_altivec_vcmpbfp", ALTIVEC_BUILTIN_VCMPBFP },
8819 { MASK_ALTIVEC, CODE_FOR_vector_eqv16qi, "__builtin_altivec_vcmpequb", ALTIVEC_BUILTIN_VCMPEQUB },
8820 { MASK_ALTIVEC, CODE_FOR_vector_eqv8hi, "__builtin_altivec_vcmpequh", ALTIVEC_BUILTIN_VCMPEQUH },
8821 { MASK_ALTIVEC, CODE_FOR_vector_eqv4si, "__builtin_altivec_vcmpequw", ALTIVEC_BUILTIN_VCMPEQUW },
8822 { MASK_ALTIVEC, CODE_FOR_vector_eqv4sf, "__builtin_altivec_vcmpeqfp", ALTIVEC_BUILTIN_VCMPEQFP },
8823 { MASK_ALTIVEC, CODE_FOR_vector_gev4sf, "__builtin_altivec_vcmpgefp", ALTIVEC_BUILTIN_VCMPGEFP },
8824 { MASK_ALTIVEC, CODE_FOR_vector_gtuv16qi, "__builtin_altivec_vcmpgtub", ALTIVEC_BUILTIN_VCMPGTUB },
8825 { MASK_ALTIVEC, CODE_FOR_vector_gtv16qi, "__builtin_altivec_vcmpgtsb", ALTIVEC_BUILTIN_VCMPGTSB },
8826 { MASK_ALTIVEC, CODE_FOR_vector_gtuv8hi, "__builtin_altivec_vcmpgtuh", ALTIVEC_BUILTIN_VCMPGTUH },
8827 { MASK_ALTIVEC, CODE_FOR_vector_gtv8hi, "__builtin_altivec_vcmpgtsh", ALTIVEC_BUILTIN_VCMPGTSH },
8828 { MASK_ALTIVEC, CODE_FOR_vector_gtuv4si, "__builtin_altivec_vcmpgtuw", ALTIVEC_BUILTIN_VCMPGTUW },
8829 { MASK_ALTIVEC, CODE_FOR_vector_gtv4si, "__builtin_altivec_vcmpgtsw", ALTIVEC_BUILTIN_VCMPGTSW },
8830 { MASK_ALTIVEC, CODE_FOR_vector_gtv4sf, "__builtin_altivec_vcmpgtfp", ALTIVEC_BUILTIN_VCMPGTFP },
8831 { MASK_ALTIVEC, CODE_FOR_altivec_vctsxs, "__builtin_altivec_vctsxs", ALTIVEC_BUILTIN_VCTSXS },
8832 { MASK_ALTIVEC, CODE_FOR_altivec_vctuxs, "__builtin_altivec_vctuxs", ALTIVEC_BUILTIN_VCTUXS },
8833 { MASK_ALTIVEC, CODE_FOR_umaxv16qi3, "__builtin_altivec_vmaxub", ALTIVEC_BUILTIN_VMAXUB },
8834 { MASK_ALTIVEC, CODE_FOR_smaxv16qi3, "__builtin_altivec_vmaxsb", ALTIVEC_BUILTIN_VMAXSB },
8835 { MASK_ALTIVEC, CODE_FOR_umaxv8hi3, "__builtin_altivec_vmaxuh", ALTIVEC_BUILTIN_VMAXUH },
8836 { MASK_ALTIVEC, CODE_FOR_smaxv8hi3, "__builtin_altivec_vmaxsh", ALTIVEC_BUILTIN_VMAXSH },
8837 { MASK_ALTIVEC, CODE_FOR_umaxv4si3, "__builtin_altivec_vmaxuw", ALTIVEC_BUILTIN_VMAXUW },
8838 { MASK_ALTIVEC, CODE_FOR_smaxv4si3, "__builtin_altivec_vmaxsw", ALTIVEC_BUILTIN_VMAXSW },
8839 { MASK_ALTIVEC, CODE_FOR_smaxv4sf3, "__builtin_altivec_vmaxfp", ALTIVEC_BUILTIN_VMAXFP },
8840 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghb, "__builtin_altivec_vmrghb", ALTIVEC_BUILTIN_VMRGHB },
8841 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghh, "__builtin_altivec_vmrghh", ALTIVEC_BUILTIN_VMRGHH },
8842 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghw, "__builtin_altivec_vmrghw", ALTIVEC_BUILTIN_VMRGHW },
8843 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglb, "__builtin_altivec_vmrglb", ALTIVEC_BUILTIN_VMRGLB },
8844 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglh, "__builtin_altivec_vmrglh", ALTIVEC_BUILTIN_VMRGLH },
8845 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglw, "__builtin_altivec_vmrglw", ALTIVEC_BUILTIN_VMRGLW },
8846 { MASK_ALTIVEC, CODE_FOR_uminv16qi3, "__builtin_altivec_vminub", ALTIVEC_BUILTIN_VMINUB },
8847 { MASK_ALTIVEC, CODE_FOR_sminv16qi3, "__builtin_altivec_vminsb", ALTIVEC_BUILTIN_VMINSB },
8848 { MASK_ALTIVEC, CODE_FOR_uminv8hi3, "__builtin_altivec_vminuh", ALTIVEC_BUILTIN_VMINUH },
8849 { MASK_ALTIVEC, CODE_FOR_sminv8hi3, "__builtin_altivec_vminsh", ALTIVEC_BUILTIN_VMINSH },
8850 { MASK_ALTIVEC, CODE_FOR_uminv4si3, "__builtin_altivec_vminuw", ALTIVEC_BUILTIN_VMINUW },
8851 { MASK_ALTIVEC, CODE_FOR_sminv4si3, "__builtin_altivec_vminsw", ALTIVEC_BUILTIN_VMINSW },
8852 { MASK_ALTIVEC, CODE_FOR_sminv4sf3, "__builtin_altivec_vminfp", ALTIVEC_BUILTIN_VMINFP },
8853 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleub, "__builtin_altivec_vmuleub", ALTIVEC_BUILTIN_VMULEUB },
8854 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleub, "__builtin_altivec_vmuleub_uns", ALTIVEC_BUILTIN_VMULEUB_UNS },
8855 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesb, "__builtin_altivec_vmulesb", ALTIVEC_BUILTIN_VMULESB },
8856 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleuh, "__builtin_altivec_vmuleuh", ALTIVEC_BUILTIN_VMULEUH },
8857 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleuh, "__builtin_altivec_vmuleuh_uns", ALTIVEC_BUILTIN_VMULEUH_UNS },
8858 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesh, "__builtin_altivec_vmulesh", ALTIVEC_BUILTIN_VMULESH },
8859 { MASK_ALTIVEC, CODE_FOR_altivec_vmuloub, "__builtin_altivec_vmuloub", ALTIVEC_BUILTIN_VMULOUB },
8860 { MASK_ALTIVEC, CODE_FOR_altivec_vmuloub, "__builtin_altivec_vmuloub_uns", ALTIVEC_BUILTIN_VMULOUB_UNS },
8861 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosb, "__builtin_altivec_vmulosb", ALTIVEC_BUILTIN_VMULOSB },
8862 { MASK_ALTIVEC, CODE_FOR_altivec_vmulouh, "__builtin_altivec_vmulouh", ALTIVEC_BUILTIN_VMULOUH },
8863 { MASK_ALTIVEC, CODE_FOR_altivec_vmulouh, "__builtin_altivec_vmulouh_uns", ALTIVEC_BUILTIN_VMULOUH_UNS },
8864 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosh, "__builtin_altivec_vmulosh", ALTIVEC_BUILTIN_VMULOSH },
8865 { MASK_ALTIVEC, CODE_FOR_norv4si3, "__builtin_altivec_vnor", ALTIVEC_BUILTIN_VNOR },
8866 { MASK_ALTIVEC, CODE_FOR_iorv4si3, "__builtin_altivec_vor", ALTIVEC_BUILTIN_VOR },
8867 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhum, "__builtin_altivec_vpkuhum", ALTIVEC_BUILTIN_VPKUHUM },
8868 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwum, "__builtin_altivec_vpkuwum", ALTIVEC_BUILTIN_VPKUWUM },
8869 { MASK_ALTIVEC, CODE_FOR_altivec_vpkpx, "__builtin_altivec_vpkpx", ALTIVEC_BUILTIN_VPKPX },
8870 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshss, "__builtin_altivec_vpkshss", ALTIVEC_BUILTIN_VPKSHSS },
8871 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswss, "__builtin_altivec_vpkswss", ALTIVEC_BUILTIN_VPKSWSS },
8872 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhus, "__builtin_altivec_vpkuhus", ALTIVEC_BUILTIN_VPKUHUS },
8873 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshus, "__builtin_altivec_vpkshus", ALTIVEC_BUILTIN_VPKSHUS },
8874 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwus, "__builtin_altivec_vpkuwus", ALTIVEC_BUILTIN_VPKUWUS },
8875 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswus, "__builtin_altivec_vpkswus", ALTIVEC_BUILTIN_VPKSWUS },
8876 { MASK_ALTIVEC, CODE_FOR_vrotlv16qi3, "__builtin_altivec_vrlb", ALTIVEC_BUILTIN_VRLB },
8877 { MASK_ALTIVEC, CODE_FOR_vrotlv8hi3, "__builtin_altivec_vrlh", ALTIVEC_BUILTIN_VRLH },
8878 { MASK_ALTIVEC, CODE_FOR_vrotlv4si3, "__builtin_altivec_vrlw", ALTIVEC_BUILTIN_VRLW },
8879 { MASK_ALTIVEC, CODE_FOR_vashlv16qi3, "__builtin_altivec_vslb", ALTIVEC_BUILTIN_VSLB },
8880 { MASK_ALTIVEC, CODE_FOR_vashlv8hi3, "__builtin_altivec_vslh", ALTIVEC_BUILTIN_VSLH },
8881 { MASK_ALTIVEC, CODE_FOR_vashlv4si3, "__builtin_altivec_vslw", ALTIVEC_BUILTIN_VSLW },
8882 { MASK_ALTIVEC, CODE_FOR_altivec_vsl, "__builtin_altivec_vsl", ALTIVEC_BUILTIN_VSL },
8883 { MASK_ALTIVEC, CODE_FOR_altivec_vslo, "__builtin_altivec_vslo", ALTIVEC_BUILTIN_VSLO },
8884 { MASK_ALTIVEC, CODE_FOR_altivec_vspltb, "__builtin_altivec_vspltb", ALTIVEC_BUILTIN_VSPLTB },
8885 { MASK_ALTIVEC, CODE_FOR_altivec_vsplth, "__builtin_altivec_vsplth", ALTIVEC_BUILTIN_VSPLTH },
8886 { MASK_ALTIVEC, CODE_FOR_altivec_vspltw, "__builtin_altivec_vspltw", ALTIVEC_BUILTIN_VSPLTW },
8887 { MASK_ALTIVEC, CODE_FOR_vlshrv16qi3, "__builtin_altivec_vsrb", ALTIVEC_BUILTIN_VSRB },
8888 { MASK_ALTIVEC, CODE_FOR_vlshrv8hi3, "__builtin_altivec_vsrh", ALTIVEC_BUILTIN_VSRH },
8889 { MASK_ALTIVEC, CODE_FOR_vlshrv4si3, "__builtin_altivec_vsrw", ALTIVEC_BUILTIN_VSRW },
8890 { MASK_ALTIVEC, CODE_FOR_vashrv16qi3, "__builtin_altivec_vsrab", ALTIVEC_BUILTIN_VSRAB },
8891 { MASK_ALTIVEC, CODE_FOR_vashrv8hi3, "__builtin_altivec_vsrah", ALTIVEC_BUILTIN_VSRAH },
8892 { MASK_ALTIVEC, CODE_FOR_vashrv4si3, "__builtin_altivec_vsraw", ALTIVEC_BUILTIN_VSRAW },
8893 { MASK_ALTIVEC, CODE_FOR_altivec_vsr, "__builtin_altivec_vsr", ALTIVEC_BUILTIN_VSR },
8894 { MASK_ALTIVEC, CODE_FOR_altivec_vsro, "__builtin_altivec_vsro", ALTIVEC_BUILTIN_VSRO },
8895 { MASK_ALTIVEC, CODE_FOR_subv16qi3, "__builtin_altivec_vsububm", ALTIVEC_BUILTIN_VSUBUBM },
8896 { MASK_ALTIVEC, CODE_FOR_subv8hi3, "__builtin_altivec_vsubuhm", ALTIVEC_BUILTIN_VSUBUHM },
8897 { MASK_ALTIVEC, CODE_FOR_subv4si3, "__builtin_altivec_vsubuwm", ALTIVEC_BUILTIN_VSUBUWM },
8898 { MASK_ALTIVEC, CODE_FOR_subv4sf3, "__builtin_altivec_vsubfp", ALTIVEC_BUILTIN_VSUBFP },
8899 { MASK_ALTIVEC, CODE_FOR_altivec_vsubcuw, "__builtin_altivec_vsubcuw", ALTIVEC_BUILTIN_VSUBCUW },
8900 { MASK_ALTIVEC, CODE_FOR_altivec_vsububs, "__builtin_altivec_vsububs", ALTIVEC_BUILTIN_VSUBUBS },
8901 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsbs, "__builtin_altivec_vsubsbs", ALTIVEC_BUILTIN_VSUBSBS },
8902 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuhs, "__builtin_altivec_vsubuhs", ALTIVEC_BUILTIN_VSUBUHS },
8903 { MASK_ALTIVEC, CODE_FOR_altivec_vsubshs, "__builtin_altivec_vsubshs", ALTIVEC_BUILTIN_VSUBSHS },
8904 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuws, "__builtin_altivec_vsubuws", ALTIVEC_BUILTIN_VSUBUWS },
8905 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsws, "__builtin_altivec_vsubsws", ALTIVEC_BUILTIN_VSUBSWS },
8906 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4ubs, "__builtin_altivec_vsum4ubs", ALTIVEC_BUILTIN_VSUM4UBS },
8907 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4sbs, "__builtin_altivec_vsum4sbs", ALTIVEC_BUILTIN_VSUM4SBS },
8908 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4shs, "__builtin_altivec_vsum4shs", ALTIVEC_BUILTIN_VSUM4SHS },
8909 { MASK_ALTIVEC, CODE_FOR_altivec_vsum2sws, "__builtin_altivec_vsum2sws", ALTIVEC_BUILTIN_VSUM2SWS },
8910 { MASK_ALTIVEC, CODE_FOR_altivec_vsumsws, "__builtin_altivec_vsumsws", ALTIVEC_BUILTIN_VSUMSWS },
8911 { MASK_ALTIVEC, CODE_FOR_xorv4si3, "__builtin_altivec_vxor", ALTIVEC_BUILTIN_VXOR },
8912 { MASK_ALTIVEC, CODE_FOR_vector_copysignv4sf3, "__builtin_altivec_copysignfp", ALTIVEC_BUILTIN_COPYSIGN_V4SF },
8914 { MASK_VSX, CODE_FOR_addv2df3, "__builtin_vsx_xvadddp", VSX_BUILTIN_XVADDDP },
8915 { MASK_VSX, CODE_FOR_subv2df3, "__builtin_vsx_xvsubdp", VSX_BUILTIN_XVSUBDP },
8916 { MASK_VSX, CODE_FOR_mulv2df3, "__builtin_vsx_xvmuldp", VSX_BUILTIN_XVMULDP },
8917 { MASK_VSX, CODE_FOR_divv2df3, "__builtin_vsx_xvdivdp", VSX_BUILTIN_XVDIVDP },
8918 { MASK_VSX, CODE_FOR_sminv2df3, "__builtin_vsx_xvmindp", VSX_BUILTIN_XVMINDP },
8919 { MASK_VSX, CODE_FOR_smaxv2df3, "__builtin_vsx_xvmaxdp", VSX_BUILTIN_XVMAXDP },
8920 { MASK_VSX, CODE_FOR_vsx_tdivv2df3_fe, "__builtin_vsx_xvtdivdp_fe", VSX_BUILTIN_XVTDIVDP_FE },
8921 { MASK_VSX, CODE_FOR_vsx_tdivv2df3_fg, "__builtin_vsx_xvtdivdp_fg", VSX_BUILTIN_XVTDIVDP_FG },
8922 { MASK_VSX, CODE_FOR_vector_eqv2df, "__builtin_vsx_xvcmpeqdp", VSX_BUILTIN_XVCMPEQDP },
8923 { MASK_VSX, CODE_FOR_vector_gtv2df, "__builtin_vsx_xvcmpgtdp", VSX_BUILTIN_XVCMPGTDP },
8924 { MASK_VSX, CODE_FOR_vector_gev2df, "__builtin_vsx_xvcmpgedp", VSX_BUILTIN_XVCMPGEDP },
8926 { MASK_VSX, CODE_FOR_addv4sf3, "__builtin_vsx_xvaddsp", VSX_BUILTIN_XVADDSP },
8927 { MASK_VSX, CODE_FOR_subv4sf3, "__builtin_vsx_xvsubsp", VSX_BUILTIN_XVSUBSP },
8928 { MASK_VSX, CODE_FOR_mulv4sf3, "__builtin_vsx_xvmulsp", VSX_BUILTIN_XVMULSP },
8929 { MASK_VSX, CODE_FOR_divv4sf3, "__builtin_vsx_xvdivsp", VSX_BUILTIN_XVDIVSP },
8930 { MASK_VSX, CODE_FOR_sminv4sf3, "__builtin_vsx_xvminsp", VSX_BUILTIN_XVMINSP },
8931 { MASK_VSX, CODE_FOR_smaxv4sf3, "__builtin_vsx_xvmaxsp", VSX_BUILTIN_XVMAXSP },
8932 { MASK_VSX, CODE_FOR_vsx_tdivv4sf3_fe, "__builtin_vsx_xvtdivsp_fe", VSX_BUILTIN_XVTDIVSP_FE },
8933 { MASK_VSX, CODE_FOR_vsx_tdivv4sf3_fg, "__builtin_vsx_xvtdivsp_fg", VSX_BUILTIN_XVTDIVSP_FG },
8934 { MASK_VSX, CODE_FOR_vector_eqv4sf, "__builtin_vsx_xvcmpeqsp", VSX_BUILTIN_XVCMPEQSP },
8935 { MASK_VSX, CODE_FOR_vector_gtv4sf, "__builtin_vsx_xvcmpgtsp", VSX_BUILTIN_XVCMPGTSP },
8936 { MASK_VSX, CODE_FOR_vector_gev4sf, "__builtin_vsx_xvcmpgesp", VSX_BUILTIN_XVCMPGESP },
8938 { MASK_VSX, CODE_FOR_smindf3, "__builtin_vsx_xsmindp", VSX_BUILTIN_XSMINDP },
8939 { MASK_VSX, CODE_FOR_smaxdf3, "__builtin_vsx_xsmaxdp", VSX_BUILTIN_XSMAXDP },
8940 { MASK_VSX, CODE_FOR_vsx_tdivdf3_fe, "__builtin_vsx_xstdivdp_fe", VSX_BUILTIN_XSTDIVDP_FE },
8941 { MASK_VSX, CODE_FOR_vsx_tdivdf3_fg, "__builtin_vsx_xstdivdp_fg", VSX_BUILTIN_XSTDIVDP_FG },
8942 { MASK_VSX, CODE_FOR_vector_copysignv2df3, "__builtin_vsx_cpsgndp", VSX_BUILTIN_CPSGNDP },
8943 { MASK_VSX, CODE_FOR_vector_copysignv4sf3, "__builtin_vsx_cpsgnsp", VSX_BUILTIN_CPSGNSP },
8945 { MASK_VSX, CODE_FOR_vsx_concat_v2df, "__builtin_vsx_concat_2df", VSX_BUILTIN_CONCAT_2DF },
8946 { MASK_VSX, CODE_FOR_vsx_concat_v2di, "__builtin_vsx_concat_2di", VSX_BUILTIN_CONCAT_2DI },
8947 { MASK_VSX, CODE_FOR_vsx_splat_v2df, "__builtin_vsx_splat_2df", VSX_BUILTIN_SPLAT_2DF },
8948 { MASK_VSX, CODE_FOR_vsx_splat_v2di, "__builtin_vsx_splat_2di", VSX_BUILTIN_SPLAT_2DI },
8949 { MASK_VSX, CODE_FOR_vsx_xxmrghw_v4sf, "__builtin_vsx_xxmrghw", VSX_BUILTIN_XXMRGHW_4SF },
8950 { MASK_VSX, CODE_FOR_vsx_xxmrghw_v4si, "__builtin_vsx_xxmrghw_4si", VSX_BUILTIN_XXMRGHW_4SI },
8951 { MASK_VSX, CODE_FOR_vsx_xxmrglw_v4sf, "__builtin_vsx_xxmrglw", VSX_BUILTIN_XXMRGLW_4SF },
8952 { MASK_VSX, CODE_FOR_vsx_xxmrglw_v4si, "__builtin_vsx_xxmrglw_4si", VSX_BUILTIN_XXMRGLW_4SI },
8953 { MASK_VSX, CODE_FOR_vec_interleave_lowv2df, "__builtin_vsx_mergel_2df", VSX_BUILTIN_VEC_MERGEL_V2DF },
8954 { MASK_VSX, CODE_FOR_vec_interleave_lowv2di, "__builtin_vsx_mergel_2di", VSX_BUILTIN_VEC_MERGEL_V2DI },
8955 { MASK_VSX, CODE_FOR_vec_interleave_highv2df, "__builtin_vsx_mergeh_2df", VSX_BUILTIN_VEC_MERGEH_V2DF },
8956 { MASK_VSX, CODE_FOR_vec_interleave_highv2di, "__builtin_vsx_mergeh_2di", VSX_BUILTIN_VEC_MERGEH_V2DI },
8958 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_add", ALTIVEC_BUILTIN_VEC_ADD },
8959 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vaddfp", ALTIVEC_BUILTIN_VEC_VADDFP },
8960 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduwm", ALTIVEC_BUILTIN_VEC_VADDUWM },
8961 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhm", ALTIVEC_BUILTIN_VEC_VADDUHM },
8962 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubm", ALTIVEC_BUILTIN_VEC_VADDUBM },
8963 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_addc", ALTIVEC_BUILTIN_VEC_ADDC },
8964 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_adds", ALTIVEC_BUILTIN_VEC_ADDS },
8965 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddsws", ALTIVEC_BUILTIN_VEC_VADDSWS },
8966 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduws", ALTIVEC_BUILTIN_VEC_VADDUWS },
8967 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddshs", ALTIVEC_BUILTIN_VEC_VADDSHS },
8968 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhs", ALTIVEC_BUILTIN_VEC_VADDUHS },
8969 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddsbs", ALTIVEC_BUILTIN_VEC_VADDSBS },
8970 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubs", ALTIVEC_BUILTIN_VEC_VADDUBS },
8971 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_and", ALTIVEC_BUILTIN_VEC_AND },
8972 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_andc", ALTIVEC_BUILTIN_VEC_ANDC },
8973 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_avg", ALTIVEC_BUILTIN_VEC_AVG },
8974 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsw", ALTIVEC_BUILTIN_VEC_VAVGSW },
8975 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavguw", ALTIVEC_BUILTIN_VEC_VAVGUW },
8976 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsh", ALTIVEC_BUILTIN_VEC_VAVGSH },
8977 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavguh", ALTIVEC_BUILTIN_VEC_VAVGUH },
8978 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsb", ALTIVEC_BUILTIN_VEC_VAVGSB },
8979 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgub", ALTIVEC_BUILTIN_VEC_VAVGUB },
8980 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpb", ALTIVEC_BUILTIN_VEC_CMPB },
8981 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpeq", ALTIVEC_BUILTIN_VEC_CMPEQ },
8982 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpeqfp", ALTIVEC_BUILTIN_VEC_VCMPEQFP },
8983 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequw", ALTIVEC_BUILTIN_VEC_VCMPEQUW },
8984 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequh", ALTIVEC_BUILTIN_VEC_VCMPEQUH },
8985 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequb", ALTIVEC_BUILTIN_VEC_VCMPEQUB },
8986 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpge", ALTIVEC_BUILTIN_VEC_CMPGE },
8987 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpgt", ALTIVEC_BUILTIN_VEC_CMPGT },
8988 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtfp", ALTIVEC_BUILTIN_VEC_VCMPGTFP },
8989 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsw", ALTIVEC_BUILTIN_VEC_VCMPGTSW },
8990 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtuw", ALTIVEC_BUILTIN_VEC_VCMPGTUW },
8991 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsh", ALTIVEC_BUILTIN_VEC_VCMPGTSH },
8992 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtuh", ALTIVEC_BUILTIN_VEC_VCMPGTUH },
8993 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsb", ALTIVEC_BUILTIN_VEC_VCMPGTSB },
8994 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtub", ALTIVEC_BUILTIN_VEC_VCMPGTUB },
8995 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmple", ALTIVEC_BUILTIN_VEC_CMPLE },
8996 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmplt", ALTIVEC_BUILTIN_VEC_CMPLT },
8997 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_copysign", ALTIVEC_BUILTIN_VEC_COPYSIGN },
8998 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_max", ALTIVEC_BUILTIN_VEC_MAX },
8999 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vmaxfp", ALTIVEC_BUILTIN_VEC_VMAXFP },
9000 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsw", ALTIVEC_BUILTIN_VEC_VMAXSW },
9001 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxuw", ALTIVEC_BUILTIN_VEC_VMAXUW },
9002 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsh", ALTIVEC_BUILTIN_VEC_VMAXSH },
9003 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxuh", ALTIVEC_BUILTIN_VEC_VMAXUH },
9004 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsb", ALTIVEC_BUILTIN_VEC_VMAXSB },
9005 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxub", ALTIVEC_BUILTIN_VEC_VMAXUB },
9006 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mergeh", ALTIVEC_BUILTIN_VEC_MERGEH },
9007 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghw", ALTIVEC_BUILTIN_VEC_VMRGHW },
9008 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghh", ALTIVEC_BUILTIN_VEC_VMRGHH },
9009 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghb", ALTIVEC_BUILTIN_VEC_VMRGHB },
9010 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mergel", ALTIVEC_BUILTIN_VEC_MERGEL },
9011 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglw", ALTIVEC_BUILTIN_VEC_VMRGLW },
9012 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglh", ALTIVEC_BUILTIN_VEC_VMRGLH },
9013 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglb", ALTIVEC_BUILTIN_VEC_VMRGLB },
9014 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_min", ALTIVEC_BUILTIN_VEC_MIN },
9015 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vminfp", ALTIVEC_BUILTIN_VEC_VMINFP },
9016 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsw", ALTIVEC_BUILTIN_VEC_VMINSW },
9017 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminuw", ALTIVEC_BUILTIN_VEC_VMINUW },
9018 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsh", ALTIVEC_BUILTIN_VEC_VMINSH },
9019 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminuh", ALTIVEC_BUILTIN_VEC_VMINUH },
9020 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsb", ALTIVEC_BUILTIN_VEC_VMINSB },
9021 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminub", ALTIVEC_BUILTIN_VEC_VMINUB },
9022 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mule", ALTIVEC_BUILTIN_VEC_MULE },
9023 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuleub", ALTIVEC_BUILTIN_VEC_VMULEUB },
9024 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulesb", ALTIVEC_BUILTIN_VEC_VMULESB },
9025 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuleuh", ALTIVEC_BUILTIN_VEC_VMULEUH },
9026 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulesh", ALTIVEC_BUILTIN_VEC_VMULESH },
9027 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mulo", ALTIVEC_BUILTIN_VEC_MULO },
9028 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulosh", ALTIVEC_BUILTIN_VEC_VMULOSH },
9029 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulouh", ALTIVEC_BUILTIN_VEC_VMULOUH },
9030 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulosb", ALTIVEC_BUILTIN_VEC_VMULOSB },
9031 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuloub", ALTIVEC_BUILTIN_VEC_VMULOUB },
9032 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_nor", ALTIVEC_BUILTIN_VEC_NOR },
9033 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_or", ALTIVEC_BUILTIN_VEC_OR },
9034 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_pack", ALTIVEC_BUILTIN_VEC_PACK },
9035 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuwum", ALTIVEC_BUILTIN_VEC_VPKUWUM },
9036 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuhum", ALTIVEC_BUILTIN_VEC_VPKUHUM },
9037 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packpx", ALTIVEC_BUILTIN_VEC_PACKPX },
9038 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packs", ALTIVEC_BUILTIN_VEC_PACKS },
9039 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkswss", ALTIVEC_BUILTIN_VEC_VPKSWSS },
9040 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuwus", ALTIVEC_BUILTIN_VEC_VPKUWUS },
9041 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkshss", ALTIVEC_BUILTIN_VEC_VPKSHSS },
9042 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuhus", ALTIVEC_BUILTIN_VEC_VPKUHUS },
9043 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packsu", ALTIVEC_BUILTIN_VEC_PACKSU },
9044 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkswus", ALTIVEC_BUILTIN_VEC_VPKSWUS },
9045 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkshus", ALTIVEC_BUILTIN_VEC_VPKSHUS },
9046 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rl", ALTIVEC_BUILTIN_VEC_RL },
9047 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlw", ALTIVEC_BUILTIN_VEC_VRLW },
9048 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlh", ALTIVEC_BUILTIN_VEC_VRLH },
9049 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlb", ALTIVEC_BUILTIN_VEC_VRLB },
9050 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sl", ALTIVEC_BUILTIN_VEC_SL },
9051 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslw", ALTIVEC_BUILTIN_VEC_VSLW },
9052 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslh", ALTIVEC_BUILTIN_VEC_VSLH },
9053 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslb", ALTIVEC_BUILTIN_VEC_VSLB },
9054 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sll", ALTIVEC_BUILTIN_VEC_SLL },
9055 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_slo", ALTIVEC_BUILTIN_VEC_SLO },
9056 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sr", ALTIVEC_BUILTIN_VEC_SR },
9057 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrw", ALTIVEC_BUILTIN_VEC_VSRW },
9058 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrh", ALTIVEC_BUILTIN_VEC_VSRH },
9059 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrb", ALTIVEC_BUILTIN_VEC_VSRB },
9060 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sra", ALTIVEC_BUILTIN_VEC_SRA },
9061 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsraw", ALTIVEC_BUILTIN_VEC_VSRAW },
9062 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrah", ALTIVEC_BUILTIN_VEC_VSRAH },
9063 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrab", ALTIVEC_BUILTIN_VEC_VSRAB },
9064 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_srl", ALTIVEC_BUILTIN_VEC_SRL },
9065 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sro", ALTIVEC_BUILTIN_VEC_SRO },
9066 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_sub", ALTIVEC_BUILTIN_VEC_SUB },
9067 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vsubfp", ALTIVEC_BUILTIN_VEC_VSUBFP },
9068 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuwm", ALTIVEC_BUILTIN_VEC_VSUBUWM },
9069 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuhm", ALTIVEC_BUILTIN_VEC_VSUBUHM },
9070 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsububm", ALTIVEC_BUILTIN_VEC_VSUBUBM },
9071 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_subc", ALTIVEC_BUILTIN_VEC_SUBC },
9072 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_subs", ALTIVEC_BUILTIN_VEC_SUBS },
9073 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubsws", ALTIVEC_BUILTIN_VEC_VSUBSWS },
9074 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuws", ALTIVEC_BUILTIN_VEC_VSUBUWS },
9075 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubshs", ALTIVEC_BUILTIN_VEC_VSUBSHS },
9076 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuhs", ALTIVEC_BUILTIN_VEC_VSUBUHS },
9077 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubsbs", ALTIVEC_BUILTIN_VEC_VSUBSBS },
9078 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsububs", ALTIVEC_BUILTIN_VEC_VSUBUBS },
9079 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sum4s", ALTIVEC_BUILTIN_VEC_SUM4S },
9080 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4shs", ALTIVEC_BUILTIN_VEC_VSUM4SHS },
9081 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4sbs", ALTIVEC_BUILTIN_VEC_VSUM4SBS },
9082 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4ubs", ALTIVEC_BUILTIN_VEC_VSUM4UBS },
9083 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sum2s", ALTIVEC_BUILTIN_VEC_SUM2S },
9084 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sums", ALTIVEC_BUILTIN_VEC_SUMS },
9085 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_xor", ALTIVEC_BUILTIN_VEC_XOR },
9087 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_mul", VSX_BUILTIN_VEC_MUL },
9088 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_div", VSX_BUILTIN_VEC_DIV },
9090 { 0, CODE_FOR_paired_divv2sf3, "__builtin_paired_divv2sf3", PAIRED_BUILTIN_DIVV2SF3 },
9091 { 0, CODE_FOR_paired_addv2sf3, "__builtin_paired_addv2sf3", PAIRED_BUILTIN_ADDV2SF3 },
9092 { 0, CODE_FOR_paired_subv2sf3, "__builtin_paired_subv2sf3", PAIRED_BUILTIN_SUBV2SF3 },
9093 { 0, CODE_FOR_paired_mulv2sf3, "__builtin_paired_mulv2sf3", PAIRED_BUILTIN_MULV2SF3 },
9094 { 0, CODE_FOR_paired_muls0, "__builtin_paired_muls0", PAIRED_BUILTIN_MULS0 },
9095 { 0, CODE_FOR_paired_muls1, "__builtin_paired_muls1", PAIRED_BUILTIN_MULS1 },
9096 { 0, CODE_FOR_paired_merge00, "__builtin_paired_merge00", PAIRED_BUILTIN_MERGE00 },
9097 { 0, CODE_FOR_paired_merge01, "__builtin_paired_merge01", PAIRED_BUILTIN_MERGE01 },
9098 { 0, CODE_FOR_paired_merge10, "__builtin_paired_merge10", PAIRED_BUILTIN_MERGE10 },
9099 { 0, CODE_FOR_paired_merge11, "__builtin_paired_merge11", PAIRED_BUILTIN_MERGE11 },
9101 /* Place holder, leave as first spe builtin. */
9102 { 0, CODE_FOR_addv2si3, "__builtin_spe_evaddw", SPE_BUILTIN_EVADDW },
9103 { 0, CODE_FOR_andv2si3, "__builtin_spe_evand", SPE_BUILTIN_EVAND },
9104 { 0, CODE_FOR_spe_evandc, "__builtin_spe_evandc", SPE_BUILTIN_EVANDC },
9105 { 0, CODE_FOR_divv2si3, "__builtin_spe_evdivws", SPE_BUILTIN_EVDIVWS },
9106 { 0, CODE_FOR_spe_evdivwu, "__builtin_spe_evdivwu", SPE_BUILTIN_EVDIVWU },
9107 { 0, CODE_FOR_spe_eveqv, "__builtin_spe_eveqv", SPE_BUILTIN_EVEQV },
9108 { 0, CODE_FOR_spe_evfsadd, "__builtin_spe_evfsadd", SPE_BUILTIN_EVFSADD },
9109 { 0, CODE_FOR_spe_evfsdiv, "__builtin_spe_evfsdiv", SPE_BUILTIN_EVFSDIV },
9110 { 0, CODE_FOR_spe_evfsmul, "__builtin_spe_evfsmul", SPE_BUILTIN_EVFSMUL },
9111 { 0, CODE_FOR_spe_evfssub, "__builtin_spe_evfssub", SPE_BUILTIN_EVFSSUB },
9112 { 0, CODE_FOR_spe_evmergehi, "__builtin_spe_evmergehi", SPE_BUILTIN_EVMERGEHI },
9113 { 0, CODE_FOR_spe_evmergehilo, "__builtin_spe_evmergehilo", SPE_BUILTIN_EVMERGEHILO },
9114 { 0, CODE_FOR_spe_evmergelo, "__builtin_spe_evmergelo", SPE_BUILTIN_EVMERGELO },
9115 { 0, CODE_FOR_spe_evmergelohi, "__builtin_spe_evmergelohi", SPE_BUILTIN_EVMERGELOHI },
9116 { 0, CODE_FOR_spe_evmhegsmfaa, "__builtin_spe_evmhegsmfaa", SPE_BUILTIN_EVMHEGSMFAA },
9117 { 0, CODE_FOR_spe_evmhegsmfan, "__builtin_spe_evmhegsmfan", SPE_BUILTIN_EVMHEGSMFAN },
9118 { 0, CODE_FOR_spe_evmhegsmiaa, "__builtin_spe_evmhegsmiaa", SPE_BUILTIN_EVMHEGSMIAA },
9119 { 0, CODE_FOR_spe_evmhegsmian, "__builtin_spe_evmhegsmian", SPE_BUILTIN_EVMHEGSMIAN },
9120 { 0, CODE_FOR_spe_evmhegumiaa, "__builtin_spe_evmhegumiaa", SPE_BUILTIN_EVMHEGUMIAA },
9121 { 0, CODE_FOR_spe_evmhegumian, "__builtin_spe_evmhegumian", SPE_BUILTIN_EVMHEGUMIAN },
9122 { 0, CODE_FOR_spe_evmhesmf, "__builtin_spe_evmhesmf", SPE_BUILTIN_EVMHESMF },
9123 { 0, CODE_FOR_spe_evmhesmfa, "__builtin_spe_evmhesmfa", SPE_BUILTIN_EVMHESMFA },
9124 { 0, CODE_FOR_spe_evmhesmfaaw, "__builtin_spe_evmhesmfaaw", SPE_BUILTIN_EVMHESMFAAW },
9125 { 0, CODE_FOR_spe_evmhesmfanw, "__builtin_spe_evmhesmfanw", SPE_BUILTIN_EVMHESMFANW },
9126 { 0, CODE_FOR_spe_evmhesmi, "__builtin_spe_evmhesmi", SPE_BUILTIN_EVMHESMI },
9127 { 0, CODE_FOR_spe_evmhesmia, "__builtin_spe_evmhesmia", SPE_BUILTIN_EVMHESMIA },
9128 { 0, CODE_FOR_spe_evmhesmiaaw, "__builtin_spe_evmhesmiaaw", SPE_BUILTIN_EVMHESMIAAW },
9129 { 0, CODE_FOR_spe_evmhesmianw, "__builtin_spe_evmhesmianw", SPE_BUILTIN_EVMHESMIANW },
9130 { 0, CODE_FOR_spe_evmhessf, "__builtin_spe_evmhessf", SPE_BUILTIN_EVMHESSF },
9131 { 0, CODE_FOR_spe_evmhessfa, "__builtin_spe_evmhessfa", SPE_BUILTIN_EVMHESSFA },
9132 { 0, CODE_FOR_spe_evmhessfaaw, "__builtin_spe_evmhessfaaw", SPE_BUILTIN_EVMHESSFAAW },
9133 { 0, CODE_FOR_spe_evmhessfanw, "__builtin_spe_evmhessfanw", SPE_BUILTIN_EVMHESSFANW },
9134 { 0, CODE_FOR_spe_evmhessiaaw, "__builtin_spe_evmhessiaaw", SPE_BUILTIN_EVMHESSIAAW },
9135 { 0, CODE_FOR_spe_evmhessianw, "__builtin_spe_evmhessianw", SPE_BUILTIN_EVMHESSIANW },
9136 { 0, CODE_FOR_spe_evmheumi, "__builtin_spe_evmheumi", SPE_BUILTIN_EVMHEUMI },
9137 { 0, CODE_FOR_spe_evmheumia, "__builtin_spe_evmheumia", SPE_BUILTIN_EVMHEUMIA },
9138 { 0, CODE_FOR_spe_evmheumiaaw, "__builtin_spe_evmheumiaaw", SPE_BUILTIN_EVMHEUMIAAW },
9139 { 0, CODE_FOR_spe_evmheumianw, "__builtin_spe_evmheumianw", SPE_BUILTIN_EVMHEUMIANW },
9140 { 0, CODE_FOR_spe_evmheusiaaw, "__builtin_spe_evmheusiaaw", SPE_BUILTIN_EVMHEUSIAAW },
9141 { 0, CODE_FOR_spe_evmheusianw, "__builtin_spe_evmheusianw", SPE_BUILTIN_EVMHEUSIANW },
9142 { 0, CODE_FOR_spe_evmhogsmfaa, "__builtin_spe_evmhogsmfaa", SPE_BUILTIN_EVMHOGSMFAA },
9143 { 0, CODE_FOR_spe_evmhogsmfan, "__builtin_spe_evmhogsmfan", SPE_BUILTIN_EVMHOGSMFAN },
9144 { 0, CODE_FOR_spe_evmhogsmiaa, "__builtin_spe_evmhogsmiaa", SPE_BUILTIN_EVMHOGSMIAA },
9145 { 0, CODE_FOR_spe_evmhogsmian, "__builtin_spe_evmhogsmian", SPE_BUILTIN_EVMHOGSMIAN },
9146 { 0, CODE_FOR_spe_evmhogumiaa, "__builtin_spe_evmhogumiaa", SPE_BUILTIN_EVMHOGUMIAA },
9147 { 0, CODE_FOR_spe_evmhogumian, "__builtin_spe_evmhogumian", SPE_BUILTIN_EVMHOGUMIAN },
9148 { 0, CODE_FOR_spe_evmhosmf, "__builtin_spe_evmhosmf", SPE_BUILTIN_EVMHOSMF },
9149 { 0, CODE_FOR_spe_evmhosmfa, "__builtin_spe_evmhosmfa", SPE_BUILTIN_EVMHOSMFA },
9150 { 0, CODE_FOR_spe_evmhosmfaaw, "__builtin_spe_evmhosmfaaw", SPE_BUILTIN_EVMHOSMFAAW },
9151 { 0, CODE_FOR_spe_evmhosmfanw, "__builtin_spe_evmhosmfanw", SPE_BUILTIN_EVMHOSMFANW },
9152 { 0, CODE_FOR_spe_evmhosmi, "__builtin_spe_evmhosmi", SPE_BUILTIN_EVMHOSMI },
9153 { 0, CODE_FOR_spe_evmhosmia, "__builtin_spe_evmhosmia", SPE_BUILTIN_EVMHOSMIA },
9154 { 0, CODE_FOR_spe_evmhosmiaaw, "__builtin_spe_evmhosmiaaw", SPE_BUILTIN_EVMHOSMIAAW },
9155 { 0, CODE_FOR_spe_evmhosmianw, "__builtin_spe_evmhosmianw", SPE_BUILTIN_EVMHOSMIANW },
9156 { 0, CODE_FOR_spe_evmhossf, "__builtin_spe_evmhossf", SPE_BUILTIN_EVMHOSSF },
9157 { 0, CODE_FOR_spe_evmhossfa, "__builtin_spe_evmhossfa", SPE_BUILTIN_EVMHOSSFA },
9158 { 0, CODE_FOR_spe_evmhossfaaw, "__builtin_spe_evmhossfaaw", SPE_BUILTIN_EVMHOSSFAAW },
9159 { 0, CODE_FOR_spe_evmhossfanw, "__builtin_spe_evmhossfanw", SPE_BUILTIN_EVMHOSSFANW },
9160 { 0, CODE_FOR_spe_evmhossiaaw, "__builtin_spe_evmhossiaaw", SPE_BUILTIN_EVMHOSSIAAW },
9161 { 0, CODE_FOR_spe_evmhossianw, "__builtin_spe_evmhossianw", SPE_BUILTIN_EVMHOSSIANW },
9162 { 0, CODE_FOR_spe_evmhoumi, "__builtin_spe_evmhoumi", SPE_BUILTIN_EVMHOUMI },
9163 { 0, CODE_FOR_spe_evmhoumia, "__builtin_spe_evmhoumia", SPE_BUILTIN_EVMHOUMIA },
9164 { 0, CODE_FOR_spe_evmhoumiaaw, "__builtin_spe_evmhoumiaaw", SPE_BUILTIN_EVMHOUMIAAW },
9165 { 0, CODE_FOR_spe_evmhoumianw, "__builtin_spe_evmhoumianw", SPE_BUILTIN_EVMHOUMIANW },
9166 { 0, CODE_FOR_spe_evmhousiaaw, "__builtin_spe_evmhousiaaw", SPE_BUILTIN_EVMHOUSIAAW },
9167 { 0, CODE_FOR_spe_evmhousianw, "__builtin_spe_evmhousianw", SPE_BUILTIN_EVMHOUSIANW },
9168 { 0, CODE_FOR_spe_evmwhsmf, "__builtin_spe_evmwhsmf", SPE_BUILTIN_EVMWHSMF },
9169 { 0, CODE_FOR_spe_evmwhsmfa, "__builtin_spe_evmwhsmfa", SPE_BUILTIN_EVMWHSMFA },
9170 { 0, CODE_FOR_spe_evmwhsmi, "__builtin_spe_evmwhsmi", SPE_BUILTIN_EVMWHSMI },
9171 { 0, CODE_FOR_spe_evmwhsmia, "__builtin_spe_evmwhsmia", SPE_BUILTIN_EVMWHSMIA },
9172 { 0, CODE_FOR_spe_evmwhssf, "__builtin_spe_evmwhssf", SPE_BUILTIN_EVMWHSSF },
9173 { 0, CODE_FOR_spe_evmwhssfa, "__builtin_spe_evmwhssfa", SPE_BUILTIN_EVMWHSSFA },
9174 { 0, CODE_FOR_spe_evmwhumi, "__builtin_spe_evmwhumi", SPE_BUILTIN_EVMWHUMI },
9175 { 0, CODE_FOR_spe_evmwhumia, "__builtin_spe_evmwhumia", SPE_BUILTIN_EVMWHUMIA },
9176 { 0, CODE_FOR_spe_evmwlsmiaaw, "__builtin_spe_evmwlsmiaaw", SPE_BUILTIN_EVMWLSMIAAW },
9177 { 0, CODE_FOR_spe_evmwlsmianw, "__builtin_spe_evmwlsmianw", SPE_BUILTIN_EVMWLSMIANW },
9178 { 0, CODE_FOR_spe_evmwlssiaaw, "__builtin_spe_evmwlssiaaw", SPE_BUILTIN_EVMWLSSIAAW },
9179 { 0, CODE_FOR_spe_evmwlssianw, "__builtin_spe_evmwlssianw", SPE_BUILTIN_EVMWLSSIANW },
9180 { 0, CODE_FOR_spe_evmwlumi, "__builtin_spe_evmwlumi", SPE_BUILTIN_EVMWLUMI },
9181 { 0, CODE_FOR_spe_evmwlumia, "__builtin_spe_evmwlumia", SPE_BUILTIN_EVMWLUMIA },
9182 { 0, CODE_FOR_spe_evmwlumiaaw, "__builtin_spe_evmwlumiaaw", SPE_BUILTIN_EVMWLUMIAAW },
9183 { 0, CODE_FOR_spe_evmwlumianw, "__builtin_spe_evmwlumianw", SPE_BUILTIN_EVMWLUMIANW },
9184 { 0, CODE_FOR_spe_evmwlusiaaw, "__builtin_spe_evmwlusiaaw", SPE_BUILTIN_EVMWLUSIAAW },
9185 { 0, CODE_FOR_spe_evmwlusianw, "__builtin_spe_evmwlusianw", SPE_BUILTIN_EVMWLUSIANW },
9186 { 0, CODE_FOR_spe_evmwsmf, "__builtin_spe_evmwsmf", SPE_BUILTIN_EVMWSMF },
9187 { 0, CODE_FOR_spe_evmwsmfa, "__builtin_spe_evmwsmfa", SPE_BUILTIN_EVMWSMFA },
9188 { 0, CODE_FOR_spe_evmwsmfaa, "__builtin_spe_evmwsmfaa", SPE_BUILTIN_EVMWSMFAA },
9189 { 0, CODE_FOR_spe_evmwsmfan, "__builtin_spe_evmwsmfan", SPE_BUILTIN_EVMWSMFAN },
9190 { 0, CODE_FOR_spe_evmwsmi, "__builtin_spe_evmwsmi", SPE_BUILTIN_EVMWSMI },
9191 { 0, CODE_FOR_spe_evmwsmia, "__builtin_spe_evmwsmia", SPE_BUILTIN_EVMWSMIA },
9192 { 0, CODE_FOR_spe_evmwsmiaa, "__builtin_spe_evmwsmiaa", SPE_BUILTIN_EVMWSMIAA },
9193 { 0, CODE_FOR_spe_evmwsmian, "__builtin_spe_evmwsmian", SPE_BUILTIN_EVMWSMIAN },
9194 { 0, CODE_FOR_spe_evmwssf, "__builtin_spe_evmwssf", SPE_BUILTIN_EVMWSSF },
9195 { 0, CODE_FOR_spe_evmwssfa, "__builtin_spe_evmwssfa", SPE_BUILTIN_EVMWSSFA },
9196 { 0, CODE_FOR_spe_evmwssfaa, "__builtin_spe_evmwssfaa", SPE_BUILTIN_EVMWSSFAA },
9197 { 0, CODE_FOR_spe_evmwssfan, "__builtin_spe_evmwssfan", SPE_BUILTIN_EVMWSSFAN },
9198 { 0, CODE_FOR_spe_evmwumi, "__builtin_spe_evmwumi", SPE_BUILTIN_EVMWUMI },
9199 { 0, CODE_FOR_spe_evmwumia, "__builtin_spe_evmwumia", SPE_BUILTIN_EVMWUMIA },
9200 { 0, CODE_FOR_spe_evmwumiaa, "__builtin_spe_evmwumiaa", SPE_BUILTIN_EVMWUMIAA },
9201 { 0, CODE_FOR_spe_evmwumian, "__builtin_spe_evmwumian", SPE_BUILTIN_EVMWUMIAN },
9202 { 0, CODE_FOR_spe_evnand, "__builtin_spe_evnand", SPE_BUILTIN_EVNAND },
9203 { 0, CODE_FOR_spe_evnor, "__builtin_spe_evnor", SPE_BUILTIN_EVNOR },
9204 { 0, CODE_FOR_spe_evor, "__builtin_spe_evor", SPE_BUILTIN_EVOR },
9205 { 0, CODE_FOR_spe_evorc, "__builtin_spe_evorc", SPE_BUILTIN_EVORC },
9206 { 0, CODE_FOR_spe_evrlw, "__builtin_spe_evrlw", SPE_BUILTIN_EVRLW },
9207 { 0, CODE_FOR_spe_evslw, "__builtin_spe_evslw", SPE_BUILTIN_EVSLW },
9208 { 0, CODE_FOR_spe_evsrws, "__builtin_spe_evsrws", SPE_BUILTIN_EVSRWS },
9209 { 0, CODE_FOR_spe_evsrwu, "__builtin_spe_evsrwu", SPE_BUILTIN_EVSRWU },
9210 { 0, CODE_FOR_subv2si3, "__builtin_spe_evsubfw", SPE_BUILTIN_EVSUBFW },
9212 /* SPE binary operations expecting a 5-bit unsigned literal. */
9213 { 0, CODE_FOR_spe_evaddiw, "__builtin_spe_evaddiw", SPE_BUILTIN_EVADDIW },
9215 { 0, CODE_FOR_spe_evrlwi, "__builtin_spe_evrlwi", SPE_BUILTIN_EVRLWI },
9216 { 0, CODE_FOR_spe_evslwi, "__builtin_spe_evslwi", SPE_BUILTIN_EVSLWI },
9217 { 0, CODE_FOR_spe_evsrwis, "__builtin_spe_evsrwis", SPE_BUILTIN_EVSRWIS },
9218 { 0, CODE_FOR_spe_evsrwiu, "__builtin_spe_evsrwiu", SPE_BUILTIN_EVSRWIU },
9219 { 0, CODE_FOR_spe_evsubifw, "__builtin_spe_evsubifw", SPE_BUILTIN_EVSUBIFW },
9220 { 0, CODE_FOR_spe_evmwhssfaa, "__builtin_spe_evmwhssfaa", SPE_BUILTIN_EVMWHSSFAA },
9221 { 0, CODE_FOR_spe_evmwhssmaa, "__builtin_spe_evmwhssmaa", SPE_BUILTIN_EVMWHSSMAA },
9222 { 0, CODE_FOR_spe_evmwhsmfaa, "__builtin_spe_evmwhsmfaa", SPE_BUILTIN_EVMWHSMFAA },
9223 { 0, CODE_FOR_spe_evmwhsmiaa, "__builtin_spe_evmwhsmiaa", SPE_BUILTIN_EVMWHSMIAA },
9224 { 0, CODE_FOR_spe_evmwhusiaa, "__builtin_spe_evmwhusiaa", SPE_BUILTIN_EVMWHUSIAA },
9225 { 0, CODE_FOR_spe_evmwhumiaa, "__builtin_spe_evmwhumiaa", SPE_BUILTIN_EVMWHUMIAA },
9226 { 0, CODE_FOR_spe_evmwhssfan, "__builtin_spe_evmwhssfan", SPE_BUILTIN_EVMWHSSFAN },
9227 { 0, CODE_FOR_spe_evmwhssian, "__builtin_spe_evmwhssian", SPE_BUILTIN_EVMWHSSIAN },
9228 { 0, CODE_FOR_spe_evmwhsmfan, "__builtin_spe_evmwhsmfan", SPE_BUILTIN_EVMWHSMFAN },
9229 { 0, CODE_FOR_spe_evmwhsmian, "__builtin_spe_evmwhsmian", SPE_BUILTIN_EVMWHSMIAN },
9230 { 0, CODE_FOR_spe_evmwhusian, "__builtin_spe_evmwhusian", SPE_BUILTIN_EVMWHUSIAN },
9231 { 0, CODE_FOR_spe_evmwhumian, "__builtin_spe_evmwhumian", SPE_BUILTIN_EVMWHUMIAN },
9232 { 0, CODE_FOR_spe_evmwhgssfaa, "__builtin_spe_evmwhgssfaa", SPE_BUILTIN_EVMWHGSSFAA },
9233 { 0, CODE_FOR_spe_evmwhgsmfaa, "__builtin_spe_evmwhgsmfaa", SPE_BUILTIN_EVMWHGSMFAA },
9234 { 0, CODE_FOR_spe_evmwhgsmiaa, "__builtin_spe_evmwhgsmiaa", SPE_BUILTIN_EVMWHGSMIAA },
9235 { 0, CODE_FOR_spe_evmwhgumiaa, "__builtin_spe_evmwhgumiaa", SPE_BUILTIN_EVMWHGUMIAA },
9236 { 0, CODE_FOR_spe_evmwhgssfan, "__builtin_spe_evmwhgssfan", SPE_BUILTIN_EVMWHGSSFAN },
9237 { 0, CODE_FOR_spe_evmwhgsmfan, "__builtin_spe_evmwhgsmfan", SPE_BUILTIN_EVMWHGSMFAN },
9238 { 0, CODE_FOR_spe_evmwhgsmian, "__builtin_spe_evmwhgsmian", SPE_BUILTIN_EVMWHGSMIAN },
9239 { 0, CODE_FOR_spe_evmwhgumian, "__builtin_spe_evmwhgumian", SPE_BUILTIN_EVMWHGUMIAN },
9240 { 0, CODE_FOR_spe_brinc, "__builtin_spe_brinc", SPE_BUILTIN_BRINC },
9242 /* Place-holder. Leave as last binary SPE builtin. */
9243 { 0, CODE_FOR_xorv2si3, "__builtin_spe_evxor", SPE_BUILTIN_EVXOR }
9246 /* AltiVec predicates. */
9248 struct builtin_description_predicates
9250 const unsigned int mask;
9251 const enum insn_code icode;
9252 const char *const name;
9253 const enum rs6000_builtins code;
9256 static const struct builtin_description_predicates bdesc_altivec_preds[] =
9258 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpbfp_p, "__builtin_altivec_vcmpbfp_p",
9259 ALTIVEC_BUILTIN_VCMPBFP_P },
9260 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_eq_v4sf_p,
9261 "__builtin_altivec_vcmpeqfp_p", ALTIVEC_BUILTIN_VCMPEQFP_P },
9262 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_ge_v4sf_p,
9263 "__builtin_altivec_vcmpgefp_p", ALTIVEC_BUILTIN_VCMPGEFP_P },
9264 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_gt_v4sf_p,
9265 "__builtin_altivec_vcmpgtfp_p", ALTIVEC_BUILTIN_VCMPGTFP_P },
9266 { MASK_ALTIVEC, CODE_FOR_vector_eq_v4si_p, "__builtin_altivec_vcmpequw_p",
9267 ALTIVEC_BUILTIN_VCMPEQUW_P },
9268 { MASK_ALTIVEC, CODE_FOR_vector_gt_v4si_p, "__builtin_altivec_vcmpgtsw_p",
9269 ALTIVEC_BUILTIN_VCMPGTSW_P },
9270 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v4si_p, "__builtin_altivec_vcmpgtuw_p",
9271 ALTIVEC_BUILTIN_VCMPGTUW_P },
9272 { MASK_ALTIVEC, CODE_FOR_vector_eq_v8hi_p, "__builtin_altivec_vcmpequh_p",
9273 ALTIVEC_BUILTIN_VCMPEQUH_P },
9274 { MASK_ALTIVEC, CODE_FOR_vector_gt_v8hi_p, "__builtin_altivec_vcmpgtsh_p",
9275 ALTIVEC_BUILTIN_VCMPGTSH_P },
9276 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v8hi_p, "__builtin_altivec_vcmpgtuh_p",
9277 ALTIVEC_BUILTIN_VCMPGTUH_P },
9278 { MASK_ALTIVEC, CODE_FOR_vector_eq_v16qi_p, "__builtin_altivec_vcmpequb_p",
9279 ALTIVEC_BUILTIN_VCMPEQUB_P },
9280 { MASK_ALTIVEC, CODE_FOR_vector_gt_v16qi_p, "__builtin_altivec_vcmpgtsb_p",
9281 ALTIVEC_BUILTIN_VCMPGTSB_P },
9282 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v16qi_p, "__builtin_altivec_vcmpgtub_p",
9283 ALTIVEC_BUILTIN_VCMPGTUB_P },
9285 { MASK_VSX, CODE_FOR_vector_eq_v4sf_p, "__builtin_vsx_xvcmpeqsp_p",
9286 VSX_BUILTIN_XVCMPEQSP_P },
9287 { MASK_VSX, CODE_FOR_vector_ge_v4sf_p, "__builtin_vsx_xvcmpgesp_p",
9288 VSX_BUILTIN_XVCMPGESP_P },
9289 { MASK_VSX, CODE_FOR_vector_gt_v4sf_p, "__builtin_vsx_xvcmpgtsp_p",
9290 VSX_BUILTIN_XVCMPGTSP_P },
9291 { MASK_VSX, CODE_FOR_vector_eq_v2df_p, "__builtin_vsx_xvcmpeqdp_p",
9292 VSX_BUILTIN_XVCMPEQDP_P },
9293 { MASK_VSX, CODE_FOR_vector_ge_v2df_p, "__builtin_vsx_xvcmpgedp_p",
9294 VSX_BUILTIN_XVCMPGEDP_P },
9295 { MASK_VSX, CODE_FOR_vector_gt_v2df_p, "__builtin_vsx_xvcmpgtdp_p",
9296 VSX_BUILTIN_XVCMPGTDP_P },
9298 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpeq_p",
9299 ALTIVEC_BUILTIN_VCMPEQ_P },
9300 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpgt_p",
9301 ALTIVEC_BUILTIN_VCMPGT_P },
9302 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpge_p",
9303 ALTIVEC_BUILTIN_VCMPGE_P }
9306 /* SPE predicates. */
9307 static struct builtin_description bdesc_spe_predicates[] =
9309 /* Place-holder. Leave as first. */
9310 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evcmpeq", SPE_BUILTIN_EVCMPEQ },
9311 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evcmpgts", SPE_BUILTIN_EVCMPGTS },
9312 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evcmpgtu", SPE_BUILTIN_EVCMPGTU },
9313 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evcmplts", SPE_BUILTIN_EVCMPLTS },
9314 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evcmpltu", SPE_BUILTIN_EVCMPLTU },
9315 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evfscmpeq", SPE_BUILTIN_EVFSCMPEQ },
9316 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evfscmpgt", SPE_BUILTIN_EVFSCMPGT },
9317 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evfscmplt", SPE_BUILTIN_EVFSCMPLT },
9318 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evfststeq", SPE_BUILTIN_EVFSTSTEQ },
9319 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evfststgt", SPE_BUILTIN_EVFSTSTGT },
9320 /* Place-holder. Leave as last. */
9321 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evfststlt", SPE_BUILTIN_EVFSTSTLT },
9324 /* SPE evsel predicates. */
9325 static struct builtin_description bdesc_spe_evsel[] =
9327 /* Place-holder. Leave as first. */
9328 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evsel_gts", SPE_BUILTIN_EVSEL_CMPGTS },
9329 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evsel_gtu", SPE_BUILTIN_EVSEL_CMPGTU },
9330 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evsel_lts", SPE_BUILTIN_EVSEL_CMPLTS },
9331 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evsel_ltu", SPE_BUILTIN_EVSEL_CMPLTU },
9332 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evsel_eq", SPE_BUILTIN_EVSEL_CMPEQ },
9333 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evsel_fsgt", SPE_BUILTIN_EVSEL_FSCMPGT },
9334 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evsel_fslt", SPE_BUILTIN_EVSEL_FSCMPLT },
9335 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evsel_fseq", SPE_BUILTIN_EVSEL_FSCMPEQ },
9336 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evsel_fststgt", SPE_BUILTIN_EVSEL_FSTSTGT },
9337 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evsel_fststlt", SPE_BUILTIN_EVSEL_FSTSTLT },
9338 /* Place-holder. Leave as last. */
9339 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evsel_fststeq", SPE_BUILTIN_EVSEL_FSTSTEQ },
9342 /* PAIRED predicates. */
9343 static const struct builtin_description bdesc_paired_preds[] =
9345 /* Place-holder. Leave as first. */
9346 { 0, CODE_FOR_paired_cmpu0, "__builtin_paired_cmpu0", PAIRED_BUILTIN_CMPU0 },
9347 /* Place-holder. Leave as last. */
9348 { 0, CODE_FOR_paired_cmpu1, "__builtin_paired_cmpu1", PAIRED_BUILTIN_CMPU1 },
9351 /* ABS* operations. */
9353 static const struct builtin_description bdesc_abs[] =
9355 { MASK_ALTIVEC, CODE_FOR_absv4si2, "__builtin_altivec_abs_v4si", ALTIVEC_BUILTIN_ABS_V4SI },
9356 { MASK_ALTIVEC, CODE_FOR_absv8hi2, "__builtin_altivec_abs_v8hi", ALTIVEC_BUILTIN_ABS_V8HI },
9357 { MASK_ALTIVEC, CODE_FOR_absv4sf2, "__builtin_altivec_abs_v4sf", ALTIVEC_BUILTIN_ABS_V4SF },
9358 { MASK_ALTIVEC, CODE_FOR_absv16qi2, "__builtin_altivec_abs_v16qi", ALTIVEC_BUILTIN_ABS_V16QI },
9359 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v4si, "__builtin_altivec_abss_v4si", ALTIVEC_BUILTIN_ABSS_V4SI },
9360 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v8hi, "__builtin_altivec_abss_v8hi", ALTIVEC_BUILTIN_ABSS_V8HI },
9361 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v16qi, "__builtin_altivec_abss_v16qi", ALTIVEC_BUILTIN_ABSS_V16QI },
9362 { MASK_VSX, CODE_FOR_absv2df2, "__builtin_vsx_xvabsdp", VSX_BUILTIN_XVABSDP },
9363 { MASK_VSX, CODE_FOR_vsx_nabsv2df2, "__builtin_vsx_xvnabsdp", VSX_BUILTIN_XVNABSDP },
9364 { MASK_VSX, CODE_FOR_absv4sf2, "__builtin_vsx_xvabssp", VSX_BUILTIN_XVABSSP },
9365 { MASK_VSX, CODE_FOR_vsx_nabsv4sf2, "__builtin_vsx_xvnabssp", VSX_BUILTIN_XVNABSSP },
9368 /* Simple unary operations: VECb = foo (unsigned literal) or VECb =
9369 foo (VECa). */
9371 static struct builtin_description bdesc_1arg[] =
9373 { MASK_ALTIVEC, CODE_FOR_altivec_vexptefp, "__builtin_altivec_vexptefp", ALTIVEC_BUILTIN_VEXPTEFP },
9374 { MASK_ALTIVEC, CODE_FOR_altivec_vlogefp, "__builtin_altivec_vlogefp", ALTIVEC_BUILTIN_VLOGEFP },
9375 { MASK_ALTIVEC, CODE_FOR_altivec_vrefp, "__builtin_altivec_vrefp", ALTIVEC_BUILTIN_VREFP },
9376 { MASK_ALTIVEC, CODE_FOR_vector_floorv4sf2, "__builtin_altivec_vrfim", ALTIVEC_BUILTIN_VRFIM },
9377 { MASK_ALTIVEC, CODE_FOR_altivec_vrfin, "__builtin_altivec_vrfin", ALTIVEC_BUILTIN_VRFIN },
9378 { MASK_ALTIVEC, CODE_FOR_vector_ceilv4sf2, "__builtin_altivec_vrfip", ALTIVEC_BUILTIN_VRFIP },
9379 { MASK_ALTIVEC, CODE_FOR_vector_btruncv4sf2, "__builtin_altivec_vrfiz", ALTIVEC_BUILTIN_VRFIZ },
9380 { MASK_ALTIVEC, CODE_FOR_altivec_vrsqrtefp, "__builtin_altivec_vrsqrtefp", ALTIVEC_BUILTIN_VRSQRTEFP },
9381 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisb, "__builtin_altivec_vspltisb", ALTIVEC_BUILTIN_VSPLTISB },
9382 { MASK_ALTIVEC, CODE_FOR_altivec_vspltish, "__builtin_altivec_vspltish", ALTIVEC_BUILTIN_VSPLTISH },
9383 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisw, "__builtin_altivec_vspltisw", ALTIVEC_BUILTIN_VSPLTISW },
9384 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsb, "__builtin_altivec_vupkhsb", ALTIVEC_BUILTIN_VUPKHSB },
9385 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhpx, "__builtin_altivec_vupkhpx", ALTIVEC_BUILTIN_VUPKHPX },
9386 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsh, "__builtin_altivec_vupkhsh", ALTIVEC_BUILTIN_VUPKHSH },
9387 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsb, "__builtin_altivec_vupklsb", ALTIVEC_BUILTIN_VUPKLSB },
9388 { MASK_ALTIVEC, CODE_FOR_altivec_vupklpx, "__builtin_altivec_vupklpx", ALTIVEC_BUILTIN_VUPKLPX },
9389 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsh, "__builtin_altivec_vupklsh", ALTIVEC_BUILTIN_VUPKLSH },
9391 { MASK_VSX, CODE_FOR_negv2df2, "__builtin_vsx_xvnegdp", VSX_BUILTIN_XVNEGDP },
9392 { MASK_VSX, CODE_FOR_sqrtv2df2, "__builtin_vsx_xvsqrtdp", VSX_BUILTIN_XVSQRTDP },
9393 { MASK_VSX, CODE_FOR_vsx_rsqrtev2df2, "__builtin_vsx_xvrsqrtedp", VSX_BUILTIN_XVRSQRTEDP },
9394 { MASK_VSX, CODE_FOR_vsx_tsqrtv2df2_fe, "__builtin_vsx_xvtsqrtdp_fe", VSX_BUILTIN_XVTSQRTDP_FE },
9395 { MASK_VSX, CODE_FOR_vsx_tsqrtv2df2_fg, "__builtin_vsx_xvtsqrtdp_fg", VSX_BUILTIN_XVTSQRTDP_FG },
9396 { MASK_VSX, CODE_FOR_vsx_frev2df2, "__builtin_vsx_xvredp", VSX_BUILTIN_XVREDP },
9398 { MASK_VSX, CODE_FOR_negv4sf2, "__builtin_vsx_xvnegsp", VSX_BUILTIN_XVNEGSP },
9399 { MASK_VSX, CODE_FOR_sqrtv4sf2, "__builtin_vsx_xvsqrtsp", VSX_BUILTIN_XVSQRTSP },
9400 { MASK_VSX, CODE_FOR_vsx_rsqrtev4sf2, "__builtin_vsx_xvrsqrtesp", VSX_BUILTIN_XVRSQRTESP },
9401 { MASK_VSX, CODE_FOR_vsx_tsqrtv4sf2_fe, "__builtin_vsx_xvtsqrtsp_fe", VSX_BUILTIN_XVTSQRTSP_FE },
9402 { MASK_VSX, CODE_FOR_vsx_tsqrtv4sf2_fg, "__builtin_vsx_xvtsqrtsp_fg", VSX_BUILTIN_XVTSQRTSP_FG },
9403 { MASK_VSX, CODE_FOR_vsx_frev4sf2, "__builtin_vsx_xvresp", VSX_BUILTIN_XVRESP },
9405 { MASK_VSX, CODE_FOR_vsx_xscvdpsp, "__builtin_vsx_xscvdpsp", VSX_BUILTIN_XSCVDPSP },
9406 { MASK_VSX, CODE_FOR_vsx_xscvdpsp, "__builtin_vsx_xscvspdp", VSX_BUILTIN_XSCVSPDP },
9407 { MASK_VSX, CODE_FOR_vsx_xvcvdpsp, "__builtin_vsx_xvcvdpsp", VSX_BUILTIN_XVCVDPSP },
9408 { MASK_VSX, CODE_FOR_vsx_xvcvspdp, "__builtin_vsx_xvcvspdp", VSX_BUILTIN_XVCVSPDP },
9409 { MASK_VSX, CODE_FOR_vsx_tsqrtdf2_fe, "__builtin_vsx_xstsqrtdp_fe", VSX_BUILTIN_XSTSQRTDP_FE },
9410 { MASK_VSX, CODE_FOR_vsx_tsqrtdf2_fg, "__builtin_vsx_xstsqrtdp_fg", VSX_BUILTIN_XSTSQRTDP_FG },
9412 { MASK_VSX, CODE_FOR_vsx_fix_truncv2dfv2di2, "__builtin_vsx_xvcvdpsxds", VSX_BUILTIN_XVCVDPSXDS },
9413 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv2dfv2di2, "__builtin_vsx_xvcvdpuxds", VSX_BUILTIN_XVCVDPUXDS },
9414 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv2dfv2di2, "__builtin_vsx_xvcvdpuxds_uns", VSX_BUILTIN_XVCVDPUXDS_UNS },
9415 { MASK_VSX, CODE_FOR_vsx_floatv2div2df2, "__builtin_vsx_xvcvsxddp", VSX_BUILTIN_XVCVSXDDP },
9416 { MASK_VSX, CODE_FOR_vsx_floatunsv2div2df2, "__builtin_vsx_xvcvuxddp", VSX_BUILTIN_XVCVUXDDP },
9417 { MASK_VSX, CODE_FOR_vsx_floatunsv2div2df2, "__builtin_vsx_xvcvuxddp_uns", VSX_BUILTIN_XVCVUXDDP_UNS },
9419 { MASK_VSX, CODE_FOR_vsx_fix_truncv4sfv4si2, "__builtin_vsx_xvcvspsxws", VSX_BUILTIN_XVCVSPSXWS },
9420 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv4sfv4si2, "__builtin_vsx_xvcvspuxws", VSX_BUILTIN_XVCVSPUXWS },
9421 { MASK_VSX, CODE_FOR_vsx_floatv4siv4sf2, "__builtin_vsx_xvcvsxwsp", VSX_BUILTIN_XVCVSXWSP },
9422 { MASK_VSX, CODE_FOR_vsx_floatunsv4siv4sf2, "__builtin_vsx_xvcvuxwsp", VSX_BUILTIN_XVCVUXWSP },
9424 { MASK_VSX, CODE_FOR_vsx_xvcvdpsxws, "__builtin_vsx_xvcvdpsxws", VSX_BUILTIN_XVCVDPSXWS },
9425 { MASK_VSX, CODE_FOR_vsx_xvcvdpuxws, "__builtin_vsx_xvcvdpuxws", VSX_BUILTIN_XVCVDPUXWS },
9426 { MASK_VSX, CODE_FOR_vsx_xvcvsxwdp, "__builtin_vsx_xvcvsxwdp", VSX_BUILTIN_XVCVSXWDP },
9427 { MASK_VSX, CODE_FOR_vsx_xvcvuxwdp, "__builtin_vsx_xvcvuxwdp", VSX_BUILTIN_XVCVUXWDP },
9428 { MASK_VSX, CODE_FOR_vsx_xvrdpi, "__builtin_vsx_xvrdpi", VSX_BUILTIN_XVRDPI },
9429 { MASK_VSX, CODE_FOR_vsx_xvrdpic, "__builtin_vsx_xvrdpic", VSX_BUILTIN_XVRDPIC },
9430 { MASK_VSX, CODE_FOR_vsx_floorv2df2, "__builtin_vsx_xvrdpim", VSX_BUILTIN_XVRDPIM },
9431 { MASK_VSX, CODE_FOR_vsx_ceilv2df2, "__builtin_vsx_xvrdpip", VSX_BUILTIN_XVRDPIP },
9432 { MASK_VSX, CODE_FOR_vsx_btruncv2df2, "__builtin_vsx_xvrdpiz", VSX_BUILTIN_XVRDPIZ },
9434 { MASK_VSX, CODE_FOR_vsx_xvcvspsxds, "__builtin_vsx_xvcvspsxds", VSX_BUILTIN_XVCVSPSXDS },
9435 { MASK_VSX, CODE_FOR_vsx_xvcvspuxds, "__builtin_vsx_xvcvspuxds", VSX_BUILTIN_XVCVSPUXDS },
9436 { MASK_VSX, CODE_FOR_vsx_xvcvsxdsp, "__builtin_vsx_xvcvsxdsp", VSX_BUILTIN_XVCVSXDSP },
9437 { MASK_VSX, CODE_FOR_vsx_xvcvuxdsp, "__builtin_vsx_xvcvuxdsp", VSX_BUILTIN_XVCVUXDSP },
9438 { MASK_VSX, CODE_FOR_vsx_xvrspi, "__builtin_vsx_xvrspi", VSX_BUILTIN_XVRSPI },
9439 { MASK_VSX, CODE_FOR_vsx_xvrspic, "__builtin_vsx_xvrspic", VSX_BUILTIN_XVRSPIC },
9440 { MASK_VSX, CODE_FOR_vsx_floorv4sf2, "__builtin_vsx_xvrspim", VSX_BUILTIN_XVRSPIM },
9441 { MASK_VSX, CODE_FOR_vsx_ceilv4sf2, "__builtin_vsx_xvrspip", VSX_BUILTIN_XVRSPIP },
9442 { MASK_VSX, CODE_FOR_vsx_btruncv4sf2, "__builtin_vsx_xvrspiz", VSX_BUILTIN_XVRSPIZ },
9444 { MASK_VSX, CODE_FOR_vsx_xsrdpi, "__builtin_vsx_xsrdpi", VSX_BUILTIN_XSRDPI },
9445 { MASK_VSX, CODE_FOR_vsx_xsrdpic, "__builtin_vsx_xsrdpic", VSX_BUILTIN_XSRDPIC },
9446 { MASK_VSX, CODE_FOR_vsx_floordf2, "__builtin_vsx_xsrdpim", VSX_BUILTIN_XSRDPIM },
9447 { MASK_VSX, CODE_FOR_vsx_ceildf2, "__builtin_vsx_xsrdpip", VSX_BUILTIN_XSRDPIP },
9448 { MASK_VSX, CODE_FOR_vsx_btruncdf2, "__builtin_vsx_xsrdpiz", VSX_BUILTIN_XSRDPIZ },
9450 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abs", ALTIVEC_BUILTIN_VEC_ABS },
9451 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abss", ALTIVEC_BUILTIN_VEC_ABSS },
9452 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_ceil", ALTIVEC_BUILTIN_VEC_CEIL },
9453 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_expte", ALTIVEC_BUILTIN_VEC_EXPTE },
9454 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_floor", ALTIVEC_BUILTIN_VEC_FLOOR },
9455 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_loge", ALTIVEC_BUILTIN_VEC_LOGE },
9456 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mtvscr", ALTIVEC_BUILTIN_VEC_MTVSCR },
9457 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_re", ALTIVEC_BUILTIN_VEC_RE },
9458 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_round", ALTIVEC_BUILTIN_VEC_ROUND },
9459 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rsqrte", ALTIVEC_BUILTIN_VEC_RSQRTE },
9460 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_trunc", ALTIVEC_BUILTIN_VEC_TRUNC },
9461 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_unpackh", ALTIVEC_BUILTIN_VEC_UNPACKH },
9462 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhsh", ALTIVEC_BUILTIN_VEC_VUPKHSH },
9463 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhpx", ALTIVEC_BUILTIN_VEC_VUPKHPX },
9464 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhsb", ALTIVEC_BUILTIN_VEC_VUPKHSB },
9465 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_unpackl", ALTIVEC_BUILTIN_VEC_UNPACKL },
9466 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklpx", ALTIVEC_BUILTIN_VEC_VUPKLPX },
9467 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsh", ALTIVEC_BUILTIN_VEC_VUPKLSH },
9468 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsb", ALTIVEC_BUILTIN_VEC_VUPKLSB },
9470 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_nearbyint", ALTIVEC_BUILTIN_VEC_NEARBYINT },
9471 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_rint", ALTIVEC_BUILTIN_VEC_RINT },
9472 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_sqrt", ALTIVEC_BUILTIN_VEC_SQRT },
9474 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_floatv4siv4sf2, "__builtin_vec_float_sisf", VECTOR_BUILTIN_FLOAT_V4SI_V4SF },
9475 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_unsigned_floatv4siv4sf2, "__builtin_vec_uns_float_sisf", VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF },
9476 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_fix_truncv4sfv4si2, "__builtin_vec_fix_sfsi", VECTOR_BUILTIN_FIX_V4SF_V4SI },
9477 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_fixuns_truncv4sfv4si2, "__builtin_vec_fixuns_sfsi", VECTOR_BUILTIN_FIXUNS_V4SF_V4SI },
9479 /* The SPE unary builtins must start with SPE_BUILTIN_EVABS and
9480 end with SPE_BUILTIN_EVSUBFUSIAAW. */
9481 { 0, CODE_FOR_absv2si2, "__builtin_spe_evabs", SPE_BUILTIN_EVABS },
9482 { 0, CODE_FOR_spe_evaddsmiaaw, "__builtin_spe_evaddsmiaaw", SPE_BUILTIN_EVADDSMIAAW },
9483 { 0, CODE_FOR_spe_evaddssiaaw, "__builtin_spe_evaddssiaaw", SPE_BUILTIN_EVADDSSIAAW },
9484 { 0, CODE_FOR_spe_evaddumiaaw, "__builtin_spe_evaddumiaaw", SPE_BUILTIN_EVADDUMIAAW },
9485 { 0, CODE_FOR_spe_evaddusiaaw, "__builtin_spe_evaddusiaaw", SPE_BUILTIN_EVADDUSIAAW },
9486 { 0, CODE_FOR_spe_evcntlsw, "__builtin_spe_evcntlsw", SPE_BUILTIN_EVCNTLSW },
9487 { 0, CODE_FOR_spe_evcntlzw, "__builtin_spe_evcntlzw", SPE_BUILTIN_EVCNTLZW },
9488 { 0, CODE_FOR_spe_evextsb, "__builtin_spe_evextsb", SPE_BUILTIN_EVEXTSB },
9489 { 0, CODE_FOR_spe_evextsh, "__builtin_spe_evextsh", SPE_BUILTIN_EVEXTSH },
9490 { 0, CODE_FOR_spe_evfsabs, "__builtin_spe_evfsabs", SPE_BUILTIN_EVFSABS },
9491 { 0, CODE_FOR_spe_evfscfsf, "__builtin_spe_evfscfsf", SPE_BUILTIN_EVFSCFSF },
9492 { 0, CODE_FOR_spe_evfscfsi, "__builtin_spe_evfscfsi", SPE_BUILTIN_EVFSCFSI },
9493 { 0, CODE_FOR_spe_evfscfuf, "__builtin_spe_evfscfuf", SPE_BUILTIN_EVFSCFUF },
9494 { 0, CODE_FOR_spe_evfscfui, "__builtin_spe_evfscfui", SPE_BUILTIN_EVFSCFUI },
9495 { 0, CODE_FOR_spe_evfsctsf, "__builtin_spe_evfsctsf", SPE_BUILTIN_EVFSCTSF },
9496 { 0, CODE_FOR_spe_evfsctsi, "__builtin_spe_evfsctsi", SPE_BUILTIN_EVFSCTSI },
9497 { 0, CODE_FOR_spe_evfsctsiz, "__builtin_spe_evfsctsiz", SPE_BUILTIN_EVFSCTSIZ },
9498 { 0, CODE_FOR_spe_evfsctuf, "__builtin_spe_evfsctuf", SPE_BUILTIN_EVFSCTUF },
9499 { 0, CODE_FOR_spe_evfsctui, "__builtin_spe_evfsctui", SPE_BUILTIN_EVFSCTUI },
9500 { 0, CODE_FOR_spe_evfsctuiz, "__builtin_spe_evfsctuiz", SPE_BUILTIN_EVFSCTUIZ },
9501 { 0, CODE_FOR_spe_evfsnabs, "__builtin_spe_evfsnabs", SPE_BUILTIN_EVFSNABS },
9502 { 0, CODE_FOR_spe_evfsneg, "__builtin_spe_evfsneg", SPE_BUILTIN_EVFSNEG },
9503 { 0, CODE_FOR_spe_evmra, "__builtin_spe_evmra", SPE_BUILTIN_EVMRA },
9504 { 0, CODE_FOR_negv2si2, "__builtin_spe_evneg", SPE_BUILTIN_EVNEG },
9505 { 0, CODE_FOR_spe_evrndw, "__builtin_spe_evrndw", SPE_BUILTIN_EVRNDW },
9506 { 0, CODE_FOR_spe_evsubfsmiaaw, "__builtin_spe_evsubfsmiaaw", SPE_BUILTIN_EVSUBFSMIAAW },
9507 { 0, CODE_FOR_spe_evsubfssiaaw, "__builtin_spe_evsubfssiaaw", SPE_BUILTIN_EVSUBFSSIAAW },
9508 { 0, CODE_FOR_spe_evsubfumiaaw, "__builtin_spe_evsubfumiaaw", SPE_BUILTIN_EVSUBFUMIAAW },
9510 /* Place-holder. Leave as last unary SPE builtin. */
9511 { 0, CODE_FOR_spe_evsubfusiaaw, "__builtin_spe_evsubfusiaaw", SPE_BUILTIN_EVSUBFUSIAAW },
9513 { 0, CODE_FOR_paired_absv2sf2, "__builtin_paired_absv2sf2", PAIRED_BUILTIN_ABSV2SF2 },
9514 { 0, CODE_FOR_nabsv2sf2, "__builtin_paired_nabsv2sf2", PAIRED_BUILTIN_NABSV2SF2 },
9515 { 0, CODE_FOR_paired_negv2sf2, "__builtin_paired_negv2sf2", PAIRED_BUILTIN_NEGV2SF2 },
9516 { 0, CODE_FOR_sqrtv2sf2, "__builtin_paired_sqrtv2sf2", PAIRED_BUILTIN_SQRTV2SF2 },
9517 { 0, CODE_FOR_resv2sf2, "__builtin_paired_resv2sf2", PAIRED_BUILTIN_RESV2SF2 }
9520 static rtx
9521 rs6000_expand_unop_builtin (enum insn_code icode, tree exp, rtx target)
9523 rtx pat;
9524 tree arg0 = CALL_EXPR_ARG (exp, 0);
9525 rtx op0 = expand_normal (arg0);
9526 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9527 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
9529 if (icode == CODE_FOR_nothing)
9530 /* Builtin not supported on this processor. */
9531 return 0;
9533 /* If we got invalid arguments bail out before generating bad rtl. */
9534 if (arg0 == error_mark_node)
9535 return const0_rtx;
9537 if (icode == CODE_FOR_altivec_vspltisb
9538 || icode == CODE_FOR_altivec_vspltish
9539 || icode == CODE_FOR_altivec_vspltisw
9540 || icode == CODE_FOR_spe_evsplatfi
9541 || icode == CODE_FOR_spe_evsplati)
9543 /* Only allow 5-bit *signed* literals. */
9544 if (GET_CODE (op0) != CONST_INT
9545 || INTVAL (op0) > 15
9546 || INTVAL (op0) < -16)
9548 error ("argument 1 must be a 5-bit signed literal");
9549 return const0_rtx;
9553 if (target == 0
9554 || GET_MODE (target) != tmode
9555 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
9556 target = gen_reg_rtx (tmode);
9558 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
9559 op0 = copy_to_mode_reg (mode0, op0);
9561 pat = GEN_FCN (icode) (target, op0);
9562 if (! pat)
9563 return 0;
9564 emit_insn (pat);
9566 return target;
9569 static rtx
9570 altivec_expand_abs_builtin (enum insn_code icode, tree exp, rtx target)
9572 rtx pat, scratch1, scratch2;
9573 tree arg0 = CALL_EXPR_ARG (exp, 0);
9574 rtx op0 = expand_normal (arg0);
9575 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9576 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
9578 /* If we have invalid arguments, bail out before generating bad rtl. */
9579 if (arg0 == error_mark_node)
9580 return const0_rtx;
9582 if (target == 0
9583 || GET_MODE (target) != tmode
9584 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
9585 target = gen_reg_rtx (tmode);
9587 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
9588 op0 = copy_to_mode_reg (mode0, op0);
9590 scratch1 = gen_reg_rtx (mode0);
9591 scratch2 = gen_reg_rtx (mode0);
9593 pat = GEN_FCN (icode) (target, op0, scratch1, scratch2);
9594 if (! pat)
9595 return 0;
9596 emit_insn (pat);
9598 return target;
9601 static rtx
9602 rs6000_expand_binop_builtin (enum insn_code icode, tree exp, rtx target)
9604 rtx pat;
9605 tree arg0 = CALL_EXPR_ARG (exp, 0);
9606 tree arg1 = CALL_EXPR_ARG (exp, 1);
9607 rtx op0 = expand_normal (arg0);
9608 rtx op1 = expand_normal (arg1);
9609 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9610 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
9611 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
9613 if (icode == CODE_FOR_nothing)
9614 /* Builtin not supported on this processor. */
9615 return 0;
9617 /* If we got invalid arguments bail out before generating bad rtl. */
9618 if (arg0 == error_mark_node || arg1 == error_mark_node)
9619 return const0_rtx;
9621 if (icode == CODE_FOR_altivec_vcfux
9622 || icode == CODE_FOR_altivec_vcfsx
9623 || icode == CODE_FOR_altivec_vctsxs
9624 || icode == CODE_FOR_altivec_vctuxs
9625 || icode == CODE_FOR_altivec_vspltb
9626 || icode == CODE_FOR_altivec_vsplth
9627 || icode == CODE_FOR_altivec_vspltw
9628 || icode == CODE_FOR_spe_evaddiw
9629 || icode == CODE_FOR_spe_evldd
9630 || icode == CODE_FOR_spe_evldh
9631 || icode == CODE_FOR_spe_evldw
9632 || icode == CODE_FOR_spe_evlhhesplat
9633 || icode == CODE_FOR_spe_evlhhossplat
9634 || icode == CODE_FOR_spe_evlhhousplat
9635 || icode == CODE_FOR_spe_evlwhe
9636 || icode == CODE_FOR_spe_evlwhos
9637 || icode == CODE_FOR_spe_evlwhou
9638 || icode == CODE_FOR_spe_evlwhsplat
9639 || icode == CODE_FOR_spe_evlwwsplat
9640 || icode == CODE_FOR_spe_evrlwi
9641 || icode == CODE_FOR_spe_evslwi
9642 || icode == CODE_FOR_spe_evsrwis
9643 || icode == CODE_FOR_spe_evsubifw
9644 || icode == CODE_FOR_spe_evsrwiu)
9646 /* Only allow 5-bit unsigned literals. */
9647 STRIP_NOPS (arg1);
9648 if (TREE_CODE (arg1) != INTEGER_CST
9649 || TREE_INT_CST_LOW (arg1) & ~0x1f)
9651 error ("argument 2 must be a 5-bit unsigned literal");
9652 return const0_rtx;
9656 if (target == 0
9657 || GET_MODE (target) != tmode
9658 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
9659 target = gen_reg_rtx (tmode);
9661 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
9662 op0 = copy_to_mode_reg (mode0, op0);
9663 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
9664 op1 = copy_to_mode_reg (mode1, op1);
9666 pat = GEN_FCN (icode) (target, op0, op1);
9667 if (! pat)
9668 return 0;
9669 emit_insn (pat);
9671 return target;
9674 static rtx
9675 altivec_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
9677 rtx pat, scratch;
9678 tree cr6_form = CALL_EXPR_ARG (exp, 0);
9679 tree arg0 = CALL_EXPR_ARG (exp, 1);
9680 tree arg1 = CALL_EXPR_ARG (exp, 2);
9681 rtx op0 = expand_normal (arg0);
9682 rtx op1 = expand_normal (arg1);
9683 enum machine_mode tmode = SImode;
9684 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
9685 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
9686 int cr6_form_int;
9688 if (TREE_CODE (cr6_form) != INTEGER_CST)
9690 error ("argument 1 of __builtin_altivec_predicate must be a constant");
9691 return const0_rtx;
9693 else
9694 cr6_form_int = TREE_INT_CST_LOW (cr6_form);
9696 gcc_assert (mode0 == mode1);
9698 /* If we have invalid arguments, bail out before generating bad rtl. */
9699 if (arg0 == error_mark_node || arg1 == error_mark_node)
9700 return const0_rtx;
9702 if (target == 0
9703 || GET_MODE (target) != tmode
9704 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
9705 target = gen_reg_rtx (tmode);
9707 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
9708 op0 = copy_to_mode_reg (mode0, op0);
9709 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
9710 op1 = copy_to_mode_reg (mode1, op1);
9712 scratch = gen_reg_rtx (mode0);
9714 pat = GEN_FCN (icode) (scratch, op0, op1);
9715 if (! pat)
9716 return 0;
9717 emit_insn (pat);
9719 /* The vec_any* and vec_all* predicates use the same opcodes for two
9720 different operations, but the bits in CR6 will be different
9721 depending on what information we want. So we have to play tricks
9722 with CR6 to get the right bits out.
9724 If you think this is disgusting, look at the specs for the
9725 AltiVec predicates. */
9727 switch (cr6_form_int)
9729 case 0:
9730 emit_insn (gen_cr6_test_for_zero (target));
9731 break;
9732 case 1:
9733 emit_insn (gen_cr6_test_for_zero_reverse (target));
9734 break;
9735 case 2:
9736 emit_insn (gen_cr6_test_for_lt (target));
9737 break;
9738 case 3:
9739 emit_insn (gen_cr6_test_for_lt_reverse (target));
9740 break;
9741 default:
9742 error ("argument 1 of __builtin_altivec_predicate is out of range");
9743 break;
9746 return target;
9749 static rtx
9750 paired_expand_lv_builtin (enum insn_code icode, tree exp, rtx target)
9752 rtx pat, addr;
9753 tree arg0 = CALL_EXPR_ARG (exp, 0);
9754 tree arg1 = CALL_EXPR_ARG (exp, 1);
9755 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9756 enum machine_mode mode0 = Pmode;
9757 enum machine_mode mode1 = Pmode;
9758 rtx op0 = expand_normal (arg0);
9759 rtx op1 = expand_normal (arg1);
9761 if (icode == CODE_FOR_nothing)
9762 /* Builtin not supported on this processor. */
9763 return 0;
9765 /* If we got invalid arguments bail out before generating bad rtl. */
9766 if (arg0 == error_mark_node || arg1 == error_mark_node)
9767 return const0_rtx;
9769 if (target == 0
9770 || GET_MODE (target) != tmode
9771 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
9772 target = gen_reg_rtx (tmode);
9774 op1 = copy_to_mode_reg (mode1, op1);
9776 if (op0 == const0_rtx)
9778 addr = gen_rtx_MEM (tmode, op1);
9780 else
9782 op0 = copy_to_mode_reg (mode0, op0);
9783 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op0, op1));
9786 pat = GEN_FCN (icode) (target, addr);
9788 if (! pat)
9789 return 0;
9790 emit_insn (pat);
9792 return target;
9795 static rtx
9796 altivec_expand_lv_builtin (enum insn_code icode, tree exp, rtx target, bool blk)
9798 rtx pat, addr;
9799 tree arg0 = CALL_EXPR_ARG (exp, 0);
9800 tree arg1 = CALL_EXPR_ARG (exp, 1);
9801 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9802 enum machine_mode mode0 = Pmode;
9803 enum machine_mode mode1 = Pmode;
9804 rtx op0 = expand_normal (arg0);
9805 rtx op1 = expand_normal (arg1);
9807 if (icode == CODE_FOR_nothing)
9808 /* Builtin not supported on this processor. */
9809 return 0;
9811 /* If we got invalid arguments bail out before generating bad rtl. */
9812 if (arg0 == error_mark_node || arg1 == error_mark_node)
9813 return const0_rtx;
9815 if (target == 0
9816 || GET_MODE (target) != tmode
9817 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
9818 target = gen_reg_rtx (tmode);
9820 op1 = copy_to_mode_reg (mode1, op1);
9822 if (op0 == const0_rtx)
9824 addr = gen_rtx_MEM (blk ? BLKmode : tmode, op1);
9826 else
9828 op0 = copy_to_mode_reg (mode0, op0);
9829 addr = gen_rtx_MEM (blk ? BLKmode : tmode, gen_rtx_PLUS (Pmode, op0, op1));
9832 pat = GEN_FCN (icode) (target, addr);
9834 if (! pat)
9835 return 0;
9836 emit_insn (pat);
9838 return target;
9841 static rtx
9842 spe_expand_stv_builtin (enum insn_code icode, tree exp)
9844 tree arg0 = CALL_EXPR_ARG (exp, 0);
9845 tree arg1 = CALL_EXPR_ARG (exp, 1);
9846 tree arg2 = CALL_EXPR_ARG (exp, 2);
9847 rtx op0 = expand_normal (arg0);
9848 rtx op1 = expand_normal (arg1);
9849 rtx op2 = expand_normal (arg2);
9850 rtx pat;
9851 enum machine_mode mode0 = insn_data[icode].operand[0].mode;
9852 enum machine_mode mode1 = insn_data[icode].operand[1].mode;
9853 enum machine_mode mode2 = insn_data[icode].operand[2].mode;
9855 /* Invalid arguments. Bail before doing anything stoopid! */
9856 if (arg0 == error_mark_node
9857 || arg1 == error_mark_node
9858 || arg2 == error_mark_node)
9859 return const0_rtx;
9861 if (! (*insn_data[icode].operand[2].predicate) (op0, mode2))
9862 op0 = copy_to_mode_reg (mode2, op0);
9863 if (! (*insn_data[icode].operand[0].predicate) (op1, mode0))
9864 op1 = copy_to_mode_reg (mode0, op1);
9865 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
9866 op2 = copy_to_mode_reg (mode1, op2);
9868 pat = GEN_FCN (icode) (op1, op2, op0);
9869 if (pat)
9870 emit_insn (pat);
9871 return NULL_RTX;
9874 static rtx
9875 paired_expand_stv_builtin (enum insn_code icode, tree exp)
9877 tree arg0 = CALL_EXPR_ARG (exp, 0);
9878 tree arg1 = CALL_EXPR_ARG (exp, 1);
9879 tree arg2 = CALL_EXPR_ARG (exp, 2);
9880 rtx op0 = expand_normal (arg0);
9881 rtx op1 = expand_normal (arg1);
9882 rtx op2 = expand_normal (arg2);
9883 rtx pat, addr;
9884 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9885 enum machine_mode mode1 = Pmode;
9886 enum machine_mode mode2 = Pmode;
9888 /* Invalid arguments. Bail before doing anything stoopid! */
9889 if (arg0 == error_mark_node
9890 || arg1 == error_mark_node
9891 || arg2 == error_mark_node)
9892 return const0_rtx;
9894 if (! (*insn_data[icode].operand[1].predicate) (op0, tmode))
9895 op0 = copy_to_mode_reg (tmode, op0);
9897 op2 = copy_to_mode_reg (mode2, op2);
9899 if (op1 == const0_rtx)
9901 addr = gen_rtx_MEM (tmode, op2);
9903 else
9905 op1 = copy_to_mode_reg (mode1, op1);
9906 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op1, op2));
9909 pat = GEN_FCN (icode) (addr, op0);
9910 if (pat)
9911 emit_insn (pat);
9912 return NULL_RTX;
9915 static rtx
9916 altivec_expand_stv_builtin (enum insn_code icode, tree exp)
9918 tree arg0 = CALL_EXPR_ARG (exp, 0);
9919 tree arg1 = CALL_EXPR_ARG (exp, 1);
9920 tree arg2 = CALL_EXPR_ARG (exp, 2);
9921 rtx op0 = expand_normal (arg0);
9922 rtx op1 = expand_normal (arg1);
9923 rtx op2 = expand_normal (arg2);
9924 rtx pat, addr;
9925 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9926 enum machine_mode mode1 = Pmode;
9927 enum machine_mode mode2 = Pmode;
9929 /* Invalid arguments. Bail before doing anything stoopid! */
9930 if (arg0 == error_mark_node
9931 || arg1 == error_mark_node
9932 || arg2 == error_mark_node)
9933 return const0_rtx;
9935 if (! (*insn_data[icode].operand[1].predicate) (op0, tmode))
9936 op0 = copy_to_mode_reg (tmode, op0);
9938 op2 = copy_to_mode_reg (mode2, op2);
9940 if (op1 == const0_rtx)
9942 addr = gen_rtx_MEM (tmode, op2);
9944 else
9946 op1 = copy_to_mode_reg (mode1, op1);
9947 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op1, op2));
9950 pat = GEN_FCN (icode) (addr, op0);
9951 if (pat)
9952 emit_insn (pat);
9953 return NULL_RTX;
9956 static rtx
9957 rs6000_expand_ternop_builtin (enum insn_code icode, tree exp, rtx target)
9959 rtx pat;
9960 tree arg0 = CALL_EXPR_ARG (exp, 0);
9961 tree arg1 = CALL_EXPR_ARG (exp, 1);
9962 tree arg2 = CALL_EXPR_ARG (exp, 2);
9963 rtx op0 = expand_normal (arg0);
9964 rtx op1 = expand_normal (arg1);
9965 rtx op2 = expand_normal (arg2);
9966 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9967 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
9968 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
9969 enum machine_mode mode2 = insn_data[icode].operand[3].mode;
9971 if (icode == CODE_FOR_nothing)
9972 /* Builtin not supported on this processor. */
9973 return 0;
9975 /* If we got invalid arguments bail out before generating bad rtl. */
9976 if (arg0 == error_mark_node
9977 || arg1 == error_mark_node
9978 || arg2 == error_mark_node)
9979 return const0_rtx;
9981 switch (icode)
9983 case CODE_FOR_altivec_vsldoi_v4sf:
9984 case CODE_FOR_altivec_vsldoi_v4si:
9985 case CODE_FOR_altivec_vsldoi_v8hi:
9986 case CODE_FOR_altivec_vsldoi_v16qi:
9987 /* Only allow 4-bit unsigned literals. */
9988 STRIP_NOPS (arg2);
9989 if (TREE_CODE (arg2) != INTEGER_CST
9990 || TREE_INT_CST_LOW (arg2) & ~0xf)
9992 error ("argument 3 must be a 4-bit unsigned literal");
9993 return const0_rtx;
9995 break;
9997 case CODE_FOR_vsx_xxpermdi_v2df:
9998 case CODE_FOR_vsx_xxpermdi_v2di:
9999 case CODE_FOR_vsx_xxsldwi_v16qi:
10000 case CODE_FOR_vsx_xxsldwi_v8hi:
10001 case CODE_FOR_vsx_xxsldwi_v4si:
10002 case CODE_FOR_vsx_xxsldwi_v4sf:
10003 case CODE_FOR_vsx_xxsldwi_v2di:
10004 case CODE_FOR_vsx_xxsldwi_v2df:
10005 /* Only allow 2-bit unsigned literals. */
10006 STRIP_NOPS (arg2);
10007 if (TREE_CODE (arg2) != INTEGER_CST
10008 || TREE_INT_CST_LOW (arg2) & ~0x3)
10010 error ("argument 3 must be a 2-bit unsigned literal");
10011 return const0_rtx;
10013 break;
10015 case CODE_FOR_vsx_set_v2df:
10016 case CODE_FOR_vsx_set_v2di:
10017 /* Only allow 1-bit unsigned literals. */
10018 STRIP_NOPS (arg2);
10019 if (TREE_CODE (arg2) != INTEGER_CST
10020 || TREE_INT_CST_LOW (arg2) & ~0x1)
10022 error ("argument 3 must be a 1-bit unsigned literal");
10023 return const0_rtx;
10025 break;
10027 default:
10028 break;
10031 if (target == 0
10032 || GET_MODE (target) != tmode
10033 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10034 target = gen_reg_rtx (tmode);
10036 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10037 op0 = copy_to_mode_reg (mode0, op0);
10038 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
10039 op1 = copy_to_mode_reg (mode1, op1);
10040 if (! (*insn_data[icode].operand[3].predicate) (op2, mode2))
10041 op2 = copy_to_mode_reg (mode2, op2);
10043 if (TARGET_PAIRED_FLOAT && icode == CODE_FOR_selv2sf4)
10044 pat = GEN_FCN (icode) (target, op0, op1, op2, CONST0_RTX (SFmode));
10045 else
10046 pat = GEN_FCN (icode) (target, op0, op1, op2);
10047 if (! pat)
10048 return 0;
10049 emit_insn (pat);
10051 return target;
10054 /* Expand the lvx builtins. */
10055 static rtx
10056 altivec_expand_ld_builtin (tree exp, rtx target, bool *expandedp)
10058 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10059 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10060 tree arg0;
10061 enum machine_mode tmode, mode0;
10062 rtx pat, op0;
10063 enum insn_code icode;
10065 switch (fcode)
10067 case ALTIVEC_BUILTIN_LD_INTERNAL_16qi:
10068 icode = CODE_FOR_vector_load_v16qi;
10069 break;
10070 case ALTIVEC_BUILTIN_LD_INTERNAL_8hi:
10071 icode = CODE_FOR_vector_load_v8hi;
10072 break;
10073 case ALTIVEC_BUILTIN_LD_INTERNAL_4si:
10074 icode = CODE_FOR_vector_load_v4si;
10075 break;
10076 case ALTIVEC_BUILTIN_LD_INTERNAL_4sf:
10077 icode = CODE_FOR_vector_load_v4sf;
10078 break;
10079 default:
10080 *expandedp = false;
10081 return NULL_RTX;
10084 *expandedp = true;
10086 arg0 = CALL_EXPR_ARG (exp, 0);
10087 op0 = expand_normal (arg0);
10088 tmode = insn_data[icode].operand[0].mode;
10089 mode0 = insn_data[icode].operand[1].mode;
10091 if (target == 0
10092 || GET_MODE (target) != tmode
10093 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10094 target = gen_reg_rtx (tmode);
10096 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10097 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
10099 pat = GEN_FCN (icode) (target, op0);
10100 if (! pat)
10101 return 0;
10102 emit_insn (pat);
10103 return target;
10106 /* Expand the stvx builtins. */
10107 static rtx
10108 altivec_expand_st_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
10109 bool *expandedp)
10111 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10112 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10113 tree arg0, arg1;
10114 enum machine_mode mode0, mode1;
10115 rtx pat, op0, op1;
10116 enum insn_code icode;
10118 switch (fcode)
10120 case ALTIVEC_BUILTIN_ST_INTERNAL_16qi:
10121 icode = CODE_FOR_vector_store_v16qi;
10122 break;
10123 case ALTIVEC_BUILTIN_ST_INTERNAL_8hi:
10124 icode = CODE_FOR_vector_store_v8hi;
10125 break;
10126 case ALTIVEC_BUILTIN_ST_INTERNAL_4si:
10127 icode = CODE_FOR_vector_store_v4si;
10128 break;
10129 case ALTIVEC_BUILTIN_ST_INTERNAL_4sf:
10130 icode = CODE_FOR_vector_store_v4sf;
10131 break;
10132 default:
10133 *expandedp = false;
10134 return NULL_RTX;
10137 arg0 = CALL_EXPR_ARG (exp, 0);
10138 arg1 = CALL_EXPR_ARG (exp, 1);
10139 op0 = expand_normal (arg0);
10140 op1 = expand_normal (arg1);
10141 mode0 = insn_data[icode].operand[0].mode;
10142 mode1 = insn_data[icode].operand[1].mode;
10144 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
10145 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
10146 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
10147 op1 = copy_to_mode_reg (mode1, op1);
10149 pat = GEN_FCN (icode) (op0, op1);
10150 if (pat)
10151 emit_insn (pat);
10153 *expandedp = true;
10154 return NULL_RTX;
10157 /* Expand the dst builtins. */
10158 static rtx
10159 altivec_expand_dst_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
10160 bool *expandedp)
10162 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10163 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10164 tree arg0, arg1, arg2;
10165 enum machine_mode mode0, mode1, mode2;
10166 rtx pat, op0, op1, op2;
10167 const struct builtin_description *d;
10168 size_t i;
10170 *expandedp = false;
10172 /* Handle DST variants. */
10173 d = bdesc_dst;
10174 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
10175 if (d->code == fcode)
10177 arg0 = CALL_EXPR_ARG (exp, 0);
10178 arg1 = CALL_EXPR_ARG (exp, 1);
10179 arg2 = CALL_EXPR_ARG (exp, 2);
10180 op0 = expand_normal (arg0);
10181 op1 = expand_normal (arg1);
10182 op2 = expand_normal (arg2);
10183 mode0 = insn_data[d->icode].operand[0].mode;
10184 mode1 = insn_data[d->icode].operand[1].mode;
10185 mode2 = insn_data[d->icode].operand[2].mode;
10187 /* Invalid arguments, bail out before generating bad rtl. */
10188 if (arg0 == error_mark_node
10189 || arg1 == error_mark_node
10190 || arg2 == error_mark_node)
10191 return const0_rtx;
10193 *expandedp = true;
10194 STRIP_NOPS (arg2);
10195 if (TREE_CODE (arg2) != INTEGER_CST
10196 || TREE_INT_CST_LOW (arg2) & ~0x3)
10198 error ("argument to %qs must be a 2-bit unsigned literal", d->name);
10199 return const0_rtx;
10202 if (! (*insn_data[d->icode].operand[0].predicate) (op0, mode0))
10203 op0 = copy_to_mode_reg (Pmode, op0);
10204 if (! (*insn_data[d->icode].operand[1].predicate) (op1, mode1))
10205 op1 = copy_to_mode_reg (mode1, op1);
10207 pat = GEN_FCN (d->icode) (op0, op1, op2);
10208 if (pat != 0)
10209 emit_insn (pat);
10211 return NULL_RTX;
10214 return NULL_RTX;
10217 /* Expand vec_init builtin. */
10218 static rtx
10219 altivec_expand_vec_init_builtin (tree type, tree exp, rtx target)
10221 enum machine_mode tmode = TYPE_MODE (type);
10222 enum machine_mode inner_mode = GET_MODE_INNER (tmode);
10223 int i, n_elt = GET_MODE_NUNITS (tmode);
10224 rtvec v = rtvec_alloc (n_elt);
10226 gcc_assert (VECTOR_MODE_P (tmode));
10227 gcc_assert (n_elt == call_expr_nargs (exp));
10229 for (i = 0; i < n_elt; ++i)
10231 rtx x = expand_normal (CALL_EXPR_ARG (exp, i));
10232 RTVEC_ELT (v, i) = gen_lowpart (inner_mode, x);
10235 if (!target || !register_operand (target, tmode))
10236 target = gen_reg_rtx (tmode);
10238 rs6000_expand_vector_init (target, gen_rtx_PARALLEL (tmode, v));
10239 return target;
10242 /* Return the integer constant in ARG. Constrain it to be in the range
10243 of the subparts of VEC_TYPE; issue an error if not. */
10245 static int
10246 get_element_number (tree vec_type, tree arg)
10248 unsigned HOST_WIDE_INT elt, max = TYPE_VECTOR_SUBPARTS (vec_type) - 1;
10250 if (!host_integerp (arg, 1)
10251 || (elt = tree_low_cst (arg, 1), elt > max))
10253 error ("selector must be an integer constant in the range 0..%wi", max);
10254 return 0;
10257 return elt;
10260 /* Expand vec_set builtin. */
10261 static rtx
10262 altivec_expand_vec_set_builtin (tree exp)
10264 enum machine_mode tmode, mode1;
10265 tree arg0, arg1, arg2;
10266 int elt;
10267 rtx op0, op1;
10269 arg0 = CALL_EXPR_ARG (exp, 0);
10270 arg1 = CALL_EXPR_ARG (exp, 1);
10271 arg2 = CALL_EXPR_ARG (exp, 2);
10273 tmode = TYPE_MODE (TREE_TYPE (arg0));
10274 mode1 = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
10275 gcc_assert (VECTOR_MODE_P (tmode));
10277 op0 = expand_expr (arg0, NULL_RTX, tmode, EXPAND_NORMAL);
10278 op1 = expand_expr (arg1, NULL_RTX, mode1, EXPAND_NORMAL);
10279 elt = get_element_number (TREE_TYPE (arg0), arg2);
10281 if (GET_MODE (op1) != mode1 && GET_MODE (op1) != VOIDmode)
10282 op1 = convert_modes (mode1, GET_MODE (op1), op1, true);
10284 op0 = force_reg (tmode, op0);
10285 op1 = force_reg (mode1, op1);
10287 rs6000_expand_vector_set (op0, op1, elt);
10289 return op0;
10292 /* Expand vec_ext builtin. */
10293 static rtx
10294 altivec_expand_vec_ext_builtin (tree exp, rtx target)
10296 enum machine_mode tmode, mode0;
10297 tree arg0, arg1;
10298 int elt;
10299 rtx op0;
10301 arg0 = CALL_EXPR_ARG (exp, 0);
10302 arg1 = CALL_EXPR_ARG (exp, 1);
10304 op0 = expand_normal (arg0);
10305 elt = get_element_number (TREE_TYPE (arg0), arg1);
10307 tmode = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
10308 mode0 = TYPE_MODE (TREE_TYPE (arg0));
10309 gcc_assert (VECTOR_MODE_P (mode0));
10311 op0 = force_reg (mode0, op0);
10313 if (optimize || !target || !register_operand (target, tmode))
10314 target = gen_reg_rtx (tmode);
10316 rs6000_expand_vector_extract (target, op0, elt);
10318 return target;
10321 /* Expand the builtin in EXP and store the result in TARGET. Store
10322 true in *EXPANDEDP if we found a builtin to expand. */
10323 static rtx
10324 altivec_expand_builtin (tree exp, rtx target, bool *expandedp)
10326 const struct builtin_description *d;
10327 const struct builtin_description_predicates *dp;
10328 size_t i;
10329 enum insn_code icode;
10330 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10331 tree arg0;
10332 rtx op0, pat;
10333 enum machine_mode tmode, mode0;
10334 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10336 if ((fcode >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
10337 && fcode <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
10338 || (fcode >= VSX_BUILTIN_OVERLOADED_FIRST
10339 && fcode <= VSX_BUILTIN_OVERLOADED_LAST))
10341 *expandedp = true;
10342 error ("unresolved overload for Altivec builtin %qF", fndecl);
10343 return const0_rtx;
10346 target = altivec_expand_ld_builtin (exp, target, expandedp);
10347 if (*expandedp)
10348 return target;
10350 target = altivec_expand_st_builtin (exp, target, expandedp);
10351 if (*expandedp)
10352 return target;
10354 target = altivec_expand_dst_builtin (exp, target, expandedp);
10355 if (*expandedp)
10356 return target;
10358 *expandedp = true;
10360 switch (fcode)
10362 case ALTIVEC_BUILTIN_STVX:
10363 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx, exp);
10364 case ALTIVEC_BUILTIN_STVEBX:
10365 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvebx, exp);
10366 case ALTIVEC_BUILTIN_STVEHX:
10367 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvehx, exp);
10368 case ALTIVEC_BUILTIN_STVEWX:
10369 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvewx, exp);
10370 case ALTIVEC_BUILTIN_STVXL:
10371 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvxl, exp);
10373 case ALTIVEC_BUILTIN_STVLX:
10374 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlx, exp);
10375 case ALTIVEC_BUILTIN_STVLXL:
10376 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlxl, exp);
10377 case ALTIVEC_BUILTIN_STVRX:
10378 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrx, exp);
10379 case ALTIVEC_BUILTIN_STVRXL:
10380 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrxl, exp);
10382 case ALTIVEC_BUILTIN_MFVSCR:
10383 icode = CODE_FOR_altivec_mfvscr;
10384 tmode = insn_data[icode].operand[0].mode;
10386 if (target == 0
10387 || GET_MODE (target) != tmode
10388 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10389 target = gen_reg_rtx (tmode);
10391 pat = GEN_FCN (icode) (target);
10392 if (! pat)
10393 return 0;
10394 emit_insn (pat);
10395 return target;
10397 case ALTIVEC_BUILTIN_MTVSCR:
10398 icode = CODE_FOR_altivec_mtvscr;
10399 arg0 = CALL_EXPR_ARG (exp, 0);
10400 op0 = expand_normal (arg0);
10401 mode0 = insn_data[icode].operand[0].mode;
10403 /* If we got invalid arguments bail out before generating bad rtl. */
10404 if (arg0 == error_mark_node)
10405 return const0_rtx;
10407 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
10408 op0 = copy_to_mode_reg (mode0, op0);
10410 pat = GEN_FCN (icode) (op0);
10411 if (pat)
10412 emit_insn (pat);
10413 return NULL_RTX;
10415 case ALTIVEC_BUILTIN_DSSALL:
10416 emit_insn (gen_altivec_dssall ());
10417 return NULL_RTX;
10419 case ALTIVEC_BUILTIN_DSS:
10420 icode = CODE_FOR_altivec_dss;
10421 arg0 = CALL_EXPR_ARG (exp, 0);
10422 STRIP_NOPS (arg0);
10423 op0 = expand_normal (arg0);
10424 mode0 = insn_data[icode].operand[0].mode;
10426 /* If we got invalid arguments bail out before generating bad rtl. */
10427 if (arg0 == error_mark_node)
10428 return const0_rtx;
10430 if (TREE_CODE (arg0) != INTEGER_CST
10431 || TREE_INT_CST_LOW (arg0) & ~0x3)
10433 error ("argument to dss must be a 2-bit unsigned literal");
10434 return const0_rtx;
10437 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
10438 op0 = copy_to_mode_reg (mode0, op0);
10440 emit_insn (gen_altivec_dss (op0));
10441 return NULL_RTX;
10443 case ALTIVEC_BUILTIN_VEC_INIT_V4SI:
10444 case ALTIVEC_BUILTIN_VEC_INIT_V8HI:
10445 case ALTIVEC_BUILTIN_VEC_INIT_V16QI:
10446 case ALTIVEC_BUILTIN_VEC_INIT_V4SF:
10447 case VSX_BUILTIN_VEC_INIT_V2DF:
10448 case VSX_BUILTIN_VEC_INIT_V2DI:
10449 return altivec_expand_vec_init_builtin (TREE_TYPE (exp), exp, target);
10451 case ALTIVEC_BUILTIN_VEC_SET_V4SI:
10452 case ALTIVEC_BUILTIN_VEC_SET_V8HI:
10453 case ALTIVEC_BUILTIN_VEC_SET_V16QI:
10454 case ALTIVEC_BUILTIN_VEC_SET_V4SF:
10455 case VSX_BUILTIN_VEC_SET_V2DF:
10456 case VSX_BUILTIN_VEC_SET_V2DI:
10457 return altivec_expand_vec_set_builtin (exp);
10459 case ALTIVEC_BUILTIN_VEC_EXT_V4SI:
10460 case ALTIVEC_BUILTIN_VEC_EXT_V8HI:
10461 case ALTIVEC_BUILTIN_VEC_EXT_V16QI:
10462 case ALTIVEC_BUILTIN_VEC_EXT_V4SF:
10463 case VSX_BUILTIN_VEC_EXT_V2DF:
10464 case VSX_BUILTIN_VEC_EXT_V2DI:
10465 return altivec_expand_vec_ext_builtin (exp, target);
10467 default:
10468 break;
10469 /* Fall through. */
10472 /* Expand abs* operations. */
10473 d = bdesc_abs;
10474 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
10475 if (d->code == fcode)
10476 return altivec_expand_abs_builtin (d->icode, exp, target);
10478 /* Expand the AltiVec predicates. */
10479 dp = bdesc_altivec_preds;
10480 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
10481 if (dp->code == fcode)
10482 return altivec_expand_predicate_builtin (dp->icode, exp, target);
10484 /* LV* are funky. We initialized them differently. */
10485 switch (fcode)
10487 case ALTIVEC_BUILTIN_LVSL:
10488 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsl,
10489 exp, target, false);
10490 case ALTIVEC_BUILTIN_LVSR:
10491 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsr,
10492 exp, target, false);
10493 case ALTIVEC_BUILTIN_LVEBX:
10494 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvebx,
10495 exp, target, false);
10496 case ALTIVEC_BUILTIN_LVEHX:
10497 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvehx,
10498 exp, target, false);
10499 case ALTIVEC_BUILTIN_LVEWX:
10500 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvewx,
10501 exp, target, false);
10502 case ALTIVEC_BUILTIN_LVXL:
10503 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvxl,
10504 exp, target, false);
10505 case ALTIVEC_BUILTIN_LVX:
10506 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx,
10507 exp, target, false);
10508 case ALTIVEC_BUILTIN_LVLX:
10509 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlx,
10510 exp, target, true);
10511 case ALTIVEC_BUILTIN_LVLXL:
10512 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlxl,
10513 exp, target, true);
10514 case ALTIVEC_BUILTIN_LVRX:
10515 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrx,
10516 exp, target, true);
10517 case ALTIVEC_BUILTIN_LVRXL:
10518 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrxl,
10519 exp, target, true);
10520 default:
10521 break;
10522 /* Fall through. */
10525 *expandedp = false;
10526 return NULL_RTX;
10529 /* Expand the builtin in EXP and store the result in TARGET. Store
10530 true in *EXPANDEDP if we found a builtin to expand. */
10531 static rtx
10532 paired_expand_builtin (tree exp, rtx target, bool * expandedp)
10534 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10535 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10536 const struct builtin_description *d;
10537 size_t i;
10539 *expandedp = true;
10541 switch (fcode)
10543 case PAIRED_BUILTIN_STX:
10544 return paired_expand_stv_builtin (CODE_FOR_paired_stx, exp);
10545 case PAIRED_BUILTIN_LX:
10546 return paired_expand_lv_builtin (CODE_FOR_paired_lx, exp, target);
10547 default:
10548 break;
10549 /* Fall through. */
10552 /* Expand the paired predicates. */
10553 d = bdesc_paired_preds;
10554 for (i = 0; i < ARRAY_SIZE (bdesc_paired_preds); i++, d++)
10555 if (d->code == fcode)
10556 return paired_expand_predicate_builtin (d->icode, exp, target);
10558 *expandedp = false;
10559 return NULL_RTX;
10562 /* Binops that need to be initialized manually, but can be expanded
10563 automagically by rs6000_expand_binop_builtin. */
10564 static struct builtin_description bdesc_2arg_spe[] =
10566 { 0, CODE_FOR_spe_evlddx, "__builtin_spe_evlddx", SPE_BUILTIN_EVLDDX },
10567 { 0, CODE_FOR_spe_evldwx, "__builtin_spe_evldwx", SPE_BUILTIN_EVLDWX },
10568 { 0, CODE_FOR_spe_evldhx, "__builtin_spe_evldhx", SPE_BUILTIN_EVLDHX },
10569 { 0, CODE_FOR_spe_evlwhex, "__builtin_spe_evlwhex", SPE_BUILTIN_EVLWHEX },
10570 { 0, CODE_FOR_spe_evlwhoux, "__builtin_spe_evlwhoux", SPE_BUILTIN_EVLWHOUX },
10571 { 0, CODE_FOR_spe_evlwhosx, "__builtin_spe_evlwhosx", SPE_BUILTIN_EVLWHOSX },
10572 { 0, CODE_FOR_spe_evlwwsplatx, "__builtin_spe_evlwwsplatx", SPE_BUILTIN_EVLWWSPLATX },
10573 { 0, CODE_FOR_spe_evlwhsplatx, "__builtin_spe_evlwhsplatx", SPE_BUILTIN_EVLWHSPLATX },
10574 { 0, CODE_FOR_spe_evlhhesplatx, "__builtin_spe_evlhhesplatx", SPE_BUILTIN_EVLHHESPLATX },
10575 { 0, CODE_FOR_spe_evlhhousplatx, "__builtin_spe_evlhhousplatx", SPE_BUILTIN_EVLHHOUSPLATX },
10576 { 0, CODE_FOR_spe_evlhhossplatx, "__builtin_spe_evlhhossplatx", SPE_BUILTIN_EVLHHOSSPLATX },
10577 { 0, CODE_FOR_spe_evldd, "__builtin_spe_evldd", SPE_BUILTIN_EVLDD },
10578 { 0, CODE_FOR_spe_evldw, "__builtin_spe_evldw", SPE_BUILTIN_EVLDW },
10579 { 0, CODE_FOR_spe_evldh, "__builtin_spe_evldh", SPE_BUILTIN_EVLDH },
10580 { 0, CODE_FOR_spe_evlwhe, "__builtin_spe_evlwhe", SPE_BUILTIN_EVLWHE },
10581 { 0, CODE_FOR_spe_evlwhou, "__builtin_spe_evlwhou", SPE_BUILTIN_EVLWHOU },
10582 { 0, CODE_FOR_spe_evlwhos, "__builtin_spe_evlwhos", SPE_BUILTIN_EVLWHOS },
10583 { 0, CODE_FOR_spe_evlwwsplat, "__builtin_spe_evlwwsplat", SPE_BUILTIN_EVLWWSPLAT },
10584 { 0, CODE_FOR_spe_evlwhsplat, "__builtin_spe_evlwhsplat", SPE_BUILTIN_EVLWHSPLAT },
10585 { 0, CODE_FOR_spe_evlhhesplat, "__builtin_spe_evlhhesplat", SPE_BUILTIN_EVLHHESPLAT },
10586 { 0, CODE_FOR_spe_evlhhousplat, "__builtin_spe_evlhhousplat", SPE_BUILTIN_EVLHHOUSPLAT },
10587 { 0, CODE_FOR_spe_evlhhossplat, "__builtin_spe_evlhhossplat", SPE_BUILTIN_EVLHHOSSPLAT }
10590 /* Expand the builtin in EXP and store the result in TARGET. Store
10591 true in *EXPANDEDP if we found a builtin to expand.
10593 This expands the SPE builtins that are not simple unary and binary
10594 operations. */
10595 static rtx
10596 spe_expand_builtin (tree exp, rtx target, bool *expandedp)
10598 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10599 tree arg1, arg0;
10600 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10601 enum insn_code icode;
10602 enum machine_mode tmode, mode0;
10603 rtx pat, op0;
10604 struct builtin_description *d;
10605 size_t i;
10607 *expandedp = true;
10609 /* Syntax check for a 5-bit unsigned immediate. */
10610 switch (fcode)
10612 case SPE_BUILTIN_EVSTDD:
10613 case SPE_BUILTIN_EVSTDH:
10614 case SPE_BUILTIN_EVSTDW:
10615 case SPE_BUILTIN_EVSTWHE:
10616 case SPE_BUILTIN_EVSTWHO:
10617 case SPE_BUILTIN_EVSTWWE:
10618 case SPE_BUILTIN_EVSTWWO:
10619 arg1 = CALL_EXPR_ARG (exp, 2);
10620 if (TREE_CODE (arg1) != INTEGER_CST
10621 || TREE_INT_CST_LOW (arg1) & ~0x1f)
10623 error ("argument 2 must be a 5-bit unsigned literal");
10624 return const0_rtx;
10626 break;
10627 default:
10628 break;
10631 /* The evsplat*i instructions are not quite generic. */
10632 switch (fcode)
10634 case SPE_BUILTIN_EVSPLATFI:
10635 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplatfi,
10636 exp, target);
10637 case SPE_BUILTIN_EVSPLATI:
10638 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplati,
10639 exp, target);
10640 default:
10641 break;
10644 d = (struct builtin_description *) bdesc_2arg_spe;
10645 for (i = 0; i < ARRAY_SIZE (bdesc_2arg_spe); ++i, ++d)
10646 if (d->code == fcode)
10647 return rs6000_expand_binop_builtin (d->icode, exp, target);
10649 d = (struct builtin_description *) bdesc_spe_predicates;
10650 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, ++d)
10651 if (d->code == fcode)
10652 return spe_expand_predicate_builtin (d->icode, exp, target);
10654 d = (struct builtin_description *) bdesc_spe_evsel;
10655 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, ++d)
10656 if (d->code == fcode)
10657 return spe_expand_evsel_builtin (d->icode, exp, target);
10659 switch (fcode)
10661 case SPE_BUILTIN_EVSTDDX:
10662 return spe_expand_stv_builtin (CODE_FOR_spe_evstddx, exp);
10663 case SPE_BUILTIN_EVSTDHX:
10664 return spe_expand_stv_builtin (CODE_FOR_spe_evstdhx, exp);
10665 case SPE_BUILTIN_EVSTDWX:
10666 return spe_expand_stv_builtin (CODE_FOR_spe_evstdwx, exp);
10667 case SPE_BUILTIN_EVSTWHEX:
10668 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhex, exp);
10669 case SPE_BUILTIN_EVSTWHOX:
10670 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhox, exp);
10671 case SPE_BUILTIN_EVSTWWEX:
10672 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwex, exp);
10673 case SPE_BUILTIN_EVSTWWOX:
10674 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwox, exp);
10675 case SPE_BUILTIN_EVSTDD:
10676 return spe_expand_stv_builtin (CODE_FOR_spe_evstdd, exp);
10677 case SPE_BUILTIN_EVSTDH:
10678 return spe_expand_stv_builtin (CODE_FOR_spe_evstdh, exp);
10679 case SPE_BUILTIN_EVSTDW:
10680 return spe_expand_stv_builtin (CODE_FOR_spe_evstdw, exp);
10681 case SPE_BUILTIN_EVSTWHE:
10682 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhe, exp);
10683 case SPE_BUILTIN_EVSTWHO:
10684 return spe_expand_stv_builtin (CODE_FOR_spe_evstwho, exp);
10685 case SPE_BUILTIN_EVSTWWE:
10686 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwe, exp);
10687 case SPE_BUILTIN_EVSTWWO:
10688 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwo, exp);
10689 case SPE_BUILTIN_MFSPEFSCR:
10690 icode = CODE_FOR_spe_mfspefscr;
10691 tmode = insn_data[icode].operand[0].mode;
10693 if (target == 0
10694 || GET_MODE (target) != tmode
10695 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10696 target = gen_reg_rtx (tmode);
10698 pat = GEN_FCN (icode) (target);
10699 if (! pat)
10700 return 0;
10701 emit_insn (pat);
10702 return target;
10703 case SPE_BUILTIN_MTSPEFSCR:
10704 icode = CODE_FOR_spe_mtspefscr;
10705 arg0 = CALL_EXPR_ARG (exp, 0);
10706 op0 = expand_normal (arg0);
10707 mode0 = insn_data[icode].operand[0].mode;
10709 if (arg0 == error_mark_node)
10710 return const0_rtx;
10712 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
10713 op0 = copy_to_mode_reg (mode0, op0);
10715 pat = GEN_FCN (icode) (op0);
10716 if (pat)
10717 emit_insn (pat);
10718 return NULL_RTX;
10719 default:
10720 break;
10723 *expandedp = false;
10724 return NULL_RTX;
10727 static rtx
10728 paired_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
10730 rtx pat, scratch, tmp;
10731 tree form = CALL_EXPR_ARG (exp, 0);
10732 tree arg0 = CALL_EXPR_ARG (exp, 1);
10733 tree arg1 = CALL_EXPR_ARG (exp, 2);
10734 rtx op0 = expand_normal (arg0);
10735 rtx op1 = expand_normal (arg1);
10736 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10737 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
10738 int form_int;
10739 enum rtx_code code;
10741 if (TREE_CODE (form) != INTEGER_CST)
10743 error ("argument 1 of __builtin_paired_predicate must be a constant");
10744 return const0_rtx;
10746 else
10747 form_int = TREE_INT_CST_LOW (form);
10749 gcc_assert (mode0 == mode1);
10751 if (arg0 == error_mark_node || arg1 == error_mark_node)
10752 return const0_rtx;
10754 if (target == 0
10755 || GET_MODE (target) != SImode
10756 || !(*insn_data[icode].operand[0].predicate) (target, SImode))
10757 target = gen_reg_rtx (SImode);
10758 if (!(*insn_data[icode].operand[1].predicate) (op0, mode0))
10759 op0 = copy_to_mode_reg (mode0, op0);
10760 if (!(*insn_data[icode].operand[2].predicate) (op1, mode1))
10761 op1 = copy_to_mode_reg (mode1, op1);
10763 scratch = gen_reg_rtx (CCFPmode);
10765 pat = GEN_FCN (icode) (scratch, op0, op1);
10766 if (!pat)
10767 return const0_rtx;
10769 emit_insn (pat);
10771 switch (form_int)
10773 /* LT bit. */
10774 case 0:
10775 code = LT;
10776 break;
10777 /* GT bit. */
10778 case 1:
10779 code = GT;
10780 break;
10781 /* EQ bit. */
10782 case 2:
10783 code = EQ;
10784 break;
10785 /* UN bit. */
10786 case 3:
10787 emit_insn (gen_move_from_CR_ov_bit (target, scratch));
10788 return target;
10789 default:
10790 error ("argument 1 of __builtin_paired_predicate is out of range");
10791 return const0_rtx;
10794 tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx);
10795 emit_move_insn (target, tmp);
10796 return target;
10799 static rtx
10800 spe_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
10802 rtx pat, scratch, tmp;
10803 tree form = CALL_EXPR_ARG (exp, 0);
10804 tree arg0 = CALL_EXPR_ARG (exp, 1);
10805 tree arg1 = CALL_EXPR_ARG (exp, 2);
10806 rtx op0 = expand_normal (arg0);
10807 rtx op1 = expand_normal (arg1);
10808 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10809 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
10810 int form_int;
10811 enum rtx_code code;
10813 if (TREE_CODE (form) != INTEGER_CST)
10815 error ("argument 1 of __builtin_spe_predicate must be a constant");
10816 return const0_rtx;
10818 else
10819 form_int = TREE_INT_CST_LOW (form);
10821 gcc_assert (mode0 == mode1);
10823 if (arg0 == error_mark_node || arg1 == error_mark_node)
10824 return const0_rtx;
10826 if (target == 0
10827 || GET_MODE (target) != SImode
10828 || ! (*insn_data[icode].operand[0].predicate) (target, SImode))
10829 target = gen_reg_rtx (SImode);
10831 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10832 op0 = copy_to_mode_reg (mode0, op0);
10833 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
10834 op1 = copy_to_mode_reg (mode1, op1);
10836 scratch = gen_reg_rtx (CCmode);
10838 pat = GEN_FCN (icode) (scratch, op0, op1);
10839 if (! pat)
10840 return const0_rtx;
10841 emit_insn (pat);
10843 /* There are 4 variants for each predicate: _any_, _all_, _upper_,
10844 _lower_. We use one compare, but look in different bits of the
10845 CR for each variant.
10847 There are 2 elements in each SPE simd type (upper/lower). The CR
10848 bits are set as follows:
10850 BIT0 | BIT 1 | BIT 2 | BIT 3
10851 U | L | (U | L) | (U & L)
10853 So, for an "all" relationship, BIT 3 would be set.
10854 For an "any" relationship, BIT 2 would be set. Etc.
10856 Following traditional nomenclature, these bits map to:
10858 BIT0 | BIT 1 | BIT 2 | BIT 3
10859 LT | GT | EQ | OV
10861 Later, we will generate rtl to look in the LT/EQ/EQ/OV bits.
10864 switch (form_int)
10866 /* All variant. OV bit. */
10867 case 0:
10868 /* We need to get to the OV bit, which is the ORDERED bit. We
10869 could generate (ordered:SI (reg:CC xx) (const_int 0)), but
10870 that's ugly and will make validate_condition_mode die.
10871 So let's just use another pattern. */
10872 emit_insn (gen_move_from_CR_ov_bit (target, scratch));
10873 return target;
10874 /* Any variant. EQ bit. */
10875 case 1:
10876 code = EQ;
10877 break;
10878 /* Upper variant. LT bit. */
10879 case 2:
10880 code = LT;
10881 break;
10882 /* Lower variant. GT bit. */
10883 case 3:
10884 code = GT;
10885 break;
10886 default:
10887 error ("argument 1 of __builtin_spe_predicate is out of range");
10888 return const0_rtx;
10891 tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx);
10892 emit_move_insn (target, tmp);
10894 return target;
10897 /* The evsel builtins look like this:
10899 e = __builtin_spe_evsel_OP (a, b, c, d);
10901 and work like this:
10903 e[upper] = a[upper] *OP* b[upper] ? c[upper] : d[upper];
10904 e[lower] = a[lower] *OP* b[lower] ? c[lower] : d[lower];
10907 static rtx
10908 spe_expand_evsel_builtin (enum insn_code icode, tree exp, rtx target)
10910 rtx pat, scratch;
10911 tree arg0 = CALL_EXPR_ARG (exp, 0);
10912 tree arg1 = CALL_EXPR_ARG (exp, 1);
10913 tree arg2 = CALL_EXPR_ARG (exp, 2);
10914 tree arg3 = CALL_EXPR_ARG (exp, 3);
10915 rtx op0 = expand_normal (arg0);
10916 rtx op1 = expand_normal (arg1);
10917 rtx op2 = expand_normal (arg2);
10918 rtx op3 = expand_normal (arg3);
10919 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10920 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
10922 gcc_assert (mode0 == mode1);
10924 if (arg0 == error_mark_node || arg1 == error_mark_node
10925 || arg2 == error_mark_node || arg3 == error_mark_node)
10926 return const0_rtx;
10928 if (target == 0
10929 || GET_MODE (target) != mode0
10930 || ! (*insn_data[icode].operand[0].predicate) (target, mode0))
10931 target = gen_reg_rtx (mode0);
10933 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10934 op0 = copy_to_mode_reg (mode0, op0);
10935 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
10936 op1 = copy_to_mode_reg (mode0, op1);
10937 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
10938 op2 = copy_to_mode_reg (mode0, op2);
10939 if (! (*insn_data[icode].operand[1].predicate) (op3, mode1))
10940 op3 = copy_to_mode_reg (mode0, op3);
10942 /* Generate the compare. */
10943 scratch = gen_reg_rtx (CCmode);
10944 pat = GEN_FCN (icode) (scratch, op0, op1);
10945 if (! pat)
10946 return const0_rtx;
10947 emit_insn (pat);
10949 if (mode0 == V2SImode)
10950 emit_insn (gen_spe_evsel (target, op2, op3, scratch));
10951 else
10952 emit_insn (gen_spe_evsel_fs (target, op2, op3, scratch));
10954 return target;
10957 /* Expand an expression EXP that calls a built-in function,
10958 with result going to TARGET if that's convenient
10959 (and in mode MODE if that's convenient).
10960 SUBTARGET may be used as the target for computing one of EXP's operands.
10961 IGNORE is nonzero if the value is to be ignored. */
10963 static rtx
10964 rs6000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
10965 enum machine_mode mode ATTRIBUTE_UNUSED,
10966 int ignore ATTRIBUTE_UNUSED)
10968 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10969 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10970 const struct builtin_description *d;
10971 size_t i;
10972 rtx ret;
10973 bool success;
10975 if (fcode == RS6000_BUILTIN_RECIP)
10976 return rs6000_expand_binop_builtin (CODE_FOR_recipdf3, exp, target);
10978 if (fcode == RS6000_BUILTIN_RECIPF)
10979 return rs6000_expand_binop_builtin (CODE_FOR_recipsf3, exp, target);
10981 if (fcode == RS6000_BUILTIN_RSQRTF)
10982 return rs6000_expand_unop_builtin (CODE_FOR_rsqrtsf2, exp, target);
10984 if (fcode == RS6000_BUILTIN_BSWAP_HI)
10985 return rs6000_expand_unop_builtin (CODE_FOR_bswaphi2, exp, target);
10987 if (fcode == POWER7_BUILTIN_BPERMD)
10988 return rs6000_expand_binop_builtin (((TARGET_64BIT)
10989 ? CODE_FOR_bpermd_di
10990 : CODE_FOR_bpermd_si), exp, target);
10992 if (fcode == ALTIVEC_BUILTIN_MASK_FOR_LOAD
10993 || fcode == ALTIVEC_BUILTIN_MASK_FOR_STORE)
10995 int icode = (int) CODE_FOR_altivec_lvsr;
10996 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10997 enum machine_mode mode = insn_data[icode].operand[1].mode;
10998 tree arg;
10999 rtx op, addr, pat;
11001 gcc_assert (TARGET_ALTIVEC);
11003 arg = CALL_EXPR_ARG (exp, 0);
11004 gcc_assert (TREE_CODE (TREE_TYPE (arg)) == POINTER_TYPE);
11005 op = expand_expr (arg, NULL_RTX, Pmode, EXPAND_NORMAL);
11006 addr = memory_address (mode, op);
11007 if (fcode == ALTIVEC_BUILTIN_MASK_FOR_STORE)
11008 op = addr;
11009 else
11011 /* For the load case need to negate the address. */
11012 op = gen_reg_rtx (GET_MODE (addr));
11013 emit_insn (gen_rtx_SET (VOIDmode, op,
11014 gen_rtx_NEG (GET_MODE (addr), addr)));
11016 op = gen_rtx_MEM (mode, op);
11018 if (target == 0
11019 || GET_MODE (target) != tmode
11020 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11021 target = gen_reg_rtx (tmode);
11023 /*pat = gen_altivec_lvsr (target, op);*/
11024 pat = GEN_FCN (icode) (target, op);
11025 if (!pat)
11026 return 0;
11027 emit_insn (pat);
11029 return target;
11032 /* FIXME: There's got to be a nicer way to handle this case than
11033 constructing a new CALL_EXPR. */
11034 if (fcode == ALTIVEC_BUILTIN_VCFUX
11035 || fcode == ALTIVEC_BUILTIN_VCFSX
11036 || fcode == ALTIVEC_BUILTIN_VCTUXS
11037 || fcode == ALTIVEC_BUILTIN_VCTSXS)
11039 if (call_expr_nargs (exp) == 1)
11040 exp = build_call_nary (TREE_TYPE (exp), CALL_EXPR_FN (exp),
11041 2, CALL_EXPR_ARG (exp, 0), integer_zero_node);
11044 if (TARGET_ALTIVEC)
11046 ret = altivec_expand_builtin (exp, target, &success);
11048 if (success)
11049 return ret;
11051 if (TARGET_SPE)
11053 ret = spe_expand_builtin (exp, target, &success);
11055 if (success)
11056 return ret;
11058 if (TARGET_PAIRED_FLOAT)
11060 ret = paired_expand_builtin (exp, target, &success);
11062 if (success)
11063 return ret;
11066 gcc_assert (TARGET_ALTIVEC || TARGET_VSX || TARGET_SPE || TARGET_PAIRED_FLOAT);
11068 /* Handle simple unary operations. */
11069 d = (struct builtin_description *) bdesc_1arg;
11070 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
11071 if (d->code == fcode)
11072 return rs6000_expand_unop_builtin (d->icode, exp, target);
11074 /* Handle simple binary operations. */
11075 d = (struct builtin_description *) bdesc_2arg;
11076 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
11077 if (d->code == fcode)
11078 return rs6000_expand_binop_builtin (d->icode, exp, target);
11080 /* Handle simple ternary operations. */
11081 d = bdesc_3arg;
11082 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
11083 if (d->code == fcode)
11084 return rs6000_expand_ternop_builtin (d->icode, exp, target);
11086 gcc_unreachable ();
11089 static void
11090 rs6000_init_builtins (void)
11092 tree tdecl;
11094 V2SI_type_node = build_vector_type (intSI_type_node, 2);
11095 V2SF_type_node = build_vector_type (float_type_node, 2);
11096 V2DI_type_node = build_vector_type (intDI_type_node, 2);
11097 V2DF_type_node = build_vector_type (double_type_node, 2);
11098 V4HI_type_node = build_vector_type (intHI_type_node, 4);
11099 V4SI_type_node = build_vector_type (intSI_type_node, 4);
11100 V4SF_type_node = build_vector_type (float_type_node, 4);
11101 V8HI_type_node = build_vector_type (intHI_type_node, 8);
11102 V16QI_type_node = build_vector_type (intQI_type_node, 16);
11104 unsigned_V16QI_type_node = build_vector_type (unsigned_intQI_type_node, 16);
11105 unsigned_V8HI_type_node = build_vector_type (unsigned_intHI_type_node, 8);
11106 unsigned_V4SI_type_node = build_vector_type (unsigned_intSI_type_node, 4);
11107 unsigned_V2DI_type_node = build_vector_type (unsigned_intDI_type_node, 2);
11109 opaque_V2SF_type_node = build_opaque_vector_type (float_type_node, 2);
11110 opaque_V2SI_type_node = build_opaque_vector_type (intSI_type_node, 2);
11111 opaque_p_V2SI_type_node = build_pointer_type (opaque_V2SI_type_node);
11112 opaque_V4SI_type_node = build_opaque_vector_type (intSI_type_node, 4);
11114 /* The 'vector bool ...' types must be kept distinct from 'vector unsigned ...'
11115 types, especially in C++ land. Similarly, 'vector pixel' is distinct from
11116 'vector unsigned short'. */
11118 bool_char_type_node = build_distinct_type_copy (unsigned_intQI_type_node);
11119 bool_short_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
11120 bool_int_type_node = build_distinct_type_copy (unsigned_intSI_type_node);
11121 bool_long_type_node = build_distinct_type_copy (unsigned_intDI_type_node);
11122 pixel_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
11124 long_integer_type_internal_node = long_integer_type_node;
11125 long_unsigned_type_internal_node = long_unsigned_type_node;
11126 intQI_type_internal_node = intQI_type_node;
11127 uintQI_type_internal_node = unsigned_intQI_type_node;
11128 intHI_type_internal_node = intHI_type_node;
11129 uintHI_type_internal_node = unsigned_intHI_type_node;
11130 intSI_type_internal_node = intSI_type_node;
11131 uintSI_type_internal_node = unsigned_intSI_type_node;
11132 intDI_type_internal_node = intDI_type_node;
11133 uintDI_type_internal_node = unsigned_intDI_type_node;
11134 float_type_internal_node = float_type_node;
11135 double_type_internal_node = float_type_node;
11136 void_type_internal_node = void_type_node;
11138 /* Initialize the modes for builtin_function_type, mapping a machine mode to
11139 tree type node. */
11140 builtin_mode_to_type[QImode][0] = integer_type_node;
11141 builtin_mode_to_type[HImode][0] = integer_type_node;
11142 builtin_mode_to_type[SImode][0] = intSI_type_node;
11143 builtin_mode_to_type[SImode][1] = unsigned_intSI_type_node;
11144 builtin_mode_to_type[DImode][0] = intDI_type_node;
11145 builtin_mode_to_type[DImode][1] = unsigned_intDI_type_node;
11146 builtin_mode_to_type[SFmode][0] = float_type_node;
11147 builtin_mode_to_type[DFmode][0] = double_type_node;
11148 builtin_mode_to_type[V2SImode][0] = V2SI_type_node;
11149 builtin_mode_to_type[V2SFmode][0] = V2SF_type_node;
11150 builtin_mode_to_type[V2DImode][0] = V2DI_type_node;
11151 builtin_mode_to_type[V2DImode][1] = unsigned_V2DI_type_node;
11152 builtin_mode_to_type[V2DFmode][0] = V2DF_type_node;
11153 builtin_mode_to_type[V4HImode][0] = V4HI_type_node;
11154 builtin_mode_to_type[V4SImode][0] = V4SI_type_node;
11155 builtin_mode_to_type[V4SImode][1] = unsigned_V4SI_type_node;
11156 builtin_mode_to_type[V4SFmode][0] = V4SF_type_node;
11157 builtin_mode_to_type[V8HImode][0] = V8HI_type_node;
11158 builtin_mode_to_type[V8HImode][1] = unsigned_V8HI_type_node;
11159 builtin_mode_to_type[V16QImode][0] = V16QI_type_node;
11160 builtin_mode_to_type[V16QImode][1] = unsigned_V16QI_type_node;
11162 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
11163 get_identifier ("__bool char"),
11164 bool_char_type_node);
11165 TYPE_NAME (bool_char_type_node) = tdecl;
11166 (*lang_hooks.decls.pushdecl) (tdecl);
11167 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
11168 get_identifier ("__bool short"),
11169 bool_short_type_node);
11170 TYPE_NAME (bool_short_type_node) = tdecl;
11171 (*lang_hooks.decls.pushdecl) (tdecl);
11172 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
11173 get_identifier ("__bool int"),
11174 bool_int_type_node);
11175 TYPE_NAME (bool_int_type_node) = tdecl;
11176 (*lang_hooks.decls.pushdecl) (tdecl);
11177 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL, get_identifier ("__pixel"),
11178 pixel_type_node);
11179 TYPE_NAME (pixel_type_node) = tdecl;
11180 (*lang_hooks.decls.pushdecl) (tdecl);
11182 bool_V16QI_type_node = build_vector_type (bool_char_type_node, 16);
11183 bool_V8HI_type_node = build_vector_type (bool_short_type_node, 8);
11184 bool_V4SI_type_node = build_vector_type (bool_int_type_node, 4);
11185 bool_V2DI_type_node = build_vector_type (bool_long_type_node, 2);
11186 pixel_V8HI_type_node = build_vector_type (pixel_type_node, 8);
11188 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
11189 get_identifier ("__vector unsigned char"),
11190 unsigned_V16QI_type_node);
11191 TYPE_NAME (unsigned_V16QI_type_node) = tdecl;
11192 (*lang_hooks.decls.pushdecl) (tdecl);
11193 tdecl = build_decl (BUILTINS_LOCATION,
11194 TYPE_DECL, get_identifier ("__vector signed char"),
11195 V16QI_type_node);
11196 TYPE_NAME (V16QI_type_node) = tdecl;
11197 (*lang_hooks.decls.pushdecl) (tdecl);
11198 tdecl = build_decl (BUILTINS_LOCATION,
11199 TYPE_DECL, get_identifier ("__vector __bool char"),
11200 bool_V16QI_type_node);
11201 TYPE_NAME ( bool_V16QI_type_node) = tdecl;
11202 (*lang_hooks.decls.pushdecl) (tdecl);
11204 tdecl = build_decl (BUILTINS_LOCATION,
11205 TYPE_DECL, get_identifier ("__vector unsigned short"),
11206 unsigned_V8HI_type_node);
11207 TYPE_NAME (unsigned_V8HI_type_node) = tdecl;
11208 (*lang_hooks.decls.pushdecl) (tdecl);
11209 tdecl = build_decl (BUILTINS_LOCATION,
11210 TYPE_DECL, get_identifier ("__vector signed short"),
11211 V8HI_type_node);
11212 TYPE_NAME (V8HI_type_node) = tdecl;
11213 (*lang_hooks.decls.pushdecl) (tdecl);
11214 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
11215 get_identifier ("__vector __bool short"),
11216 bool_V8HI_type_node);
11217 TYPE_NAME (bool_V8HI_type_node) = tdecl;
11218 (*lang_hooks.decls.pushdecl) (tdecl);
11220 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
11221 get_identifier ("__vector unsigned int"),
11222 unsigned_V4SI_type_node);
11223 TYPE_NAME (unsigned_V4SI_type_node) = tdecl;
11224 (*lang_hooks.decls.pushdecl) (tdecl);
11225 tdecl = build_decl (BUILTINS_LOCATION,
11226 TYPE_DECL, get_identifier ("__vector signed int"),
11227 V4SI_type_node);
11228 TYPE_NAME (V4SI_type_node) = tdecl;
11229 (*lang_hooks.decls.pushdecl) (tdecl);
11230 tdecl = build_decl (BUILTINS_LOCATION,
11231 TYPE_DECL, get_identifier ("__vector __bool int"),
11232 bool_V4SI_type_node);
11233 TYPE_NAME (bool_V4SI_type_node) = tdecl;
11234 (*lang_hooks.decls.pushdecl) (tdecl);
11236 tdecl = build_decl (BUILTINS_LOCATION,
11237 TYPE_DECL, get_identifier ("__vector float"),
11238 V4SF_type_node);
11239 TYPE_NAME (V4SF_type_node) = tdecl;
11240 (*lang_hooks.decls.pushdecl) (tdecl);
11241 tdecl = build_decl (BUILTINS_LOCATION,
11242 TYPE_DECL, get_identifier ("__vector __pixel"),
11243 pixel_V8HI_type_node);
11244 TYPE_NAME (pixel_V8HI_type_node) = tdecl;
11245 (*lang_hooks.decls.pushdecl) (tdecl);
11247 if (TARGET_VSX)
11249 tdecl = build_decl (BUILTINS_LOCATION,
11250 TYPE_DECL, get_identifier ("__vector double"),
11251 V2DF_type_node);
11252 TYPE_NAME (V2DF_type_node) = tdecl;
11253 (*lang_hooks.decls.pushdecl) (tdecl);
11255 tdecl = build_decl (BUILTINS_LOCATION,
11256 TYPE_DECL, get_identifier ("__vector long"),
11257 V2DI_type_node);
11258 TYPE_NAME (V2DI_type_node) = tdecl;
11259 (*lang_hooks.decls.pushdecl) (tdecl);
11261 tdecl = build_decl (BUILTINS_LOCATION,
11262 TYPE_DECL, get_identifier ("__vector unsigned long"),
11263 unsigned_V2DI_type_node);
11264 TYPE_NAME (unsigned_V2DI_type_node) = tdecl;
11265 (*lang_hooks.decls.pushdecl) (tdecl);
11267 tdecl = build_decl (BUILTINS_LOCATION,
11268 TYPE_DECL, get_identifier ("__vector __bool long"),
11269 bool_V2DI_type_node);
11270 TYPE_NAME (bool_V2DI_type_node) = tdecl;
11271 (*lang_hooks.decls.pushdecl) (tdecl);
11274 if (TARGET_PAIRED_FLOAT)
11275 paired_init_builtins ();
11276 if (TARGET_SPE)
11277 spe_init_builtins ();
11278 if (TARGET_ALTIVEC)
11279 altivec_init_builtins ();
11280 if (TARGET_ALTIVEC || TARGET_SPE || TARGET_PAIRED_FLOAT || TARGET_VSX)
11281 rs6000_common_init_builtins ();
11282 if (TARGET_PPC_GFXOPT)
11284 tree ftype = builtin_function_type (SFmode, SFmode, SFmode, VOIDmode,
11285 RS6000_BUILTIN_RECIPF,
11286 "__builtin_recipdivf");
11287 def_builtin (MASK_PPC_GFXOPT, "__builtin_recipdivf", ftype,
11288 RS6000_BUILTIN_RECIPF);
11290 ftype = builtin_function_type (SFmode, SFmode, VOIDmode, VOIDmode,
11291 RS6000_BUILTIN_RSQRTF,
11292 "__builtin_rsqrtf");
11293 def_builtin (MASK_PPC_GFXOPT, "__builtin_rsqrtf", ftype,
11294 RS6000_BUILTIN_RSQRTF);
11296 if (TARGET_POPCNTB)
11298 tree ftype = builtin_function_type (DFmode, DFmode, DFmode, VOIDmode,
11299 RS6000_BUILTIN_RECIP,
11300 "__builtin_recipdiv");
11301 def_builtin (MASK_POPCNTB, "__builtin_recipdiv", ftype,
11302 RS6000_BUILTIN_RECIP);
11305 if (TARGET_POPCNTD)
11307 enum machine_mode mode = (TARGET_64BIT) ? DImode : SImode;
11308 tree ftype = builtin_function_type (mode, mode, mode, VOIDmode,
11309 POWER7_BUILTIN_BPERMD,
11310 "__builtin_bpermd");
11311 def_builtin (MASK_POPCNTD, "__builtin_bpermd", ftype,
11312 POWER7_BUILTIN_BPERMD);
11314 if (TARGET_POWERPC)
11316 /* Don't use builtin_function_type here, as it maps HI/QI to SI. */
11317 tree ftype = build_function_type_list (unsigned_intHI_type_node,
11318 unsigned_intHI_type_node,
11319 NULL_TREE);
11320 def_builtin (MASK_POWERPC, "__builtin_bswap16", ftype,
11321 RS6000_BUILTIN_BSWAP_HI);
11324 #if TARGET_XCOFF
11325 /* AIX libm provides clog as __clog. */
11326 if (built_in_decls [BUILT_IN_CLOG])
11327 set_user_assembler_name (built_in_decls [BUILT_IN_CLOG], "__clog");
11328 #endif
11330 #ifdef SUBTARGET_INIT_BUILTINS
11331 SUBTARGET_INIT_BUILTINS;
11332 #endif
11335 /* Returns the rs6000 builtin decl for CODE. */
11337 static tree
11338 rs6000_builtin_decl (unsigned code, bool initialize_p ATTRIBUTE_UNUSED)
11340 if (code >= RS6000_BUILTIN_COUNT)
11341 return error_mark_node;
11343 return rs6000_builtin_decls[code];
11346 /* Search through a set of builtins and enable the mask bits.
11347 DESC is an array of builtins.
11348 SIZE is the total number of builtins.
11349 START is the builtin enum at which to start.
11350 END is the builtin enum at which to end. */
11351 static void
11352 enable_mask_for_builtins (struct builtin_description *desc, int size,
11353 enum rs6000_builtins start,
11354 enum rs6000_builtins end)
11356 int i;
11358 for (i = 0; i < size; ++i)
11359 if (desc[i].code == start)
11360 break;
11362 if (i == size)
11363 return;
11365 for (; i < size; ++i)
11367 /* Flip all the bits on. */
11368 desc[i].mask = target_flags;
11369 if (desc[i].code == end)
11370 break;
11374 static void
11375 spe_init_builtins (void)
11377 tree endlink = void_list_node;
11378 tree puint_type_node = build_pointer_type (unsigned_type_node);
11379 tree pushort_type_node = build_pointer_type (short_unsigned_type_node);
11380 struct builtin_description *d;
11381 size_t i;
11383 tree v2si_ftype_4_v2si
11384 = build_function_type
11385 (opaque_V2SI_type_node,
11386 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11387 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11388 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11389 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11390 endlink)))));
11392 tree v2sf_ftype_4_v2sf
11393 = build_function_type
11394 (opaque_V2SF_type_node,
11395 tree_cons (NULL_TREE, opaque_V2SF_type_node,
11396 tree_cons (NULL_TREE, opaque_V2SF_type_node,
11397 tree_cons (NULL_TREE, opaque_V2SF_type_node,
11398 tree_cons (NULL_TREE, opaque_V2SF_type_node,
11399 endlink)))));
11401 tree int_ftype_int_v2si_v2si
11402 = build_function_type
11403 (integer_type_node,
11404 tree_cons (NULL_TREE, integer_type_node,
11405 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11406 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11407 endlink))));
11409 tree int_ftype_int_v2sf_v2sf
11410 = build_function_type
11411 (integer_type_node,
11412 tree_cons (NULL_TREE, integer_type_node,
11413 tree_cons (NULL_TREE, opaque_V2SF_type_node,
11414 tree_cons (NULL_TREE, opaque_V2SF_type_node,
11415 endlink))));
11417 tree void_ftype_v2si_puint_int
11418 = build_function_type (void_type_node,
11419 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11420 tree_cons (NULL_TREE, puint_type_node,
11421 tree_cons (NULL_TREE,
11422 integer_type_node,
11423 endlink))));
11425 tree void_ftype_v2si_puint_char
11426 = build_function_type (void_type_node,
11427 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11428 tree_cons (NULL_TREE, puint_type_node,
11429 tree_cons (NULL_TREE,
11430 char_type_node,
11431 endlink))));
11433 tree void_ftype_v2si_pv2si_int
11434 = build_function_type (void_type_node,
11435 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11436 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
11437 tree_cons (NULL_TREE,
11438 integer_type_node,
11439 endlink))));
11441 tree void_ftype_v2si_pv2si_char
11442 = build_function_type (void_type_node,
11443 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11444 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
11445 tree_cons (NULL_TREE,
11446 char_type_node,
11447 endlink))));
11449 tree void_ftype_int
11450 = build_function_type (void_type_node,
11451 tree_cons (NULL_TREE, integer_type_node, endlink));
11453 tree int_ftype_void
11454 = build_function_type (integer_type_node, endlink);
11456 tree v2si_ftype_pv2si_int
11457 = build_function_type (opaque_V2SI_type_node,
11458 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
11459 tree_cons (NULL_TREE, integer_type_node,
11460 endlink)));
11462 tree v2si_ftype_puint_int
11463 = build_function_type (opaque_V2SI_type_node,
11464 tree_cons (NULL_TREE, puint_type_node,
11465 tree_cons (NULL_TREE, integer_type_node,
11466 endlink)));
11468 tree v2si_ftype_pushort_int
11469 = build_function_type (opaque_V2SI_type_node,
11470 tree_cons (NULL_TREE, pushort_type_node,
11471 tree_cons (NULL_TREE, integer_type_node,
11472 endlink)));
11474 tree v2si_ftype_signed_char
11475 = build_function_type (opaque_V2SI_type_node,
11476 tree_cons (NULL_TREE, signed_char_type_node,
11477 endlink));
11479 /* The initialization of the simple binary and unary builtins is
11480 done in rs6000_common_init_builtins, but we have to enable the
11481 mask bits here manually because we have run out of `target_flags'
11482 bits. We really need to redesign this mask business. */
11484 enable_mask_for_builtins ((struct builtin_description *) bdesc_2arg,
11485 ARRAY_SIZE (bdesc_2arg),
11486 SPE_BUILTIN_EVADDW,
11487 SPE_BUILTIN_EVXOR);
11488 enable_mask_for_builtins ((struct builtin_description *) bdesc_1arg,
11489 ARRAY_SIZE (bdesc_1arg),
11490 SPE_BUILTIN_EVABS,
11491 SPE_BUILTIN_EVSUBFUSIAAW);
11492 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_predicates,
11493 ARRAY_SIZE (bdesc_spe_predicates),
11494 SPE_BUILTIN_EVCMPEQ,
11495 SPE_BUILTIN_EVFSTSTLT);
11496 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_evsel,
11497 ARRAY_SIZE (bdesc_spe_evsel),
11498 SPE_BUILTIN_EVSEL_CMPGTS,
11499 SPE_BUILTIN_EVSEL_FSTSTEQ);
11501 (*lang_hooks.decls.pushdecl)
11502 (build_decl (BUILTINS_LOCATION, TYPE_DECL,
11503 get_identifier ("__ev64_opaque__"),
11504 opaque_V2SI_type_node));
11506 /* Initialize irregular SPE builtins. */
11508 def_builtin (target_flags, "__builtin_spe_mtspefscr", void_ftype_int, SPE_BUILTIN_MTSPEFSCR);
11509 def_builtin (target_flags, "__builtin_spe_mfspefscr", int_ftype_void, SPE_BUILTIN_MFSPEFSCR);
11510 def_builtin (target_flags, "__builtin_spe_evstddx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDDX);
11511 def_builtin (target_flags, "__builtin_spe_evstdhx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDHX);
11512 def_builtin (target_flags, "__builtin_spe_evstdwx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDWX);
11513 def_builtin (target_flags, "__builtin_spe_evstwhex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHEX);
11514 def_builtin (target_flags, "__builtin_spe_evstwhox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHOX);
11515 def_builtin (target_flags, "__builtin_spe_evstwwex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWEX);
11516 def_builtin (target_flags, "__builtin_spe_evstwwox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWOX);
11517 def_builtin (target_flags, "__builtin_spe_evstdd", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDD);
11518 def_builtin (target_flags, "__builtin_spe_evstdh", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDH);
11519 def_builtin (target_flags, "__builtin_spe_evstdw", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDW);
11520 def_builtin (target_flags, "__builtin_spe_evstwhe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHE);
11521 def_builtin (target_flags, "__builtin_spe_evstwho", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHO);
11522 def_builtin (target_flags, "__builtin_spe_evstwwe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWE);
11523 def_builtin (target_flags, "__builtin_spe_evstwwo", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWO);
11524 def_builtin (target_flags, "__builtin_spe_evsplatfi", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATFI);
11525 def_builtin (target_flags, "__builtin_spe_evsplati", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATI);
11527 /* Loads. */
11528 def_builtin (target_flags, "__builtin_spe_evlddx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDDX);
11529 def_builtin (target_flags, "__builtin_spe_evldwx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDWX);
11530 def_builtin (target_flags, "__builtin_spe_evldhx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDHX);
11531 def_builtin (target_flags, "__builtin_spe_evlwhex", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHEX);
11532 def_builtin (target_flags, "__builtin_spe_evlwhoux", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOUX);
11533 def_builtin (target_flags, "__builtin_spe_evlwhosx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOSX);
11534 def_builtin (target_flags, "__builtin_spe_evlwwsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLATX);
11535 def_builtin (target_flags, "__builtin_spe_evlwhsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLATX);
11536 def_builtin (target_flags, "__builtin_spe_evlhhesplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLATX);
11537 def_builtin (target_flags, "__builtin_spe_evlhhousplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLATX);
11538 def_builtin (target_flags, "__builtin_spe_evlhhossplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLATX);
11539 def_builtin (target_flags, "__builtin_spe_evldd", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDD);
11540 def_builtin (target_flags, "__builtin_spe_evldw", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDW);
11541 def_builtin (target_flags, "__builtin_spe_evldh", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDH);
11542 def_builtin (target_flags, "__builtin_spe_evlhhesplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLAT);
11543 def_builtin (target_flags, "__builtin_spe_evlhhossplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLAT);
11544 def_builtin (target_flags, "__builtin_spe_evlhhousplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLAT);
11545 def_builtin (target_flags, "__builtin_spe_evlwhe", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHE);
11546 def_builtin (target_flags, "__builtin_spe_evlwhos", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOS);
11547 def_builtin (target_flags, "__builtin_spe_evlwhou", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOU);
11548 def_builtin (target_flags, "__builtin_spe_evlwhsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLAT);
11549 def_builtin (target_flags, "__builtin_spe_evlwwsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLAT);
11551 /* Predicates. */
11552 d = (struct builtin_description *) bdesc_spe_predicates;
11553 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, d++)
11555 tree type;
11557 switch (insn_data[d->icode].operand[1].mode)
11559 case V2SImode:
11560 type = int_ftype_int_v2si_v2si;
11561 break;
11562 case V2SFmode:
11563 type = int_ftype_int_v2sf_v2sf;
11564 break;
11565 default:
11566 gcc_unreachable ();
11569 def_builtin (d->mask, d->name, type, d->code);
11572 /* Evsel predicates. */
11573 d = (struct builtin_description *) bdesc_spe_evsel;
11574 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, d++)
11576 tree type;
11578 switch (insn_data[d->icode].operand[1].mode)
11580 case V2SImode:
11581 type = v2si_ftype_4_v2si;
11582 break;
11583 case V2SFmode:
11584 type = v2sf_ftype_4_v2sf;
11585 break;
11586 default:
11587 gcc_unreachable ();
11590 def_builtin (d->mask, d->name, type, d->code);
11594 static void
11595 paired_init_builtins (void)
11597 const struct builtin_description *d;
11598 size_t i;
11599 tree endlink = void_list_node;
11601 tree int_ftype_int_v2sf_v2sf
11602 = build_function_type
11603 (integer_type_node,
11604 tree_cons (NULL_TREE, integer_type_node,
11605 tree_cons (NULL_TREE, V2SF_type_node,
11606 tree_cons (NULL_TREE, V2SF_type_node,
11607 endlink))));
11608 tree pcfloat_type_node =
11609 build_pointer_type (build_qualified_type
11610 (float_type_node, TYPE_QUAL_CONST));
11612 tree v2sf_ftype_long_pcfloat = build_function_type_list (V2SF_type_node,
11613 long_integer_type_node,
11614 pcfloat_type_node,
11615 NULL_TREE);
11616 tree void_ftype_v2sf_long_pcfloat =
11617 build_function_type_list (void_type_node,
11618 V2SF_type_node,
11619 long_integer_type_node,
11620 pcfloat_type_node,
11621 NULL_TREE);
11624 def_builtin (0, "__builtin_paired_lx", v2sf_ftype_long_pcfloat,
11625 PAIRED_BUILTIN_LX);
11628 def_builtin (0, "__builtin_paired_stx", void_ftype_v2sf_long_pcfloat,
11629 PAIRED_BUILTIN_STX);
11631 /* Predicates. */
11632 d = bdesc_paired_preds;
11633 for (i = 0; i < ARRAY_SIZE (bdesc_paired_preds); ++i, d++)
11635 tree type;
11637 switch (insn_data[d->icode].operand[1].mode)
11639 case V2SFmode:
11640 type = int_ftype_int_v2sf_v2sf;
11641 break;
11642 default:
11643 gcc_unreachable ();
11646 def_builtin (d->mask, d->name, type, d->code);
11650 static void
11651 altivec_init_builtins (void)
11653 const struct builtin_description *d;
11654 const struct builtin_description_predicates *dp;
11655 size_t i;
11656 tree ftype;
11658 tree pfloat_type_node = build_pointer_type (float_type_node);
11659 tree pint_type_node = build_pointer_type (integer_type_node);
11660 tree pshort_type_node = build_pointer_type (short_integer_type_node);
11661 tree pchar_type_node = build_pointer_type (char_type_node);
11663 tree pvoid_type_node = build_pointer_type (void_type_node);
11665 tree pcfloat_type_node = build_pointer_type (build_qualified_type (float_type_node, TYPE_QUAL_CONST));
11666 tree pcint_type_node = build_pointer_type (build_qualified_type (integer_type_node, TYPE_QUAL_CONST));
11667 tree pcshort_type_node = build_pointer_type (build_qualified_type (short_integer_type_node, TYPE_QUAL_CONST));
11668 tree pcchar_type_node = build_pointer_type (build_qualified_type (char_type_node, TYPE_QUAL_CONST));
11670 tree pcvoid_type_node = build_pointer_type (build_qualified_type (void_type_node, TYPE_QUAL_CONST));
11672 tree int_ftype_opaque
11673 = build_function_type_list (integer_type_node,
11674 opaque_V4SI_type_node, NULL_TREE);
11675 tree opaque_ftype_opaque
11676 = build_function_type (integer_type_node,
11677 NULL_TREE);
11678 tree opaque_ftype_opaque_int
11679 = build_function_type_list (opaque_V4SI_type_node,
11680 opaque_V4SI_type_node, integer_type_node, NULL_TREE);
11681 tree opaque_ftype_opaque_opaque_int
11682 = build_function_type_list (opaque_V4SI_type_node,
11683 opaque_V4SI_type_node, opaque_V4SI_type_node,
11684 integer_type_node, NULL_TREE);
11685 tree int_ftype_int_opaque_opaque
11686 = build_function_type_list (integer_type_node,
11687 integer_type_node, opaque_V4SI_type_node,
11688 opaque_V4SI_type_node, NULL_TREE);
11689 tree int_ftype_int_v4si_v4si
11690 = build_function_type_list (integer_type_node,
11691 integer_type_node, V4SI_type_node,
11692 V4SI_type_node, NULL_TREE);
11693 tree v4sf_ftype_pcfloat
11694 = build_function_type_list (V4SF_type_node, pcfloat_type_node, NULL_TREE);
11695 tree void_ftype_pfloat_v4sf
11696 = build_function_type_list (void_type_node,
11697 pfloat_type_node, V4SF_type_node, NULL_TREE);
11698 tree v4si_ftype_pcint
11699 = build_function_type_list (V4SI_type_node, pcint_type_node, NULL_TREE);
11700 tree void_ftype_pint_v4si
11701 = build_function_type_list (void_type_node,
11702 pint_type_node, V4SI_type_node, NULL_TREE);
11703 tree v8hi_ftype_pcshort
11704 = build_function_type_list (V8HI_type_node, pcshort_type_node, NULL_TREE);
11705 tree void_ftype_pshort_v8hi
11706 = build_function_type_list (void_type_node,
11707 pshort_type_node, V8HI_type_node, NULL_TREE);
11708 tree v16qi_ftype_pcchar
11709 = build_function_type_list (V16QI_type_node, pcchar_type_node, NULL_TREE);
11710 tree void_ftype_pchar_v16qi
11711 = build_function_type_list (void_type_node,
11712 pchar_type_node, V16QI_type_node, NULL_TREE);
11713 tree void_ftype_v4si
11714 = build_function_type_list (void_type_node, V4SI_type_node, NULL_TREE);
11715 tree v8hi_ftype_void
11716 = build_function_type (V8HI_type_node, void_list_node);
11717 tree void_ftype_void
11718 = build_function_type (void_type_node, void_list_node);
11719 tree void_ftype_int
11720 = build_function_type_list (void_type_node, integer_type_node, NULL_TREE);
11722 tree opaque_ftype_long_pcvoid
11723 = build_function_type_list (opaque_V4SI_type_node,
11724 long_integer_type_node, pcvoid_type_node, NULL_TREE);
11725 tree v16qi_ftype_long_pcvoid
11726 = build_function_type_list (V16QI_type_node,
11727 long_integer_type_node, pcvoid_type_node, NULL_TREE);
11728 tree v8hi_ftype_long_pcvoid
11729 = build_function_type_list (V8HI_type_node,
11730 long_integer_type_node, pcvoid_type_node, NULL_TREE);
11731 tree v4si_ftype_long_pcvoid
11732 = build_function_type_list (V4SI_type_node,
11733 long_integer_type_node, pcvoid_type_node, NULL_TREE);
11735 tree void_ftype_opaque_long_pvoid
11736 = build_function_type_list (void_type_node,
11737 opaque_V4SI_type_node, long_integer_type_node,
11738 pvoid_type_node, NULL_TREE);
11739 tree void_ftype_v4si_long_pvoid
11740 = build_function_type_list (void_type_node,
11741 V4SI_type_node, long_integer_type_node,
11742 pvoid_type_node, NULL_TREE);
11743 tree void_ftype_v16qi_long_pvoid
11744 = build_function_type_list (void_type_node,
11745 V16QI_type_node, long_integer_type_node,
11746 pvoid_type_node, NULL_TREE);
11747 tree void_ftype_v8hi_long_pvoid
11748 = build_function_type_list (void_type_node,
11749 V8HI_type_node, long_integer_type_node,
11750 pvoid_type_node, NULL_TREE);
11751 tree int_ftype_int_v8hi_v8hi
11752 = build_function_type_list (integer_type_node,
11753 integer_type_node, V8HI_type_node,
11754 V8HI_type_node, NULL_TREE);
11755 tree int_ftype_int_v16qi_v16qi
11756 = build_function_type_list (integer_type_node,
11757 integer_type_node, V16QI_type_node,
11758 V16QI_type_node, NULL_TREE);
11759 tree int_ftype_int_v4sf_v4sf
11760 = build_function_type_list (integer_type_node,
11761 integer_type_node, V4SF_type_node,
11762 V4SF_type_node, NULL_TREE);
11763 tree int_ftype_int_v2df_v2df
11764 = build_function_type_list (integer_type_node,
11765 integer_type_node, V2DF_type_node,
11766 V2DF_type_node, NULL_TREE);
11767 tree v4si_ftype_v4si
11768 = build_function_type_list (V4SI_type_node, V4SI_type_node, NULL_TREE);
11769 tree v8hi_ftype_v8hi
11770 = build_function_type_list (V8HI_type_node, V8HI_type_node, NULL_TREE);
11771 tree v16qi_ftype_v16qi
11772 = build_function_type_list (V16QI_type_node, V16QI_type_node, NULL_TREE);
11773 tree v4sf_ftype_v4sf
11774 = build_function_type_list (V4SF_type_node, V4SF_type_node, NULL_TREE);
11775 tree v2df_ftype_v2df
11776 = build_function_type_list (V2DF_type_node, V2DF_type_node, NULL_TREE);
11777 tree void_ftype_pcvoid_int_int
11778 = build_function_type_list (void_type_node,
11779 pcvoid_type_node, integer_type_node,
11780 integer_type_node, NULL_TREE);
11782 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_4sf", v4sf_ftype_pcfloat,
11783 ALTIVEC_BUILTIN_LD_INTERNAL_4sf);
11784 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_4sf", void_ftype_pfloat_v4sf,
11785 ALTIVEC_BUILTIN_ST_INTERNAL_4sf);
11786 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_4si", v4si_ftype_pcint,
11787 ALTIVEC_BUILTIN_LD_INTERNAL_4si);
11788 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_4si", void_ftype_pint_v4si,
11789 ALTIVEC_BUILTIN_ST_INTERNAL_4si);
11790 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_8hi", v8hi_ftype_pcshort,
11791 ALTIVEC_BUILTIN_LD_INTERNAL_8hi);
11792 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_8hi", void_ftype_pshort_v8hi,
11793 ALTIVEC_BUILTIN_ST_INTERNAL_8hi);
11794 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_16qi", v16qi_ftype_pcchar,
11795 ALTIVEC_BUILTIN_LD_INTERNAL_16qi);
11796 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_16qi", void_ftype_pchar_v16qi,
11797 ALTIVEC_BUILTIN_ST_INTERNAL_16qi);
11798 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mtvscr", void_ftype_v4si, ALTIVEC_BUILTIN_MTVSCR);
11799 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mfvscr", v8hi_ftype_void, ALTIVEC_BUILTIN_MFVSCR);
11800 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dssall", void_ftype_void, ALTIVEC_BUILTIN_DSSALL);
11801 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dss", void_ftype_int, ALTIVEC_BUILTIN_DSS);
11802 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSL);
11803 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSR);
11804 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEBX);
11805 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEHX);
11806 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEWX);
11807 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvxl", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVXL);
11808 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVX);
11809 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVX);
11810 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvewx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVEWX);
11811 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvxl", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVXL);
11812 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvebx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVEBX);
11813 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvehx", void_ftype_v8hi_long_pvoid, ALTIVEC_BUILTIN_STVEHX);
11814 def_builtin (MASK_ALTIVEC, "__builtin_vec_ld", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LD);
11815 def_builtin (MASK_ALTIVEC, "__builtin_vec_lde", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDE);
11816 def_builtin (MASK_ALTIVEC, "__builtin_vec_ldl", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDL);
11817 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSL);
11818 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSR);
11819 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEBX);
11820 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEHX);
11821 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEWX);
11822 def_builtin (MASK_ALTIVEC, "__builtin_vec_st", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_ST);
11823 def_builtin (MASK_ALTIVEC, "__builtin_vec_ste", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STE);
11824 def_builtin (MASK_ALTIVEC, "__builtin_vec_stl", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STL);
11825 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvewx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEWX);
11826 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvebx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEBX);
11827 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvehx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEHX);
11829 if (rs6000_cpu == PROCESSOR_CELL)
11831 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvlx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVLX);
11832 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvlxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVLXL);
11833 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvrx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVRX);
11834 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvrxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVRXL);
11836 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvlx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVLX);
11837 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvlxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVLXL);
11838 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvrx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVRX);
11839 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvrxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVRXL);
11841 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvlx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVLX);
11842 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvlxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVLXL);
11843 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvrx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVRX);
11844 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvrxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVRXL);
11846 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvlx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVLX);
11847 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvlxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVLXL);
11848 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvrx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVRX);
11849 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvrxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVRXL);
11851 def_builtin (MASK_ALTIVEC, "__builtin_vec_step", int_ftype_opaque, ALTIVEC_BUILTIN_VEC_STEP);
11852 def_builtin (MASK_ALTIVEC, "__builtin_vec_splats", opaque_ftype_opaque, ALTIVEC_BUILTIN_VEC_SPLATS);
11853 def_builtin (MASK_ALTIVEC, "__builtin_vec_promote", opaque_ftype_opaque, ALTIVEC_BUILTIN_VEC_PROMOTE);
11855 def_builtin (MASK_ALTIVEC, "__builtin_vec_sld", opaque_ftype_opaque_opaque_int, ALTIVEC_BUILTIN_VEC_SLD);
11856 def_builtin (MASK_ALTIVEC, "__builtin_vec_splat", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_SPLAT);
11857 def_builtin (MASK_ALTIVEC, "__builtin_vec_extract", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_EXTRACT);
11858 def_builtin (MASK_ALTIVEC, "__builtin_vec_insert", opaque_ftype_opaque_opaque_int, ALTIVEC_BUILTIN_VEC_INSERT);
11859 def_builtin (MASK_ALTIVEC, "__builtin_vec_vspltw", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTW);
11860 def_builtin (MASK_ALTIVEC, "__builtin_vec_vsplth", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTH);
11861 def_builtin (MASK_ALTIVEC, "__builtin_vec_vspltb", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTB);
11862 def_builtin (MASK_ALTIVEC, "__builtin_vec_ctf", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTF);
11863 def_builtin (MASK_ALTIVEC, "__builtin_vec_vcfsx", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFSX);
11864 def_builtin (MASK_ALTIVEC, "__builtin_vec_vcfux", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFUX);
11865 def_builtin (MASK_ALTIVEC, "__builtin_vec_cts", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTS);
11866 def_builtin (MASK_ALTIVEC, "__builtin_vec_ctu", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTU);
11868 /* Add the DST variants. */
11869 d = bdesc_dst;
11870 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
11871 def_builtin (d->mask, d->name, void_ftype_pcvoid_int_int, d->code);
11873 /* Initialize the predicates. */
11874 dp = bdesc_altivec_preds;
11875 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
11877 enum machine_mode mode1;
11878 tree type;
11879 bool is_overloaded = ((dp->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
11880 && dp->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
11881 || (dp->code >= VSX_BUILTIN_OVERLOADED_FIRST
11882 && dp->code <= VSX_BUILTIN_OVERLOADED_LAST));
11884 if (is_overloaded)
11885 mode1 = VOIDmode;
11886 else
11887 mode1 = insn_data[dp->icode].operand[1].mode;
11889 switch (mode1)
11891 case VOIDmode:
11892 type = int_ftype_int_opaque_opaque;
11893 break;
11894 case V4SImode:
11895 type = int_ftype_int_v4si_v4si;
11896 break;
11897 case V8HImode:
11898 type = int_ftype_int_v8hi_v8hi;
11899 break;
11900 case V16QImode:
11901 type = int_ftype_int_v16qi_v16qi;
11902 break;
11903 case V4SFmode:
11904 type = int_ftype_int_v4sf_v4sf;
11905 break;
11906 case V2DFmode:
11907 type = int_ftype_int_v2df_v2df;
11908 break;
11909 default:
11910 gcc_unreachable ();
11913 def_builtin (dp->mask, dp->name, type, dp->code);
11916 /* Initialize the abs* operators. */
11917 d = bdesc_abs;
11918 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
11920 enum machine_mode mode0;
11921 tree type;
11923 mode0 = insn_data[d->icode].operand[0].mode;
11925 switch (mode0)
11927 case V4SImode:
11928 type = v4si_ftype_v4si;
11929 break;
11930 case V8HImode:
11931 type = v8hi_ftype_v8hi;
11932 break;
11933 case V16QImode:
11934 type = v16qi_ftype_v16qi;
11935 break;
11936 case V4SFmode:
11937 type = v4sf_ftype_v4sf;
11938 break;
11939 case V2DFmode:
11940 type = v2df_ftype_v2df;
11941 break;
11942 default:
11943 gcc_unreachable ();
11946 def_builtin (d->mask, d->name, type, d->code);
11949 if (TARGET_ALTIVEC)
11951 tree decl;
11953 /* Initialize target builtin that implements
11954 targetm.vectorize.builtin_mask_for_load. */
11956 decl = add_builtin_function ("__builtin_altivec_mask_for_load",
11957 v16qi_ftype_long_pcvoid,
11958 ALTIVEC_BUILTIN_MASK_FOR_LOAD,
11959 BUILT_IN_MD, NULL, NULL_TREE);
11960 TREE_READONLY (decl) = 1;
11961 /* Record the decl. Will be used by rs6000_builtin_mask_for_load. */
11962 altivec_builtin_mask_for_load = decl;
11965 /* Access to the vec_init patterns. */
11966 ftype = build_function_type_list (V4SI_type_node, integer_type_node,
11967 integer_type_node, integer_type_node,
11968 integer_type_node, NULL_TREE);
11969 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v4si", ftype,
11970 ALTIVEC_BUILTIN_VEC_INIT_V4SI);
11972 ftype = build_function_type_list (V8HI_type_node, short_integer_type_node,
11973 short_integer_type_node,
11974 short_integer_type_node,
11975 short_integer_type_node,
11976 short_integer_type_node,
11977 short_integer_type_node,
11978 short_integer_type_node,
11979 short_integer_type_node, NULL_TREE);
11980 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v8hi", ftype,
11981 ALTIVEC_BUILTIN_VEC_INIT_V8HI);
11983 ftype = build_function_type_list (V16QI_type_node, char_type_node,
11984 char_type_node, char_type_node,
11985 char_type_node, char_type_node,
11986 char_type_node, char_type_node,
11987 char_type_node, char_type_node,
11988 char_type_node, char_type_node,
11989 char_type_node, char_type_node,
11990 char_type_node, char_type_node,
11991 char_type_node, NULL_TREE);
11992 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v16qi", ftype,
11993 ALTIVEC_BUILTIN_VEC_INIT_V16QI);
11995 ftype = build_function_type_list (V4SF_type_node, float_type_node,
11996 float_type_node, float_type_node,
11997 float_type_node, NULL_TREE);
11998 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v4sf", ftype,
11999 ALTIVEC_BUILTIN_VEC_INIT_V4SF);
12001 if (TARGET_VSX)
12003 ftype = build_function_type_list (V2DF_type_node, double_type_node,
12004 double_type_node, NULL_TREE);
12005 def_builtin (MASK_VSX, "__builtin_vec_init_v2df", ftype,
12006 VSX_BUILTIN_VEC_INIT_V2DF);
12008 ftype = build_function_type_list (V2DI_type_node, intDI_type_node,
12009 intDI_type_node, NULL_TREE);
12010 def_builtin (MASK_VSX, "__builtin_vec_init_v2di", ftype,
12011 VSX_BUILTIN_VEC_INIT_V2DI);
12014 /* Access to the vec_set patterns. */
12015 ftype = build_function_type_list (V4SI_type_node, V4SI_type_node,
12016 intSI_type_node,
12017 integer_type_node, NULL_TREE);
12018 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v4si", ftype,
12019 ALTIVEC_BUILTIN_VEC_SET_V4SI);
12021 ftype = build_function_type_list (V8HI_type_node, V8HI_type_node,
12022 intHI_type_node,
12023 integer_type_node, NULL_TREE);
12024 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v8hi", ftype,
12025 ALTIVEC_BUILTIN_VEC_SET_V8HI);
12027 ftype = build_function_type_list (V16QI_type_node, V16QI_type_node,
12028 intQI_type_node,
12029 integer_type_node, NULL_TREE);
12030 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v16qi", ftype,
12031 ALTIVEC_BUILTIN_VEC_SET_V16QI);
12033 ftype = build_function_type_list (V4SF_type_node, V4SF_type_node,
12034 float_type_node,
12035 integer_type_node, NULL_TREE);
12036 def_builtin (MASK_ALTIVEC|MASK_VSX, "__builtin_vec_set_v4sf", ftype,
12037 ALTIVEC_BUILTIN_VEC_SET_V4SF);
12039 if (TARGET_VSX)
12041 ftype = build_function_type_list (V2DF_type_node, V2DF_type_node,
12042 double_type_node,
12043 integer_type_node, NULL_TREE);
12044 def_builtin (MASK_VSX, "__builtin_vec_set_v2df", ftype,
12045 VSX_BUILTIN_VEC_SET_V2DF);
12047 ftype = build_function_type_list (V2DI_type_node, V2DI_type_node,
12048 intDI_type_node,
12049 integer_type_node, NULL_TREE);
12050 def_builtin (MASK_VSX, "__builtin_vec_set_v2di", ftype,
12051 VSX_BUILTIN_VEC_SET_V2DI);
12054 /* Access to the vec_extract patterns. */
12055 ftype = build_function_type_list (intSI_type_node, V4SI_type_node,
12056 integer_type_node, NULL_TREE);
12057 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v4si", ftype,
12058 ALTIVEC_BUILTIN_VEC_EXT_V4SI);
12060 ftype = build_function_type_list (intHI_type_node, V8HI_type_node,
12061 integer_type_node, NULL_TREE);
12062 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v8hi", ftype,
12063 ALTIVEC_BUILTIN_VEC_EXT_V8HI);
12065 ftype = build_function_type_list (intQI_type_node, V16QI_type_node,
12066 integer_type_node, NULL_TREE);
12067 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v16qi", ftype,
12068 ALTIVEC_BUILTIN_VEC_EXT_V16QI);
12070 ftype = build_function_type_list (float_type_node, V4SF_type_node,
12071 integer_type_node, NULL_TREE);
12072 def_builtin (MASK_ALTIVEC|MASK_VSX, "__builtin_vec_ext_v4sf", ftype,
12073 ALTIVEC_BUILTIN_VEC_EXT_V4SF);
12075 if (TARGET_VSX)
12077 ftype = build_function_type_list (double_type_node, V2DF_type_node,
12078 integer_type_node, NULL_TREE);
12079 def_builtin (MASK_VSX, "__builtin_vec_ext_v2df", ftype,
12080 VSX_BUILTIN_VEC_EXT_V2DF);
12082 ftype = build_function_type_list (intDI_type_node, V2DI_type_node,
12083 integer_type_node, NULL_TREE);
12084 def_builtin (MASK_VSX, "__builtin_vec_ext_v2di", ftype,
12085 VSX_BUILTIN_VEC_EXT_V2DI);
12089 /* Hash function for builtin functions with up to 3 arguments and a return
12090 type. */
12091 static unsigned
12092 builtin_hash_function (const void *hash_entry)
12094 unsigned ret = 0;
12095 int i;
12096 const struct builtin_hash_struct *bh =
12097 (const struct builtin_hash_struct *) hash_entry;
12099 for (i = 0; i < 4; i++)
12101 ret = (ret * (unsigned)MAX_MACHINE_MODE) + ((unsigned)bh->mode[i]);
12102 ret = (ret * 2) + bh->uns_p[i];
12105 return ret;
12108 /* Compare builtin hash entries H1 and H2 for equivalence. */
12109 static int
12110 builtin_hash_eq (const void *h1, const void *h2)
12112 const struct builtin_hash_struct *p1 = (const struct builtin_hash_struct *) h1;
12113 const struct builtin_hash_struct *p2 = (const struct builtin_hash_struct *) h2;
12115 return ((p1->mode[0] == p2->mode[0])
12116 && (p1->mode[1] == p2->mode[1])
12117 && (p1->mode[2] == p2->mode[2])
12118 && (p1->mode[3] == p2->mode[3])
12119 && (p1->uns_p[0] == p2->uns_p[0])
12120 && (p1->uns_p[1] == p2->uns_p[1])
12121 && (p1->uns_p[2] == p2->uns_p[2])
12122 && (p1->uns_p[3] == p2->uns_p[3]));
12125 /* Map types for builtin functions with an explicit return type and up to 3
12126 arguments. Functions with fewer than 3 arguments use VOIDmode as the type
12127 of the argument. */
12128 static tree
12129 builtin_function_type (enum machine_mode mode_ret, enum machine_mode mode_arg0,
12130 enum machine_mode mode_arg1, enum machine_mode mode_arg2,
12131 enum rs6000_builtins builtin, const char *name)
12133 struct builtin_hash_struct h;
12134 struct builtin_hash_struct *h2;
12135 void **found;
12136 int num_args = 3;
12137 int i;
12138 tree ret_type = NULL_TREE;
12139 tree arg_type[3] = { NULL_TREE, NULL_TREE, NULL_TREE };
12140 tree args;
12142 /* Create builtin_hash_table. */
12143 if (builtin_hash_table == NULL)
12144 builtin_hash_table = htab_create_ggc (1500, builtin_hash_function,
12145 builtin_hash_eq, NULL);
12147 h.type = NULL_TREE;
12148 h.mode[0] = mode_ret;
12149 h.mode[1] = mode_arg0;
12150 h.mode[2] = mode_arg1;
12151 h.mode[3] = mode_arg2;
12152 h.uns_p[0] = 0;
12153 h.uns_p[1] = 0;
12154 h.uns_p[2] = 0;
12155 h.uns_p[3] = 0;
12157 /* If the builtin is a type that produces unsigned results or takes unsigned
12158 arguments, and it is returned as a decl for the vectorizer (such as
12159 widening multiplies, permute), make sure the arguments and return value
12160 are type correct. */
12161 switch (builtin)
12163 /* unsigned 2 argument functions. */
12164 case ALTIVEC_BUILTIN_VMULEUB_UNS:
12165 case ALTIVEC_BUILTIN_VMULEUH_UNS:
12166 case ALTIVEC_BUILTIN_VMULOUB_UNS:
12167 case ALTIVEC_BUILTIN_VMULOUH_UNS:
12168 h.uns_p[0] = 1;
12169 h.uns_p[1] = 1;
12170 h.uns_p[2] = 1;
12171 break;
12173 /* unsigned 3 argument functions. */
12174 case ALTIVEC_BUILTIN_VPERM_16QI_UNS:
12175 case ALTIVEC_BUILTIN_VPERM_8HI_UNS:
12176 case ALTIVEC_BUILTIN_VPERM_4SI_UNS:
12177 case ALTIVEC_BUILTIN_VPERM_2DI_UNS:
12178 case ALTIVEC_BUILTIN_VSEL_16QI_UNS:
12179 case ALTIVEC_BUILTIN_VSEL_8HI_UNS:
12180 case ALTIVEC_BUILTIN_VSEL_4SI_UNS:
12181 case ALTIVEC_BUILTIN_VSEL_2DI_UNS:
12182 case VSX_BUILTIN_VPERM_16QI_UNS:
12183 case VSX_BUILTIN_VPERM_8HI_UNS:
12184 case VSX_BUILTIN_VPERM_4SI_UNS:
12185 case VSX_BUILTIN_VPERM_2DI_UNS:
12186 case VSX_BUILTIN_XXSEL_16QI_UNS:
12187 case VSX_BUILTIN_XXSEL_8HI_UNS:
12188 case VSX_BUILTIN_XXSEL_4SI_UNS:
12189 case VSX_BUILTIN_XXSEL_2DI_UNS:
12190 h.uns_p[0] = 1;
12191 h.uns_p[1] = 1;
12192 h.uns_p[2] = 1;
12193 h.uns_p[3] = 1;
12194 break;
12196 /* signed permute functions with unsigned char mask. */
12197 case ALTIVEC_BUILTIN_VPERM_16QI:
12198 case ALTIVEC_BUILTIN_VPERM_8HI:
12199 case ALTIVEC_BUILTIN_VPERM_4SI:
12200 case ALTIVEC_BUILTIN_VPERM_4SF:
12201 case ALTIVEC_BUILTIN_VPERM_2DI:
12202 case ALTIVEC_BUILTIN_VPERM_2DF:
12203 case VSX_BUILTIN_VPERM_16QI:
12204 case VSX_BUILTIN_VPERM_8HI:
12205 case VSX_BUILTIN_VPERM_4SI:
12206 case VSX_BUILTIN_VPERM_4SF:
12207 case VSX_BUILTIN_VPERM_2DI:
12208 case VSX_BUILTIN_VPERM_2DF:
12209 h.uns_p[3] = 1;
12210 break;
12212 /* unsigned args, signed return. */
12213 case VSX_BUILTIN_XVCVUXDDP_UNS:
12214 case VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF:
12215 h.uns_p[1] = 1;
12216 break;
12218 /* signed args, unsigned return. */
12219 case VSX_BUILTIN_XVCVDPUXDS_UNS:
12220 case VECTOR_BUILTIN_FIXUNS_V4SF_V4SI:
12221 h.uns_p[0] = 1;
12222 break;
12224 default:
12225 break;
12228 /* Figure out how many args are present. */
12229 while (num_args > 0 && h.mode[num_args] == VOIDmode)
12230 num_args--;
12232 if (num_args == 0)
12233 fatal_error ("internal error: builtin function %s had no type", name);
12235 ret_type = builtin_mode_to_type[h.mode[0]][h.uns_p[0]];
12236 if (!ret_type && h.uns_p[0])
12237 ret_type = builtin_mode_to_type[h.mode[0]][0];
12239 if (!ret_type)
12240 fatal_error ("internal error: builtin function %s had an unexpected "
12241 "return type %s", name, GET_MODE_NAME (h.mode[0]));
12243 for (i = 0; i < num_args; i++)
12245 int m = (int) h.mode[i+1];
12246 int uns_p = h.uns_p[i+1];
12248 arg_type[i] = builtin_mode_to_type[m][uns_p];
12249 if (!arg_type[i] && uns_p)
12250 arg_type[i] = builtin_mode_to_type[m][0];
12252 if (!arg_type[i])
12253 fatal_error ("internal error: builtin function %s, argument %d "
12254 "had unexpected argument type %s", name, i,
12255 GET_MODE_NAME (m));
12258 found = htab_find_slot (builtin_hash_table, &h, INSERT);
12259 if (*found == NULL)
12261 h2 = GGC_NEW (struct builtin_hash_struct);
12262 *h2 = h;
12263 *found = (void *)h2;
12264 args = void_list_node;
12266 for (i = num_args - 1; i >= 0; i--)
12267 args = tree_cons (NULL_TREE, arg_type[i], args);
12269 h2->type = build_function_type (ret_type, args);
12272 return ((struct builtin_hash_struct *)(*found))->type;
12275 static void
12276 rs6000_common_init_builtins (void)
12278 const struct builtin_description *d;
12279 size_t i;
12281 tree opaque_ftype_opaque = NULL_TREE;
12282 tree opaque_ftype_opaque_opaque = NULL_TREE;
12283 tree opaque_ftype_opaque_opaque_opaque = NULL_TREE;
12284 tree v2si_ftype_qi = NULL_TREE;
12285 tree v2si_ftype_v2si_qi = NULL_TREE;
12286 tree v2si_ftype_int_qi = NULL_TREE;
12288 if (!TARGET_PAIRED_FLOAT)
12290 builtin_mode_to_type[V2SImode][0] = opaque_V2SI_type_node;
12291 builtin_mode_to_type[V2SFmode][0] = opaque_V2SF_type_node;
12294 /* Add the ternary operators. */
12295 d = bdesc_3arg;
12296 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
12298 tree type;
12299 int mask = d->mask;
12301 if ((mask != 0 && (mask & target_flags) == 0)
12302 || (mask == 0 && !TARGET_PAIRED_FLOAT))
12303 continue;
12305 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
12306 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
12307 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
12308 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
12310 if (! (type = opaque_ftype_opaque_opaque_opaque))
12311 type = opaque_ftype_opaque_opaque_opaque
12312 = build_function_type_list (opaque_V4SI_type_node,
12313 opaque_V4SI_type_node,
12314 opaque_V4SI_type_node,
12315 opaque_V4SI_type_node,
12316 NULL_TREE);
12318 else
12320 enum insn_code icode = d->icode;
12321 if (d->name == 0 || icode == CODE_FOR_nothing)
12322 continue;
12324 type = builtin_function_type (insn_data[icode].operand[0].mode,
12325 insn_data[icode].operand[1].mode,
12326 insn_data[icode].operand[2].mode,
12327 insn_data[icode].operand[3].mode,
12328 d->code, d->name);
12331 def_builtin (d->mask, d->name, type, d->code);
12334 /* Add the binary operators. */
12335 d = bdesc_2arg;
12336 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
12338 enum machine_mode mode0, mode1, mode2;
12339 tree type;
12340 int mask = d->mask;
12342 if ((mask != 0 && (mask & target_flags) == 0)
12343 || (mask == 0 && !TARGET_PAIRED_FLOAT))
12344 continue;
12346 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
12347 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
12348 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
12349 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
12351 if (! (type = opaque_ftype_opaque_opaque))
12352 type = opaque_ftype_opaque_opaque
12353 = build_function_type_list (opaque_V4SI_type_node,
12354 opaque_V4SI_type_node,
12355 opaque_V4SI_type_node,
12356 NULL_TREE);
12358 else
12360 enum insn_code icode = d->icode;
12361 if (d->name == 0 || icode == CODE_FOR_nothing)
12362 continue;
12364 mode0 = insn_data[icode].operand[0].mode;
12365 mode1 = insn_data[icode].operand[1].mode;
12366 mode2 = insn_data[icode].operand[2].mode;
12368 if (mode0 == V2SImode && mode1 == V2SImode && mode2 == QImode)
12370 if (! (type = v2si_ftype_v2si_qi))
12371 type = v2si_ftype_v2si_qi
12372 = build_function_type_list (opaque_V2SI_type_node,
12373 opaque_V2SI_type_node,
12374 char_type_node,
12375 NULL_TREE);
12378 else if (mode0 == V2SImode && GET_MODE_CLASS (mode1) == MODE_INT
12379 && mode2 == QImode)
12381 if (! (type = v2si_ftype_int_qi))
12382 type = v2si_ftype_int_qi
12383 = build_function_type_list (opaque_V2SI_type_node,
12384 integer_type_node,
12385 char_type_node,
12386 NULL_TREE);
12389 else
12390 type = builtin_function_type (mode0, mode1, mode2, VOIDmode,
12391 d->code, d->name);
12394 def_builtin (d->mask, d->name, type, d->code);
12397 /* Add the simple unary operators. */
12398 d = (struct builtin_description *) bdesc_1arg;
12399 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
12401 enum machine_mode mode0, mode1;
12402 tree type;
12403 int mask = d->mask;
12405 if ((mask != 0 && (mask & target_flags) == 0)
12406 || (mask == 0 && !TARGET_PAIRED_FLOAT))
12407 continue;
12409 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
12410 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
12411 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
12412 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
12414 if (! (type = opaque_ftype_opaque))
12415 type = opaque_ftype_opaque
12416 = build_function_type_list (opaque_V4SI_type_node,
12417 opaque_V4SI_type_node,
12418 NULL_TREE);
12420 else
12422 enum insn_code icode = d->icode;
12423 if (d->name == 0 || icode == CODE_FOR_nothing)
12424 continue;
12426 mode0 = insn_data[icode].operand[0].mode;
12427 mode1 = insn_data[icode].operand[1].mode;
12429 if (mode0 == V2SImode && mode1 == QImode)
12431 if (! (type = v2si_ftype_qi))
12432 type = v2si_ftype_qi
12433 = build_function_type_list (opaque_V2SI_type_node,
12434 char_type_node,
12435 NULL_TREE);
12438 else
12439 type = builtin_function_type (mode0, mode1, VOIDmode, VOIDmode,
12440 d->code, d->name);
12443 def_builtin (d->mask, d->name, type, d->code);
12447 static void
12448 rs6000_init_libfuncs (void)
12450 if (DEFAULT_ABI != ABI_V4 && TARGET_XCOFF
12451 && !TARGET_POWER2 && !TARGET_POWERPC)
12453 /* AIX library routines for float->int conversion. */
12454 set_conv_libfunc (sfix_optab, SImode, DFmode, "__itrunc");
12455 set_conv_libfunc (ufix_optab, SImode, DFmode, "__uitrunc");
12456 set_conv_libfunc (sfix_optab, SImode, TFmode, "_qitrunc");
12457 set_conv_libfunc (ufix_optab, SImode, TFmode, "_quitrunc");
12460 if (!TARGET_IEEEQUAD)
12461 /* AIX/Darwin/64-bit Linux quad floating point routines. */
12462 if (!TARGET_XL_COMPAT)
12464 set_optab_libfunc (add_optab, TFmode, "__gcc_qadd");
12465 set_optab_libfunc (sub_optab, TFmode, "__gcc_qsub");
12466 set_optab_libfunc (smul_optab, TFmode, "__gcc_qmul");
12467 set_optab_libfunc (sdiv_optab, TFmode, "__gcc_qdiv");
12469 if (!(TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)))
12471 set_optab_libfunc (neg_optab, TFmode, "__gcc_qneg");
12472 set_optab_libfunc (eq_optab, TFmode, "__gcc_qeq");
12473 set_optab_libfunc (ne_optab, TFmode, "__gcc_qne");
12474 set_optab_libfunc (gt_optab, TFmode, "__gcc_qgt");
12475 set_optab_libfunc (ge_optab, TFmode, "__gcc_qge");
12476 set_optab_libfunc (lt_optab, TFmode, "__gcc_qlt");
12477 set_optab_libfunc (le_optab, TFmode, "__gcc_qle");
12479 set_conv_libfunc (sext_optab, TFmode, SFmode, "__gcc_stoq");
12480 set_conv_libfunc (sext_optab, TFmode, DFmode, "__gcc_dtoq");
12481 set_conv_libfunc (trunc_optab, SFmode, TFmode, "__gcc_qtos");
12482 set_conv_libfunc (trunc_optab, DFmode, TFmode, "__gcc_qtod");
12483 set_conv_libfunc (sfix_optab, SImode, TFmode, "__gcc_qtoi");
12484 set_conv_libfunc (ufix_optab, SImode, TFmode, "__gcc_qtou");
12485 set_conv_libfunc (sfloat_optab, TFmode, SImode, "__gcc_itoq");
12486 set_conv_libfunc (ufloat_optab, TFmode, SImode, "__gcc_utoq");
12489 if (!(TARGET_HARD_FLOAT && TARGET_FPRS))
12490 set_optab_libfunc (unord_optab, TFmode, "__gcc_qunord");
12492 else
12494 set_optab_libfunc (add_optab, TFmode, "_xlqadd");
12495 set_optab_libfunc (sub_optab, TFmode, "_xlqsub");
12496 set_optab_libfunc (smul_optab, TFmode, "_xlqmul");
12497 set_optab_libfunc (sdiv_optab, TFmode, "_xlqdiv");
12499 else
12501 /* 32-bit SVR4 quad floating point routines. */
12503 set_optab_libfunc (add_optab, TFmode, "_q_add");
12504 set_optab_libfunc (sub_optab, TFmode, "_q_sub");
12505 set_optab_libfunc (neg_optab, TFmode, "_q_neg");
12506 set_optab_libfunc (smul_optab, TFmode, "_q_mul");
12507 set_optab_libfunc (sdiv_optab, TFmode, "_q_div");
12508 if (TARGET_PPC_GPOPT || TARGET_POWER2)
12509 set_optab_libfunc (sqrt_optab, TFmode, "_q_sqrt");
12511 set_optab_libfunc (eq_optab, TFmode, "_q_feq");
12512 set_optab_libfunc (ne_optab, TFmode, "_q_fne");
12513 set_optab_libfunc (gt_optab, TFmode, "_q_fgt");
12514 set_optab_libfunc (ge_optab, TFmode, "_q_fge");
12515 set_optab_libfunc (lt_optab, TFmode, "_q_flt");
12516 set_optab_libfunc (le_optab, TFmode, "_q_fle");
12518 set_conv_libfunc (sext_optab, TFmode, SFmode, "_q_stoq");
12519 set_conv_libfunc (sext_optab, TFmode, DFmode, "_q_dtoq");
12520 set_conv_libfunc (trunc_optab, SFmode, TFmode, "_q_qtos");
12521 set_conv_libfunc (trunc_optab, DFmode, TFmode, "_q_qtod");
12522 set_conv_libfunc (sfix_optab, SImode, TFmode, "_q_qtoi");
12523 set_conv_libfunc (ufix_optab, SImode, TFmode, "_q_qtou");
12524 set_conv_libfunc (sfloat_optab, TFmode, SImode, "_q_itoq");
12525 set_conv_libfunc (ufloat_optab, TFmode, SImode, "_q_utoq");
12530 /* Expand a block clear operation, and return 1 if successful. Return 0
12531 if we should let the compiler generate normal code.
12533 operands[0] is the destination
12534 operands[1] is the length
12535 operands[3] is the alignment */
12538 expand_block_clear (rtx operands[])
12540 rtx orig_dest = operands[0];
12541 rtx bytes_rtx = operands[1];
12542 rtx align_rtx = operands[3];
12543 bool constp = (GET_CODE (bytes_rtx) == CONST_INT);
12544 HOST_WIDE_INT align;
12545 HOST_WIDE_INT bytes;
12546 int offset;
12547 int clear_bytes;
12548 int clear_step;
12550 /* If this is not a fixed size move, just call memcpy */
12551 if (! constp)
12552 return 0;
12554 /* This must be a fixed size alignment */
12555 gcc_assert (GET_CODE (align_rtx) == CONST_INT);
12556 align = INTVAL (align_rtx) * BITS_PER_UNIT;
12558 /* Anything to clear? */
12559 bytes = INTVAL (bytes_rtx);
12560 if (bytes <= 0)
12561 return 1;
12563 /* Use the builtin memset after a point, to avoid huge code bloat.
12564 When optimize_size, avoid any significant code bloat; calling
12565 memset is about 4 instructions, so allow for one instruction to
12566 load zero and three to do clearing. */
12567 if (TARGET_ALTIVEC && align >= 128)
12568 clear_step = 16;
12569 else if (TARGET_POWERPC64 && align >= 32)
12570 clear_step = 8;
12571 else if (TARGET_SPE && align >= 64)
12572 clear_step = 8;
12573 else
12574 clear_step = 4;
12576 if (optimize_size && bytes > 3 * clear_step)
12577 return 0;
12578 if (! optimize_size && bytes > 8 * clear_step)
12579 return 0;
12581 for (offset = 0; bytes > 0; offset += clear_bytes, bytes -= clear_bytes)
12583 enum machine_mode mode = BLKmode;
12584 rtx dest;
12586 if (bytes >= 16 && TARGET_ALTIVEC && align >= 128)
12588 clear_bytes = 16;
12589 mode = V4SImode;
12591 else if (bytes >= 8 && TARGET_SPE && align >= 64)
12593 clear_bytes = 8;
12594 mode = V2SImode;
12596 else if (bytes >= 8 && TARGET_POWERPC64
12597 /* 64-bit loads and stores require word-aligned
12598 displacements. */
12599 && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
12601 clear_bytes = 8;
12602 mode = DImode;
12604 else if (bytes >= 4 && (align >= 32 || !STRICT_ALIGNMENT))
12605 { /* move 4 bytes */
12606 clear_bytes = 4;
12607 mode = SImode;
12609 else if (bytes >= 2 && (align >= 16 || !STRICT_ALIGNMENT))
12610 { /* move 2 bytes */
12611 clear_bytes = 2;
12612 mode = HImode;
12614 else /* move 1 byte at a time */
12616 clear_bytes = 1;
12617 mode = QImode;
12620 dest = adjust_address (orig_dest, mode, offset);
12622 emit_move_insn (dest, CONST0_RTX (mode));
12625 return 1;
12629 /* Expand a block move operation, and return 1 if successful. Return 0
12630 if we should let the compiler generate normal code.
12632 operands[0] is the destination
12633 operands[1] is the source
12634 operands[2] is the length
12635 operands[3] is the alignment */
12637 #define MAX_MOVE_REG 4
12640 expand_block_move (rtx operands[])
12642 rtx orig_dest = operands[0];
12643 rtx orig_src = operands[1];
12644 rtx bytes_rtx = operands[2];
12645 rtx align_rtx = operands[3];
12646 int constp = (GET_CODE (bytes_rtx) == CONST_INT);
12647 int align;
12648 int bytes;
12649 int offset;
12650 int move_bytes;
12651 rtx stores[MAX_MOVE_REG];
12652 int num_reg = 0;
12654 /* If this is not a fixed size move, just call memcpy */
12655 if (! constp)
12656 return 0;
12658 /* This must be a fixed size alignment */
12659 gcc_assert (GET_CODE (align_rtx) == CONST_INT);
12660 align = INTVAL (align_rtx) * BITS_PER_UNIT;
12662 /* Anything to move? */
12663 bytes = INTVAL (bytes_rtx);
12664 if (bytes <= 0)
12665 return 1;
12667 /* store_one_arg depends on expand_block_move to handle at least the size of
12668 reg_parm_stack_space. */
12669 if (bytes > (TARGET_POWERPC64 ? 64 : 32))
12670 return 0;
12672 for (offset = 0; bytes > 0; offset += move_bytes, bytes -= move_bytes)
12674 union {
12675 rtx (*movmemsi) (rtx, rtx, rtx, rtx);
12676 rtx (*mov) (rtx, rtx);
12677 } gen_func;
12678 enum machine_mode mode = BLKmode;
12679 rtx src, dest;
12681 /* Altivec first, since it will be faster than a string move
12682 when it applies, and usually not significantly larger. */
12683 if (TARGET_ALTIVEC && bytes >= 16 && align >= 128)
12685 move_bytes = 16;
12686 mode = V4SImode;
12687 gen_func.mov = gen_movv4si;
12689 else if (TARGET_SPE && bytes >= 8 && align >= 64)
12691 move_bytes = 8;
12692 mode = V2SImode;
12693 gen_func.mov = gen_movv2si;
12695 else if (TARGET_STRING
12696 && bytes > 24 /* move up to 32 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]
12703 && ! fixed_regs[11]
12704 && ! fixed_regs[12])
12706 move_bytes = (bytes > 32) ? 32 : bytes;
12707 gen_func.movmemsi = gen_movmemsi_8reg;
12709 else if (TARGET_STRING
12710 && bytes > 16 /* move up to 24 bytes at a time */
12711 && ! fixed_regs[5]
12712 && ! fixed_regs[6]
12713 && ! fixed_regs[7]
12714 && ! fixed_regs[8]
12715 && ! fixed_regs[9]
12716 && ! fixed_regs[10])
12718 move_bytes = (bytes > 24) ? 24 : bytes;
12719 gen_func.movmemsi = gen_movmemsi_6reg;
12721 else if (TARGET_STRING
12722 && bytes > 8 /* move up to 16 bytes at a time */
12723 && ! fixed_regs[5]
12724 && ! fixed_regs[6]
12725 && ! fixed_regs[7]
12726 && ! fixed_regs[8])
12728 move_bytes = (bytes > 16) ? 16 : bytes;
12729 gen_func.movmemsi = gen_movmemsi_4reg;
12731 else if (bytes >= 8 && TARGET_POWERPC64
12732 /* 64-bit loads and stores require word-aligned
12733 displacements. */
12734 && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
12736 move_bytes = 8;
12737 mode = DImode;
12738 gen_func.mov = gen_movdi;
12740 else if (TARGET_STRING && bytes > 4 && !TARGET_POWERPC64)
12741 { /* move up to 8 bytes at a time */
12742 move_bytes = (bytes > 8) ? 8 : bytes;
12743 gen_func.movmemsi = gen_movmemsi_2reg;
12745 else if (bytes >= 4 && (align >= 32 || !STRICT_ALIGNMENT))
12746 { /* move 4 bytes */
12747 move_bytes = 4;
12748 mode = SImode;
12749 gen_func.mov = gen_movsi;
12751 else if (bytes >= 2 && (align >= 16 || !STRICT_ALIGNMENT))
12752 { /* move 2 bytes */
12753 move_bytes = 2;
12754 mode = HImode;
12755 gen_func.mov = gen_movhi;
12757 else if (TARGET_STRING && bytes > 1)
12758 { /* move up to 4 bytes at a time */
12759 move_bytes = (bytes > 4) ? 4 : bytes;
12760 gen_func.movmemsi = gen_movmemsi_1reg;
12762 else /* move 1 byte at a time */
12764 move_bytes = 1;
12765 mode = QImode;
12766 gen_func.mov = gen_movqi;
12769 src = adjust_address (orig_src, mode, offset);
12770 dest = adjust_address (orig_dest, mode, offset);
12772 if (mode != BLKmode)
12774 rtx tmp_reg = gen_reg_rtx (mode);
12776 emit_insn ((*gen_func.mov) (tmp_reg, src));
12777 stores[num_reg++] = (*gen_func.mov) (dest, tmp_reg);
12780 if (mode == BLKmode || num_reg >= MAX_MOVE_REG || bytes == move_bytes)
12782 int i;
12783 for (i = 0; i < num_reg; i++)
12784 emit_insn (stores[i]);
12785 num_reg = 0;
12788 if (mode == BLKmode)
12790 /* Move the address into scratch registers. The movmemsi
12791 patterns require zero offset. */
12792 if (!REG_P (XEXP (src, 0)))
12794 rtx src_reg = copy_addr_to_reg (XEXP (src, 0));
12795 src = replace_equiv_address (src, src_reg);
12797 set_mem_size (src, GEN_INT (move_bytes));
12799 if (!REG_P (XEXP (dest, 0)))
12801 rtx dest_reg = copy_addr_to_reg (XEXP (dest, 0));
12802 dest = replace_equiv_address (dest, dest_reg);
12804 set_mem_size (dest, GEN_INT (move_bytes));
12806 emit_insn ((*gen_func.movmemsi) (dest, src,
12807 GEN_INT (move_bytes & 31),
12808 align_rtx));
12812 return 1;
12816 /* Return a string to perform a load_multiple operation.
12817 operands[0] is the vector.
12818 operands[1] is the source address.
12819 operands[2] is the first destination register. */
12821 const char *
12822 rs6000_output_load_multiple (rtx operands[3])
12824 /* We have to handle the case where the pseudo used to contain the address
12825 is assigned to one of the output registers. */
12826 int i, j;
12827 int words = XVECLEN (operands[0], 0);
12828 rtx xop[10];
12830 if (XVECLEN (operands[0], 0) == 1)
12831 return "{l|lwz} %2,0(%1)";
12833 for (i = 0; i < words; i++)
12834 if (refers_to_regno_p (REGNO (operands[2]) + i,
12835 REGNO (operands[2]) + i + 1, operands[1], 0))
12837 if (i == words-1)
12839 xop[0] = GEN_INT (4 * (words-1));
12840 xop[1] = operands[1];
12841 xop[2] = operands[2];
12842 output_asm_insn ("{lsi|lswi} %2,%1,%0\n\t{l|lwz} %1,%0(%1)", xop);
12843 return "";
12845 else if (i == 0)
12847 xop[0] = GEN_INT (4 * (words-1));
12848 xop[1] = operands[1];
12849 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + 1);
12850 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);
12851 return "";
12853 else
12855 for (j = 0; j < words; j++)
12856 if (j != i)
12858 xop[0] = GEN_INT (j * 4);
12859 xop[1] = operands[1];
12860 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + j);
12861 output_asm_insn ("{l|lwz} %2,%0(%1)", xop);
12863 xop[0] = GEN_INT (i * 4);
12864 xop[1] = operands[1];
12865 output_asm_insn ("{l|lwz} %1,%0(%1)", xop);
12866 return "";
12870 return "{lsi|lswi} %2,%1,%N0";
12874 /* A validation routine: say whether CODE, a condition code, and MODE
12875 match. The other alternatives either don't make sense or should
12876 never be generated. */
12878 void
12879 validate_condition_mode (enum rtx_code code, enum machine_mode mode)
12881 gcc_assert ((GET_RTX_CLASS (code) == RTX_COMPARE
12882 || GET_RTX_CLASS (code) == RTX_COMM_COMPARE)
12883 && GET_MODE_CLASS (mode) == MODE_CC);
12885 /* These don't make sense. */
12886 gcc_assert ((code != GT && code != LT && code != GE && code != LE)
12887 || mode != CCUNSmode);
12889 gcc_assert ((code != GTU && code != LTU && code != GEU && code != LEU)
12890 || mode == CCUNSmode);
12892 gcc_assert (mode == CCFPmode
12893 || (code != ORDERED && code != UNORDERED
12894 && code != UNEQ && code != LTGT
12895 && code != UNGT && code != UNLT
12896 && code != UNGE && code != UNLE));
12898 /* These should never be generated except for
12899 flag_finite_math_only. */
12900 gcc_assert (mode != CCFPmode
12901 || flag_finite_math_only
12902 || (code != LE && code != GE
12903 && code != UNEQ && code != LTGT
12904 && code != UNGT && code != UNLT));
12906 /* These are invalid; the information is not there. */
12907 gcc_assert (mode != CCEQmode || code == EQ || code == NE);
12911 /* Return 1 if ANDOP is a mask that has no bits on that are not in the
12912 mask required to convert the result of a rotate insn into a shift
12913 left insn of SHIFTOP bits. Both are known to be SImode CONST_INT. */
12916 includes_lshift_p (rtx shiftop, rtx andop)
12918 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
12920 shift_mask <<= INTVAL (shiftop);
12922 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
12925 /* Similar, but for right shift. */
12928 includes_rshift_p (rtx shiftop, rtx andop)
12930 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
12932 shift_mask >>= INTVAL (shiftop);
12934 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
12937 /* Return 1 if ANDOP is a mask suitable for use with an rldic insn
12938 to perform a left shift. It must have exactly SHIFTOP least
12939 significant 0's, then one or more 1's, then zero or more 0's. */
12942 includes_rldic_lshift_p (rtx shiftop, rtx andop)
12944 if (GET_CODE (andop) == CONST_INT)
12946 HOST_WIDE_INT c, lsb, shift_mask;
12948 c = INTVAL (andop);
12949 if (c == 0 || c == ~0)
12950 return 0;
12952 shift_mask = ~0;
12953 shift_mask <<= INTVAL (shiftop);
12955 /* Find the least significant one bit. */
12956 lsb = c & -c;
12958 /* It must coincide with the LSB of the shift mask. */
12959 if (-lsb != shift_mask)
12960 return 0;
12962 /* Invert to look for the next transition (if any). */
12963 c = ~c;
12965 /* Remove the low group of ones (originally low group of zeros). */
12966 c &= -lsb;
12968 /* Again find the lsb, and check we have all 1's above. */
12969 lsb = c & -c;
12970 return c == -lsb;
12972 else if (GET_CODE (andop) == CONST_DOUBLE
12973 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
12975 HOST_WIDE_INT low, high, lsb;
12976 HOST_WIDE_INT shift_mask_low, shift_mask_high;
12978 low = CONST_DOUBLE_LOW (andop);
12979 if (HOST_BITS_PER_WIDE_INT < 64)
12980 high = CONST_DOUBLE_HIGH (andop);
12982 if ((low == 0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == 0))
12983 || (low == ~0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0)))
12984 return 0;
12986 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
12988 shift_mask_high = ~0;
12989 if (INTVAL (shiftop) > 32)
12990 shift_mask_high <<= INTVAL (shiftop) - 32;
12992 lsb = high & -high;
12994 if (-lsb != shift_mask_high || INTVAL (shiftop) < 32)
12995 return 0;
12997 high = ~high;
12998 high &= -lsb;
13000 lsb = high & -high;
13001 return high == -lsb;
13004 shift_mask_low = ~0;
13005 shift_mask_low <<= INTVAL (shiftop);
13007 lsb = low & -low;
13009 if (-lsb != shift_mask_low)
13010 return 0;
13012 if (HOST_BITS_PER_WIDE_INT < 64)
13013 high = ~high;
13014 low = ~low;
13015 low &= -lsb;
13017 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
13019 lsb = high & -high;
13020 return high == -lsb;
13023 lsb = low & -low;
13024 return low == -lsb && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0);
13026 else
13027 return 0;
13030 /* Return 1 if ANDOP is a mask suitable for use with an rldicr insn
13031 to perform a left shift. It must have SHIFTOP or more least
13032 significant 0's, with the remainder of the word 1's. */
13035 includes_rldicr_lshift_p (rtx shiftop, rtx andop)
13037 if (GET_CODE (andop) == CONST_INT)
13039 HOST_WIDE_INT c, lsb, shift_mask;
13041 shift_mask = ~0;
13042 shift_mask <<= INTVAL (shiftop);
13043 c = INTVAL (andop);
13045 /* Find the least significant one bit. */
13046 lsb = c & -c;
13048 /* It must be covered by the shift mask.
13049 This test also rejects c == 0. */
13050 if ((lsb & shift_mask) == 0)
13051 return 0;
13053 /* Check we have all 1's above the transition, and reject all 1's. */
13054 return c == -lsb && lsb != 1;
13056 else if (GET_CODE (andop) == CONST_DOUBLE
13057 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
13059 HOST_WIDE_INT low, lsb, shift_mask_low;
13061 low = CONST_DOUBLE_LOW (andop);
13063 if (HOST_BITS_PER_WIDE_INT < 64)
13065 HOST_WIDE_INT high, shift_mask_high;
13067 high = CONST_DOUBLE_HIGH (andop);
13069 if (low == 0)
13071 shift_mask_high = ~0;
13072 if (INTVAL (shiftop) > 32)
13073 shift_mask_high <<= INTVAL (shiftop) - 32;
13075 lsb = high & -high;
13077 if ((lsb & shift_mask_high) == 0)
13078 return 0;
13080 return high == -lsb;
13082 if (high != ~0)
13083 return 0;
13086 shift_mask_low = ~0;
13087 shift_mask_low <<= INTVAL (shiftop);
13089 lsb = low & -low;
13091 if ((lsb & shift_mask_low) == 0)
13092 return 0;
13094 return low == -lsb && lsb != 1;
13096 else
13097 return 0;
13100 /* Return 1 if operands will generate a valid arguments to rlwimi
13101 instruction for insert with right shift in 64-bit mode. The mask may
13102 not start on the first bit or stop on the last bit because wrap-around
13103 effects of instruction do not correspond to semantics of RTL insn. */
13106 insvdi_rshift_rlwimi_p (rtx sizeop, rtx startop, rtx shiftop)
13108 if (INTVAL (startop) > 32
13109 && INTVAL (startop) < 64
13110 && INTVAL (sizeop) > 1
13111 && INTVAL (sizeop) + INTVAL (startop) < 64
13112 && INTVAL (shiftop) > 0
13113 && INTVAL (sizeop) + INTVAL (shiftop) < 32
13114 && (64 - (INTVAL (shiftop) & 63)) >= INTVAL (sizeop))
13115 return 1;
13117 return 0;
13120 /* Return 1 if REGNO (reg1) == REGNO (reg2) - 1 making them candidates
13121 for lfq and stfq insns iff the registers are hard registers. */
13124 registers_ok_for_quad_peep (rtx reg1, rtx reg2)
13126 /* We might have been passed a SUBREG. */
13127 if (GET_CODE (reg1) != REG || GET_CODE (reg2) != REG)
13128 return 0;
13130 /* We might have been passed non floating point registers. */
13131 if (!FP_REGNO_P (REGNO (reg1))
13132 || !FP_REGNO_P (REGNO (reg2)))
13133 return 0;
13135 return (REGNO (reg1) == REGNO (reg2) - 1);
13138 /* Return 1 if addr1 and addr2 are suitable for lfq or stfq insn.
13139 addr1 and addr2 must be in consecutive memory locations
13140 (addr2 == addr1 + 8). */
13143 mems_ok_for_quad_peep (rtx mem1, rtx mem2)
13145 rtx addr1, addr2;
13146 unsigned int reg1, reg2;
13147 int offset1, offset2;
13149 /* The mems cannot be volatile. */
13150 if (MEM_VOLATILE_P (mem1) || MEM_VOLATILE_P (mem2))
13151 return 0;
13153 addr1 = XEXP (mem1, 0);
13154 addr2 = XEXP (mem2, 0);
13156 /* Extract an offset (if used) from the first addr. */
13157 if (GET_CODE (addr1) == PLUS)
13159 /* If not a REG, return zero. */
13160 if (GET_CODE (XEXP (addr1, 0)) != REG)
13161 return 0;
13162 else
13164 reg1 = REGNO (XEXP (addr1, 0));
13165 /* The offset must be constant! */
13166 if (GET_CODE (XEXP (addr1, 1)) != CONST_INT)
13167 return 0;
13168 offset1 = INTVAL (XEXP (addr1, 1));
13171 else if (GET_CODE (addr1) != REG)
13172 return 0;
13173 else
13175 reg1 = REGNO (addr1);
13176 /* This was a simple (mem (reg)) expression. Offset is 0. */
13177 offset1 = 0;
13180 /* And now for the second addr. */
13181 if (GET_CODE (addr2) == PLUS)
13183 /* If not a REG, return zero. */
13184 if (GET_CODE (XEXP (addr2, 0)) != REG)
13185 return 0;
13186 else
13188 reg2 = REGNO (XEXP (addr2, 0));
13189 /* The offset must be constant. */
13190 if (GET_CODE (XEXP (addr2, 1)) != CONST_INT)
13191 return 0;
13192 offset2 = INTVAL (XEXP (addr2, 1));
13195 else if (GET_CODE (addr2) != REG)
13196 return 0;
13197 else
13199 reg2 = REGNO (addr2);
13200 /* This was a simple (mem (reg)) expression. Offset is 0. */
13201 offset2 = 0;
13204 /* Both of these must have the same base register. */
13205 if (reg1 != reg2)
13206 return 0;
13208 /* The offset for the second addr must be 8 more than the first addr. */
13209 if (offset2 != offset1 + 8)
13210 return 0;
13212 /* All the tests passed. addr1 and addr2 are valid for lfq or stfq
13213 instructions. */
13214 return 1;
13219 rs6000_secondary_memory_needed_rtx (enum machine_mode mode)
13221 static bool eliminated = false;
13222 rtx ret;
13224 if (mode != SDmode)
13225 ret = assign_stack_local (mode, GET_MODE_SIZE (mode), 0);
13226 else
13228 rtx mem = cfun->machine->sdmode_stack_slot;
13229 gcc_assert (mem != NULL_RTX);
13231 if (!eliminated)
13233 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
13234 cfun->machine->sdmode_stack_slot = mem;
13235 eliminated = true;
13237 ret = mem;
13240 if (TARGET_DEBUG_ADDR)
13242 fprintf (stderr, "\nrs6000_secondary_memory_needed_rtx, mode %s, rtx:\n",
13243 GET_MODE_NAME (mode));
13244 if (!ret)
13245 fprintf (stderr, "\tNULL_RTX\n");
13246 else
13247 debug_rtx (ret);
13250 return ret;
13253 static tree
13254 rs6000_check_sdmode (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
13256 /* Don't walk into types. */
13257 if (*tp == NULL_TREE || *tp == error_mark_node || TYPE_P (*tp))
13259 *walk_subtrees = 0;
13260 return NULL_TREE;
13263 switch (TREE_CODE (*tp))
13265 case VAR_DECL:
13266 case PARM_DECL:
13267 case FIELD_DECL:
13268 case RESULT_DECL:
13269 case SSA_NAME:
13270 case REAL_CST:
13271 case INDIRECT_REF:
13272 case ALIGN_INDIRECT_REF:
13273 case MISALIGNED_INDIRECT_REF:
13274 case VIEW_CONVERT_EXPR:
13275 if (TYPE_MODE (TREE_TYPE (*tp)) == SDmode)
13276 return *tp;
13277 break;
13278 default:
13279 break;
13282 return NULL_TREE;
13285 enum reload_reg_type {
13286 GPR_REGISTER_TYPE,
13287 VECTOR_REGISTER_TYPE,
13288 OTHER_REGISTER_TYPE
13291 static enum reload_reg_type
13292 rs6000_reload_register_type (enum reg_class rclass)
13294 switch (rclass)
13296 case GENERAL_REGS:
13297 case BASE_REGS:
13298 return GPR_REGISTER_TYPE;
13300 case FLOAT_REGS:
13301 case ALTIVEC_REGS:
13302 case VSX_REGS:
13303 return VECTOR_REGISTER_TYPE;
13305 default:
13306 return OTHER_REGISTER_TYPE;
13310 /* Inform reload about cases where moving X with a mode MODE to a register in
13311 RCLASS requires an extra scratch or immediate register. Return the class
13312 needed for the immediate register.
13314 For VSX and Altivec, we may need a register to convert sp+offset into
13315 reg+sp. */
13317 static enum reg_class
13318 rs6000_secondary_reload (bool in_p,
13319 rtx x,
13320 enum reg_class rclass,
13321 enum machine_mode mode,
13322 secondary_reload_info *sri)
13324 enum reg_class ret = ALL_REGS;
13325 enum insn_code icode;
13326 bool default_p = false;
13328 sri->icode = CODE_FOR_nothing;
13330 /* Convert vector loads and stores into gprs to use an additional base
13331 register. */
13332 icode = rs6000_vector_reload[mode][in_p != false];
13333 if (icode != CODE_FOR_nothing)
13335 ret = NO_REGS;
13336 sri->icode = CODE_FOR_nothing;
13337 sri->extra_cost = 0;
13339 if (GET_CODE (x) == MEM)
13341 rtx addr = XEXP (x, 0);
13343 /* Loads to and stores from gprs can do reg+offset, and wouldn't need
13344 an extra register in that case, but it would need an extra
13345 register if the addressing is reg+reg or (reg+reg)&(-16). */
13346 if (rclass == GENERAL_REGS || rclass == BASE_REGS)
13348 if (!legitimate_indirect_address_p (addr, false)
13349 && !rs6000_legitimate_offset_address_p (TImode, addr, false))
13351 sri->icode = icode;
13352 /* account for splitting the loads, and converting the
13353 address from reg+reg to reg. */
13354 sri->extra_cost = (((TARGET_64BIT) ? 3 : 5)
13355 + ((GET_CODE (addr) == AND) ? 1 : 0));
13358 /* Loads to and stores from vector registers can only do reg+reg
13359 addressing. Altivec registers can also do (reg+reg)&(-16). */
13360 else if (rclass == VSX_REGS || rclass == ALTIVEC_REGS
13361 || rclass == FLOAT_REGS || rclass == NO_REGS)
13363 if (!VECTOR_MEM_ALTIVEC_P (mode)
13364 && GET_CODE (addr) == AND
13365 && GET_CODE (XEXP (addr, 1)) == CONST_INT
13366 && INTVAL (XEXP (addr, 1)) == -16
13367 && (legitimate_indirect_address_p (XEXP (addr, 0), false)
13368 || legitimate_indexed_address_p (XEXP (addr, 0), false)))
13370 sri->icode = icode;
13371 sri->extra_cost = ((GET_CODE (XEXP (addr, 0)) == PLUS)
13372 ? 2 : 1);
13374 else if (!legitimate_indirect_address_p (addr, false)
13375 && (rclass == NO_REGS
13376 || !legitimate_indexed_address_p (addr, false)))
13378 sri->icode = icode;
13379 sri->extra_cost = 1;
13381 else
13382 icode = CODE_FOR_nothing;
13384 /* Any other loads, including to pseudo registers which haven't been
13385 assigned to a register yet, default to require a scratch
13386 register. */
13387 else
13389 sri->icode = icode;
13390 sri->extra_cost = 2;
13393 else if (REG_P (x))
13395 int regno = true_regnum (x);
13397 icode = CODE_FOR_nothing;
13398 if (regno < 0 || regno >= FIRST_PSEUDO_REGISTER)
13399 default_p = true;
13400 else
13402 enum reg_class xclass = REGNO_REG_CLASS (regno);
13403 enum reload_reg_type rtype1 = rs6000_reload_register_type (rclass);
13404 enum reload_reg_type rtype2 = rs6000_reload_register_type (xclass);
13406 /* If memory is needed, use default_secondary_reload to create the
13407 stack slot. */
13408 if (rtype1 != rtype2 || rtype1 == OTHER_REGISTER_TYPE)
13409 default_p = true;
13410 else
13411 ret = NO_REGS;
13414 else
13415 default_p = true;
13417 else
13418 default_p = true;
13420 if (default_p)
13421 ret = default_secondary_reload (in_p, x, rclass, mode, sri);
13423 gcc_assert (ret != ALL_REGS);
13425 if (TARGET_DEBUG_ADDR)
13427 fprintf (stderr,
13428 "\nrs6000_secondary_reload, return %s, in_p = %s, rclass = %s, "
13429 "mode = %s",
13430 reg_class_names[ret],
13431 in_p ? "true" : "false",
13432 reg_class_names[rclass],
13433 GET_MODE_NAME (mode));
13435 if (default_p)
13436 fprintf (stderr, ", default secondary reload");
13438 if (sri->icode != CODE_FOR_nothing)
13439 fprintf (stderr, ", reload func = %s, extra cost = %d\n",
13440 insn_data[sri->icode].name, sri->extra_cost);
13441 else
13442 fprintf (stderr, "\n");
13444 debug_rtx (x);
13447 return ret;
13450 /* Fixup reload addresses for Altivec or VSX loads/stores to change SP+offset
13451 to SP+reg addressing. */
13453 void
13454 rs6000_secondary_reload_inner (rtx reg, rtx mem, rtx scratch, bool store_p)
13456 int regno = true_regnum (reg);
13457 enum machine_mode mode = GET_MODE (reg);
13458 enum reg_class rclass;
13459 rtx addr;
13460 rtx and_op2 = NULL_RTX;
13461 rtx addr_op1;
13462 rtx addr_op2;
13463 rtx scratch_or_premodify = scratch;
13464 rtx and_rtx;
13465 rtx cc_clobber;
13467 if (TARGET_DEBUG_ADDR)
13469 fprintf (stderr, "\nrs6000_secondary_reload_inner, type = %s\n",
13470 store_p ? "store" : "load");
13471 fprintf (stderr, "reg:\n");
13472 debug_rtx (reg);
13473 fprintf (stderr, "mem:\n");
13474 debug_rtx (mem);
13475 fprintf (stderr, "scratch:\n");
13476 debug_rtx (scratch);
13479 gcc_assert (regno >= 0 && regno < FIRST_PSEUDO_REGISTER);
13480 gcc_assert (GET_CODE (mem) == MEM);
13481 rclass = REGNO_REG_CLASS (regno);
13482 addr = XEXP (mem, 0);
13484 switch (rclass)
13486 /* GPRs can handle reg + small constant, all other addresses need to use
13487 the scratch register. */
13488 case GENERAL_REGS:
13489 case BASE_REGS:
13490 if (GET_CODE (addr) == AND)
13492 and_op2 = XEXP (addr, 1);
13493 addr = XEXP (addr, 0);
13496 if (GET_CODE (addr) == PRE_MODIFY)
13498 scratch_or_premodify = XEXP (addr, 0);
13499 gcc_assert (REG_P (scratch_or_premodify));
13500 gcc_assert (GET_CODE (XEXP (addr, 1)) == PLUS);
13501 addr = XEXP (addr, 1);
13504 if (GET_CODE (addr) == PLUS
13505 && (!rs6000_legitimate_offset_address_p (TImode, addr, false)
13506 || and_op2 != NULL_RTX))
13508 addr_op1 = XEXP (addr, 0);
13509 addr_op2 = XEXP (addr, 1);
13510 gcc_assert (legitimate_indirect_address_p (addr_op1, false));
13512 if (!REG_P (addr_op2)
13513 && (GET_CODE (addr_op2) != CONST_INT
13514 || !satisfies_constraint_I (addr_op2)))
13516 if (TARGET_DEBUG_ADDR)
13518 fprintf (stderr,
13519 "\nMove plus addr to register %s, mode = %s: ",
13520 rs6000_reg_names[REGNO (scratch)],
13521 GET_MODE_NAME (mode));
13522 debug_rtx (addr_op2);
13524 rs6000_emit_move (scratch, addr_op2, Pmode);
13525 addr_op2 = scratch;
13528 emit_insn (gen_rtx_SET (VOIDmode,
13529 scratch_or_premodify,
13530 gen_rtx_PLUS (Pmode,
13531 addr_op1,
13532 addr_op2)));
13534 addr = scratch_or_premodify;
13535 scratch_or_premodify = scratch;
13537 else if (!legitimate_indirect_address_p (addr, false)
13538 && !rs6000_legitimate_offset_address_p (TImode, addr, false))
13540 if (TARGET_DEBUG_ADDR)
13542 fprintf (stderr, "\nMove addr to register %s, mode = %s: ",
13543 rs6000_reg_names[REGNO (scratch_or_premodify)],
13544 GET_MODE_NAME (mode));
13545 debug_rtx (addr);
13547 rs6000_emit_move (scratch_or_premodify, addr, Pmode);
13548 addr = scratch_or_premodify;
13549 scratch_or_premodify = scratch;
13551 break;
13553 /* Float/Altivec registers can only handle reg+reg addressing. Move
13554 other addresses into a scratch register. */
13555 case FLOAT_REGS:
13556 case VSX_REGS:
13557 case ALTIVEC_REGS:
13559 /* With float regs, we need to handle the AND ourselves, since we can't
13560 use the Altivec instruction with an implicit AND -16. Allow scalar
13561 loads to float registers to use reg+offset even if VSX. */
13562 if (GET_CODE (addr) == AND
13563 && (rclass != ALTIVEC_REGS || GET_MODE_SIZE (mode) != 16
13564 || GET_CODE (XEXP (addr, 1)) != CONST_INT
13565 || INTVAL (XEXP (addr, 1)) != -16
13566 || !VECTOR_MEM_ALTIVEC_P (mode)))
13568 and_op2 = XEXP (addr, 1);
13569 addr = XEXP (addr, 0);
13572 /* If we aren't using a VSX load, save the PRE_MODIFY register and use it
13573 as the address later. */
13574 if (GET_CODE (addr) == PRE_MODIFY
13575 && (!VECTOR_MEM_VSX_P (mode)
13576 || and_op2 != NULL_RTX
13577 || !legitimate_indexed_address_p (XEXP (addr, 1), false)))
13579 scratch_or_premodify = XEXP (addr, 0);
13580 gcc_assert (legitimate_indirect_address_p (scratch_or_premodify,
13581 false));
13582 gcc_assert (GET_CODE (XEXP (addr, 1)) == PLUS);
13583 addr = XEXP (addr, 1);
13586 if (legitimate_indirect_address_p (addr, false) /* reg */
13587 || legitimate_indexed_address_p (addr, false) /* reg+reg */
13588 || GET_CODE (addr) == PRE_MODIFY /* VSX pre-modify */
13589 || (GET_CODE (addr) == AND /* Altivec memory */
13590 && GET_CODE (XEXP (addr, 1)) == CONST_INT
13591 && INTVAL (XEXP (addr, 1)) == -16
13592 && VECTOR_MEM_ALTIVEC_P (mode))
13593 || (rclass == FLOAT_REGS /* legacy float mem */
13594 && GET_MODE_SIZE (mode) == 8
13595 && and_op2 == NULL_RTX
13596 && scratch_or_premodify == scratch
13597 && rs6000_legitimate_offset_address_p (mode, addr, false)))
13600 else if (GET_CODE (addr) == PLUS)
13602 addr_op1 = XEXP (addr, 0);
13603 addr_op2 = XEXP (addr, 1);
13604 gcc_assert (REG_P (addr_op1));
13606 if (TARGET_DEBUG_ADDR)
13608 fprintf (stderr, "\nMove plus addr to register %s, mode = %s: ",
13609 rs6000_reg_names[REGNO (scratch)], GET_MODE_NAME (mode));
13610 debug_rtx (addr_op2);
13612 rs6000_emit_move (scratch, addr_op2, Pmode);
13613 emit_insn (gen_rtx_SET (VOIDmode,
13614 scratch_or_premodify,
13615 gen_rtx_PLUS (Pmode,
13616 addr_op1,
13617 scratch)));
13618 addr = scratch_or_premodify;
13619 scratch_or_premodify = scratch;
13622 else if (GET_CODE (addr) == SYMBOL_REF || GET_CODE (addr) == CONST
13623 || GET_CODE (addr) == CONST_INT || REG_P (addr))
13625 if (TARGET_DEBUG_ADDR)
13627 fprintf (stderr, "\nMove addr to register %s, mode = %s: ",
13628 rs6000_reg_names[REGNO (scratch_or_premodify)],
13629 GET_MODE_NAME (mode));
13630 debug_rtx (addr);
13633 rs6000_emit_move (scratch_or_premodify, addr, Pmode);
13634 addr = scratch_or_premodify;
13635 scratch_or_premodify = scratch;
13638 else
13639 gcc_unreachable ();
13641 break;
13643 default:
13644 gcc_unreachable ();
13647 /* If the original address involved a pre-modify that we couldn't use the VSX
13648 memory instruction with update, and we haven't taken care of already,
13649 store the address in the pre-modify register and use that as the
13650 address. */
13651 if (scratch_or_premodify != scratch && scratch_or_premodify != addr)
13653 emit_insn (gen_rtx_SET (VOIDmode, scratch_or_premodify, addr));
13654 addr = scratch_or_premodify;
13657 /* If the original address involved an AND -16 and we couldn't use an ALTIVEC
13658 memory instruction, recreate the AND now, including the clobber which is
13659 generated by the general ANDSI3/ANDDI3 patterns for the
13660 andi. instruction. */
13661 if (and_op2 != NULL_RTX)
13663 if (! legitimate_indirect_address_p (addr, false))
13665 emit_insn (gen_rtx_SET (VOIDmode, scratch, addr));
13666 addr = scratch;
13669 if (TARGET_DEBUG_ADDR)
13671 fprintf (stderr, "\nAnd addr to register %s, mode = %s: ",
13672 rs6000_reg_names[REGNO (scratch)], GET_MODE_NAME (mode));
13673 debug_rtx (and_op2);
13676 and_rtx = gen_rtx_SET (VOIDmode,
13677 scratch,
13678 gen_rtx_AND (Pmode,
13679 addr,
13680 and_op2));
13682 cc_clobber = gen_rtx_CLOBBER (CCmode, gen_rtx_SCRATCH (CCmode));
13683 emit_insn (gen_rtx_PARALLEL (VOIDmode,
13684 gen_rtvec (2, and_rtx, cc_clobber)));
13685 addr = scratch;
13688 /* Adjust the address if it changed. */
13689 if (addr != XEXP (mem, 0))
13691 mem = change_address (mem, mode, addr);
13692 if (TARGET_DEBUG_ADDR)
13693 fprintf (stderr, "\nrs6000_secondary_reload_inner, mem adjusted.\n");
13696 /* Now create the move. */
13697 if (store_p)
13698 emit_insn (gen_rtx_SET (VOIDmode, mem, reg));
13699 else
13700 emit_insn (gen_rtx_SET (VOIDmode, reg, mem));
13702 return;
13705 /* Target hook to return the cover classes for Integrated Register Allocator.
13706 Cover classes is a set of non-intersected register classes covering all hard
13707 registers used for register allocation purpose. Any move between two
13708 registers of a cover class should be cheaper than load or store of the
13709 registers. The value is array of register classes with LIM_REG_CLASSES used
13710 as the end marker.
13712 We need two IRA_COVER_CLASSES, one for pre-VSX, and the other for VSX to
13713 account for the Altivec and Floating registers being subsets of the VSX
13714 register set under VSX, but distinct register sets on pre-VSX machines. */
13716 static const enum reg_class *
13717 rs6000_ira_cover_classes (void)
13719 static const enum reg_class cover_pre_vsx[] = IRA_COVER_CLASSES_PRE_VSX;
13720 static const enum reg_class cover_vsx[] = IRA_COVER_CLASSES_VSX;
13722 return (TARGET_VSX) ? cover_vsx : cover_pre_vsx;
13725 /* Allocate a 64-bit stack slot to be used for copying SDmode
13726 values through if this function has any SDmode references. */
13728 static void
13729 rs6000_alloc_sdmode_stack_slot (void)
13731 tree t;
13732 basic_block bb;
13733 gimple_stmt_iterator gsi;
13735 gcc_assert (cfun->machine->sdmode_stack_slot == NULL_RTX);
13737 FOR_EACH_BB (bb)
13738 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
13740 tree ret = walk_gimple_op (gsi_stmt (gsi), rs6000_check_sdmode, NULL);
13741 if (ret)
13743 rtx stack = assign_stack_local (DDmode, GET_MODE_SIZE (DDmode), 0);
13744 cfun->machine->sdmode_stack_slot = adjust_address_nv (stack,
13745 SDmode, 0);
13746 return;
13750 /* Check for any SDmode parameters of the function. */
13751 for (t = DECL_ARGUMENTS (cfun->decl); t; t = TREE_CHAIN (t))
13753 if (TREE_TYPE (t) == error_mark_node)
13754 continue;
13756 if (TYPE_MODE (TREE_TYPE (t)) == SDmode
13757 || TYPE_MODE (DECL_ARG_TYPE (t)) == SDmode)
13759 rtx stack = assign_stack_local (DDmode, GET_MODE_SIZE (DDmode), 0);
13760 cfun->machine->sdmode_stack_slot = adjust_address_nv (stack,
13761 SDmode, 0);
13762 return;
13767 static void
13768 rs6000_instantiate_decls (void)
13770 if (cfun->machine->sdmode_stack_slot != NULL_RTX)
13771 instantiate_decl_rtl (cfun->machine->sdmode_stack_slot);
13774 /* Given an rtx X being reloaded into a reg required to be
13775 in class CLASS, return the class of reg to actually use.
13776 In general this is just CLASS; but on some machines
13777 in some cases it is preferable to use a more restrictive class.
13779 On the RS/6000, we have to return NO_REGS when we want to reload a
13780 floating-point CONST_DOUBLE to force it to be copied to memory.
13782 We also don't want to reload integer values into floating-point
13783 registers if we can at all help it. In fact, this can
13784 cause reload to die, if it tries to generate a reload of CTR
13785 into a FP register and discovers it doesn't have the memory location
13786 required.
13788 ??? Would it be a good idea to have reload do the converse, that is
13789 try to reload floating modes into FP registers if possible?
13792 static enum reg_class
13793 rs6000_preferred_reload_class (rtx x, enum reg_class rclass)
13795 enum machine_mode mode = GET_MODE (x);
13797 if (VECTOR_UNIT_VSX_P (mode)
13798 && x == CONST0_RTX (mode) && VSX_REG_CLASS_P (rclass))
13799 return rclass;
13801 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode)
13802 && (rclass == ALTIVEC_REGS || rclass == VSX_REGS)
13803 && easy_vector_constant (x, mode))
13804 return ALTIVEC_REGS;
13806 if (CONSTANT_P (x) && reg_classes_intersect_p (rclass, FLOAT_REGS))
13807 return NO_REGS;
13809 if (GET_MODE_CLASS (mode) == MODE_INT && rclass == NON_SPECIAL_REGS)
13810 return GENERAL_REGS;
13812 /* For VSX, prefer the traditional registers for DF if the address is of the
13813 form reg+offset because we can use the non-VSX loads. Prefer the Altivec
13814 registers if Altivec is handling the vector operations (i.e. V16QI, V8HI,
13815 and V4SI). */
13816 if (rclass == VSX_REGS && VECTOR_MEM_VSX_P (mode))
13818 if (mode == DFmode && GET_CODE (x) == MEM)
13820 rtx addr = XEXP (x, 0);
13822 if (legitimate_indirect_address_p (addr, false)) /* reg */
13823 return VSX_REGS;
13825 if (legitimate_indexed_address_p (addr, false)) /* reg+reg */
13826 return VSX_REGS;
13828 if (GET_CODE (addr) == PRE_MODIFY
13829 && legitimate_indexed_address_p (XEXP (addr, 0), false))
13830 return VSX_REGS;
13832 return FLOAT_REGS;
13835 if (VECTOR_UNIT_ALTIVEC_P (mode))
13836 return ALTIVEC_REGS;
13838 return rclass;
13841 return rclass;
13844 /* Debug version of rs6000_preferred_reload_class. */
13845 static enum reg_class
13846 rs6000_debug_preferred_reload_class (rtx x, enum reg_class rclass)
13848 enum reg_class ret = rs6000_preferred_reload_class (x, rclass);
13850 fprintf (stderr,
13851 "\nrs6000_preferred_reload_class, return %s, rclass = %s, "
13852 "mode = %s, x:\n",
13853 reg_class_names[ret], reg_class_names[rclass],
13854 GET_MODE_NAME (GET_MODE (x)));
13855 debug_rtx (x);
13857 return ret;
13860 /* If we are copying between FP or AltiVec registers and anything else, we need
13861 a memory location. The exception is when we are targeting ppc64 and the
13862 move to/from fpr to gpr instructions are available. Also, under VSX, you
13863 can copy vector registers from the FP register set to the Altivec register
13864 set and vice versa. */
13866 static bool
13867 rs6000_secondary_memory_needed (enum reg_class class1,
13868 enum reg_class class2,
13869 enum machine_mode mode)
13871 if (class1 == class2)
13872 return false;
13874 /* Under VSX, there are 3 register classes that values could be in (VSX_REGS,
13875 ALTIVEC_REGS, and FLOAT_REGS). We don't need to use memory to copy
13876 between these classes. But we need memory for other things that can go in
13877 FLOAT_REGS like SFmode. */
13878 if (TARGET_VSX
13879 && (VECTOR_MEM_VSX_P (mode) || VECTOR_UNIT_VSX_P (mode))
13880 && (class1 == VSX_REGS || class1 == ALTIVEC_REGS
13881 || class1 == FLOAT_REGS))
13882 return (class2 != VSX_REGS && class2 != ALTIVEC_REGS
13883 && class2 != FLOAT_REGS);
13885 if (class1 == VSX_REGS || class2 == VSX_REGS)
13886 return true;
13888 if (class1 == FLOAT_REGS
13889 && (!TARGET_MFPGPR || !TARGET_POWERPC64
13890 || ((mode != DFmode)
13891 && (mode != DDmode)
13892 && (mode != DImode))))
13893 return true;
13895 if (class2 == FLOAT_REGS
13896 && (!TARGET_MFPGPR || !TARGET_POWERPC64
13897 || ((mode != DFmode)
13898 && (mode != DDmode)
13899 && (mode != DImode))))
13900 return true;
13902 if (class1 == ALTIVEC_REGS || class2 == ALTIVEC_REGS)
13903 return true;
13905 return false;
13908 /* Debug version of rs6000_secondary_memory_needed. */
13909 static bool
13910 rs6000_debug_secondary_memory_needed (enum reg_class class1,
13911 enum reg_class class2,
13912 enum machine_mode mode)
13914 bool ret = rs6000_secondary_memory_needed (class1, class2, mode);
13916 fprintf (stderr,
13917 "rs6000_secondary_memory_needed, return: %s, class1 = %s, "
13918 "class2 = %s, mode = %s\n",
13919 ret ? "true" : "false", reg_class_names[class1],
13920 reg_class_names[class2], GET_MODE_NAME (mode));
13922 return ret;
13925 /* Return the register class of a scratch register needed to copy IN into
13926 or out of a register in RCLASS in MODE. If it can be done directly,
13927 NO_REGS is returned. */
13929 static enum reg_class
13930 rs6000_secondary_reload_class (enum reg_class rclass, enum machine_mode mode,
13931 rtx in)
13933 int regno;
13935 if (TARGET_ELF || (DEFAULT_ABI == ABI_DARWIN
13936 #if TARGET_MACHO
13937 && MACHOPIC_INDIRECT
13938 #endif
13941 /* We cannot copy a symbolic operand directly into anything
13942 other than BASE_REGS for TARGET_ELF. So indicate that a
13943 register from BASE_REGS is needed as an intermediate
13944 register.
13946 On Darwin, pic addresses require a load from memory, which
13947 needs a base register. */
13948 if (rclass != BASE_REGS
13949 && (GET_CODE (in) == SYMBOL_REF
13950 || GET_CODE (in) == HIGH
13951 || GET_CODE (in) == LABEL_REF
13952 || GET_CODE (in) == CONST))
13953 return BASE_REGS;
13956 if (GET_CODE (in) == REG)
13958 regno = REGNO (in);
13959 if (regno >= FIRST_PSEUDO_REGISTER)
13961 regno = true_regnum (in);
13962 if (regno >= FIRST_PSEUDO_REGISTER)
13963 regno = -1;
13966 else if (GET_CODE (in) == SUBREG)
13968 regno = true_regnum (in);
13969 if (regno >= FIRST_PSEUDO_REGISTER)
13970 regno = -1;
13972 else
13973 regno = -1;
13975 /* We can place anything into GENERAL_REGS and can put GENERAL_REGS
13976 into anything. */
13977 if (rclass == GENERAL_REGS || rclass == BASE_REGS
13978 || (regno >= 0 && INT_REGNO_P (regno)))
13979 return NO_REGS;
13981 /* Constants, memory, and FP registers can go into FP registers. */
13982 if ((regno == -1 || FP_REGNO_P (regno))
13983 && (rclass == FLOAT_REGS || rclass == NON_SPECIAL_REGS))
13984 return (mode != SDmode) ? NO_REGS : GENERAL_REGS;
13986 /* Memory, and FP/altivec registers can go into fp/altivec registers under
13987 VSX. */
13988 if (TARGET_VSX
13989 && (regno == -1 || VSX_REGNO_P (regno))
13990 && VSX_REG_CLASS_P (rclass))
13991 return NO_REGS;
13993 /* Memory, and AltiVec registers can go into AltiVec registers. */
13994 if ((regno == -1 || ALTIVEC_REGNO_P (regno))
13995 && rclass == ALTIVEC_REGS)
13996 return NO_REGS;
13998 /* We can copy among the CR registers. */
13999 if ((rclass == CR_REGS || rclass == CR0_REGS)
14000 && regno >= 0 && CR_REGNO_P (regno))
14001 return NO_REGS;
14003 /* Otherwise, we need GENERAL_REGS. */
14004 return GENERAL_REGS;
14007 /* Debug version of rs6000_secondary_reload_class. */
14008 static enum reg_class
14009 rs6000_debug_secondary_reload_class (enum reg_class rclass,
14010 enum machine_mode mode, rtx in)
14012 enum reg_class ret = rs6000_secondary_reload_class (rclass, mode, in);
14013 fprintf (stderr,
14014 "\nrs6000_secondary_reload_class, return %s, rclass = %s, "
14015 "mode = %s, input rtx:\n",
14016 reg_class_names[ret], reg_class_names[rclass],
14017 GET_MODE_NAME (mode));
14018 debug_rtx (in);
14020 return ret;
14023 /* Return nonzero if for CLASS a mode change from FROM to TO is invalid. */
14025 static bool
14026 rs6000_cannot_change_mode_class (enum machine_mode from,
14027 enum machine_mode to,
14028 enum reg_class rclass)
14030 unsigned from_size = GET_MODE_SIZE (from);
14031 unsigned to_size = GET_MODE_SIZE (to);
14033 if (from_size != to_size)
14035 enum reg_class xclass = (TARGET_VSX) ? VSX_REGS : FLOAT_REGS;
14036 return ((from_size < 8 || to_size < 8 || TARGET_IEEEQUAD)
14037 && reg_classes_intersect_p (xclass, rclass));
14040 if (TARGET_E500_DOUBLE
14041 && ((((to) == DFmode) + ((from) == DFmode)) == 1
14042 || (((to) == TFmode) + ((from) == TFmode)) == 1
14043 || (((to) == DDmode) + ((from) == DDmode)) == 1
14044 || (((to) == TDmode) + ((from) == TDmode)) == 1
14045 || (((to) == DImode) + ((from) == DImode)) == 1))
14046 return true;
14048 /* Since the VSX register set includes traditional floating point registers
14049 and altivec registers, just check for the size being different instead of
14050 trying to check whether the modes are vector modes. Otherwise it won't
14051 allow say DF and DI to change classes. */
14052 if (TARGET_VSX && VSX_REG_CLASS_P (rclass))
14053 return (from_size != 8 && from_size != 16);
14055 if (TARGET_ALTIVEC && rclass == ALTIVEC_REGS
14056 && (ALTIVEC_VECTOR_MODE (from) + ALTIVEC_VECTOR_MODE (to)) == 1)
14057 return true;
14059 if (TARGET_SPE && (SPE_VECTOR_MODE (from) + SPE_VECTOR_MODE (to)) == 1
14060 && reg_classes_intersect_p (GENERAL_REGS, rclass))
14061 return true;
14063 return false;
14066 /* Debug version of rs6000_cannot_change_mode_class. */
14067 static bool
14068 rs6000_debug_cannot_change_mode_class (enum machine_mode from,
14069 enum machine_mode to,
14070 enum reg_class rclass)
14072 bool ret = rs6000_cannot_change_mode_class (from, to, rclass);
14074 fprintf (stderr,
14075 "rs6000_cannot_change_mode_class, return %s, from = %s, "
14076 "to = %s, rclass = %s\n",
14077 ret ? "true" : "false",
14078 GET_MODE_NAME (from), GET_MODE_NAME (to),
14079 reg_class_names[rclass]);
14081 return ret;
14084 /* Given a comparison operation, return the bit number in CCR to test. We
14085 know this is a valid comparison.
14087 SCC_P is 1 if this is for an scc. That means that %D will have been
14088 used instead of %C, so the bits will be in different places.
14090 Return -1 if OP isn't a valid comparison for some reason. */
14093 ccr_bit (rtx op, int scc_p)
14095 enum rtx_code code = GET_CODE (op);
14096 enum machine_mode cc_mode;
14097 int cc_regnum;
14098 int base_bit;
14099 rtx reg;
14101 if (!COMPARISON_P (op))
14102 return -1;
14104 reg = XEXP (op, 0);
14106 gcc_assert (GET_CODE (reg) == REG && CR_REGNO_P (REGNO (reg)));
14108 cc_mode = GET_MODE (reg);
14109 cc_regnum = REGNO (reg);
14110 base_bit = 4 * (cc_regnum - CR0_REGNO);
14112 validate_condition_mode (code, cc_mode);
14114 /* When generating a sCOND operation, only positive conditions are
14115 allowed. */
14116 gcc_assert (!scc_p
14117 || code == EQ || code == GT || code == LT || code == UNORDERED
14118 || code == GTU || code == LTU);
14120 switch (code)
14122 case NE:
14123 return scc_p ? base_bit + 3 : base_bit + 2;
14124 case EQ:
14125 return base_bit + 2;
14126 case GT: case GTU: case UNLE:
14127 return base_bit + 1;
14128 case LT: case LTU: case UNGE:
14129 return base_bit;
14130 case ORDERED: case UNORDERED:
14131 return base_bit + 3;
14133 case GE: case GEU:
14134 /* If scc, we will have done a cror to put the bit in the
14135 unordered position. So test that bit. For integer, this is ! LT
14136 unless this is an scc insn. */
14137 return scc_p ? base_bit + 3 : base_bit;
14139 case LE: case LEU:
14140 return scc_p ? base_bit + 3 : base_bit + 1;
14142 default:
14143 gcc_unreachable ();
14147 /* Return the GOT register. */
14150 rs6000_got_register (rtx value ATTRIBUTE_UNUSED)
14152 /* The second flow pass currently (June 1999) can't update
14153 regs_ever_live without disturbing other parts of the compiler, so
14154 update it here to make the prolog/epilogue code happy. */
14155 if (!can_create_pseudo_p ()
14156 && !df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM))
14157 df_set_regs_ever_live (RS6000_PIC_OFFSET_TABLE_REGNUM, true);
14159 crtl->uses_pic_offset_table = 1;
14161 return pic_offset_table_rtx;
14164 /* Function to init struct machine_function.
14165 This will be called, via a pointer variable,
14166 from push_function_context. */
14168 static struct machine_function *
14169 rs6000_init_machine_status (void)
14171 return GGC_CNEW (machine_function);
14174 /* These macros test for integers and extract the low-order bits. */
14175 #define INT_P(X) \
14176 ((GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST_DOUBLE) \
14177 && GET_MODE (X) == VOIDmode)
14179 #define INT_LOWPART(X) \
14180 (GET_CODE (X) == CONST_INT ? INTVAL (X) : CONST_DOUBLE_LOW (X))
14183 extract_MB (rtx op)
14185 int i;
14186 unsigned long val = INT_LOWPART (op);
14188 /* If the high bit is zero, the value is the first 1 bit we find
14189 from the left. */
14190 if ((val & 0x80000000) == 0)
14192 gcc_assert (val & 0xffffffff);
14194 i = 1;
14195 while (((val <<= 1) & 0x80000000) == 0)
14196 ++i;
14197 return i;
14200 /* If the high bit is set and the low bit is not, or the mask is all
14201 1's, the value is zero. */
14202 if ((val & 1) == 0 || (val & 0xffffffff) == 0xffffffff)
14203 return 0;
14205 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
14206 from the right. */
14207 i = 31;
14208 while (((val >>= 1) & 1) != 0)
14209 --i;
14211 return i;
14215 extract_ME (rtx op)
14217 int i;
14218 unsigned long val = INT_LOWPART (op);
14220 /* If the low bit is zero, the value is the first 1 bit we find from
14221 the right. */
14222 if ((val & 1) == 0)
14224 gcc_assert (val & 0xffffffff);
14226 i = 30;
14227 while (((val >>= 1) & 1) == 0)
14228 --i;
14230 return i;
14233 /* If the low bit is set and the high bit is not, or the mask is all
14234 1's, the value is 31. */
14235 if ((val & 0x80000000) == 0 || (val & 0xffffffff) == 0xffffffff)
14236 return 31;
14238 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
14239 from the left. */
14240 i = 0;
14241 while (((val <<= 1) & 0x80000000) != 0)
14242 ++i;
14244 return i;
14247 /* Locate some local-dynamic symbol still in use by this function
14248 so that we can print its name in some tls_ld pattern. */
14250 static const char *
14251 rs6000_get_some_local_dynamic_name (void)
14253 rtx insn;
14255 if (cfun->machine->some_ld_name)
14256 return cfun->machine->some_ld_name;
14258 for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
14259 if (INSN_P (insn)
14260 && for_each_rtx (&PATTERN (insn),
14261 rs6000_get_some_local_dynamic_name_1, 0))
14262 return cfun->machine->some_ld_name;
14264 gcc_unreachable ();
14267 /* Helper function for rs6000_get_some_local_dynamic_name. */
14269 static int
14270 rs6000_get_some_local_dynamic_name_1 (rtx *px, void *data ATTRIBUTE_UNUSED)
14272 rtx x = *px;
14274 if (GET_CODE (x) == SYMBOL_REF)
14276 const char *str = XSTR (x, 0);
14277 if (SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_DYNAMIC)
14279 cfun->machine->some_ld_name = str;
14280 return 1;
14284 return 0;
14287 /* Write out a function code label. */
14289 void
14290 rs6000_output_function_entry (FILE *file, const char *fname)
14292 if (fname[0] != '.')
14294 switch (DEFAULT_ABI)
14296 default:
14297 gcc_unreachable ();
14299 case ABI_AIX:
14300 if (DOT_SYMBOLS)
14301 putc ('.', file);
14302 else
14303 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "L.");
14304 break;
14306 case ABI_V4:
14307 case ABI_DARWIN:
14308 break;
14311 if (TARGET_AIX)
14312 RS6000_OUTPUT_BASENAME (file, fname);
14313 else
14314 assemble_name (file, fname);
14317 /* Print an operand. Recognize special options, documented below. */
14319 #if TARGET_ELF
14320 #define SMALL_DATA_RELOC ((rs6000_sdata == SDATA_EABI) ? "sda21" : "sdarel")
14321 #define SMALL_DATA_REG ((rs6000_sdata == SDATA_EABI) ? 0 : 13)
14322 #else
14323 #define SMALL_DATA_RELOC "sda21"
14324 #define SMALL_DATA_REG 0
14325 #endif
14327 void
14328 print_operand (FILE *file, rtx x, int code)
14330 int i;
14331 HOST_WIDE_INT val;
14332 unsigned HOST_WIDE_INT uval;
14334 switch (code)
14336 case '.':
14337 /* Write out an instruction after the call which may be replaced
14338 with glue code by the loader. This depends on the AIX version. */
14339 asm_fprintf (file, RS6000_CALL_GLUE);
14340 return;
14342 /* %a is output_address. */
14344 case 'A':
14345 /* If X is a constant integer whose low-order 5 bits are zero,
14346 write 'l'. Otherwise, write 'r'. This is a kludge to fix a bug
14347 in the AIX assembler where "sri" with a zero shift count
14348 writes a trash instruction. */
14349 if (GET_CODE (x) == CONST_INT && (INTVAL (x) & 31) == 0)
14350 putc ('l', file);
14351 else
14352 putc ('r', file);
14353 return;
14355 case 'b':
14356 /* If constant, low-order 16 bits of constant, unsigned.
14357 Otherwise, write normally. */
14358 if (INT_P (x))
14359 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 0xffff);
14360 else
14361 print_operand (file, x, 0);
14362 return;
14364 case 'B':
14365 /* If the low-order bit is zero, write 'r'; otherwise, write 'l'
14366 for 64-bit mask direction. */
14367 putc (((INT_LOWPART (x) & 1) == 0 ? 'r' : 'l'), file);
14368 return;
14370 /* %c is output_addr_const if a CONSTANT_ADDRESS_P, otherwise
14371 output_operand. */
14373 case 'c':
14374 /* X is a CR register. Print the number of the GT bit of the CR. */
14375 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
14376 output_operand_lossage ("invalid %%c value");
14377 else
14378 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 1);
14379 return;
14381 case 'D':
14382 /* Like 'J' but get to the GT bit only. */
14383 gcc_assert (GET_CODE (x) == REG);
14385 /* Bit 1 is GT bit. */
14386 i = 4 * (REGNO (x) - CR0_REGNO) + 1;
14388 /* Add one for shift count in rlinm for scc. */
14389 fprintf (file, "%d", i + 1);
14390 return;
14392 case 'E':
14393 /* X is a CR register. Print the number of the EQ bit of the CR */
14394 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
14395 output_operand_lossage ("invalid %%E value");
14396 else
14397 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 2);
14398 return;
14400 case 'f':
14401 /* X is a CR register. Print the shift count needed to move it
14402 to the high-order four bits. */
14403 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
14404 output_operand_lossage ("invalid %%f value");
14405 else
14406 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO));
14407 return;
14409 case 'F':
14410 /* Similar, but print the count for the rotate in the opposite
14411 direction. */
14412 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
14413 output_operand_lossage ("invalid %%F value");
14414 else
14415 fprintf (file, "%d", 32 - 4 * (REGNO (x) - CR0_REGNO));
14416 return;
14418 case 'G':
14419 /* X is a constant integer. If it is negative, print "m",
14420 otherwise print "z". This is to make an aze or ame insn. */
14421 if (GET_CODE (x) != CONST_INT)
14422 output_operand_lossage ("invalid %%G value");
14423 else if (INTVAL (x) >= 0)
14424 putc ('z', file);
14425 else
14426 putc ('m', file);
14427 return;
14429 case 'h':
14430 /* If constant, output low-order five bits. Otherwise, write
14431 normally. */
14432 if (INT_P (x))
14433 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 31);
14434 else
14435 print_operand (file, x, 0);
14436 return;
14438 case 'H':
14439 /* If constant, output low-order six bits. Otherwise, write
14440 normally. */
14441 if (INT_P (x))
14442 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 63);
14443 else
14444 print_operand (file, x, 0);
14445 return;
14447 case 'I':
14448 /* Print `i' if this is a constant, else nothing. */
14449 if (INT_P (x))
14450 putc ('i', file);
14451 return;
14453 case 'j':
14454 /* Write the bit number in CCR for jump. */
14455 i = ccr_bit (x, 0);
14456 if (i == -1)
14457 output_operand_lossage ("invalid %%j code");
14458 else
14459 fprintf (file, "%d", i);
14460 return;
14462 case 'J':
14463 /* Similar, but add one for shift count in rlinm for scc and pass
14464 scc flag to `ccr_bit'. */
14465 i = ccr_bit (x, 1);
14466 if (i == -1)
14467 output_operand_lossage ("invalid %%J code");
14468 else
14469 /* If we want bit 31, write a shift count of zero, not 32. */
14470 fprintf (file, "%d", i == 31 ? 0 : i + 1);
14471 return;
14473 case 'k':
14474 /* X must be a constant. Write the 1's complement of the
14475 constant. */
14476 if (! INT_P (x))
14477 output_operand_lossage ("invalid %%k value");
14478 else
14479 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ~ INT_LOWPART (x));
14480 return;
14482 case 'K':
14483 /* X must be a symbolic constant on ELF. Write an
14484 expression suitable for an 'addi' that adds in the low 16
14485 bits of the MEM. */
14486 if (GET_CODE (x) != CONST)
14488 print_operand_address (file, x);
14489 fputs ("@l", file);
14491 else
14493 if (GET_CODE (XEXP (x, 0)) != PLUS
14494 || (GET_CODE (XEXP (XEXP (x, 0), 0)) != SYMBOL_REF
14495 && GET_CODE (XEXP (XEXP (x, 0), 0)) != LABEL_REF)
14496 || GET_CODE (XEXP (XEXP (x, 0), 1)) != CONST_INT)
14497 output_operand_lossage ("invalid %%K value");
14498 print_operand_address (file, XEXP (XEXP (x, 0), 0));
14499 fputs ("@l", file);
14500 /* For GNU as, there must be a non-alphanumeric character
14501 between 'l' and the number. The '-' is added by
14502 print_operand() already. */
14503 if (INTVAL (XEXP (XEXP (x, 0), 1)) >= 0)
14504 fputs ("+", file);
14505 print_operand (file, XEXP (XEXP (x, 0), 1), 0);
14507 return;
14509 /* %l is output_asm_label. */
14511 case 'L':
14512 /* Write second word of DImode or DFmode reference. Works on register
14513 or non-indexed memory only. */
14514 if (GET_CODE (x) == REG)
14515 fputs (reg_names[REGNO (x) + 1], file);
14516 else if (GET_CODE (x) == MEM)
14518 /* Handle possible auto-increment. Since it is pre-increment and
14519 we have already done it, we can just use an offset of word. */
14520 if (GET_CODE (XEXP (x, 0)) == PRE_INC
14521 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
14522 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
14523 UNITS_PER_WORD));
14524 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
14525 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
14526 UNITS_PER_WORD));
14527 else
14528 output_address (XEXP (adjust_address_nv (x, SImode,
14529 UNITS_PER_WORD),
14530 0));
14532 if (small_data_operand (x, GET_MODE (x)))
14533 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
14534 reg_names[SMALL_DATA_REG]);
14536 return;
14538 case 'm':
14539 /* MB value for a mask operand. */
14540 if (! mask_operand (x, SImode))
14541 output_operand_lossage ("invalid %%m value");
14543 fprintf (file, "%d", extract_MB (x));
14544 return;
14546 case 'M':
14547 /* ME value for a mask operand. */
14548 if (! mask_operand (x, SImode))
14549 output_operand_lossage ("invalid %%M value");
14551 fprintf (file, "%d", extract_ME (x));
14552 return;
14554 /* %n outputs the negative of its operand. */
14556 case 'N':
14557 /* Write the number of elements in the vector times 4. */
14558 if (GET_CODE (x) != PARALLEL)
14559 output_operand_lossage ("invalid %%N value");
14560 else
14561 fprintf (file, "%d", XVECLEN (x, 0) * 4);
14562 return;
14564 case 'O':
14565 /* Similar, but subtract 1 first. */
14566 if (GET_CODE (x) != PARALLEL)
14567 output_operand_lossage ("invalid %%O value");
14568 else
14569 fprintf (file, "%d", (XVECLEN (x, 0) - 1) * 4);
14570 return;
14572 case 'p':
14573 /* X is a CONST_INT that is a power of two. Output the logarithm. */
14574 if (! INT_P (x)
14575 || INT_LOWPART (x) < 0
14576 || (i = exact_log2 (INT_LOWPART (x))) < 0)
14577 output_operand_lossage ("invalid %%p value");
14578 else
14579 fprintf (file, "%d", i);
14580 return;
14582 case 'P':
14583 /* The operand must be an indirect memory reference. The result
14584 is the register name. */
14585 if (GET_CODE (x) != MEM || GET_CODE (XEXP (x, 0)) != REG
14586 || REGNO (XEXP (x, 0)) >= 32)
14587 output_operand_lossage ("invalid %%P value");
14588 else
14589 fputs (reg_names[REGNO (XEXP (x, 0))], file);
14590 return;
14592 case 'q':
14593 /* This outputs the logical code corresponding to a boolean
14594 expression. The expression may have one or both operands
14595 negated (if one, only the first one). For condition register
14596 logical operations, it will also treat the negated
14597 CR codes as NOTs, but not handle NOTs of them. */
14599 const char *const *t = 0;
14600 const char *s;
14601 enum rtx_code code = GET_CODE (x);
14602 static const char * const tbl[3][3] = {
14603 { "and", "andc", "nor" },
14604 { "or", "orc", "nand" },
14605 { "xor", "eqv", "xor" } };
14607 if (code == AND)
14608 t = tbl[0];
14609 else if (code == IOR)
14610 t = tbl[1];
14611 else if (code == XOR)
14612 t = tbl[2];
14613 else
14614 output_operand_lossage ("invalid %%q value");
14616 if (GET_CODE (XEXP (x, 0)) != NOT)
14617 s = t[0];
14618 else
14620 if (GET_CODE (XEXP (x, 1)) == NOT)
14621 s = t[2];
14622 else
14623 s = t[1];
14626 fputs (s, file);
14628 return;
14630 case 'Q':
14631 if (TARGET_MFCRF)
14632 fputc (',', file);
14633 /* FALLTHRU */
14634 else
14635 return;
14637 case 'R':
14638 /* X is a CR register. Print the mask for `mtcrf'. */
14639 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
14640 output_operand_lossage ("invalid %%R value");
14641 else
14642 fprintf (file, "%d", 128 >> (REGNO (x) - CR0_REGNO));
14643 return;
14645 case 's':
14646 /* Low 5 bits of 32 - value */
14647 if (! INT_P (x))
14648 output_operand_lossage ("invalid %%s value");
14649 else
14650 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (32 - INT_LOWPART (x)) & 31);
14651 return;
14653 case 'S':
14654 /* PowerPC64 mask position. All 0's is excluded.
14655 CONST_INT 32-bit mask is considered sign-extended so any
14656 transition must occur within the CONST_INT, not on the boundary. */
14657 if (! mask64_operand (x, DImode))
14658 output_operand_lossage ("invalid %%S value");
14660 uval = INT_LOWPART (x);
14662 if (uval & 1) /* Clear Left */
14664 #if HOST_BITS_PER_WIDE_INT > 64
14665 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
14666 #endif
14667 i = 64;
14669 else /* Clear Right */
14671 uval = ~uval;
14672 #if HOST_BITS_PER_WIDE_INT > 64
14673 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
14674 #endif
14675 i = 63;
14677 while (uval != 0)
14678 --i, uval >>= 1;
14679 gcc_assert (i >= 0);
14680 fprintf (file, "%d", i);
14681 return;
14683 case 't':
14684 /* Like 'J' but get to the OVERFLOW/UNORDERED bit. */
14685 gcc_assert (GET_CODE (x) == REG && GET_MODE (x) == CCmode);
14687 /* Bit 3 is OV bit. */
14688 i = 4 * (REGNO (x) - CR0_REGNO) + 3;
14690 /* If we want bit 31, write a shift count of zero, not 32. */
14691 fprintf (file, "%d", i == 31 ? 0 : i + 1);
14692 return;
14694 case 'T':
14695 /* Print the symbolic name of a branch target register. */
14696 if (GET_CODE (x) != REG || (REGNO (x) != LR_REGNO
14697 && REGNO (x) != CTR_REGNO))
14698 output_operand_lossage ("invalid %%T value");
14699 else if (REGNO (x) == LR_REGNO)
14700 fputs (TARGET_NEW_MNEMONICS ? "lr" : "r", file);
14701 else
14702 fputs ("ctr", file);
14703 return;
14705 case 'u':
14706 /* High-order 16 bits of constant for use in unsigned operand. */
14707 if (! INT_P (x))
14708 output_operand_lossage ("invalid %%u value");
14709 else
14710 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
14711 (INT_LOWPART (x) >> 16) & 0xffff);
14712 return;
14714 case 'v':
14715 /* High-order 16 bits of constant for use in signed operand. */
14716 if (! INT_P (x))
14717 output_operand_lossage ("invalid %%v value");
14718 else
14719 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
14720 (INT_LOWPART (x) >> 16) & 0xffff);
14721 return;
14723 case 'U':
14724 /* Print `u' if this has an auto-increment or auto-decrement. */
14725 if (GET_CODE (x) == MEM
14726 && (GET_CODE (XEXP (x, 0)) == PRE_INC
14727 || GET_CODE (XEXP (x, 0)) == PRE_DEC
14728 || GET_CODE (XEXP (x, 0)) == PRE_MODIFY))
14729 putc ('u', file);
14730 return;
14732 case 'V':
14733 /* Print the trap code for this operand. */
14734 switch (GET_CODE (x))
14736 case EQ:
14737 fputs ("eq", file); /* 4 */
14738 break;
14739 case NE:
14740 fputs ("ne", file); /* 24 */
14741 break;
14742 case LT:
14743 fputs ("lt", file); /* 16 */
14744 break;
14745 case LE:
14746 fputs ("le", file); /* 20 */
14747 break;
14748 case GT:
14749 fputs ("gt", file); /* 8 */
14750 break;
14751 case GE:
14752 fputs ("ge", file); /* 12 */
14753 break;
14754 case LTU:
14755 fputs ("llt", file); /* 2 */
14756 break;
14757 case LEU:
14758 fputs ("lle", file); /* 6 */
14759 break;
14760 case GTU:
14761 fputs ("lgt", file); /* 1 */
14762 break;
14763 case GEU:
14764 fputs ("lge", file); /* 5 */
14765 break;
14766 default:
14767 gcc_unreachable ();
14769 break;
14771 case 'w':
14772 /* If constant, low-order 16 bits of constant, signed. Otherwise, write
14773 normally. */
14774 if (INT_P (x))
14775 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
14776 ((INT_LOWPART (x) & 0xffff) ^ 0x8000) - 0x8000);
14777 else
14778 print_operand (file, x, 0);
14779 return;
14781 case 'W':
14782 /* MB value for a PowerPC64 rldic operand. */
14783 val = (GET_CODE (x) == CONST_INT
14784 ? INTVAL (x) : CONST_DOUBLE_HIGH (x));
14786 if (val < 0)
14787 i = -1;
14788 else
14789 for (i = 0; i < HOST_BITS_PER_WIDE_INT; i++)
14790 if ((val <<= 1) < 0)
14791 break;
14793 #if HOST_BITS_PER_WIDE_INT == 32
14794 if (GET_CODE (x) == CONST_INT && i >= 0)
14795 i += 32; /* zero-extend high-part was all 0's */
14796 else if (GET_CODE (x) == CONST_DOUBLE && i == 32)
14798 val = CONST_DOUBLE_LOW (x);
14800 gcc_assert (val);
14801 if (val < 0)
14802 --i;
14803 else
14804 for ( ; i < 64; i++)
14805 if ((val <<= 1) < 0)
14806 break;
14808 #endif
14810 fprintf (file, "%d", i + 1);
14811 return;
14813 case 'x':
14814 /* X is a FPR or Altivec register used in a VSX context. */
14815 if (GET_CODE (x) != REG || !VSX_REGNO_P (REGNO (x)))
14816 output_operand_lossage ("invalid %%x value");
14817 else
14819 int reg = REGNO (x);
14820 int vsx_reg = (FP_REGNO_P (reg)
14821 ? reg - 32
14822 : reg - FIRST_ALTIVEC_REGNO + 32);
14824 #ifdef TARGET_REGNAMES
14825 if (TARGET_REGNAMES)
14826 fprintf (file, "%%vs%d", vsx_reg);
14827 else
14828 #endif
14829 fprintf (file, "%d", vsx_reg);
14831 return;
14833 case 'X':
14834 if (GET_CODE (x) == MEM
14835 && (legitimate_indexed_address_p (XEXP (x, 0), 0)
14836 || (GET_CODE (XEXP (x, 0)) == PRE_MODIFY
14837 && legitimate_indexed_address_p (XEXP (XEXP (x, 0), 1), 0))))
14838 putc ('x', file);
14839 return;
14841 case 'Y':
14842 /* Like 'L', for third word of TImode */
14843 if (GET_CODE (x) == REG)
14844 fputs (reg_names[REGNO (x) + 2], file);
14845 else if (GET_CODE (x) == MEM)
14847 if (GET_CODE (XEXP (x, 0)) == PRE_INC
14848 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
14849 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
14850 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
14851 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
14852 else
14853 output_address (XEXP (adjust_address_nv (x, SImode, 8), 0));
14854 if (small_data_operand (x, GET_MODE (x)))
14855 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
14856 reg_names[SMALL_DATA_REG]);
14858 return;
14860 case 'z':
14861 /* X is a SYMBOL_REF. Write out the name preceded by a
14862 period and without any trailing data in brackets. Used for function
14863 names. If we are configured for System V (or the embedded ABI) on
14864 the PowerPC, do not emit the period, since those systems do not use
14865 TOCs and the like. */
14866 gcc_assert (GET_CODE (x) == SYMBOL_REF);
14868 /* Mark the decl as referenced so that cgraph will output the
14869 function. */
14870 if (SYMBOL_REF_DECL (x))
14871 mark_decl_referenced (SYMBOL_REF_DECL (x));
14873 /* For macho, check to see if we need a stub. */
14874 if (TARGET_MACHO)
14876 const char *name = XSTR (x, 0);
14877 #if TARGET_MACHO
14878 if (MACHOPIC_INDIRECT
14879 && machopic_classify_symbol (x) == MACHOPIC_UNDEFINED_FUNCTION)
14880 name = machopic_indirection_name (x, /*stub_p=*/true);
14881 #endif
14882 assemble_name (file, name);
14884 else if (!DOT_SYMBOLS)
14885 assemble_name (file, XSTR (x, 0));
14886 else
14887 rs6000_output_function_entry (file, XSTR (x, 0));
14888 return;
14890 case 'Z':
14891 /* Like 'L', for last word of TImode. */
14892 if (GET_CODE (x) == REG)
14893 fputs (reg_names[REGNO (x) + 3], file);
14894 else if (GET_CODE (x) == MEM)
14896 if (GET_CODE (XEXP (x, 0)) == PRE_INC
14897 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
14898 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
14899 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
14900 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
14901 else
14902 output_address (XEXP (adjust_address_nv (x, SImode, 12), 0));
14903 if (small_data_operand (x, GET_MODE (x)))
14904 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
14905 reg_names[SMALL_DATA_REG]);
14907 return;
14909 /* Print AltiVec or SPE memory operand. */
14910 case 'y':
14912 rtx tmp;
14914 gcc_assert (GET_CODE (x) == MEM);
14916 tmp = XEXP (x, 0);
14918 /* Ugly hack because %y is overloaded. */
14919 if ((TARGET_SPE || TARGET_E500_DOUBLE)
14920 && (GET_MODE_SIZE (GET_MODE (x)) == 8
14921 || GET_MODE (x) == TFmode
14922 || GET_MODE (x) == TImode))
14924 /* Handle [reg]. */
14925 if (GET_CODE (tmp) == REG)
14927 fprintf (file, "0(%s)", reg_names[REGNO (tmp)]);
14928 break;
14930 /* Handle [reg+UIMM]. */
14931 else if (GET_CODE (tmp) == PLUS &&
14932 GET_CODE (XEXP (tmp, 1)) == CONST_INT)
14934 int x;
14936 gcc_assert (GET_CODE (XEXP (tmp, 0)) == REG);
14938 x = INTVAL (XEXP (tmp, 1));
14939 fprintf (file, "%d(%s)", x, reg_names[REGNO (XEXP (tmp, 0))]);
14940 break;
14943 /* Fall through. Must be [reg+reg]. */
14945 if (VECTOR_MEM_ALTIVEC_P (GET_MODE (x))
14946 && GET_CODE (tmp) == AND
14947 && GET_CODE (XEXP (tmp, 1)) == CONST_INT
14948 && INTVAL (XEXP (tmp, 1)) == -16)
14949 tmp = XEXP (tmp, 0);
14950 else if (VECTOR_MEM_VSX_P (GET_MODE (x))
14951 && GET_CODE (tmp) == PRE_MODIFY)
14952 tmp = XEXP (tmp, 1);
14953 if (GET_CODE (tmp) == REG)
14954 fprintf (file, "0,%s", reg_names[REGNO (tmp)]);
14955 else
14957 if (!GET_CODE (tmp) == PLUS
14958 || !REG_P (XEXP (tmp, 0))
14959 || !REG_P (XEXP (tmp, 1)))
14961 output_operand_lossage ("invalid %%y value, try using the 'Z' constraint");
14962 break;
14965 if (REGNO (XEXP (tmp, 0)) == 0)
14966 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 1)) ],
14967 reg_names[ REGNO (XEXP (tmp, 0)) ]);
14968 else
14969 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 0)) ],
14970 reg_names[ REGNO (XEXP (tmp, 1)) ]);
14972 break;
14975 case 0:
14976 if (GET_CODE (x) == REG)
14977 fprintf (file, "%s", reg_names[REGNO (x)]);
14978 else if (GET_CODE (x) == MEM)
14980 /* We need to handle PRE_INC and PRE_DEC here, since we need to
14981 know the width from the mode. */
14982 if (GET_CODE (XEXP (x, 0)) == PRE_INC)
14983 fprintf (file, "%d(%s)", GET_MODE_SIZE (GET_MODE (x)),
14984 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
14985 else if (GET_CODE (XEXP (x, 0)) == PRE_DEC)
14986 fprintf (file, "%d(%s)", - GET_MODE_SIZE (GET_MODE (x)),
14987 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
14988 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
14989 output_address (XEXP (XEXP (x, 0), 1));
14990 else
14991 output_address (XEXP (x, 0));
14993 else
14994 output_addr_const (file, x);
14995 return;
14997 case '&':
14998 assemble_name (file, rs6000_get_some_local_dynamic_name ());
14999 return;
15001 default:
15002 output_operand_lossage ("invalid %%xn code");
15006 /* Print the address of an operand. */
15008 void
15009 print_operand_address (FILE *file, rtx x)
15011 if (GET_CODE (x) == REG)
15012 fprintf (file, "0(%s)", reg_names[ REGNO (x) ]);
15013 else if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST
15014 || GET_CODE (x) == LABEL_REF)
15016 output_addr_const (file, x);
15017 if (small_data_operand (x, GET_MODE (x)))
15018 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
15019 reg_names[SMALL_DATA_REG]);
15020 else
15021 gcc_assert (!TARGET_TOC);
15023 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == REG)
15025 gcc_assert (REG_P (XEXP (x, 0)));
15026 if (REGNO (XEXP (x, 0)) == 0)
15027 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 1)) ],
15028 reg_names[ REGNO (XEXP (x, 0)) ]);
15029 else
15030 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 0)) ],
15031 reg_names[ REGNO (XEXP (x, 1)) ]);
15033 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == CONST_INT)
15034 fprintf (file, HOST_WIDE_INT_PRINT_DEC "(%s)",
15035 INTVAL (XEXP (x, 1)), reg_names[ REGNO (XEXP (x, 0)) ]);
15036 #if TARGET_ELF
15037 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
15038 && CONSTANT_P (XEXP (x, 1)))
15040 output_addr_const (file, XEXP (x, 1));
15041 fprintf (file, "@l(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
15043 #endif
15044 #if TARGET_MACHO
15045 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
15046 && CONSTANT_P (XEXP (x, 1)))
15048 fprintf (file, "lo16(");
15049 output_addr_const (file, XEXP (x, 1));
15050 fprintf (file, ")(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
15052 #endif
15053 else if (legitimate_constant_pool_address_p (x))
15055 output_addr_const (file, XEXP (x, 1));
15056 fprintf (file, "(%s)", reg_names[REGNO (XEXP (x, 0))]);
15058 else
15059 gcc_unreachable ();
15062 /* Implement OUTPUT_ADDR_CONST_EXTRA for address X. */
15064 bool
15065 rs6000_output_addr_const_extra (FILE *file, rtx x)
15067 if (GET_CODE (x) == UNSPEC)
15068 switch (XINT (x, 1))
15070 case UNSPEC_TOCREL:
15071 x = XVECEXP (x, 0, 0);
15072 gcc_assert (GET_CODE (x) == SYMBOL_REF);
15073 output_addr_const (file, x);
15074 if (!TARGET_AIX || (TARGET_ELF && TARGET_MINIMAL_TOC))
15076 putc ('-', file);
15077 assemble_name (file, toc_label_name);
15079 else if (TARGET_ELF)
15080 fputs ("@toc", file);
15081 return true;
15083 #if TARGET_MACHO
15084 case UNSPEC_MACHOPIC_OFFSET:
15085 output_addr_const (file, XVECEXP (x, 0, 0));
15086 putc ('-', file);
15087 machopic_output_function_base_name (file);
15088 return true;
15089 #endif
15091 return false;
15094 /* Target hook for assembling integer objects. The PowerPC version has
15095 to handle fixup entries for relocatable code if RELOCATABLE_NEEDS_FIXUP
15096 is defined. It also needs to handle DI-mode objects on 64-bit
15097 targets. */
15099 static bool
15100 rs6000_assemble_integer (rtx x, unsigned int size, int aligned_p)
15102 #ifdef RELOCATABLE_NEEDS_FIXUP
15103 /* Special handling for SI values. */
15104 if (RELOCATABLE_NEEDS_FIXUP && size == 4 && aligned_p)
15106 static int recurse = 0;
15108 /* For -mrelocatable, we mark all addresses that need to be fixed up
15109 in the .fixup section. */
15110 if (TARGET_RELOCATABLE
15111 && in_section != toc_section
15112 && in_section != text_section
15113 && !unlikely_text_section_p (in_section)
15114 && !recurse
15115 && GET_CODE (x) != CONST_INT
15116 && GET_CODE (x) != CONST_DOUBLE
15117 && CONSTANT_P (x))
15119 char buf[256];
15121 recurse = 1;
15122 ASM_GENERATE_INTERNAL_LABEL (buf, "LCP", fixuplabelno);
15123 fixuplabelno++;
15124 ASM_OUTPUT_LABEL (asm_out_file, buf);
15125 fprintf (asm_out_file, "\t.long\t(");
15126 output_addr_const (asm_out_file, x);
15127 fprintf (asm_out_file, ")@fixup\n");
15128 fprintf (asm_out_file, "\t.section\t\".fixup\",\"aw\"\n");
15129 ASM_OUTPUT_ALIGN (asm_out_file, 2);
15130 fprintf (asm_out_file, "\t.long\t");
15131 assemble_name (asm_out_file, buf);
15132 fprintf (asm_out_file, "\n\t.previous\n");
15133 recurse = 0;
15134 return true;
15136 /* Remove initial .'s to turn a -mcall-aixdesc function
15137 address into the address of the descriptor, not the function
15138 itself. */
15139 else if (GET_CODE (x) == SYMBOL_REF
15140 && XSTR (x, 0)[0] == '.'
15141 && DEFAULT_ABI == ABI_AIX)
15143 const char *name = XSTR (x, 0);
15144 while (*name == '.')
15145 name++;
15147 fprintf (asm_out_file, "\t.long\t%s\n", name);
15148 return true;
15151 #endif /* RELOCATABLE_NEEDS_FIXUP */
15152 return default_assemble_integer (x, size, aligned_p);
15155 #ifdef HAVE_GAS_HIDDEN
15156 /* Emit an assembler directive to set symbol visibility for DECL to
15157 VISIBILITY_TYPE. */
15159 static void
15160 rs6000_assemble_visibility (tree decl, int vis)
15162 /* Functions need to have their entry point symbol visibility set as
15163 well as their descriptor symbol visibility. */
15164 if (DEFAULT_ABI == ABI_AIX
15165 && DOT_SYMBOLS
15166 && TREE_CODE (decl) == FUNCTION_DECL)
15168 static const char * const visibility_types[] = {
15169 NULL, "internal", "hidden", "protected"
15172 const char *name, *type;
15174 name = ((* targetm.strip_name_encoding)
15175 (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))));
15176 type = visibility_types[vis];
15178 fprintf (asm_out_file, "\t.%s\t%s\n", type, name);
15179 fprintf (asm_out_file, "\t.%s\t.%s\n", type, name);
15181 else
15182 default_assemble_visibility (decl, vis);
15184 #endif
15186 enum rtx_code
15187 rs6000_reverse_condition (enum machine_mode mode, enum rtx_code code)
15189 /* Reversal of FP compares takes care -- an ordered compare
15190 becomes an unordered compare and vice versa. */
15191 if (mode == CCFPmode
15192 && (!flag_finite_math_only
15193 || code == UNLT || code == UNLE || code == UNGT || code == UNGE
15194 || code == UNEQ || code == LTGT))
15195 return reverse_condition_maybe_unordered (code);
15196 else
15197 return reverse_condition (code);
15200 /* Generate a compare for CODE. Return a brand-new rtx that
15201 represents the result of the compare. */
15203 static rtx
15204 rs6000_generate_compare (rtx cmp, enum machine_mode mode)
15206 enum machine_mode comp_mode;
15207 rtx compare_result;
15208 enum rtx_code code = GET_CODE (cmp);
15209 rtx op0 = XEXP (cmp, 0);
15210 rtx op1 = XEXP (cmp, 1);
15212 if (FLOAT_MODE_P (mode))
15213 comp_mode = CCFPmode;
15214 else if (code == GTU || code == LTU
15215 || code == GEU || code == LEU)
15216 comp_mode = CCUNSmode;
15217 else if ((code == EQ || code == NE)
15218 && GET_CODE (op0) == SUBREG
15219 && GET_CODE (op1) == SUBREG
15220 && SUBREG_PROMOTED_UNSIGNED_P (op0)
15221 && SUBREG_PROMOTED_UNSIGNED_P (op1))
15222 /* These are unsigned values, perhaps there will be a later
15223 ordering compare that can be shared with this one.
15224 Unfortunately we cannot detect the signedness of the operands
15225 for non-subregs. */
15226 comp_mode = CCUNSmode;
15227 else
15228 comp_mode = CCmode;
15230 /* First, the compare. */
15231 compare_result = gen_reg_rtx (comp_mode);
15233 /* E500 FP compare instructions on the GPRs. Yuck! */
15234 if ((!TARGET_FPRS && TARGET_HARD_FLOAT)
15235 && FLOAT_MODE_P (mode))
15237 rtx cmp, or_result, compare_result2;
15238 enum machine_mode op_mode = GET_MODE (op0);
15240 if (op_mode == VOIDmode)
15241 op_mode = GET_MODE (op1);
15243 /* The E500 FP compare instructions toggle the GT bit (CR bit 1) only.
15244 This explains the following mess. */
15246 switch (code)
15248 case EQ: case UNEQ: case NE: case LTGT:
15249 switch (op_mode)
15251 case SFmode:
15252 cmp = (flag_finite_math_only && !flag_trapping_math)
15253 ? gen_tstsfeq_gpr (compare_result, op0, op1)
15254 : gen_cmpsfeq_gpr (compare_result, op0, op1);
15255 break;
15257 case DFmode:
15258 cmp = (flag_finite_math_only && !flag_trapping_math)
15259 ? gen_tstdfeq_gpr (compare_result, op0, op1)
15260 : gen_cmpdfeq_gpr (compare_result, op0, op1);
15261 break;
15263 case TFmode:
15264 cmp = (flag_finite_math_only && !flag_trapping_math)
15265 ? gen_tsttfeq_gpr (compare_result, op0, op1)
15266 : gen_cmptfeq_gpr (compare_result, op0, op1);
15267 break;
15269 default:
15270 gcc_unreachable ();
15272 break;
15274 case GT: case GTU: case UNGT: case UNGE: case GE: case GEU:
15275 switch (op_mode)
15277 case SFmode:
15278 cmp = (flag_finite_math_only && !flag_trapping_math)
15279 ? gen_tstsfgt_gpr (compare_result, op0, op1)
15280 : gen_cmpsfgt_gpr (compare_result, op0, op1);
15281 break;
15283 case DFmode:
15284 cmp = (flag_finite_math_only && !flag_trapping_math)
15285 ? gen_tstdfgt_gpr (compare_result, op0, op1)
15286 : gen_cmpdfgt_gpr (compare_result, op0, op1);
15287 break;
15289 case TFmode:
15290 cmp = (flag_finite_math_only && !flag_trapping_math)
15291 ? gen_tsttfgt_gpr (compare_result, op0, op1)
15292 : gen_cmptfgt_gpr (compare_result, op0, op1);
15293 break;
15295 default:
15296 gcc_unreachable ();
15298 break;
15300 case LT: case LTU: case UNLT: case UNLE: case LE: case LEU:
15301 switch (op_mode)
15303 case SFmode:
15304 cmp = (flag_finite_math_only && !flag_trapping_math)
15305 ? gen_tstsflt_gpr (compare_result, op0, op1)
15306 : gen_cmpsflt_gpr (compare_result, op0, op1);
15307 break;
15309 case DFmode:
15310 cmp = (flag_finite_math_only && !flag_trapping_math)
15311 ? gen_tstdflt_gpr (compare_result, op0, op1)
15312 : gen_cmpdflt_gpr (compare_result, op0, op1);
15313 break;
15315 case TFmode:
15316 cmp = (flag_finite_math_only && !flag_trapping_math)
15317 ? gen_tsttflt_gpr (compare_result, op0, op1)
15318 : gen_cmptflt_gpr (compare_result, op0, op1);
15319 break;
15321 default:
15322 gcc_unreachable ();
15324 break;
15325 default:
15326 gcc_unreachable ();
15329 /* Synthesize LE and GE from LT/GT || EQ. */
15330 if (code == LE || code == GE || code == LEU || code == GEU)
15332 emit_insn (cmp);
15334 switch (code)
15336 case LE: code = LT; break;
15337 case GE: code = GT; break;
15338 case LEU: code = LT; break;
15339 case GEU: code = GT; break;
15340 default: gcc_unreachable ();
15343 compare_result2 = gen_reg_rtx (CCFPmode);
15345 /* Do the EQ. */
15346 switch (op_mode)
15348 case SFmode:
15349 cmp = (flag_finite_math_only && !flag_trapping_math)
15350 ? gen_tstsfeq_gpr (compare_result2, op0, op1)
15351 : gen_cmpsfeq_gpr (compare_result2, op0, op1);
15352 break;
15354 case DFmode:
15355 cmp = (flag_finite_math_only && !flag_trapping_math)
15356 ? gen_tstdfeq_gpr (compare_result2, op0, op1)
15357 : gen_cmpdfeq_gpr (compare_result2, op0, op1);
15358 break;
15360 case TFmode:
15361 cmp = (flag_finite_math_only && !flag_trapping_math)
15362 ? gen_tsttfeq_gpr (compare_result2, op0, op1)
15363 : gen_cmptfeq_gpr (compare_result2, op0, op1);
15364 break;
15366 default:
15367 gcc_unreachable ();
15369 emit_insn (cmp);
15371 /* OR them together. */
15372 or_result = gen_reg_rtx (CCFPmode);
15373 cmp = gen_e500_cr_ior_compare (or_result, compare_result,
15374 compare_result2);
15375 compare_result = or_result;
15376 code = EQ;
15378 else
15380 if (code == NE || code == LTGT)
15381 code = NE;
15382 else
15383 code = EQ;
15386 emit_insn (cmp);
15388 else
15390 /* Generate XLC-compatible TFmode compare as PARALLEL with extra
15391 CLOBBERs to match cmptf_internal2 pattern. */
15392 if (comp_mode == CCFPmode && TARGET_XL_COMPAT
15393 && GET_MODE (op0) == TFmode
15394 && !TARGET_IEEEQUAD
15395 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128)
15396 emit_insn (gen_rtx_PARALLEL (VOIDmode,
15397 gen_rtvec (9,
15398 gen_rtx_SET (VOIDmode,
15399 compare_result,
15400 gen_rtx_COMPARE (comp_mode, op0, op1)),
15401 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15402 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15403 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15404 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15405 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15406 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15407 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15408 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)))));
15409 else if (GET_CODE (op1) == UNSPEC
15410 && XINT (op1, 1) == UNSPEC_SP_TEST)
15412 rtx op1b = XVECEXP (op1, 0, 0);
15413 comp_mode = CCEQmode;
15414 compare_result = gen_reg_rtx (CCEQmode);
15415 if (TARGET_64BIT)
15416 emit_insn (gen_stack_protect_testdi (compare_result, op0, op1b));
15417 else
15418 emit_insn (gen_stack_protect_testsi (compare_result, op0, op1b));
15420 else
15421 emit_insn (gen_rtx_SET (VOIDmode, compare_result,
15422 gen_rtx_COMPARE (comp_mode, op0, op1)));
15425 /* Some kinds of FP comparisons need an OR operation;
15426 under flag_finite_math_only we don't bother. */
15427 if (FLOAT_MODE_P (mode)
15428 && !flag_finite_math_only
15429 && !(TARGET_HARD_FLOAT && !TARGET_FPRS)
15430 && (code == LE || code == GE
15431 || code == UNEQ || code == LTGT
15432 || code == UNGT || code == UNLT))
15434 enum rtx_code or1, or2;
15435 rtx or1_rtx, or2_rtx, compare2_rtx;
15436 rtx or_result = gen_reg_rtx (CCEQmode);
15438 switch (code)
15440 case LE: or1 = LT; or2 = EQ; break;
15441 case GE: or1 = GT; or2 = EQ; break;
15442 case UNEQ: or1 = UNORDERED; or2 = EQ; break;
15443 case LTGT: or1 = LT; or2 = GT; break;
15444 case UNGT: or1 = UNORDERED; or2 = GT; break;
15445 case UNLT: or1 = UNORDERED; or2 = LT; break;
15446 default: gcc_unreachable ();
15448 validate_condition_mode (or1, comp_mode);
15449 validate_condition_mode (or2, comp_mode);
15450 or1_rtx = gen_rtx_fmt_ee (or1, SImode, compare_result, const0_rtx);
15451 or2_rtx = gen_rtx_fmt_ee (or2, SImode, compare_result, const0_rtx);
15452 compare2_rtx = gen_rtx_COMPARE (CCEQmode,
15453 gen_rtx_IOR (SImode, or1_rtx, or2_rtx),
15454 const_true_rtx);
15455 emit_insn (gen_rtx_SET (VOIDmode, or_result, compare2_rtx));
15457 compare_result = or_result;
15458 code = EQ;
15461 validate_condition_mode (code, GET_MODE (compare_result));
15463 return gen_rtx_fmt_ee (code, VOIDmode, compare_result, const0_rtx);
15467 /* Emit the RTL for an sCOND pattern. */
15469 void
15470 rs6000_emit_sISEL (enum machine_mode mode, rtx operands[])
15472 rtx condition_rtx;
15473 enum machine_mode op_mode;
15474 enum rtx_code cond_code;
15475 rtx result = operands[0];
15477 condition_rtx = rs6000_generate_compare (operands[1], mode);
15478 cond_code = GET_CODE (condition_rtx);
15480 op_mode = GET_MODE (XEXP (operands[1], 0));
15481 if (op_mode == VOIDmode)
15482 op_mode = GET_MODE (XEXP (operands[1], 1));
15484 if (TARGET_POWERPC64 && GET_MODE (result) == DImode)
15486 PUT_MODE (condition_rtx, DImode);
15487 if (cond_code == GEU || cond_code == GTU || cond_code == LEU
15488 || cond_code == LTU)
15489 emit_insn (gen_isel_unsigned_di (result, condition_rtx,
15490 force_reg (DImode, const1_rtx),
15491 force_reg (DImode, const0_rtx),
15492 XEXP (condition_rtx, 0)));
15493 else
15494 emit_insn (gen_isel_signed_di (result, condition_rtx,
15495 force_reg (DImode, const1_rtx),
15496 force_reg (DImode, const0_rtx),
15497 XEXP (condition_rtx, 0)));
15499 else
15501 PUT_MODE (condition_rtx, SImode);
15502 if (cond_code == GEU || cond_code == GTU || cond_code == LEU
15503 || cond_code == LTU)
15504 emit_insn (gen_isel_unsigned_si (result, condition_rtx,
15505 force_reg (SImode, const1_rtx),
15506 force_reg (SImode, const0_rtx),
15507 XEXP (condition_rtx, 0)));
15508 else
15509 emit_insn (gen_isel_signed_si (result, condition_rtx,
15510 force_reg (SImode, const1_rtx),
15511 force_reg (SImode, const0_rtx),
15512 XEXP (condition_rtx, 0)));
15516 void
15517 rs6000_emit_sCOND (enum machine_mode mode, rtx operands[])
15519 rtx condition_rtx;
15520 enum machine_mode op_mode;
15521 enum rtx_code cond_code;
15522 rtx result = operands[0];
15524 if (TARGET_ISEL && (mode == SImode || mode == DImode))
15526 rs6000_emit_sISEL (mode, operands);
15527 return;
15530 condition_rtx = rs6000_generate_compare (operands[1], mode);
15531 cond_code = GET_CODE (condition_rtx);
15533 if (FLOAT_MODE_P (mode)
15534 && !TARGET_FPRS && TARGET_HARD_FLOAT)
15536 rtx t;
15538 PUT_MODE (condition_rtx, SImode);
15539 t = XEXP (condition_rtx, 0);
15541 gcc_assert (cond_code == NE || cond_code == EQ);
15543 if (cond_code == NE)
15544 emit_insn (gen_e500_flip_gt_bit (t, t));
15546 emit_insn (gen_move_from_CR_gt_bit (result, t));
15547 return;
15550 if (cond_code == NE
15551 || cond_code == GE || cond_code == LE
15552 || cond_code == GEU || cond_code == LEU
15553 || cond_code == ORDERED || cond_code == UNGE || cond_code == UNLE)
15555 rtx not_result = gen_reg_rtx (CCEQmode);
15556 rtx not_op, rev_cond_rtx;
15557 enum machine_mode cc_mode;
15559 cc_mode = GET_MODE (XEXP (condition_rtx, 0));
15561 rev_cond_rtx = gen_rtx_fmt_ee (rs6000_reverse_condition (cc_mode, cond_code),
15562 SImode, XEXP (condition_rtx, 0), const0_rtx);
15563 not_op = gen_rtx_COMPARE (CCEQmode, rev_cond_rtx, const0_rtx);
15564 emit_insn (gen_rtx_SET (VOIDmode, not_result, not_op));
15565 condition_rtx = gen_rtx_EQ (VOIDmode, not_result, const0_rtx);
15568 op_mode = GET_MODE (XEXP (operands[1], 0));
15569 if (op_mode == VOIDmode)
15570 op_mode = GET_MODE (XEXP (operands[1], 1));
15572 if (TARGET_POWERPC64 && (op_mode == DImode || FLOAT_MODE_P (mode)))
15574 PUT_MODE (condition_rtx, DImode);
15575 convert_move (result, condition_rtx, 0);
15577 else
15579 PUT_MODE (condition_rtx, SImode);
15580 emit_insn (gen_rtx_SET (VOIDmode, result, condition_rtx));
15584 /* Emit a branch of kind CODE to location LOC. */
15586 void
15587 rs6000_emit_cbranch (enum machine_mode mode, rtx operands[])
15589 rtx condition_rtx, loc_ref;
15591 condition_rtx = rs6000_generate_compare (operands[0], mode);
15592 loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands[3]);
15593 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
15594 gen_rtx_IF_THEN_ELSE (VOIDmode, condition_rtx,
15595 loc_ref, pc_rtx)));
15598 /* Return the string to output a conditional branch to LABEL, which is
15599 the operand number of the label, or -1 if the branch is really a
15600 conditional return.
15602 OP is the conditional expression. XEXP (OP, 0) is assumed to be a
15603 condition code register and its mode specifies what kind of
15604 comparison we made.
15606 REVERSED is nonzero if we should reverse the sense of the comparison.
15608 INSN is the insn. */
15610 char *
15611 output_cbranch (rtx op, const char *label, int reversed, rtx insn)
15613 static char string[64];
15614 enum rtx_code code = GET_CODE (op);
15615 rtx cc_reg = XEXP (op, 0);
15616 enum machine_mode mode = GET_MODE (cc_reg);
15617 int cc_regno = REGNO (cc_reg) - CR0_REGNO;
15618 int need_longbranch = label != NULL && get_attr_length (insn) == 8;
15619 int really_reversed = reversed ^ need_longbranch;
15620 char *s = string;
15621 const char *ccode;
15622 const char *pred;
15623 rtx note;
15625 validate_condition_mode (code, mode);
15627 /* Work out which way this really branches. We could use
15628 reverse_condition_maybe_unordered here always but this
15629 makes the resulting assembler clearer. */
15630 if (really_reversed)
15632 /* Reversal of FP compares takes care -- an ordered compare
15633 becomes an unordered compare and vice versa. */
15634 if (mode == CCFPmode)
15635 code = reverse_condition_maybe_unordered (code);
15636 else
15637 code = reverse_condition (code);
15640 if ((!TARGET_FPRS && TARGET_HARD_FLOAT) && mode == CCFPmode)
15642 /* The efscmp/tst* instructions twiddle bit 2, which maps nicely
15643 to the GT bit. */
15644 switch (code)
15646 case EQ:
15647 /* Opposite of GT. */
15648 code = GT;
15649 break;
15651 case NE:
15652 code = UNLE;
15653 break;
15655 default:
15656 gcc_unreachable ();
15660 switch (code)
15662 /* Not all of these are actually distinct opcodes, but
15663 we distinguish them for clarity of the resulting assembler. */
15664 case NE: case LTGT:
15665 ccode = "ne"; break;
15666 case EQ: case UNEQ:
15667 ccode = "eq"; break;
15668 case GE: case GEU:
15669 ccode = "ge"; break;
15670 case GT: case GTU: case UNGT:
15671 ccode = "gt"; break;
15672 case LE: case LEU:
15673 ccode = "le"; break;
15674 case LT: case LTU: case UNLT:
15675 ccode = "lt"; break;
15676 case UNORDERED: ccode = "un"; break;
15677 case ORDERED: ccode = "nu"; break;
15678 case UNGE: ccode = "nl"; break;
15679 case UNLE: ccode = "ng"; break;
15680 default:
15681 gcc_unreachable ();
15684 /* Maybe we have a guess as to how likely the branch is.
15685 The old mnemonics don't have a way to specify this information. */
15686 pred = "";
15687 note = find_reg_note (insn, REG_BR_PROB, NULL_RTX);
15688 if (note != NULL_RTX)
15690 /* PROB is the difference from 50%. */
15691 int prob = INTVAL (XEXP (note, 0)) - REG_BR_PROB_BASE / 2;
15693 /* Only hint for highly probable/improbable branches on newer
15694 cpus as static prediction overrides processor dynamic
15695 prediction. For older cpus we may as well always hint, but
15696 assume not taken for branches that are very close to 50% as a
15697 mispredicted taken branch is more expensive than a
15698 mispredicted not-taken branch. */
15699 if (rs6000_always_hint
15700 || (abs (prob) > REG_BR_PROB_BASE / 100 * 48
15701 && br_prob_note_reliable_p (note)))
15703 if (abs (prob) > REG_BR_PROB_BASE / 20
15704 && ((prob > 0) ^ need_longbranch))
15705 pred = "+";
15706 else
15707 pred = "-";
15711 if (label == NULL)
15712 s += sprintf (s, "{b%sr|b%slr%s} ", ccode, ccode, pred);
15713 else
15714 s += sprintf (s, "{b%s|b%s%s} ", ccode, ccode, pred);
15716 /* We need to escape any '%' characters in the reg_names string.
15717 Assume they'd only be the first character.... */
15718 if (reg_names[cc_regno + CR0_REGNO][0] == '%')
15719 *s++ = '%';
15720 s += sprintf (s, "%s", reg_names[cc_regno + CR0_REGNO]);
15722 if (label != NULL)
15724 /* If the branch distance was too far, we may have to use an
15725 unconditional branch to go the distance. */
15726 if (need_longbranch)
15727 s += sprintf (s, ",$+8\n\tb %s", label);
15728 else
15729 s += sprintf (s, ",%s", label);
15732 return string;
15735 /* Return the string to flip the GT bit on a CR. */
15736 char *
15737 output_e500_flip_gt_bit (rtx dst, rtx src)
15739 static char string[64];
15740 int a, b;
15742 gcc_assert (GET_CODE (dst) == REG && CR_REGNO_P (REGNO (dst))
15743 && GET_CODE (src) == REG && CR_REGNO_P (REGNO (src)));
15745 /* GT bit. */
15746 a = 4 * (REGNO (dst) - CR0_REGNO) + 1;
15747 b = 4 * (REGNO (src) - CR0_REGNO) + 1;
15749 sprintf (string, "crnot %d,%d", a, b);
15750 return string;
15753 /* Return insn for VSX or Altivec comparisons. */
15755 static rtx
15756 rs6000_emit_vector_compare_inner (enum rtx_code code, rtx op0, rtx op1)
15758 rtx mask;
15759 enum machine_mode mode = GET_MODE (op0);
15761 switch (code)
15763 default:
15764 break;
15766 case GE:
15767 if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
15768 return NULL_RTX;
15770 case EQ:
15771 case GT:
15772 case GTU:
15773 mask = gen_reg_rtx (mode);
15774 emit_insn (gen_rtx_SET (VOIDmode,
15775 mask,
15776 gen_rtx_fmt_ee (code, mode, op0, op1)));
15777 return mask;
15780 return NULL_RTX;
15783 /* Emit vector compare for operands OP0 and OP1 using code RCODE.
15784 DMODE is expected destination mode. This is a recursive function. */
15786 static rtx
15787 rs6000_emit_vector_compare (enum rtx_code rcode,
15788 rtx op0, rtx op1,
15789 enum machine_mode dmode)
15791 rtx mask;
15792 bool swap_operands = false;
15793 bool try_again = false;
15795 gcc_assert (VECTOR_UNIT_ALTIVEC_OR_VSX_P (dmode));
15796 gcc_assert (GET_MODE (op0) == GET_MODE (op1));
15798 /* See if the comparison works as is. */
15799 mask = rs6000_emit_vector_compare_inner (rcode, op0, op1);
15800 if (mask)
15801 return mask;
15803 switch (rcode)
15805 case LT:
15806 rcode = GT;
15807 swap_operands = true;
15808 try_again = true;
15809 break;
15810 case LTU:
15811 rcode = GTU;
15812 swap_operands = true;
15813 try_again = true;
15814 break;
15815 case NE:
15816 case UNLE:
15817 case UNLT:
15818 case UNGE:
15819 case UNGT:
15820 /* Invert condition and try again.
15821 e.g., A != B becomes ~(A==B). */
15823 enum rtx_code rev_code;
15824 enum insn_code nor_code;
15825 rtx mask2;
15827 rev_code = reverse_condition_maybe_unordered (rcode);
15828 if (rev_code == UNKNOWN)
15829 return NULL_RTX;
15831 nor_code = optab_handler (one_cmpl_optab, (int)dmode)->insn_code;
15832 if (nor_code == CODE_FOR_nothing)
15833 return NULL_RTX;
15835 mask2 = rs6000_emit_vector_compare (rev_code, op0, op1, dmode);
15836 if (!mask2)
15837 return NULL_RTX;
15839 mask = gen_reg_rtx (dmode);
15840 emit_insn (GEN_FCN (nor_code) (mask, mask2));
15841 return mask;
15843 break;
15844 case GE:
15845 case GEU:
15846 case LE:
15847 case LEU:
15848 /* Try GT/GTU/LT/LTU OR EQ */
15850 rtx c_rtx, eq_rtx;
15851 enum insn_code ior_code;
15852 enum rtx_code new_code;
15854 switch (rcode)
15856 case GE:
15857 new_code = GT;
15858 break;
15860 case GEU:
15861 new_code = GTU;
15862 break;
15864 case LE:
15865 new_code = LT;
15866 break;
15868 case LEU:
15869 new_code = LTU;
15870 break;
15872 default:
15873 gcc_unreachable ();
15876 ior_code = optab_handler (ior_optab, (int)dmode)->insn_code;
15877 if (ior_code == CODE_FOR_nothing)
15878 return NULL_RTX;
15880 c_rtx = rs6000_emit_vector_compare (new_code, op0, op1, dmode);
15881 if (!c_rtx)
15882 return NULL_RTX;
15884 eq_rtx = rs6000_emit_vector_compare (EQ, op0, op1, dmode);
15885 if (!eq_rtx)
15886 return NULL_RTX;
15888 mask = gen_reg_rtx (dmode);
15889 emit_insn (GEN_FCN (ior_code) (mask, c_rtx, eq_rtx));
15890 return mask;
15892 break;
15893 default:
15894 return NULL_RTX;
15897 if (try_again)
15899 if (swap_operands)
15901 rtx tmp;
15902 tmp = op0;
15903 op0 = op1;
15904 op1 = tmp;
15907 mask = rs6000_emit_vector_compare_inner (rcode, op0, op1);
15908 if (mask)
15909 return mask;
15912 /* You only get two chances. */
15913 return NULL_RTX;
15916 /* Emit vector conditional expression. DEST is destination. OP_TRUE and
15917 OP_FALSE are two VEC_COND_EXPR operands. CC_OP0 and CC_OP1 are the two
15918 operands for the relation operation COND. */
15921 rs6000_emit_vector_cond_expr (rtx dest, rtx op_true, rtx op_false,
15922 rtx cond, rtx cc_op0, rtx cc_op1)
15924 enum machine_mode dest_mode = GET_MODE (dest);
15925 enum rtx_code rcode = GET_CODE (cond);
15926 enum machine_mode cc_mode = CCmode;
15927 rtx mask;
15928 rtx cond2;
15929 rtx tmp;
15930 bool invert_move = false;
15932 if (VECTOR_UNIT_NONE_P (dest_mode))
15933 return 0;
15935 switch (rcode)
15937 /* Swap operands if we can, and fall back to doing the operation as
15938 specified, and doing a NOR to invert the test. */
15939 case NE:
15940 case UNLE:
15941 case UNLT:
15942 case UNGE:
15943 case UNGT:
15944 /* Invert condition and try again.
15945 e.g., A = (B != C) ? D : E becomes A = (B == C) ? E : D. */
15946 invert_move = true;
15947 rcode = reverse_condition_maybe_unordered (rcode);
15948 if (rcode == UNKNOWN)
15949 return 0;
15950 break;
15952 /* Mark unsigned tests with CCUNSmode. */
15953 case GTU:
15954 case GEU:
15955 case LTU:
15956 case LEU:
15957 cc_mode = CCUNSmode;
15958 break;
15960 default:
15961 break;
15964 /* Get the vector mask for the given relational operations. */
15965 mask = rs6000_emit_vector_compare (rcode, cc_op0, cc_op1, dest_mode);
15967 if (!mask)
15968 return 0;
15970 if (invert_move)
15972 tmp = op_true;
15973 op_true = op_false;
15974 op_false = tmp;
15977 cond2 = gen_rtx_fmt_ee (NE, cc_mode, mask, const0_rtx);
15978 emit_insn (gen_rtx_SET (VOIDmode,
15979 dest,
15980 gen_rtx_IF_THEN_ELSE (dest_mode,
15981 cond2,
15982 op_true,
15983 op_false)));
15984 return 1;
15987 /* Emit a conditional move: move TRUE_COND to DEST if OP of the
15988 operands of the last comparison is nonzero/true, FALSE_COND if it
15989 is zero/false. Return 0 if the hardware has no such operation. */
15992 rs6000_emit_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
15994 enum rtx_code code = GET_CODE (op);
15995 rtx op0 = XEXP (op, 0);
15996 rtx op1 = XEXP (op, 1);
15997 REAL_VALUE_TYPE c1;
15998 enum machine_mode compare_mode = GET_MODE (op0);
15999 enum machine_mode result_mode = GET_MODE (dest);
16000 rtx temp;
16001 bool is_against_zero;
16003 /* These modes should always match. */
16004 if (GET_MODE (op1) != compare_mode
16005 /* In the isel case however, we can use a compare immediate, so
16006 op1 may be a small constant. */
16007 && (!TARGET_ISEL || !short_cint_operand (op1, VOIDmode)))
16008 return 0;
16009 if (GET_MODE (true_cond) != result_mode)
16010 return 0;
16011 if (GET_MODE (false_cond) != result_mode)
16012 return 0;
16014 /* First, work out if the hardware can do this at all, or
16015 if it's too slow.... */
16016 if (!FLOAT_MODE_P (compare_mode))
16018 if (TARGET_ISEL)
16019 return rs6000_emit_int_cmove (dest, op, true_cond, false_cond);
16020 return 0;
16022 else if (TARGET_HARD_FLOAT && !TARGET_FPRS
16023 && SCALAR_FLOAT_MODE_P (compare_mode))
16024 return 0;
16026 is_against_zero = op1 == CONST0_RTX (compare_mode);
16028 /* A floating-point subtract might overflow, underflow, or produce
16029 an inexact result, thus changing the floating-point flags, so it
16030 can't be generated if we care about that. It's safe if one side
16031 of the construct is zero, since then no subtract will be
16032 generated. */
16033 if (SCALAR_FLOAT_MODE_P (compare_mode)
16034 && flag_trapping_math && ! is_against_zero)
16035 return 0;
16037 /* Eliminate half of the comparisons by switching operands, this
16038 makes the remaining code simpler. */
16039 if (code == UNLT || code == UNGT || code == UNORDERED || code == NE
16040 || code == LTGT || code == LT || code == UNLE)
16042 code = reverse_condition_maybe_unordered (code);
16043 temp = true_cond;
16044 true_cond = false_cond;
16045 false_cond = temp;
16048 /* UNEQ and LTGT take four instructions for a comparison with zero,
16049 it'll probably be faster to use a branch here too. */
16050 if (code == UNEQ && HONOR_NANS (compare_mode))
16051 return 0;
16053 if (GET_CODE (op1) == CONST_DOUBLE)
16054 REAL_VALUE_FROM_CONST_DOUBLE (c1, op1);
16056 /* We're going to try to implement comparisons by performing
16057 a subtract, then comparing against zero. Unfortunately,
16058 Inf - Inf is NaN which is not zero, and so if we don't
16059 know that the operand is finite and the comparison
16060 would treat EQ different to UNORDERED, we can't do it. */
16061 if (HONOR_INFINITIES (compare_mode)
16062 && code != GT && code != UNGE
16063 && (GET_CODE (op1) != CONST_DOUBLE || real_isinf (&c1))
16064 /* Constructs of the form (a OP b ? a : b) are safe. */
16065 && ((! rtx_equal_p (op0, false_cond) && ! rtx_equal_p (op1, false_cond))
16066 || (! rtx_equal_p (op0, true_cond)
16067 && ! rtx_equal_p (op1, true_cond))))
16068 return 0;
16070 /* At this point we know we can use fsel. */
16072 /* Reduce the comparison to a comparison against zero. */
16073 if (! is_against_zero)
16075 temp = gen_reg_rtx (compare_mode);
16076 emit_insn (gen_rtx_SET (VOIDmode, temp,
16077 gen_rtx_MINUS (compare_mode, op0, op1)));
16078 op0 = temp;
16079 op1 = CONST0_RTX (compare_mode);
16082 /* If we don't care about NaNs we can reduce some of the comparisons
16083 down to faster ones. */
16084 if (! HONOR_NANS (compare_mode))
16085 switch (code)
16087 case GT:
16088 code = LE;
16089 temp = true_cond;
16090 true_cond = false_cond;
16091 false_cond = temp;
16092 break;
16093 case UNGE:
16094 code = GE;
16095 break;
16096 case UNEQ:
16097 code = EQ;
16098 break;
16099 default:
16100 break;
16103 /* Now, reduce everything down to a GE. */
16104 switch (code)
16106 case GE:
16107 break;
16109 case LE:
16110 temp = gen_reg_rtx (compare_mode);
16111 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
16112 op0 = temp;
16113 break;
16115 case ORDERED:
16116 temp = gen_reg_rtx (compare_mode);
16117 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_ABS (compare_mode, op0)));
16118 op0 = temp;
16119 break;
16121 case EQ:
16122 temp = gen_reg_rtx (compare_mode);
16123 emit_insn (gen_rtx_SET (VOIDmode, temp,
16124 gen_rtx_NEG (compare_mode,
16125 gen_rtx_ABS (compare_mode, op0))));
16126 op0 = temp;
16127 break;
16129 case UNGE:
16130 /* a UNGE 0 <-> (a GE 0 || -a UNLT 0) */
16131 temp = gen_reg_rtx (result_mode);
16132 emit_insn (gen_rtx_SET (VOIDmode, temp,
16133 gen_rtx_IF_THEN_ELSE (result_mode,
16134 gen_rtx_GE (VOIDmode,
16135 op0, op1),
16136 true_cond, false_cond)));
16137 false_cond = true_cond;
16138 true_cond = temp;
16140 temp = gen_reg_rtx (compare_mode);
16141 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
16142 op0 = temp;
16143 break;
16145 case GT:
16146 /* a GT 0 <-> (a GE 0 && -a UNLT 0) */
16147 temp = gen_reg_rtx (result_mode);
16148 emit_insn (gen_rtx_SET (VOIDmode, temp,
16149 gen_rtx_IF_THEN_ELSE (result_mode,
16150 gen_rtx_GE (VOIDmode,
16151 op0, op1),
16152 true_cond, false_cond)));
16153 true_cond = false_cond;
16154 false_cond = temp;
16156 temp = gen_reg_rtx (compare_mode);
16157 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
16158 op0 = temp;
16159 break;
16161 default:
16162 gcc_unreachable ();
16165 emit_insn (gen_rtx_SET (VOIDmode, dest,
16166 gen_rtx_IF_THEN_ELSE (result_mode,
16167 gen_rtx_GE (VOIDmode,
16168 op0, op1),
16169 true_cond, false_cond)));
16170 return 1;
16173 /* Same as above, but for ints (isel). */
16175 static int
16176 rs6000_emit_int_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
16178 rtx condition_rtx, cr;
16179 enum machine_mode mode = GET_MODE (dest);
16181 if (mode != SImode && (!TARGET_POWERPC64 || mode != DImode))
16182 return 0;
16184 /* We still have to do the compare, because isel doesn't do a
16185 compare, it just looks at the CRx bits set by a previous compare
16186 instruction. */
16187 condition_rtx = rs6000_generate_compare (op, mode);
16188 cr = XEXP (condition_rtx, 0);
16190 if (mode == SImode)
16192 if (GET_MODE (cr) == CCmode)
16193 emit_insn (gen_isel_signed_si (dest, condition_rtx,
16194 true_cond, false_cond, cr));
16195 else
16196 emit_insn (gen_isel_unsigned_si (dest, condition_rtx,
16197 true_cond, false_cond, cr));
16199 else
16201 if (GET_MODE (cr) == CCmode)
16202 emit_insn (gen_isel_signed_di (dest, condition_rtx,
16203 true_cond, false_cond, cr));
16204 else
16205 emit_insn (gen_isel_unsigned_di (dest, condition_rtx,
16206 true_cond, false_cond, cr));
16209 return 1;
16212 const char *
16213 output_isel (rtx *operands)
16215 enum rtx_code code;
16217 code = GET_CODE (operands[1]);
16218 if (code == GE || code == GEU || code == LE || code == LEU || code == NE)
16220 PUT_CODE (operands[1], reverse_condition (code));
16221 return "isel %0,%3,%2,%j1";
16223 else
16224 return "isel %0,%2,%3,%j1";
16227 void
16228 rs6000_emit_minmax (rtx dest, enum rtx_code code, rtx op0, rtx op1)
16230 enum machine_mode mode = GET_MODE (op0);
16231 enum rtx_code c;
16232 rtx target;
16234 /* VSX/altivec have direct min/max insns. */
16235 if ((code == SMAX || code == SMIN) && VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode))
16237 emit_insn (gen_rtx_SET (VOIDmode,
16238 dest,
16239 gen_rtx_fmt_ee (code, mode, op0, op1)));
16240 return;
16243 if (code == SMAX || code == SMIN)
16244 c = GE;
16245 else
16246 c = GEU;
16248 if (code == SMAX || code == UMAX)
16249 target = emit_conditional_move (dest, c, op0, op1, mode,
16250 op0, op1, mode, 0);
16251 else
16252 target = emit_conditional_move (dest, c, op0, op1, mode,
16253 op1, op0, mode, 0);
16254 gcc_assert (target);
16255 if (target != dest)
16256 emit_move_insn (dest, target);
16259 /* Emit instructions to perform a load-reserved/store-conditional operation.
16260 The operation performed is an atomic
16261 (set M (CODE:MODE M OP))
16262 If not NULL, BEFORE is atomically set to M before the operation, and
16263 AFTER is set to M after the operation (that is, (CODE:MODE M OP)).
16264 If SYNC_P then a memory barrier is emitted before the operation.
16265 Either OP or M may be wrapped in a NOT operation. */
16267 void
16268 rs6000_emit_sync (enum rtx_code code, enum machine_mode mode,
16269 rtx m, rtx op, rtx before_param, rtx after_param,
16270 bool sync_p)
16272 enum machine_mode used_mode;
16273 rtx the_op, set_before, set_after, set_atomic, cc_scratch, before, after;
16274 rtx used_m;
16275 rtvec vec;
16276 HOST_WIDE_INT imask = GET_MODE_MASK (mode);
16277 rtx shift = NULL_RTX;
16279 if (sync_p)
16280 emit_insn (gen_lwsync ());
16282 used_m = m;
16284 /* If this is smaller than SImode, we'll have to use SImode with
16285 adjustments. */
16286 if (mode == QImode || mode == HImode)
16288 rtx newop, oldop;
16290 if (MEM_ALIGN (used_m) >= 32)
16292 int ishift = 0;
16293 if (BYTES_BIG_ENDIAN)
16294 ishift = GET_MODE_BITSIZE (SImode) - GET_MODE_BITSIZE (mode);
16296 shift = GEN_INT (ishift);
16297 used_m = change_address (used_m, SImode, 0);
16299 else
16301 rtx addrSI, aligned_addr;
16302 int shift_mask = mode == QImode ? 0x18 : 0x10;
16304 addrSI = gen_lowpart_common (SImode,
16305 force_reg (Pmode, XEXP (used_m, 0)));
16306 addrSI = force_reg (SImode, addrSI);
16307 shift = gen_reg_rtx (SImode);
16309 emit_insn (gen_rlwinm (shift, addrSI, GEN_INT (3),
16310 GEN_INT (shift_mask)));
16311 emit_insn (gen_xorsi3 (shift, shift, GEN_INT (shift_mask)));
16313 aligned_addr = expand_binop (Pmode, and_optab,
16314 XEXP (used_m, 0),
16315 GEN_INT (-4), NULL_RTX,
16316 1, OPTAB_LIB_WIDEN);
16317 used_m = change_address (used_m, SImode, aligned_addr);
16318 set_mem_align (used_m, 32);
16320 /* It's safe to keep the old alias set of USED_M, because
16321 the operation is atomic and only affects the original
16322 USED_M. */
16323 m = used_m;
16325 if (GET_CODE (op) == NOT)
16327 oldop = lowpart_subreg (SImode, XEXP (op, 0), mode);
16328 oldop = gen_rtx_NOT (SImode, oldop);
16330 else
16331 oldop = lowpart_subreg (SImode, op, mode);
16333 switch (code)
16335 case IOR:
16336 case XOR:
16337 newop = expand_binop (SImode, and_optab,
16338 oldop, GEN_INT (imask), NULL_RTX,
16339 1, OPTAB_LIB_WIDEN);
16340 emit_insn (gen_ashlsi3 (newop, newop, shift));
16341 break;
16343 case NOT: /* NAND */
16344 newop = expand_binop (SImode, ior_optab,
16345 oldop, GEN_INT (~imask), NULL_RTX,
16346 1, OPTAB_LIB_WIDEN);
16347 emit_insn (gen_rotlsi3 (newop, newop, shift));
16348 break;
16350 case AND:
16351 newop = expand_binop (SImode, ior_optab,
16352 oldop, GEN_INT (~imask), NULL_RTX,
16353 1, OPTAB_LIB_WIDEN);
16354 emit_insn (gen_rotlsi3 (newop, newop, shift));
16355 break;
16357 case PLUS:
16358 case MINUS:
16360 rtx mask;
16362 newop = expand_binop (SImode, and_optab,
16363 oldop, GEN_INT (imask), NULL_RTX,
16364 1, OPTAB_LIB_WIDEN);
16365 emit_insn (gen_ashlsi3 (newop, newop, shift));
16367 mask = gen_reg_rtx (SImode);
16368 emit_move_insn (mask, GEN_INT (imask));
16369 emit_insn (gen_ashlsi3 (mask, mask, shift));
16371 if (code == PLUS)
16372 newop = gen_rtx_PLUS (SImode, m, newop);
16373 else
16374 newop = gen_rtx_MINUS (SImode, m, newop);
16375 newop = gen_rtx_AND (SImode, newop, mask);
16376 newop = gen_rtx_IOR (SImode, newop,
16377 gen_rtx_AND (SImode,
16378 gen_rtx_NOT (SImode, mask),
16379 m));
16380 break;
16383 default:
16384 gcc_unreachable ();
16387 op = newop;
16388 used_mode = SImode;
16389 before = gen_reg_rtx (used_mode);
16390 after = gen_reg_rtx (used_mode);
16392 else
16394 used_mode = mode;
16395 before = before_param;
16396 after = after_param;
16398 if (before == NULL_RTX)
16399 before = gen_reg_rtx (used_mode);
16400 if (after == NULL_RTX)
16401 after = gen_reg_rtx (used_mode);
16404 if ((code == PLUS || code == MINUS)
16405 && used_mode != mode)
16406 the_op = op; /* Computed above. */
16407 else if (GET_CODE (op) == NOT && GET_CODE (m) != NOT)
16408 the_op = gen_rtx_fmt_ee (code, used_mode, op, m);
16409 else if (code == NOT)
16410 the_op = gen_rtx_fmt_ee (IOR, used_mode,
16411 gen_rtx_NOT (used_mode, m),
16412 gen_rtx_NOT (used_mode, op));
16413 else
16414 the_op = gen_rtx_fmt_ee (code, used_mode, m, op);
16416 set_after = gen_rtx_SET (VOIDmode, after, the_op);
16417 set_before = gen_rtx_SET (VOIDmode, before, used_m);
16418 set_atomic = gen_rtx_SET (VOIDmode, used_m,
16419 gen_rtx_UNSPEC (used_mode,
16420 gen_rtvec (1, the_op),
16421 UNSPEC_SYNC_OP));
16422 cc_scratch = gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (CCmode));
16424 if ((code == PLUS || code == MINUS) && used_mode != mode)
16425 vec = gen_rtvec (5, set_after, set_before, set_atomic, cc_scratch,
16426 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (SImode)));
16427 else
16428 vec = gen_rtvec (4, set_after, set_before, set_atomic, cc_scratch);
16429 emit_insn (gen_rtx_PARALLEL (VOIDmode, vec));
16431 /* Shift and mask the return values properly. */
16432 if (used_mode != mode && before_param)
16434 emit_insn (gen_lshrsi3 (before, before, shift));
16435 convert_move (before_param, before, 1);
16438 if (used_mode != mode && after_param)
16440 emit_insn (gen_lshrsi3 (after, after, shift));
16441 convert_move (after_param, after, 1);
16444 /* The previous sequence will end with a branch that's dependent on
16445 the conditional store, so placing an isync will ensure that no
16446 other instructions (especially, no load or store instructions)
16447 can start before the atomic operation completes. */
16448 if (sync_p)
16449 emit_insn (gen_isync ());
16452 /* A subroutine of the atomic operation splitters. Jump to LABEL if
16453 COND is true. Mark the jump as unlikely to be taken. */
16455 static void
16456 emit_unlikely_jump (rtx cond, rtx label)
16458 rtx very_unlikely = GEN_INT (REG_BR_PROB_BASE / 100 - 1);
16459 rtx x;
16461 x = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, label, pc_rtx);
16462 x = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, x));
16463 add_reg_note (x, REG_BR_PROB, very_unlikely);
16466 /* A subroutine of the atomic operation splitters. Emit a load-locked
16467 instruction in MODE. */
16469 static void
16470 emit_load_locked (enum machine_mode mode, rtx reg, rtx mem)
16472 rtx (*fn) (rtx, rtx) = NULL;
16473 if (mode == SImode)
16474 fn = gen_load_locked_si;
16475 else if (mode == DImode)
16476 fn = gen_load_locked_di;
16477 emit_insn (fn (reg, mem));
16480 /* A subroutine of the atomic operation splitters. Emit a store-conditional
16481 instruction in MODE. */
16483 static void
16484 emit_store_conditional (enum machine_mode mode, rtx res, rtx mem, rtx val)
16486 rtx (*fn) (rtx, rtx, rtx) = NULL;
16487 if (mode == SImode)
16488 fn = gen_store_conditional_si;
16489 else if (mode == DImode)
16490 fn = gen_store_conditional_di;
16492 /* Emit sync before stwcx. to address PPC405 Erratum. */
16493 if (PPC405_ERRATUM77)
16494 emit_insn (gen_memory_barrier ());
16496 emit_insn (fn (res, mem, val));
16499 /* Expand an atomic fetch-and-operate pattern. CODE is the binary operation
16500 to perform. MEM is the memory on which to operate. VAL is the second
16501 operand of the binary operator. BEFORE and AFTER are optional locations to
16502 return the value of MEM either before of after the operation. SCRATCH is
16503 a scratch register. */
16505 void
16506 rs6000_split_atomic_op (enum rtx_code code, rtx mem, rtx val,
16507 rtx before, rtx after, rtx scratch)
16509 enum machine_mode mode = GET_MODE (mem);
16510 rtx label, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
16512 emit_insn (gen_lwsync ());
16514 label = gen_label_rtx ();
16515 emit_label (label);
16516 label = gen_rtx_LABEL_REF (VOIDmode, label);
16518 if (before == NULL_RTX)
16519 before = scratch;
16520 emit_load_locked (mode, before, mem);
16522 if (code == NOT)
16523 x = gen_rtx_IOR (mode,
16524 gen_rtx_NOT (mode, before),
16525 gen_rtx_NOT (mode, val));
16526 else if (code == AND)
16527 x = gen_rtx_UNSPEC (mode, gen_rtvec (2, before, val), UNSPEC_AND);
16528 else
16529 x = gen_rtx_fmt_ee (code, mode, before, val);
16531 if (after != NULL_RTX)
16532 emit_insn (gen_rtx_SET (VOIDmode, after, copy_rtx (x)));
16533 emit_insn (gen_rtx_SET (VOIDmode, scratch, x));
16535 emit_store_conditional (mode, cond, mem, scratch);
16537 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
16538 emit_unlikely_jump (x, label);
16540 emit_insn (gen_isync ());
16543 /* Expand an atomic compare and swap operation. MEM is the memory on which
16544 to operate. OLDVAL is the old value to be compared. NEWVAL is the new
16545 value to be stored. SCRATCH is a scratch GPR. */
16547 void
16548 rs6000_split_compare_and_swap (rtx retval, rtx mem, rtx oldval, rtx newval,
16549 rtx scratch)
16551 enum machine_mode mode = GET_MODE (mem);
16552 rtx label1, label2, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
16554 emit_insn (gen_lwsync ());
16556 label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
16557 label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
16558 emit_label (XEXP (label1, 0));
16560 emit_load_locked (mode, retval, mem);
16562 x = gen_rtx_COMPARE (CCmode, retval, oldval);
16563 emit_insn (gen_rtx_SET (VOIDmode, cond, x));
16565 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
16566 emit_unlikely_jump (x, label2);
16568 emit_move_insn (scratch, newval);
16569 emit_store_conditional (mode, cond, mem, scratch);
16571 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
16572 emit_unlikely_jump (x, label1);
16574 emit_insn (gen_isync ());
16575 emit_label (XEXP (label2, 0));
16578 /* Expand an atomic test and set operation. MEM is the memory on which
16579 to operate. VAL is the value set. SCRATCH is a scratch GPR. */
16581 void
16582 rs6000_split_lock_test_and_set (rtx retval, rtx mem, rtx val, rtx scratch)
16584 enum machine_mode mode = GET_MODE (mem);
16585 rtx label, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
16587 label = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
16588 emit_label (XEXP (label, 0));
16590 emit_load_locked (mode, retval, mem);
16591 emit_move_insn (scratch, val);
16592 emit_store_conditional (mode, cond, mem, scratch);
16594 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
16595 emit_unlikely_jump (x, label);
16597 emit_insn (gen_isync ());
16600 void
16601 rs6000_expand_compare_and_swapqhi (rtx dst, rtx mem, rtx oldval, rtx newval)
16603 enum machine_mode mode = GET_MODE (mem);
16604 rtx addrSI, align, wdst, shift, mask;
16605 HOST_WIDE_INT shift_mask = mode == QImode ? 0x18 : 0x10;
16606 HOST_WIDE_INT imask = GET_MODE_MASK (mode);
16608 /* Shift amount for subword relative to aligned word. */
16609 addrSI = force_reg (GET_MODE (XEXP (mem, 0)), XEXP (mem, 0));
16610 addrSI = force_reg (SImode, gen_lowpart_common (SImode, addrSI));
16611 shift = gen_reg_rtx (SImode);
16612 emit_insn (gen_rlwinm (shift, addrSI, GEN_INT (3),
16613 GEN_INT (shift_mask)));
16614 emit_insn (gen_xorsi3 (shift, shift, GEN_INT (shift_mask)));
16616 /* Shift and mask old value into position within word. */
16617 oldval = convert_modes (SImode, mode, oldval, 1);
16618 oldval = expand_binop (SImode, and_optab,
16619 oldval, GEN_INT (imask), NULL_RTX,
16620 1, OPTAB_LIB_WIDEN);
16621 emit_insn (gen_ashlsi3 (oldval, oldval, shift));
16623 /* Shift and mask new value into position within word. */
16624 newval = convert_modes (SImode, mode, newval, 1);
16625 newval = expand_binop (SImode, and_optab,
16626 newval, GEN_INT (imask), NULL_RTX,
16627 1, OPTAB_LIB_WIDEN);
16628 emit_insn (gen_ashlsi3 (newval, newval, shift));
16630 /* Mask for insertion. */
16631 mask = gen_reg_rtx (SImode);
16632 emit_move_insn (mask, GEN_INT (imask));
16633 emit_insn (gen_ashlsi3 (mask, mask, shift));
16635 /* Address of aligned word containing subword. */
16636 align = expand_binop (Pmode, and_optab, XEXP (mem, 0), GEN_INT (-4),
16637 NULL_RTX, 1, OPTAB_LIB_WIDEN);
16638 mem = change_address (mem, SImode, align);
16639 set_mem_align (mem, 32);
16640 MEM_VOLATILE_P (mem) = 1;
16642 wdst = gen_reg_rtx (SImode);
16643 emit_insn (gen_sync_compare_and_swapqhi_internal (wdst, mask,
16644 oldval, newval, mem));
16646 /* Shift the result back. */
16647 emit_insn (gen_lshrsi3 (wdst, wdst, shift));
16649 emit_move_insn (dst, gen_lowpart (mode, wdst));
16652 void
16653 rs6000_split_compare_and_swapqhi (rtx dest, rtx mask,
16654 rtx oldval, rtx newval, rtx mem,
16655 rtx scratch)
16657 rtx label1, label2, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
16659 emit_insn (gen_lwsync ());
16660 label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
16661 label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
16662 emit_label (XEXP (label1, 0));
16664 emit_load_locked (SImode, scratch, mem);
16666 /* Mask subword within loaded value for comparison with oldval.
16667 Use UNSPEC_AND to avoid clobber.*/
16668 emit_insn (gen_rtx_SET (SImode, dest,
16669 gen_rtx_UNSPEC (SImode,
16670 gen_rtvec (2, scratch, mask),
16671 UNSPEC_AND)));
16673 x = gen_rtx_COMPARE (CCmode, dest, oldval);
16674 emit_insn (gen_rtx_SET (VOIDmode, cond, x));
16676 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
16677 emit_unlikely_jump (x, label2);
16679 /* Clear subword within loaded value for insertion of new value. */
16680 emit_insn (gen_rtx_SET (SImode, scratch,
16681 gen_rtx_AND (SImode,
16682 gen_rtx_NOT (SImode, mask), scratch)));
16683 emit_insn (gen_iorsi3 (scratch, scratch, newval));
16684 emit_store_conditional (SImode, cond, mem, scratch);
16686 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
16687 emit_unlikely_jump (x, label1);
16689 emit_insn (gen_isync ());
16690 emit_label (XEXP (label2, 0));
16694 /* Emit instructions to move SRC to DST. Called by splitters for
16695 multi-register moves. It will emit at most one instruction for
16696 each register that is accessed; that is, it won't emit li/lis pairs
16697 (or equivalent for 64-bit code). One of SRC or DST must be a hard
16698 register. */
16700 void
16701 rs6000_split_multireg_move (rtx dst, rtx src)
16703 /* The register number of the first register being moved. */
16704 int reg;
16705 /* The mode that is to be moved. */
16706 enum machine_mode mode;
16707 /* The mode that the move is being done in, and its size. */
16708 enum machine_mode reg_mode;
16709 int reg_mode_size;
16710 /* The number of registers that will be moved. */
16711 int nregs;
16713 reg = REG_P (dst) ? REGNO (dst) : REGNO (src);
16714 mode = GET_MODE (dst);
16715 nregs = hard_regno_nregs[reg][mode];
16716 if (FP_REGNO_P (reg))
16717 reg_mode = DECIMAL_FLOAT_MODE_P (mode) ? DDmode :
16718 ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? DFmode : SFmode);
16719 else if (ALTIVEC_REGNO_P (reg))
16720 reg_mode = V16QImode;
16721 else if (TARGET_E500_DOUBLE && mode == TFmode)
16722 reg_mode = DFmode;
16723 else
16724 reg_mode = word_mode;
16725 reg_mode_size = GET_MODE_SIZE (reg_mode);
16727 gcc_assert (reg_mode_size * nregs == GET_MODE_SIZE (mode));
16729 if (REG_P (src) && REG_P (dst) && (REGNO (src) < REGNO (dst)))
16731 /* Move register range backwards, if we might have destructive
16732 overlap. */
16733 int i;
16734 for (i = nregs - 1; i >= 0; i--)
16735 emit_insn (gen_rtx_SET (VOIDmode,
16736 simplify_gen_subreg (reg_mode, dst, mode,
16737 i * reg_mode_size),
16738 simplify_gen_subreg (reg_mode, src, mode,
16739 i * reg_mode_size)));
16741 else
16743 int i;
16744 int j = -1;
16745 bool used_update = false;
16747 if (MEM_P (src) && INT_REGNO_P (reg))
16749 rtx breg;
16751 if (GET_CODE (XEXP (src, 0)) == PRE_INC
16752 || GET_CODE (XEXP (src, 0)) == PRE_DEC)
16754 rtx delta_rtx;
16755 breg = XEXP (XEXP (src, 0), 0);
16756 delta_rtx = (GET_CODE (XEXP (src, 0)) == PRE_INC
16757 ? GEN_INT (GET_MODE_SIZE (GET_MODE (src)))
16758 : GEN_INT (-GET_MODE_SIZE (GET_MODE (src))));
16759 emit_insn (gen_add3_insn (breg, breg, delta_rtx));
16760 src = replace_equiv_address (src, breg);
16762 else if (! rs6000_offsettable_memref_p (src))
16764 rtx basereg;
16765 basereg = gen_rtx_REG (Pmode, reg);
16766 emit_insn (gen_rtx_SET (VOIDmode, basereg, XEXP (src, 0)));
16767 src = replace_equiv_address (src, basereg);
16770 breg = XEXP (src, 0);
16771 if (GET_CODE (breg) == PLUS || GET_CODE (breg) == LO_SUM)
16772 breg = XEXP (breg, 0);
16774 /* If the base register we are using to address memory is
16775 also a destination reg, then change that register last. */
16776 if (REG_P (breg)
16777 && REGNO (breg) >= REGNO (dst)
16778 && REGNO (breg) < REGNO (dst) + nregs)
16779 j = REGNO (breg) - REGNO (dst);
16782 if (GET_CODE (dst) == MEM && INT_REGNO_P (reg))
16784 rtx breg;
16786 if (GET_CODE (XEXP (dst, 0)) == PRE_INC
16787 || GET_CODE (XEXP (dst, 0)) == PRE_DEC)
16789 rtx delta_rtx;
16790 breg = XEXP (XEXP (dst, 0), 0);
16791 delta_rtx = (GET_CODE (XEXP (dst, 0)) == PRE_INC
16792 ? GEN_INT (GET_MODE_SIZE (GET_MODE (dst)))
16793 : GEN_INT (-GET_MODE_SIZE (GET_MODE (dst))));
16795 /* We have to update the breg before doing the store.
16796 Use store with update, if available. */
16798 if (TARGET_UPDATE)
16800 rtx nsrc = simplify_gen_subreg (reg_mode, src, mode, 0);
16801 emit_insn (TARGET_32BIT
16802 ? (TARGET_POWERPC64
16803 ? gen_movdi_si_update (breg, breg, delta_rtx, nsrc)
16804 : gen_movsi_update (breg, breg, delta_rtx, nsrc))
16805 : gen_movdi_di_update (breg, breg, delta_rtx, nsrc));
16806 used_update = true;
16808 else
16809 emit_insn (gen_add3_insn (breg, breg, delta_rtx));
16810 dst = replace_equiv_address (dst, breg);
16812 else
16813 gcc_assert (rs6000_offsettable_memref_p (dst));
16816 for (i = 0; i < nregs; i++)
16818 /* Calculate index to next subword. */
16819 ++j;
16820 if (j == nregs)
16821 j = 0;
16823 /* If compiler already emitted move of first word by
16824 store with update, no need to do anything. */
16825 if (j == 0 && used_update)
16826 continue;
16828 emit_insn (gen_rtx_SET (VOIDmode,
16829 simplify_gen_subreg (reg_mode, dst, mode,
16830 j * reg_mode_size),
16831 simplify_gen_subreg (reg_mode, src, mode,
16832 j * reg_mode_size)));
16838 /* This page contains routines that are used to determine what the
16839 function prologue and epilogue code will do and write them out. */
16841 /* Return the first fixed-point register that is required to be
16842 saved. 32 if none. */
16845 first_reg_to_save (void)
16847 int first_reg;
16849 /* Find lowest numbered live register. */
16850 for (first_reg = 13; first_reg <= 31; first_reg++)
16851 if (df_regs_ever_live_p (first_reg)
16852 && (! call_used_regs[first_reg]
16853 || (first_reg == RS6000_PIC_OFFSET_TABLE_REGNUM
16854 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
16855 || (DEFAULT_ABI == ABI_DARWIN && flag_pic)
16856 || (TARGET_TOC && TARGET_MINIMAL_TOC)))))
16857 break;
16859 #if TARGET_MACHO
16860 if (flag_pic
16861 && crtl->uses_pic_offset_table
16862 && first_reg > RS6000_PIC_OFFSET_TABLE_REGNUM)
16863 return RS6000_PIC_OFFSET_TABLE_REGNUM;
16864 #endif
16866 return first_reg;
16869 /* Similar, for FP regs. */
16872 first_fp_reg_to_save (void)
16874 int first_reg;
16876 /* Find lowest numbered live register. */
16877 for (first_reg = 14 + 32; first_reg <= 63; first_reg++)
16878 if (df_regs_ever_live_p (first_reg))
16879 break;
16881 return first_reg;
16884 /* Similar, for AltiVec regs. */
16886 static int
16887 first_altivec_reg_to_save (void)
16889 int i;
16891 /* Stack frame remains as is unless we are in AltiVec ABI. */
16892 if (! TARGET_ALTIVEC_ABI)
16893 return LAST_ALTIVEC_REGNO + 1;
16895 /* On Darwin, the unwind routines are compiled without
16896 TARGET_ALTIVEC, and use save_world to save/restore the
16897 altivec registers when necessary. */
16898 if (DEFAULT_ABI == ABI_DARWIN && crtl->calls_eh_return
16899 && ! TARGET_ALTIVEC)
16900 return FIRST_ALTIVEC_REGNO + 20;
16902 /* Find lowest numbered live register. */
16903 for (i = FIRST_ALTIVEC_REGNO + 20; i <= LAST_ALTIVEC_REGNO; ++i)
16904 if (df_regs_ever_live_p (i))
16905 break;
16907 return i;
16910 /* Return a 32-bit mask of the AltiVec registers we need to set in
16911 VRSAVE. Bit n of the return value is 1 if Vn is live. The MSB in
16912 the 32-bit word is 0. */
16914 static unsigned int
16915 compute_vrsave_mask (void)
16917 unsigned int i, mask = 0;
16919 /* On Darwin, the unwind routines are compiled without
16920 TARGET_ALTIVEC, and use save_world to save/restore the
16921 call-saved altivec registers when necessary. */
16922 if (DEFAULT_ABI == ABI_DARWIN && crtl->calls_eh_return
16923 && ! TARGET_ALTIVEC)
16924 mask |= 0xFFF;
16926 /* First, find out if we use _any_ altivec registers. */
16927 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
16928 if (df_regs_ever_live_p (i))
16929 mask |= ALTIVEC_REG_BIT (i);
16931 if (mask == 0)
16932 return mask;
16934 /* Next, remove the argument registers from the set. These must
16935 be in the VRSAVE mask set by the caller, so we don't need to add
16936 them in again. More importantly, the mask we compute here is
16937 used to generate CLOBBERs in the set_vrsave insn, and we do not
16938 wish the argument registers to die. */
16939 for (i = crtl->args.info.vregno - 1; i >= ALTIVEC_ARG_MIN_REG; --i)
16940 mask &= ~ALTIVEC_REG_BIT (i);
16942 /* Similarly, remove the return value from the set. */
16944 bool yes = false;
16945 diddle_return_value (is_altivec_return_reg, &yes);
16946 if (yes)
16947 mask &= ~ALTIVEC_REG_BIT (ALTIVEC_ARG_RETURN);
16950 return mask;
16953 /* For a very restricted set of circumstances, we can cut down the
16954 size of prologues/epilogues by calling our own save/restore-the-world
16955 routines. */
16957 static void
16958 compute_save_world_info (rs6000_stack_t *info_ptr)
16960 info_ptr->world_save_p = 1;
16961 info_ptr->world_save_p
16962 = (WORLD_SAVE_P (info_ptr)
16963 && DEFAULT_ABI == ABI_DARWIN
16964 && ! (cfun->calls_setjmp && flag_exceptions)
16965 && info_ptr->first_fp_reg_save == FIRST_SAVED_FP_REGNO
16966 && info_ptr->first_gp_reg_save == FIRST_SAVED_GP_REGNO
16967 && info_ptr->first_altivec_reg_save == FIRST_SAVED_ALTIVEC_REGNO
16968 && info_ptr->cr_save_p);
16970 /* This will not work in conjunction with sibcalls. Make sure there
16971 are none. (This check is expensive, but seldom executed.) */
16972 if (WORLD_SAVE_P (info_ptr))
16974 rtx insn;
16975 for ( insn = get_last_insn_anywhere (); insn; insn = PREV_INSN (insn))
16976 if ( GET_CODE (insn) == CALL_INSN
16977 && SIBLING_CALL_P (insn))
16979 info_ptr->world_save_p = 0;
16980 break;
16984 if (WORLD_SAVE_P (info_ptr))
16986 /* Even if we're not touching VRsave, make sure there's room on the
16987 stack for it, if it looks like we're calling SAVE_WORLD, which
16988 will attempt to save it. */
16989 info_ptr->vrsave_size = 4;
16991 /* If we are going to save the world, we need to save the link register too. */
16992 info_ptr->lr_save_p = 1;
16994 /* "Save" the VRsave register too if we're saving the world. */
16995 if (info_ptr->vrsave_mask == 0)
16996 info_ptr->vrsave_mask = compute_vrsave_mask ();
16998 /* Because the Darwin register save/restore routines only handle
16999 F14 .. F31 and V20 .. V31 as per the ABI, perform a consistency
17000 check. */
17001 gcc_assert (info_ptr->first_fp_reg_save >= FIRST_SAVED_FP_REGNO
17002 && (info_ptr->first_altivec_reg_save
17003 >= FIRST_SAVED_ALTIVEC_REGNO));
17005 return;
17009 static void
17010 is_altivec_return_reg (rtx reg, void *xyes)
17012 bool *yes = (bool *) xyes;
17013 if (REGNO (reg) == ALTIVEC_ARG_RETURN)
17014 *yes = true;
17018 /* Calculate the stack information for the current function. This is
17019 complicated by having two separate calling sequences, the AIX calling
17020 sequence and the V.4 calling sequence.
17022 AIX (and Darwin/Mac OS X) stack frames look like:
17023 32-bit 64-bit
17024 SP----> +---------------------------------------+
17025 | back chain to caller | 0 0
17026 +---------------------------------------+
17027 | saved CR | 4 8 (8-11)
17028 +---------------------------------------+
17029 | saved LR | 8 16
17030 +---------------------------------------+
17031 | reserved for compilers | 12 24
17032 +---------------------------------------+
17033 | reserved for binders | 16 32
17034 +---------------------------------------+
17035 | saved TOC pointer | 20 40
17036 +---------------------------------------+
17037 | Parameter save area (P) | 24 48
17038 +---------------------------------------+
17039 | Alloca space (A) | 24+P etc.
17040 +---------------------------------------+
17041 | Local variable space (L) | 24+P+A
17042 +---------------------------------------+
17043 | Float/int conversion temporary (X) | 24+P+A+L
17044 +---------------------------------------+
17045 | Save area for AltiVec registers (W) | 24+P+A+L+X
17046 +---------------------------------------+
17047 | AltiVec alignment padding (Y) | 24+P+A+L+X+W
17048 +---------------------------------------+
17049 | Save area for VRSAVE register (Z) | 24+P+A+L+X+W+Y
17050 +---------------------------------------+
17051 | Save area for GP registers (G) | 24+P+A+X+L+X+W+Y+Z
17052 +---------------------------------------+
17053 | Save area for FP registers (F) | 24+P+A+X+L+X+W+Y+Z+G
17054 +---------------------------------------+
17055 old SP->| back chain to caller's caller |
17056 +---------------------------------------+
17058 The required alignment for AIX configurations is two words (i.e., 8
17059 or 16 bytes).
17062 V.4 stack frames look like:
17064 SP----> +---------------------------------------+
17065 | back chain to caller | 0
17066 +---------------------------------------+
17067 | caller's saved LR | 4
17068 +---------------------------------------+
17069 | Parameter save area (P) | 8
17070 +---------------------------------------+
17071 | Alloca space (A) | 8+P
17072 +---------------------------------------+
17073 | Varargs save area (V) | 8+P+A
17074 +---------------------------------------+
17075 | Local variable space (L) | 8+P+A+V
17076 +---------------------------------------+
17077 | Float/int conversion temporary (X) | 8+P+A+V+L
17078 +---------------------------------------+
17079 | Save area for AltiVec registers (W) | 8+P+A+V+L+X
17080 +---------------------------------------+
17081 | AltiVec alignment padding (Y) | 8+P+A+V+L+X+W
17082 +---------------------------------------+
17083 | Save area for VRSAVE register (Z) | 8+P+A+V+L+X+W+Y
17084 +---------------------------------------+
17085 | SPE: area for 64-bit GP registers |
17086 +---------------------------------------+
17087 | SPE alignment padding |
17088 +---------------------------------------+
17089 | saved CR (C) | 8+P+A+V+L+X+W+Y+Z
17090 +---------------------------------------+
17091 | Save area for GP registers (G) | 8+P+A+V+L+X+W+Y+Z+C
17092 +---------------------------------------+
17093 | Save area for FP registers (F) | 8+P+A+V+L+X+W+Y+Z+C+G
17094 +---------------------------------------+
17095 old SP->| back chain to caller's caller |
17096 +---------------------------------------+
17098 The required alignment for V.4 is 16 bytes, or 8 bytes if -meabi is
17099 given. (But note below and in sysv4.h that we require only 8 and
17100 may round up the size of our stack frame anyways. The historical
17101 reason is early versions of powerpc-linux which didn't properly
17102 align the stack at program startup. A happy side-effect is that
17103 -mno-eabi libraries can be used with -meabi programs.)
17105 The EABI configuration defaults to the V.4 layout. However,
17106 the stack alignment requirements may differ. If -mno-eabi is not
17107 given, the required stack alignment is 8 bytes; if -mno-eabi is
17108 given, the required alignment is 16 bytes. (But see V.4 comment
17109 above.) */
17111 #ifndef ABI_STACK_BOUNDARY
17112 #define ABI_STACK_BOUNDARY STACK_BOUNDARY
17113 #endif
17115 static rs6000_stack_t *
17116 rs6000_stack_info (void)
17118 static rs6000_stack_t info;
17119 rs6000_stack_t *info_ptr = &info;
17120 int reg_size = TARGET_32BIT ? 4 : 8;
17121 int ehrd_size;
17122 int save_align;
17123 int first_gp;
17124 HOST_WIDE_INT non_fixed_size;
17126 memset (&info, 0, sizeof (info));
17128 if (TARGET_SPE)
17130 /* Cache value so we don't rescan instruction chain over and over. */
17131 if (cfun->machine->insn_chain_scanned_p == 0)
17132 cfun->machine->insn_chain_scanned_p
17133 = spe_func_has_64bit_regs_p () + 1;
17134 info_ptr->spe_64bit_regs_used = cfun->machine->insn_chain_scanned_p - 1;
17137 /* Select which calling sequence. */
17138 info_ptr->abi = DEFAULT_ABI;
17140 /* Calculate which registers need to be saved & save area size. */
17141 info_ptr->first_gp_reg_save = first_reg_to_save ();
17142 /* Assume that we will have to save RS6000_PIC_OFFSET_TABLE_REGNUM,
17143 even if it currently looks like we won't. Reload may need it to
17144 get at a constant; if so, it will have already created a constant
17145 pool entry for it. */
17146 if (((TARGET_TOC && TARGET_MINIMAL_TOC)
17147 || (flag_pic == 1 && DEFAULT_ABI == ABI_V4)
17148 || (flag_pic && DEFAULT_ABI == ABI_DARWIN))
17149 && crtl->uses_const_pool
17150 && info_ptr->first_gp_reg_save > RS6000_PIC_OFFSET_TABLE_REGNUM)
17151 first_gp = RS6000_PIC_OFFSET_TABLE_REGNUM;
17152 else
17153 first_gp = info_ptr->first_gp_reg_save;
17155 info_ptr->gp_size = reg_size * (32 - first_gp);
17157 /* For the SPE, we have an additional upper 32-bits on each GPR.
17158 Ideally we should save the entire 64-bits only when the upper
17159 half is used in SIMD instructions. Since we only record
17160 registers live (not the size they are used in), this proves
17161 difficult because we'd have to traverse the instruction chain at
17162 the right time, taking reload into account. This is a real pain,
17163 so we opt to save the GPRs in 64-bits always if but one register
17164 gets used in 64-bits. Otherwise, all the registers in the frame
17165 get saved in 32-bits.
17167 So... since when we save all GPRs (except the SP) in 64-bits, the
17168 traditional GP save area will be empty. */
17169 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
17170 info_ptr->gp_size = 0;
17172 info_ptr->first_fp_reg_save = first_fp_reg_to_save ();
17173 info_ptr->fp_size = 8 * (64 - info_ptr->first_fp_reg_save);
17175 info_ptr->first_altivec_reg_save = first_altivec_reg_to_save ();
17176 info_ptr->altivec_size = 16 * (LAST_ALTIVEC_REGNO + 1
17177 - info_ptr->first_altivec_reg_save);
17179 /* Does this function call anything? */
17180 info_ptr->calls_p = (! current_function_is_leaf
17181 || cfun->machine->ra_needs_full_frame);
17183 /* Determine if we need to save the link register. */
17184 if ((DEFAULT_ABI == ABI_AIX
17185 && crtl->profile
17186 && !TARGET_PROFILE_KERNEL)
17187 #ifdef TARGET_RELOCATABLE
17188 || (TARGET_RELOCATABLE && (get_pool_size () != 0))
17189 #endif
17190 || (info_ptr->first_fp_reg_save != 64
17191 && !FP_SAVE_INLINE (info_ptr->first_fp_reg_save))
17192 || (DEFAULT_ABI == ABI_V4 && cfun->calls_alloca)
17193 || info_ptr->calls_p
17194 || rs6000_ra_ever_killed ())
17196 info_ptr->lr_save_p = 1;
17197 df_set_regs_ever_live (LR_REGNO, true);
17200 /* Determine if we need to save the condition code registers. */
17201 if (df_regs_ever_live_p (CR2_REGNO)
17202 || df_regs_ever_live_p (CR3_REGNO)
17203 || df_regs_ever_live_p (CR4_REGNO))
17205 info_ptr->cr_save_p = 1;
17206 if (DEFAULT_ABI == ABI_V4)
17207 info_ptr->cr_size = reg_size;
17210 /* If the current function calls __builtin_eh_return, then we need
17211 to allocate stack space for registers that will hold data for
17212 the exception handler. */
17213 if (crtl->calls_eh_return)
17215 unsigned int i;
17216 for (i = 0; EH_RETURN_DATA_REGNO (i) != INVALID_REGNUM; ++i)
17217 continue;
17219 /* SPE saves EH registers in 64-bits. */
17220 ehrd_size = i * (TARGET_SPE_ABI
17221 && info_ptr->spe_64bit_regs_used != 0
17222 ? UNITS_PER_SPE_WORD : UNITS_PER_WORD);
17224 else
17225 ehrd_size = 0;
17227 /* Determine various sizes. */
17228 info_ptr->reg_size = reg_size;
17229 info_ptr->fixed_size = RS6000_SAVE_AREA;
17230 info_ptr->vars_size = RS6000_ALIGN (get_frame_size (), 8);
17231 info_ptr->parm_size = RS6000_ALIGN (crtl->outgoing_args_size,
17232 TARGET_ALTIVEC ? 16 : 8);
17233 if (FRAME_GROWS_DOWNWARD)
17234 info_ptr->vars_size
17235 += RS6000_ALIGN (info_ptr->fixed_size + info_ptr->vars_size
17236 + info_ptr->parm_size,
17237 ABI_STACK_BOUNDARY / BITS_PER_UNIT)
17238 - (info_ptr->fixed_size + info_ptr->vars_size
17239 + info_ptr->parm_size);
17241 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
17242 info_ptr->spe_gp_size = 8 * (32 - first_gp);
17243 else
17244 info_ptr->spe_gp_size = 0;
17246 if (TARGET_ALTIVEC_ABI)
17247 info_ptr->vrsave_mask = compute_vrsave_mask ();
17248 else
17249 info_ptr->vrsave_mask = 0;
17251 if (TARGET_ALTIVEC_VRSAVE && info_ptr->vrsave_mask)
17252 info_ptr->vrsave_size = 4;
17253 else
17254 info_ptr->vrsave_size = 0;
17256 compute_save_world_info (info_ptr);
17258 /* Calculate the offsets. */
17259 switch (DEFAULT_ABI)
17261 case ABI_NONE:
17262 default:
17263 gcc_unreachable ();
17265 case ABI_AIX:
17266 case ABI_DARWIN:
17267 info_ptr->fp_save_offset = - info_ptr->fp_size;
17268 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
17270 if (TARGET_ALTIVEC_ABI)
17272 info_ptr->vrsave_save_offset
17273 = info_ptr->gp_save_offset - info_ptr->vrsave_size;
17275 /* Align stack so vector save area is on a quadword boundary.
17276 The padding goes above the vectors. */
17277 if (info_ptr->altivec_size != 0)
17278 info_ptr->altivec_padding_size
17279 = info_ptr->vrsave_save_offset & 0xF;
17280 else
17281 info_ptr->altivec_padding_size = 0;
17283 info_ptr->altivec_save_offset
17284 = info_ptr->vrsave_save_offset
17285 - info_ptr->altivec_padding_size
17286 - info_ptr->altivec_size;
17287 gcc_assert (info_ptr->altivec_size == 0
17288 || info_ptr->altivec_save_offset % 16 == 0);
17290 /* Adjust for AltiVec case. */
17291 info_ptr->ehrd_offset = info_ptr->altivec_save_offset - ehrd_size;
17293 else
17294 info_ptr->ehrd_offset = info_ptr->gp_save_offset - ehrd_size;
17295 info_ptr->cr_save_offset = reg_size; /* first word when 64-bit. */
17296 info_ptr->lr_save_offset = 2*reg_size;
17297 break;
17299 case ABI_V4:
17300 info_ptr->fp_save_offset = - info_ptr->fp_size;
17301 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
17302 info_ptr->cr_save_offset = info_ptr->gp_save_offset - info_ptr->cr_size;
17304 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
17306 /* Align stack so SPE GPR save area is aligned on a
17307 double-word boundary. */
17308 if (info_ptr->spe_gp_size != 0 && info_ptr->cr_save_offset != 0)
17309 info_ptr->spe_padding_size
17310 = 8 - (-info_ptr->cr_save_offset % 8);
17311 else
17312 info_ptr->spe_padding_size = 0;
17314 info_ptr->spe_gp_save_offset
17315 = info_ptr->cr_save_offset
17316 - info_ptr->spe_padding_size
17317 - info_ptr->spe_gp_size;
17319 /* Adjust for SPE case. */
17320 info_ptr->ehrd_offset = info_ptr->spe_gp_save_offset;
17322 else if (TARGET_ALTIVEC_ABI)
17324 info_ptr->vrsave_save_offset
17325 = info_ptr->cr_save_offset - info_ptr->vrsave_size;
17327 /* Align stack so vector save area is on a quadword boundary. */
17328 if (info_ptr->altivec_size != 0)
17329 info_ptr->altivec_padding_size
17330 = 16 - (-info_ptr->vrsave_save_offset % 16);
17331 else
17332 info_ptr->altivec_padding_size = 0;
17334 info_ptr->altivec_save_offset
17335 = info_ptr->vrsave_save_offset
17336 - info_ptr->altivec_padding_size
17337 - info_ptr->altivec_size;
17339 /* Adjust for AltiVec case. */
17340 info_ptr->ehrd_offset = info_ptr->altivec_save_offset;
17342 else
17343 info_ptr->ehrd_offset = info_ptr->cr_save_offset;
17344 info_ptr->ehrd_offset -= ehrd_size;
17345 info_ptr->lr_save_offset = reg_size;
17346 break;
17349 save_align = (TARGET_ALTIVEC_ABI || DEFAULT_ABI == ABI_DARWIN) ? 16 : 8;
17350 info_ptr->save_size = RS6000_ALIGN (info_ptr->fp_size
17351 + info_ptr->gp_size
17352 + info_ptr->altivec_size
17353 + info_ptr->altivec_padding_size
17354 + info_ptr->spe_gp_size
17355 + info_ptr->spe_padding_size
17356 + ehrd_size
17357 + info_ptr->cr_size
17358 + info_ptr->vrsave_size,
17359 save_align);
17361 non_fixed_size = (info_ptr->vars_size
17362 + info_ptr->parm_size
17363 + info_ptr->save_size);
17365 info_ptr->total_size = RS6000_ALIGN (non_fixed_size + info_ptr->fixed_size,
17366 ABI_STACK_BOUNDARY / BITS_PER_UNIT);
17368 /* Determine if we need to allocate any stack frame:
17370 For AIX we need to push the stack if a frame pointer is needed
17371 (because the stack might be dynamically adjusted), if we are
17372 debugging, if we make calls, or if the sum of fp_save, gp_save,
17373 and local variables are more than the space needed to save all
17374 non-volatile registers: 32-bit: 18*8 + 19*4 = 220 or 64-bit: 18*8
17375 + 18*8 = 288 (GPR13 reserved).
17377 For V.4 we don't have the stack cushion that AIX uses, but assume
17378 that the debugger can handle stackless frames. */
17380 if (info_ptr->calls_p)
17381 info_ptr->push_p = 1;
17383 else if (DEFAULT_ABI == ABI_V4)
17384 info_ptr->push_p = non_fixed_size != 0;
17386 else if (frame_pointer_needed)
17387 info_ptr->push_p = 1;
17389 else if (TARGET_XCOFF && write_symbols != NO_DEBUG)
17390 info_ptr->push_p = 1;
17392 else
17393 info_ptr->push_p = non_fixed_size > (TARGET_32BIT ? 220 : 288);
17395 /* Zero offsets if we're not saving those registers. */
17396 if (info_ptr->fp_size == 0)
17397 info_ptr->fp_save_offset = 0;
17399 if (info_ptr->gp_size == 0)
17400 info_ptr->gp_save_offset = 0;
17402 if (! TARGET_ALTIVEC_ABI || info_ptr->altivec_size == 0)
17403 info_ptr->altivec_save_offset = 0;
17405 if (! TARGET_ALTIVEC_ABI || info_ptr->vrsave_mask == 0)
17406 info_ptr->vrsave_save_offset = 0;
17408 if (! TARGET_SPE_ABI
17409 || info_ptr->spe_64bit_regs_used == 0
17410 || info_ptr->spe_gp_size == 0)
17411 info_ptr->spe_gp_save_offset = 0;
17413 if (! info_ptr->lr_save_p)
17414 info_ptr->lr_save_offset = 0;
17416 if (! info_ptr->cr_save_p)
17417 info_ptr->cr_save_offset = 0;
17419 return info_ptr;
17422 /* Return true if the current function uses any GPRs in 64-bit SIMD
17423 mode. */
17425 static bool
17426 spe_func_has_64bit_regs_p (void)
17428 rtx insns, insn;
17430 /* Functions that save and restore all the call-saved registers will
17431 need to save/restore the registers in 64-bits. */
17432 if (crtl->calls_eh_return
17433 || cfun->calls_setjmp
17434 || crtl->has_nonlocal_goto)
17435 return true;
17437 insns = get_insns ();
17439 for (insn = NEXT_INSN (insns); insn != NULL_RTX; insn = NEXT_INSN (insn))
17441 if (INSN_P (insn))
17443 rtx i;
17445 /* FIXME: This should be implemented with attributes...
17447 (set_attr "spe64" "true")....then,
17448 if (get_spe64(insn)) return true;
17450 It's the only reliable way to do the stuff below. */
17452 i = PATTERN (insn);
17453 if (GET_CODE (i) == SET)
17455 enum machine_mode mode = GET_MODE (SET_SRC (i));
17457 if (SPE_VECTOR_MODE (mode))
17458 return true;
17459 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode))
17460 return true;
17465 return false;
17468 static void
17469 debug_stack_info (rs6000_stack_t *info)
17471 const char *abi_string;
17473 if (! info)
17474 info = rs6000_stack_info ();
17476 fprintf (stderr, "\nStack information for function %s:\n",
17477 ((current_function_decl && DECL_NAME (current_function_decl))
17478 ? IDENTIFIER_POINTER (DECL_NAME (current_function_decl))
17479 : "<unknown>"));
17481 switch (info->abi)
17483 default: abi_string = "Unknown"; break;
17484 case ABI_NONE: abi_string = "NONE"; break;
17485 case ABI_AIX: abi_string = "AIX"; break;
17486 case ABI_DARWIN: abi_string = "Darwin"; break;
17487 case ABI_V4: abi_string = "V.4"; break;
17490 fprintf (stderr, "\tABI = %5s\n", abi_string);
17492 if (TARGET_ALTIVEC_ABI)
17493 fprintf (stderr, "\tALTIVEC ABI extensions enabled.\n");
17495 if (TARGET_SPE_ABI)
17496 fprintf (stderr, "\tSPE ABI extensions enabled.\n");
17498 if (info->first_gp_reg_save != 32)
17499 fprintf (stderr, "\tfirst_gp_reg_save = %5d\n", info->first_gp_reg_save);
17501 if (info->first_fp_reg_save != 64)
17502 fprintf (stderr, "\tfirst_fp_reg_save = %5d\n", info->first_fp_reg_save);
17504 if (info->first_altivec_reg_save <= LAST_ALTIVEC_REGNO)
17505 fprintf (stderr, "\tfirst_altivec_reg_save = %5d\n",
17506 info->first_altivec_reg_save);
17508 if (info->lr_save_p)
17509 fprintf (stderr, "\tlr_save_p = %5d\n", info->lr_save_p);
17511 if (info->cr_save_p)
17512 fprintf (stderr, "\tcr_save_p = %5d\n", info->cr_save_p);
17514 if (info->vrsave_mask)
17515 fprintf (stderr, "\tvrsave_mask = 0x%x\n", info->vrsave_mask);
17517 if (info->push_p)
17518 fprintf (stderr, "\tpush_p = %5d\n", info->push_p);
17520 if (info->calls_p)
17521 fprintf (stderr, "\tcalls_p = %5d\n", info->calls_p);
17523 if (info->gp_save_offset)
17524 fprintf (stderr, "\tgp_save_offset = %5d\n", info->gp_save_offset);
17526 if (info->fp_save_offset)
17527 fprintf (stderr, "\tfp_save_offset = %5d\n", info->fp_save_offset);
17529 if (info->altivec_save_offset)
17530 fprintf (stderr, "\taltivec_save_offset = %5d\n",
17531 info->altivec_save_offset);
17533 if (info->spe_gp_save_offset)
17534 fprintf (stderr, "\tspe_gp_save_offset = %5d\n",
17535 info->spe_gp_save_offset);
17537 if (info->vrsave_save_offset)
17538 fprintf (stderr, "\tvrsave_save_offset = %5d\n",
17539 info->vrsave_save_offset);
17541 if (info->lr_save_offset)
17542 fprintf (stderr, "\tlr_save_offset = %5d\n", info->lr_save_offset);
17544 if (info->cr_save_offset)
17545 fprintf (stderr, "\tcr_save_offset = %5d\n", info->cr_save_offset);
17547 if (info->varargs_save_offset)
17548 fprintf (stderr, "\tvarargs_save_offset = %5d\n", info->varargs_save_offset);
17550 if (info->total_size)
17551 fprintf (stderr, "\ttotal_size = "HOST_WIDE_INT_PRINT_DEC"\n",
17552 info->total_size);
17554 if (info->vars_size)
17555 fprintf (stderr, "\tvars_size = "HOST_WIDE_INT_PRINT_DEC"\n",
17556 info->vars_size);
17558 if (info->parm_size)
17559 fprintf (stderr, "\tparm_size = %5d\n", info->parm_size);
17561 if (info->fixed_size)
17562 fprintf (stderr, "\tfixed_size = %5d\n", info->fixed_size);
17564 if (info->gp_size)
17565 fprintf (stderr, "\tgp_size = %5d\n", info->gp_size);
17567 if (info->spe_gp_size)
17568 fprintf (stderr, "\tspe_gp_size = %5d\n", info->spe_gp_size);
17570 if (info->fp_size)
17571 fprintf (stderr, "\tfp_size = %5d\n", info->fp_size);
17573 if (info->altivec_size)
17574 fprintf (stderr, "\taltivec_size = %5d\n", info->altivec_size);
17576 if (info->vrsave_size)
17577 fprintf (stderr, "\tvrsave_size = %5d\n", info->vrsave_size);
17579 if (info->altivec_padding_size)
17580 fprintf (stderr, "\taltivec_padding_size= %5d\n",
17581 info->altivec_padding_size);
17583 if (info->spe_padding_size)
17584 fprintf (stderr, "\tspe_padding_size = %5d\n",
17585 info->spe_padding_size);
17587 if (info->cr_size)
17588 fprintf (stderr, "\tcr_size = %5d\n", info->cr_size);
17590 if (info->save_size)
17591 fprintf (stderr, "\tsave_size = %5d\n", info->save_size);
17593 if (info->reg_size != 4)
17594 fprintf (stderr, "\treg_size = %5d\n", info->reg_size);
17596 fprintf (stderr, "\n");
17600 rs6000_return_addr (int count, rtx frame)
17602 /* Currently we don't optimize very well between prolog and body
17603 code and for PIC code the code can be actually quite bad, so
17604 don't try to be too clever here. */
17605 if (count != 0 || (DEFAULT_ABI != ABI_AIX && flag_pic))
17607 cfun->machine->ra_needs_full_frame = 1;
17609 return
17610 gen_rtx_MEM
17611 (Pmode,
17612 memory_address
17613 (Pmode,
17614 plus_constant (copy_to_reg
17615 (gen_rtx_MEM (Pmode,
17616 memory_address (Pmode, frame))),
17617 RETURN_ADDRESS_OFFSET)));
17620 cfun->machine->ra_need_lr = 1;
17621 return get_hard_reg_initial_val (Pmode, LR_REGNO);
17624 /* Say whether a function is a candidate for sibcall handling or not.
17625 We do not allow indirect calls to be optimized into sibling calls.
17626 Also, we can't do it if there are any vector parameters; there's
17627 nowhere to put the VRsave code so it works; note that functions with
17628 vector parameters are required to have a prototype, so the argument
17629 type info must be available here. (The tail recursion case can work
17630 with vector parameters, but there's no way to distinguish here.) */
17631 static bool
17632 rs6000_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED)
17634 tree type;
17635 if (decl)
17637 if (TARGET_ALTIVEC_VRSAVE)
17639 for (type = TYPE_ARG_TYPES (TREE_TYPE (decl));
17640 type; type = TREE_CHAIN (type))
17642 if (TREE_CODE (TREE_VALUE (type)) == VECTOR_TYPE)
17643 return false;
17646 if (DEFAULT_ABI == ABI_DARWIN
17647 || ((*targetm.binds_local_p) (decl)
17648 && (DEFAULT_ABI != ABI_AIX || !DECL_EXTERNAL (decl))))
17650 tree attr_list = TYPE_ATTRIBUTES (TREE_TYPE (decl));
17652 if (!lookup_attribute ("longcall", attr_list)
17653 || lookup_attribute ("shortcall", attr_list))
17654 return true;
17657 return false;
17660 /* NULL if INSN insn is valid within a low-overhead loop.
17661 Otherwise return why doloop cannot be applied.
17662 PowerPC uses the COUNT register for branch on table instructions. */
17664 static const char *
17665 rs6000_invalid_within_doloop (const_rtx insn)
17667 if (CALL_P (insn))
17668 return "Function call in the loop.";
17670 if (JUMP_P (insn)
17671 && (GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC
17672 || GET_CODE (PATTERN (insn)) == ADDR_VEC))
17673 return "Computed branch in the loop.";
17675 return NULL;
17678 static int
17679 rs6000_ra_ever_killed (void)
17681 rtx top;
17682 rtx reg;
17683 rtx insn;
17685 if (cfun->is_thunk)
17686 return 0;
17688 /* regs_ever_live has LR marked as used if any sibcalls are present,
17689 but this should not force saving and restoring in the
17690 pro/epilogue. Likewise, reg_set_between_p thinks a sibcall
17691 clobbers LR, so that is inappropriate. */
17693 /* Also, the prologue can generate a store into LR that
17694 doesn't really count, like this:
17696 move LR->R0
17697 bcl to set PIC register
17698 move LR->R31
17699 move R0->LR
17701 When we're called from the epilogue, we need to avoid counting
17702 this as a store. */
17704 push_topmost_sequence ();
17705 top = get_insns ();
17706 pop_topmost_sequence ();
17707 reg = gen_rtx_REG (Pmode, LR_REGNO);
17709 for (insn = NEXT_INSN (top); insn != NULL_RTX; insn = NEXT_INSN (insn))
17711 if (INSN_P (insn))
17713 if (CALL_P (insn))
17715 if (!SIBLING_CALL_P (insn))
17716 return 1;
17718 else if (find_regno_note (insn, REG_INC, LR_REGNO))
17719 return 1;
17720 else if (set_of (reg, insn) != NULL_RTX
17721 && !prologue_epilogue_contains (insn))
17722 return 1;
17725 return 0;
17728 /* Emit instructions needed to load the TOC register.
17729 This is only needed when TARGET_TOC, TARGET_MINIMAL_TOC, and there is
17730 a constant pool; or for SVR4 -fpic. */
17732 void
17733 rs6000_emit_load_toc_table (int fromprolog)
17735 rtx dest;
17736 dest = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
17738 if (TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI != ABI_AIX && flag_pic)
17740 char buf[30];
17741 rtx lab, tmp1, tmp2, got;
17743 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
17744 lab = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
17745 if (flag_pic == 2)
17746 got = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
17747 else
17748 got = rs6000_got_sym ();
17749 tmp1 = tmp2 = dest;
17750 if (!fromprolog)
17752 tmp1 = gen_reg_rtx (Pmode);
17753 tmp2 = gen_reg_rtx (Pmode);
17755 emit_insn (gen_load_toc_v4_PIC_1 (lab));
17756 emit_move_insn (tmp1,
17757 gen_rtx_REG (Pmode, LR_REGNO));
17758 emit_insn (gen_load_toc_v4_PIC_3b (tmp2, tmp1, got, lab));
17759 emit_insn (gen_load_toc_v4_PIC_3c (dest, tmp2, got, lab));
17761 else if (TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 1)
17763 emit_insn (gen_load_toc_v4_pic_si ());
17764 emit_move_insn (dest, gen_rtx_REG (Pmode, LR_REGNO));
17766 else if (TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2)
17768 char buf[30];
17769 rtx temp0 = (fromprolog
17770 ? gen_rtx_REG (Pmode, 0)
17771 : gen_reg_rtx (Pmode));
17773 if (fromprolog)
17775 rtx symF, symL;
17777 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
17778 symF = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
17780 ASM_GENERATE_INTERNAL_LABEL (buf, "LCL", rs6000_pic_labelno);
17781 symL = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
17783 emit_insn (gen_load_toc_v4_PIC_1 (symF));
17784 emit_move_insn (dest,
17785 gen_rtx_REG (Pmode, LR_REGNO));
17786 emit_insn (gen_load_toc_v4_PIC_2 (temp0, dest, symL, symF));
17788 else
17790 rtx tocsym;
17792 tocsym = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
17793 emit_insn (gen_load_toc_v4_PIC_1b (tocsym));
17794 emit_move_insn (dest,
17795 gen_rtx_REG (Pmode, LR_REGNO));
17796 emit_move_insn (temp0, gen_rtx_MEM (Pmode, dest));
17798 emit_insn (gen_addsi3 (dest, temp0, dest));
17800 else if (TARGET_ELF && !TARGET_AIX && flag_pic == 0 && TARGET_MINIMAL_TOC)
17802 /* This is for AIX code running in non-PIC ELF32. */
17803 char buf[30];
17804 rtx realsym;
17805 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
17806 realsym = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
17808 emit_insn (gen_elf_high (dest, realsym));
17809 emit_insn (gen_elf_low (dest, dest, realsym));
17811 else
17813 gcc_assert (DEFAULT_ABI == ABI_AIX);
17815 if (TARGET_32BIT)
17816 emit_insn (gen_load_toc_aix_si (dest));
17817 else
17818 emit_insn (gen_load_toc_aix_di (dest));
17822 /* Emit instructions to restore the link register after determining where
17823 its value has been stored. */
17825 void
17826 rs6000_emit_eh_reg_restore (rtx source, rtx scratch)
17828 rs6000_stack_t *info = rs6000_stack_info ();
17829 rtx operands[2];
17831 operands[0] = source;
17832 operands[1] = scratch;
17834 if (info->lr_save_p)
17836 rtx frame_rtx = stack_pointer_rtx;
17837 HOST_WIDE_INT sp_offset = 0;
17838 rtx tmp;
17840 if (frame_pointer_needed
17841 || cfun->calls_alloca
17842 || info->total_size > 32767)
17844 tmp = gen_frame_mem (Pmode, frame_rtx);
17845 emit_move_insn (operands[1], tmp);
17846 frame_rtx = operands[1];
17848 else if (info->push_p)
17849 sp_offset = info->total_size;
17851 tmp = plus_constant (frame_rtx, info->lr_save_offset + sp_offset);
17852 tmp = gen_frame_mem (Pmode, tmp);
17853 emit_move_insn (tmp, operands[0]);
17855 else
17856 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO), operands[0]);
17859 static GTY(()) alias_set_type set = -1;
17861 alias_set_type
17862 get_TOC_alias_set (void)
17864 if (set == -1)
17865 set = new_alias_set ();
17866 return set;
17869 /* This returns nonzero if the current function uses the TOC. This is
17870 determined by the presence of (use (unspec ... UNSPEC_TOC)), which
17871 is generated by the ABI_V4 load_toc_* patterns. */
17872 #if TARGET_ELF
17873 static int
17874 uses_TOC (void)
17876 rtx insn;
17878 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
17879 if (INSN_P (insn))
17881 rtx pat = PATTERN (insn);
17882 int i;
17884 if (GET_CODE (pat) == PARALLEL)
17885 for (i = 0; i < XVECLEN (pat, 0); i++)
17887 rtx sub = XVECEXP (pat, 0, i);
17888 if (GET_CODE (sub) == USE)
17890 sub = XEXP (sub, 0);
17891 if (GET_CODE (sub) == UNSPEC
17892 && XINT (sub, 1) == UNSPEC_TOC)
17893 return 1;
17897 return 0;
17899 #endif
17902 create_TOC_reference (rtx symbol)
17904 if (TARGET_DEBUG_ADDR)
17906 if (GET_CODE (symbol) == SYMBOL_REF)
17907 fprintf (stderr, "\ncreate_TOC_reference, (symbol_ref %s)\n",
17908 XSTR (symbol, 0));
17909 else
17911 fprintf (stderr, "\ncreate_TOC_reference, code %s:\n",
17912 GET_RTX_NAME (GET_CODE (symbol)));
17913 debug_rtx (symbol);
17917 if (!can_create_pseudo_p ())
17918 df_set_regs_ever_live (TOC_REGISTER, true);
17919 return gen_rtx_PLUS (Pmode,
17920 gen_rtx_REG (Pmode, TOC_REGISTER),
17921 gen_rtx_CONST (Pmode,
17922 gen_rtx_UNSPEC (Pmode, gen_rtvec (1, symbol), UNSPEC_TOCREL)));
17925 /* Issue assembly directives that create a reference to the given DWARF
17926 FRAME_TABLE_LABEL from the current function section. */
17927 void
17928 rs6000_aix_asm_output_dwarf_table_ref (char * frame_table_label)
17930 fprintf (asm_out_file, "\t.ref %s\n",
17931 TARGET_STRIP_NAME_ENCODING (frame_table_label));
17934 /* If _Unwind_* has been called from within the same module,
17935 toc register is not guaranteed to be saved to 40(1) on function
17936 entry. Save it there in that case. */
17938 void
17939 rs6000_aix_emit_builtin_unwind_init (void)
17941 rtx mem;
17942 rtx stack_top = gen_reg_rtx (Pmode);
17943 rtx opcode_addr = gen_reg_rtx (Pmode);
17944 rtx opcode = gen_reg_rtx (SImode);
17945 rtx tocompare = gen_reg_rtx (SImode);
17946 rtx no_toc_save_needed = gen_label_rtx ();
17948 mem = gen_frame_mem (Pmode, hard_frame_pointer_rtx);
17949 emit_move_insn (stack_top, mem);
17951 mem = gen_frame_mem (Pmode,
17952 gen_rtx_PLUS (Pmode, stack_top,
17953 GEN_INT (2 * GET_MODE_SIZE (Pmode))));
17954 emit_move_insn (opcode_addr, mem);
17955 emit_move_insn (opcode, gen_rtx_MEM (SImode, opcode_addr));
17956 emit_move_insn (tocompare, gen_int_mode (TARGET_32BIT ? 0x80410014
17957 : 0xE8410028, SImode));
17959 do_compare_rtx_and_jump (opcode, tocompare, EQ, 1,
17960 SImode, NULL_RTX, NULL_RTX,
17961 no_toc_save_needed, -1);
17963 mem = gen_frame_mem (Pmode,
17964 gen_rtx_PLUS (Pmode, stack_top,
17965 GEN_INT (5 * GET_MODE_SIZE (Pmode))));
17966 emit_move_insn (mem, gen_rtx_REG (Pmode, 2));
17967 emit_label (no_toc_save_needed);
17970 /* This ties together stack memory (MEM with an alias set of frame_alias_set)
17971 and the change to the stack pointer. */
17973 static void
17974 rs6000_emit_stack_tie (void)
17976 rtx mem = gen_frame_mem (BLKmode,
17977 gen_rtx_REG (Pmode, STACK_POINTER_REGNUM));
17979 emit_insn (gen_stack_tie (mem));
17982 /* Emit the correct code for allocating stack space, as insns.
17983 If COPY_R12, make sure a copy of the old frame is left in r12.
17984 If COPY_R11, make sure a copy of the old frame is left in r11,
17985 in preference to r12 if COPY_R12.
17986 The generated code may use hard register 0 as a temporary. */
17988 static void
17989 rs6000_emit_allocate_stack (HOST_WIDE_INT size, int copy_r12, int copy_r11)
17991 rtx insn;
17992 rtx stack_reg = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
17993 rtx tmp_reg = gen_rtx_REG (Pmode, 0);
17994 rtx todec = gen_int_mode (-size, Pmode);
17995 rtx par, set, mem;
17997 if (INTVAL (todec) != -size)
17999 warning (0, "stack frame too large");
18000 emit_insn (gen_trap ());
18001 return;
18004 if (crtl->limit_stack)
18006 if (REG_P (stack_limit_rtx)
18007 && REGNO (stack_limit_rtx) > 1
18008 && REGNO (stack_limit_rtx) <= 31)
18010 emit_insn (gen_add3_insn (tmp_reg, stack_limit_rtx, GEN_INT (size)));
18011 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
18012 const0_rtx));
18014 else if (GET_CODE (stack_limit_rtx) == SYMBOL_REF
18015 && TARGET_32BIT
18016 && DEFAULT_ABI == ABI_V4)
18018 rtx toload = gen_rtx_CONST (VOIDmode,
18019 gen_rtx_PLUS (Pmode,
18020 stack_limit_rtx,
18021 GEN_INT (size)));
18023 emit_insn (gen_elf_high (tmp_reg, toload));
18024 emit_insn (gen_elf_low (tmp_reg, tmp_reg, toload));
18025 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
18026 const0_rtx));
18028 else
18029 warning (0, "stack limit expression is not supported");
18032 if (copy_r12 || copy_r11)
18033 emit_move_insn (copy_r11
18034 ? gen_rtx_REG (Pmode, 11)
18035 : gen_rtx_REG (Pmode, 12),
18036 stack_reg);
18038 if (size > 32767)
18040 /* Need a note here so that try_split doesn't get confused. */
18041 if (get_last_insn () == NULL_RTX)
18042 emit_note (NOTE_INSN_DELETED);
18043 insn = emit_move_insn (tmp_reg, todec);
18044 try_split (PATTERN (insn), insn, 0);
18045 todec = tmp_reg;
18048 insn = emit_insn (TARGET_32BIT
18049 ? gen_movsi_update_stack (stack_reg, stack_reg,
18050 todec, stack_reg)
18051 : gen_movdi_di_update_stack (stack_reg, stack_reg,
18052 todec, stack_reg));
18053 /* Since we didn't use gen_frame_mem to generate the MEM, grab
18054 it now and set the alias set/attributes. The above gen_*_update
18055 calls will generate a PARALLEL with the MEM set being the first
18056 operation. */
18057 par = PATTERN (insn);
18058 gcc_assert (GET_CODE (par) == PARALLEL);
18059 set = XVECEXP (par, 0, 0);
18060 gcc_assert (GET_CODE (set) == SET);
18061 mem = SET_DEST (set);
18062 gcc_assert (MEM_P (mem));
18063 MEM_NOTRAP_P (mem) = 1;
18064 set_mem_alias_set (mem, get_frame_alias_set ());
18066 RTX_FRAME_RELATED_P (insn) = 1;
18067 add_reg_note (insn, REG_FRAME_RELATED_EXPR,
18068 gen_rtx_SET (VOIDmode, stack_reg,
18069 gen_rtx_PLUS (Pmode, stack_reg,
18070 GEN_INT (-size))));
18073 /* Add to 'insn' a note which is PATTERN (INSN) but with REG replaced
18074 with (plus:P (reg 1) VAL), and with REG2 replaced with RREG if REG2
18075 is not NULL. It would be nice if dwarf2out_frame_debug_expr could
18076 deduce these equivalences by itself so it wasn't necessary to hold
18077 its hand so much. */
18079 static void
18080 rs6000_frame_related (rtx insn, rtx reg, HOST_WIDE_INT val,
18081 rtx reg2, rtx rreg)
18083 rtx real, temp;
18085 /* copy_rtx will not make unique copies of registers, so we need to
18086 ensure we don't have unwanted sharing here. */
18087 if (reg == reg2)
18088 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
18090 if (reg == rreg)
18091 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
18093 real = copy_rtx (PATTERN (insn));
18095 if (reg2 != NULL_RTX)
18096 real = replace_rtx (real, reg2, rreg);
18098 real = replace_rtx (real, reg,
18099 gen_rtx_PLUS (Pmode, gen_rtx_REG (Pmode,
18100 STACK_POINTER_REGNUM),
18101 GEN_INT (val)));
18103 /* We expect that 'real' is either a SET or a PARALLEL containing
18104 SETs (and possibly other stuff). In a PARALLEL, all the SETs
18105 are important so they all have to be marked RTX_FRAME_RELATED_P. */
18107 if (GET_CODE (real) == SET)
18109 rtx set = real;
18111 temp = simplify_rtx (SET_SRC (set));
18112 if (temp)
18113 SET_SRC (set) = temp;
18114 temp = simplify_rtx (SET_DEST (set));
18115 if (temp)
18116 SET_DEST (set) = temp;
18117 if (GET_CODE (SET_DEST (set)) == MEM)
18119 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
18120 if (temp)
18121 XEXP (SET_DEST (set), 0) = temp;
18124 else
18126 int i;
18128 gcc_assert (GET_CODE (real) == PARALLEL);
18129 for (i = 0; i < XVECLEN (real, 0); i++)
18130 if (GET_CODE (XVECEXP (real, 0, i)) == SET)
18132 rtx set = XVECEXP (real, 0, i);
18134 temp = simplify_rtx (SET_SRC (set));
18135 if (temp)
18136 SET_SRC (set) = temp;
18137 temp = simplify_rtx (SET_DEST (set));
18138 if (temp)
18139 SET_DEST (set) = temp;
18140 if (GET_CODE (SET_DEST (set)) == MEM)
18142 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
18143 if (temp)
18144 XEXP (SET_DEST (set), 0) = temp;
18146 RTX_FRAME_RELATED_P (set) = 1;
18150 RTX_FRAME_RELATED_P (insn) = 1;
18151 add_reg_note (insn, REG_FRAME_RELATED_EXPR, real);
18154 /* Returns an insn that has a vrsave set operation with the
18155 appropriate CLOBBERs. */
18157 static rtx
18158 generate_set_vrsave (rtx reg, rs6000_stack_t *info, int epiloguep)
18160 int nclobs, i;
18161 rtx insn, clobs[TOTAL_ALTIVEC_REGS + 1];
18162 rtx vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
18164 clobs[0]
18165 = gen_rtx_SET (VOIDmode,
18166 vrsave,
18167 gen_rtx_UNSPEC_VOLATILE (SImode,
18168 gen_rtvec (2, reg, vrsave),
18169 UNSPECV_SET_VRSAVE));
18171 nclobs = 1;
18173 /* We need to clobber the registers in the mask so the scheduler
18174 does not move sets to VRSAVE before sets of AltiVec registers.
18176 However, if the function receives nonlocal gotos, reload will set
18177 all call saved registers live. We will end up with:
18179 (set (reg 999) (mem))
18180 (parallel [ (set (reg vrsave) (unspec blah))
18181 (clobber (reg 999))])
18183 The clobber will cause the store into reg 999 to be dead, and
18184 flow will attempt to delete an epilogue insn. In this case, we
18185 need an unspec use/set of the register. */
18187 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
18188 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
18190 if (!epiloguep || call_used_regs [i])
18191 clobs[nclobs++] = gen_rtx_CLOBBER (VOIDmode,
18192 gen_rtx_REG (V4SImode, i));
18193 else
18195 rtx reg = gen_rtx_REG (V4SImode, i);
18197 clobs[nclobs++]
18198 = gen_rtx_SET (VOIDmode,
18199 reg,
18200 gen_rtx_UNSPEC (V4SImode,
18201 gen_rtvec (1, reg), 27));
18205 insn = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (nclobs));
18207 for (i = 0; i < nclobs; ++i)
18208 XVECEXP (insn, 0, i) = clobs[i];
18210 return insn;
18213 /* Save a register into the frame, and emit RTX_FRAME_RELATED_P notes.
18214 Save REGNO into [FRAME_REG + OFFSET] in mode MODE. */
18216 static void
18217 emit_frame_save (rtx frame_reg, rtx frame_ptr, enum machine_mode mode,
18218 unsigned int regno, int offset, HOST_WIDE_INT total_size)
18220 rtx reg, offset_rtx, insn, mem, addr, int_rtx;
18221 rtx replacea, replaceb;
18223 int_rtx = GEN_INT (offset);
18225 /* Some cases that need register indexed addressing. */
18226 if ((TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
18227 || (TARGET_VSX && VSX_VECTOR_MODE (mode))
18228 || (TARGET_E500_DOUBLE && mode == DFmode)
18229 || (TARGET_SPE_ABI
18230 && SPE_VECTOR_MODE (mode)
18231 && !SPE_CONST_OFFSET_OK (offset)))
18233 /* Whomever calls us must make sure r11 is available in the
18234 flow path of instructions in the prologue. */
18235 offset_rtx = gen_rtx_REG (Pmode, 11);
18236 emit_move_insn (offset_rtx, int_rtx);
18238 replacea = offset_rtx;
18239 replaceb = int_rtx;
18241 else
18243 offset_rtx = int_rtx;
18244 replacea = NULL_RTX;
18245 replaceb = NULL_RTX;
18248 reg = gen_rtx_REG (mode, regno);
18249 addr = gen_rtx_PLUS (Pmode, frame_reg, offset_rtx);
18250 mem = gen_frame_mem (mode, addr);
18252 insn = emit_move_insn (mem, reg);
18254 rs6000_frame_related (insn, frame_ptr, total_size, replacea, replaceb);
18257 /* Emit an offset memory reference suitable for a frame store, while
18258 converting to a valid addressing mode. */
18260 static rtx
18261 gen_frame_mem_offset (enum machine_mode mode, rtx reg, int offset)
18263 rtx int_rtx, offset_rtx;
18265 int_rtx = GEN_INT (offset);
18267 if ((TARGET_SPE_ABI && SPE_VECTOR_MODE (mode))
18268 || (TARGET_E500_DOUBLE && mode == DFmode))
18270 offset_rtx = gen_rtx_REG (Pmode, FIXED_SCRATCH);
18271 emit_move_insn (offset_rtx, int_rtx);
18273 else
18274 offset_rtx = int_rtx;
18276 return gen_frame_mem (mode, gen_rtx_PLUS (Pmode, reg, offset_rtx));
18279 /* Look for user-defined global regs. We should not save and restore these,
18280 and cannot use stmw/lmw if there are any in its range. */
18282 static bool
18283 no_global_regs_above (int first, bool gpr)
18285 int i;
18286 int last = gpr ? 32 : 64;
18287 for (i = first; i < last; i++)
18288 if (global_regs[i])
18289 return false;
18290 return true;
18293 #ifndef TARGET_FIX_AND_CONTINUE
18294 #define TARGET_FIX_AND_CONTINUE 0
18295 #endif
18297 /* It's really GPR 13 and FPR 14, but we need the smaller of the two. */
18298 #define FIRST_SAVRES_REGISTER FIRST_SAVED_GP_REGNO
18299 #define LAST_SAVRES_REGISTER 31
18300 #define N_SAVRES_REGISTERS (LAST_SAVRES_REGISTER - FIRST_SAVRES_REGISTER + 1)
18302 static GTY(()) rtx savres_routine_syms[N_SAVRES_REGISTERS][8];
18304 /* Temporary holding space for an out-of-line register save/restore
18305 routine name. */
18306 static char savres_routine_name[30];
18308 /* Return the name for an out-of-line register save/restore routine.
18309 We are saving/restoring GPRs if GPR is true. */
18311 static char *
18312 rs6000_savres_routine_name (rs6000_stack_t *info, int regno,
18313 bool savep, bool gpr, bool lr)
18315 const char *prefix = "";
18316 const char *suffix = "";
18318 /* Different targets are supposed to define
18319 {SAVE,RESTORE}_FP_{PREFIX,SUFFIX} with the idea that the needed
18320 routine name could be defined with:
18322 sprintf (name, "%s%d%s", SAVE_FP_PREFIX, regno, SAVE_FP_SUFFIX)
18324 This is a nice idea in practice, but in reality, things are
18325 complicated in several ways:
18327 - ELF targets have save/restore routines for GPRs.
18329 - SPE targets use different prefixes for 32/64-bit registers, and
18330 neither of them fit neatly in the FOO_{PREFIX,SUFFIX} regimen.
18332 - PPC64 ELF targets have routines for save/restore of GPRs that
18333 differ in what they do with the link register, so having a set
18334 prefix doesn't work. (We only use one of the save routines at
18335 the moment, though.)
18337 - PPC32 elf targets have "exit" versions of the restore routines
18338 that restore the link register and can save some extra space.
18339 These require an extra suffix. (There are also "tail" versions
18340 of the restore routines and "GOT" versions of the save routines,
18341 but we don't generate those at present. Same problems apply,
18342 though.)
18344 We deal with all this by synthesizing our own prefix/suffix and
18345 using that for the simple sprintf call shown above. */
18346 if (TARGET_SPE)
18348 /* No floating point saves on the SPE. */
18349 gcc_assert (gpr);
18351 if (savep)
18352 prefix = info->spe_64bit_regs_used ? "_save64gpr_" : "_save32gpr_";
18353 else
18354 prefix = info->spe_64bit_regs_used ? "_rest64gpr_" : "_rest32gpr_";
18356 if (lr)
18357 suffix = "_x";
18359 else if (DEFAULT_ABI == ABI_V4)
18361 if (TARGET_64BIT)
18362 goto aix_names;
18364 if (gpr)
18365 prefix = savep ? "_savegpr_" : "_restgpr_";
18366 else
18367 prefix = savep ? "_savefpr_" : "_restfpr_";
18369 if (lr)
18370 suffix = "_x";
18372 else if (DEFAULT_ABI == ABI_AIX)
18374 #ifndef POWERPC_LINUX
18375 /* No out-of-line save/restore routines for GPRs on AIX. */
18376 gcc_assert (!TARGET_AIX || !gpr);
18377 #endif
18379 aix_names:
18380 if (gpr)
18381 prefix = (savep
18382 ? (lr ? "_savegpr0_" : "_savegpr1_")
18383 : (lr ? "_restgpr0_" : "_restgpr1_"));
18384 #ifdef POWERPC_LINUX
18385 else if (lr)
18386 prefix = (savep ? "_savefpr_" : "_restfpr_");
18387 #endif
18388 else
18390 prefix = savep ? SAVE_FP_PREFIX : RESTORE_FP_PREFIX;
18391 suffix = savep ? SAVE_FP_SUFFIX : RESTORE_FP_SUFFIX;
18394 else if (DEFAULT_ABI == ABI_DARWIN)
18395 sorry ("Out-of-line save/restore routines not supported on Darwin");
18397 sprintf (savres_routine_name, "%s%d%s", prefix, regno, suffix);
18399 return savres_routine_name;
18402 /* Return an RTL SYMBOL_REF for an out-of-line register save/restore routine.
18403 We are saving/restoring GPRs if GPR is true. */
18405 static rtx
18406 rs6000_savres_routine_sym (rs6000_stack_t *info, bool savep,
18407 bool gpr, bool lr)
18409 int regno = gpr ? info->first_gp_reg_save : (info->first_fp_reg_save - 32);
18410 rtx sym;
18411 int select = ((savep ? 1 : 0) << 2
18412 | ((TARGET_SPE_ABI
18413 /* On the SPE, we never have any FPRs, but we do have
18414 32/64-bit versions of the routines. */
18415 ? (info->spe_64bit_regs_used ? 1 : 0)
18416 : (gpr ? 1 : 0)) << 1)
18417 | (lr ? 1: 0));
18419 /* Don't generate bogus routine names. */
18420 gcc_assert (FIRST_SAVRES_REGISTER <= regno
18421 && regno <= LAST_SAVRES_REGISTER);
18423 sym = savres_routine_syms[regno-FIRST_SAVRES_REGISTER][select];
18425 if (sym == NULL)
18427 char *name;
18429 name = rs6000_savres_routine_name (info, regno, savep, gpr, lr);
18431 sym = savres_routine_syms[regno-FIRST_SAVRES_REGISTER][select]
18432 = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (name));
18433 SYMBOL_REF_FLAGS (sym) |= SYMBOL_FLAG_FUNCTION;
18436 return sym;
18439 /* Emit a sequence of insns, including a stack tie if needed, for
18440 resetting the stack pointer. If SAVRES is true, then don't reset the
18441 stack pointer, but move the base of the frame into r11 for use by
18442 out-of-line register restore routines. */
18444 static rtx
18445 rs6000_emit_stack_reset (rs6000_stack_t *info,
18446 rtx sp_reg_rtx, rtx frame_reg_rtx,
18447 int sp_offset, bool savres)
18449 /* This blockage is needed so that sched doesn't decide to move
18450 the sp change before the register restores. */
18451 if (frame_reg_rtx != sp_reg_rtx
18452 || (TARGET_SPE_ABI
18453 && info->spe_64bit_regs_used != 0
18454 && info->first_gp_reg_save != 32))
18455 rs6000_emit_stack_tie ();
18457 if (frame_reg_rtx != sp_reg_rtx)
18459 if (sp_offset != 0)
18461 rtx dest_reg = savres ? gen_rtx_REG (Pmode, 11) : sp_reg_rtx;
18462 return emit_insn (gen_add3_insn (dest_reg, frame_reg_rtx,
18463 GEN_INT (sp_offset)));
18465 else if (!savres)
18466 return emit_move_insn (sp_reg_rtx, frame_reg_rtx);
18468 else if (sp_offset != 0)
18470 /* If we are restoring registers out-of-line, we will be using the
18471 "exit" variants of the restore routines, which will reset the
18472 stack for us. But we do need to point r11 into the right place
18473 for those routines. */
18474 rtx dest_reg = (savres
18475 ? gen_rtx_REG (Pmode, 11)
18476 : sp_reg_rtx);
18478 rtx insn = emit_insn (gen_add3_insn (dest_reg, sp_reg_rtx,
18479 GEN_INT (sp_offset)));
18480 if (!savres)
18481 return insn;
18483 return NULL_RTX;
18486 /* Construct a parallel rtx describing the effect of a call to an
18487 out-of-line register save/restore routine. */
18489 static rtx
18490 rs6000_make_savres_rtx (rs6000_stack_t *info,
18491 rtx frame_reg_rtx, int save_area_offset,
18492 enum machine_mode reg_mode,
18493 bool savep, bool gpr, bool lr)
18495 int i;
18496 int offset, start_reg, end_reg, n_regs;
18497 int reg_size = GET_MODE_SIZE (reg_mode);
18498 rtx sym;
18499 rtvec p;
18501 offset = 0;
18502 start_reg = (gpr
18503 ? info->first_gp_reg_save
18504 : info->first_fp_reg_save);
18505 end_reg = gpr ? 32 : 64;
18506 n_regs = end_reg - start_reg;
18507 p = rtvec_alloc ((lr ? 4 : 3) + n_regs);
18509 if (!savep && lr)
18510 RTVEC_ELT (p, offset++) = gen_rtx_RETURN (VOIDmode);
18512 RTVEC_ELT (p, offset++)
18513 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 65));
18515 sym = rs6000_savres_routine_sym (info, savep, gpr, lr);
18516 RTVEC_ELT (p, offset++) = gen_rtx_USE (VOIDmode, sym);
18517 RTVEC_ELT (p, offset++)
18518 = gen_rtx_USE (VOIDmode,
18519 gen_rtx_REG (Pmode, DEFAULT_ABI != ABI_AIX ? 11
18520 : gpr && !lr ? 12
18521 : 1));
18523 for (i = 0; i < end_reg - start_reg; i++)
18525 rtx addr, reg, mem;
18526 reg = gen_rtx_REG (reg_mode, start_reg + i);
18527 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18528 GEN_INT (save_area_offset + reg_size*i));
18529 mem = gen_frame_mem (reg_mode, addr);
18531 RTVEC_ELT (p, i + offset) = gen_rtx_SET (VOIDmode,
18532 savep ? mem : reg,
18533 savep ? reg : mem);
18536 if (savep && lr)
18538 rtx addr, reg, mem;
18539 reg = gen_rtx_REG (Pmode, 0);
18540 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18541 GEN_INT (info->lr_save_offset));
18542 mem = gen_frame_mem (Pmode, addr);
18543 RTVEC_ELT (p, i + offset) = gen_rtx_SET (VOIDmode, mem, reg);
18546 return gen_rtx_PARALLEL (VOIDmode, p);
18549 /* Determine whether the gp REG is really used. */
18551 static bool
18552 rs6000_reg_live_or_pic_offset_p (int reg)
18554 return ((df_regs_ever_live_p (reg)
18555 && (!call_used_regs[reg]
18556 || (reg == RS6000_PIC_OFFSET_TABLE_REGNUM
18557 && TARGET_TOC && TARGET_MINIMAL_TOC)))
18558 || (reg == RS6000_PIC_OFFSET_TABLE_REGNUM
18559 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
18560 || (DEFAULT_ABI == ABI_DARWIN && flag_pic))));
18563 enum {
18564 SAVRES_MULTIPLE = 0x1,
18565 SAVRES_INLINE_FPRS = 0x2,
18566 SAVRES_INLINE_GPRS = 0x4,
18567 SAVRES_NOINLINE_GPRS_SAVES_LR = 0x8,
18568 SAVRES_NOINLINE_FPRS_SAVES_LR = 0x10,
18569 SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR = 0x20
18572 /* Determine the strategy for savings/restoring registers. */
18574 static int
18575 rs6000_savres_strategy (rs6000_stack_t *info, bool savep,
18576 int using_static_chain_p, int sibcall)
18578 bool using_multiple_p;
18579 bool common;
18580 bool savres_fprs_inline;
18581 bool savres_gprs_inline;
18582 bool noclobber_global_gprs
18583 = no_global_regs_above (info->first_gp_reg_save, /*gpr=*/true);
18584 int strategy;
18586 using_multiple_p = (TARGET_MULTIPLE && ! TARGET_POWERPC64
18587 && (!TARGET_SPE_ABI
18588 || info->spe_64bit_regs_used == 0)
18589 && info->first_gp_reg_save < 31
18590 && noclobber_global_gprs);
18591 /* Don't bother to try to save things out-of-line if r11 is occupied
18592 by the static chain. It would require too much fiddling and the
18593 static chain is rarely used anyway. */
18594 common = (using_static_chain_p
18595 || sibcall
18596 || crtl->calls_eh_return
18597 || !info->lr_save_p
18598 || cfun->machine->ra_need_lr
18599 || info->total_size > 32767);
18600 savres_fprs_inline = (common
18601 || info->first_fp_reg_save == 64
18602 || !no_global_regs_above (info->first_fp_reg_save,
18603 /*gpr=*/false)
18604 /* The out-of-line FP routines use
18605 double-precision stores; we can't use those
18606 routines if we don't have such stores. */
18607 || (TARGET_HARD_FLOAT && !TARGET_DOUBLE_FLOAT)
18608 || FP_SAVE_INLINE (info->first_fp_reg_save));
18609 savres_gprs_inline = (common
18610 /* Saving CR interferes with the exit routines
18611 used on the SPE, so just punt here. */
18612 || (!savep
18613 && TARGET_SPE_ABI
18614 && info->spe_64bit_regs_used != 0
18615 && info->cr_save_p != 0)
18616 || info->first_gp_reg_save == 32
18617 || !noclobber_global_gprs
18618 || GP_SAVE_INLINE (info->first_gp_reg_save));
18620 if (savep)
18621 /* If we are going to use store multiple, then don't even bother
18622 with the out-of-line routines, since the store-multiple instruction
18623 will always be smaller. */
18624 savres_gprs_inline = savres_gprs_inline || using_multiple_p;
18625 else
18627 /* The situation is more complicated with load multiple. We'd
18628 prefer to use the out-of-line routines for restores, since the
18629 "exit" out-of-line routines can handle the restore of LR and
18630 the frame teardown. But we can only use the out-of-line
18631 routines if we know that we've used store multiple or
18632 out-of-line routines in the prologue, i.e. if we've saved all
18633 the registers from first_gp_reg_save. Otherwise, we risk
18634 loading garbage from the stack. Furthermore, we can only use
18635 the "exit" out-of-line gpr restore if we haven't saved any
18636 fprs. */
18637 bool saved_all = !savres_gprs_inline || using_multiple_p;
18639 if (saved_all && info->first_fp_reg_save != 64)
18640 /* We can't use the exit routine; use load multiple if it's
18641 available. */
18642 savres_gprs_inline = savres_gprs_inline || using_multiple_p;
18645 strategy = (using_multiple_p
18646 | (savres_fprs_inline << 1)
18647 | (savres_gprs_inline << 2));
18648 #ifdef POWERPC_LINUX
18649 if (TARGET_64BIT)
18651 if (!savres_fprs_inline)
18652 strategy |= SAVRES_NOINLINE_FPRS_SAVES_LR;
18653 else if (!savres_gprs_inline && info->first_fp_reg_save == 64)
18654 strategy |= SAVRES_NOINLINE_GPRS_SAVES_LR;
18656 #else
18657 if (TARGET_AIX && !savres_fprs_inline)
18658 strategy |= SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR;
18659 #endif
18660 return strategy;
18663 /* Emit function prologue as insns. */
18665 void
18666 rs6000_emit_prologue (void)
18668 rs6000_stack_t *info = rs6000_stack_info ();
18669 enum machine_mode reg_mode = Pmode;
18670 int reg_size = TARGET_32BIT ? 4 : 8;
18671 rtx sp_reg_rtx = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
18672 rtx frame_ptr_rtx = gen_rtx_REG (Pmode, 12);
18673 rtx frame_reg_rtx = sp_reg_rtx;
18674 rtx cr_save_rtx = NULL_RTX;
18675 rtx insn;
18676 int strategy;
18677 int saving_FPRs_inline;
18678 int saving_GPRs_inline;
18679 int using_store_multiple;
18680 int using_static_chain_p = (cfun->static_chain_decl != NULL_TREE
18681 && df_regs_ever_live_p (STATIC_CHAIN_REGNUM)
18682 && call_used_regs[STATIC_CHAIN_REGNUM]);
18683 HOST_WIDE_INT sp_offset = 0;
18685 if (TARGET_FIX_AND_CONTINUE)
18687 /* gdb on darwin arranges to forward a function from the old
18688 address by modifying the first 5 instructions of the function
18689 to branch to the overriding function. This is necessary to
18690 permit function pointers that point to the old function to
18691 actually forward to the new function. */
18692 emit_insn (gen_nop ());
18693 emit_insn (gen_nop ());
18694 emit_insn (gen_nop ());
18695 emit_insn (gen_nop ());
18696 emit_insn (gen_nop ());
18699 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
18701 reg_mode = V2SImode;
18702 reg_size = 8;
18705 strategy = rs6000_savres_strategy (info, /*savep=*/true,
18706 /*static_chain_p=*/using_static_chain_p,
18707 /*sibcall=*/0);
18708 using_store_multiple = strategy & SAVRES_MULTIPLE;
18709 saving_FPRs_inline = strategy & SAVRES_INLINE_FPRS;
18710 saving_GPRs_inline = strategy & SAVRES_INLINE_GPRS;
18712 /* For V.4, update stack before we do any saving and set back pointer. */
18713 if (! WORLD_SAVE_P (info)
18714 && info->push_p
18715 && (DEFAULT_ABI == ABI_V4
18716 || crtl->calls_eh_return))
18718 bool need_r11 = (TARGET_SPE
18719 ? (!saving_GPRs_inline
18720 && info->spe_64bit_regs_used == 0)
18721 : (!saving_FPRs_inline || !saving_GPRs_inline));
18722 if (info->total_size < 32767)
18723 sp_offset = info->total_size;
18724 else
18725 frame_reg_rtx = (need_r11
18726 ? gen_rtx_REG (Pmode, 11)
18727 : frame_ptr_rtx);
18728 rs6000_emit_allocate_stack (info->total_size,
18729 (frame_reg_rtx != sp_reg_rtx
18730 && (info->cr_save_p
18731 || info->lr_save_p
18732 || info->first_fp_reg_save < 64
18733 || info->first_gp_reg_save < 32
18735 need_r11);
18736 if (frame_reg_rtx != sp_reg_rtx)
18737 rs6000_emit_stack_tie ();
18740 /* Handle world saves specially here. */
18741 if (WORLD_SAVE_P (info))
18743 int i, j, sz;
18744 rtx treg;
18745 rtvec p;
18746 rtx reg0;
18748 /* save_world expects lr in r0. */
18749 reg0 = gen_rtx_REG (Pmode, 0);
18750 if (info->lr_save_p)
18752 insn = emit_move_insn (reg0,
18753 gen_rtx_REG (Pmode, LR_REGNO));
18754 RTX_FRAME_RELATED_P (insn) = 1;
18757 /* The SAVE_WORLD and RESTORE_WORLD routines make a number of
18758 assumptions about the offsets of various bits of the stack
18759 frame. */
18760 gcc_assert (info->gp_save_offset == -220
18761 && info->fp_save_offset == -144
18762 && info->lr_save_offset == 8
18763 && info->cr_save_offset == 4
18764 && info->push_p
18765 && info->lr_save_p
18766 && (!crtl->calls_eh_return
18767 || info->ehrd_offset == -432)
18768 && info->vrsave_save_offset == -224
18769 && info->altivec_save_offset == -416);
18771 treg = gen_rtx_REG (SImode, 11);
18772 emit_move_insn (treg, GEN_INT (-info->total_size));
18774 /* SAVE_WORLD takes the caller's LR in R0 and the frame size
18775 in R11. It also clobbers R12, so beware! */
18777 /* Preserve CR2 for save_world prologues */
18778 sz = 5;
18779 sz += 32 - info->first_gp_reg_save;
18780 sz += 64 - info->first_fp_reg_save;
18781 sz += LAST_ALTIVEC_REGNO - info->first_altivec_reg_save + 1;
18782 p = rtvec_alloc (sz);
18783 j = 0;
18784 RTVEC_ELT (p, j++) = gen_rtx_CLOBBER (VOIDmode,
18785 gen_rtx_REG (SImode,
18786 LR_REGNO));
18787 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
18788 gen_rtx_SYMBOL_REF (Pmode,
18789 "*save_world"));
18790 /* We do floats first so that the instruction pattern matches
18791 properly. */
18792 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
18794 rtx reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
18795 ? DFmode : SFmode),
18796 info->first_fp_reg_save + i);
18797 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18798 GEN_INT (info->fp_save_offset
18799 + sp_offset + 8 * i));
18800 rtx mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
18801 ? DFmode : SFmode), addr);
18803 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
18805 for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++)
18807 rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i);
18808 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18809 GEN_INT (info->altivec_save_offset
18810 + sp_offset + 16 * i));
18811 rtx mem = gen_frame_mem (V4SImode, addr);
18813 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
18815 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
18817 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
18818 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18819 GEN_INT (info->gp_save_offset
18820 + sp_offset + reg_size * i));
18821 rtx mem = gen_frame_mem (reg_mode, addr);
18823 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
18827 /* CR register traditionally saved as CR2. */
18828 rtx reg = gen_rtx_REG (reg_mode, CR2_REGNO);
18829 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18830 GEN_INT (info->cr_save_offset
18831 + sp_offset));
18832 rtx mem = gen_frame_mem (reg_mode, addr);
18834 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
18836 /* Explain about use of R0. */
18837 if (info->lr_save_p)
18839 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18840 GEN_INT (info->lr_save_offset
18841 + sp_offset));
18842 rtx mem = gen_frame_mem (reg_mode, addr);
18844 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg0);
18846 /* Explain what happens to the stack pointer. */
18848 rtx newval = gen_rtx_PLUS (Pmode, sp_reg_rtx, treg);
18849 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, sp_reg_rtx, newval);
18852 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
18853 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
18854 treg, GEN_INT (-info->total_size));
18855 sp_offset = info->total_size;
18858 /* If we use the link register, get it into r0. */
18859 if (!WORLD_SAVE_P (info) && info->lr_save_p)
18861 rtx addr, reg, mem;
18863 insn = emit_move_insn (gen_rtx_REG (Pmode, 0),
18864 gen_rtx_REG (Pmode, LR_REGNO));
18865 RTX_FRAME_RELATED_P (insn) = 1;
18867 if (!(strategy & (SAVRES_NOINLINE_GPRS_SAVES_LR
18868 | SAVRES_NOINLINE_FPRS_SAVES_LR)))
18870 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18871 GEN_INT (info->lr_save_offset + sp_offset));
18872 reg = gen_rtx_REG (Pmode, 0);
18873 mem = gen_rtx_MEM (Pmode, addr);
18874 /* This should not be of rs6000_sr_alias_set, because of
18875 __builtin_return_address. */
18877 insn = emit_move_insn (mem, reg);
18878 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
18879 NULL_RTX, NULL_RTX);
18883 /* If we need to save CR, put it into r12 or r11. */
18884 if (!WORLD_SAVE_P (info) && info->cr_save_p && frame_reg_rtx != frame_ptr_rtx)
18886 rtx set;
18888 cr_save_rtx
18889 = gen_rtx_REG (SImode, DEFAULT_ABI == ABI_AIX && !saving_GPRs_inline
18890 ? 11 : 12);
18891 insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
18892 RTX_FRAME_RELATED_P (insn) = 1;
18893 /* Now, there's no way that dwarf2out_frame_debug_expr is going
18894 to understand '(unspec:SI [(reg:CC 68) ...] UNSPEC_MOVESI_FROM_CR)'.
18895 But that's OK. All we have to do is specify that _one_ condition
18896 code register is saved in this stack slot. The thrower's epilogue
18897 will then restore all the call-saved registers.
18898 We use CR2_REGNO (70) to be compatible with gcc-2.95 on Linux. */
18899 set = gen_rtx_SET (VOIDmode, cr_save_rtx,
18900 gen_rtx_REG (SImode, CR2_REGNO));
18901 add_reg_note (insn, REG_FRAME_RELATED_EXPR, set);
18904 /* Do any required saving of fpr's. If only one or two to save, do
18905 it ourselves. Otherwise, call function. */
18906 if (!WORLD_SAVE_P (info) && saving_FPRs_inline)
18908 int i;
18909 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
18910 if ((df_regs_ever_live_p (info->first_fp_reg_save+i)
18911 && ! call_used_regs[info->first_fp_reg_save+i]))
18912 emit_frame_save (frame_reg_rtx, frame_ptr_rtx,
18913 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
18914 ? DFmode : SFmode,
18915 info->first_fp_reg_save + i,
18916 info->fp_save_offset + sp_offset + 8 * i,
18917 info->total_size);
18919 else if (!WORLD_SAVE_P (info) && info->first_fp_reg_save != 64)
18921 rtx par;
18923 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
18924 info->fp_save_offset + sp_offset,
18925 DFmode,
18926 /*savep=*/true, /*gpr=*/false,
18927 /*lr=*/(strategy
18928 & SAVRES_NOINLINE_FPRS_SAVES_LR)
18929 != 0);
18930 insn = emit_insn (par);
18931 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
18932 NULL_RTX, NULL_RTX);
18935 /* Save GPRs. This is done as a PARALLEL if we are using
18936 the store-multiple instructions. */
18937 if (!WORLD_SAVE_P (info)
18938 && TARGET_SPE_ABI
18939 && info->spe_64bit_regs_used != 0
18940 && info->first_gp_reg_save != 32)
18942 int i;
18943 rtx spe_save_area_ptr;
18945 /* Determine whether we can address all of the registers that need
18946 to be saved with an offset from the stack pointer that fits in
18947 the small const field for SPE memory instructions. */
18948 int spe_regs_addressable_via_sp
18949 = (SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset
18950 + (32 - info->first_gp_reg_save - 1) * reg_size)
18951 && saving_GPRs_inline);
18952 int spe_offset;
18954 if (spe_regs_addressable_via_sp)
18956 spe_save_area_ptr = frame_reg_rtx;
18957 spe_offset = info->spe_gp_save_offset + sp_offset;
18959 else
18961 /* Make r11 point to the start of the SPE save area. We need
18962 to be careful here if r11 is holding the static chain. If
18963 it is, then temporarily save it in r0. We would use r0 as
18964 our base register here, but using r0 as a base register in
18965 loads and stores means something different from what we
18966 would like. */
18967 int ool_adjust = (saving_GPRs_inline
18969 : (info->first_gp_reg_save
18970 - (FIRST_SAVRES_REGISTER+1))*8);
18971 HOST_WIDE_INT offset = (info->spe_gp_save_offset
18972 + sp_offset - ool_adjust);
18974 if (using_static_chain_p)
18976 rtx r0 = gen_rtx_REG (Pmode, 0);
18977 gcc_assert (info->first_gp_reg_save > 11);
18979 emit_move_insn (r0, gen_rtx_REG (Pmode, 11));
18982 spe_save_area_ptr = gen_rtx_REG (Pmode, 11);
18983 insn = emit_insn (gen_addsi3 (spe_save_area_ptr,
18984 frame_reg_rtx,
18985 GEN_INT (offset)));
18986 /* We need to make sure the move to r11 gets noted for
18987 properly outputting unwind information. */
18988 if (!saving_GPRs_inline)
18989 rs6000_frame_related (insn, frame_reg_rtx, offset,
18990 NULL_RTX, NULL_RTX);
18991 spe_offset = 0;
18994 if (saving_GPRs_inline)
18996 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
18997 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
18999 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
19000 rtx offset, addr, mem;
19002 /* We're doing all this to ensure that the offset fits into
19003 the immediate offset of 'evstdd'. */
19004 gcc_assert (SPE_CONST_OFFSET_OK (reg_size * i + spe_offset));
19006 offset = GEN_INT (reg_size * i + spe_offset);
19007 addr = gen_rtx_PLUS (Pmode, spe_save_area_ptr, offset);
19008 mem = gen_rtx_MEM (V2SImode, addr);
19010 insn = emit_move_insn (mem, reg);
19012 rs6000_frame_related (insn, spe_save_area_ptr,
19013 info->spe_gp_save_offset
19014 + sp_offset + reg_size * i,
19015 offset, const0_rtx);
19018 else
19020 rtx par;
19022 par = rs6000_make_savres_rtx (info, gen_rtx_REG (Pmode, 11),
19023 0, reg_mode,
19024 /*savep=*/true, /*gpr=*/true,
19025 /*lr=*/false);
19026 insn = emit_insn (par);
19027 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19028 NULL_RTX, NULL_RTX);
19032 /* Move the static chain pointer back. */
19033 if (using_static_chain_p && !spe_regs_addressable_via_sp)
19034 emit_move_insn (gen_rtx_REG (Pmode, 11), gen_rtx_REG (Pmode, 0));
19036 else if (!WORLD_SAVE_P (info) && !saving_GPRs_inline)
19038 rtx par;
19040 /* Need to adjust r11 (r12) if we saved any FPRs. */
19041 if (info->first_fp_reg_save != 64)
19043 rtx dest_reg = gen_rtx_REG (reg_mode, DEFAULT_ABI == ABI_AIX
19044 ? 12 : 11);
19045 rtx offset = GEN_INT (sp_offset
19046 + (-8 * (64-info->first_fp_reg_save)));
19047 emit_insn (gen_add3_insn (dest_reg, frame_reg_rtx, offset));
19050 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
19051 info->gp_save_offset + sp_offset,
19052 reg_mode,
19053 /*savep=*/true, /*gpr=*/true,
19054 /*lr=*/(strategy
19055 & SAVRES_NOINLINE_GPRS_SAVES_LR)
19056 != 0);
19057 insn = emit_insn (par);
19058 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19059 NULL_RTX, NULL_RTX);
19061 else if (!WORLD_SAVE_P (info) && using_store_multiple)
19063 rtvec p;
19064 int i;
19065 p = rtvec_alloc (32 - info->first_gp_reg_save);
19066 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
19068 rtx addr, reg, mem;
19069 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
19070 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19071 GEN_INT (info->gp_save_offset
19072 + sp_offset
19073 + reg_size * i));
19074 mem = gen_frame_mem (reg_mode, addr);
19076 RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, mem, reg);
19078 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
19079 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19080 NULL_RTX, NULL_RTX);
19082 else if (!WORLD_SAVE_P (info))
19084 int i;
19085 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
19086 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
19088 rtx addr, reg, mem;
19089 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
19091 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19092 GEN_INT (info->gp_save_offset
19093 + sp_offset
19094 + reg_size * i));
19095 mem = gen_frame_mem (reg_mode, addr);
19097 insn = emit_move_insn (mem, reg);
19098 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19099 NULL_RTX, NULL_RTX);
19103 /* ??? There's no need to emit actual instructions here, but it's the
19104 easiest way to get the frame unwind information emitted. */
19105 if (crtl->calls_eh_return)
19107 unsigned int i, regno;
19109 /* In AIX ABI we need to pretend we save r2 here. */
19110 if (TARGET_AIX)
19112 rtx addr, reg, mem;
19114 reg = gen_rtx_REG (reg_mode, 2);
19115 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19116 GEN_INT (sp_offset + 5 * reg_size));
19117 mem = gen_frame_mem (reg_mode, addr);
19119 insn = emit_move_insn (mem, reg);
19120 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19121 NULL_RTX, NULL_RTX);
19122 PATTERN (insn) = gen_blockage ();
19125 for (i = 0; ; ++i)
19127 regno = EH_RETURN_DATA_REGNO (i);
19128 if (regno == INVALID_REGNUM)
19129 break;
19131 emit_frame_save (frame_reg_rtx, frame_ptr_rtx, reg_mode, regno,
19132 info->ehrd_offset + sp_offset
19133 + reg_size * (int) i,
19134 info->total_size);
19138 /* Save CR if we use any that must be preserved. */
19139 if (!WORLD_SAVE_P (info) && info->cr_save_p)
19141 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19142 GEN_INT (info->cr_save_offset + sp_offset));
19143 rtx mem = gen_frame_mem (SImode, addr);
19144 /* See the large comment above about why CR2_REGNO is used. */
19145 rtx magic_eh_cr_reg = gen_rtx_REG (SImode, CR2_REGNO);
19147 /* If r12 was used to hold the original sp, copy cr into r0 now
19148 that it's free. */
19149 if (REGNO (frame_reg_rtx) == 12)
19151 rtx set;
19153 cr_save_rtx = gen_rtx_REG (SImode, 0);
19154 insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
19155 RTX_FRAME_RELATED_P (insn) = 1;
19156 set = gen_rtx_SET (VOIDmode, cr_save_rtx, magic_eh_cr_reg);
19157 add_reg_note (insn, REG_FRAME_RELATED_EXPR, set);
19159 insn = emit_move_insn (mem, cr_save_rtx);
19161 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19162 NULL_RTX, NULL_RTX);
19165 /* Update stack and set back pointer unless this is V.4,
19166 for which it was done previously. */
19167 if (!WORLD_SAVE_P (info) && info->push_p
19168 && !(DEFAULT_ABI == ABI_V4 || crtl->calls_eh_return))
19170 if (info->total_size < 32767)
19171 sp_offset = info->total_size;
19172 else
19173 frame_reg_rtx = frame_ptr_rtx;
19174 rs6000_emit_allocate_stack (info->total_size,
19175 (frame_reg_rtx != sp_reg_rtx
19176 && ((info->altivec_size != 0)
19177 || (info->vrsave_mask != 0)
19179 FALSE);
19180 if (frame_reg_rtx != sp_reg_rtx)
19181 rs6000_emit_stack_tie ();
19184 /* Set frame pointer, if needed. */
19185 if (frame_pointer_needed)
19187 insn = emit_move_insn (gen_rtx_REG (Pmode, HARD_FRAME_POINTER_REGNUM),
19188 sp_reg_rtx);
19189 RTX_FRAME_RELATED_P (insn) = 1;
19192 /* Save AltiVec registers if needed. Save here because the red zone does
19193 not include AltiVec registers. */
19194 if (!WORLD_SAVE_P (info) && TARGET_ALTIVEC_ABI && info->altivec_size != 0)
19196 int i;
19198 /* There should be a non inline version of this, for when we
19199 are saving lots of vector registers. */
19200 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
19201 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
19203 rtx areg, savereg, mem;
19204 int offset;
19206 offset = info->altivec_save_offset + sp_offset
19207 + 16 * (i - info->first_altivec_reg_save);
19209 savereg = gen_rtx_REG (V4SImode, i);
19211 areg = gen_rtx_REG (Pmode, 0);
19212 emit_move_insn (areg, GEN_INT (offset));
19214 /* AltiVec addressing mode is [reg+reg]. */
19215 mem = gen_frame_mem (V4SImode,
19216 gen_rtx_PLUS (Pmode, frame_reg_rtx, areg));
19218 insn = emit_move_insn (mem, savereg);
19220 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19221 areg, GEN_INT (offset));
19225 /* VRSAVE is a bit vector representing which AltiVec registers
19226 are used. The OS uses this to determine which vector
19227 registers to save on a context switch. We need to save
19228 VRSAVE on the stack frame, add whatever AltiVec registers we
19229 used in this function, and do the corresponding magic in the
19230 epilogue. */
19232 if (TARGET_ALTIVEC && TARGET_ALTIVEC_VRSAVE
19233 && info->vrsave_mask != 0)
19235 rtx reg, mem, vrsave;
19236 int offset;
19238 /* Get VRSAVE onto a GPR. Note that ABI_V4 might be using r12
19239 as frame_reg_rtx and r11 as the static chain pointer for
19240 nested functions. */
19241 reg = gen_rtx_REG (SImode, 0);
19242 vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
19243 if (TARGET_MACHO)
19244 emit_insn (gen_get_vrsave_internal (reg));
19245 else
19246 emit_insn (gen_rtx_SET (VOIDmode, reg, vrsave));
19248 if (!WORLD_SAVE_P (info))
19250 /* Save VRSAVE. */
19251 offset = info->vrsave_save_offset + sp_offset;
19252 mem = gen_frame_mem (SImode,
19253 gen_rtx_PLUS (Pmode, frame_reg_rtx,
19254 GEN_INT (offset)));
19255 insn = emit_move_insn (mem, reg);
19258 /* Include the registers in the mask. */
19259 emit_insn (gen_iorsi3 (reg, reg, GEN_INT ((int) info->vrsave_mask)));
19261 insn = emit_insn (generate_set_vrsave (reg, info, 0));
19264 /* If we are using RS6000_PIC_OFFSET_TABLE_REGNUM, we need to set it up. */
19265 if ((TARGET_TOC && TARGET_MINIMAL_TOC && get_pool_size () != 0)
19266 || (DEFAULT_ABI == ABI_V4
19267 && (flag_pic == 1 || (flag_pic && TARGET_SECURE_PLT))
19268 && df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM)))
19270 /* If emit_load_toc_table will use the link register, we need to save
19271 it. We use R12 for this purpose because emit_load_toc_table
19272 can use register 0. This allows us to use a plain 'blr' to return
19273 from the procedure more often. */
19274 int save_LR_around_toc_setup = (TARGET_ELF
19275 && DEFAULT_ABI != ABI_AIX
19276 && flag_pic
19277 && ! info->lr_save_p
19278 && EDGE_COUNT (EXIT_BLOCK_PTR->preds) > 0);
19279 if (save_LR_around_toc_setup)
19281 rtx lr = gen_rtx_REG (Pmode, LR_REGNO);
19283 insn = emit_move_insn (frame_ptr_rtx, lr);
19284 RTX_FRAME_RELATED_P (insn) = 1;
19286 rs6000_emit_load_toc_table (TRUE);
19288 insn = emit_move_insn (lr, frame_ptr_rtx);
19289 RTX_FRAME_RELATED_P (insn) = 1;
19291 else
19292 rs6000_emit_load_toc_table (TRUE);
19295 #if TARGET_MACHO
19296 if (DEFAULT_ABI == ABI_DARWIN
19297 && flag_pic && crtl->uses_pic_offset_table)
19299 rtx lr = gen_rtx_REG (Pmode, LR_REGNO);
19300 rtx src = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
19302 /* Save and restore LR locally around this call (in R0). */
19303 if (!info->lr_save_p)
19304 emit_move_insn (gen_rtx_REG (Pmode, 0), lr);
19306 emit_insn (gen_load_macho_picbase (src));
19308 emit_move_insn (gen_rtx_REG (Pmode,
19309 RS6000_PIC_OFFSET_TABLE_REGNUM),
19310 lr);
19312 if (!info->lr_save_p)
19313 emit_move_insn (lr, gen_rtx_REG (Pmode, 0));
19315 #endif
19318 /* Write function prologue. */
19320 static void
19321 rs6000_output_function_prologue (FILE *file,
19322 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
19324 rs6000_stack_t *info = rs6000_stack_info ();
19326 if (TARGET_DEBUG_STACK)
19327 debug_stack_info (info);
19329 /* Write .extern for any function we will call to save and restore
19330 fp values. */
19331 if (info->first_fp_reg_save < 64
19332 && !FP_SAVE_INLINE (info->first_fp_reg_save))
19334 char *name;
19335 int regno = info->first_fp_reg_save - 32;
19337 name = rs6000_savres_routine_name (info, regno, /*savep=*/true,
19338 /*gpr=*/false, /*lr=*/false);
19339 fprintf (file, "\t.extern %s\n", name);
19341 name = rs6000_savres_routine_name (info, regno, /*savep=*/false,
19342 /*gpr=*/false, /*lr=*/true);
19343 fprintf (file, "\t.extern %s\n", name);
19346 /* Write .extern for AIX common mode routines, if needed. */
19347 if (! TARGET_POWER && ! TARGET_POWERPC && ! common_mode_defined)
19349 fputs ("\t.extern __mulh\n", file);
19350 fputs ("\t.extern __mull\n", file);
19351 fputs ("\t.extern __divss\n", file);
19352 fputs ("\t.extern __divus\n", file);
19353 fputs ("\t.extern __quoss\n", file);
19354 fputs ("\t.extern __quous\n", file);
19355 common_mode_defined = 1;
19358 if (! HAVE_prologue)
19360 rtx prologue;
19362 start_sequence ();
19364 /* A NOTE_INSN_DELETED is supposed to be at the start and end of
19365 the "toplevel" insn chain. */
19366 emit_note (NOTE_INSN_DELETED);
19367 rs6000_emit_prologue ();
19368 emit_note (NOTE_INSN_DELETED);
19370 /* Expand INSN_ADDRESSES so final() doesn't crash. */
19372 rtx insn;
19373 unsigned addr = 0;
19374 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
19376 INSN_ADDRESSES_NEW (insn, addr);
19377 addr += 4;
19381 prologue = get_insns ();
19382 end_sequence ();
19384 if (TARGET_DEBUG_STACK)
19385 debug_rtx_list (prologue, 100);
19387 emit_insn_before_noloc (prologue, BB_HEAD (ENTRY_BLOCK_PTR->next_bb),
19388 ENTRY_BLOCK_PTR);
19391 rs6000_pic_labelno++;
19394 /* Non-zero if vmx regs are restored before the frame pop, zero if
19395 we restore after the pop when possible. */
19396 #define ALWAYS_RESTORE_ALTIVEC_BEFORE_POP 0
19398 /* Reload CR from REG. */
19400 static void
19401 rs6000_restore_saved_cr (rtx reg, int using_mfcr_multiple)
19403 int count = 0;
19404 int i;
19406 if (using_mfcr_multiple)
19408 for (i = 0; i < 8; i++)
19409 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
19410 count++;
19411 gcc_assert (count);
19414 if (using_mfcr_multiple && count > 1)
19416 rtvec p;
19417 int ndx;
19419 p = rtvec_alloc (count);
19421 ndx = 0;
19422 for (i = 0; i < 8; i++)
19423 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
19425 rtvec r = rtvec_alloc (2);
19426 RTVEC_ELT (r, 0) = reg;
19427 RTVEC_ELT (r, 1) = GEN_INT (1 << (7-i));
19428 RTVEC_ELT (p, ndx) =
19429 gen_rtx_SET (VOIDmode, gen_rtx_REG (CCmode, CR0_REGNO+i),
19430 gen_rtx_UNSPEC (CCmode, r, UNSPEC_MOVESI_TO_CR));
19431 ndx++;
19433 emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
19434 gcc_assert (ndx == count);
19436 else
19437 for (i = 0; i < 8; i++)
19438 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
19440 emit_insn (gen_movsi_to_cr_one (gen_rtx_REG (CCmode,
19441 CR0_REGNO+i),
19442 reg));
19446 /* Return true if OFFSET from stack pointer can be clobbered by signals.
19447 V.4 doesn't have any stack cushion, AIX ABIs have 220 or 288 bytes
19448 below stack pointer not cloberred by signals. */
19450 static inline bool
19451 offset_below_red_zone_p (HOST_WIDE_INT offset)
19453 return offset < (DEFAULT_ABI == ABI_V4
19455 : TARGET_32BIT ? -220 : -288);
19458 /* Emit function epilogue as insns. */
19460 void
19461 rs6000_emit_epilogue (int sibcall)
19463 rs6000_stack_t *info;
19464 int restoring_GPRs_inline;
19465 int restoring_FPRs_inline;
19466 int using_load_multiple;
19467 int using_mtcr_multiple;
19468 int use_backchain_to_restore_sp;
19469 int restore_lr;
19470 int strategy;
19471 int sp_offset = 0;
19472 rtx sp_reg_rtx = gen_rtx_REG (Pmode, 1);
19473 rtx frame_reg_rtx = sp_reg_rtx;
19474 rtx cfa_restores = NULL_RTX;
19475 rtx insn;
19476 rtx cr_save_reg = NULL_RTX;
19477 enum machine_mode reg_mode = Pmode;
19478 int reg_size = TARGET_32BIT ? 4 : 8;
19479 int i;
19481 info = rs6000_stack_info ();
19483 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
19485 reg_mode = V2SImode;
19486 reg_size = 8;
19489 strategy = rs6000_savres_strategy (info, /*savep=*/false,
19490 /*static_chain_p=*/0, sibcall);
19491 using_load_multiple = strategy & SAVRES_MULTIPLE;
19492 restoring_FPRs_inline = strategy & SAVRES_INLINE_FPRS;
19493 restoring_GPRs_inline = strategy & SAVRES_INLINE_GPRS;
19494 using_mtcr_multiple = (rs6000_cpu == PROCESSOR_PPC601
19495 || rs6000_cpu == PROCESSOR_PPC603
19496 || rs6000_cpu == PROCESSOR_PPC750
19497 || optimize_size);
19498 /* Restore via the backchain when we have a large frame, since this
19499 is more efficient than an addis, addi pair. The second condition
19500 here will not trigger at the moment; We don't actually need a
19501 frame pointer for alloca, but the generic parts of the compiler
19502 give us one anyway. */
19503 use_backchain_to_restore_sp = (info->total_size > 32767
19504 || info->total_size
19505 + (info->lr_save_p ? info->lr_save_offset : 0)
19506 > 32767
19507 || (cfun->calls_alloca
19508 && !frame_pointer_needed));
19509 restore_lr = (info->lr_save_p
19510 && (restoring_FPRs_inline
19511 || (strategy & SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR))
19512 && (restoring_GPRs_inline
19513 || info->first_fp_reg_save < 64));
19515 if (WORLD_SAVE_P (info))
19517 int i, j;
19518 char rname[30];
19519 const char *alloc_rname;
19520 rtvec p;
19522 /* eh_rest_world_r10 will return to the location saved in the LR
19523 stack slot (which is not likely to be our caller.)
19524 Input: R10 -- stack adjustment. Clobbers R0, R11, R12, R7, R8.
19525 rest_world is similar, except any R10 parameter is ignored.
19526 The exception-handling stuff that was here in 2.95 is no
19527 longer necessary. */
19529 p = rtvec_alloc (9
19531 + 32 - info->first_gp_reg_save
19532 + LAST_ALTIVEC_REGNO + 1 - info->first_altivec_reg_save
19533 + 63 + 1 - info->first_fp_reg_save);
19535 strcpy (rname, ((crtl->calls_eh_return) ?
19536 "*eh_rest_world_r10" : "*rest_world"));
19537 alloc_rname = ggc_strdup (rname);
19539 j = 0;
19540 RTVEC_ELT (p, j++) = gen_rtx_RETURN (VOIDmode);
19541 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
19542 gen_rtx_REG (Pmode,
19543 LR_REGNO));
19544 RTVEC_ELT (p, j++)
19545 = gen_rtx_USE (VOIDmode, gen_rtx_SYMBOL_REF (Pmode, alloc_rname));
19546 /* The instruction pattern requires a clobber here;
19547 it is shared with the restVEC helper. */
19548 RTVEC_ELT (p, j++)
19549 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 11));
19552 /* CR register traditionally saved as CR2. */
19553 rtx reg = gen_rtx_REG (reg_mode, CR2_REGNO);
19554 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19555 GEN_INT (info->cr_save_offset));
19556 rtx mem = gen_frame_mem (reg_mode, addr);
19558 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
19561 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
19563 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
19564 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19565 GEN_INT (info->gp_save_offset
19566 + reg_size * i));
19567 rtx mem = gen_frame_mem (reg_mode, addr);
19569 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
19571 for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++)
19573 rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i);
19574 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19575 GEN_INT (info->altivec_save_offset
19576 + 16 * i));
19577 rtx mem = gen_frame_mem (V4SImode, addr);
19579 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
19581 for (i = 0; info->first_fp_reg_save + i <= 63; i++)
19583 rtx reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
19584 ? DFmode : SFmode),
19585 info->first_fp_reg_save + i);
19586 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19587 GEN_INT (info->fp_save_offset
19588 + 8 * i));
19589 rtx mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
19590 ? DFmode : SFmode), addr);
19592 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
19594 RTVEC_ELT (p, j++)
19595 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 0));
19596 RTVEC_ELT (p, j++)
19597 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 12));
19598 RTVEC_ELT (p, j++)
19599 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 7));
19600 RTVEC_ELT (p, j++)
19601 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 8));
19602 RTVEC_ELT (p, j++)
19603 = gen_rtx_USE (VOIDmode, gen_rtx_REG (SImode, 10));
19604 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
19606 return;
19609 /* frame_reg_rtx + sp_offset points to the top of this stack frame. */
19610 if (info->push_p)
19611 sp_offset = info->total_size;
19613 /* Restore AltiVec registers if we must do so before adjusting the
19614 stack. */
19615 if (TARGET_ALTIVEC_ABI
19616 && info->altivec_size != 0
19617 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
19618 || (DEFAULT_ABI != ABI_V4
19619 && offset_below_red_zone_p (info->altivec_save_offset))))
19621 int i;
19623 if (use_backchain_to_restore_sp)
19625 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
19626 emit_move_insn (frame_reg_rtx,
19627 gen_rtx_MEM (Pmode, sp_reg_rtx));
19628 sp_offset = 0;
19630 else if (frame_pointer_needed)
19631 frame_reg_rtx = hard_frame_pointer_rtx;
19633 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
19634 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
19636 rtx addr, areg, mem, reg;
19638 areg = gen_rtx_REG (Pmode, 0);
19639 emit_move_insn
19640 (areg, GEN_INT (info->altivec_save_offset
19641 + sp_offset
19642 + 16 * (i - info->first_altivec_reg_save)));
19644 /* AltiVec addressing mode is [reg+reg]. */
19645 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
19646 mem = gen_frame_mem (V4SImode, addr);
19648 reg = gen_rtx_REG (V4SImode, i);
19649 emit_move_insn (reg, mem);
19650 if (offset_below_red_zone_p (info->altivec_save_offset
19651 + (i - info->first_altivec_reg_save)
19652 * 16))
19653 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
19654 cfa_restores);
19658 /* Restore VRSAVE if we must do so before adjusting the stack. */
19659 if (TARGET_ALTIVEC
19660 && TARGET_ALTIVEC_VRSAVE
19661 && info->vrsave_mask != 0
19662 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
19663 || (DEFAULT_ABI != ABI_V4
19664 && offset_below_red_zone_p (info->vrsave_save_offset))))
19666 rtx addr, mem, reg;
19668 if (frame_reg_rtx == sp_reg_rtx)
19670 if (use_backchain_to_restore_sp)
19672 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
19673 emit_move_insn (frame_reg_rtx,
19674 gen_rtx_MEM (Pmode, sp_reg_rtx));
19675 sp_offset = 0;
19677 else if (frame_pointer_needed)
19678 frame_reg_rtx = hard_frame_pointer_rtx;
19681 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19682 GEN_INT (info->vrsave_save_offset + sp_offset));
19683 mem = gen_frame_mem (SImode, addr);
19684 reg = gen_rtx_REG (SImode, 12);
19685 emit_move_insn (reg, mem);
19687 emit_insn (generate_set_vrsave (reg, info, 1));
19690 insn = NULL_RTX;
19691 /* If we have a large stack frame, restore the old stack pointer
19692 using the backchain. */
19693 if (use_backchain_to_restore_sp)
19695 if (frame_reg_rtx == sp_reg_rtx)
19697 /* Under V.4, don't reset the stack pointer until after we're done
19698 loading the saved registers. */
19699 if (DEFAULT_ABI == ABI_V4)
19700 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
19702 insn = emit_move_insn (frame_reg_rtx,
19703 gen_rtx_MEM (Pmode, sp_reg_rtx));
19704 sp_offset = 0;
19706 else if (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
19707 && DEFAULT_ABI == ABI_V4)
19708 /* frame_reg_rtx has been set up by the altivec restore. */
19710 else
19712 insn = emit_move_insn (sp_reg_rtx, frame_reg_rtx);
19713 frame_reg_rtx = sp_reg_rtx;
19716 /* If we have a frame pointer, we can restore the old stack pointer
19717 from it. */
19718 else if (frame_pointer_needed)
19720 frame_reg_rtx = sp_reg_rtx;
19721 if (DEFAULT_ABI == ABI_V4)
19722 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
19724 insn = emit_insn (gen_add3_insn (frame_reg_rtx, hard_frame_pointer_rtx,
19725 GEN_INT (info->total_size)));
19726 sp_offset = 0;
19728 else if (info->push_p
19729 && DEFAULT_ABI != ABI_V4
19730 && !crtl->calls_eh_return)
19732 insn = emit_insn (gen_add3_insn (sp_reg_rtx, sp_reg_rtx,
19733 GEN_INT (info->total_size)));
19734 sp_offset = 0;
19736 if (insn && frame_reg_rtx == sp_reg_rtx)
19738 if (cfa_restores)
19740 REG_NOTES (insn) = cfa_restores;
19741 cfa_restores = NULL_RTX;
19743 add_reg_note (insn, REG_CFA_DEF_CFA, sp_reg_rtx);
19744 RTX_FRAME_RELATED_P (insn) = 1;
19747 /* Restore AltiVec registers if we have not done so already. */
19748 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
19749 && TARGET_ALTIVEC_ABI
19750 && info->altivec_size != 0
19751 && (DEFAULT_ABI == ABI_V4
19752 || !offset_below_red_zone_p (info->altivec_save_offset)))
19754 int i;
19756 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
19757 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
19759 rtx addr, areg, mem, reg;
19761 areg = gen_rtx_REG (Pmode, 0);
19762 emit_move_insn
19763 (areg, GEN_INT (info->altivec_save_offset
19764 + sp_offset
19765 + 16 * (i - info->first_altivec_reg_save)));
19767 /* AltiVec addressing mode is [reg+reg]. */
19768 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
19769 mem = gen_frame_mem (V4SImode, addr);
19771 reg = gen_rtx_REG (V4SImode, i);
19772 emit_move_insn (reg, mem);
19773 if (DEFAULT_ABI == ABI_V4)
19774 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
19775 cfa_restores);
19779 /* Restore VRSAVE if we have not done so already. */
19780 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
19781 && TARGET_ALTIVEC
19782 && TARGET_ALTIVEC_VRSAVE
19783 && info->vrsave_mask != 0
19784 && (DEFAULT_ABI == ABI_V4
19785 || !offset_below_red_zone_p (info->vrsave_save_offset)))
19787 rtx addr, mem, reg;
19789 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19790 GEN_INT (info->vrsave_save_offset + sp_offset));
19791 mem = gen_frame_mem (SImode, addr);
19792 reg = gen_rtx_REG (SImode, 12);
19793 emit_move_insn (reg, mem);
19795 emit_insn (generate_set_vrsave (reg, info, 1));
19798 /* Get the old lr if we saved it. If we are restoring registers
19799 out-of-line, then the out-of-line routines can do this for us. */
19800 if (restore_lr && restoring_GPRs_inline)
19802 rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
19803 info->lr_save_offset + sp_offset);
19805 emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
19808 /* Get the old cr if we saved it. */
19809 if (info->cr_save_p)
19811 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19812 GEN_INT (info->cr_save_offset + sp_offset));
19813 rtx mem = gen_frame_mem (SImode, addr);
19815 cr_save_reg = gen_rtx_REG (SImode,
19816 DEFAULT_ABI == ABI_AIX
19817 && !restoring_GPRs_inline
19818 && info->first_fp_reg_save < 64
19819 ? 11 : 12);
19820 emit_move_insn (cr_save_reg, mem);
19823 /* Set LR here to try to overlap restores below. LR is always saved
19824 above incoming stack, so it never needs REG_CFA_RESTORE. */
19825 if (restore_lr && restoring_GPRs_inline)
19826 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO),
19827 gen_rtx_REG (Pmode, 0));
19829 /* Load exception handler data registers, if needed. */
19830 if (crtl->calls_eh_return)
19832 unsigned int i, regno;
19834 if (TARGET_AIX)
19836 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19837 GEN_INT (sp_offset + 5 * reg_size));
19838 rtx mem = gen_frame_mem (reg_mode, addr);
19840 emit_move_insn (gen_rtx_REG (reg_mode, 2), mem);
19843 for (i = 0; ; ++i)
19845 rtx mem;
19847 regno = EH_RETURN_DATA_REGNO (i);
19848 if (regno == INVALID_REGNUM)
19849 break;
19851 mem = gen_frame_mem_offset (reg_mode, frame_reg_rtx,
19852 info->ehrd_offset + sp_offset
19853 + reg_size * (int) i);
19855 emit_move_insn (gen_rtx_REG (reg_mode, regno), mem);
19859 /* Restore GPRs. This is done as a PARALLEL if we are using
19860 the load-multiple instructions. */
19861 if (TARGET_SPE_ABI
19862 && info->spe_64bit_regs_used != 0
19863 && info->first_gp_reg_save != 32)
19865 /* Determine whether we can address all of the registers that need
19866 to be saved with an offset from the stack pointer that fits in
19867 the small const field for SPE memory instructions. */
19868 int spe_regs_addressable_via_sp
19869 = (SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset
19870 + (32 - info->first_gp_reg_save - 1) * reg_size)
19871 && restoring_GPRs_inline);
19872 int spe_offset;
19874 if (spe_regs_addressable_via_sp)
19875 spe_offset = info->spe_gp_save_offset + sp_offset;
19876 else
19878 rtx old_frame_reg_rtx = frame_reg_rtx;
19879 /* Make r11 point to the start of the SPE save area. We worried about
19880 not clobbering it when we were saving registers in the prologue.
19881 There's no need to worry here because the static chain is passed
19882 anew to every function. */
19883 int ool_adjust = (restoring_GPRs_inline
19885 : (info->first_gp_reg_save
19886 - (FIRST_SAVRES_REGISTER+1))*8);
19888 if (frame_reg_rtx == sp_reg_rtx)
19889 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
19890 emit_insn (gen_addsi3 (frame_reg_rtx, old_frame_reg_rtx,
19891 GEN_INT (info->spe_gp_save_offset
19892 + sp_offset
19893 - ool_adjust)));
19894 /* Keep the invariant that frame_reg_rtx + sp_offset points
19895 at the top of the stack frame. */
19896 sp_offset = -info->spe_gp_save_offset;
19898 spe_offset = 0;
19901 if (restoring_GPRs_inline)
19903 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
19904 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
19906 rtx offset, addr, mem, reg;
19908 /* We're doing all this to ensure that the immediate offset
19909 fits into the immediate field of 'evldd'. */
19910 gcc_assert (SPE_CONST_OFFSET_OK (spe_offset + reg_size * i));
19912 offset = GEN_INT (spe_offset + reg_size * i);
19913 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, offset);
19914 mem = gen_rtx_MEM (V2SImode, addr);
19915 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
19917 insn = emit_move_insn (reg, mem);
19918 if (DEFAULT_ABI == ABI_V4)
19920 if (frame_pointer_needed
19921 && info->first_gp_reg_save + i
19922 == HARD_FRAME_POINTER_REGNUM)
19924 add_reg_note (insn, REG_CFA_DEF_CFA,
19925 plus_constant (frame_reg_rtx,
19926 sp_offset));
19927 RTX_FRAME_RELATED_P (insn) = 1;
19930 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
19931 cfa_restores);
19935 else
19937 rtx par;
19939 par = rs6000_make_savres_rtx (info, gen_rtx_REG (Pmode, 11),
19940 0, reg_mode,
19941 /*savep=*/false, /*gpr=*/true,
19942 /*lr=*/true);
19943 emit_jump_insn (par);
19944 /* We don't want anybody else emitting things after we jumped
19945 back. */
19946 return;
19949 else if (!restoring_GPRs_inline)
19951 /* We are jumping to an out-of-line function. */
19952 bool can_use_exit = info->first_fp_reg_save == 64;
19953 rtx par;
19955 /* Emit stack reset code if we need it. */
19956 if (can_use_exit)
19957 rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx,
19958 sp_offset, can_use_exit);
19959 else
19961 emit_insn (gen_add3_insn (gen_rtx_REG (Pmode, DEFAULT_ABI == ABI_AIX
19962 ? 12 : 11),
19963 frame_reg_rtx,
19964 GEN_INT (sp_offset - info->fp_size)));
19965 if (REGNO (frame_reg_rtx) == 11)
19966 sp_offset += info->fp_size;
19969 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
19970 info->gp_save_offset, reg_mode,
19971 /*savep=*/false, /*gpr=*/true,
19972 /*lr=*/can_use_exit);
19974 if (can_use_exit)
19976 if (info->cr_save_p)
19978 rs6000_restore_saved_cr (cr_save_reg, using_mtcr_multiple);
19979 if (DEFAULT_ABI == ABI_V4)
19980 cfa_restores
19981 = alloc_reg_note (REG_CFA_RESTORE,
19982 gen_rtx_REG (SImode, CR2_REGNO),
19983 cfa_restores);
19986 emit_jump_insn (par);
19988 /* We don't want anybody else emitting things after we jumped
19989 back. */
19990 return;
19993 insn = emit_insn (par);
19994 if (DEFAULT_ABI == ABI_V4)
19996 if (frame_pointer_needed)
19998 add_reg_note (insn, REG_CFA_DEF_CFA,
19999 plus_constant (frame_reg_rtx, sp_offset));
20000 RTX_FRAME_RELATED_P (insn) = 1;
20003 for (i = info->first_gp_reg_save; i < 32; i++)
20004 cfa_restores
20005 = alloc_reg_note (REG_CFA_RESTORE,
20006 gen_rtx_REG (reg_mode, i), cfa_restores);
20009 else if (using_load_multiple)
20011 rtvec p;
20012 p = rtvec_alloc (32 - info->first_gp_reg_save);
20013 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20015 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20016 GEN_INT (info->gp_save_offset
20017 + sp_offset
20018 + reg_size * i));
20019 rtx mem = gen_frame_mem (reg_mode, addr);
20020 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20022 RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, reg, mem);
20023 if (DEFAULT_ABI == ABI_V4)
20024 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
20025 cfa_restores);
20027 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
20028 if (DEFAULT_ABI == ABI_V4 && frame_pointer_needed)
20030 add_reg_note (insn, REG_CFA_DEF_CFA,
20031 plus_constant (frame_reg_rtx, sp_offset));
20032 RTX_FRAME_RELATED_P (insn) = 1;
20035 else
20037 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20038 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
20040 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20041 GEN_INT (info->gp_save_offset
20042 + sp_offset
20043 + reg_size * i));
20044 rtx mem = gen_frame_mem (reg_mode, addr);
20045 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20047 insn = emit_move_insn (reg, mem);
20048 if (DEFAULT_ABI == ABI_V4)
20050 if (frame_pointer_needed
20051 && info->first_gp_reg_save + i
20052 == HARD_FRAME_POINTER_REGNUM)
20054 add_reg_note (insn, REG_CFA_DEF_CFA,
20055 plus_constant (frame_reg_rtx, sp_offset));
20056 RTX_FRAME_RELATED_P (insn) = 1;
20059 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
20060 cfa_restores);
20065 if (restore_lr && !restoring_GPRs_inline)
20067 rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
20068 info->lr_save_offset + sp_offset);
20070 emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
20071 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO),
20072 gen_rtx_REG (Pmode, 0));
20075 /* Restore fpr's if we need to do it without calling a function. */
20076 if (restoring_FPRs_inline)
20077 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
20078 if ((df_regs_ever_live_p (info->first_fp_reg_save+i)
20079 && ! call_used_regs[info->first_fp_reg_save+i]))
20081 rtx addr, mem, reg;
20082 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20083 GEN_INT (info->fp_save_offset
20084 + sp_offset
20085 + 8 * i));
20086 mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20087 ? DFmode : SFmode), addr);
20088 reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20089 ? DFmode : SFmode),
20090 info->first_fp_reg_save + i);
20092 emit_move_insn (reg, mem);
20093 if (DEFAULT_ABI == ABI_V4)
20094 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
20095 cfa_restores);
20098 /* If we saved cr, restore it here. Just those that were used. */
20099 if (info->cr_save_p)
20101 rs6000_restore_saved_cr (cr_save_reg, using_mtcr_multiple);
20102 if (DEFAULT_ABI == ABI_V4)
20103 cfa_restores
20104 = alloc_reg_note (REG_CFA_RESTORE, gen_rtx_REG (SImode, CR2_REGNO),
20105 cfa_restores);
20108 /* If this is V.4, unwind the stack pointer after all of the loads
20109 have been done. */
20110 insn = rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx,
20111 sp_offset, !restoring_FPRs_inline);
20112 if (insn)
20114 if (cfa_restores)
20116 REG_NOTES (insn) = cfa_restores;
20117 cfa_restores = NULL_RTX;
20119 add_reg_note (insn, REG_CFA_DEF_CFA, sp_reg_rtx);
20120 RTX_FRAME_RELATED_P (insn) = 1;
20123 if (crtl->calls_eh_return)
20125 rtx sa = EH_RETURN_STACKADJ_RTX;
20126 emit_insn (gen_add3_insn (sp_reg_rtx, sp_reg_rtx, sa));
20129 if (!sibcall)
20131 rtvec p;
20132 bool lr = (strategy & SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR) == 0;
20133 if (! restoring_FPRs_inline)
20134 p = rtvec_alloc (4 + 64 - info->first_fp_reg_save);
20135 else
20136 p = rtvec_alloc (2);
20138 RTVEC_ELT (p, 0) = gen_rtx_RETURN (VOIDmode);
20139 RTVEC_ELT (p, 1) = ((restoring_FPRs_inline || !lr)
20140 ? gen_rtx_USE (VOIDmode, gen_rtx_REG (Pmode, 65))
20141 : gen_rtx_CLOBBER (VOIDmode,
20142 gen_rtx_REG (Pmode, 65)));
20144 /* If we have to restore more than two FP registers, branch to the
20145 restore function. It will return to our caller. */
20146 if (! restoring_FPRs_inline)
20148 int i;
20149 rtx sym;
20151 sym = rs6000_savres_routine_sym (info,
20152 /*savep=*/false,
20153 /*gpr=*/false,
20154 /*lr=*/lr);
20155 RTVEC_ELT (p, 2) = gen_rtx_USE (VOIDmode, sym);
20156 RTVEC_ELT (p, 3) = gen_rtx_USE (VOIDmode,
20157 gen_rtx_REG (Pmode,
20158 DEFAULT_ABI == ABI_AIX
20159 ? 1 : 11));
20160 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
20162 rtx addr, mem;
20163 addr = gen_rtx_PLUS (Pmode, sp_reg_rtx,
20164 GEN_INT (info->fp_save_offset + 8*i));
20165 mem = gen_frame_mem (DFmode, addr);
20167 RTVEC_ELT (p, i+4) =
20168 gen_rtx_SET (VOIDmode,
20169 gen_rtx_REG (DFmode, info->first_fp_reg_save + i),
20170 mem);
20174 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
20178 /* Write function epilogue. */
20180 static void
20181 rs6000_output_function_epilogue (FILE *file,
20182 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
20184 if (! HAVE_epilogue)
20186 rtx insn = get_last_insn ();
20187 /* If the last insn was a BARRIER, we don't have to write anything except
20188 the trace table. */
20189 if (GET_CODE (insn) == NOTE)
20190 insn = prev_nonnote_insn (insn);
20191 if (insn == 0 || GET_CODE (insn) != BARRIER)
20193 /* This is slightly ugly, but at least we don't have two
20194 copies of the epilogue-emitting code. */
20195 start_sequence ();
20197 /* A NOTE_INSN_DELETED is supposed to be at the start
20198 and end of the "toplevel" insn chain. */
20199 emit_note (NOTE_INSN_DELETED);
20200 rs6000_emit_epilogue (FALSE);
20201 emit_note (NOTE_INSN_DELETED);
20203 /* Expand INSN_ADDRESSES so final() doesn't crash. */
20205 rtx insn;
20206 unsigned addr = 0;
20207 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
20209 INSN_ADDRESSES_NEW (insn, addr);
20210 addr += 4;
20214 if (TARGET_DEBUG_STACK)
20215 debug_rtx_list (get_insns (), 100);
20216 final (get_insns (), file, FALSE);
20217 end_sequence ();
20221 #if TARGET_MACHO
20222 macho_branch_islands ();
20223 /* Mach-O doesn't support labels at the end of objects, so if
20224 it looks like we might want one, insert a NOP. */
20226 rtx insn = get_last_insn ();
20227 while (insn
20228 && NOTE_P (insn)
20229 && NOTE_KIND (insn) != NOTE_INSN_DELETED_LABEL)
20230 insn = PREV_INSN (insn);
20231 if (insn
20232 && (LABEL_P (insn)
20233 || (NOTE_P (insn)
20234 && NOTE_KIND (insn) == NOTE_INSN_DELETED_LABEL)))
20235 fputs ("\tnop\n", file);
20237 #endif
20239 /* Output a traceback table here. See /usr/include/sys/debug.h for info
20240 on its format.
20242 We don't output a traceback table if -finhibit-size-directive was
20243 used. The documentation for -finhibit-size-directive reads
20244 ``don't output a @code{.size} assembler directive, or anything
20245 else that would cause trouble if the function is split in the
20246 middle, and the two halves are placed at locations far apart in
20247 memory.'' The traceback table has this property, since it
20248 includes the offset from the start of the function to the
20249 traceback table itself.
20251 System V.4 Powerpc's (and the embedded ABI derived from it) use a
20252 different traceback table. */
20253 if (DEFAULT_ABI == ABI_AIX && ! flag_inhibit_size_directive
20254 && rs6000_traceback != traceback_none && !cfun->is_thunk)
20256 const char *fname = NULL;
20257 const char *language_string = lang_hooks.name;
20258 int fixed_parms = 0, float_parms = 0, parm_info = 0;
20259 int i;
20260 int optional_tbtab;
20261 rs6000_stack_t *info = rs6000_stack_info ();
20263 if (rs6000_traceback == traceback_full)
20264 optional_tbtab = 1;
20265 else if (rs6000_traceback == traceback_part)
20266 optional_tbtab = 0;
20267 else
20268 optional_tbtab = !optimize_size && !TARGET_ELF;
20270 if (optional_tbtab)
20272 fname = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0);
20273 while (*fname == '.') /* V.4 encodes . in the name */
20274 fname++;
20276 /* Need label immediately before tbtab, so we can compute
20277 its offset from the function start. */
20278 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
20279 ASM_OUTPUT_LABEL (file, fname);
20282 /* The .tbtab pseudo-op can only be used for the first eight
20283 expressions, since it can't handle the possibly variable
20284 length fields that follow. However, if you omit the optional
20285 fields, the assembler outputs zeros for all optional fields
20286 anyways, giving each variable length field is minimum length
20287 (as defined in sys/debug.h). Thus we can not use the .tbtab
20288 pseudo-op at all. */
20290 /* An all-zero word flags the start of the tbtab, for debuggers
20291 that have to find it by searching forward from the entry
20292 point or from the current pc. */
20293 fputs ("\t.long 0\n", file);
20295 /* Tbtab format type. Use format type 0. */
20296 fputs ("\t.byte 0,", file);
20298 /* Language type. Unfortunately, there does not seem to be any
20299 official way to discover the language being compiled, so we
20300 use language_string.
20301 C is 0. Fortran is 1. Pascal is 2. Ada is 3. C++ is 9.
20302 Java is 13. Objective-C is 14. Objective-C++ isn't assigned
20303 a number, so for now use 9. LTO isn't assigned a number either,
20304 so for now use 0. */
20305 if (! strcmp (language_string, "GNU C")
20306 || ! strcmp (language_string, "GNU GIMPLE"))
20307 i = 0;
20308 else if (! strcmp (language_string, "GNU F77")
20309 || ! strcmp (language_string, "GNU Fortran"))
20310 i = 1;
20311 else if (! strcmp (language_string, "GNU Pascal"))
20312 i = 2;
20313 else if (! strcmp (language_string, "GNU Ada"))
20314 i = 3;
20315 else if (! strcmp (language_string, "GNU C++")
20316 || ! strcmp (language_string, "GNU Objective-C++"))
20317 i = 9;
20318 else if (! strcmp (language_string, "GNU Java"))
20319 i = 13;
20320 else if (! strcmp (language_string, "GNU Objective-C"))
20321 i = 14;
20322 else
20323 gcc_unreachable ();
20324 fprintf (file, "%d,", i);
20326 /* 8 single bit fields: global linkage (not set for C extern linkage,
20327 apparently a PL/I convention?), out-of-line epilogue/prologue, offset
20328 from start of procedure stored in tbtab, internal function, function
20329 has controlled storage, function has no toc, function uses fp,
20330 function logs/aborts fp operations. */
20331 /* Assume that fp operations are used if any fp reg must be saved. */
20332 fprintf (file, "%d,",
20333 (optional_tbtab << 5) | ((info->first_fp_reg_save != 64) << 1));
20335 /* 6 bitfields: function is interrupt handler, name present in
20336 proc table, function calls alloca, on condition directives
20337 (controls stack walks, 3 bits), saves condition reg, saves
20338 link reg. */
20339 /* The `function calls alloca' bit seems to be set whenever reg 31 is
20340 set up as a frame pointer, even when there is no alloca call. */
20341 fprintf (file, "%d,",
20342 ((optional_tbtab << 6)
20343 | ((optional_tbtab & frame_pointer_needed) << 5)
20344 | (info->cr_save_p << 1)
20345 | (info->lr_save_p)));
20347 /* 3 bitfields: saves backchain, fixup code, number of fpr saved
20348 (6 bits). */
20349 fprintf (file, "%d,",
20350 (info->push_p << 7) | (64 - info->first_fp_reg_save));
20352 /* 2 bitfields: spare bits (2 bits), number of gpr saved (6 bits). */
20353 fprintf (file, "%d,", (32 - first_reg_to_save ()));
20355 if (optional_tbtab)
20357 /* Compute the parameter info from the function decl argument
20358 list. */
20359 tree decl;
20360 int next_parm_info_bit = 31;
20362 for (decl = DECL_ARGUMENTS (current_function_decl);
20363 decl; decl = TREE_CHAIN (decl))
20365 rtx parameter = DECL_INCOMING_RTL (decl);
20366 enum machine_mode mode = GET_MODE (parameter);
20368 if (GET_CODE (parameter) == REG)
20370 if (SCALAR_FLOAT_MODE_P (mode))
20372 int bits;
20374 float_parms++;
20376 switch (mode)
20378 case SFmode:
20379 case SDmode:
20380 bits = 0x2;
20381 break;
20383 case DFmode:
20384 case DDmode:
20385 case TFmode:
20386 case TDmode:
20387 bits = 0x3;
20388 break;
20390 default:
20391 gcc_unreachable ();
20394 /* If only one bit will fit, don't or in this entry. */
20395 if (next_parm_info_bit > 0)
20396 parm_info |= (bits << (next_parm_info_bit - 1));
20397 next_parm_info_bit -= 2;
20399 else
20401 fixed_parms += ((GET_MODE_SIZE (mode)
20402 + (UNITS_PER_WORD - 1))
20403 / UNITS_PER_WORD);
20404 next_parm_info_bit -= 1;
20410 /* Number of fixed point parameters. */
20411 /* This is actually the number of words of fixed point parameters; thus
20412 an 8 byte struct counts as 2; and thus the maximum value is 8. */
20413 fprintf (file, "%d,", fixed_parms);
20415 /* 2 bitfields: number of floating point parameters (7 bits), parameters
20416 all on stack. */
20417 /* This is actually the number of fp registers that hold parameters;
20418 and thus the maximum value is 13. */
20419 /* Set parameters on stack bit if parameters are not in their original
20420 registers, regardless of whether they are on the stack? Xlc
20421 seems to set the bit when not optimizing. */
20422 fprintf (file, "%d\n", ((float_parms << 1) | (! optimize)));
20424 if (! optional_tbtab)
20425 return;
20427 /* Optional fields follow. Some are variable length. */
20429 /* Parameter types, left adjusted bit fields: 0 fixed, 10 single float,
20430 11 double float. */
20431 /* There is an entry for each parameter in a register, in the order that
20432 they occur in the parameter list. Any intervening arguments on the
20433 stack are ignored. If the list overflows a long (max possible length
20434 34 bits) then completely leave off all elements that don't fit. */
20435 /* Only emit this long if there was at least one parameter. */
20436 if (fixed_parms || float_parms)
20437 fprintf (file, "\t.long %d\n", parm_info);
20439 /* Offset from start of code to tb table. */
20440 fputs ("\t.long ", file);
20441 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
20442 if (TARGET_AIX)
20443 RS6000_OUTPUT_BASENAME (file, fname);
20444 else
20445 assemble_name (file, fname);
20446 putc ('-', file);
20447 rs6000_output_function_entry (file, fname);
20448 putc ('\n', file);
20450 /* Interrupt handler mask. */
20451 /* Omit this long, since we never set the interrupt handler bit
20452 above. */
20454 /* Number of CTL (controlled storage) anchors. */
20455 /* Omit this long, since the has_ctl bit is never set above. */
20457 /* Displacement into stack of each CTL anchor. */
20458 /* Omit this list of longs, because there are no CTL anchors. */
20460 /* Length of function name. */
20461 if (*fname == '*')
20462 ++fname;
20463 fprintf (file, "\t.short %d\n", (int) strlen (fname));
20465 /* Function name. */
20466 assemble_string (fname, strlen (fname));
20468 /* Register for alloca automatic storage; this is always reg 31.
20469 Only emit this if the alloca bit was set above. */
20470 if (frame_pointer_needed)
20471 fputs ("\t.byte 31\n", file);
20473 fputs ("\t.align 2\n", file);
20477 /* A C compound statement that outputs the assembler code for a thunk
20478 function, used to implement C++ virtual function calls with
20479 multiple inheritance. The thunk acts as a wrapper around a virtual
20480 function, adjusting the implicit object parameter before handing
20481 control off to the real function.
20483 First, emit code to add the integer DELTA to the location that
20484 contains the incoming first argument. Assume that this argument
20485 contains a pointer, and is the one used to pass the `this' pointer
20486 in C++. This is the incoming argument *before* the function
20487 prologue, e.g. `%o0' on a sparc. The addition must preserve the
20488 values of all other incoming arguments.
20490 After the addition, emit code to jump to FUNCTION, which is a
20491 `FUNCTION_DECL'. This is a direct pure jump, not a call, and does
20492 not touch the return address. Hence returning from FUNCTION will
20493 return to whoever called the current `thunk'.
20495 The effect must be as if FUNCTION had been called directly with the
20496 adjusted first argument. This macro is responsible for emitting
20497 all of the code for a thunk function; output_function_prologue()
20498 and output_function_epilogue() are not invoked.
20500 The THUNK_FNDECL is redundant. (DELTA and FUNCTION have already
20501 been extracted from it.) It might possibly be useful on some
20502 targets, but probably not.
20504 If you do not define this macro, the target-independent code in the
20505 C++ frontend will generate a less efficient heavyweight thunk that
20506 calls FUNCTION instead of jumping to it. The generic approach does
20507 not support varargs. */
20509 static void
20510 rs6000_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
20511 HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
20512 tree function)
20514 rtx this_rtx, insn, funexp;
20516 reload_completed = 1;
20517 epilogue_completed = 1;
20519 /* Mark the end of the (empty) prologue. */
20520 emit_note (NOTE_INSN_PROLOGUE_END);
20522 /* Find the "this" pointer. If the function returns a structure,
20523 the structure return pointer is in r3. */
20524 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function))
20525 this_rtx = gen_rtx_REG (Pmode, 4);
20526 else
20527 this_rtx = gen_rtx_REG (Pmode, 3);
20529 /* Apply the constant offset, if required. */
20530 if (delta)
20531 emit_insn (gen_add3_insn (this_rtx, this_rtx, GEN_INT (delta)));
20533 /* Apply the offset from the vtable, if required. */
20534 if (vcall_offset)
20536 rtx vcall_offset_rtx = GEN_INT (vcall_offset);
20537 rtx tmp = gen_rtx_REG (Pmode, 12);
20539 emit_move_insn (tmp, gen_rtx_MEM (Pmode, this_rtx));
20540 if (((unsigned HOST_WIDE_INT) vcall_offset) + 0x8000 >= 0x10000)
20542 emit_insn (gen_add3_insn (tmp, tmp, vcall_offset_rtx));
20543 emit_move_insn (tmp, gen_rtx_MEM (Pmode, tmp));
20545 else
20547 rtx loc = gen_rtx_PLUS (Pmode, tmp, vcall_offset_rtx);
20549 emit_move_insn (tmp, gen_rtx_MEM (Pmode, loc));
20551 emit_insn (gen_add3_insn (this_rtx, this_rtx, tmp));
20554 /* Generate a tail call to the target function. */
20555 if (!TREE_USED (function))
20557 assemble_external (function);
20558 TREE_USED (function) = 1;
20560 funexp = XEXP (DECL_RTL (function), 0);
20561 funexp = gen_rtx_MEM (FUNCTION_MODE, funexp);
20563 #if TARGET_MACHO
20564 if (MACHOPIC_INDIRECT)
20565 funexp = machopic_indirect_call_target (funexp);
20566 #endif
20568 /* gen_sibcall expects reload to convert scratch pseudo to LR so we must
20569 generate sibcall RTL explicitly. */
20570 insn = emit_call_insn (
20571 gen_rtx_PARALLEL (VOIDmode,
20572 gen_rtvec (4,
20573 gen_rtx_CALL (VOIDmode,
20574 funexp, const0_rtx),
20575 gen_rtx_USE (VOIDmode, const0_rtx),
20576 gen_rtx_USE (VOIDmode,
20577 gen_rtx_REG (SImode,
20578 LR_REGNO)),
20579 gen_rtx_RETURN (VOIDmode))));
20580 SIBLING_CALL_P (insn) = 1;
20581 emit_barrier ();
20583 /* Run just enough of rest_of_compilation to get the insns emitted.
20584 There's not really enough bulk here to make other passes such as
20585 instruction scheduling worth while. Note that use_thunk calls
20586 assemble_start_function and assemble_end_function. */
20587 insn = get_insns ();
20588 insn_locators_alloc ();
20589 shorten_branches (insn);
20590 final_start_function (insn, file, 1);
20591 final (insn, file, 1);
20592 final_end_function ();
20594 reload_completed = 0;
20595 epilogue_completed = 0;
20598 /* A quick summary of the various types of 'constant-pool tables'
20599 under PowerPC:
20601 Target Flags Name One table per
20602 AIX (none) AIX TOC object file
20603 AIX -mfull-toc AIX TOC object file
20604 AIX -mminimal-toc AIX minimal TOC translation unit
20605 SVR4/EABI (none) SVR4 SDATA object file
20606 SVR4/EABI -fpic SVR4 pic object file
20607 SVR4/EABI -fPIC SVR4 PIC translation unit
20608 SVR4/EABI -mrelocatable EABI TOC function
20609 SVR4/EABI -maix AIX TOC object file
20610 SVR4/EABI -maix -mminimal-toc
20611 AIX minimal TOC translation unit
20613 Name Reg. Set by entries contains:
20614 made by addrs? fp? sum?
20616 AIX TOC 2 crt0 as Y option option
20617 AIX minimal TOC 30 prolog gcc Y Y option
20618 SVR4 SDATA 13 crt0 gcc N Y N
20619 SVR4 pic 30 prolog ld Y not yet N
20620 SVR4 PIC 30 prolog gcc Y option option
20621 EABI TOC 30 prolog gcc Y option option
20625 /* Hash functions for the hash table. */
20627 static unsigned
20628 rs6000_hash_constant (rtx k)
20630 enum rtx_code code = GET_CODE (k);
20631 enum machine_mode mode = GET_MODE (k);
20632 unsigned result = (code << 3) ^ mode;
20633 const char *format;
20634 int flen, fidx;
20636 format = GET_RTX_FORMAT (code);
20637 flen = strlen (format);
20638 fidx = 0;
20640 switch (code)
20642 case LABEL_REF:
20643 return result * 1231 + (unsigned) INSN_UID (XEXP (k, 0));
20645 case CONST_DOUBLE:
20646 if (mode != VOIDmode)
20647 return real_hash (CONST_DOUBLE_REAL_VALUE (k)) * result;
20648 flen = 2;
20649 break;
20651 case CODE_LABEL:
20652 fidx = 3;
20653 break;
20655 default:
20656 break;
20659 for (; fidx < flen; fidx++)
20660 switch (format[fidx])
20662 case 's':
20664 unsigned i, len;
20665 const char *str = XSTR (k, fidx);
20666 len = strlen (str);
20667 result = result * 613 + len;
20668 for (i = 0; i < len; i++)
20669 result = result * 613 + (unsigned) str[i];
20670 break;
20672 case 'u':
20673 case 'e':
20674 result = result * 1231 + rs6000_hash_constant (XEXP (k, fidx));
20675 break;
20676 case 'i':
20677 case 'n':
20678 result = result * 613 + (unsigned) XINT (k, fidx);
20679 break;
20680 case 'w':
20681 if (sizeof (unsigned) >= sizeof (HOST_WIDE_INT))
20682 result = result * 613 + (unsigned) XWINT (k, fidx);
20683 else
20685 size_t i;
20686 for (i = 0; i < sizeof (HOST_WIDE_INT) / sizeof (unsigned); i++)
20687 result = result * 613 + (unsigned) (XWINT (k, fidx)
20688 >> CHAR_BIT * i);
20690 break;
20691 case '0':
20692 break;
20693 default:
20694 gcc_unreachable ();
20697 return result;
20700 static unsigned
20701 toc_hash_function (const void *hash_entry)
20703 const struct toc_hash_struct *thc =
20704 (const struct toc_hash_struct *) hash_entry;
20705 return rs6000_hash_constant (thc->key) ^ thc->key_mode;
20708 /* Compare H1 and H2 for equivalence. */
20710 static int
20711 toc_hash_eq (const void *h1, const void *h2)
20713 rtx r1 = ((const struct toc_hash_struct *) h1)->key;
20714 rtx r2 = ((const struct toc_hash_struct *) h2)->key;
20716 if (((const struct toc_hash_struct *) h1)->key_mode
20717 != ((const struct toc_hash_struct *) h2)->key_mode)
20718 return 0;
20720 return rtx_equal_p (r1, r2);
20723 /* These are the names given by the C++ front-end to vtables, and
20724 vtable-like objects. Ideally, this logic should not be here;
20725 instead, there should be some programmatic way of inquiring as
20726 to whether or not an object is a vtable. */
20728 #define VTABLE_NAME_P(NAME) \
20729 (strncmp ("_vt.", name, strlen ("_vt.")) == 0 \
20730 || strncmp ("_ZTV", name, strlen ("_ZTV")) == 0 \
20731 || strncmp ("_ZTT", name, strlen ("_ZTT")) == 0 \
20732 || strncmp ("_ZTI", name, strlen ("_ZTI")) == 0 \
20733 || strncmp ("_ZTC", name, strlen ("_ZTC")) == 0)
20735 #ifdef NO_DOLLAR_IN_LABEL
20736 /* Return a GGC-allocated character string translating dollar signs in
20737 input NAME to underscores. Used by XCOFF ASM_OUTPUT_LABELREF. */
20739 const char *
20740 rs6000_xcoff_strip_dollar (const char *name)
20742 char *strip, *p;
20743 int len;
20745 p = strchr (name, '$');
20747 if (p == 0 || p == name)
20748 return name;
20750 len = strlen (name);
20751 strip = (char *) alloca (len + 1);
20752 strcpy (strip, name);
20753 p = strchr (strip, '$');
20754 while (p)
20756 *p = '_';
20757 p = strchr (p + 1, '$');
20760 return ggc_alloc_string (strip, len);
20762 #endif
20764 void
20765 rs6000_output_symbol_ref (FILE *file, rtx x)
20767 /* Currently C++ toc references to vtables can be emitted before it
20768 is decided whether the vtable is public or private. If this is
20769 the case, then the linker will eventually complain that there is
20770 a reference to an unknown section. Thus, for vtables only,
20771 we emit the TOC reference to reference the symbol and not the
20772 section. */
20773 const char *name = XSTR (x, 0);
20775 if (VTABLE_NAME_P (name))
20777 RS6000_OUTPUT_BASENAME (file, name);
20779 else
20780 assemble_name (file, name);
20783 /* Output a TOC entry. We derive the entry name from what is being
20784 written. */
20786 void
20787 output_toc (FILE *file, rtx x, int labelno, enum machine_mode mode)
20789 char buf[256];
20790 const char *name = buf;
20791 rtx base = x;
20792 HOST_WIDE_INT offset = 0;
20794 gcc_assert (!TARGET_NO_TOC);
20796 /* When the linker won't eliminate them, don't output duplicate
20797 TOC entries (this happens on AIX if there is any kind of TOC,
20798 and on SVR4 under -fPIC or -mrelocatable). Don't do this for
20799 CODE_LABELs. */
20800 if (TARGET_TOC && GET_CODE (x) != LABEL_REF)
20802 struct toc_hash_struct *h;
20803 void * * found;
20805 /* Create toc_hash_table. This can't be done at OVERRIDE_OPTIONS
20806 time because GGC is not initialized at that point. */
20807 if (toc_hash_table == NULL)
20808 toc_hash_table = htab_create_ggc (1021, toc_hash_function,
20809 toc_hash_eq, NULL);
20811 h = GGC_NEW (struct toc_hash_struct);
20812 h->key = x;
20813 h->key_mode = mode;
20814 h->labelno = labelno;
20816 found = htab_find_slot (toc_hash_table, h, INSERT);
20817 if (*found == NULL)
20818 *found = h;
20819 else /* This is indeed a duplicate.
20820 Set this label equal to that label. */
20822 fputs ("\t.set ", file);
20823 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
20824 fprintf (file, "%d,", labelno);
20825 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
20826 fprintf (file, "%d\n", ((*(const struct toc_hash_struct **)
20827 found)->labelno));
20828 return;
20832 /* If we're going to put a double constant in the TOC, make sure it's
20833 aligned properly when strict alignment is on. */
20834 if (GET_CODE (x) == CONST_DOUBLE
20835 && STRICT_ALIGNMENT
20836 && GET_MODE_BITSIZE (mode) >= 64
20837 && ! (TARGET_NO_FP_IN_TOC && ! TARGET_MINIMAL_TOC)) {
20838 ASM_OUTPUT_ALIGN (file, 3);
20841 (*targetm.asm_out.internal_label) (file, "LC", labelno);
20843 /* Handle FP constants specially. Note that if we have a minimal
20844 TOC, things we put here aren't actually in the TOC, so we can allow
20845 FP constants. */
20846 if (GET_CODE (x) == CONST_DOUBLE &&
20847 (GET_MODE (x) == TFmode || GET_MODE (x) == TDmode))
20849 REAL_VALUE_TYPE rv;
20850 long k[4];
20852 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
20853 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
20854 REAL_VALUE_TO_TARGET_DECIMAL128 (rv, k);
20855 else
20856 REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv, k);
20858 if (TARGET_64BIT)
20860 if (TARGET_MINIMAL_TOC)
20861 fputs (DOUBLE_INT_ASM_OP, file);
20862 else
20863 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
20864 k[0] & 0xffffffff, k[1] & 0xffffffff,
20865 k[2] & 0xffffffff, k[3] & 0xffffffff);
20866 fprintf (file, "0x%lx%08lx,0x%lx%08lx\n",
20867 k[0] & 0xffffffff, k[1] & 0xffffffff,
20868 k[2] & 0xffffffff, k[3] & 0xffffffff);
20869 return;
20871 else
20873 if (TARGET_MINIMAL_TOC)
20874 fputs ("\t.long ", file);
20875 else
20876 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
20877 k[0] & 0xffffffff, k[1] & 0xffffffff,
20878 k[2] & 0xffffffff, k[3] & 0xffffffff);
20879 fprintf (file, "0x%lx,0x%lx,0x%lx,0x%lx\n",
20880 k[0] & 0xffffffff, k[1] & 0xffffffff,
20881 k[2] & 0xffffffff, k[3] & 0xffffffff);
20882 return;
20885 else if (GET_CODE (x) == CONST_DOUBLE &&
20886 (GET_MODE (x) == DFmode || GET_MODE (x) == DDmode))
20888 REAL_VALUE_TYPE rv;
20889 long k[2];
20891 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
20893 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
20894 REAL_VALUE_TO_TARGET_DECIMAL64 (rv, k);
20895 else
20896 REAL_VALUE_TO_TARGET_DOUBLE (rv, k);
20898 if (TARGET_64BIT)
20900 if (TARGET_MINIMAL_TOC)
20901 fputs (DOUBLE_INT_ASM_OP, file);
20902 else
20903 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
20904 k[0] & 0xffffffff, k[1] & 0xffffffff);
20905 fprintf (file, "0x%lx%08lx\n",
20906 k[0] & 0xffffffff, k[1] & 0xffffffff);
20907 return;
20909 else
20911 if (TARGET_MINIMAL_TOC)
20912 fputs ("\t.long ", file);
20913 else
20914 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
20915 k[0] & 0xffffffff, k[1] & 0xffffffff);
20916 fprintf (file, "0x%lx,0x%lx\n",
20917 k[0] & 0xffffffff, k[1] & 0xffffffff);
20918 return;
20921 else if (GET_CODE (x) == CONST_DOUBLE &&
20922 (GET_MODE (x) == SFmode || GET_MODE (x) == SDmode))
20924 REAL_VALUE_TYPE rv;
20925 long l;
20927 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
20928 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
20929 REAL_VALUE_TO_TARGET_DECIMAL32 (rv, l);
20930 else
20931 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
20933 if (TARGET_64BIT)
20935 if (TARGET_MINIMAL_TOC)
20936 fputs (DOUBLE_INT_ASM_OP, file);
20937 else
20938 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
20939 fprintf (file, "0x%lx00000000\n", l & 0xffffffff);
20940 return;
20942 else
20944 if (TARGET_MINIMAL_TOC)
20945 fputs ("\t.long ", file);
20946 else
20947 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
20948 fprintf (file, "0x%lx\n", l & 0xffffffff);
20949 return;
20952 else if (GET_MODE (x) == VOIDmode
20953 && (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE))
20955 unsigned HOST_WIDE_INT low;
20956 HOST_WIDE_INT high;
20958 if (GET_CODE (x) == CONST_DOUBLE)
20960 low = CONST_DOUBLE_LOW (x);
20961 high = CONST_DOUBLE_HIGH (x);
20963 else
20964 #if HOST_BITS_PER_WIDE_INT == 32
20966 low = INTVAL (x);
20967 high = (low & 0x80000000) ? ~0 : 0;
20969 #else
20971 low = INTVAL (x) & 0xffffffff;
20972 high = (HOST_WIDE_INT) INTVAL (x) >> 32;
20974 #endif
20976 /* TOC entries are always Pmode-sized, but since this
20977 is a bigendian machine then if we're putting smaller
20978 integer constants in the TOC we have to pad them.
20979 (This is still a win over putting the constants in
20980 a separate constant pool, because then we'd have
20981 to have both a TOC entry _and_ the actual constant.)
20983 For a 32-bit target, CONST_INT values are loaded and shifted
20984 entirely within `low' and can be stored in one TOC entry. */
20986 /* It would be easy to make this work, but it doesn't now. */
20987 gcc_assert (!TARGET_64BIT || POINTER_SIZE >= GET_MODE_BITSIZE (mode));
20989 if (POINTER_SIZE > GET_MODE_BITSIZE (mode))
20991 #if HOST_BITS_PER_WIDE_INT == 32
20992 lshift_double (low, high, POINTER_SIZE - GET_MODE_BITSIZE (mode),
20993 POINTER_SIZE, &low, &high, 0);
20994 #else
20995 low |= high << 32;
20996 low <<= POINTER_SIZE - GET_MODE_BITSIZE (mode);
20997 high = (HOST_WIDE_INT) low >> 32;
20998 low &= 0xffffffff;
20999 #endif
21002 if (TARGET_64BIT)
21004 if (TARGET_MINIMAL_TOC)
21005 fputs (DOUBLE_INT_ASM_OP, file);
21006 else
21007 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
21008 (long) high & 0xffffffff, (long) low & 0xffffffff);
21009 fprintf (file, "0x%lx%08lx\n",
21010 (long) high & 0xffffffff, (long) low & 0xffffffff);
21011 return;
21013 else
21015 if (POINTER_SIZE < GET_MODE_BITSIZE (mode))
21017 if (TARGET_MINIMAL_TOC)
21018 fputs ("\t.long ", file);
21019 else
21020 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
21021 (long) high & 0xffffffff, (long) low & 0xffffffff);
21022 fprintf (file, "0x%lx,0x%lx\n",
21023 (long) high & 0xffffffff, (long) low & 0xffffffff);
21025 else
21027 if (TARGET_MINIMAL_TOC)
21028 fputs ("\t.long ", file);
21029 else
21030 fprintf (file, "\t.tc IS_%lx[TC],", (long) low & 0xffffffff);
21031 fprintf (file, "0x%lx\n", (long) low & 0xffffffff);
21033 return;
21037 if (GET_CODE (x) == CONST)
21039 gcc_assert (GET_CODE (XEXP (x, 0)) == PLUS
21040 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT);
21042 base = XEXP (XEXP (x, 0), 0);
21043 offset = INTVAL (XEXP (XEXP (x, 0), 1));
21046 switch (GET_CODE (base))
21048 case SYMBOL_REF:
21049 name = XSTR (base, 0);
21050 break;
21052 case LABEL_REF:
21053 ASM_GENERATE_INTERNAL_LABEL (buf, "L",
21054 CODE_LABEL_NUMBER (XEXP (base, 0)));
21055 break;
21057 case CODE_LABEL:
21058 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (base));
21059 break;
21061 default:
21062 gcc_unreachable ();
21065 if (TARGET_MINIMAL_TOC)
21066 fputs (TARGET_32BIT ? "\t.long " : DOUBLE_INT_ASM_OP, file);
21067 else
21069 fputs ("\t.tc ", file);
21070 RS6000_OUTPUT_BASENAME (file, name);
21072 if (offset < 0)
21073 fprintf (file, ".N" HOST_WIDE_INT_PRINT_UNSIGNED, - offset);
21074 else if (offset)
21075 fprintf (file, ".P" HOST_WIDE_INT_PRINT_UNSIGNED, offset);
21077 fputs ("[TC],", file);
21080 /* Currently C++ toc references to vtables can be emitted before it
21081 is decided whether the vtable is public or private. If this is
21082 the case, then the linker will eventually complain that there is
21083 a TOC reference to an unknown section. Thus, for vtables only,
21084 we emit the TOC reference to reference the symbol and not the
21085 section. */
21086 if (VTABLE_NAME_P (name))
21088 RS6000_OUTPUT_BASENAME (file, name);
21089 if (offset < 0)
21090 fprintf (file, HOST_WIDE_INT_PRINT_DEC, offset);
21091 else if (offset > 0)
21092 fprintf (file, "+" HOST_WIDE_INT_PRINT_DEC, offset);
21094 else
21095 output_addr_const (file, x);
21096 putc ('\n', file);
21099 /* Output an assembler pseudo-op to write an ASCII string of N characters
21100 starting at P to FILE.
21102 On the RS/6000, we have to do this using the .byte operation and
21103 write out special characters outside the quoted string.
21104 Also, the assembler is broken; very long strings are truncated,
21105 so we must artificially break them up early. */
21107 void
21108 output_ascii (FILE *file, const char *p, int n)
21110 char c;
21111 int i, count_string;
21112 const char *for_string = "\t.byte \"";
21113 const char *for_decimal = "\t.byte ";
21114 const char *to_close = NULL;
21116 count_string = 0;
21117 for (i = 0; i < n; i++)
21119 c = *p++;
21120 if (c >= ' ' && c < 0177)
21122 if (for_string)
21123 fputs (for_string, file);
21124 putc (c, file);
21126 /* Write two quotes to get one. */
21127 if (c == '"')
21129 putc (c, file);
21130 ++count_string;
21133 for_string = NULL;
21134 for_decimal = "\"\n\t.byte ";
21135 to_close = "\"\n";
21136 ++count_string;
21138 if (count_string >= 512)
21140 fputs (to_close, file);
21142 for_string = "\t.byte \"";
21143 for_decimal = "\t.byte ";
21144 to_close = NULL;
21145 count_string = 0;
21148 else
21150 if (for_decimal)
21151 fputs (for_decimal, file);
21152 fprintf (file, "%d", c);
21154 for_string = "\n\t.byte \"";
21155 for_decimal = ", ";
21156 to_close = "\n";
21157 count_string = 0;
21161 /* Now close the string if we have written one. Then end the line. */
21162 if (to_close)
21163 fputs (to_close, file);
21166 /* Generate a unique section name for FILENAME for a section type
21167 represented by SECTION_DESC. Output goes into BUF.
21169 SECTION_DESC can be any string, as long as it is different for each
21170 possible section type.
21172 We name the section in the same manner as xlc. The name begins with an
21173 underscore followed by the filename (after stripping any leading directory
21174 names) with the last period replaced by the string SECTION_DESC. If
21175 FILENAME does not contain a period, SECTION_DESC is appended to the end of
21176 the name. */
21178 void
21179 rs6000_gen_section_name (char **buf, const char *filename,
21180 const char *section_desc)
21182 const char *q, *after_last_slash, *last_period = 0;
21183 char *p;
21184 int len;
21186 after_last_slash = filename;
21187 for (q = filename; *q; q++)
21189 if (*q == '/')
21190 after_last_slash = q + 1;
21191 else if (*q == '.')
21192 last_period = q;
21195 len = strlen (after_last_slash) + strlen (section_desc) + 2;
21196 *buf = (char *) xmalloc (len);
21198 p = *buf;
21199 *p++ = '_';
21201 for (q = after_last_slash; *q; q++)
21203 if (q == last_period)
21205 strcpy (p, section_desc);
21206 p += strlen (section_desc);
21207 break;
21210 else if (ISALNUM (*q))
21211 *p++ = *q;
21214 if (last_period == 0)
21215 strcpy (p, section_desc);
21216 else
21217 *p = '\0';
21220 /* Emit profile function. */
21222 void
21223 output_profile_hook (int labelno ATTRIBUTE_UNUSED)
21225 /* Non-standard profiling for kernels, which just saves LR then calls
21226 _mcount without worrying about arg saves. The idea is to change
21227 the function prologue as little as possible as it isn't easy to
21228 account for arg save/restore code added just for _mcount. */
21229 if (TARGET_PROFILE_KERNEL)
21230 return;
21232 if (DEFAULT_ABI == ABI_AIX)
21234 #ifndef NO_PROFILE_COUNTERS
21235 # define NO_PROFILE_COUNTERS 0
21236 #endif
21237 if (NO_PROFILE_COUNTERS)
21238 emit_library_call (init_one_libfunc (RS6000_MCOUNT),
21239 LCT_NORMAL, VOIDmode, 0);
21240 else
21242 char buf[30];
21243 const char *label_name;
21244 rtx fun;
21246 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
21247 label_name = (*targetm.strip_name_encoding) (ggc_strdup (buf));
21248 fun = gen_rtx_SYMBOL_REF (Pmode, label_name);
21250 emit_library_call (init_one_libfunc (RS6000_MCOUNT),
21251 LCT_NORMAL, VOIDmode, 1, fun, Pmode);
21254 else if (DEFAULT_ABI == ABI_DARWIN)
21256 const char *mcount_name = RS6000_MCOUNT;
21257 int caller_addr_regno = LR_REGNO;
21259 /* Be conservative and always set this, at least for now. */
21260 crtl->uses_pic_offset_table = 1;
21262 #if TARGET_MACHO
21263 /* For PIC code, set up a stub and collect the caller's address
21264 from r0, which is where the prologue puts it. */
21265 if (MACHOPIC_INDIRECT
21266 && crtl->uses_pic_offset_table)
21267 caller_addr_regno = 0;
21268 #endif
21269 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, mcount_name),
21270 LCT_NORMAL, VOIDmode, 1,
21271 gen_rtx_REG (Pmode, caller_addr_regno), Pmode);
21275 /* Write function profiler code. */
21277 void
21278 output_function_profiler (FILE *file, int labelno)
21280 char buf[100];
21282 switch (DEFAULT_ABI)
21284 default:
21285 gcc_unreachable ();
21287 case ABI_V4:
21288 if (!TARGET_32BIT)
21290 warning (0, "no profiling of 64-bit code for this ABI");
21291 return;
21293 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
21294 fprintf (file, "\tmflr %s\n", reg_names[0]);
21295 if (NO_PROFILE_COUNTERS)
21297 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
21298 reg_names[0], reg_names[1]);
21300 else if (TARGET_SECURE_PLT && flag_pic)
21302 asm_fprintf (file, "\tbcl 20,31,1f\n1:\n\t{st|stw} %s,4(%s)\n",
21303 reg_names[0], reg_names[1]);
21304 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
21305 asm_fprintf (file, "\t{cau|addis} %s,%s,",
21306 reg_names[12], reg_names[12]);
21307 assemble_name (file, buf);
21308 asm_fprintf (file, "-1b@ha\n\t{cal|la} %s,", reg_names[0]);
21309 assemble_name (file, buf);
21310 asm_fprintf (file, "-1b@l(%s)\n", reg_names[12]);
21312 else if (flag_pic == 1)
21314 fputs ("\tbl _GLOBAL_OFFSET_TABLE_@local-4\n", file);
21315 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
21316 reg_names[0], reg_names[1]);
21317 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
21318 asm_fprintf (file, "\t{l|lwz} %s,", reg_names[0]);
21319 assemble_name (file, buf);
21320 asm_fprintf (file, "@got(%s)\n", reg_names[12]);
21322 else if (flag_pic > 1)
21324 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
21325 reg_names[0], reg_names[1]);
21326 /* Now, we need to get the address of the label. */
21327 fputs ("\tbcl 20,31,1f\n\t.long ", file);
21328 assemble_name (file, buf);
21329 fputs ("-.\n1:", file);
21330 asm_fprintf (file, "\tmflr %s\n", reg_names[11]);
21331 asm_fprintf (file, "\t{l|lwz} %s,0(%s)\n",
21332 reg_names[0], reg_names[11]);
21333 asm_fprintf (file, "\t{cax|add} %s,%s,%s\n",
21334 reg_names[0], reg_names[0], reg_names[11]);
21336 else
21338 asm_fprintf (file, "\t{liu|lis} %s,", reg_names[12]);
21339 assemble_name (file, buf);
21340 fputs ("@ha\n", file);
21341 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
21342 reg_names[0], reg_names[1]);
21343 asm_fprintf (file, "\t{cal|la} %s,", reg_names[0]);
21344 assemble_name (file, buf);
21345 asm_fprintf (file, "@l(%s)\n", reg_names[12]);
21348 /* ABI_V4 saves the static chain reg with ASM_OUTPUT_REG_PUSH. */
21349 fprintf (file, "\tbl %s%s\n",
21350 RS6000_MCOUNT, flag_pic ? "@plt" : "");
21351 break;
21353 case ABI_AIX:
21354 case ABI_DARWIN:
21355 if (!TARGET_PROFILE_KERNEL)
21357 /* Don't do anything, done in output_profile_hook (). */
21359 else
21361 gcc_assert (!TARGET_32BIT);
21363 asm_fprintf (file, "\tmflr %s\n", reg_names[0]);
21364 asm_fprintf (file, "\tstd %s,16(%s)\n", reg_names[0], reg_names[1]);
21366 if (cfun->static_chain_decl != NULL)
21368 asm_fprintf (file, "\tstd %s,24(%s)\n",
21369 reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
21370 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
21371 asm_fprintf (file, "\tld %s,24(%s)\n",
21372 reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
21374 else
21375 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
21377 break;
21383 /* The following variable value is the last issued insn. */
21385 static rtx last_scheduled_insn;
21387 /* The following variable helps to balance issuing of load and
21388 store instructions */
21390 static int load_store_pendulum;
21392 /* Power4 load update and store update instructions are cracked into a
21393 load or store and an integer insn which are executed in the same cycle.
21394 Branches have their own dispatch slot which does not count against the
21395 GCC issue rate, but it changes the program flow so there are no other
21396 instructions to issue in this cycle. */
21398 static int
21399 rs6000_variable_issue_1 (rtx insn, int more)
21401 last_scheduled_insn = insn;
21402 if (GET_CODE (PATTERN (insn)) == USE
21403 || GET_CODE (PATTERN (insn)) == CLOBBER)
21405 cached_can_issue_more = more;
21406 return cached_can_issue_more;
21409 if (insn_terminates_group_p (insn, current_group))
21411 cached_can_issue_more = 0;
21412 return cached_can_issue_more;
21415 /* If no reservation, but reach here */
21416 if (recog_memoized (insn) < 0)
21417 return more;
21419 if (rs6000_sched_groups)
21421 if (is_microcoded_insn (insn))
21422 cached_can_issue_more = 0;
21423 else if (is_cracked_insn (insn))
21424 cached_can_issue_more = more > 2 ? more - 2 : 0;
21425 else
21426 cached_can_issue_more = more - 1;
21428 return cached_can_issue_more;
21431 if (rs6000_cpu_attr == CPU_CELL && is_nonpipeline_insn (insn))
21432 return 0;
21434 cached_can_issue_more = more - 1;
21435 return cached_can_issue_more;
21438 static int
21439 rs6000_variable_issue (FILE *stream, int verbose, rtx insn, int more)
21441 int r = rs6000_variable_issue_1 (insn, more);
21442 if (verbose)
21443 fprintf (stream, "// rs6000_variable_issue (more = %d) = %d\n", more, r);
21444 return r;
21447 /* Adjust the cost of a scheduling dependency. Return the new cost of
21448 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
21450 static int
21451 rs6000_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
21453 enum attr_type attr_type;
21455 if (! recog_memoized (insn))
21456 return 0;
21458 switch (REG_NOTE_KIND (link))
21460 case REG_DEP_TRUE:
21462 /* Data dependency; DEP_INSN writes a register that INSN reads
21463 some cycles later. */
21465 /* Separate a load from a narrower, dependent store. */
21466 if (rs6000_sched_groups
21467 && GET_CODE (PATTERN (insn)) == SET
21468 && GET_CODE (PATTERN (dep_insn)) == SET
21469 && GET_CODE (XEXP (PATTERN (insn), 1)) == MEM
21470 && GET_CODE (XEXP (PATTERN (dep_insn), 0)) == MEM
21471 && (GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (insn), 1)))
21472 > GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (dep_insn), 0)))))
21473 return cost + 14;
21475 attr_type = get_attr_type (insn);
21477 switch (attr_type)
21479 case TYPE_JMPREG:
21480 /* Tell the first scheduling pass about the latency between
21481 a mtctr and bctr (and mtlr and br/blr). The first
21482 scheduling pass will not know about this latency since
21483 the mtctr instruction, which has the latency associated
21484 to it, will be generated by reload. */
21485 return TARGET_POWER ? 5 : 4;
21486 case TYPE_BRANCH:
21487 /* Leave some extra cycles between a compare and its
21488 dependent branch, to inhibit expensive mispredicts. */
21489 if ((rs6000_cpu_attr == CPU_PPC603
21490 || rs6000_cpu_attr == CPU_PPC604
21491 || rs6000_cpu_attr == CPU_PPC604E
21492 || rs6000_cpu_attr == CPU_PPC620
21493 || rs6000_cpu_attr == CPU_PPC630
21494 || rs6000_cpu_attr == CPU_PPC750
21495 || rs6000_cpu_attr == CPU_PPC7400
21496 || rs6000_cpu_attr == CPU_PPC7450
21497 || rs6000_cpu_attr == CPU_POWER4
21498 || rs6000_cpu_attr == CPU_POWER5
21499 || rs6000_cpu_attr == CPU_POWER7
21500 || rs6000_cpu_attr == CPU_CELL)
21501 && recog_memoized (dep_insn)
21502 && (INSN_CODE (dep_insn) >= 0))
21504 switch (get_attr_type (dep_insn))
21506 case TYPE_CMP:
21507 case TYPE_COMPARE:
21508 case TYPE_DELAYED_COMPARE:
21509 case TYPE_IMUL_COMPARE:
21510 case TYPE_LMUL_COMPARE:
21511 case TYPE_FPCOMPARE:
21512 case TYPE_CR_LOGICAL:
21513 case TYPE_DELAYED_CR:
21514 return cost + 2;
21515 default:
21516 break;
21518 break;
21520 case TYPE_STORE:
21521 case TYPE_STORE_U:
21522 case TYPE_STORE_UX:
21523 case TYPE_FPSTORE:
21524 case TYPE_FPSTORE_U:
21525 case TYPE_FPSTORE_UX:
21526 if ((rs6000_cpu == PROCESSOR_POWER6)
21527 && recog_memoized (dep_insn)
21528 && (INSN_CODE (dep_insn) >= 0))
21531 if (GET_CODE (PATTERN (insn)) != SET)
21532 /* If this happens, we have to extend this to schedule
21533 optimally. Return default for now. */
21534 return cost;
21536 /* Adjust the cost for the case where the value written
21537 by a fixed point operation is used as the address
21538 gen value on a store. */
21539 switch (get_attr_type (dep_insn))
21541 case TYPE_LOAD:
21542 case TYPE_LOAD_U:
21543 case TYPE_LOAD_UX:
21544 case TYPE_CNTLZ:
21546 if (! store_data_bypass_p (dep_insn, insn))
21547 return 4;
21548 break;
21550 case TYPE_LOAD_EXT:
21551 case TYPE_LOAD_EXT_U:
21552 case TYPE_LOAD_EXT_UX:
21553 case TYPE_VAR_SHIFT_ROTATE:
21554 case TYPE_VAR_DELAYED_COMPARE:
21556 if (! store_data_bypass_p (dep_insn, insn))
21557 return 6;
21558 break;
21560 case TYPE_INTEGER:
21561 case TYPE_COMPARE:
21562 case TYPE_FAST_COMPARE:
21563 case TYPE_EXTS:
21564 case TYPE_SHIFT:
21565 case TYPE_INSERT_WORD:
21566 case TYPE_INSERT_DWORD:
21567 case TYPE_FPLOAD_U:
21568 case TYPE_FPLOAD_UX:
21569 case TYPE_STORE_U:
21570 case TYPE_STORE_UX:
21571 case TYPE_FPSTORE_U:
21572 case TYPE_FPSTORE_UX:
21574 if (! store_data_bypass_p (dep_insn, insn))
21575 return 3;
21576 break;
21578 case TYPE_IMUL:
21579 case TYPE_IMUL2:
21580 case TYPE_IMUL3:
21581 case TYPE_LMUL:
21582 case TYPE_IMUL_COMPARE:
21583 case TYPE_LMUL_COMPARE:
21585 if (! store_data_bypass_p (dep_insn, insn))
21586 return 17;
21587 break;
21589 case TYPE_IDIV:
21591 if (! store_data_bypass_p (dep_insn, insn))
21592 return 45;
21593 break;
21595 case TYPE_LDIV:
21597 if (! store_data_bypass_p (dep_insn, insn))
21598 return 57;
21599 break;
21601 default:
21602 break;
21605 break;
21607 case TYPE_LOAD:
21608 case TYPE_LOAD_U:
21609 case TYPE_LOAD_UX:
21610 case TYPE_LOAD_EXT:
21611 case TYPE_LOAD_EXT_U:
21612 case TYPE_LOAD_EXT_UX:
21613 if ((rs6000_cpu == PROCESSOR_POWER6)
21614 && recog_memoized (dep_insn)
21615 && (INSN_CODE (dep_insn) >= 0))
21618 /* Adjust the cost for the case where the value written
21619 by a fixed point instruction is used within the address
21620 gen portion of a subsequent load(u)(x) */
21621 switch (get_attr_type (dep_insn))
21623 case TYPE_LOAD:
21624 case TYPE_LOAD_U:
21625 case TYPE_LOAD_UX:
21626 case TYPE_CNTLZ:
21628 if (set_to_load_agen (dep_insn, insn))
21629 return 4;
21630 break;
21632 case TYPE_LOAD_EXT:
21633 case TYPE_LOAD_EXT_U:
21634 case TYPE_LOAD_EXT_UX:
21635 case TYPE_VAR_SHIFT_ROTATE:
21636 case TYPE_VAR_DELAYED_COMPARE:
21638 if (set_to_load_agen (dep_insn, insn))
21639 return 6;
21640 break;
21642 case TYPE_INTEGER:
21643 case TYPE_COMPARE:
21644 case TYPE_FAST_COMPARE:
21645 case TYPE_EXTS:
21646 case TYPE_SHIFT:
21647 case TYPE_INSERT_WORD:
21648 case TYPE_INSERT_DWORD:
21649 case TYPE_FPLOAD_U:
21650 case TYPE_FPLOAD_UX:
21651 case TYPE_STORE_U:
21652 case TYPE_STORE_UX:
21653 case TYPE_FPSTORE_U:
21654 case TYPE_FPSTORE_UX:
21656 if (set_to_load_agen (dep_insn, insn))
21657 return 3;
21658 break;
21660 case TYPE_IMUL:
21661 case TYPE_IMUL2:
21662 case TYPE_IMUL3:
21663 case TYPE_LMUL:
21664 case TYPE_IMUL_COMPARE:
21665 case TYPE_LMUL_COMPARE:
21667 if (set_to_load_agen (dep_insn, insn))
21668 return 17;
21669 break;
21671 case TYPE_IDIV:
21673 if (set_to_load_agen (dep_insn, insn))
21674 return 45;
21675 break;
21677 case TYPE_LDIV:
21679 if (set_to_load_agen (dep_insn, insn))
21680 return 57;
21681 break;
21683 default:
21684 break;
21687 break;
21689 case TYPE_FPLOAD:
21690 if ((rs6000_cpu == PROCESSOR_POWER6)
21691 && recog_memoized (dep_insn)
21692 && (INSN_CODE (dep_insn) >= 0)
21693 && (get_attr_type (dep_insn) == TYPE_MFFGPR))
21694 return 2;
21696 default:
21697 break;
21700 /* Fall out to return default cost. */
21702 break;
21704 case REG_DEP_OUTPUT:
21705 /* Output dependency; DEP_INSN writes a register that INSN writes some
21706 cycles later. */
21707 if ((rs6000_cpu == PROCESSOR_POWER6)
21708 && recog_memoized (dep_insn)
21709 && (INSN_CODE (dep_insn) >= 0))
21711 attr_type = get_attr_type (insn);
21713 switch (attr_type)
21715 case TYPE_FP:
21716 if (get_attr_type (dep_insn) == TYPE_FP)
21717 return 1;
21718 break;
21719 case TYPE_FPLOAD:
21720 if (get_attr_type (dep_insn) == TYPE_MFFGPR)
21721 return 2;
21722 break;
21723 default:
21724 break;
21727 case REG_DEP_ANTI:
21728 /* Anti dependency; DEP_INSN reads a register that INSN writes some
21729 cycles later. */
21730 return 0;
21732 default:
21733 gcc_unreachable ();
21736 return cost;
21739 /* Debug version of rs6000_adjust_cost. */
21741 static int
21742 rs6000_debug_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
21744 int ret = rs6000_adjust_cost (insn, link, dep_insn, cost);
21746 if (ret != cost)
21748 const char *dep;
21750 switch (REG_NOTE_KIND (link))
21752 default: dep = "unknown depencency"; break;
21753 case REG_DEP_TRUE: dep = "data dependency"; break;
21754 case REG_DEP_OUTPUT: dep = "output dependency"; break;
21755 case REG_DEP_ANTI: dep = "anti depencency"; break;
21758 fprintf (stderr,
21759 "\nrs6000_adjust_cost, final cost = %d, orig cost = %d, "
21760 "%s, insn:\n", ret, cost, dep);
21762 debug_rtx (insn);
21765 return ret;
21768 /* The function returns a true if INSN is microcoded.
21769 Return false otherwise. */
21771 static bool
21772 is_microcoded_insn (rtx insn)
21774 if (!insn || !NONDEBUG_INSN_P (insn)
21775 || GET_CODE (PATTERN (insn)) == USE
21776 || GET_CODE (PATTERN (insn)) == CLOBBER)
21777 return false;
21779 if (rs6000_cpu_attr == CPU_CELL)
21780 return get_attr_cell_micro (insn) == CELL_MICRO_ALWAYS;
21782 if (rs6000_sched_groups)
21784 enum attr_type type = get_attr_type (insn);
21785 if (type == TYPE_LOAD_EXT_U
21786 || type == TYPE_LOAD_EXT_UX
21787 || type == TYPE_LOAD_UX
21788 || type == TYPE_STORE_UX
21789 || type == TYPE_MFCR)
21790 return true;
21793 return false;
21796 /* The function returns true if INSN is cracked into 2 instructions
21797 by the processor (and therefore occupies 2 issue slots). */
21799 static bool
21800 is_cracked_insn (rtx insn)
21802 if (!insn || !NONDEBUG_INSN_P (insn)
21803 || GET_CODE (PATTERN (insn)) == USE
21804 || GET_CODE (PATTERN (insn)) == CLOBBER)
21805 return false;
21807 if (rs6000_sched_groups)
21809 enum attr_type type = get_attr_type (insn);
21810 if (type == TYPE_LOAD_U || type == TYPE_STORE_U
21811 || type == TYPE_FPLOAD_U || type == TYPE_FPSTORE_U
21812 || type == TYPE_FPLOAD_UX || type == TYPE_FPSTORE_UX
21813 || type == TYPE_LOAD_EXT || type == TYPE_DELAYED_CR
21814 || type == TYPE_COMPARE || type == TYPE_DELAYED_COMPARE
21815 || type == TYPE_IMUL_COMPARE || type == TYPE_LMUL_COMPARE
21816 || type == TYPE_IDIV || type == TYPE_LDIV
21817 || type == TYPE_INSERT_WORD)
21818 return true;
21821 return false;
21824 /* The function returns true if INSN can be issued only from
21825 the branch slot. */
21827 static bool
21828 is_branch_slot_insn (rtx insn)
21830 if (!insn || !NONDEBUG_INSN_P (insn)
21831 || GET_CODE (PATTERN (insn)) == USE
21832 || GET_CODE (PATTERN (insn)) == CLOBBER)
21833 return false;
21835 if (rs6000_sched_groups)
21837 enum attr_type type = get_attr_type (insn);
21838 if (type == TYPE_BRANCH || type == TYPE_JMPREG)
21839 return true;
21840 return false;
21843 return false;
21846 /* The function returns true if out_inst sets a value that is
21847 used in the address generation computation of in_insn */
21848 static bool
21849 set_to_load_agen (rtx out_insn, rtx in_insn)
21851 rtx out_set, in_set;
21853 /* For performance reasons, only handle the simple case where
21854 both loads are a single_set. */
21855 out_set = single_set (out_insn);
21856 if (out_set)
21858 in_set = single_set (in_insn);
21859 if (in_set)
21860 return reg_mentioned_p (SET_DEST (out_set), SET_SRC (in_set));
21863 return false;
21866 /* The function returns true if the target storage location of
21867 out_insn is adjacent to the target storage location of in_insn */
21868 /* Return 1 if memory locations are adjacent. */
21870 static bool
21871 adjacent_mem_locations (rtx insn1, rtx insn2)
21874 rtx a = get_store_dest (PATTERN (insn1));
21875 rtx b = get_store_dest (PATTERN (insn2));
21877 if ((GET_CODE (XEXP (a, 0)) == REG
21878 || (GET_CODE (XEXP (a, 0)) == PLUS
21879 && GET_CODE (XEXP (XEXP (a, 0), 1)) == CONST_INT))
21880 && (GET_CODE (XEXP (b, 0)) == REG
21881 || (GET_CODE (XEXP (b, 0)) == PLUS
21882 && GET_CODE (XEXP (XEXP (b, 0), 1)) == CONST_INT)))
21884 HOST_WIDE_INT val0 = 0, val1 = 0, val_diff;
21885 rtx reg0, reg1;
21887 if (GET_CODE (XEXP (a, 0)) == PLUS)
21889 reg0 = XEXP (XEXP (a, 0), 0);
21890 val0 = INTVAL (XEXP (XEXP (a, 0), 1));
21892 else
21893 reg0 = XEXP (a, 0);
21895 if (GET_CODE (XEXP (b, 0)) == PLUS)
21897 reg1 = XEXP (XEXP (b, 0), 0);
21898 val1 = INTVAL (XEXP (XEXP (b, 0), 1));
21900 else
21901 reg1 = XEXP (b, 0);
21903 val_diff = val1 - val0;
21905 return ((REGNO (reg0) == REGNO (reg1))
21906 && ((MEM_SIZE (a) && val_diff == INTVAL (MEM_SIZE (a)))
21907 || (MEM_SIZE (b) && val_diff == -INTVAL (MEM_SIZE (b)))));
21910 return false;
21913 /* A C statement (sans semicolon) to update the integer scheduling
21914 priority INSN_PRIORITY (INSN). Increase the priority to execute the
21915 INSN earlier, reduce the priority to execute INSN later. Do not
21916 define this macro if you do not need to adjust the scheduling
21917 priorities of insns. */
21919 static int
21920 rs6000_adjust_priority (rtx insn ATTRIBUTE_UNUSED, int priority)
21922 /* On machines (like the 750) which have asymmetric integer units,
21923 where one integer unit can do multiply and divides and the other
21924 can't, reduce the priority of multiply/divide so it is scheduled
21925 before other integer operations. */
21927 #if 0
21928 if (! INSN_P (insn))
21929 return priority;
21931 if (GET_CODE (PATTERN (insn)) == USE)
21932 return priority;
21934 switch (rs6000_cpu_attr) {
21935 case CPU_PPC750:
21936 switch (get_attr_type (insn))
21938 default:
21939 break;
21941 case TYPE_IMUL:
21942 case TYPE_IDIV:
21943 fprintf (stderr, "priority was %#x (%d) before adjustment\n",
21944 priority, priority);
21945 if (priority >= 0 && priority < 0x01000000)
21946 priority >>= 3;
21947 break;
21950 #endif
21952 if (insn_must_be_first_in_group (insn)
21953 && reload_completed
21954 && current_sched_info->sched_max_insns_priority
21955 && rs6000_sched_restricted_insns_priority)
21958 /* Prioritize insns that can be dispatched only in the first
21959 dispatch slot. */
21960 if (rs6000_sched_restricted_insns_priority == 1)
21961 /* Attach highest priority to insn. This means that in
21962 haifa-sched.c:ready_sort(), dispatch-slot restriction considerations
21963 precede 'priority' (critical path) considerations. */
21964 return current_sched_info->sched_max_insns_priority;
21965 else if (rs6000_sched_restricted_insns_priority == 2)
21966 /* Increase priority of insn by a minimal amount. This means that in
21967 haifa-sched.c:ready_sort(), only 'priority' (critical path)
21968 considerations precede dispatch-slot restriction considerations. */
21969 return (priority + 1);
21972 if (rs6000_cpu == PROCESSOR_POWER6
21973 && ((load_store_pendulum == -2 && is_load_insn (insn))
21974 || (load_store_pendulum == 2 && is_store_insn (insn))))
21975 /* Attach highest priority to insn if the scheduler has just issued two
21976 stores and this instruction is a load, or two loads and this instruction
21977 is a store. Power6 wants loads and stores scheduled alternately
21978 when possible */
21979 return current_sched_info->sched_max_insns_priority;
21981 return priority;
21984 /* Return true if the instruction is nonpipelined on the Cell. */
21985 static bool
21986 is_nonpipeline_insn (rtx insn)
21988 enum attr_type type;
21989 if (!insn || !NONDEBUG_INSN_P (insn)
21990 || GET_CODE (PATTERN (insn)) == USE
21991 || GET_CODE (PATTERN (insn)) == CLOBBER)
21992 return false;
21994 type = get_attr_type (insn);
21995 if (type == TYPE_IMUL
21996 || type == TYPE_IMUL2
21997 || type == TYPE_IMUL3
21998 || type == TYPE_LMUL
21999 || type == TYPE_IDIV
22000 || type == TYPE_LDIV
22001 || type == TYPE_SDIV
22002 || type == TYPE_DDIV
22003 || type == TYPE_SSQRT
22004 || type == TYPE_DSQRT
22005 || type == TYPE_MFCR
22006 || type == TYPE_MFCRF
22007 || type == TYPE_MFJMPR)
22009 return true;
22011 return false;
22015 /* Return how many instructions the machine can issue per cycle. */
22017 static int
22018 rs6000_issue_rate (void)
22020 /* Unless scheduling for register pressure, use issue rate of 1 for
22021 first scheduling pass to decrease degradation. */
22022 if (!reload_completed && !flag_sched_pressure)
22023 return 1;
22025 switch (rs6000_cpu_attr) {
22026 case CPU_RIOS1: /* ? */
22027 case CPU_RS64A:
22028 case CPU_PPC601: /* ? */
22029 case CPU_PPC7450:
22030 return 3;
22031 case CPU_PPC440:
22032 case CPU_PPC603:
22033 case CPU_PPC750:
22034 case CPU_PPC7400:
22035 case CPU_PPC8540:
22036 case CPU_CELL:
22037 case CPU_PPCE300C2:
22038 case CPU_PPCE300C3:
22039 case CPU_PPCE500MC:
22040 case CPU_PPCE500MC64:
22041 return 2;
22042 case CPU_RIOS2:
22043 case CPU_PPC476:
22044 case CPU_PPC604:
22045 case CPU_PPC604E:
22046 case CPU_PPC620:
22047 case CPU_PPC630:
22048 return 4;
22049 case CPU_POWER4:
22050 case CPU_POWER5:
22051 case CPU_POWER6:
22052 case CPU_POWER7:
22053 return 5;
22054 default:
22055 return 1;
22059 /* Return how many instructions to look ahead for better insn
22060 scheduling. */
22062 static int
22063 rs6000_use_sched_lookahead (void)
22065 if (rs6000_cpu_attr == CPU_PPC8540)
22066 return 4;
22067 if (rs6000_cpu_attr == CPU_CELL)
22068 return (reload_completed ? 8 : 0);
22069 return 0;
22072 /* We are choosing insn from the ready queue. Return nonzero if INSN can be chosen. */
22073 static int
22074 rs6000_use_sched_lookahead_guard (rtx insn)
22076 if (rs6000_cpu_attr != CPU_CELL)
22077 return 1;
22079 if (insn == NULL_RTX || !INSN_P (insn))
22080 abort ();
22082 if (!reload_completed
22083 || is_nonpipeline_insn (insn)
22084 || is_microcoded_insn (insn))
22085 return 0;
22087 return 1;
22090 /* Determine is PAT refers to memory. */
22092 static bool
22093 is_mem_ref (rtx pat)
22095 const char * fmt;
22096 int i, j;
22097 bool ret = false;
22099 /* stack_tie does not produce any real memory traffic. */
22100 if (GET_CODE (pat) == UNSPEC
22101 && XINT (pat, 1) == UNSPEC_TIE)
22102 return false;
22104 if (GET_CODE (pat) == MEM)
22105 return true;
22107 /* Recursively process the pattern. */
22108 fmt = GET_RTX_FORMAT (GET_CODE (pat));
22110 for (i = GET_RTX_LENGTH (GET_CODE (pat)) - 1; i >= 0 && !ret; i--)
22112 if (fmt[i] == 'e')
22113 ret |= is_mem_ref (XEXP (pat, i));
22114 else if (fmt[i] == 'E')
22115 for (j = XVECLEN (pat, i) - 1; j >= 0; j--)
22116 ret |= is_mem_ref (XVECEXP (pat, i, j));
22119 return ret;
22122 /* Determine if PAT is a PATTERN of a load insn. */
22124 static bool
22125 is_load_insn1 (rtx pat)
22127 if (!pat || pat == NULL_RTX)
22128 return false;
22130 if (GET_CODE (pat) == SET)
22131 return is_mem_ref (SET_SRC (pat));
22133 if (GET_CODE (pat) == PARALLEL)
22135 int i;
22137 for (i = 0; i < XVECLEN (pat, 0); i++)
22138 if (is_load_insn1 (XVECEXP (pat, 0, i)))
22139 return true;
22142 return false;
22145 /* Determine if INSN loads from memory. */
22147 static bool
22148 is_load_insn (rtx insn)
22150 if (!insn || !INSN_P (insn))
22151 return false;
22153 if (GET_CODE (insn) == CALL_INSN)
22154 return false;
22156 return is_load_insn1 (PATTERN (insn));
22159 /* Determine if PAT is a PATTERN of a store insn. */
22161 static bool
22162 is_store_insn1 (rtx pat)
22164 if (!pat || pat == NULL_RTX)
22165 return false;
22167 if (GET_CODE (pat) == SET)
22168 return is_mem_ref (SET_DEST (pat));
22170 if (GET_CODE (pat) == PARALLEL)
22172 int i;
22174 for (i = 0; i < XVECLEN (pat, 0); i++)
22175 if (is_store_insn1 (XVECEXP (pat, 0, i)))
22176 return true;
22179 return false;
22182 /* Determine if INSN stores to memory. */
22184 static bool
22185 is_store_insn (rtx insn)
22187 if (!insn || !INSN_P (insn))
22188 return false;
22190 return is_store_insn1 (PATTERN (insn));
22193 /* Return the dest of a store insn. */
22195 static rtx
22196 get_store_dest (rtx pat)
22198 gcc_assert (is_store_insn1 (pat));
22200 if (GET_CODE (pat) == SET)
22201 return SET_DEST (pat);
22202 else if (GET_CODE (pat) == PARALLEL)
22204 int i;
22206 for (i = 0; i < XVECLEN (pat, 0); i++)
22208 rtx inner_pat = XVECEXP (pat, 0, i);
22209 if (GET_CODE (inner_pat) == SET
22210 && is_mem_ref (SET_DEST (inner_pat)))
22211 return inner_pat;
22214 /* We shouldn't get here, because we should have either a simple
22215 store insn or a store with update which are covered above. */
22216 gcc_unreachable();
22219 /* Returns whether the dependence between INSN and NEXT is considered
22220 costly by the given target. */
22222 static bool
22223 rs6000_is_costly_dependence (dep_t dep, int cost, int distance)
22225 rtx insn;
22226 rtx next;
22228 /* If the flag is not enabled - no dependence is considered costly;
22229 allow all dependent insns in the same group.
22230 This is the most aggressive option. */
22231 if (rs6000_sched_costly_dep == no_dep_costly)
22232 return false;
22234 /* If the flag is set to 1 - a dependence is always considered costly;
22235 do not allow dependent instructions in the same group.
22236 This is the most conservative option. */
22237 if (rs6000_sched_costly_dep == all_deps_costly)
22238 return true;
22240 insn = DEP_PRO (dep);
22241 next = DEP_CON (dep);
22243 if (rs6000_sched_costly_dep == store_to_load_dep_costly
22244 && is_load_insn (next)
22245 && is_store_insn (insn))
22246 /* Prevent load after store in the same group. */
22247 return true;
22249 if (rs6000_sched_costly_dep == true_store_to_load_dep_costly
22250 && is_load_insn (next)
22251 && is_store_insn (insn)
22252 && DEP_TYPE (dep) == REG_DEP_TRUE)
22253 /* Prevent load after store in the same group if it is a true
22254 dependence. */
22255 return true;
22257 /* The flag is set to X; dependences with latency >= X are considered costly,
22258 and will not be scheduled in the same group. */
22259 if (rs6000_sched_costly_dep <= max_dep_latency
22260 && ((cost - distance) >= (int)rs6000_sched_costly_dep))
22261 return true;
22263 return false;
22266 /* Return the next insn after INSN that is found before TAIL is reached,
22267 skipping any "non-active" insns - insns that will not actually occupy
22268 an issue slot. Return NULL_RTX if such an insn is not found. */
22270 static rtx
22271 get_next_active_insn (rtx insn, rtx tail)
22273 if (insn == NULL_RTX || insn == tail)
22274 return NULL_RTX;
22276 while (1)
22278 insn = NEXT_INSN (insn);
22279 if (insn == NULL_RTX || insn == tail)
22280 return NULL_RTX;
22282 if (CALL_P (insn)
22283 || JUMP_P (insn)
22284 || (NONJUMP_INSN_P (insn)
22285 && GET_CODE (PATTERN (insn)) != USE
22286 && GET_CODE (PATTERN (insn)) != CLOBBER
22287 && INSN_CODE (insn) != CODE_FOR_stack_tie))
22288 break;
22290 return insn;
22293 /* We are about to begin issuing insns for this clock cycle. */
22295 static int
22296 rs6000_sched_reorder (FILE *dump ATTRIBUTE_UNUSED, int sched_verbose,
22297 rtx *ready ATTRIBUTE_UNUSED,
22298 int *pn_ready ATTRIBUTE_UNUSED,
22299 int clock_var ATTRIBUTE_UNUSED)
22301 int n_ready = *pn_ready;
22303 if (sched_verbose)
22304 fprintf (dump, "// rs6000_sched_reorder :\n");
22306 /* Reorder the ready list, if the second to last ready insn
22307 is a nonepipeline insn. */
22308 if (rs6000_cpu_attr == CPU_CELL && n_ready > 1)
22310 if (is_nonpipeline_insn (ready[n_ready - 1])
22311 && (recog_memoized (ready[n_ready - 2]) > 0))
22312 /* Simply swap first two insns. */
22314 rtx tmp = ready[n_ready - 1];
22315 ready[n_ready - 1] = ready[n_ready - 2];
22316 ready[n_ready - 2] = tmp;
22320 if (rs6000_cpu == PROCESSOR_POWER6)
22321 load_store_pendulum = 0;
22323 return rs6000_issue_rate ();
22326 /* Like rs6000_sched_reorder, but called after issuing each insn. */
22328 static int
22329 rs6000_sched_reorder2 (FILE *dump, int sched_verbose, rtx *ready,
22330 int *pn_ready, int clock_var ATTRIBUTE_UNUSED)
22332 if (sched_verbose)
22333 fprintf (dump, "// rs6000_sched_reorder2 :\n");
22335 /* For Power6, we need to handle some special cases to try and keep the
22336 store queue from overflowing and triggering expensive flushes.
22338 This code monitors how load and store instructions are being issued
22339 and skews the ready list one way or the other to increase the likelihood
22340 that a desired instruction is issued at the proper time.
22342 A couple of things are done. First, we maintain a "load_store_pendulum"
22343 to track the current state of load/store issue.
22345 - If the pendulum is at zero, then no loads or stores have been
22346 issued in the current cycle so we do nothing.
22348 - If the pendulum is 1, then a single load has been issued in this
22349 cycle and we attempt to locate another load in the ready list to
22350 issue with it.
22352 - If the pendulum is -2, then two stores have already been
22353 issued in this cycle, so we increase the priority of the first load
22354 in the ready list to increase it's likelihood of being chosen first
22355 in the next cycle.
22357 - If the pendulum is -1, then a single store has been issued in this
22358 cycle and we attempt to locate another store in the ready list to
22359 issue with it, preferring a store to an adjacent memory location to
22360 facilitate store pairing in the store queue.
22362 - If the pendulum is 2, then two loads have already been
22363 issued in this cycle, so we increase the priority of the first store
22364 in the ready list to increase it's likelihood of being chosen first
22365 in the next cycle.
22367 - If the pendulum < -2 or > 2, then do nothing.
22369 Note: This code covers the most common scenarios. There exist non
22370 load/store instructions which make use of the LSU and which
22371 would need to be accounted for to strictly model the behavior
22372 of the machine. Those instructions are currently unaccounted
22373 for to help minimize compile time overhead of this code.
22375 if (rs6000_cpu == PROCESSOR_POWER6 && last_scheduled_insn)
22377 int pos;
22378 int i;
22379 rtx tmp;
22381 if (is_store_insn (last_scheduled_insn))
22382 /* Issuing a store, swing the load_store_pendulum to the left */
22383 load_store_pendulum--;
22384 else if (is_load_insn (last_scheduled_insn))
22385 /* Issuing a load, swing the load_store_pendulum to the right */
22386 load_store_pendulum++;
22387 else
22388 return cached_can_issue_more;
22390 /* If the pendulum is balanced, or there is only one instruction on
22391 the ready list, then all is well, so return. */
22392 if ((load_store_pendulum == 0) || (*pn_ready <= 1))
22393 return cached_can_issue_more;
22395 if (load_store_pendulum == 1)
22397 /* A load has been issued in this cycle. Scan the ready list
22398 for another load to issue with it */
22399 pos = *pn_ready-1;
22401 while (pos >= 0)
22403 if (is_load_insn (ready[pos]))
22405 /* Found a load. Move it to the head of the ready list,
22406 and adjust it's priority so that it is more likely to
22407 stay there */
22408 tmp = ready[pos];
22409 for (i=pos; i<*pn_ready-1; i++)
22410 ready[i] = ready[i + 1];
22411 ready[*pn_ready-1] = tmp;
22413 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
22414 INSN_PRIORITY (tmp)++;
22415 break;
22417 pos--;
22420 else if (load_store_pendulum == -2)
22422 /* Two stores have been issued in this cycle. Increase the
22423 priority of the first load in the ready list to favor it for
22424 issuing in the next cycle. */
22425 pos = *pn_ready-1;
22427 while (pos >= 0)
22429 if (is_load_insn (ready[pos])
22430 && !sel_sched_p ()
22431 && INSN_PRIORITY_KNOWN (ready[pos]))
22433 INSN_PRIORITY (ready[pos])++;
22435 /* Adjust the pendulum to account for the fact that a load
22436 was found and increased in priority. This is to prevent
22437 increasing the priority of multiple loads */
22438 load_store_pendulum--;
22440 break;
22442 pos--;
22445 else if (load_store_pendulum == -1)
22447 /* A store has been issued in this cycle. Scan the ready list for
22448 another store to issue with it, preferring a store to an adjacent
22449 memory location */
22450 int first_store_pos = -1;
22452 pos = *pn_ready-1;
22454 while (pos >= 0)
22456 if (is_store_insn (ready[pos]))
22458 /* Maintain the index of the first store found on the
22459 list */
22460 if (first_store_pos == -1)
22461 first_store_pos = pos;
22463 if (is_store_insn (last_scheduled_insn)
22464 && adjacent_mem_locations (last_scheduled_insn,ready[pos]))
22466 /* Found an adjacent store. Move it to the head of the
22467 ready list, and adjust it's priority so that it is
22468 more likely to stay there */
22469 tmp = ready[pos];
22470 for (i=pos; i<*pn_ready-1; i++)
22471 ready[i] = ready[i + 1];
22472 ready[*pn_ready-1] = tmp;
22474 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
22475 INSN_PRIORITY (tmp)++;
22477 first_store_pos = -1;
22479 break;
22482 pos--;
22485 if (first_store_pos >= 0)
22487 /* An adjacent store wasn't found, but a non-adjacent store was,
22488 so move the non-adjacent store to the front of the ready
22489 list, and adjust its priority so that it is more likely to
22490 stay there. */
22491 tmp = ready[first_store_pos];
22492 for (i=first_store_pos; i<*pn_ready-1; i++)
22493 ready[i] = ready[i + 1];
22494 ready[*pn_ready-1] = tmp;
22495 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
22496 INSN_PRIORITY (tmp)++;
22499 else if (load_store_pendulum == 2)
22501 /* Two loads have been issued in this cycle. Increase the priority
22502 of the first store in the ready list to favor it for issuing in
22503 the next cycle. */
22504 pos = *pn_ready-1;
22506 while (pos >= 0)
22508 if (is_store_insn (ready[pos])
22509 && !sel_sched_p ()
22510 && INSN_PRIORITY_KNOWN (ready[pos]))
22512 INSN_PRIORITY (ready[pos])++;
22514 /* Adjust the pendulum to account for the fact that a store
22515 was found and increased in priority. This is to prevent
22516 increasing the priority of multiple stores */
22517 load_store_pendulum++;
22519 break;
22521 pos--;
22526 return cached_can_issue_more;
22529 /* Return whether the presence of INSN causes a dispatch group termination
22530 of group WHICH_GROUP.
22532 If WHICH_GROUP == current_group, this function will return true if INSN
22533 causes the termination of the current group (i.e, the dispatch group to
22534 which INSN belongs). This means that INSN will be the last insn in the
22535 group it belongs to.
22537 If WHICH_GROUP == previous_group, this function will return true if INSN
22538 causes the termination of the previous group (i.e, the dispatch group that
22539 precedes the group to which INSN belongs). This means that INSN will be
22540 the first insn in the group it belongs to). */
22542 static bool
22543 insn_terminates_group_p (rtx insn, enum group_termination which_group)
22545 bool first, last;
22547 if (! insn)
22548 return false;
22550 first = insn_must_be_first_in_group (insn);
22551 last = insn_must_be_last_in_group (insn);
22553 if (first && last)
22554 return true;
22556 if (which_group == current_group)
22557 return last;
22558 else if (which_group == previous_group)
22559 return first;
22561 return false;
22565 static bool
22566 insn_must_be_first_in_group (rtx insn)
22568 enum attr_type type;
22570 if (!insn
22571 || GET_CODE (insn) == NOTE
22572 || DEBUG_INSN_P (insn)
22573 || GET_CODE (PATTERN (insn)) == USE
22574 || GET_CODE (PATTERN (insn)) == CLOBBER)
22575 return false;
22577 switch (rs6000_cpu)
22579 case PROCESSOR_POWER5:
22580 if (is_cracked_insn (insn))
22581 return true;
22582 case PROCESSOR_POWER4:
22583 if (is_microcoded_insn (insn))
22584 return true;
22586 if (!rs6000_sched_groups)
22587 return false;
22589 type = get_attr_type (insn);
22591 switch (type)
22593 case TYPE_MFCR:
22594 case TYPE_MFCRF:
22595 case TYPE_MTCR:
22596 case TYPE_DELAYED_CR:
22597 case TYPE_CR_LOGICAL:
22598 case TYPE_MTJMPR:
22599 case TYPE_MFJMPR:
22600 case TYPE_IDIV:
22601 case TYPE_LDIV:
22602 case TYPE_LOAD_L:
22603 case TYPE_STORE_C:
22604 case TYPE_ISYNC:
22605 case TYPE_SYNC:
22606 return true;
22607 default:
22608 break;
22610 break;
22611 case PROCESSOR_POWER6:
22612 type = get_attr_type (insn);
22614 switch (type)
22616 case TYPE_INSERT_DWORD:
22617 case TYPE_EXTS:
22618 case TYPE_CNTLZ:
22619 case TYPE_SHIFT:
22620 case TYPE_VAR_SHIFT_ROTATE:
22621 case TYPE_TRAP:
22622 case TYPE_IMUL:
22623 case TYPE_IMUL2:
22624 case TYPE_IMUL3:
22625 case TYPE_LMUL:
22626 case TYPE_IDIV:
22627 case TYPE_INSERT_WORD:
22628 case TYPE_DELAYED_COMPARE:
22629 case TYPE_IMUL_COMPARE:
22630 case TYPE_LMUL_COMPARE:
22631 case TYPE_FPCOMPARE:
22632 case TYPE_MFCR:
22633 case TYPE_MTCR:
22634 case TYPE_MFJMPR:
22635 case TYPE_MTJMPR:
22636 case TYPE_ISYNC:
22637 case TYPE_SYNC:
22638 case TYPE_LOAD_L:
22639 case TYPE_STORE_C:
22640 case TYPE_LOAD_U:
22641 case TYPE_LOAD_UX:
22642 case TYPE_LOAD_EXT_UX:
22643 case TYPE_STORE_U:
22644 case TYPE_STORE_UX:
22645 case TYPE_FPLOAD_U:
22646 case TYPE_FPLOAD_UX:
22647 case TYPE_FPSTORE_U:
22648 case TYPE_FPSTORE_UX:
22649 return true;
22650 default:
22651 break;
22653 break;
22654 case PROCESSOR_POWER7:
22655 type = get_attr_type (insn);
22657 switch (type)
22659 case TYPE_CR_LOGICAL:
22660 case TYPE_MFCR:
22661 case TYPE_MFCRF:
22662 case TYPE_MTCR:
22663 case TYPE_IDIV:
22664 case TYPE_LDIV:
22665 case TYPE_COMPARE:
22666 case TYPE_DELAYED_COMPARE:
22667 case TYPE_VAR_DELAYED_COMPARE:
22668 case TYPE_ISYNC:
22669 case TYPE_LOAD_L:
22670 case TYPE_STORE_C:
22671 case TYPE_LOAD_U:
22672 case TYPE_LOAD_UX:
22673 case TYPE_LOAD_EXT:
22674 case TYPE_LOAD_EXT_U:
22675 case TYPE_LOAD_EXT_UX:
22676 case TYPE_STORE_U:
22677 case TYPE_STORE_UX:
22678 case TYPE_FPLOAD_U:
22679 case TYPE_FPLOAD_UX:
22680 case TYPE_FPSTORE_U:
22681 case TYPE_FPSTORE_UX:
22682 case TYPE_MFJMPR:
22683 case TYPE_MTJMPR:
22684 return true;
22685 default:
22686 break;
22688 break;
22689 default:
22690 break;
22693 return false;
22696 static bool
22697 insn_must_be_last_in_group (rtx insn)
22699 enum attr_type type;
22701 if (!insn
22702 || GET_CODE (insn) == NOTE
22703 || DEBUG_INSN_P (insn)
22704 || GET_CODE (PATTERN (insn)) == USE
22705 || GET_CODE (PATTERN (insn)) == CLOBBER)
22706 return false;
22708 switch (rs6000_cpu) {
22709 case PROCESSOR_POWER4:
22710 case PROCESSOR_POWER5:
22711 if (is_microcoded_insn (insn))
22712 return true;
22714 if (is_branch_slot_insn (insn))
22715 return true;
22717 break;
22718 case PROCESSOR_POWER6:
22719 type = get_attr_type (insn);
22721 switch (type)
22723 case TYPE_EXTS:
22724 case TYPE_CNTLZ:
22725 case TYPE_SHIFT:
22726 case TYPE_VAR_SHIFT_ROTATE:
22727 case TYPE_TRAP:
22728 case TYPE_IMUL:
22729 case TYPE_IMUL2:
22730 case TYPE_IMUL3:
22731 case TYPE_LMUL:
22732 case TYPE_IDIV:
22733 case TYPE_DELAYED_COMPARE:
22734 case TYPE_IMUL_COMPARE:
22735 case TYPE_LMUL_COMPARE:
22736 case TYPE_FPCOMPARE:
22737 case TYPE_MFCR:
22738 case TYPE_MTCR:
22739 case TYPE_MFJMPR:
22740 case TYPE_MTJMPR:
22741 case TYPE_ISYNC:
22742 case TYPE_SYNC:
22743 case TYPE_LOAD_L:
22744 case TYPE_STORE_C:
22745 return true;
22746 default:
22747 break;
22749 break;
22750 case PROCESSOR_POWER7:
22751 type = get_attr_type (insn);
22753 switch (type)
22755 case TYPE_ISYNC:
22756 case TYPE_SYNC:
22757 case TYPE_LOAD_L:
22758 case TYPE_STORE_C:
22759 case TYPE_LOAD_EXT_U:
22760 case TYPE_LOAD_EXT_UX:
22761 case TYPE_STORE_UX:
22762 return true;
22763 default:
22764 break;
22766 break;
22767 default:
22768 break;
22771 return false;
22774 /* Return true if it is recommended to keep NEXT_INSN "far" (in a separate
22775 dispatch group) from the insns in GROUP_INSNS. Return false otherwise. */
22777 static bool
22778 is_costly_group (rtx *group_insns, rtx next_insn)
22780 int i;
22781 int issue_rate = rs6000_issue_rate ();
22783 for (i = 0; i < issue_rate; i++)
22785 sd_iterator_def sd_it;
22786 dep_t dep;
22787 rtx insn = group_insns[i];
22789 if (!insn)
22790 continue;
22792 FOR_EACH_DEP (insn, SD_LIST_FORW, sd_it, dep)
22794 rtx next = DEP_CON (dep);
22796 if (next == next_insn
22797 && rs6000_is_costly_dependence (dep, dep_cost (dep), 0))
22798 return true;
22802 return false;
22805 /* Utility of the function redefine_groups.
22806 Check if it is too costly to schedule NEXT_INSN together with GROUP_INSNS
22807 in the same dispatch group. If so, insert nops before NEXT_INSN, in order
22808 to keep it "far" (in a separate group) from GROUP_INSNS, following
22809 one of the following schemes, depending on the value of the flag
22810 -minsert_sched_nops = X:
22811 (1) X == sched_finish_regroup_exact: insert exactly as many nops as needed
22812 in order to force NEXT_INSN into a separate group.
22813 (2) X < sched_finish_regroup_exact: insert exactly X nops.
22814 GROUP_END, CAN_ISSUE_MORE and GROUP_COUNT record the state after nop
22815 insertion (has a group just ended, how many vacant issue slots remain in the
22816 last group, and how many dispatch groups were encountered so far). */
22818 static int
22819 force_new_group (int sched_verbose, FILE *dump, rtx *group_insns,
22820 rtx next_insn, bool *group_end, int can_issue_more,
22821 int *group_count)
22823 rtx nop;
22824 bool force;
22825 int issue_rate = rs6000_issue_rate ();
22826 bool end = *group_end;
22827 int i;
22829 if (next_insn == NULL_RTX || DEBUG_INSN_P (next_insn))
22830 return can_issue_more;
22832 if (rs6000_sched_insert_nops > sched_finish_regroup_exact)
22833 return can_issue_more;
22835 force = is_costly_group (group_insns, next_insn);
22836 if (!force)
22837 return can_issue_more;
22839 if (sched_verbose > 6)
22840 fprintf (dump,"force: group count = %d, can_issue_more = %d\n",
22841 *group_count ,can_issue_more);
22843 if (rs6000_sched_insert_nops == sched_finish_regroup_exact)
22845 if (*group_end)
22846 can_issue_more = 0;
22848 /* Since only a branch can be issued in the last issue_slot, it is
22849 sufficient to insert 'can_issue_more - 1' nops if next_insn is not
22850 a branch. If next_insn is a branch, we insert 'can_issue_more' nops;
22851 in this case the last nop will start a new group and the branch
22852 will be forced to the new group. */
22853 if (can_issue_more && !is_branch_slot_insn (next_insn))
22854 can_issue_more--;
22856 while (can_issue_more > 0)
22858 nop = gen_nop ();
22859 emit_insn_before (nop, next_insn);
22860 can_issue_more--;
22863 *group_end = true;
22864 return 0;
22867 if (rs6000_sched_insert_nops < sched_finish_regroup_exact)
22869 int n_nops = rs6000_sched_insert_nops;
22871 /* Nops can't be issued from the branch slot, so the effective
22872 issue_rate for nops is 'issue_rate - 1'. */
22873 if (can_issue_more == 0)
22874 can_issue_more = issue_rate;
22875 can_issue_more--;
22876 if (can_issue_more == 0)
22878 can_issue_more = issue_rate - 1;
22879 (*group_count)++;
22880 end = true;
22881 for (i = 0; i < issue_rate; i++)
22883 group_insns[i] = 0;
22887 while (n_nops > 0)
22889 nop = gen_nop ();
22890 emit_insn_before (nop, next_insn);
22891 if (can_issue_more == issue_rate - 1) /* new group begins */
22892 end = false;
22893 can_issue_more--;
22894 if (can_issue_more == 0)
22896 can_issue_more = issue_rate - 1;
22897 (*group_count)++;
22898 end = true;
22899 for (i = 0; i < issue_rate; i++)
22901 group_insns[i] = 0;
22904 n_nops--;
22907 /* Scale back relative to 'issue_rate' (instead of 'issue_rate - 1'). */
22908 can_issue_more++;
22910 /* Is next_insn going to start a new group? */
22911 *group_end
22912 = (end
22913 || (can_issue_more == 1 && !is_branch_slot_insn (next_insn))
22914 || (can_issue_more <= 2 && is_cracked_insn (next_insn))
22915 || (can_issue_more < issue_rate &&
22916 insn_terminates_group_p (next_insn, previous_group)));
22917 if (*group_end && end)
22918 (*group_count)--;
22920 if (sched_verbose > 6)
22921 fprintf (dump, "done force: group count = %d, can_issue_more = %d\n",
22922 *group_count, can_issue_more);
22923 return can_issue_more;
22926 return can_issue_more;
22929 /* This function tries to synch the dispatch groups that the compiler "sees"
22930 with the dispatch groups that the processor dispatcher is expected to
22931 form in practice. It tries to achieve this synchronization by forcing the
22932 estimated processor grouping on the compiler (as opposed to the function
22933 'pad_goups' which tries to force the scheduler's grouping on the processor).
22935 The function scans the insn sequence between PREV_HEAD_INSN and TAIL and
22936 examines the (estimated) dispatch groups that will be formed by the processor
22937 dispatcher. It marks these group boundaries to reflect the estimated
22938 processor grouping, overriding the grouping that the scheduler had marked.
22939 Depending on the value of the flag '-minsert-sched-nops' this function can
22940 force certain insns into separate groups or force a certain distance between
22941 them by inserting nops, for example, if there exists a "costly dependence"
22942 between the insns.
22944 The function estimates the group boundaries that the processor will form as
22945 follows: It keeps track of how many vacant issue slots are available after
22946 each insn. A subsequent insn will start a new group if one of the following
22947 4 cases applies:
22948 - no more vacant issue slots remain in the current dispatch group.
22949 - only the last issue slot, which is the branch slot, is vacant, but the next
22950 insn is not a branch.
22951 - only the last 2 or less issue slots, including the branch slot, are vacant,
22952 which means that a cracked insn (which occupies two issue slots) can't be
22953 issued in this group.
22954 - less than 'issue_rate' slots are vacant, and the next insn always needs to
22955 start a new group. */
22957 static int
22958 redefine_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail)
22960 rtx insn, next_insn;
22961 int issue_rate;
22962 int can_issue_more;
22963 int slot, i;
22964 bool group_end;
22965 int group_count = 0;
22966 rtx *group_insns;
22968 /* Initialize. */
22969 issue_rate = rs6000_issue_rate ();
22970 group_insns = XALLOCAVEC (rtx, issue_rate);
22971 for (i = 0; i < issue_rate; i++)
22973 group_insns[i] = 0;
22975 can_issue_more = issue_rate;
22976 slot = 0;
22977 insn = get_next_active_insn (prev_head_insn, tail);
22978 group_end = false;
22980 while (insn != NULL_RTX)
22982 slot = (issue_rate - can_issue_more);
22983 group_insns[slot] = insn;
22984 can_issue_more =
22985 rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more);
22986 if (insn_terminates_group_p (insn, current_group))
22987 can_issue_more = 0;
22989 next_insn = get_next_active_insn (insn, tail);
22990 if (next_insn == NULL_RTX)
22991 return group_count + 1;
22993 /* Is next_insn going to start a new group? */
22994 group_end
22995 = (can_issue_more == 0
22996 || (can_issue_more == 1 && !is_branch_slot_insn (next_insn))
22997 || (can_issue_more <= 2 && is_cracked_insn (next_insn))
22998 || (can_issue_more < issue_rate &&
22999 insn_terminates_group_p (next_insn, previous_group)));
23001 can_issue_more = force_new_group (sched_verbose, dump, group_insns,
23002 next_insn, &group_end, can_issue_more,
23003 &group_count);
23005 if (group_end)
23007 group_count++;
23008 can_issue_more = 0;
23009 for (i = 0; i < issue_rate; i++)
23011 group_insns[i] = 0;
23015 if (GET_MODE (next_insn) == TImode && can_issue_more)
23016 PUT_MODE (next_insn, VOIDmode);
23017 else if (!can_issue_more && GET_MODE (next_insn) != TImode)
23018 PUT_MODE (next_insn, TImode);
23020 insn = next_insn;
23021 if (can_issue_more == 0)
23022 can_issue_more = issue_rate;
23023 } /* while */
23025 return group_count;
23028 /* Scan the insn sequence between PREV_HEAD_INSN and TAIL and examine the
23029 dispatch group boundaries that the scheduler had marked. Pad with nops
23030 any dispatch groups which have vacant issue slots, in order to force the
23031 scheduler's grouping on the processor dispatcher. The function
23032 returns the number of dispatch groups found. */
23034 static int
23035 pad_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail)
23037 rtx insn, next_insn;
23038 rtx nop;
23039 int issue_rate;
23040 int can_issue_more;
23041 int group_end;
23042 int group_count = 0;
23044 /* Initialize issue_rate. */
23045 issue_rate = rs6000_issue_rate ();
23046 can_issue_more = issue_rate;
23048 insn = get_next_active_insn (prev_head_insn, tail);
23049 next_insn = get_next_active_insn (insn, tail);
23051 while (insn != NULL_RTX)
23053 can_issue_more =
23054 rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more);
23056 group_end = (next_insn == NULL_RTX || GET_MODE (next_insn) == TImode);
23058 if (next_insn == NULL_RTX)
23059 break;
23061 if (group_end)
23063 /* If the scheduler had marked group termination at this location
23064 (between insn and next_insn), and neither insn nor next_insn will
23065 force group termination, pad the group with nops to force group
23066 termination. */
23067 if (can_issue_more
23068 && (rs6000_sched_insert_nops == sched_finish_pad_groups)
23069 && !insn_terminates_group_p (insn, current_group)
23070 && !insn_terminates_group_p (next_insn, previous_group))
23072 if (!is_branch_slot_insn (next_insn))
23073 can_issue_more--;
23075 while (can_issue_more)
23077 nop = gen_nop ();
23078 emit_insn_before (nop, next_insn);
23079 can_issue_more--;
23083 can_issue_more = issue_rate;
23084 group_count++;
23087 insn = next_insn;
23088 next_insn = get_next_active_insn (insn, tail);
23091 return group_count;
23094 /* We're beginning a new block. Initialize data structures as necessary. */
23096 static void
23097 rs6000_sched_init (FILE *dump ATTRIBUTE_UNUSED,
23098 int sched_verbose ATTRIBUTE_UNUSED,
23099 int max_ready ATTRIBUTE_UNUSED)
23101 last_scheduled_insn = NULL_RTX;
23102 load_store_pendulum = 0;
23105 /* The following function is called at the end of scheduling BB.
23106 After reload, it inserts nops at insn group bundling. */
23108 static void
23109 rs6000_sched_finish (FILE *dump, int sched_verbose)
23111 int n_groups;
23113 if (sched_verbose)
23114 fprintf (dump, "=== Finishing schedule.\n");
23116 if (reload_completed && rs6000_sched_groups)
23118 /* Do not run sched_finish hook when selective scheduling enabled. */
23119 if (sel_sched_p ())
23120 return;
23122 if (rs6000_sched_insert_nops == sched_finish_none)
23123 return;
23125 if (rs6000_sched_insert_nops == sched_finish_pad_groups)
23126 n_groups = pad_groups (dump, sched_verbose,
23127 current_sched_info->prev_head,
23128 current_sched_info->next_tail);
23129 else
23130 n_groups = redefine_groups (dump, sched_verbose,
23131 current_sched_info->prev_head,
23132 current_sched_info->next_tail);
23134 if (sched_verbose >= 6)
23136 fprintf (dump, "ngroups = %d\n", n_groups);
23137 print_rtl (dump, current_sched_info->prev_head);
23138 fprintf (dump, "Done finish_sched\n");
23143 struct _rs6000_sched_context
23145 short cached_can_issue_more;
23146 rtx last_scheduled_insn;
23147 int load_store_pendulum;
23150 typedef struct _rs6000_sched_context rs6000_sched_context_def;
23151 typedef rs6000_sched_context_def *rs6000_sched_context_t;
23153 /* Allocate store for new scheduling context. */
23154 static void *
23155 rs6000_alloc_sched_context (void)
23157 return xmalloc (sizeof (rs6000_sched_context_def));
23160 /* If CLEAN_P is true then initializes _SC with clean data,
23161 and from the global context otherwise. */
23162 static void
23163 rs6000_init_sched_context (void *_sc, bool clean_p)
23165 rs6000_sched_context_t sc = (rs6000_sched_context_t) _sc;
23167 if (clean_p)
23169 sc->cached_can_issue_more = 0;
23170 sc->last_scheduled_insn = NULL_RTX;
23171 sc->load_store_pendulum = 0;
23173 else
23175 sc->cached_can_issue_more = cached_can_issue_more;
23176 sc->last_scheduled_insn = last_scheduled_insn;
23177 sc->load_store_pendulum = load_store_pendulum;
23181 /* Sets the global scheduling context to the one pointed to by _SC. */
23182 static void
23183 rs6000_set_sched_context (void *_sc)
23185 rs6000_sched_context_t sc = (rs6000_sched_context_t) _sc;
23187 gcc_assert (sc != NULL);
23189 cached_can_issue_more = sc->cached_can_issue_more;
23190 last_scheduled_insn = sc->last_scheduled_insn;
23191 load_store_pendulum = sc->load_store_pendulum;
23194 /* Free _SC. */
23195 static void
23196 rs6000_free_sched_context (void *_sc)
23198 gcc_assert (_sc != NULL);
23200 free (_sc);
23204 /* Length in units of the trampoline for entering a nested function. */
23207 rs6000_trampoline_size (void)
23209 int ret = 0;
23211 switch (DEFAULT_ABI)
23213 default:
23214 gcc_unreachable ();
23216 case ABI_AIX:
23217 ret = (TARGET_32BIT) ? 12 : 24;
23218 break;
23220 case ABI_DARWIN:
23221 case ABI_V4:
23222 ret = (TARGET_32BIT) ? 40 : 48;
23223 break;
23226 return ret;
23229 /* Emit RTL insns to initialize the variable parts of a trampoline.
23230 FNADDR is an RTX for the address of the function's pure code.
23231 CXT is an RTX for the static chain value for the function. */
23233 static void
23234 rs6000_trampoline_init (rtx m_tramp, tree fndecl, rtx cxt)
23236 int regsize = (TARGET_32BIT) ? 4 : 8;
23237 rtx fnaddr = XEXP (DECL_RTL (fndecl), 0);
23238 rtx ctx_reg = force_reg (Pmode, cxt);
23239 rtx addr = force_reg (Pmode, XEXP (m_tramp, 0));
23241 switch (DEFAULT_ABI)
23243 default:
23244 gcc_unreachable ();
23246 /* Under AIX, just build the 3 word function descriptor */
23247 case ABI_AIX:
23249 rtx fnmem = gen_const_mem (Pmode, force_reg (Pmode, fnaddr));
23250 rtx fn_reg = gen_reg_rtx (Pmode);
23251 rtx toc_reg = gen_reg_rtx (Pmode);
23253 /* Macro to shorten the code expansions below. */
23254 # define MEM_PLUS(MEM, OFFSET) adjust_address (MEM, Pmode, OFFSET)
23256 m_tramp = replace_equiv_address (m_tramp, addr);
23258 emit_move_insn (fn_reg, MEM_PLUS (fnmem, 0));
23259 emit_move_insn (toc_reg, MEM_PLUS (fnmem, regsize));
23260 emit_move_insn (MEM_PLUS (m_tramp, 0), fn_reg);
23261 emit_move_insn (MEM_PLUS (m_tramp, regsize), toc_reg);
23262 emit_move_insn (MEM_PLUS (m_tramp, 2*regsize), ctx_reg);
23264 # undef MEM_PLUS
23266 break;
23268 /* Under V.4/eabi/darwin, __trampoline_setup does the real work. */
23269 case ABI_DARWIN:
23270 case ABI_V4:
23271 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__trampoline_setup"),
23272 LCT_NORMAL, VOIDmode, 4,
23273 addr, Pmode,
23274 GEN_INT (rs6000_trampoline_size ()), SImode,
23275 fnaddr, Pmode,
23276 ctx_reg, Pmode);
23277 break;
23282 /* Handle the "altivec" attribute. The attribute may have
23283 arguments as follows:
23285 __attribute__((altivec(vector__)))
23286 __attribute__((altivec(pixel__))) (always followed by 'unsigned short')
23287 __attribute__((altivec(bool__))) (always followed by 'unsigned')
23289 and may appear more than once (e.g., 'vector bool char') in a
23290 given declaration. */
23292 static tree
23293 rs6000_handle_altivec_attribute (tree *node,
23294 tree name ATTRIBUTE_UNUSED,
23295 tree args,
23296 int flags ATTRIBUTE_UNUSED,
23297 bool *no_add_attrs)
23299 tree type = *node, result = NULL_TREE;
23300 enum machine_mode mode;
23301 int unsigned_p;
23302 char altivec_type
23303 = ((args && TREE_CODE (args) == TREE_LIST && TREE_VALUE (args)
23304 && TREE_CODE (TREE_VALUE (args)) == IDENTIFIER_NODE)
23305 ? *IDENTIFIER_POINTER (TREE_VALUE (args))
23306 : '?');
23308 while (POINTER_TYPE_P (type)
23309 || TREE_CODE (type) == FUNCTION_TYPE
23310 || TREE_CODE (type) == METHOD_TYPE
23311 || TREE_CODE (type) == ARRAY_TYPE)
23312 type = TREE_TYPE (type);
23314 mode = TYPE_MODE (type);
23316 /* Check for invalid AltiVec type qualifiers. */
23317 if (type == long_double_type_node)
23318 error ("use of %<long double%> in AltiVec types is invalid");
23319 else if (type == boolean_type_node)
23320 error ("use of boolean types in AltiVec types is invalid");
23321 else if (TREE_CODE (type) == COMPLEX_TYPE)
23322 error ("use of %<complex%> in AltiVec types is invalid");
23323 else if (DECIMAL_FLOAT_MODE_P (mode))
23324 error ("use of decimal floating point types in AltiVec types is invalid");
23325 else if (!TARGET_VSX)
23327 if (type == long_unsigned_type_node || type == long_integer_type_node)
23329 if (TARGET_64BIT)
23330 error ("use of %<long%> in AltiVec types is invalid for "
23331 "64-bit code without -mvsx");
23332 else if (rs6000_warn_altivec_long)
23333 warning (0, "use of %<long%> in AltiVec types is deprecated; "
23334 "use %<int%>");
23336 else if (type == long_long_unsigned_type_node
23337 || type == long_long_integer_type_node)
23338 error ("use of %<long long%> in AltiVec types is invalid without "
23339 "-mvsx");
23340 else if (type == double_type_node)
23341 error ("use of %<double%> in AltiVec types is invalid without -mvsx");
23344 switch (altivec_type)
23346 case 'v':
23347 unsigned_p = TYPE_UNSIGNED (type);
23348 switch (mode)
23350 case DImode:
23351 result = (unsigned_p ? unsigned_V2DI_type_node : V2DI_type_node);
23352 break;
23353 case SImode:
23354 result = (unsigned_p ? unsigned_V4SI_type_node : V4SI_type_node);
23355 break;
23356 case HImode:
23357 result = (unsigned_p ? unsigned_V8HI_type_node : V8HI_type_node);
23358 break;
23359 case QImode:
23360 result = (unsigned_p ? unsigned_V16QI_type_node : V16QI_type_node);
23361 break;
23362 case SFmode: result = V4SF_type_node; break;
23363 case DFmode: result = V2DF_type_node; break;
23364 /* If the user says 'vector int bool', we may be handed the 'bool'
23365 attribute _before_ the 'vector' attribute, and so select the
23366 proper type in the 'b' case below. */
23367 case V4SImode: case V8HImode: case V16QImode: case V4SFmode:
23368 case V2DImode: case V2DFmode:
23369 result = type;
23370 default: break;
23372 break;
23373 case 'b':
23374 switch (mode)
23376 case DImode: case V2DImode: result = bool_V2DI_type_node; break;
23377 case SImode: case V4SImode: result = bool_V4SI_type_node; break;
23378 case HImode: case V8HImode: result = bool_V8HI_type_node; break;
23379 case QImode: case V16QImode: result = bool_V16QI_type_node;
23380 default: break;
23382 break;
23383 case 'p':
23384 switch (mode)
23386 case V8HImode: result = pixel_V8HI_type_node;
23387 default: break;
23389 default: break;
23392 /* Propagate qualifiers attached to the element type
23393 onto the vector type. */
23394 if (result && result != type && TYPE_QUALS (type))
23395 result = build_qualified_type (result, TYPE_QUALS (type));
23397 *no_add_attrs = true; /* No need to hang on to the attribute. */
23399 if (result)
23400 *node = lang_hooks.types.reconstruct_complex_type (*node, result);
23402 return NULL_TREE;
23405 /* AltiVec defines four built-in scalar types that serve as vector
23406 elements; we must teach the compiler how to mangle them. */
23408 static const char *
23409 rs6000_mangle_type (const_tree type)
23411 type = TYPE_MAIN_VARIANT (type);
23413 if (TREE_CODE (type) != VOID_TYPE && TREE_CODE (type) != BOOLEAN_TYPE
23414 && TREE_CODE (type) != INTEGER_TYPE && TREE_CODE (type) != REAL_TYPE)
23415 return NULL;
23417 if (type == bool_char_type_node) return "U6__boolc";
23418 if (type == bool_short_type_node) return "U6__bools";
23419 if (type == pixel_type_node) return "u7__pixel";
23420 if (type == bool_int_type_node) return "U6__booli";
23421 if (type == bool_long_type_node) return "U6__booll";
23423 /* Mangle IBM extended float long double as `g' (__float128) on
23424 powerpc*-linux where long-double-64 previously was the default. */
23425 if (TYPE_MAIN_VARIANT (type) == long_double_type_node
23426 && TARGET_ELF
23427 && TARGET_LONG_DOUBLE_128
23428 && !TARGET_IEEEQUAD)
23429 return "g";
23431 /* For all other types, use normal C++ mangling. */
23432 return NULL;
23435 /* Handle a "longcall" or "shortcall" attribute; arguments as in
23436 struct attribute_spec.handler. */
23438 static tree
23439 rs6000_handle_longcall_attribute (tree *node, tree name,
23440 tree args ATTRIBUTE_UNUSED,
23441 int flags ATTRIBUTE_UNUSED,
23442 bool *no_add_attrs)
23444 if (TREE_CODE (*node) != FUNCTION_TYPE
23445 && TREE_CODE (*node) != FIELD_DECL
23446 && TREE_CODE (*node) != TYPE_DECL)
23448 warning (OPT_Wattributes, "%qE attribute only applies to functions",
23449 name);
23450 *no_add_attrs = true;
23453 return NULL_TREE;
23456 /* Set longcall attributes on all functions declared when
23457 rs6000_default_long_calls is true. */
23458 static void
23459 rs6000_set_default_type_attributes (tree type)
23461 if (rs6000_default_long_calls
23462 && (TREE_CODE (type) == FUNCTION_TYPE
23463 || TREE_CODE (type) == METHOD_TYPE))
23464 TYPE_ATTRIBUTES (type) = tree_cons (get_identifier ("longcall"),
23465 NULL_TREE,
23466 TYPE_ATTRIBUTES (type));
23468 #if TARGET_MACHO
23469 darwin_set_default_type_attributes (type);
23470 #endif
23473 /* Return a reference suitable for calling a function with the
23474 longcall attribute. */
23477 rs6000_longcall_ref (rtx call_ref)
23479 const char *call_name;
23480 tree node;
23482 if (GET_CODE (call_ref) != SYMBOL_REF)
23483 return call_ref;
23485 /* System V adds '.' to the internal name, so skip them. */
23486 call_name = XSTR (call_ref, 0);
23487 if (*call_name == '.')
23489 while (*call_name == '.')
23490 call_name++;
23492 node = get_identifier (call_name);
23493 call_ref = gen_rtx_SYMBOL_REF (VOIDmode, IDENTIFIER_POINTER (node));
23496 return force_reg (Pmode, call_ref);
23499 #ifndef TARGET_USE_MS_BITFIELD_LAYOUT
23500 #define TARGET_USE_MS_BITFIELD_LAYOUT 0
23501 #endif
23503 /* Handle a "ms_struct" or "gcc_struct" attribute; arguments as in
23504 struct attribute_spec.handler. */
23505 static tree
23506 rs6000_handle_struct_attribute (tree *node, tree name,
23507 tree args ATTRIBUTE_UNUSED,
23508 int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
23510 tree *type = NULL;
23511 if (DECL_P (*node))
23513 if (TREE_CODE (*node) == TYPE_DECL)
23514 type = &TREE_TYPE (*node);
23516 else
23517 type = node;
23519 if (!(type && (TREE_CODE (*type) == RECORD_TYPE
23520 || TREE_CODE (*type) == UNION_TYPE)))
23522 warning (OPT_Wattributes, "%qE attribute ignored", name);
23523 *no_add_attrs = true;
23526 else if ((is_attribute_p ("ms_struct", name)
23527 && lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (*type)))
23528 || ((is_attribute_p ("gcc_struct", name)
23529 && lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (*type)))))
23531 warning (OPT_Wattributes, "%qE incompatible attribute ignored",
23532 name);
23533 *no_add_attrs = true;
23536 return NULL_TREE;
23539 static bool
23540 rs6000_ms_bitfield_layout_p (const_tree record_type)
23542 return (TARGET_USE_MS_BITFIELD_LAYOUT &&
23543 !lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (record_type)))
23544 || lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (record_type));
23547 #ifdef USING_ELFOS_H
23549 /* A get_unnamed_section callback, used for switching to toc_section. */
23551 static void
23552 rs6000_elf_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
23554 if (DEFAULT_ABI == ABI_AIX
23555 && TARGET_MINIMAL_TOC
23556 && !TARGET_RELOCATABLE)
23558 if (!toc_initialized)
23560 toc_initialized = 1;
23561 fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);
23562 (*targetm.asm_out.internal_label) (asm_out_file, "LCTOC", 0);
23563 fprintf (asm_out_file, "\t.tc ");
23564 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1[TC],");
23565 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
23566 fprintf (asm_out_file, "\n");
23568 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
23569 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
23570 fprintf (asm_out_file, " = .+32768\n");
23572 else
23573 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
23575 else if (DEFAULT_ABI == ABI_AIX && !TARGET_RELOCATABLE)
23576 fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);
23577 else
23579 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
23580 if (!toc_initialized)
23582 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
23583 fprintf (asm_out_file, " = .+32768\n");
23584 toc_initialized = 1;
23589 /* Implement TARGET_ASM_INIT_SECTIONS. */
23591 static void
23592 rs6000_elf_asm_init_sections (void)
23594 toc_section
23595 = get_unnamed_section (0, rs6000_elf_output_toc_section_asm_op, NULL);
23597 sdata2_section
23598 = get_unnamed_section (SECTION_WRITE, output_section_asm_op,
23599 SDATA2_SECTION_ASM_OP);
23602 /* Implement TARGET_SELECT_RTX_SECTION. */
23604 static section *
23605 rs6000_elf_select_rtx_section (enum machine_mode mode, rtx x,
23606 unsigned HOST_WIDE_INT align)
23608 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
23609 return toc_section;
23610 else
23611 return default_elf_select_rtx_section (mode, x, align);
23614 /* For a SYMBOL_REF, set generic flags and then perform some
23615 target-specific processing.
23617 When the AIX ABI is requested on a non-AIX system, replace the
23618 function name with the real name (with a leading .) rather than the
23619 function descriptor name. This saves a lot of overriding code to
23620 read the prefixes. */
23622 static void
23623 rs6000_elf_encode_section_info (tree decl, rtx rtl, int first)
23625 default_encode_section_info (decl, rtl, first);
23627 if (first
23628 && TREE_CODE (decl) == FUNCTION_DECL
23629 && !TARGET_AIX
23630 && DEFAULT_ABI == ABI_AIX)
23632 rtx sym_ref = XEXP (rtl, 0);
23633 size_t len = strlen (XSTR (sym_ref, 0));
23634 char *str = XALLOCAVEC (char, len + 2);
23635 str[0] = '.';
23636 memcpy (str + 1, XSTR (sym_ref, 0), len + 1);
23637 XSTR (sym_ref, 0) = ggc_alloc_string (str, len + 1);
23641 static inline bool
23642 compare_section_name (const char *section, const char *templ)
23644 int len;
23646 len = strlen (templ);
23647 return (strncmp (section, templ, len) == 0
23648 && (section[len] == 0 || section[len] == '.'));
23651 bool
23652 rs6000_elf_in_small_data_p (const_tree decl)
23654 if (rs6000_sdata == SDATA_NONE)
23655 return false;
23657 /* We want to merge strings, so we never consider them small data. */
23658 if (TREE_CODE (decl) == STRING_CST)
23659 return false;
23661 /* Functions are never in the small data area. */
23662 if (TREE_CODE (decl) == FUNCTION_DECL)
23663 return false;
23665 if (TREE_CODE (decl) == VAR_DECL && DECL_SECTION_NAME (decl))
23667 const char *section = TREE_STRING_POINTER (DECL_SECTION_NAME (decl));
23668 if (compare_section_name (section, ".sdata")
23669 || compare_section_name (section, ".sdata2")
23670 || compare_section_name (section, ".gnu.linkonce.s")
23671 || compare_section_name (section, ".sbss")
23672 || compare_section_name (section, ".sbss2")
23673 || compare_section_name (section, ".gnu.linkonce.sb")
23674 || strcmp (section, ".PPC.EMB.sdata0") == 0
23675 || strcmp (section, ".PPC.EMB.sbss0") == 0)
23676 return true;
23678 else
23680 HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (decl));
23682 if (size > 0
23683 && (unsigned HOST_WIDE_INT) size <= g_switch_value
23684 /* If it's not public, and we're not going to reference it there,
23685 there's no need to put it in the small data section. */
23686 && (rs6000_sdata != SDATA_DATA || TREE_PUBLIC (decl)))
23687 return true;
23690 return false;
23693 #endif /* USING_ELFOS_H */
23695 /* Implement TARGET_USE_BLOCKS_FOR_CONSTANT_P. */
23697 static bool
23698 rs6000_use_blocks_for_constant_p (enum machine_mode mode, const_rtx x)
23700 return !ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode);
23703 /* Return a REG that occurs in ADDR with coefficient 1.
23704 ADDR can be effectively incremented by incrementing REG.
23706 r0 is special and we must not select it as an address
23707 register by this routine since our caller will try to
23708 increment the returned register via an "la" instruction. */
23711 find_addr_reg (rtx addr)
23713 while (GET_CODE (addr) == PLUS)
23715 if (GET_CODE (XEXP (addr, 0)) == REG
23716 && REGNO (XEXP (addr, 0)) != 0)
23717 addr = XEXP (addr, 0);
23718 else if (GET_CODE (XEXP (addr, 1)) == REG
23719 && REGNO (XEXP (addr, 1)) != 0)
23720 addr = XEXP (addr, 1);
23721 else if (CONSTANT_P (XEXP (addr, 0)))
23722 addr = XEXP (addr, 1);
23723 else if (CONSTANT_P (XEXP (addr, 1)))
23724 addr = XEXP (addr, 0);
23725 else
23726 gcc_unreachable ();
23728 gcc_assert (GET_CODE (addr) == REG && REGNO (addr) != 0);
23729 return addr;
23732 void
23733 rs6000_fatal_bad_address (rtx op)
23735 fatal_insn ("bad address", op);
23738 #if TARGET_MACHO
23740 static tree branch_island_list = 0;
23742 /* Remember to generate a branch island for far calls to the given
23743 function. */
23745 static void
23746 add_compiler_branch_island (tree label_name, tree function_name,
23747 int line_number)
23749 tree branch_island = build_tree_list (function_name, label_name);
23750 TREE_TYPE (branch_island) = build_int_cst (NULL_TREE, line_number);
23751 TREE_CHAIN (branch_island) = branch_island_list;
23752 branch_island_list = branch_island;
23755 #define BRANCH_ISLAND_LABEL_NAME(BRANCH_ISLAND) TREE_VALUE (BRANCH_ISLAND)
23756 #define BRANCH_ISLAND_FUNCTION_NAME(BRANCH_ISLAND) TREE_PURPOSE (BRANCH_ISLAND)
23757 #define BRANCH_ISLAND_LINE_NUMBER(BRANCH_ISLAND) \
23758 TREE_INT_CST_LOW (TREE_TYPE (BRANCH_ISLAND))
23760 /* Generate far-jump branch islands for everything on the
23761 branch_island_list. Invoked immediately after the last instruction
23762 of the epilogue has been emitted; the branch-islands must be
23763 appended to, and contiguous with, the function body. Mach-O stubs
23764 are generated in machopic_output_stub(). */
23766 static void
23767 macho_branch_islands (void)
23769 char tmp_buf[512];
23770 tree branch_island;
23772 for (branch_island = branch_island_list;
23773 branch_island;
23774 branch_island = TREE_CHAIN (branch_island))
23776 const char *label =
23777 IDENTIFIER_POINTER (BRANCH_ISLAND_LABEL_NAME (branch_island));
23778 const char *name =
23779 IDENTIFIER_POINTER (BRANCH_ISLAND_FUNCTION_NAME (branch_island));
23780 char name_buf[512];
23781 /* Cheap copy of the details from the Darwin ASM_OUTPUT_LABELREF(). */
23782 if (name[0] == '*' || name[0] == '&')
23783 strcpy (name_buf, name+1);
23784 else
23786 name_buf[0] = '_';
23787 strcpy (name_buf+1, name);
23789 strcpy (tmp_buf, "\n");
23790 strcat (tmp_buf, label);
23791 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
23792 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
23793 dbxout_stabd (N_SLINE, BRANCH_ISLAND_LINE_NUMBER (branch_island));
23794 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
23795 if (flag_pic)
23797 strcat (tmp_buf, ":\n\tmflr r0\n\tbcl 20,31,");
23798 strcat (tmp_buf, label);
23799 strcat (tmp_buf, "_pic\n");
23800 strcat (tmp_buf, label);
23801 strcat (tmp_buf, "_pic:\n\tmflr r11\n");
23803 strcat (tmp_buf, "\taddis r11,r11,ha16(");
23804 strcat (tmp_buf, name_buf);
23805 strcat (tmp_buf, " - ");
23806 strcat (tmp_buf, label);
23807 strcat (tmp_buf, "_pic)\n");
23809 strcat (tmp_buf, "\tmtlr r0\n");
23811 strcat (tmp_buf, "\taddi r12,r11,lo16(");
23812 strcat (tmp_buf, name_buf);
23813 strcat (tmp_buf, " - ");
23814 strcat (tmp_buf, label);
23815 strcat (tmp_buf, "_pic)\n");
23817 strcat (tmp_buf, "\tmtctr r12\n\tbctr\n");
23819 else
23821 strcat (tmp_buf, ":\nlis r12,hi16(");
23822 strcat (tmp_buf, name_buf);
23823 strcat (tmp_buf, ")\n\tori r12,r12,lo16(");
23824 strcat (tmp_buf, name_buf);
23825 strcat (tmp_buf, ")\n\tmtctr r12\n\tbctr");
23827 output_asm_insn (tmp_buf, 0);
23828 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
23829 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
23830 dbxout_stabd (N_SLINE, BRANCH_ISLAND_LINE_NUMBER (branch_island));
23831 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
23834 branch_island_list = 0;
23837 /* NO_PREVIOUS_DEF checks in the link list whether the function name is
23838 already there or not. */
23840 static int
23841 no_previous_def (tree function_name)
23843 tree branch_island;
23844 for (branch_island = branch_island_list;
23845 branch_island;
23846 branch_island = TREE_CHAIN (branch_island))
23847 if (function_name == BRANCH_ISLAND_FUNCTION_NAME (branch_island))
23848 return 0;
23849 return 1;
23852 /* GET_PREV_LABEL gets the label name from the previous definition of
23853 the function. */
23855 static tree
23856 get_prev_label (tree function_name)
23858 tree branch_island;
23859 for (branch_island = branch_island_list;
23860 branch_island;
23861 branch_island = TREE_CHAIN (branch_island))
23862 if (function_name == BRANCH_ISLAND_FUNCTION_NAME (branch_island))
23863 return BRANCH_ISLAND_LABEL_NAME (branch_island);
23864 return 0;
23867 #ifndef DARWIN_LINKER_GENERATES_ISLANDS
23868 #define DARWIN_LINKER_GENERATES_ISLANDS 0
23869 #endif
23871 /* KEXTs still need branch islands. */
23872 #define DARWIN_GENERATE_ISLANDS (!DARWIN_LINKER_GENERATES_ISLANDS \
23873 || flag_mkernel || flag_apple_kext)
23875 /* INSN is either a function call or a millicode call. It may have an
23876 unconditional jump in its delay slot.
23878 CALL_DEST is the routine we are calling. */
23880 char *
23881 output_call (rtx insn, rtx *operands, int dest_operand_number,
23882 int cookie_operand_number)
23884 static char buf[256];
23885 if (DARWIN_GENERATE_ISLANDS
23886 && GET_CODE (operands[dest_operand_number]) == SYMBOL_REF
23887 && (INTVAL (operands[cookie_operand_number]) & CALL_LONG))
23889 tree labelname;
23890 tree funname = get_identifier (XSTR (operands[dest_operand_number], 0));
23892 if (no_previous_def (funname))
23894 rtx label_rtx = gen_label_rtx ();
23895 char *label_buf, temp_buf[256];
23896 ASM_GENERATE_INTERNAL_LABEL (temp_buf, "L",
23897 CODE_LABEL_NUMBER (label_rtx));
23898 label_buf = temp_buf[0] == '*' ? temp_buf + 1 : temp_buf;
23899 labelname = get_identifier (label_buf);
23900 add_compiler_branch_island (labelname, funname, insn_line (insn));
23902 else
23903 labelname = get_prev_label (funname);
23905 /* "jbsr foo, L42" is Mach-O for "Link as 'bl foo' if a 'bl'
23906 instruction will reach 'foo', otherwise link as 'bl L42'".
23907 "L42" should be a 'branch island', that will do a far jump to
23908 'foo'. Branch islands are generated in
23909 macho_branch_islands(). */
23910 sprintf (buf, "jbsr %%z%d,%.246s",
23911 dest_operand_number, IDENTIFIER_POINTER (labelname));
23913 else
23914 sprintf (buf, "bl %%z%d", dest_operand_number);
23915 return buf;
23918 /* Generate PIC and indirect symbol stubs. */
23920 void
23921 machopic_output_stub (FILE *file, const char *symb, const char *stub)
23923 unsigned int length;
23924 char *symbol_name, *lazy_ptr_name;
23925 char *local_label_0;
23926 static int label = 0;
23928 /* Lose our funky encoding stuff so it doesn't contaminate the stub. */
23929 symb = (*targetm.strip_name_encoding) (symb);
23932 length = strlen (symb);
23933 symbol_name = XALLOCAVEC (char, length + 32);
23934 GEN_SYMBOL_NAME_FOR_SYMBOL (symbol_name, symb, length);
23936 lazy_ptr_name = XALLOCAVEC (char, length + 32);
23937 GEN_LAZY_PTR_NAME_FOR_SYMBOL (lazy_ptr_name, symb, length);
23939 if (flag_pic == 2)
23940 switch_to_section (darwin_sections[machopic_picsymbol_stub1_section]);
23941 else
23942 switch_to_section (darwin_sections[machopic_symbol_stub1_section]);
23944 if (flag_pic == 2)
23946 fprintf (file, "\t.align 5\n");
23948 fprintf (file, "%s:\n", stub);
23949 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
23951 label++;
23952 local_label_0 = XALLOCAVEC (char, sizeof ("\"L00000000000$spb\""));
23953 sprintf (local_label_0, "\"L%011d$spb\"", label);
23955 fprintf (file, "\tmflr r0\n");
23956 fprintf (file, "\tbcl 20,31,%s\n", local_label_0);
23957 fprintf (file, "%s:\n\tmflr r11\n", local_label_0);
23958 fprintf (file, "\taddis r11,r11,ha16(%s-%s)\n",
23959 lazy_ptr_name, local_label_0);
23960 fprintf (file, "\tmtlr r0\n");
23961 fprintf (file, "\t%s r12,lo16(%s-%s)(r11)\n",
23962 (TARGET_64BIT ? "ldu" : "lwzu"),
23963 lazy_ptr_name, local_label_0);
23964 fprintf (file, "\tmtctr r12\n");
23965 fprintf (file, "\tbctr\n");
23967 else
23969 fprintf (file, "\t.align 4\n");
23971 fprintf (file, "%s:\n", stub);
23972 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
23974 fprintf (file, "\tlis r11,ha16(%s)\n", lazy_ptr_name);
23975 fprintf (file, "\t%s r12,lo16(%s)(r11)\n",
23976 (TARGET_64BIT ? "ldu" : "lwzu"),
23977 lazy_ptr_name);
23978 fprintf (file, "\tmtctr r12\n");
23979 fprintf (file, "\tbctr\n");
23982 switch_to_section (darwin_sections[machopic_lazy_symbol_ptr_section]);
23983 fprintf (file, "%s:\n", lazy_ptr_name);
23984 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
23985 fprintf (file, "%sdyld_stub_binding_helper\n",
23986 (TARGET_64BIT ? DOUBLE_INT_ASM_OP : "\t.long\t"));
23989 /* Legitimize PIC addresses. If the address is already
23990 position-independent, we return ORIG. Newly generated
23991 position-independent addresses go into a reg. This is REG if non
23992 zero, otherwise we allocate register(s) as necessary. */
23994 #define SMALL_INT(X) ((UINTVAL (X) + 0x8000) < 0x10000)
23997 rs6000_machopic_legitimize_pic_address (rtx orig, enum machine_mode mode,
23998 rtx reg)
24000 rtx base, offset;
24002 if (reg == NULL && ! reload_in_progress && ! reload_completed)
24003 reg = gen_reg_rtx (Pmode);
24005 if (GET_CODE (orig) == CONST)
24007 rtx reg_temp;
24009 if (GET_CODE (XEXP (orig, 0)) == PLUS
24010 && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx)
24011 return orig;
24013 gcc_assert (GET_CODE (XEXP (orig, 0)) == PLUS);
24015 /* Use a different reg for the intermediate value, as
24016 it will be marked UNCHANGING. */
24017 reg_temp = !can_create_pseudo_p () ? reg : gen_reg_rtx (Pmode);
24018 base = rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 0),
24019 Pmode, reg_temp);
24020 offset =
24021 rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 1),
24022 Pmode, reg);
24024 if (GET_CODE (offset) == CONST_INT)
24026 if (SMALL_INT (offset))
24027 return plus_constant (base, INTVAL (offset));
24028 else if (! reload_in_progress && ! reload_completed)
24029 offset = force_reg (Pmode, offset);
24030 else
24032 rtx mem = force_const_mem (Pmode, orig);
24033 return machopic_legitimize_pic_address (mem, Pmode, reg);
24036 return gen_rtx_PLUS (Pmode, base, offset);
24039 /* Fall back on generic machopic code. */
24040 return machopic_legitimize_pic_address (orig, mode, reg);
24043 /* Output a .machine directive for the Darwin assembler, and call
24044 the generic start_file routine. */
24046 static void
24047 rs6000_darwin_file_start (void)
24049 static const struct
24051 const char *arg;
24052 const char *name;
24053 int if_set;
24054 } mapping[] = {
24055 { "ppc64", "ppc64", MASK_64BIT },
24056 { "970", "ppc970", MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64 },
24057 { "power4", "ppc970", 0 },
24058 { "G5", "ppc970", 0 },
24059 { "7450", "ppc7450", 0 },
24060 { "7400", "ppc7400", MASK_ALTIVEC },
24061 { "G4", "ppc7400", 0 },
24062 { "750", "ppc750", 0 },
24063 { "740", "ppc750", 0 },
24064 { "G3", "ppc750", 0 },
24065 { "604e", "ppc604e", 0 },
24066 { "604", "ppc604", 0 },
24067 { "603e", "ppc603", 0 },
24068 { "603", "ppc603", 0 },
24069 { "601", "ppc601", 0 },
24070 { NULL, "ppc", 0 } };
24071 const char *cpu_id = "";
24072 size_t i;
24074 rs6000_file_start ();
24075 darwin_file_start ();
24077 /* Determine the argument to -mcpu=. Default to G3 if not specified. */
24078 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
24079 if (rs6000_select[i].set_arch_p && rs6000_select[i].string
24080 && rs6000_select[i].string[0] != '\0')
24081 cpu_id = rs6000_select[i].string;
24083 /* Look through the mapping array. Pick the first name that either
24084 matches the argument, has a bit set in IF_SET that is also set
24085 in the target flags, or has a NULL name. */
24087 i = 0;
24088 while (mapping[i].arg != NULL
24089 && strcmp (mapping[i].arg, cpu_id) != 0
24090 && (mapping[i].if_set & target_flags) == 0)
24091 i++;
24093 fprintf (asm_out_file, "\t.machine %s\n", mapping[i].name);
24096 #endif /* TARGET_MACHO */
24098 #if TARGET_ELF
24099 static int
24100 rs6000_elf_reloc_rw_mask (void)
24102 if (flag_pic)
24103 return 3;
24104 else if (DEFAULT_ABI == ABI_AIX)
24105 return 2;
24106 else
24107 return 0;
24110 /* Record an element in the table of global constructors. SYMBOL is
24111 a SYMBOL_REF of the function to be called; PRIORITY is a number
24112 between 0 and MAX_INIT_PRIORITY.
24114 This differs from default_named_section_asm_out_constructor in
24115 that we have special handling for -mrelocatable. */
24117 static void
24118 rs6000_elf_asm_out_constructor (rtx symbol, int priority)
24120 const char *section = ".ctors";
24121 char buf[16];
24123 if (priority != DEFAULT_INIT_PRIORITY)
24125 sprintf (buf, ".ctors.%.5u",
24126 /* Invert the numbering so the linker puts us in the proper
24127 order; constructors are run from right to left, and the
24128 linker sorts in increasing order. */
24129 MAX_INIT_PRIORITY - priority);
24130 section = buf;
24133 switch_to_section (get_section (section, SECTION_WRITE, NULL));
24134 assemble_align (POINTER_SIZE);
24136 if (TARGET_RELOCATABLE)
24138 fputs ("\t.long (", asm_out_file);
24139 output_addr_const (asm_out_file, symbol);
24140 fputs (")@fixup\n", asm_out_file);
24142 else
24143 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
24146 static void
24147 rs6000_elf_asm_out_destructor (rtx symbol, int priority)
24149 const char *section = ".dtors";
24150 char buf[16];
24152 if (priority != DEFAULT_INIT_PRIORITY)
24154 sprintf (buf, ".dtors.%.5u",
24155 /* Invert the numbering so the linker puts us in the proper
24156 order; constructors are run from right to left, and the
24157 linker sorts in increasing order. */
24158 MAX_INIT_PRIORITY - priority);
24159 section = buf;
24162 switch_to_section (get_section (section, SECTION_WRITE, NULL));
24163 assemble_align (POINTER_SIZE);
24165 if (TARGET_RELOCATABLE)
24167 fputs ("\t.long (", asm_out_file);
24168 output_addr_const (asm_out_file, symbol);
24169 fputs (")@fixup\n", asm_out_file);
24171 else
24172 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
24175 void
24176 rs6000_elf_declare_function_name (FILE *file, const char *name, tree decl)
24178 if (TARGET_64BIT)
24180 fputs ("\t.section\t\".opd\",\"aw\"\n\t.align 3\n", file);
24181 ASM_OUTPUT_LABEL (file, name);
24182 fputs (DOUBLE_INT_ASM_OP, file);
24183 rs6000_output_function_entry (file, name);
24184 fputs (",.TOC.@tocbase,0\n\t.previous\n", file);
24185 if (DOT_SYMBOLS)
24187 fputs ("\t.size\t", file);
24188 assemble_name (file, name);
24189 fputs (",24\n\t.type\t.", file);
24190 assemble_name (file, name);
24191 fputs (",@function\n", file);
24192 if (TREE_PUBLIC (decl) && ! DECL_WEAK (decl))
24194 fputs ("\t.globl\t.", file);
24195 assemble_name (file, name);
24196 putc ('\n', file);
24199 else
24200 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
24201 ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
24202 rs6000_output_function_entry (file, name);
24203 fputs (":\n", file);
24204 return;
24207 if (TARGET_RELOCATABLE
24208 && !TARGET_SECURE_PLT
24209 && (get_pool_size () != 0 || crtl->profile)
24210 && uses_TOC ())
24212 char buf[256];
24214 (*targetm.asm_out.internal_label) (file, "LCL", rs6000_pic_labelno);
24216 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
24217 fprintf (file, "\t.long ");
24218 assemble_name (file, buf);
24219 putc ('-', file);
24220 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
24221 assemble_name (file, buf);
24222 putc ('\n', file);
24225 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
24226 ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
24228 if (DEFAULT_ABI == ABI_AIX)
24230 const char *desc_name, *orig_name;
24232 orig_name = (*targetm.strip_name_encoding) (name);
24233 desc_name = orig_name;
24234 while (*desc_name == '.')
24235 desc_name++;
24237 if (TREE_PUBLIC (decl))
24238 fprintf (file, "\t.globl %s\n", desc_name);
24240 fprintf (file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
24241 fprintf (file, "%s:\n", desc_name);
24242 fprintf (file, "\t.long %s\n", orig_name);
24243 fputs ("\t.long _GLOBAL_OFFSET_TABLE_\n", file);
24244 if (DEFAULT_ABI == ABI_AIX)
24245 fputs ("\t.long 0\n", file);
24246 fprintf (file, "\t.previous\n");
24248 ASM_OUTPUT_LABEL (file, name);
24251 static void
24252 rs6000_elf_end_indicate_exec_stack (void)
24254 if (TARGET_32BIT)
24255 file_end_indicate_exec_stack ();
24257 #endif
24259 #if TARGET_XCOFF
24260 static void
24261 rs6000_xcoff_asm_output_anchor (rtx symbol)
24263 char buffer[100];
24265 sprintf (buffer, "$ + " HOST_WIDE_INT_PRINT_DEC,
24266 SYMBOL_REF_BLOCK_OFFSET (symbol));
24267 ASM_OUTPUT_DEF (asm_out_file, XSTR (symbol, 0), buffer);
24270 static void
24271 rs6000_xcoff_asm_globalize_label (FILE *stream, const char *name)
24273 fputs (GLOBAL_ASM_OP, stream);
24274 RS6000_OUTPUT_BASENAME (stream, name);
24275 putc ('\n', stream);
24278 /* A get_unnamed_decl callback, used for read-only sections. PTR
24279 points to the section string variable. */
24281 static void
24282 rs6000_xcoff_output_readonly_section_asm_op (const void *directive)
24284 fprintf (asm_out_file, "\t.csect %s[RO],%s\n",
24285 *(const char *const *) directive,
24286 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR);
24289 /* Likewise for read-write sections. */
24291 static void
24292 rs6000_xcoff_output_readwrite_section_asm_op (const void *directive)
24294 fprintf (asm_out_file, "\t.csect %s[RW],%s\n",
24295 *(const char *const *) directive,
24296 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR);
24299 /* A get_unnamed_section callback, used for switching to toc_section. */
24301 static void
24302 rs6000_xcoff_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
24304 if (TARGET_MINIMAL_TOC)
24306 /* toc_section is always selected at least once from
24307 rs6000_xcoff_file_start, so this is guaranteed to
24308 always be defined once and only once in each file. */
24309 if (!toc_initialized)
24311 fputs ("\t.toc\nLCTOC..1:\n", asm_out_file);
24312 fputs ("\t.tc toc_table[TC],toc_table[RW]\n", asm_out_file);
24313 toc_initialized = 1;
24315 fprintf (asm_out_file, "\t.csect toc_table[RW]%s\n",
24316 (TARGET_32BIT ? "" : ",3"));
24318 else
24319 fputs ("\t.toc\n", asm_out_file);
24322 /* Implement TARGET_ASM_INIT_SECTIONS. */
24324 static void
24325 rs6000_xcoff_asm_init_sections (void)
24327 read_only_data_section
24328 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
24329 &xcoff_read_only_section_name);
24331 private_data_section
24332 = get_unnamed_section (SECTION_WRITE,
24333 rs6000_xcoff_output_readwrite_section_asm_op,
24334 &xcoff_private_data_section_name);
24336 read_only_private_data_section
24337 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
24338 &xcoff_private_data_section_name);
24340 toc_section
24341 = get_unnamed_section (0, rs6000_xcoff_output_toc_section_asm_op, NULL);
24343 readonly_data_section = read_only_data_section;
24344 exception_section = data_section;
24347 static int
24348 rs6000_xcoff_reloc_rw_mask (void)
24350 return 3;
24353 static void
24354 rs6000_xcoff_asm_named_section (const char *name, unsigned int flags,
24355 tree decl ATTRIBUTE_UNUSED)
24357 int smclass;
24358 static const char * const suffix[3] = { "PR", "RO", "RW" };
24360 if (flags & SECTION_CODE)
24361 smclass = 0;
24362 else if (flags & SECTION_WRITE)
24363 smclass = 2;
24364 else
24365 smclass = 1;
24367 fprintf (asm_out_file, "\t.csect %s%s[%s],%u\n",
24368 (flags & SECTION_CODE) ? "." : "",
24369 name, suffix[smclass], flags & SECTION_ENTSIZE);
24372 static section *
24373 rs6000_xcoff_select_section (tree decl, int reloc,
24374 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
24376 if (decl_readonly_section (decl, reloc))
24378 if (TREE_PUBLIC (decl))
24379 return read_only_data_section;
24380 else
24381 return read_only_private_data_section;
24383 else
24385 if (TREE_PUBLIC (decl))
24386 return data_section;
24387 else
24388 return private_data_section;
24392 static void
24393 rs6000_xcoff_unique_section (tree decl, int reloc ATTRIBUTE_UNUSED)
24395 const char *name;
24397 /* Use select_section for private and uninitialized data. */
24398 if (!TREE_PUBLIC (decl)
24399 || DECL_COMMON (decl)
24400 || DECL_INITIAL (decl) == NULL_TREE
24401 || DECL_INITIAL (decl) == error_mark_node
24402 || (flag_zero_initialized_in_bss
24403 && initializer_zerop (DECL_INITIAL (decl))))
24404 return;
24406 name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
24407 name = (*targetm.strip_name_encoding) (name);
24408 DECL_SECTION_NAME (decl) = build_string (strlen (name), name);
24411 /* Select section for constant in constant pool.
24413 On RS/6000, all constants are in the private read-only data area.
24414 However, if this is being placed in the TOC it must be output as a
24415 toc entry. */
24417 static section *
24418 rs6000_xcoff_select_rtx_section (enum machine_mode mode, rtx x,
24419 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
24421 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
24422 return toc_section;
24423 else
24424 return read_only_private_data_section;
24427 /* Remove any trailing [DS] or the like from the symbol name. */
24429 static const char *
24430 rs6000_xcoff_strip_name_encoding (const char *name)
24432 size_t len;
24433 if (*name == '*')
24434 name++;
24435 len = strlen (name);
24436 if (name[len - 1] == ']')
24437 return ggc_alloc_string (name, len - 4);
24438 else
24439 return name;
24442 /* Section attributes. AIX is always PIC. */
24444 static unsigned int
24445 rs6000_xcoff_section_type_flags (tree decl, const char *name, int reloc)
24447 unsigned int align;
24448 unsigned int flags = default_section_type_flags (decl, name, reloc);
24450 /* Align to at least UNIT size. */
24451 if (flags & SECTION_CODE)
24452 align = MIN_UNITS_PER_WORD;
24453 else
24454 /* Increase alignment of large objects if not already stricter. */
24455 align = MAX ((DECL_ALIGN (decl) / BITS_PER_UNIT),
24456 int_size_in_bytes (TREE_TYPE (decl)) > MIN_UNITS_PER_WORD
24457 ? UNITS_PER_FP_WORD : MIN_UNITS_PER_WORD);
24459 return flags | (exact_log2 (align) & SECTION_ENTSIZE);
24462 /* Output at beginning of assembler file.
24464 Initialize the section names for the RS/6000 at this point.
24466 Specify filename, including full path, to assembler.
24468 We want to go into the TOC section so at least one .toc will be emitted.
24469 Also, in order to output proper .bs/.es pairs, we need at least one static
24470 [RW] section emitted.
24472 Finally, declare mcount when profiling to make the assembler happy. */
24474 static void
24475 rs6000_xcoff_file_start (void)
24477 rs6000_gen_section_name (&xcoff_bss_section_name,
24478 main_input_filename, ".bss_");
24479 rs6000_gen_section_name (&xcoff_private_data_section_name,
24480 main_input_filename, ".rw_");
24481 rs6000_gen_section_name (&xcoff_read_only_section_name,
24482 main_input_filename, ".ro_");
24484 fputs ("\t.file\t", asm_out_file);
24485 output_quoted_string (asm_out_file, main_input_filename);
24486 fputc ('\n', asm_out_file);
24487 if (write_symbols != NO_DEBUG)
24488 switch_to_section (private_data_section);
24489 switch_to_section (text_section);
24490 if (profile_flag)
24491 fprintf (asm_out_file, "\t.extern %s\n", RS6000_MCOUNT);
24492 rs6000_file_start ();
24495 /* Output at end of assembler file.
24496 On the RS/6000, referencing data should automatically pull in text. */
24498 static void
24499 rs6000_xcoff_file_end (void)
24501 switch_to_section (text_section);
24502 fputs ("_section_.text:\n", asm_out_file);
24503 switch_to_section (data_section);
24504 fputs (TARGET_32BIT
24505 ? "\t.long _section_.text\n" : "\t.llong _section_.text\n",
24506 asm_out_file);
24508 #endif /* TARGET_XCOFF */
24510 /* Compute a (partial) cost for rtx X. Return true if the complete
24511 cost has been computed, and false if subexpressions should be
24512 scanned. In either case, *TOTAL contains the cost result. */
24514 static bool
24515 rs6000_rtx_costs (rtx x, int code, int outer_code, int *total,
24516 bool speed)
24518 enum machine_mode mode = GET_MODE (x);
24520 switch (code)
24522 /* On the RS/6000, if it is valid in the insn, it is free. */
24523 case CONST_INT:
24524 if (((outer_code == SET
24525 || outer_code == PLUS
24526 || outer_code == MINUS)
24527 && (satisfies_constraint_I (x)
24528 || satisfies_constraint_L (x)))
24529 || (outer_code == AND
24530 && (satisfies_constraint_K (x)
24531 || (mode == SImode
24532 ? satisfies_constraint_L (x)
24533 : satisfies_constraint_J (x))
24534 || mask_operand (x, mode)
24535 || (mode == DImode
24536 && mask64_operand (x, DImode))))
24537 || ((outer_code == IOR || outer_code == XOR)
24538 && (satisfies_constraint_K (x)
24539 || (mode == SImode
24540 ? satisfies_constraint_L (x)
24541 : satisfies_constraint_J (x))))
24542 || outer_code == ASHIFT
24543 || outer_code == ASHIFTRT
24544 || outer_code == LSHIFTRT
24545 || outer_code == ROTATE
24546 || outer_code == ROTATERT
24547 || outer_code == ZERO_EXTRACT
24548 || (outer_code == MULT
24549 && satisfies_constraint_I (x))
24550 || ((outer_code == DIV || outer_code == UDIV
24551 || outer_code == MOD || outer_code == UMOD)
24552 && exact_log2 (INTVAL (x)) >= 0)
24553 || (outer_code == COMPARE
24554 && (satisfies_constraint_I (x)
24555 || satisfies_constraint_K (x)))
24556 || (outer_code == EQ
24557 && (satisfies_constraint_I (x)
24558 || satisfies_constraint_K (x)
24559 || (mode == SImode
24560 ? satisfies_constraint_L (x)
24561 : satisfies_constraint_J (x))))
24562 || (outer_code == GTU
24563 && satisfies_constraint_I (x))
24564 || (outer_code == LTU
24565 && satisfies_constraint_P (x)))
24567 *total = 0;
24568 return true;
24570 else if ((outer_code == PLUS
24571 && reg_or_add_cint_operand (x, VOIDmode))
24572 || (outer_code == MINUS
24573 && reg_or_sub_cint_operand (x, VOIDmode))
24574 || ((outer_code == SET
24575 || outer_code == IOR
24576 || outer_code == XOR)
24577 && (INTVAL (x)
24578 & ~ (unsigned HOST_WIDE_INT) 0xffffffff) == 0))
24580 *total = COSTS_N_INSNS (1);
24581 return true;
24583 /* FALLTHRU */
24585 case CONST_DOUBLE:
24586 if (mode == DImode && code == CONST_DOUBLE)
24588 if ((outer_code == IOR || outer_code == XOR)
24589 && CONST_DOUBLE_HIGH (x) == 0
24590 && (CONST_DOUBLE_LOW (x)
24591 & ~ (unsigned HOST_WIDE_INT) 0xffff) == 0)
24593 *total = 0;
24594 return true;
24596 else if ((outer_code == AND && and64_2_operand (x, DImode))
24597 || ((outer_code == SET
24598 || outer_code == IOR
24599 || outer_code == XOR)
24600 && CONST_DOUBLE_HIGH (x) == 0))
24602 *total = COSTS_N_INSNS (1);
24603 return true;
24606 /* FALLTHRU */
24608 case CONST:
24609 case HIGH:
24610 case SYMBOL_REF:
24611 case MEM:
24612 /* When optimizing for size, MEM should be slightly more expensive
24613 than generating address, e.g., (plus (reg) (const)).
24614 L1 cache latency is about two instructions. */
24615 *total = !speed ? COSTS_N_INSNS (1) + 1 : COSTS_N_INSNS (2);
24616 return true;
24618 case LABEL_REF:
24619 *total = 0;
24620 return true;
24622 case PLUS:
24623 if (mode == DFmode)
24625 if (GET_CODE (XEXP (x, 0)) == MULT)
24627 /* FNMA accounted in outer NEG. */
24628 if (outer_code == NEG)
24629 *total = rs6000_cost->dmul - rs6000_cost->fp;
24630 else
24631 *total = rs6000_cost->dmul;
24633 else
24634 *total = rs6000_cost->fp;
24636 else if (mode == SFmode)
24638 /* FNMA accounted in outer NEG. */
24639 if (outer_code == NEG && GET_CODE (XEXP (x, 0)) == MULT)
24640 *total = 0;
24641 else
24642 *total = rs6000_cost->fp;
24644 else
24645 *total = COSTS_N_INSNS (1);
24646 return false;
24648 case MINUS:
24649 if (mode == DFmode)
24651 if (GET_CODE (XEXP (x, 0)) == MULT
24652 || GET_CODE (XEXP (x, 1)) == MULT)
24654 /* FNMA accounted in outer NEG. */
24655 if (outer_code == NEG)
24656 *total = rs6000_cost->dmul - rs6000_cost->fp;
24657 else
24658 *total = rs6000_cost->dmul;
24660 else
24661 *total = rs6000_cost->fp;
24663 else if (mode == SFmode)
24665 /* FNMA accounted in outer NEG. */
24666 if (outer_code == NEG && GET_CODE (XEXP (x, 0)) == MULT)
24667 *total = 0;
24668 else
24669 *total = rs6000_cost->fp;
24671 else
24672 *total = COSTS_N_INSNS (1);
24673 return false;
24675 case MULT:
24676 if (GET_CODE (XEXP (x, 1)) == CONST_INT
24677 && satisfies_constraint_I (XEXP (x, 1)))
24679 if (INTVAL (XEXP (x, 1)) >= -256
24680 && INTVAL (XEXP (x, 1)) <= 255)
24681 *total = rs6000_cost->mulsi_const9;
24682 else
24683 *total = rs6000_cost->mulsi_const;
24685 /* FMA accounted in outer PLUS/MINUS. */
24686 else if ((mode == DFmode || mode == SFmode)
24687 && (outer_code == PLUS || outer_code == MINUS))
24688 *total = 0;
24689 else if (mode == DFmode)
24690 *total = rs6000_cost->dmul;
24691 else if (mode == SFmode)
24692 *total = rs6000_cost->fp;
24693 else if (mode == DImode)
24694 *total = rs6000_cost->muldi;
24695 else
24696 *total = rs6000_cost->mulsi;
24697 return false;
24699 case DIV:
24700 case MOD:
24701 if (FLOAT_MODE_P (mode))
24703 *total = mode == DFmode ? rs6000_cost->ddiv
24704 : rs6000_cost->sdiv;
24705 return false;
24707 /* FALLTHRU */
24709 case UDIV:
24710 case UMOD:
24711 if (GET_CODE (XEXP (x, 1)) == CONST_INT
24712 && exact_log2 (INTVAL (XEXP (x, 1))) >= 0)
24714 if (code == DIV || code == MOD)
24715 /* Shift, addze */
24716 *total = COSTS_N_INSNS (2);
24717 else
24718 /* Shift */
24719 *total = COSTS_N_INSNS (1);
24721 else
24723 if (GET_MODE (XEXP (x, 1)) == DImode)
24724 *total = rs6000_cost->divdi;
24725 else
24726 *total = rs6000_cost->divsi;
24728 /* Add in shift and subtract for MOD. */
24729 if (code == MOD || code == UMOD)
24730 *total += COSTS_N_INSNS (2);
24731 return false;
24733 case CTZ:
24734 case FFS:
24735 *total = COSTS_N_INSNS (4);
24736 return false;
24738 case POPCOUNT:
24739 *total = COSTS_N_INSNS (6);
24740 return false;
24742 case NOT:
24743 if (outer_code == AND || outer_code == IOR || outer_code == XOR)
24745 *total = 0;
24746 return false;
24748 /* FALLTHRU */
24750 case AND:
24751 case CLZ:
24752 case IOR:
24753 case XOR:
24754 case ZERO_EXTRACT:
24755 *total = COSTS_N_INSNS (1);
24756 return false;
24758 case ASHIFT:
24759 case ASHIFTRT:
24760 case LSHIFTRT:
24761 case ROTATE:
24762 case ROTATERT:
24763 /* Handle mul_highpart. */
24764 if (outer_code == TRUNCATE
24765 && GET_CODE (XEXP (x, 0)) == MULT)
24767 if (mode == DImode)
24768 *total = rs6000_cost->muldi;
24769 else
24770 *total = rs6000_cost->mulsi;
24771 return true;
24773 else if (outer_code == AND)
24774 *total = 0;
24775 else
24776 *total = COSTS_N_INSNS (1);
24777 return false;
24779 case SIGN_EXTEND:
24780 case ZERO_EXTEND:
24781 if (GET_CODE (XEXP (x, 0)) == MEM)
24782 *total = 0;
24783 else
24784 *total = COSTS_N_INSNS (1);
24785 return false;
24787 case COMPARE:
24788 case NEG:
24789 case ABS:
24790 if (!FLOAT_MODE_P (mode))
24792 *total = COSTS_N_INSNS (1);
24793 return false;
24795 /* FALLTHRU */
24797 case FLOAT:
24798 case UNSIGNED_FLOAT:
24799 case FIX:
24800 case UNSIGNED_FIX:
24801 case FLOAT_TRUNCATE:
24802 *total = rs6000_cost->fp;
24803 return false;
24805 case FLOAT_EXTEND:
24806 if (mode == DFmode)
24807 *total = 0;
24808 else
24809 *total = rs6000_cost->fp;
24810 return false;
24812 case UNSPEC:
24813 switch (XINT (x, 1))
24815 case UNSPEC_FRSP:
24816 *total = rs6000_cost->fp;
24817 return true;
24819 default:
24820 break;
24822 break;
24824 case CALL:
24825 case IF_THEN_ELSE:
24826 if (!speed)
24828 *total = COSTS_N_INSNS (1);
24829 return true;
24831 else if (FLOAT_MODE_P (mode)
24832 && TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS)
24834 *total = rs6000_cost->fp;
24835 return false;
24837 break;
24839 case EQ:
24840 case GTU:
24841 case LTU:
24842 /* Carry bit requires mode == Pmode.
24843 NEG or PLUS already counted so only add one. */
24844 if (mode == Pmode
24845 && (outer_code == NEG || outer_code == PLUS))
24847 *total = COSTS_N_INSNS (1);
24848 return true;
24850 if (outer_code == SET)
24852 if (XEXP (x, 1) == const0_rtx)
24854 if (TARGET_ISEL && !TARGET_MFCRF)
24855 *total = COSTS_N_INSNS (8);
24856 else
24857 *total = COSTS_N_INSNS (2);
24858 return true;
24860 else if (mode == Pmode)
24862 *total = COSTS_N_INSNS (3);
24863 return false;
24866 /* FALLTHRU */
24868 case GT:
24869 case LT:
24870 case UNORDERED:
24871 if (outer_code == SET && (XEXP (x, 1) == const0_rtx))
24873 if (TARGET_ISEL && !TARGET_MFCRF)
24874 *total = COSTS_N_INSNS (8);
24875 else
24876 *total = COSTS_N_INSNS (2);
24877 return true;
24879 /* CC COMPARE. */
24880 if (outer_code == COMPARE)
24882 *total = 0;
24883 return true;
24885 break;
24887 default:
24888 break;
24891 return false;
24894 /* Debug form of r6000_rtx_costs that is selected if -mdebug=cost. */
24896 static bool
24897 rs6000_debug_rtx_costs (rtx x, int code, int outer_code, int *total,
24898 bool speed)
24900 bool ret = rs6000_rtx_costs (x, code, outer_code, total, speed);
24902 fprintf (stderr,
24903 "\nrs6000_rtx_costs, return = %s, code = %s, outer_code = %s, "
24904 "total = %d, speed = %s, x:\n",
24905 ret ? "complete" : "scan inner",
24906 GET_RTX_NAME (code),
24907 GET_RTX_NAME (outer_code),
24908 *total,
24909 speed ? "true" : "false");
24911 debug_rtx (x);
24913 return ret;
24916 /* Debug form of ADDRESS_COST that is selected if -mdebug=cost. */
24918 static int
24919 rs6000_debug_address_cost (rtx x, bool speed)
24921 int ret = TARGET_ADDRESS_COST (x, speed);
24923 fprintf (stderr, "\nrs6000_address_cost, return = %d, speed = %s, x:\n",
24924 ret, speed ? "true" : "false");
24925 debug_rtx (x);
24927 return ret;
24931 /* A C expression returning the cost of moving data from a register of class
24932 CLASS1 to one of CLASS2. */
24935 rs6000_register_move_cost (enum machine_mode mode,
24936 enum reg_class from, enum reg_class to)
24938 int ret;
24940 /* Moves from/to GENERAL_REGS. */
24941 if (reg_classes_intersect_p (to, GENERAL_REGS)
24942 || reg_classes_intersect_p (from, GENERAL_REGS))
24944 if (! reg_classes_intersect_p (to, GENERAL_REGS))
24945 from = to;
24947 if (from == FLOAT_REGS || from == ALTIVEC_REGS || from == VSX_REGS)
24948 ret = (rs6000_memory_move_cost (mode, from, 0)
24949 + rs6000_memory_move_cost (mode, GENERAL_REGS, 0));
24951 /* It's more expensive to move CR_REGS than CR0_REGS because of the
24952 shift. */
24953 else if (from == CR_REGS)
24954 ret = 4;
24956 /* Power6 has slower LR/CTR moves so make them more expensive than
24957 memory in order to bias spills to memory .*/
24958 else if (rs6000_cpu == PROCESSOR_POWER6
24959 && reg_classes_intersect_p (from, LINK_OR_CTR_REGS))
24960 ret = 6 * hard_regno_nregs[0][mode];
24962 else
24963 /* A move will cost one instruction per GPR moved. */
24964 ret = 2 * hard_regno_nregs[0][mode];
24967 /* If we have VSX, we can easily move between FPR or Altivec registers. */
24968 else if (VECTOR_UNIT_VSX_P (mode)
24969 && reg_classes_intersect_p (to, VSX_REGS)
24970 && reg_classes_intersect_p (from, VSX_REGS))
24971 ret = 2 * hard_regno_nregs[32][mode];
24973 /* Moving between two similar registers is just one instruction. */
24974 else if (reg_classes_intersect_p (to, from))
24975 ret = (mode == TFmode || mode == TDmode) ? 4 : 2;
24977 /* Everything else has to go through GENERAL_REGS. */
24978 else
24979 ret = (rs6000_register_move_cost (mode, GENERAL_REGS, to)
24980 + rs6000_register_move_cost (mode, from, GENERAL_REGS));
24982 if (TARGET_DEBUG_COST)
24983 fprintf (stderr,
24984 "rs6000_register_move_cost:, ret=%d, mode=%s, from=%s, to=%s\n",
24985 ret, GET_MODE_NAME (mode), reg_class_names[from],
24986 reg_class_names[to]);
24988 return ret;
24991 /* A C expressions returning the cost of moving data of MODE from a register to
24992 or from memory. */
24995 rs6000_memory_move_cost (enum machine_mode mode, enum reg_class rclass,
24996 int in ATTRIBUTE_UNUSED)
24998 int ret;
25000 if (reg_classes_intersect_p (rclass, GENERAL_REGS))
25001 ret = 4 * hard_regno_nregs[0][mode];
25002 else if (reg_classes_intersect_p (rclass, FLOAT_REGS))
25003 ret = 4 * hard_regno_nregs[32][mode];
25004 else if (reg_classes_intersect_p (rclass, ALTIVEC_REGS))
25005 ret = 4 * hard_regno_nregs[FIRST_ALTIVEC_REGNO][mode];
25006 else
25007 ret = 4 + rs6000_register_move_cost (mode, rclass, GENERAL_REGS);
25009 if (TARGET_DEBUG_COST)
25010 fprintf (stderr,
25011 "rs6000_memory_move_cost: ret=%d, mode=%s, rclass=%s, in=%d\n",
25012 ret, GET_MODE_NAME (mode), reg_class_names[rclass], in);
25014 return ret;
25017 /* Returns a code for a target-specific builtin that implements
25018 reciprocal of the function, or NULL_TREE if not available. */
25020 static tree
25021 rs6000_builtin_reciprocal (unsigned int fn, bool md_fn,
25022 bool sqrt ATTRIBUTE_UNUSED)
25024 if (! (TARGET_RECIP && TARGET_PPC_GFXOPT && !optimize_size
25025 && flag_finite_math_only && !flag_trapping_math
25026 && flag_unsafe_math_optimizations))
25027 return NULL_TREE;
25029 if (md_fn)
25030 return NULL_TREE;
25031 else
25032 switch (fn)
25034 case BUILT_IN_SQRTF:
25035 return rs6000_builtin_decls[RS6000_BUILTIN_RSQRTF];
25037 default:
25038 return NULL_TREE;
25042 /* Newton-Raphson approximation of single-precision floating point divide n/d.
25043 Assumes no trapping math and finite arguments. */
25045 void
25046 rs6000_emit_swdivsf (rtx dst, rtx n, rtx d)
25048 rtx x0, e0, e1, y1, u0, v0, one;
25050 x0 = gen_reg_rtx (SFmode);
25051 e0 = gen_reg_rtx (SFmode);
25052 e1 = gen_reg_rtx (SFmode);
25053 y1 = gen_reg_rtx (SFmode);
25054 u0 = gen_reg_rtx (SFmode);
25055 v0 = gen_reg_rtx (SFmode);
25056 one = force_reg (SFmode, CONST_DOUBLE_FROM_REAL_VALUE (dconst1, SFmode));
25058 /* x0 = 1./d estimate */
25059 emit_insn (gen_rtx_SET (VOIDmode, x0,
25060 gen_rtx_UNSPEC (SFmode, gen_rtvec (1, d),
25061 UNSPEC_FRES)));
25062 /* e0 = 1. - d * x0 */
25063 emit_insn (gen_rtx_SET (VOIDmode, e0,
25064 gen_rtx_MINUS (SFmode, one,
25065 gen_rtx_MULT (SFmode, d, x0))));
25066 /* e1 = e0 + e0 * e0 */
25067 emit_insn (gen_rtx_SET (VOIDmode, e1,
25068 gen_rtx_PLUS (SFmode,
25069 gen_rtx_MULT (SFmode, e0, e0), e0)));
25070 /* y1 = x0 + e1 * x0 */
25071 emit_insn (gen_rtx_SET (VOIDmode, y1,
25072 gen_rtx_PLUS (SFmode,
25073 gen_rtx_MULT (SFmode, e1, x0), x0)));
25074 /* u0 = n * y1 */
25075 emit_insn (gen_rtx_SET (VOIDmode, u0,
25076 gen_rtx_MULT (SFmode, n, y1)));
25077 /* v0 = n - d * u0 */
25078 emit_insn (gen_rtx_SET (VOIDmode, v0,
25079 gen_rtx_MINUS (SFmode, n,
25080 gen_rtx_MULT (SFmode, d, u0))));
25081 /* dst = u0 + v0 * y1 */
25082 emit_insn (gen_rtx_SET (VOIDmode, dst,
25083 gen_rtx_PLUS (SFmode,
25084 gen_rtx_MULT (SFmode, v0, y1), u0)));
25087 /* Newton-Raphson approximation of double-precision floating point divide n/d.
25088 Assumes no trapping math and finite arguments. */
25090 void
25091 rs6000_emit_swdivdf (rtx dst, rtx n, rtx d)
25093 rtx x0, e0, e1, e2, y1, y2, y3, u0, v0, one;
25095 x0 = gen_reg_rtx (DFmode);
25096 e0 = gen_reg_rtx (DFmode);
25097 e1 = gen_reg_rtx (DFmode);
25098 e2 = gen_reg_rtx (DFmode);
25099 y1 = gen_reg_rtx (DFmode);
25100 y2 = gen_reg_rtx (DFmode);
25101 y3 = gen_reg_rtx (DFmode);
25102 u0 = gen_reg_rtx (DFmode);
25103 v0 = gen_reg_rtx (DFmode);
25104 one = force_reg (DFmode, CONST_DOUBLE_FROM_REAL_VALUE (dconst1, DFmode));
25106 /* x0 = 1./d estimate */
25107 emit_insn (gen_rtx_SET (VOIDmode, x0,
25108 gen_rtx_UNSPEC (DFmode, gen_rtvec (1, d),
25109 UNSPEC_FRES)));
25110 /* e0 = 1. - d * x0 */
25111 emit_insn (gen_rtx_SET (VOIDmode, e0,
25112 gen_rtx_MINUS (DFmode, one,
25113 gen_rtx_MULT (SFmode, d, x0))));
25114 /* y1 = x0 + e0 * x0 */
25115 emit_insn (gen_rtx_SET (VOIDmode, y1,
25116 gen_rtx_PLUS (DFmode,
25117 gen_rtx_MULT (DFmode, e0, x0), x0)));
25118 /* e1 = e0 * e0 */
25119 emit_insn (gen_rtx_SET (VOIDmode, e1,
25120 gen_rtx_MULT (DFmode, e0, e0)));
25121 /* y2 = y1 + e1 * y1 */
25122 emit_insn (gen_rtx_SET (VOIDmode, y2,
25123 gen_rtx_PLUS (DFmode,
25124 gen_rtx_MULT (DFmode, e1, y1), y1)));
25125 /* e2 = e1 * e1 */
25126 emit_insn (gen_rtx_SET (VOIDmode, e2,
25127 gen_rtx_MULT (DFmode, e1, e1)));
25128 /* y3 = y2 + e2 * y2 */
25129 emit_insn (gen_rtx_SET (VOIDmode, y3,
25130 gen_rtx_PLUS (DFmode,
25131 gen_rtx_MULT (DFmode, e2, y2), y2)));
25132 /* u0 = n * y3 */
25133 emit_insn (gen_rtx_SET (VOIDmode, u0,
25134 gen_rtx_MULT (DFmode, n, y3)));
25135 /* v0 = n - d * u0 */
25136 emit_insn (gen_rtx_SET (VOIDmode, v0,
25137 gen_rtx_MINUS (DFmode, n,
25138 gen_rtx_MULT (DFmode, d, u0))));
25139 /* dst = u0 + v0 * y3 */
25140 emit_insn (gen_rtx_SET (VOIDmode, dst,
25141 gen_rtx_PLUS (DFmode,
25142 gen_rtx_MULT (DFmode, v0, y3), u0)));
25146 /* Newton-Raphson approximation of single-precision floating point rsqrt.
25147 Assumes no trapping math and finite arguments. */
25149 void
25150 rs6000_emit_swrsqrtsf (rtx dst, rtx src)
25152 rtx x0, x1, x2, y1, u0, u1, u2, v0, v1, v2, t0,
25153 half, one, halfthree, c1, cond, label;
25155 x0 = gen_reg_rtx (SFmode);
25156 x1 = gen_reg_rtx (SFmode);
25157 x2 = gen_reg_rtx (SFmode);
25158 y1 = gen_reg_rtx (SFmode);
25159 u0 = gen_reg_rtx (SFmode);
25160 u1 = gen_reg_rtx (SFmode);
25161 u2 = gen_reg_rtx (SFmode);
25162 v0 = gen_reg_rtx (SFmode);
25163 v1 = gen_reg_rtx (SFmode);
25164 v2 = gen_reg_rtx (SFmode);
25165 t0 = gen_reg_rtx (SFmode);
25166 halfthree = gen_reg_rtx (SFmode);
25167 cond = gen_rtx_REG (CCFPmode, CR1_REGNO);
25168 label = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
25170 /* check 0.0, 1.0, NaN, Inf by testing src * src = src */
25171 emit_insn (gen_rtx_SET (VOIDmode, t0,
25172 gen_rtx_MULT (SFmode, src, src)));
25174 emit_insn (gen_rtx_SET (VOIDmode, cond,
25175 gen_rtx_COMPARE (CCFPmode, t0, src)));
25176 c1 = gen_rtx_EQ (VOIDmode, cond, const0_rtx);
25177 emit_unlikely_jump (c1, label);
25179 half = force_reg (SFmode, CONST_DOUBLE_FROM_REAL_VALUE (dconsthalf, SFmode));
25180 one = force_reg (SFmode, CONST_DOUBLE_FROM_REAL_VALUE (dconst1, SFmode));
25182 /* halfthree = 1.5 = 1.0 + 0.5 */
25183 emit_insn (gen_rtx_SET (VOIDmode, halfthree,
25184 gen_rtx_PLUS (SFmode, one, half)));
25186 /* x0 = rsqrt estimate */
25187 emit_insn (gen_rtx_SET (VOIDmode, x0,
25188 gen_rtx_UNSPEC (SFmode, gen_rtvec (1, src),
25189 UNSPEC_RSQRT)));
25191 /* y1 = 0.5 * src = 1.5 * src - src -> fewer constants */
25192 emit_insn (gen_rtx_SET (VOIDmode, y1,
25193 gen_rtx_MINUS (SFmode,
25194 gen_rtx_MULT (SFmode, src, halfthree),
25195 src)));
25197 /* x1 = x0 * (1.5 - y1 * (x0 * x0)) */
25198 emit_insn (gen_rtx_SET (VOIDmode, u0,
25199 gen_rtx_MULT (SFmode, x0, x0)));
25200 emit_insn (gen_rtx_SET (VOIDmode, v0,
25201 gen_rtx_MINUS (SFmode,
25202 halfthree,
25203 gen_rtx_MULT (SFmode, y1, u0))));
25204 emit_insn (gen_rtx_SET (VOIDmode, x1,
25205 gen_rtx_MULT (SFmode, x0, v0)));
25207 /* x2 = x1 * (1.5 - y1 * (x1 * x1)) */
25208 emit_insn (gen_rtx_SET (VOIDmode, u1,
25209 gen_rtx_MULT (SFmode, x1, x1)));
25210 emit_insn (gen_rtx_SET (VOIDmode, v1,
25211 gen_rtx_MINUS (SFmode,
25212 halfthree,
25213 gen_rtx_MULT (SFmode, y1, u1))));
25214 emit_insn (gen_rtx_SET (VOIDmode, x2,
25215 gen_rtx_MULT (SFmode, x1, v1)));
25217 /* dst = x2 * (1.5 - y1 * (x2 * x2)) */
25218 emit_insn (gen_rtx_SET (VOIDmode, u2,
25219 gen_rtx_MULT (SFmode, x2, x2)));
25220 emit_insn (gen_rtx_SET (VOIDmode, v2,
25221 gen_rtx_MINUS (SFmode,
25222 halfthree,
25223 gen_rtx_MULT (SFmode, y1, u2))));
25224 emit_insn (gen_rtx_SET (VOIDmode, dst,
25225 gen_rtx_MULT (SFmode, x2, v2)));
25227 emit_label (XEXP (label, 0));
25230 /* Emit popcount intrinsic on TARGET_POPCNTB (Power5) and TARGET_POPCNTD
25231 (Power7) targets. DST is the target, and SRC is the argument operand. */
25233 void
25234 rs6000_emit_popcount (rtx dst, rtx src)
25236 enum machine_mode mode = GET_MODE (dst);
25237 rtx tmp1, tmp2;
25239 /* Use the PPC ISA 2.06 popcnt{w,d} instruction if we can. */
25240 if (TARGET_POPCNTD)
25242 if (mode == SImode)
25243 emit_insn (gen_popcntwsi2 (dst, src));
25244 else
25245 emit_insn (gen_popcntddi2 (dst, src));
25246 return;
25249 tmp1 = gen_reg_rtx (mode);
25251 if (mode == SImode)
25253 emit_insn (gen_popcntbsi2 (tmp1, src));
25254 tmp2 = expand_mult (SImode, tmp1, GEN_INT (0x01010101),
25255 NULL_RTX, 0);
25256 tmp2 = force_reg (SImode, tmp2);
25257 emit_insn (gen_lshrsi3 (dst, tmp2, GEN_INT (24)));
25259 else
25261 emit_insn (gen_popcntbdi2 (tmp1, src));
25262 tmp2 = expand_mult (DImode, tmp1,
25263 GEN_INT ((HOST_WIDE_INT)
25264 0x01010101 << 32 | 0x01010101),
25265 NULL_RTX, 0);
25266 tmp2 = force_reg (DImode, tmp2);
25267 emit_insn (gen_lshrdi3 (dst, tmp2, GEN_INT (56)));
25272 /* Emit parity intrinsic on TARGET_POPCNTB targets. DST is the
25273 target, and SRC is the argument operand. */
25275 void
25276 rs6000_emit_parity (rtx dst, rtx src)
25278 enum machine_mode mode = GET_MODE (dst);
25279 rtx tmp;
25281 tmp = gen_reg_rtx (mode);
25282 if (mode == SImode)
25284 /* Is mult+shift >= shift+xor+shift+xor? */
25285 if (rs6000_cost->mulsi_const >= COSTS_N_INSNS (3))
25287 rtx tmp1, tmp2, tmp3, tmp4;
25289 tmp1 = gen_reg_rtx (SImode);
25290 emit_insn (gen_popcntbsi2 (tmp1, src));
25292 tmp2 = gen_reg_rtx (SImode);
25293 emit_insn (gen_lshrsi3 (tmp2, tmp1, GEN_INT (16)));
25294 tmp3 = gen_reg_rtx (SImode);
25295 emit_insn (gen_xorsi3 (tmp3, tmp1, tmp2));
25297 tmp4 = gen_reg_rtx (SImode);
25298 emit_insn (gen_lshrsi3 (tmp4, tmp3, GEN_INT (8)));
25299 emit_insn (gen_xorsi3 (tmp, tmp3, tmp4));
25301 else
25302 rs6000_emit_popcount (tmp, src);
25303 emit_insn (gen_andsi3 (dst, tmp, const1_rtx));
25305 else
25307 /* Is mult+shift >= shift+xor+shift+xor+shift+xor? */
25308 if (rs6000_cost->muldi >= COSTS_N_INSNS (5))
25310 rtx tmp1, tmp2, tmp3, tmp4, tmp5, tmp6;
25312 tmp1 = gen_reg_rtx (DImode);
25313 emit_insn (gen_popcntbdi2 (tmp1, src));
25315 tmp2 = gen_reg_rtx (DImode);
25316 emit_insn (gen_lshrdi3 (tmp2, tmp1, GEN_INT (32)));
25317 tmp3 = gen_reg_rtx (DImode);
25318 emit_insn (gen_xordi3 (tmp3, tmp1, tmp2));
25320 tmp4 = gen_reg_rtx (DImode);
25321 emit_insn (gen_lshrdi3 (tmp4, tmp3, GEN_INT (16)));
25322 tmp5 = gen_reg_rtx (DImode);
25323 emit_insn (gen_xordi3 (tmp5, tmp3, tmp4));
25325 tmp6 = gen_reg_rtx (DImode);
25326 emit_insn (gen_lshrdi3 (tmp6, tmp5, GEN_INT (8)));
25327 emit_insn (gen_xordi3 (tmp, tmp5, tmp6));
25329 else
25330 rs6000_emit_popcount (tmp, src);
25331 emit_insn (gen_anddi3 (dst, tmp, const1_rtx));
25335 /* Return an RTX representing where to find the function value of a
25336 function returning MODE. */
25337 static rtx
25338 rs6000_complex_function_value (enum machine_mode mode)
25340 unsigned int regno;
25341 rtx r1, r2;
25342 enum machine_mode inner = GET_MODE_INNER (mode);
25343 unsigned int inner_bytes = GET_MODE_SIZE (inner);
25345 if (FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
25346 regno = FP_ARG_RETURN;
25347 else
25349 regno = GP_ARG_RETURN;
25351 /* 32-bit is OK since it'll go in r3/r4. */
25352 if (TARGET_32BIT && inner_bytes >= 4)
25353 return gen_rtx_REG (mode, regno);
25356 if (inner_bytes >= 8)
25357 return gen_rtx_REG (mode, regno);
25359 r1 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno),
25360 const0_rtx);
25361 r2 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno + 1),
25362 GEN_INT (inner_bytes));
25363 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
25366 /* Target hook for TARGET_FUNCTION_VALUE.
25368 On the SPE, both FPs and vectors are returned in r3.
25370 On RS/6000 an integer value is in r3 and a floating-point value is in
25371 fp1, unless -msoft-float. */
25374 rs6000_function_value (const_tree valtype,
25375 const_tree fn_decl_or_type ATTRIBUTE_UNUSED,
25376 bool outgoing ATTRIBUTE_UNUSED)
25378 enum machine_mode mode;
25379 unsigned int regno;
25381 /* Special handling for structs in darwin64. */
25382 if (rs6000_darwin64_abi
25383 && TYPE_MODE (valtype) == BLKmode
25384 && TREE_CODE (valtype) == RECORD_TYPE
25385 && int_size_in_bytes (valtype) > 0)
25387 CUMULATIVE_ARGS valcum;
25388 rtx valret;
25390 valcum.words = 0;
25391 valcum.fregno = FP_ARG_MIN_REG;
25392 valcum.vregno = ALTIVEC_ARG_MIN_REG;
25393 /* Do a trial code generation as if this were going to be passed as
25394 an argument; if any part goes in memory, we return NULL. */
25395 valret = rs6000_darwin64_record_arg (&valcum, valtype, 1, true);
25396 if (valret)
25397 return valret;
25398 /* Otherwise fall through to standard ABI rules. */
25401 if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DImode)
25403 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
25404 return gen_rtx_PARALLEL (DImode,
25405 gen_rtvec (2,
25406 gen_rtx_EXPR_LIST (VOIDmode,
25407 gen_rtx_REG (SImode, GP_ARG_RETURN),
25408 const0_rtx),
25409 gen_rtx_EXPR_LIST (VOIDmode,
25410 gen_rtx_REG (SImode,
25411 GP_ARG_RETURN + 1),
25412 GEN_INT (4))));
25414 if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DCmode)
25416 return gen_rtx_PARALLEL (DCmode,
25417 gen_rtvec (4,
25418 gen_rtx_EXPR_LIST (VOIDmode,
25419 gen_rtx_REG (SImode, GP_ARG_RETURN),
25420 const0_rtx),
25421 gen_rtx_EXPR_LIST (VOIDmode,
25422 gen_rtx_REG (SImode,
25423 GP_ARG_RETURN + 1),
25424 GEN_INT (4)),
25425 gen_rtx_EXPR_LIST (VOIDmode,
25426 gen_rtx_REG (SImode,
25427 GP_ARG_RETURN + 2),
25428 GEN_INT (8)),
25429 gen_rtx_EXPR_LIST (VOIDmode,
25430 gen_rtx_REG (SImode,
25431 GP_ARG_RETURN + 3),
25432 GEN_INT (12))));
25435 mode = TYPE_MODE (valtype);
25436 if ((INTEGRAL_TYPE_P (valtype) && GET_MODE_BITSIZE (mode) < BITS_PER_WORD)
25437 || POINTER_TYPE_P (valtype))
25438 mode = TARGET_32BIT ? SImode : DImode;
25440 if (DECIMAL_FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
25441 /* _Decimal128 must use an even/odd register pair. */
25442 regno = (mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN;
25443 else if (SCALAR_FLOAT_TYPE_P (valtype) && TARGET_HARD_FLOAT && TARGET_FPRS
25444 && ((TARGET_SINGLE_FLOAT && (mode == SFmode)) || TARGET_DOUBLE_FLOAT))
25445 regno = FP_ARG_RETURN;
25446 else if (TREE_CODE (valtype) == COMPLEX_TYPE
25447 && targetm.calls.split_complex_arg)
25448 return rs6000_complex_function_value (mode);
25449 else if (TREE_CODE (valtype) == VECTOR_TYPE
25450 && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI
25451 && ALTIVEC_VECTOR_MODE (mode))
25452 regno = ALTIVEC_ARG_RETURN;
25453 else if (TREE_CODE (valtype) == VECTOR_TYPE
25454 && TARGET_VSX && TARGET_ALTIVEC_ABI
25455 && VSX_VECTOR_MODE (mode))
25456 regno = ALTIVEC_ARG_RETURN;
25457 else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
25458 && (mode == DFmode || mode == DCmode
25459 || mode == TFmode || mode == TCmode))
25460 return spe_build_register_parallel (mode, GP_ARG_RETURN);
25461 else
25462 regno = GP_ARG_RETURN;
25464 return gen_rtx_REG (mode, regno);
25467 /* Define how to find the value returned by a library function
25468 assuming the value has mode MODE. */
25470 rs6000_libcall_value (enum machine_mode mode)
25472 unsigned int regno;
25474 if (TARGET_32BIT && TARGET_POWERPC64 && mode == DImode)
25476 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
25477 return gen_rtx_PARALLEL (DImode,
25478 gen_rtvec (2,
25479 gen_rtx_EXPR_LIST (VOIDmode,
25480 gen_rtx_REG (SImode, GP_ARG_RETURN),
25481 const0_rtx),
25482 gen_rtx_EXPR_LIST (VOIDmode,
25483 gen_rtx_REG (SImode,
25484 GP_ARG_RETURN + 1),
25485 GEN_INT (4))));
25488 if (DECIMAL_FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
25489 /* _Decimal128 must use an even/odd register pair. */
25490 regno = (mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN;
25491 else if (SCALAR_FLOAT_MODE_P (mode)
25492 && TARGET_HARD_FLOAT && TARGET_FPRS
25493 && ((TARGET_SINGLE_FLOAT && mode == SFmode) || TARGET_DOUBLE_FLOAT))
25494 regno = FP_ARG_RETURN;
25495 else if (ALTIVEC_VECTOR_MODE (mode)
25496 && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI)
25497 regno = ALTIVEC_ARG_RETURN;
25498 else if (VSX_VECTOR_MODE (mode)
25499 && TARGET_VSX && TARGET_ALTIVEC_ABI)
25500 regno = ALTIVEC_ARG_RETURN;
25501 else if (COMPLEX_MODE_P (mode) && targetm.calls.split_complex_arg)
25502 return rs6000_complex_function_value (mode);
25503 else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
25504 && (mode == DFmode || mode == DCmode
25505 || mode == TFmode || mode == TCmode))
25506 return spe_build_register_parallel (mode, GP_ARG_RETURN);
25507 else
25508 regno = GP_ARG_RETURN;
25510 return gen_rtx_REG (mode, regno);
25514 /* Given FROM and TO register numbers, say whether this elimination is allowed.
25515 Frame pointer elimination is automatically handled.
25517 For the RS/6000, if frame pointer elimination is being done, we would like
25518 to convert ap into fp, not sp.
25520 We need r30 if -mminimal-toc was specified, and there are constant pool
25521 references. */
25523 bool
25524 rs6000_can_eliminate (const int from, const int to)
25526 return (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM
25527 ? ! frame_pointer_needed
25528 : from == RS6000_PIC_OFFSET_TABLE_REGNUM
25529 ? ! TARGET_MINIMAL_TOC || TARGET_NO_TOC || get_pool_size () == 0
25530 : true);
25533 /* Define the offset between two registers, FROM to be eliminated and its
25534 replacement TO, at the start of a routine. */
25535 HOST_WIDE_INT
25536 rs6000_initial_elimination_offset (int from, int to)
25538 rs6000_stack_t *info = rs6000_stack_info ();
25539 HOST_WIDE_INT offset;
25541 if (from == HARD_FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
25542 offset = info->push_p ? 0 : -info->total_size;
25543 else if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
25545 offset = info->push_p ? 0 : -info->total_size;
25546 if (FRAME_GROWS_DOWNWARD)
25547 offset += info->fixed_size + info->vars_size + info->parm_size;
25549 else if (from == FRAME_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
25550 offset = FRAME_GROWS_DOWNWARD
25551 ? info->fixed_size + info->vars_size + info->parm_size
25552 : 0;
25553 else if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
25554 offset = info->total_size;
25555 else if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
25556 offset = info->push_p ? info->total_size : 0;
25557 else if (from == RS6000_PIC_OFFSET_TABLE_REGNUM)
25558 offset = 0;
25559 else
25560 gcc_unreachable ();
25562 return offset;
25565 static rtx
25566 rs6000_dwarf_register_span (rtx reg)
25568 rtx parts[8];
25569 int i, words;
25570 unsigned regno = REGNO (reg);
25571 enum machine_mode mode = GET_MODE (reg);
25573 if (TARGET_SPE
25574 && regno < 32
25575 && (SPE_VECTOR_MODE (GET_MODE (reg))
25576 || (TARGET_E500_DOUBLE && FLOAT_MODE_P (mode)
25577 && mode != SFmode && mode != SDmode && mode != SCmode)))
25579 else
25580 return NULL_RTX;
25582 regno = REGNO (reg);
25584 /* The duality of the SPE register size wreaks all kinds of havoc.
25585 This is a way of distinguishing r0 in 32-bits from r0 in
25586 64-bits. */
25587 words = (GET_MODE_SIZE (mode) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD;
25588 gcc_assert (words <= 4);
25589 for (i = 0; i < words; i++, regno++)
25591 if (BYTES_BIG_ENDIAN)
25593 parts[2 * i] = gen_rtx_REG (SImode, regno + 1200);
25594 parts[2 * i + 1] = gen_rtx_REG (SImode, regno);
25596 else
25598 parts[2 * i] = gen_rtx_REG (SImode, regno);
25599 parts[2 * i + 1] = gen_rtx_REG (SImode, regno + 1200);
25603 return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (words * 2, parts));
25606 /* Fill in sizes for SPE register high parts in table used by unwinder. */
25608 static void
25609 rs6000_init_dwarf_reg_sizes_extra (tree address)
25611 if (TARGET_SPE)
25613 int i;
25614 enum machine_mode mode = TYPE_MODE (char_type_node);
25615 rtx addr = expand_expr (address, NULL_RTX, VOIDmode, EXPAND_NORMAL);
25616 rtx mem = gen_rtx_MEM (BLKmode, addr);
25617 rtx value = gen_int_mode (4, mode);
25619 for (i = 1201; i < 1232; i++)
25621 int column = DWARF_REG_TO_UNWIND_COLUMN (i);
25622 HOST_WIDE_INT offset
25623 = DWARF_FRAME_REGNUM (column) * GET_MODE_SIZE (mode);
25625 emit_move_insn (adjust_address (mem, mode, offset), value);
25630 /* Map internal gcc register numbers to DWARF2 register numbers. */
25632 unsigned int
25633 rs6000_dbx_register_number (unsigned int regno)
25635 if (regno <= 63 || write_symbols != DWARF2_DEBUG)
25636 return regno;
25637 if (regno == MQ_REGNO)
25638 return 100;
25639 if (regno == LR_REGNO)
25640 return 108;
25641 if (regno == CTR_REGNO)
25642 return 109;
25643 if (CR_REGNO_P (regno))
25644 return regno - CR0_REGNO + 86;
25645 if (regno == XER_REGNO)
25646 return 101;
25647 if (ALTIVEC_REGNO_P (regno))
25648 return regno - FIRST_ALTIVEC_REGNO + 1124;
25649 if (regno == VRSAVE_REGNO)
25650 return 356;
25651 if (regno == VSCR_REGNO)
25652 return 67;
25653 if (regno == SPE_ACC_REGNO)
25654 return 99;
25655 if (regno == SPEFSCR_REGNO)
25656 return 612;
25657 /* SPE high reg number. We get these values of regno from
25658 rs6000_dwarf_register_span. */
25659 gcc_assert (regno >= 1200 && regno < 1232);
25660 return regno;
25663 /* target hook eh_return_filter_mode */
25664 static enum machine_mode
25665 rs6000_eh_return_filter_mode (void)
25667 return TARGET_32BIT ? SImode : word_mode;
25670 /* Target hook for scalar_mode_supported_p. */
25671 static bool
25672 rs6000_scalar_mode_supported_p (enum machine_mode mode)
25674 if (DECIMAL_FLOAT_MODE_P (mode))
25675 return default_decimal_float_supported_p ();
25676 else
25677 return default_scalar_mode_supported_p (mode);
25680 /* Target hook for vector_mode_supported_p. */
25681 static bool
25682 rs6000_vector_mode_supported_p (enum machine_mode mode)
25685 if (TARGET_PAIRED_FLOAT && PAIRED_VECTOR_MODE (mode))
25686 return true;
25688 if (TARGET_SPE && SPE_VECTOR_MODE (mode))
25689 return true;
25691 else if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode))
25692 return true;
25694 else
25695 return false;
25698 /* Target hook for invalid_arg_for_unprototyped_fn. */
25699 static const char *
25700 invalid_arg_for_unprototyped_fn (const_tree typelist, const_tree funcdecl, const_tree val)
25702 return (!rs6000_darwin64_abi
25703 && typelist == 0
25704 && TREE_CODE (TREE_TYPE (val)) == VECTOR_TYPE
25705 && (funcdecl == NULL_TREE
25706 || (TREE_CODE (funcdecl) == FUNCTION_DECL
25707 && DECL_BUILT_IN_CLASS (funcdecl) != BUILT_IN_MD)))
25708 ? N_("AltiVec argument passed to unprototyped function")
25709 : NULL;
25712 /* For TARGET_SECURE_PLT 32-bit PIC code we can save PIC register
25713 setup by using __stack_chk_fail_local hidden function instead of
25714 calling __stack_chk_fail directly. Otherwise it is better to call
25715 __stack_chk_fail directly. */
25717 static tree
25718 rs6000_stack_protect_fail (void)
25720 return (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
25721 ? default_hidden_stack_protect_fail ()
25722 : default_external_stack_protect_fail ();
25725 void
25726 rs6000_final_prescan_insn (rtx insn, rtx *operand ATTRIBUTE_UNUSED,
25727 int num_operands ATTRIBUTE_UNUSED)
25729 if (rs6000_warn_cell_microcode)
25731 const char *temp;
25732 int insn_code_number = recog_memoized (insn);
25733 location_t location = locator_location (INSN_LOCATOR (insn));
25735 /* Punt on insns we cannot recognize. */
25736 if (insn_code_number < 0)
25737 return;
25739 temp = get_insn_template (insn_code_number, insn);
25741 if (get_attr_cell_micro (insn) == CELL_MICRO_ALWAYS)
25742 warning_at (location, OPT_mwarn_cell_microcode,
25743 "emitting microcode insn %s\t[%s] #%d",
25744 temp, insn_data[INSN_CODE (insn)].name, INSN_UID (insn));
25745 else if (get_attr_cell_micro (insn) == CELL_MICRO_CONDITIONAL)
25746 warning_at (location, OPT_mwarn_cell_microcode,
25747 "emitting conditional microcode insn %s\t[%s] #%d",
25748 temp, insn_data[INSN_CODE (insn)].name, INSN_UID (insn));
25752 #include "gt-rs6000.h"