2011-03-27 Vladimir Makarov <vmakarov@redhat.com>
[official-gcc.git] / gcc / config / rs6000 / rs6000.c
blob8b1d4122d878981246589185c5f9e0b939aabac2
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, 2011
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 "insn-config.h"
31 #include "conditions.h"
32 #include "insn-attr.h"
33 #include "flags.h"
34 #include "recog.h"
35 #include "obstack.h"
36 #include "tree.h"
37 #include "expr.h"
38 #include "optabs.h"
39 #include "except.h"
40 #include "function.h"
41 #include "output.h"
42 #include "basic-block.h"
43 #include "integrate.h"
44 #include "diagnostic-core.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 "cfgloop.h"
55 #include "sched-int.h"
56 #include "gimple.h"
57 #include "tree-flow.h"
58 #include "intl.h"
59 #include "params.h"
60 #include "tm-constrs.h"
61 #include "opts.h"
62 #if TARGET_XCOFF
63 #include "xcoffout.h" /* get declarations of xcoff_*_section_name */
64 #endif
65 #if TARGET_MACHO
66 #include "gstab.h" /* for N_SLINE */
67 #endif
69 #ifndef TARGET_NO_PROTOTYPE
70 #define TARGET_NO_PROTOTYPE 0
71 #endif
73 #define min(A,B) ((A) < (B) ? (A) : (B))
74 #define max(A,B) ((A) > (B) ? (A) : (B))
76 /* Structure used to define the rs6000 stack */
77 typedef struct rs6000_stack {
78 int reload_completed; /* stack info won't change from here on */
79 int first_gp_reg_save; /* first callee saved GP register used */
80 int first_fp_reg_save; /* first callee saved FP register used */
81 int first_altivec_reg_save; /* first callee saved AltiVec register used */
82 int lr_save_p; /* true if the link reg needs to be saved */
83 int cr_save_p; /* true if the CR reg needs to be saved */
84 unsigned int vrsave_mask; /* mask of vec registers to save */
85 int push_p; /* true if we need to allocate stack space */
86 int calls_p; /* true if the function makes any calls */
87 int world_save_p; /* true if we're saving *everything*:
88 r13-r31, cr, f14-f31, vrsave, v20-v31 */
89 enum rs6000_abi abi; /* which ABI to use */
90 int gp_save_offset; /* offset to save GP regs from initial SP */
91 int fp_save_offset; /* offset to save FP regs from initial SP */
92 int altivec_save_offset; /* offset to save AltiVec regs from initial SP */
93 int lr_save_offset; /* offset to save LR from initial SP */
94 int cr_save_offset; /* offset to save CR from initial SP */
95 int vrsave_save_offset; /* offset to save VRSAVE from initial SP */
96 int spe_gp_save_offset; /* offset to save spe 64-bit gprs */
97 int varargs_save_offset; /* offset to save the varargs registers */
98 int ehrd_offset; /* offset to EH return data */
99 int reg_size; /* register size (4 or 8) */
100 HOST_WIDE_INT vars_size; /* variable save area size */
101 int parm_size; /* outgoing parameter size */
102 int save_size; /* save area size */
103 int fixed_size; /* fixed size of stack frame */
104 int gp_size; /* size of saved GP registers */
105 int fp_size; /* size of saved FP registers */
106 int altivec_size; /* size of saved AltiVec registers */
107 int cr_size; /* size to hold CR if not in save_size */
108 int vrsave_size; /* size to hold VRSAVE if not in save_size */
109 int altivec_padding_size; /* size of altivec alignment padding if
110 not in save_size */
111 int spe_gp_size; /* size of 64-bit GPR save size for SPE */
112 int spe_padding_size;
113 HOST_WIDE_INT total_size; /* total bytes allocated for stack */
114 int spe_64bit_regs_used;
115 int savres_strategy;
116 } rs6000_stack_t;
118 /* A C structure for machine-specific, per-function data.
119 This is added to the cfun structure. */
120 typedef struct GTY(()) machine_function
122 /* Some local-dynamic symbol. */
123 const char *some_ld_name;
124 /* Whether the instruction chain has been scanned already. */
125 int insn_chain_scanned_p;
126 /* Flags if __builtin_return_address (n) with n >= 1 was used. */
127 int ra_needs_full_frame;
128 /* Flags if __builtin_return_address (0) was used. */
129 int ra_need_lr;
130 /* Cache lr_save_p after expansion of builtin_eh_return. */
131 int lr_save_state;
132 /* Offset from virtual_stack_vars_rtx to the start of the ABI_V4
133 varargs save area. */
134 HOST_WIDE_INT varargs_save_offset;
135 /* Temporary stack slot to use for SDmode copies. This slot is
136 64-bits wide and is allocated early enough so that the offset
137 does not overflow the 16-bit load/store offset field. */
138 rtx sdmode_stack_slot;
139 } machine_function;
141 /* Target cpu type */
143 struct rs6000_cpu_select rs6000_select[3] =
145 /* switch name, tune arch */
146 { (const char *)0, "--with-cpu=", 1, 1 },
147 { (const char *)0, "-mcpu=", 1, 1 },
148 { (const char *)0, "-mtune=", 1, 0 },
151 /* String variables to hold the various options. */
152 static const char *rs6000_sched_insert_nops_str;
153 static const char *rs6000_sched_costly_dep_str;
154 static const char *rs6000_recip_name;
156 #ifdef USING_ELFOS_H
157 static const char *rs6000_abi_name;
158 static const char *rs6000_sdata_name;
159 #endif
161 /* Support targetm.vectorize.builtin_mask_for_load. */
162 static GTY(()) tree altivec_builtin_mask_for_load;
164 /* Set to nonzero once AIX common-mode calls have been defined. */
165 static GTY(()) int common_mode_defined;
167 /* Label number of label created for -mrelocatable, to call to so we can
168 get the address of the GOT section */
169 static int rs6000_pic_labelno;
171 #ifdef USING_ELFOS_H
172 /* Counter for labels which are to be placed in .fixup. */
173 int fixuplabelno = 0;
174 #endif
176 /* Whether to use variant of AIX ABI for PowerPC64 Linux. */
177 int dot_symbols;
179 /* Specify the machine mode that pointers have. After generation of rtl, the
180 compiler makes no further distinction between pointers and any other objects
181 of this machine mode. The type is unsigned since not all things that
182 include rs6000.h also include machmode.h. */
183 unsigned rs6000_pmode;
185 /* Width in bits of a pointer. */
186 unsigned rs6000_pointer_size;
188 #ifdef HAVE_AS_GNU_ATTRIBUTE
189 /* Flag whether floating point values have been passed/returned. */
190 static bool rs6000_passes_float;
191 /* Flag whether vector values have been passed/returned. */
192 static bool rs6000_passes_vector;
193 /* Flag whether small (<= 8 byte) structures have been returned. */
194 static bool rs6000_returns_struct;
195 #endif
197 /* Value is TRUE if register/mode pair is acceptable. */
198 bool rs6000_hard_regno_mode_ok_p[NUM_MACHINE_MODES][FIRST_PSEUDO_REGISTER];
200 /* Maximum number of registers needed for a given register class and mode. */
201 unsigned char rs6000_class_max_nregs[NUM_MACHINE_MODES][LIM_REG_CLASSES];
203 /* How many registers are needed for a given register and mode. */
204 unsigned char rs6000_hard_regno_nregs[NUM_MACHINE_MODES][FIRST_PSEUDO_REGISTER];
206 /* Map register number to register class. */
207 enum reg_class rs6000_regno_regclass[FIRST_PSEUDO_REGISTER];
209 /* Reload functions based on the type and the vector unit. */
210 static enum insn_code rs6000_vector_reload[NUM_MACHINE_MODES][2];
212 /* Built in types. */
213 tree rs6000_builtin_types[RS6000_BTI_MAX];
214 tree rs6000_builtin_decls[RS6000_BUILTIN_COUNT];
216 /* Flag to say the TOC is initialized */
217 int toc_initialized;
218 char toc_label_name[10];
220 /* Cached value of rs6000_variable_issue. This is cached in
221 rs6000_variable_issue hook and returned from rs6000_sched_reorder2. */
222 static short cached_can_issue_more;
224 static GTY(()) section *read_only_data_section;
225 static GTY(()) section *private_data_section;
226 static GTY(()) section *read_only_private_data_section;
227 static GTY(()) section *sdata2_section;
228 static GTY(()) section *toc_section;
230 /* True for any options that were explicitly set. */
231 static struct {
232 bool aix_struct_ret; /* True if -maix-struct-ret was used. */
233 bool alignment; /* True if -malign- was used. */
234 bool spe_abi; /* True if -mabi=spe/no-spe was used. */
235 bool altivec_abi; /* True if -mabi=altivec/no-altivec used. */
236 bool spe; /* True if -mspe= was used. */
237 bool float_gprs; /* True if -mfloat-gprs= was used. */
238 bool long_double; /* True if -mlong-double- was used. */
239 bool ieee; /* True if -mabi=ieee/ibmlongdouble used. */
240 bool vrsave; /* True if -mvrsave was used. */
241 bool cmodel; /* True if -mcmodel was used. */
242 } rs6000_explicit_options;
244 struct builtin_description
246 /* mask is not const because we're going to alter it below. This
247 nonsense will go away when we rewrite the -march infrastructure
248 to give us more target flag bits. */
249 unsigned int mask;
250 const enum insn_code icode;
251 const char *const name;
252 const enum rs6000_builtins code;
255 /* Describe the vector unit used for modes. */
256 enum rs6000_vector rs6000_vector_unit[NUM_MACHINE_MODES];
257 enum rs6000_vector rs6000_vector_mem[NUM_MACHINE_MODES];
259 /* Register classes for various constraints that are based on the target
260 switches. */
261 enum reg_class rs6000_constraints[RS6000_CONSTRAINT_MAX];
263 /* Describe the alignment of a vector. */
264 int rs6000_vector_align[NUM_MACHINE_MODES];
266 /* Map selected modes to types for builtins. */
267 static GTY(()) tree builtin_mode_to_type[MAX_MACHINE_MODE][2];
269 /* What modes to automatically generate reciprocal divide estimate (fre) and
270 reciprocal sqrt (frsqrte) for. */
271 unsigned char rs6000_recip_bits[MAX_MACHINE_MODE];
273 /* Masks to determine which reciprocal esitmate instructions to generate
274 automatically. */
275 enum rs6000_recip_mask {
276 RECIP_SF_DIV = 0x001, /* Use divide estimate */
277 RECIP_DF_DIV = 0x002,
278 RECIP_V4SF_DIV = 0x004,
279 RECIP_V2DF_DIV = 0x008,
281 RECIP_SF_RSQRT = 0x010, /* Use reciprocal sqrt estimate. */
282 RECIP_DF_RSQRT = 0x020,
283 RECIP_V4SF_RSQRT = 0x040,
284 RECIP_V2DF_RSQRT = 0x080,
286 /* Various combination of flags for -mrecip=xxx. */
287 RECIP_NONE = 0,
288 RECIP_ALL = (RECIP_SF_DIV | RECIP_DF_DIV | RECIP_V4SF_DIV
289 | RECIP_V2DF_DIV | RECIP_SF_RSQRT | RECIP_DF_RSQRT
290 | RECIP_V4SF_RSQRT | RECIP_V2DF_RSQRT),
292 RECIP_HIGH_PRECISION = RECIP_ALL,
294 /* On low precision machines like the power5, don't enable double precision
295 reciprocal square root estimate, since it isn't accurate enough. */
296 RECIP_LOW_PRECISION = (RECIP_ALL & ~(RECIP_DF_RSQRT | RECIP_V2DF_RSQRT))
299 /* -mrecip options. */
300 static struct
302 const char *string; /* option name */
303 unsigned int mask; /* mask bits to set */
304 } recip_options[] = {
305 { "all", RECIP_ALL },
306 { "none", RECIP_NONE },
307 { "div", (RECIP_SF_DIV | RECIP_DF_DIV | RECIP_V4SF_DIV
308 | RECIP_V2DF_DIV) },
309 { "divf", (RECIP_SF_DIV | RECIP_V4SF_DIV) },
310 { "divd", (RECIP_DF_DIV | RECIP_V2DF_DIV) },
311 { "rsqrt", (RECIP_SF_RSQRT | RECIP_DF_RSQRT | RECIP_V4SF_RSQRT
312 | RECIP_V2DF_RSQRT) },
313 { "rsqrtf", (RECIP_SF_RSQRT | RECIP_V4SF_RSQRT) },
314 { "rsqrtd", (RECIP_DF_RSQRT | RECIP_V2DF_RSQRT) },
317 /* 2 argument gen function typedef. */
318 typedef rtx (*gen_2arg_fn_t) (rtx, rtx, rtx);
321 /* Target cpu costs. */
323 struct processor_costs {
324 const int mulsi; /* cost of SImode multiplication. */
325 const int mulsi_const; /* cost of SImode multiplication by constant. */
326 const int mulsi_const9; /* cost of SImode mult by short constant. */
327 const int muldi; /* cost of DImode multiplication. */
328 const int divsi; /* cost of SImode division. */
329 const int divdi; /* cost of DImode division. */
330 const int fp; /* cost of simple SFmode and DFmode insns. */
331 const int dmul; /* cost of DFmode multiplication (and fmadd). */
332 const int sdiv; /* cost of SFmode division (fdivs). */
333 const int ddiv; /* cost of DFmode division (fdiv). */
334 const int cache_line_size; /* cache line size in bytes. */
335 const int l1_cache_size; /* size of l1 cache, in kilobytes. */
336 const int l2_cache_size; /* size of l2 cache, in kilobytes. */
337 const int simultaneous_prefetches; /* number of parallel prefetch
338 operations. */
341 const struct processor_costs *rs6000_cost;
343 /* Processor costs (relative to an add) */
345 /* Instruction size costs on 32bit processors. */
346 static const
347 struct processor_costs size32_cost = {
348 COSTS_N_INSNS (1), /* mulsi */
349 COSTS_N_INSNS (1), /* mulsi_const */
350 COSTS_N_INSNS (1), /* mulsi_const9 */
351 COSTS_N_INSNS (1), /* muldi */
352 COSTS_N_INSNS (1), /* divsi */
353 COSTS_N_INSNS (1), /* divdi */
354 COSTS_N_INSNS (1), /* fp */
355 COSTS_N_INSNS (1), /* dmul */
356 COSTS_N_INSNS (1), /* sdiv */
357 COSTS_N_INSNS (1), /* ddiv */
364 /* Instruction size costs on 64bit processors. */
365 static const
366 struct processor_costs size64_cost = {
367 COSTS_N_INSNS (1), /* mulsi */
368 COSTS_N_INSNS (1), /* mulsi_const */
369 COSTS_N_INSNS (1), /* mulsi_const9 */
370 COSTS_N_INSNS (1), /* muldi */
371 COSTS_N_INSNS (1), /* divsi */
372 COSTS_N_INSNS (1), /* divdi */
373 COSTS_N_INSNS (1), /* fp */
374 COSTS_N_INSNS (1), /* dmul */
375 COSTS_N_INSNS (1), /* sdiv */
376 COSTS_N_INSNS (1), /* ddiv */
377 128,
383 /* Instruction costs on RIOS1 processors. */
384 static const
385 struct processor_costs rios1_cost = {
386 COSTS_N_INSNS (5), /* mulsi */
387 COSTS_N_INSNS (4), /* mulsi_const */
388 COSTS_N_INSNS (3), /* mulsi_const9 */
389 COSTS_N_INSNS (5), /* muldi */
390 COSTS_N_INSNS (19), /* divsi */
391 COSTS_N_INSNS (19), /* divdi */
392 COSTS_N_INSNS (2), /* fp */
393 COSTS_N_INSNS (2), /* dmul */
394 COSTS_N_INSNS (19), /* sdiv */
395 COSTS_N_INSNS (19), /* ddiv */
396 128, /* cache line size */
397 64, /* l1 cache */
398 512, /* l2 cache */
399 0, /* streams */
402 /* Instruction costs on RIOS2 processors. */
403 static const
404 struct processor_costs rios2_cost = {
405 COSTS_N_INSNS (2), /* mulsi */
406 COSTS_N_INSNS (2), /* mulsi_const */
407 COSTS_N_INSNS (2), /* mulsi_const9 */
408 COSTS_N_INSNS (2), /* muldi */
409 COSTS_N_INSNS (13), /* divsi */
410 COSTS_N_INSNS (13), /* divdi */
411 COSTS_N_INSNS (2), /* fp */
412 COSTS_N_INSNS (2), /* dmul */
413 COSTS_N_INSNS (17), /* sdiv */
414 COSTS_N_INSNS (17), /* ddiv */
415 256, /* cache line size */
416 256, /* l1 cache */
417 1024, /* l2 cache */
418 0, /* streams */
421 /* Instruction costs on RS64A processors. */
422 static const
423 struct processor_costs rs64a_cost = {
424 COSTS_N_INSNS (20), /* mulsi */
425 COSTS_N_INSNS (12), /* mulsi_const */
426 COSTS_N_INSNS (8), /* mulsi_const9 */
427 COSTS_N_INSNS (34), /* muldi */
428 COSTS_N_INSNS (65), /* divsi */
429 COSTS_N_INSNS (67), /* divdi */
430 COSTS_N_INSNS (4), /* fp */
431 COSTS_N_INSNS (4), /* dmul */
432 COSTS_N_INSNS (31), /* sdiv */
433 COSTS_N_INSNS (31), /* ddiv */
434 128, /* cache line size */
435 128, /* l1 cache */
436 2048, /* l2 cache */
437 1, /* streams */
440 /* Instruction costs on MPCCORE processors. */
441 static const
442 struct processor_costs mpccore_cost = {
443 COSTS_N_INSNS (2), /* mulsi */
444 COSTS_N_INSNS (2), /* mulsi_const */
445 COSTS_N_INSNS (2), /* mulsi_const9 */
446 COSTS_N_INSNS (2), /* muldi */
447 COSTS_N_INSNS (6), /* divsi */
448 COSTS_N_INSNS (6), /* divdi */
449 COSTS_N_INSNS (4), /* fp */
450 COSTS_N_INSNS (5), /* dmul */
451 COSTS_N_INSNS (10), /* sdiv */
452 COSTS_N_INSNS (17), /* ddiv */
453 32, /* cache line size */
454 4, /* l1 cache */
455 16, /* l2 cache */
456 1, /* streams */
459 /* Instruction costs on PPC403 processors. */
460 static const
461 struct processor_costs ppc403_cost = {
462 COSTS_N_INSNS (4), /* mulsi */
463 COSTS_N_INSNS (4), /* mulsi_const */
464 COSTS_N_INSNS (4), /* mulsi_const9 */
465 COSTS_N_INSNS (4), /* muldi */
466 COSTS_N_INSNS (33), /* divsi */
467 COSTS_N_INSNS (33), /* divdi */
468 COSTS_N_INSNS (11), /* fp */
469 COSTS_N_INSNS (11), /* dmul */
470 COSTS_N_INSNS (11), /* sdiv */
471 COSTS_N_INSNS (11), /* ddiv */
472 32, /* cache line size */
473 4, /* l1 cache */
474 16, /* l2 cache */
475 1, /* streams */
478 /* Instruction costs on PPC405 processors. */
479 static const
480 struct processor_costs ppc405_cost = {
481 COSTS_N_INSNS (5), /* mulsi */
482 COSTS_N_INSNS (4), /* mulsi_const */
483 COSTS_N_INSNS (3), /* mulsi_const9 */
484 COSTS_N_INSNS (5), /* muldi */
485 COSTS_N_INSNS (35), /* divsi */
486 COSTS_N_INSNS (35), /* divdi */
487 COSTS_N_INSNS (11), /* fp */
488 COSTS_N_INSNS (11), /* dmul */
489 COSTS_N_INSNS (11), /* sdiv */
490 COSTS_N_INSNS (11), /* ddiv */
491 32, /* cache line size */
492 16, /* l1 cache */
493 128, /* l2 cache */
494 1, /* streams */
497 /* Instruction costs on PPC440 processors. */
498 static const
499 struct processor_costs ppc440_cost = {
500 COSTS_N_INSNS (3), /* mulsi */
501 COSTS_N_INSNS (2), /* mulsi_const */
502 COSTS_N_INSNS (2), /* mulsi_const9 */
503 COSTS_N_INSNS (3), /* muldi */
504 COSTS_N_INSNS (34), /* divsi */
505 COSTS_N_INSNS (34), /* divdi */
506 COSTS_N_INSNS (5), /* fp */
507 COSTS_N_INSNS (5), /* dmul */
508 COSTS_N_INSNS (19), /* sdiv */
509 COSTS_N_INSNS (33), /* ddiv */
510 32, /* cache line size */
511 32, /* l1 cache */
512 256, /* l2 cache */
513 1, /* streams */
516 /* Instruction costs on PPC476 processors. */
517 static const
518 struct processor_costs ppc476_cost = {
519 COSTS_N_INSNS (4), /* mulsi */
520 COSTS_N_INSNS (4), /* mulsi_const */
521 COSTS_N_INSNS (4), /* mulsi_const9 */
522 COSTS_N_INSNS (4), /* muldi */
523 COSTS_N_INSNS (11), /* divsi */
524 COSTS_N_INSNS (11), /* divdi */
525 COSTS_N_INSNS (6), /* fp */
526 COSTS_N_INSNS (6), /* dmul */
527 COSTS_N_INSNS (19), /* sdiv */
528 COSTS_N_INSNS (33), /* ddiv */
529 32, /* l1 cache line size */
530 32, /* l1 cache */
531 512, /* l2 cache */
532 1, /* streams */
535 /* Instruction costs on PPC601 processors. */
536 static const
537 struct processor_costs ppc601_cost = {
538 COSTS_N_INSNS (5), /* mulsi */
539 COSTS_N_INSNS (5), /* mulsi_const */
540 COSTS_N_INSNS (5), /* mulsi_const9 */
541 COSTS_N_INSNS (5), /* muldi */
542 COSTS_N_INSNS (36), /* divsi */
543 COSTS_N_INSNS (36), /* divdi */
544 COSTS_N_INSNS (4), /* fp */
545 COSTS_N_INSNS (5), /* dmul */
546 COSTS_N_INSNS (17), /* sdiv */
547 COSTS_N_INSNS (31), /* ddiv */
548 32, /* cache line size */
549 32, /* l1 cache */
550 256, /* l2 cache */
551 1, /* streams */
554 /* Instruction costs on PPC603 processors. */
555 static const
556 struct processor_costs ppc603_cost = {
557 COSTS_N_INSNS (5), /* mulsi */
558 COSTS_N_INSNS (3), /* mulsi_const */
559 COSTS_N_INSNS (2), /* mulsi_const9 */
560 COSTS_N_INSNS (5), /* muldi */
561 COSTS_N_INSNS (37), /* divsi */
562 COSTS_N_INSNS (37), /* divdi */
563 COSTS_N_INSNS (3), /* fp */
564 COSTS_N_INSNS (4), /* dmul */
565 COSTS_N_INSNS (18), /* sdiv */
566 COSTS_N_INSNS (33), /* ddiv */
567 32, /* cache line size */
568 8, /* l1 cache */
569 64, /* l2 cache */
570 1, /* streams */
573 /* Instruction costs on PPC604 processors. */
574 static const
575 struct processor_costs ppc604_cost = {
576 COSTS_N_INSNS (4), /* mulsi */
577 COSTS_N_INSNS (4), /* mulsi_const */
578 COSTS_N_INSNS (4), /* mulsi_const9 */
579 COSTS_N_INSNS (4), /* muldi */
580 COSTS_N_INSNS (20), /* divsi */
581 COSTS_N_INSNS (20), /* divdi */
582 COSTS_N_INSNS (3), /* fp */
583 COSTS_N_INSNS (3), /* dmul */
584 COSTS_N_INSNS (18), /* sdiv */
585 COSTS_N_INSNS (32), /* ddiv */
586 32, /* cache line size */
587 16, /* l1 cache */
588 512, /* l2 cache */
589 1, /* streams */
592 /* Instruction costs on PPC604e processors. */
593 static const
594 struct processor_costs ppc604e_cost = {
595 COSTS_N_INSNS (2), /* mulsi */
596 COSTS_N_INSNS (2), /* mulsi_const */
597 COSTS_N_INSNS (2), /* mulsi_const9 */
598 COSTS_N_INSNS (2), /* muldi */
599 COSTS_N_INSNS (20), /* divsi */
600 COSTS_N_INSNS (20), /* divdi */
601 COSTS_N_INSNS (3), /* fp */
602 COSTS_N_INSNS (3), /* dmul */
603 COSTS_N_INSNS (18), /* sdiv */
604 COSTS_N_INSNS (32), /* ddiv */
605 32, /* cache line size */
606 32, /* l1 cache */
607 1024, /* l2 cache */
608 1, /* streams */
611 /* Instruction costs on PPC620 processors. */
612 static const
613 struct processor_costs ppc620_cost = {
614 COSTS_N_INSNS (5), /* mulsi */
615 COSTS_N_INSNS (4), /* mulsi_const */
616 COSTS_N_INSNS (3), /* mulsi_const9 */
617 COSTS_N_INSNS (7), /* muldi */
618 COSTS_N_INSNS (21), /* divsi */
619 COSTS_N_INSNS (37), /* divdi */
620 COSTS_N_INSNS (3), /* fp */
621 COSTS_N_INSNS (3), /* dmul */
622 COSTS_N_INSNS (18), /* sdiv */
623 COSTS_N_INSNS (32), /* ddiv */
624 128, /* cache line size */
625 32, /* l1 cache */
626 1024, /* l2 cache */
627 1, /* streams */
630 /* Instruction costs on PPC630 processors. */
631 static const
632 struct processor_costs ppc630_cost = {
633 COSTS_N_INSNS (5), /* mulsi */
634 COSTS_N_INSNS (4), /* mulsi_const */
635 COSTS_N_INSNS (3), /* mulsi_const9 */
636 COSTS_N_INSNS (7), /* muldi */
637 COSTS_N_INSNS (21), /* divsi */
638 COSTS_N_INSNS (37), /* divdi */
639 COSTS_N_INSNS (3), /* fp */
640 COSTS_N_INSNS (3), /* dmul */
641 COSTS_N_INSNS (17), /* sdiv */
642 COSTS_N_INSNS (21), /* ddiv */
643 128, /* cache line size */
644 64, /* l1 cache */
645 1024, /* l2 cache */
646 1, /* streams */
649 /* Instruction costs on Cell processor. */
650 /* COSTS_N_INSNS (1) ~ one add. */
651 static const
652 struct processor_costs ppccell_cost = {
653 COSTS_N_INSNS (9/2)+2, /* mulsi */
654 COSTS_N_INSNS (6/2), /* mulsi_const */
655 COSTS_N_INSNS (6/2), /* mulsi_const9 */
656 COSTS_N_INSNS (15/2)+2, /* muldi */
657 COSTS_N_INSNS (38/2), /* divsi */
658 COSTS_N_INSNS (70/2), /* divdi */
659 COSTS_N_INSNS (10/2), /* fp */
660 COSTS_N_INSNS (10/2), /* dmul */
661 COSTS_N_INSNS (74/2), /* sdiv */
662 COSTS_N_INSNS (74/2), /* ddiv */
663 128, /* cache line size */
664 32, /* l1 cache */
665 512, /* l2 cache */
666 6, /* streams */
669 /* Instruction costs on PPC750 and PPC7400 processors. */
670 static const
671 struct processor_costs ppc750_cost = {
672 COSTS_N_INSNS (5), /* mulsi */
673 COSTS_N_INSNS (3), /* mulsi_const */
674 COSTS_N_INSNS (2), /* mulsi_const9 */
675 COSTS_N_INSNS (5), /* muldi */
676 COSTS_N_INSNS (17), /* divsi */
677 COSTS_N_INSNS (17), /* divdi */
678 COSTS_N_INSNS (3), /* fp */
679 COSTS_N_INSNS (3), /* dmul */
680 COSTS_N_INSNS (17), /* sdiv */
681 COSTS_N_INSNS (31), /* ddiv */
682 32, /* cache line size */
683 32, /* l1 cache */
684 512, /* l2 cache */
685 1, /* streams */
688 /* Instruction costs on PPC7450 processors. */
689 static const
690 struct processor_costs ppc7450_cost = {
691 COSTS_N_INSNS (4), /* mulsi */
692 COSTS_N_INSNS (3), /* mulsi_const */
693 COSTS_N_INSNS (3), /* mulsi_const9 */
694 COSTS_N_INSNS (4), /* muldi */
695 COSTS_N_INSNS (23), /* divsi */
696 COSTS_N_INSNS (23), /* divdi */
697 COSTS_N_INSNS (5), /* fp */
698 COSTS_N_INSNS (5), /* dmul */
699 COSTS_N_INSNS (21), /* sdiv */
700 COSTS_N_INSNS (35), /* ddiv */
701 32, /* cache line size */
702 32, /* l1 cache */
703 1024, /* l2 cache */
704 1, /* streams */
707 /* Instruction costs on PPC8540 processors. */
708 static const
709 struct processor_costs ppc8540_cost = {
710 COSTS_N_INSNS (4), /* mulsi */
711 COSTS_N_INSNS (4), /* mulsi_const */
712 COSTS_N_INSNS (4), /* mulsi_const9 */
713 COSTS_N_INSNS (4), /* muldi */
714 COSTS_N_INSNS (19), /* divsi */
715 COSTS_N_INSNS (19), /* divdi */
716 COSTS_N_INSNS (4), /* fp */
717 COSTS_N_INSNS (4), /* dmul */
718 COSTS_N_INSNS (29), /* sdiv */
719 COSTS_N_INSNS (29), /* ddiv */
720 32, /* cache line size */
721 32, /* l1 cache */
722 256, /* l2 cache */
723 1, /* prefetch streams /*/
726 /* Instruction costs on E300C2 and E300C3 cores. */
727 static const
728 struct processor_costs ppce300c2c3_cost = {
729 COSTS_N_INSNS (4), /* mulsi */
730 COSTS_N_INSNS (4), /* mulsi_const */
731 COSTS_N_INSNS (4), /* mulsi_const9 */
732 COSTS_N_INSNS (4), /* muldi */
733 COSTS_N_INSNS (19), /* divsi */
734 COSTS_N_INSNS (19), /* divdi */
735 COSTS_N_INSNS (3), /* fp */
736 COSTS_N_INSNS (4), /* dmul */
737 COSTS_N_INSNS (18), /* sdiv */
738 COSTS_N_INSNS (33), /* ddiv */
740 16, /* l1 cache */
741 16, /* l2 cache */
742 1, /* prefetch streams /*/
745 /* Instruction costs on PPCE500MC processors. */
746 static const
747 struct processor_costs ppce500mc_cost = {
748 COSTS_N_INSNS (4), /* mulsi */
749 COSTS_N_INSNS (4), /* mulsi_const */
750 COSTS_N_INSNS (4), /* mulsi_const9 */
751 COSTS_N_INSNS (4), /* muldi */
752 COSTS_N_INSNS (14), /* divsi */
753 COSTS_N_INSNS (14), /* divdi */
754 COSTS_N_INSNS (8), /* fp */
755 COSTS_N_INSNS (10), /* dmul */
756 COSTS_N_INSNS (36), /* sdiv */
757 COSTS_N_INSNS (66), /* ddiv */
758 64, /* cache line size */
759 32, /* l1 cache */
760 128, /* l2 cache */
761 1, /* prefetch streams /*/
764 /* Instruction costs on PPCE500MC64 processors. */
765 static const
766 struct processor_costs ppce500mc64_cost = {
767 COSTS_N_INSNS (4), /* mulsi */
768 COSTS_N_INSNS (4), /* mulsi_const */
769 COSTS_N_INSNS (4), /* mulsi_const9 */
770 COSTS_N_INSNS (4), /* muldi */
771 COSTS_N_INSNS (14), /* divsi */
772 COSTS_N_INSNS (14), /* divdi */
773 COSTS_N_INSNS (4), /* fp */
774 COSTS_N_INSNS (10), /* dmul */
775 COSTS_N_INSNS (36), /* sdiv */
776 COSTS_N_INSNS (66), /* ddiv */
777 64, /* cache line size */
778 32, /* l1 cache */
779 128, /* l2 cache */
780 1, /* prefetch streams /*/
783 /* Instruction costs on AppliedMicro Titan processors. */
784 static const
785 struct processor_costs titan_cost = {
786 COSTS_N_INSNS (5), /* mulsi */
787 COSTS_N_INSNS (5), /* mulsi_const */
788 COSTS_N_INSNS (5), /* mulsi_const9 */
789 COSTS_N_INSNS (5), /* muldi */
790 COSTS_N_INSNS (18), /* divsi */
791 COSTS_N_INSNS (18), /* divdi */
792 COSTS_N_INSNS (10), /* fp */
793 COSTS_N_INSNS (10), /* dmul */
794 COSTS_N_INSNS (46), /* sdiv */
795 COSTS_N_INSNS (72), /* ddiv */
796 32, /* cache line size */
797 32, /* l1 cache */
798 512, /* l2 cache */
799 1, /* prefetch streams /*/
802 /* Instruction costs on POWER4 and POWER5 processors. */
803 static const
804 struct processor_costs power4_cost = {
805 COSTS_N_INSNS (3), /* mulsi */
806 COSTS_N_INSNS (2), /* mulsi_const */
807 COSTS_N_INSNS (2), /* mulsi_const9 */
808 COSTS_N_INSNS (4), /* muldi */
809 COSTS_N_INSNS (18), /* divsi */
810 COSTS_N_INSNS (34), /* divdi */
811 COSTS_N_INSNS (3), /* fp */
812 COSTS_N_INSNS (3), /* dmul */
813 COSTS_N_INSNS (17), /* sdiv */
814 COSTS_N_INSNS (17), /* ddiv */
815 128, /* cache line size */
816 32, /* l1 cache */
817 1024, /* l2 cache */
818 8, /* prefetch streams /*/
821 /* Instruction costs on POWER6 processors. */
822 static const
823 struct processor_costs power6_cost = {
824 COSTS_N_INSNS (8), /* mulsi */
825 COSTS_N_INSNS (8), /* mulsi_const */
826 COSTS_N_INSNS (8), /* mulsi_const9 */
827 COSTS_N_INSNS (8), /* muldi */
828 COSTS_N_INSNS (22), /* divsi */
829 COSTS_N_INSNS (28), /* divdi */
830 COSTS_N_INSNS (3), /* fp */
831 COSTS_N_INSNS (3), /* dmul */
832 COSTS_N_INSNS (13), /* sdiv */
833 COSTS_N_INSNS (16), /* ddiv */
834 128, /* cache line size */
835 64, /* l1 cache */
836 2048, /* l2 cache */
837 16, /* prefetch streams */
840 /* Instruction costs on POWER7 processors. */
841 static const
842 struct processor_costs power7_cost = {
843 COSTS_N_INSNS (2), /* mulsi */
844 COSTS_N_INSNS (2), /* mulsi_const */
845 COSTS_N_INSNS (2), /* mulsi_const9 */
846 COSTS_N_INSNS (2), /* muldi */
847 COSTS_N_INSNS (18), /* divsi */
848 COSTS_N_INSNS (34), /* divdi */
849 COSTS_N_INSNS (3), /* fp */
850 COSTS_N_INSNS (3), /* dmul */
851 COSTS_N_INSNS (13), /* sdiv */
852 COSTS_N_INSNS (16), /* ddiv */
853 128, /* cache line size */
854 32, /* l1 cache */
855 256, /* l2 cache */
856 12, /* prefetch streams */
859 /* Instruction costs on POWER A2 processors. */
860 static const
861 struct processor_costs ppca2_cost = {
862 COSTS_N_INSNS (16), /* mulsi */
863 COSTS_N_INSNS (16), /* mulsi_const */
864 COSTS_N_INSNS (16), /* mulsi_const9 */
865 COSTS_N_INSNS (16), /* muldi */
866 COSTS_N_INSNS (22), /* divsi */
867 COSTS_N_INSNS (28), /* divdi */
868 COSTS_N_INSNS (3), /* fp */
869 COSTS_N_INSNS (3), /* dmul */
870 COSTS_N_INSNS (59), /* sdiv */
871 COSTS_N_INSNS (72), /* ddiv */
873 16, /* l1 cache */
874 2048, /* l2 cache */
875 16, /* prefetch streams */
879 /* Table that classifies rs6000 builtin functions (pure, const, etc.). */
880 #undef RS6000_BUILTIN
881 #undef RS6000_BUILTIN_EQUATE
882 #define RS6000_BUILTIN(NAME, TYPE) TYPE,
883 #define RS6000_BUILTIN_EQUATE(NAME, VALUE)
885 static const enum rs6000_btc builtin_classify[(int)RS6000_BUILTIN_COUNT] =
887 #include "rs6000-builtin.def"
890 #undef RS6000_BUILTIN
891 #undef RS6000_BUILTIN_EQUATE
893 /* Support for -mveclibabi=<xxx> to control which vector library to use. */
894 static tree (*rs6000_veclib_handler) (tree, tree, tree);
897 static bool rs6000_function_ok_for_sibcall (tree, tree);
898 static const char *rs6000_invalid_within_doloop (const_rtx);
899 static bool rs6000_legitimate_address_p (enum machine_mode, rtx, bool);
900 static bool rs6000_debug_legitimate_address_p (enum machine_mode, rtx, bool);
901 static rtx rs6000_generate_compare (rtx, enum machine_mode);
902 static void rs6000_emit_stack_tie (void);
903 static void rs6000_frame_related (rtx, rtx, HOST_WIDE_INT, rtx, rtx);
904 static bool spe_func_has_64bit_regs_p (void);
905 static void emit_frame_save (rtx, rtx, enum machine_mode, unsigned int,
906 int, HOST_WIDE_INT);
907 static rtx gen_frame_mem_offset (enum machine_mode, rtx, int);
908 static unsigned rs6000_hash_constant (rtx);
909 static unsigned toc_hash_function (const void *);
910 static int toc_hash_eq (const void *, const void *);
911 static bool reg_offset_addressing_ok_p (enum machine_mode);
912 static bool virtual_stack_registers_memory_p (rtx);
913 static bool constant_pool_expr_p (rtx);
914 static bool legitimate_small_data_p (enum machine_mode, rtx);
915 static bool legitimate_lo_sum_address_p (enum machine_mode, rtx, int);
916 static struct machine_function * rs6000_init_machine_status (void);
917 static bool rs6000_assemble_integer (rtx, unsigned int, int);
918 static bool no_global_regs_above (int, bool);
919 #ifdef HAVE_GAS_HIDDEN
920 static void rs6000_assemble_visibility (tree, int);
921 #endif
922 static int rs6000_ra_ever_killed (void);
923 static bool rs6000_attribute_takes_identifier_p (const_tree);
924 static tree rs6000_handle_longcall_attribute (tree *, tree, tree, int, bool *);
925 static tree rs6000_handle_altivec_attribute (tree *, tree, tree, int, bool *);
926 static bool rs6000_ms_bitfield_layout_p (const_tree);
927 static tree rs6000_handle_struct_attribute (tree *, tree, tree, int, bool *);
928 static void rs6000_eliminate_indexed_memrefs (rtx operands[2]);
929 static const char *rs6000_mangle_type (const_tree);
930 static void rs6000_set_default_type_attributes (tree);
931 static rtx rs6000_savres_routine_sym (rs6000_stack_t *, bool, bool, bool);
932 static rtx rs6000_emit_stack_reset (rs6000_stack_t *, rtx, rtx, int, bool);
933 static rtx rs6000_make_savres_rtx (rs6000_stack_t *, rtx, int,
934 enum machine_mode, bool, bool, bool);
935 static bool rs6000_reg_live_or_pic_offset_p (int);
936 static tree rs6000_builtin_vectorized_libmass (tree, tree, tree);
937 static tree rs6000_builtin_vectorized_function (tree, tree, tree);
938 static void rs6000_restore_saved_cr (rtx, int);
939 static bool rs6000_output_addr_const_extra (FILE *, rtx);
940 static void rs6000_output_function_prologue (FILE *, HOST_WIDE_INT);
941 static void rs6000_output_function_epilogue (FILE *, HOST_WIDE_INT);
942 static void rs6000_output_mi_thunk (FILE *, tree, HOST_WIDE_INT, HOST_WIDE_INT,
943 tree);
944 static rtx rs6000_emit_set_long_const (rtx, HOST_WIDE_INT, HOST_WIDE_INT);
945 static bool rs6000_return_in_memory (const_tree, const_tree);
946 static rtx rs6000_function_value (const_tree, const_tree, bool);
947 static void rs6000_file_start (void);
948 #if TARGET_ELF
949 static int rs6000_elf_reloc_rw_mask (void);
950 static void rs6000_elf_asm_out_constructor (rtx, int) ATTRIBUTE_UNUSED;
951 static void rs6000_elf_asm_out_destructor (rtx, int) ATTRIBUTE_UNUSED;
952 static void rs6000_elf_file_end (void) ATTRIBUTE_UNUSED;
953 static void rs6000_elf_asm_init_sections (void);
954 static section *rs6000_elf_select_rtx_section (enum machine_mode, rtx,
955 unsigned HOST_WIDE_INT);
956 static void rs6000_elf_encode_section_info (tree, rtx, int)
957 ATTRIBUTE_UNUSED;
958 #endif
959 static bool rs6000_use_blocks_for_constant_p (enum machine_mode, const_rtx);
960 static void rs6000_alloc_sdmode_stack_slot (void);
961 static void rs6000_instantiate_decls (void);
962 #if TARGET_XCOFF
963 static void rs6000_xcoff_asm_output_anchor (rtx);
964 static void rs6000_xcoff_asm_globalize_label (FILE *, const char *);
965 static void rs6000_xcoff_asm_init_sections (void);
966 static int rs6000_xcoff_reloc_rw_mask (void);
967 static void rs6000_xcoff_asm_named_section (const char *, unsigned int, tree);
968 static section *rs6000_xcoff_select_section (tree, int,
969 unsigned HOST_WIDE_INT);
970 static void rs6000_xcoff_unique_section (tree, int);
971 static section *rs6000_xcoff_select_rtx_section
972 (enum machine_mode, rtx, unsigned HOST_WIDE_INT);
973 static const char * rs6000_xcoff_strip_name_encoding (const char *);
974 static unsigned int rs6000_xcoff_section_type_flags (tree, const char *, int);
975 static void rs6000_xcoff_file_start (void);
976 static void rs6000_xcoff_file_end (void);
977 #endif
978 static int rs6000_variable_issue (FILE *, int, rtx, int);
979 static int rs6000_register_move_cost (enum machine_mode,
980 reg_class_t, reg_class_t);
981 static int rs6000_memory_move_cost (enum machine_mode, reg_class_t, bool);
982 static bool rs6000_rtx_costs (rtx, int, int, int *, bool);
983 static bool rs6000_debug_rtx_costs (rtx, int, int, int *, bool);
984 static int rs6000_debug_address_cost (rtx, bool);
985 static int rs6000_adjust_cost (rtx, rtx, rtx, int);
986 static int rs6000_debug_adjust_cost (rtx, rtx, rtx, int);
987 static void rs6000_sched_init (FILE *, int, int);
988 static bool is_microcoded_insn (rtx);
989 static bool is_nonpipeline_insn (rtx);
990 static bool is_cracked_insn (rtx);
991 static bool is_branch_slot_insn (rtx);
992 static bool is_load_insn (rtx);
993 static rtx get_store_dest (rtx pat);
994 static bool is_store_insn (rtx);
995 static bool set_to_load_agen (rtx,rtx);
996 static bool adjacent_mem_locations (rtx,rtx);
997 static int rs6000_adjust_priority (rtx, int);
998 static int rs6000_issue_rate (void);
999 static bool rs6000_is_costly_dependence (dep_t, int, int);
1000 static rtx get_next_active_insn (rtx, rtx);
1001 static bool insn_terminates_group_p (rtx , enum group_termination);
1002 static bool insn_must_be_first_in_group (rtx);
1003 static bool insn_must_be_last_in_group (rtx);
1004 static bool is_costly_group (rtx *, rtx);
1005 static int force_new_group (int, FILE *, rtx *, rtx, bool *, int, int *);
1006 static int redefine_groups (FILE *, int, rtx, rtx);
1007 static int pad_groups (FILE *, int, rtx, rtx);
1008 static void rs6000_sched_finish (FILE *, int);
1009 static int rs6000_sched_reorder (FILE *, int, rtx *, int *, int);
1010 static int rs6000_sched_reorder2 (FILE *, int, rtx *, int *, int);
1011 static int rs6000_use_sched_lookahead (void);
1012 static int rs6000_use_sched_lookahead_guard (rtx);
1013 static void * rs6000_alloc_sched_context (void);
1014 static void rs6000_init_sched_context (void *, bool);
1015 static void rs6000_set_sched_context (void *);
1016 static void rs6000_free_sched_context (void *);
1017 static tree rs6000_builtin_reciprocal (unsigned int, bool, bool);
1018 static tree rs6000_builtin_mask_for_load (void);
1019 static tree rs6000_builtin_mul_widen_even (tree);
1020 static tree rs6000_builtin_mul_widen_odd (tree);
1021 static tree rs6000_builtin_conversion (unsigned int, tree, tree);
1022 static tree rs6000_builtin_vec_perm (tree, tree *);
1023 static bool rs6000_builtin_support_vector_misalignment (enum
1024 machine_mode,
1025 const_tree,
1026 int, bool);
1027 static int rs6000_builtin_vectorization_cost (enum vect_cost_for_stmt,
1028 tree, int);
1029 static enum machine_mode rs6000_preferred_simd_mode (enum machine_mode);
1031 static void def_builtin (int, const char *, tree, int);
1032 static bool rs6000_vector_alignment_reachable (const_tree, bool);
1033 static void rs6000_init_builtins (void);
1034 static tree rs6000_builtin_decl (unsigned, bool);
1036 static rtx rs6000_expand_unop_builtin (enum insn_code, tree, rtx);
1037 static rtx rs6000_expand_binop_builtin (enum insn_code, tree, rtx);
1038 static rtx rs6000_expand_ternop_builtin (enum insn_code, tree, rtx);
1039 static rtx rs6000_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
1040 static void altivec_init_builtins (void);
1041 static unsigned builtin_hash_function (const void *);
1042 static int builtin_hash_eq (const void *, const void *);
1043 static tree builtin_function_type (enum machine_mode, enum machine_mode,
1044 enum machine_mode, enum machine_mode,
1045 enum rs6000_builtins, const char *name);
1046 static void rs6000_common_init_builtins (void);
1047 static void rs6000_init_libfuncs (void);
1049 static void paired_init_builtins (void);
1050 static rtx paired_expand_builtin (tree, rtx, bool *);
1051 static rtx paired_expand_lv_builtin (enum insn_code, tree, rtx);
1052 static rtx paired_expand_stv_builtin (enum insn_code, tree);
1053 static rtx paired_expand_predicate_builtin (enum insn_code, tree, rtx);
1055 static void enable_mask_for_builtins (struct builtin_description *, int,
1056 enum rs6000_builtins,
1057 enum rs6000_builtins);
1058 static void spe_init_builtins (void);
1059 static rtx spe_expand_builtin (tree, rtx, bool *);
1060 static rtx spe_expand_stv_builtin (enum insn_code, tree);
1061 static rtx spe_expand_predicate_builtin (enum insn_code, tree, rtx);
1062 static rtx spe_expand_evsel_builtin (enum insn_code, tree, rtx);
1063 static int rs6000_emit_int_cmove (rtx, rtx, rtx, rtx);
1064 static rs6000_stack_t *rs6000_stack_info (void);
1065 static void debug_stack_info (rs6000_stack_t *);
1067 static rtx altivec_expand_builtin (tree, rtx, bool *);
1068 static rtx altivec_expand_ld_builtin (tree, rtx, bool *);
1069 static rtx altivec_expand_st_builtin (tree, rtx, bool *);
1070 static rtx altivec_expand_dst_builtin (tree, rtx, bool *);
1071 static rtx altivec_expand_abs_builtin (enum insn_code, tree, rtx);
1072 static rtx altivec_expand_predicate_builtin (enum insn_code, tree, rtx);
1073 static rtx altivec_expand_stv_builtin (enum insn_code, tree);
1074 static rtx altivec_expand_vec_init_builtin (tree, tree, rtx);
1075 static rtx altivec_expand_vec_set_builtin (tree);
1076 static rtx altivec_expand_vec_ext_builtin (tree, rtx);
1077 static int get_element_number (tree, tree);
1078 static void rs6000_option_override (void);
1079 static void rs6000_option_init_struct (struct gcc_options *);
1080 static void rs6000_option_default_params (void);
1081 static bool rs6000_handle_option (struct gcc_options *, struct gcc_options *,
1082 const struct cl_decoded_option *,
1083 location_t);
1084 static int rs6000_loop_align_max_skip (rtx);
1085 static void rs6000_parse_yes_no_option (const char *, const char *, int *);
1086 static int first_altivec_reg_to_save (void);
1087 static unsigned int compute_vrsave_mask (void);
1088 static void compute_save_world_info (rs6000_stack_t *info_ptr);
1089 static void is_altivec_return_reg (rtx, void *);
1090 static rtx generate_set_vrsave (rtx, rs6000_stack_t *, int);
1091 int easy_vector_constant (rtx, enum machine_mode);
1092 static rtx rs6000_dwarf_register_span (rtx);
1093 static void rs6000_init_dwarf_reg_sizes_extra (tree);
1094 static rtx rs6000_legitimize_address (rtx, rtx, enum machine_mode);
1095 static rtx rs6000_debug_legitimize_address (rtx, rtx, enum machine_mode);
1096 static rtx rs6000_legitimize_tls_address (rtx, enum tls_model);
1097 static void rs6000_output_dwarf_dtprel (FILE *, int, rtx) ATTRIBUTE_UNUSED;
1098 static rtx rs6000_delegitimize_address (rtx);
1099 static rtx rs6000_tls_get_addr (void);
1100 static rtx rs6000_got_sym (void);
1101 static int rs6000_tls_symbol_ref_1 (rtx *, void *);
1102 static const char *rs6000_get_some_local_dynamic_name (void);
1103 static int rs6000_get_some_local_dynamic_name_1 (rtx *, void *);
1104 static rtx rs6000_complex_function_value (enum machine_mode);
1105 static rtx rs6000_spe_function_arg (const CUMULATIVE_ARGS *,
1106 enum machine_mode, const_tree);
1107 static void rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS *,
1108 HOST_WIDE_INT, int);
1109 static void rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS *,
1110 const_tree,
1111 HOST_WIDE_INT);
1112 static void rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS *,
1113 HOST_WIDE_INT,
1114 rtx[], int *);
1115 static void rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *,
1116 const_tree, HOST_WIDE_INT,
1117 rtx[], int *);
1118 static rtx rs6000_darwin64_record_arg (CUMULATIVE_ARGS *, const_tree, bool, bool);
1119 static rtx rs6000_mixed_function_arg (enum machine_mode, const_tree, int);
1120 static void rs6000_function_arg_advance (CUMULATIVE_ARGS *, enum machine_mode,
1121 const_tree, bool);
1122 static rtx rs6000_function_arg (CUMULATIVE_ARGS *, enum machine_mode,
1123 const_tree, bool);
1124 static unsigned int rs6000_function_arg_boundary (enum machine_mode,
1125 const_tree);
1126 static void rs6000_move_block_from_reg (int regno, rtx x, int nregs);
1127 static void setup_incoming_varargs (CUMULATIVE_ARGS *,
1128 enum machine_mode, tree,
1129 int *, int);
1130 static bool rs6000_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode,
1131 const_tree, bool);
1132 static int rs6000_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode,
1133 tree, bool);
1134 static const char *invalid_arg_for_unprototyped_fn (const_tree, const_tree, const_tree);
1135 #if TARGET_MACHO
1136 static void macho_branch_islands (void);
1137 static int no_previous_def (tree function_name);
1138 static tree get_prev_label (tree function_name);
1139 static void rs6000_darwin_file_start (void);
1140 #endif
1142 static tree rs6000_build_builtin_va_list (void);
1143 static void rs6000_va_start (tree, rtx);
1144 static tree rs6000_gimplify_va_arg (tree, tree, gimple_seq *, gimple_seq *);
1145 static bool rs6000_must_pass_in_stack (enum machine_mode, const_tree);
1146 static bool rs6000_scalar_mode_supported_p (enum machine_mode);
1147 static bool rs6000_vector_mode_supported_p (enum machine_mode);
1148 static rtx rs6000_emit_vector_compare_inner (enum rtx_code, rtx, rtx);
1149 static rtx rs6000_emit_vector_compare (enum rtx_code, rtx, rtx,
1150 enum machine_mode);
1151 static tree rs6000_stack_protect_fail (void);
1153 static rtx rs6000_legitimize_reload_address (rtx, enum machine_mode, int, int,
1154 int, int *);
1156 static rtx rs6000_debug_legitimize_reload_address (rtx, enum machine_mode, int,
1157 int, int, int *);
1159 rtx (*rs6000_legitimize_reload_address_ptr) (rtx, enum machine_mode, int, int,
1160 int, int *)
1161 = rs6000_legitimize_reload_address;
1163 static bool rs6000_mode_dependent_address_p (const_rtx);
1164 static bool rs6000_mode_dependent_address (const_rtx);
1165 static bool rs6000_debug_mode_dependent_address (const_rtx);
1166 static bool (*rs6000_mode_dependent_address_ptr) (const_rtx)
1167 = rs6000_mode_dependent_address;
1169 static enum reg_class rs6000_secondary_reload_class (enum reg_class,
1170 enum machine_mode, rtx);
1171 static enum reg_class rs6000_debug_secondary_reload_class (enum reg_class,
1172 enum machine_mode,
1173 rtx);
1174 enum reg_class (*rs6000_secondary_reload_class_ptr) (enum reg_class,
1175 enum machine_mode, rtx)
1176 = rs6000_secondary_reload_class;
1178 static enum reg_class rs6000_preferred_reload_class (rtx, enum reg_class);
1179 static enum reg_class rs6000_debug_preferred_reload_class (rtx,
1180 enum reg_class);
1181 enum reg_class (*rs6000_preferred_reload_class_ptr) (rtx, enum reg_class)
1182 = rs6000_preferred_reload_class;
1184 static bool rs6000_secondary_memory_needed (enum reg_class, enum reg_class,
1185 enum machine_mode);
1187 static bool rs6000_debug_secondary_memory_needed (enum reg_class,
1188 enum reg_class,
1189 enum machine_mode);
1191 bool (*rs6000_secondary_memory_needed_ptr) (enum reg_class, enum reg_class,
1192 enum machine_mode)
1193 = rs6000_secondary_memory_needed;
1195 static bool rs6000_cannot_change_mode_class (enum machine_mode,
1196 enum machine_mode,
1197 enum reg_class);
1198 static bool rs6000_debug_cannot_change_mode_class (enum machine_mode,
1199 enum machine_mode,
1200 enum reg_class);
1202 bool (*rs6000_cannot_change_mode_class_ptr) (enum machine_mode,
1203 enum machine_mode,
1204 enum reg_class)
1205 = rs6000_cannot_change_mode_class;
1207 static reg_class_t rs6000_secondary_reload (bool, rtx, reg_class_t,
1208 enum machine_mode,
1209 struct secondary_reload_info *);
1211 const int INSN_NOT_AVAILABLE = -1;
1212 static enum machine_mode rs6000_eh_return_filter_mode (void);
1213 static bool rs6000_can_eliminate (const int, const int);
1214 static void rs6000_conditional_register_usage (void);
1215 static void rs6000_trampoline_init (rtx, tree, rtx);
1217 /* Hash table stuff for keeping track of TOC entries. */
1219 struct GTY(()) toc_hash_struct
1221 /* `key' will satisfy CONSTANT_P; in fact, it will satisfy
1222 ASM_OUTPUT_SPECIAL_POOL_ENTRY_P. */
1223 rtx key;
1224 enum machine_mode key_mode;
1225 int labelno;
1228 static GTY ((param_is (struct toc_hash_struct))) htab_t toc_hash_table;
1230 /* Hash table to keep track of the argument types for builtin functions. */
1232 struct GTY(()) builtin_hash_struct
1234 tree type;
1235 enum machine_mode mode[4]; /* return value + 3 arguments. */
1236 unsigned char uns_p[4]; /* and whether the types are unsigned. */
1239 static GTY ((param_is (struct builtin_hash_struct))) htab_t builtin_hash_table;
1241 static bool rs6000_valid_attribute_p (tree, tree, tree, int);
1242 static void rs6000_function_specific_save (struct cl_target_option *);
1243 static void rs6000_function_specific_restore (struct cl_target_option *);
1244 static void rs6000_function_specific_print (FILE *, int,
1245 struct cl_target_option *);
1246 static bool rs6000_can_inline_p (tree, tree);
1247 static void rs6000_set_current_function (tree);
1250 /* Default register names. */
1251 char rs6000_reg_names[][8] =
1253 "0", "1", "2", "3", "4", "5", "6", "7",
1254 "8", "9", "10", "11", "12", "13", "14", "15",
1255 "16", "17", "18", "19", "20", "21", "22", "23",
1256 "24", "25", "26", "27", "28", "29", "30", "31",
1257 "0", "1", "2", "3", "4", "5", "6", "7",
1258 "8", "9", "10", "11", "12", "13", "14", "15",
1259 "16", "17", "18", "19", "20", "21", "22", "23",
1260 "24", "25", "26", "27", "28", "29", "30", "31",
1261 "mq", "lr", "ctr","ap",
1262 "0", "1", "2", "3", "4", "5", "6", "7",
1263 "ca",
1264 /* AltiVec registers. */
1265 "0", "1", "2", "3", "4", "5", "6", "7",
1266 "8", "9", "10", "11", "12", "13", "14", "15",
1267 "16", "17", "18", "19", "20", "21", "22", "23",
1268 "24", "25", "26", "27", "28", "29", "30", "31",
1269 "vrsave", "vscr",
1270 /* SPE registers. */
1271 "spe_acc", "spefscr",
1272 /* Soft frame pointer. */
1273 "sfp"
1276 #ifdef TARGET_REGNAMES
1277 static const char alt_reg_names[][8] =
1279 "%r0", "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7",
1280 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15",
1281 "%r16", "%r17", "%r18", "%r19", "%r20", "%r21", "%r22", "%r23",
1282 "%r24", "%r25", "%r26", "%r27", "%r28", "%r29", "%r30", "%r31",
1283 "%f0", "%f1", "%f2", "%f3", "%f4", "%f5", "%f6", "%f7",
1284 "%f8", "%f9", "%f10", "%f11", "%f12", "%f13", "%f14", "%f15",
1285 "%f16", "%f17", "%f18", "%f19", "%f20", "%f21", "%f22", "%f23",
1286 "%f24", "%f25", "%f26", "%f27", "%f28", "%f29", "%f30", "%f31",
1287 "mq", "lr", "ctr", "ap",
1288 "%cr0", "%cr1", "%cr2", "%cr3", "%cr4", "%cr5", "%cr6", "%cr7",
1289 "ca",
1290 /* AltiVec registers. */
1291 "%v0", "%v1", "%v2", "%v3", "%v4", "%v5", "%v6", "%v7",
1292 "%v8", "%v9", "%v10", "%v11", "%v12", "%v13", "%v14", "%v15",
1293 "%v16", "%v17", "%v18", "%v19", "%v20", "%v21", "%v22", "%v23",
1294 "%v24", "%v25", "%v26", "%v27", "%v28", "%v29", "%v30", "%v31",
1295 "vrsave", "vscr",
1296 /* SPE registers. */
1297 "spe_acc", "spefscr",
1298 /* Soft frame pointer. */
1299 "sfp"
1301 #endif
1303 /* Table of valid machine attributes. */
1305 static const struct attribute_spec rs6000_attribute_table[] =
1307 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler,
1308 affects_type_identity } */
1309 { "altivec", 1, 1, false, true, false, rs6000_handle_altivec_attribute,
1310 false },
1311 { "longcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute,
1312 false },
1313 { "shortcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute,
1314 false },
1315 { "ms_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute,
1316 false },
1317 { "gcc_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute,
1318 false },
1319 #ifdef SUBTARGET_ATTRIBUTE_TABLE
1320 SUBTARGET_ATTRIBUTE_TABLE,
1321 #endif
1322 { NULL, 0, 0, false, false, false, NULL, false }
1325 /* Implement TARGET_OPTION_OPTIMIZATION_TABLE. */
1326 static const struct default_options rs6000_option_optimization_table[] =
1328 { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 },
1329 { OPT_LEVELS_NONE, 0, NULL, 0 }
1332 #ifndef MASK_STRICT_ALIGN
1333 #define MASK_STRICT_ALIGN 0
1334 #endif
1335 #ifndef TARGET_PROFILE_KERNEL
1336 #define TARGET_PROFILE_KERNEL 0
1337 #endif
1339 /* The VRSAVE bitmask puts bit %v0 as the most significant bit. */
1340 #define ALTIVEC_REG_BIT(REGNO) (0x80000000 >> ((REGNO) - FIRST_ALTIVEC_REGNO))
1342 /* Initialize the GCC target structure. */
1343 #undef TARGET_ATTRIBUTE_TABLE
1344 #define TARGET_ATTRIBUTE_TABLE rs6000_attribute_table
1345 #undef TARGET_SET_DEFAULT_TYPE_ATTRIBUTES
1346 #define TARGET_SET_DEFAULT_TYPE_ATTRIBUTES rs6000_set_default_type_attributes
1347 #undef TARGET_ATTRIBUTE_TAKES_IDENTIFIER_P
1348 #define TARGET_ATTRIBUTE_TAKES_IDENTIFIER_P rs6000_attribute_takes_identifier_p
1350 #undef TARGET_ASM_ALIGNED_DI_OP
1351 #define TARGET_ASM_ALIGNED_DI_OP DOUBLE_INT_ASM_OP
1353 /* Default unaligned ops are only provided for ELF. Find the ops needed
1354 for non-ELF systems. */
1355 #ifndef OBJECT_FORMAT_ELF
1356 #if TARGET_XCOFF
1357 /* For XCOFF. rs6000_assemble_integer will handle unaligned DIs on
1358 64-bit targets. */
1359 #undef TARGET_ASM_UNALIGNED_HI_OP
1360 #define TARGET_ASM_UNALIGNED_HI_OP "\t.vbyte\t2,"
1361 #undef TARGET_ASM_UNALIGNED_SI_OP
1362 #define TARGET_ASM_UNALIGNED_SI_OP "\t.vbyte\t4,"
1363 #undef TARGET_ASM_UNALIGNED_DI_OP
1364 #define TARGET_ASM_UNALIGNED_DI_OP "\t.vbyte\t8,"
1365 #else
1366 /* For Darwin. */
1367 #undef TARGET_ASM_UNALIGNED_HI_OP
1368 #define TARGET_ASM_UNALIGNED_HI_OP "\t.short\t"
1369 #undef TARGET_ASM_UNALIGNED_SI_OP
1370 #define TARGET_ASM_UNALIGNED_SI_OP "\t.long\t"
1371 #undef TARGET_ASM_UNALIGNED_DI_OP
1372 #define TARGET_ASM_UNALIGNED_DI_OP "\t.quad\t"
1373 #undef TARGET_ASM_ALIGNED_DI_OP
1374 #define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t"
1375 #endif
1376 #endif
1378 /* This hook deals with fixups for relocatable code and DI-mode objects
1379 in 64-bit code. */
1380 #undef TARGET_ASM_INTEGER
1381 #define TARGET_ASM_INTEGER rs6000_assemble_integer
1383 #ifdef HAVE_GAS_HIDDEN
1384 #undef TARGET_ASM_ASSEMBLE_VISIBILITY
1385 #define TARGET_ASM_ASSEMBLE_VISIBILITY rs6000_assemble_visibility
1386 #endif
1388 #undef TARGET_HAVE_TLS
1389 #define TARGET_HAVE_TLS HAVE_AS_TLS
1391 #undef TARGET_CANNOT_FORCE_CONST_MEM
1392 #define TARGET_CANNOT_FORCE_CONST_MEM rs6000_tls_referenced_p
1394 #undef TARGET_DELEGITIMIZE_ADDRESS
1395 #define TARGET_DELEGITIMIZE_ADDRESS rs6000_delegitimize_address
1397 #undef TARGET_ASM_FUNCTION_PROLOGUE
1398 #define TARGET_ASM_FUNCTION_PROLOGUE rs6000_output_function_prologue
1399 #undef TARGET_ASM_FUNCTION_EPILOGUE
1400 #define TARGET_ASM_FUNCTION_EPILOGUE rs6000_output_function_epilogue
1402 #undef TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA
1403 #define TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA rs6000_output_addr_const_extra
1405 #undef TARGET_LEGITIMIZE_ADDRESS
1406 #define TARGET_LEGITIMIZE_ADDRESS rs6000_legitimize_address
1408 #undef TARGET_SCHED_VARIABLE_ISSUE
1409 #define TARGET_SCHED_VARIABLE_ISSUE rs6000_variable_issue
1411 #undef TARGET_SCHED_ISSUE_RATE
1412 #define TARGET_SCHED_ISSUE_RATE rs6000_issue_rate
1413 #undef TARGET_SCHED_ADJUST_COST
1414 #define TARGET_SCHED_ADJUST_COST rs6000_adjust_cost
1415 #undef TARGET_SCHED_ADJUST_PRIORITY
1416 #define TARGET_SCHED_ADJUST_PRIORITY rs6000_adjust_priority
1417 #undef TARGET_SCHED_IS_COSTLY_DEPENDENCE
1418 #define TARGET_SCHED_IS_COSTLY_DEPENDENCE rs6000_is_costly_dependence
1419 #undef TARGET_SCHED_INIT
1420 #define TARGET_SCHED_INIT rs6000_sched_init
1421 #undef TARGET_SCHED_FINISH
1422 #define TARGET_SCHED_FINISH rs6000_sched_finish
1423 #undef TARGET_SCHED_REORDER
1424 #define TARGET_SCHED_REORDER rs6000_sched_reorder
1425 #undef TARGET_SCHED_REORDER2
1426 #define TARGET_SCHED_REORDER2 rs6000_sched_reorder2
1428 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
1429 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD rs6000_use_sched_lookahead
1431 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD
1432 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD rs6000_use_sched_lookahead_guard
1434 #undef TARGET_SCHED_ALLOC_SCHED_CONTEXT
1435 #define TARGET_SCHED_ALLOC_SCHED_CONTEXT rs6000_alloc_sched_context
1436 #undef TARGET_SCHED_INIT_SCHED_CONTEXT
1437 #define TARGET_SCHED_INIT_SCHED_CONTEXT rs6000_init_sched_context
1438 #undef TARGET_SCHED_SET_SCHED_CONTEXT
1439 #define TARGET_SCHED_SET_SCHED_CONTEXT rs6000_set_sched_context
1440 #undef TARGET_SCHED_FREE_SCHED_CONTEXT
1441 #define TARGET_SCHED_FREE_SCHED_CONTEXT rs6000_free_sched_context
1443 #undef TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD
1444 #define TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD rs6000_builtin_mask_for_load
1445 #undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN
1446 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN rs6000_builtin_mul_widen_even
1447 #undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD
1448 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD rs6000_builtin_mul_widen_odd
1449 #undef TARGET_VECTORIZE_BUILTIN_CONVERSION
1450 #define TARGET_VECTORIZE_BUILTIN_CONVERSION rs6000_builtin_conversion
1451 #undef TARGET_VECTORIZE_BUILTIN_VEC_PERM
1452 #define TARGET_VECTORIZE_BUILTIN_VEC_PERM rs6000_builtin_vec_perm
1453 #undef TARGET_VECTORIZE_SUPPORT_VECTOR_MISALIGNMENT
1454 #define TARGET_VECTORIZE_SUPPORT_VECTOR_MISALIGNMENT \
1455 rs6000_builtin_support_vector_misalignment
1456 #undef TARGET_VECTORIZE_VECTOR_ALIGNMENT_REACHABLE
1457 #define TARGET_VECTORIZE_VECTOR_ALIGNMENT_REACHABLE rs6000_vector_alignment_reachable
1458 #undef TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST
1459 #define TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST \
1460 rs6000_builtin_vectorization_cost
1461 #undef TARGET_VECTORIZE_PREFERRED_SIMD_MODE
1462 #define TARGET_VECTORIZE_PREFERRED_SIMD_MODE \
1463 rs6000_preferred_simd_mode
1465 #undef TARGET_INIT_BUILTINS
1466 #define TARGET_INIT_BUILTINS rs6000_init_builtins
1467 #undef TARGET_BUILTIN_DECL
1468 #define TARGET_BUILTIN_DECL rs6000_builtin_decl
1470 #undef TARGET_EXPAND_BUILTIN
1471 #define TARGET_EXPAND_BUILTIN rs6000_expand_builtin
1473 #undef TARGET_MANGLE_TYPE
1474 #define TARGET_MANGLE_TYPE rs6000_mangle_type
1476 #undef TARGET_INIT_LIBFUNCS
1477 #define TARGET_INIT_LIBFUNCS rs6000_init_libfuncs
1479 #if TARGET_MACHO
1480 #undef TARGET_BINDS_LOCAL_P
1481 #define TARGET_BINDS_LOCAL_P darwin_binds_local_p
1482 #endif
1484 #undef TARGET_MS_BITFIELD_LAYOUT_P
1485 #define TARGET_MS_BITFIELD_LAYOUT_P rs6000_ms_bitfield_layout_p
1487 #undef TARGET_ASM_OUTPUT_MI_THUNK
1488 #define TARGET_ASM_OUTPUT_MI_THUNK rs6000_output_mi_thunk
1490 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
1491 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true
1493 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
1494 #define TARGET_FUNCTION_OK_FOR_SIBCALL rs6000_function_ok_for_sibcall
1496 #undef TARGET_INVALID_WITHIN_DOLOOP
1497 #define TARGET_INVALID_WITHIN_DOLOOP rs6000_invalid_within_doloop
1499 #undef TARGET_REGISTER_MOVE_COST
1500 #define TARGET_REGISTER_MOVE_COST rs6000_register_move_cost
1501 #undef TARGET_MEMORY_MOVE_COST
1502 #define TARGET_MEMORY_MOVE_COST rs6000_memory_move_cost
1503 #undef TARGET_RTX_COSTS
1504 #define TARGET_RTX_COSTS rs6000_rtx_costs
1505 #undef TARGET_ADDRESS_COST
1506 #define TARGET_ADDRESS_COST hook_int_rtx_bool_0
1508 #undef TARGET_DWARF_REGISTER_SPAN
1509 #define TARGET_DWARF_REGISTER_SPAN rs6000_dwarf_register_span
1511 #undef TARGET_INIT_DWARF_REG_SIZES_EXTRA
1512 #define TARGET_INIT_DWARF_REG_SIZES_EXTRA rs6000_init_dwarf_reg_sizes_extra
1514 /* On rs6000, function arguments are promoted, as are function return
1515 values. */
1516 #undef TARGET_PROMOTE_FUNCTION_MODE
1517 #define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote
1519 #undef TARGET_RETURN_IN_MEMORY
1520 #define TARGET_RETURN_IN_MEMORY rs6000_return_in_memory
1522 #undef TARGET_SETUP_INCOMING_VARARGS
1523 #define TARGET_SETUP_INCOMING_VARARGS setup_incoming_varargs
1525 /* Always strict argument naming on rs6000. */
1526 #undef TARGET_STRICT_ARGUMENT_NAMING
1527 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
1528 #undef TARGET_PRETEND_OUTGOING_VARARGS_NAMED
1529 #define TARGET_PRETEND_OUTGOING_VARARGS_NAMED hook_bool_CUMULATIVE_ARGS_true
1530 #undef TARGET_SPLIT_COMPLEX_ARG
1531 #define TARGET_SPLIT_COMPLEX_ARG hook_bool_const_tree_true
1532 #undef TARGET_MUST_PASS_IN_STACK
1533 #define TARGET_MUST_PASS_IN_STACK rs6000_must_pass_in_stack
1534 #undef TARGET_PASS_BY_REFERENCE
1535 #define TARGET_PASS_BY_REFERENCE rs6000_pass_by_reference
1536 #undef TARGET_ARG_PARTIAL_BYTES
1537 #define TARGET_ARG_PARTIAL_BYTES rs6000_arg_partial_bytes
1538 #undef TARGET_FUNCTION_ARG_ADVANCE
1539 #define TARGET_FUNCTION_ARG_ADVANCE rs6000_function_arg_advance
1540 #undef TARGET_FUNCTION_ARG
1541 #define TARGET_FUNCTION_ARG rs6000_function_arg
1542 #undef TARGET_FUNCTION_ARG_BOUNDARY
1543 #define TARGET_FUNCTION_ARG_BOUNDARY rs6000_function_arg_boundary
1545 #undef TARGET_BUILD_BUILTIN_VA_LIST
1546 #define TARGET_BUILD_BUILTIN_VA_LIST rs6000_build_builtin_va_list
1548 #undef TARGET_EXPAND_BUILTIN_VA_START
1549 #define TARGET_EXPAND_BUILTIN_VA_START rs6000_va_start
1551 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
1552 #define TARGET_GIMPLIFY_VA_ARG_EXPR rs6000_gimplify_va_arg
1554 #undef TARGET_EH_RETURN_FILTER_MODE
1555 #define TARGET_EH_RETURN_FILTER_MODE rs6000_eh_return_filter_mode
1557 #undef TARGET_SCALAR_MODE_SUPPORTED_P
1558 #define TARGET_SCALAR_MODE_SUPPORTED_P rs6000_scalar_mode_supported_p
1560 #undef TARGET_VECTOR_MODE_SUPPORTED_P
1561 #define TARGET_VECTOR_MODE_SUPPORTED_P rs6000_vector_mode_supported_p
1563 #undef TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN
1564 #define TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN invalid_arg_for_unprototyped_fn
1566 #undef TARGET_HANDLE_OPTION
1567 #define TARGET_HANDLE_OPTION rs6000_handle_option
1569 #undef TARGET_ASM_LOOP_ALIGN_MAX_SKIP
1570 #define TARGET_ASM_LOOP_ALIGN_MAX_SKIP rs6000_loop_align_max_skip
1572 #undef TARGET_OPTION_OVERRIDE
1573 #define TARGET_OPTION_OVERRIDE rs6000_option_override
1575 #undef TARGET_OPTION_INIT_STRUCT
1576 #define TARGET_OPTION_INIT_STRUCT rs6000_option_init_struct
1578 #undef TARGET_OPTION_DEFAULT_PARAMS
1579 #define TARGET_OPTION_DEFAULT_PARAMS rs6000_option_default_params
1581 #undef TARGET_OPTION_OPTIMIZATION_TABLE
1582 #define TARGET_OPTION_OPTIMIZATION_TABLE rs6000_option_optimization_table
1584 #undef TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION
1585 #define TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION \
1586 rs6000_builtin_vectorized_function
1588 #undef TARGET_DEFAULT_TARGET_FLAGS
1589 #define TARGET_DEFAULT_TARGET_FLAGS \
1590 (TARGET_DEFAULT)
1592 #undef TARGET_STACK_PROTECT_FAIL
1593 #define TARGET_STACK_PROTECT_FAIL rs6000_stack_protect_fail
1595 /* MPC604EUM 3.5.2 Weak Consistency between Multiple Processors
1596 The PowerPC architecture requires only weak consistency among
1597 processors--that is, memory accesses between processors need not be
1598 sequentially consistent and memory accesses among processors can occur
1599 in any order. The ability to order memory accesses weakly provides
1600 opportunities for more efficient use of the system bus. Unless a
1601 dependency exists, the 604e allows read operations to precede store
1602 operations. */
1603 #undef TARGET_RELAXED_ORDERING
1604 #define TARGET_RELAXED_ORDERING true
1606 #ifdef HAVE_AS_TLS
1607 #undef TARGET_ASM_OUTPUT_DWARF_DTPREL
1608 #define TARGET_ASM_OUTPUT_DWARF_DTPREL rs6000_output_dwarf_dtprel
1609 #endif
1611 /* Use a 32-bit anchor range. This leads to sequences like:
1613 addis tmp,anchor,high
1614 add dest,tmp,low
1616 where tmp itself acts as an anchor, and can be shared between
1617 accesses to the same 64k page. */
1618 #undef TARGET_MIN_ANCHOR_OFFSET
1619 #define TARGET_MIN_ANCHOR_OFFSET -0x7fffffff - 1
1620 #undef TARGET_MAX_ANCHOR_OFFSET
1621 #define TARGET_MAX_ANCHOR_OFFSET 0x7fffffff
1622 #undef TARGET_USE_BLOCKS_FOR_CONSTANT_P
1623 #define TARGET_USE_BLOCKS_FOR_CONSTANT_P rs6000_use_blocks_for_constant_p
1625 #undef TARGET_BUILTIN_RECIPROCAL
1626 #define TARGET_BUILTIN_RECIPROCAL rs6000_builtin_reciprocal
1628 #undef TARGET_EXPAND_TO_RTL_HOOK
1629 #define TARGET_EXPAND_TO_RTL_HOOK rs6000_alloc_sdmode_stack_slot
1631 #undef TARGET_INSTANTIATE_DECLS
1632 #define TARGET_INSTANTIATE_DECLS rs6000_instantiate_decls
1634 #undef TARGET_SECONDARY_RELOAD
1635 #define TARGET_SECONDARY_RELOAD rs6000_secondary_reload
1637 #undef TARGET_LEGITIMATE_ADDRESS_P
1638 #define TARGET_LEGITIMATE_ADDRESS_P rs6000_legitimate_address_p
1640 #undef TARGET_MODE_DEPENDENT_ADDRESS_P
1641 #define TARGET_MODE_DEPENDENT_ADDRESS_P rs6000_mode_dependent_address_p
1643 #undef TARGET_CAN_ELIMINATE
1644 #define TARGET_CAN_ELIMINATE rs6000_can_eliminate
1646 #undef TARGET_CONDITIONAL_REGISTER_USAGE
1647 #define TARGET_CONDITIONAL_REGISTER_USAGE rs6000_conditional_register_usage
1649 #undef TARGET_TRAMPOLINE_INIT
1650 #define TARGET_TRAMPOLINE_INIT rs6000_trampoline_init
1652 #undef TARGET_FUNCTION_VALUE
1653 #define TARGET_FUNCTION_VALUE rs6000_function_value
1655 #undef TARGET_OPTION_VALID_ATTRIBUTE_P
1656 #define TARGET_OPTION_VALID_ATTRIBUTE_P rs6000_valid_attribute_p
1658 #undef TARGET_OPTION_SAVE
1659 #define TARGET_OPTION_SAVE rs6000_function_specific_save
1661 #undef TARGET_OPTION_RESTORE
1662 #define TARGET_OPTION_RESTORE rs6000_function_specific_restore
1664 #undef TARGET_OPTION_PRINT
1665 #define TARGET_OPTION_PRINT rs6000_function_specific_print
1667 #undef TARGET_CAN_INLINE_P
1668 #define TARGET_CAN_INLINE_P rs6000_can_inline_p
1670 #undef TARGET_SET_CURRENT_FUNCTION
1671 #define TARGET_SET_CURRENT_FUNCTION rs6000_set_current_function
1673 struct gcc_target targetm = TARGET_INITIALIZER;
1676 /* Simplifications for entries below. */
1678 enum {
1679 POWERPC_BASE_MASK = MASK_POWERPC | MASK_NEW_MNEMONICS,
1680 POWERPC_7400_MASK = POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_ALTIVEC
1683 /* Some OSs don't support saving the high part of 64-bit registers on context
1684 switch. Other OSs don't support saving Altivec registers. On those OSs, we
1685 don't touch the MASK_POWERPC64 or MASK_ALTIVEC settings; if the user wants
1686 either, the user must explicitly specify them and we won't interfere with
1687 the user's specification. */
1689 enum {
1690 POWER_MASKS = MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING,
1691 POWERPC_MASKS = (POWERPC_BASE_MASK | MASK_PPC_GPOPT | MASK_STRICT_ALIGN
1692 | MASK_PPC_GFXOPT | MASK_POWERPC64 | MASK_ALTIVEC
1693 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_MULHW
1694 | MASK_DLMZB | MASK_CMPB | MASK_MFPGPR | MASK_DFP
1695 | MASK_POPCNTD | MASK_VSX | MASK_ISEL | MASK_NO_UPDATE
1696 | MASK_RECIP_PRECISION)
1699 /* Masks for instructions set at various powerpc ISAs. */
1700 enum {
1701 ISA_2_1_MASKS = MASK_MFCRF,
1702 ISA_2_2_MASKS = (ISA_2_1_MASKS | MASK_POPCNTB),
1703 ISA_2_4_MASKS = (ISA_2_2_MASKS | MASK_FPRND),
1705 /* For ISA 2.05, do not add MFPGPR, since it isn't in ISA 2.06, and don't add
1706 ALTIVEC, since in general it isn't a win on power6. In ISA 2.04, fsel,
1707 fre, fsqrt, etc. were no longer documented as optional. Group masks by
1708 server and embedded. */
1709 ISA_2_5_MASKS_EMBEDDED = (ISA_2_2_MASKS | MASK_CMPB | MASK_RECIP_PRECISION
1710 | MASK_PPC_GFXOPT | MASK_PPC_GPOPT),
1711 ISA_2_5_MASKS_SERVER = (ISA_2_5_MASKS_EMBEDDED | MASK_DFP),
1713 /* For ISA 2.06, don't add ISEL, since in general it isn't a win, but
1714 altivec is a win so enable it. */
1715 ISA_2_6_MASKS_EMBEDDED = (ISA_2_5_MASKS_EMBEDDED | MASK_POPCNTD),
1716 ISA_2_6_MASKS_SERVER = (ISA_2_5_MASKS_SERVER | MASK_POPCNTD | MASK_ALTIVEC
1717 | MASK_VSX)
1720 /* This table occasionally claims that a processor does not support a
1721 particular feature even though it does, but the feature is slower than the
1722 alternative. Thus, it shouldn't be relied on as a complete description of
1723 the processor's support.
1725 Please keep this list in order, and don't forget to update the documentation
1726 in invoke.texi when adding a new processor or flag. */
1728 struct rs6000_ptt
1730 const char *const name; /* Canonical processor name. */
1731 const enum processor_type processor; /* Processor type enum value. */
1732 const int target_enable; /* Target flags to enable. */
1735 static struct rs6000_ptt const processor_target_table[] =
1737 {"401", PROCESSOR_PPC403, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
1738 {"403", PROCESSOR_PPC403,
1739 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_STRICT_ALIGN},
1740 {"405", PROCESSOR_PPC405,
1741 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
1742 {"405fp", PROCESSOR_PPC405,
1743 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
1744 {"440", PROCESSOR_PPC440,
1745 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
1746 {"440fp", PROCESSOR_PPC440,
1747 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
1748 {"464", PROCESSOR_PPC440,
1749 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
1750 {"464fp", PROCESSOR_PPC440,
1751 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
1752 {"476", PROCESSOR_PPC476,
1753 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_PPC_GFXOPT | MASK_MFCRF
1754 | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_MULHW | MASK_DLMZB},
1755 {"476fp", PROCESSOR_PPC476,
1756 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_MFCRF | MASK_POPCNTB
1757 | MASK_FPRND | MASK_CMPB | MASK_MULHW | MASK_DLMZB},
1758 {"505", PROCESSOR_MPCCORE, POWERPC_BASE_MASK},
1759 {"601", PROCESSOR_PPC601,
1760 MASK_POWER | POWERPC_BASE_MASK | MASK_MULTIPLE | MASK_STRING},
1761 {"602", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1762 {"603", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1763 {"603e", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1764 {"604", PROCESSOR_PPC604, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1765 {"604e", PROCESSOR_PPC604e, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1766 {"620", PROCESSOR_PPC620,
1767 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
1768 {"630", PROCESSOR_PPC630,
1769 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
1770 {"740", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1771 {"7400", PROCESSOR_PPC7400, POWERPC_7400_MASK},
1772 {"7450", PROCESSOR_PPC7450, POWERPC_7400_MASK},
1773 {"750", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1774 {"801", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
1775 {"821", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
1776 {"823", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
1777 {"8540", PROCESSOR_PPC8540, POWERPC_BASE_MASK | MASK_STRICT_ALIGN
1778 | MASK_ISEL},
1779 /* 8548 has a dummy entry for now. */
1780 {"8548", PROCESSOR_PPC8540, POWERPC_BASE_MASK | MASK_STRICT_ALIGN
1781 | MASK_ISEL},
1782 {"a2", PROCESSOR_PPCA2,
1783 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64 | MASK_POPCNTB
1784 | MASK_CMPB | MASK_NO_UPDATE },
1785 {"e300c2", PROCESSOR_PPCE300C2, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
1786 {"e300c3", PROCESSOR_PPCE300C3, POWERPC_BASE_MASK},
1787 {"e500mc", PROCESSOR_PPCE500MC, POWERPC_BASE_MASK | MASK_PPC_GFXOPT
1788 | MASK_ISEL},
1789 {"e500mc64", PROCESSOR_PPCE500MC64, POWERPC_BASE_MASK | MASK_POWERPC64
1790 | MASK_PPC_GFXOPT | MASK_ISEL},
1791 {"860", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
1792 {"970", PROCESSOR_POWER4,
1793 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
1794 {"cell", PROCESSOR_CELL,
1795 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
1796 {"common", PROCESSOR_COMMON, MASK_NEW_MNEMONICS},
1797 {"ec603e", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
1798 {"G3", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1799 {"G4", PROCESSOR_PPC7450, POWERPC_7400_MASK},
1800 {"G5", PROCESSOR_POWER4,
1801 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
1802 {"titan", PROCESSOR_TITAN,
1803 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
1804 {"power", PROCESSOR_POWER, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
1805 {"power2", PROCESSOR_POWER,
1806 MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING},
1807 {"power3", PROCESSOR_PPC630,
1808 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
1809 {"power4", PROCESSOR_POWER4,
1810 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
1811 | MASK_MFCRF},
1812 {"power5", PROCESSOR_POWER5,
1813 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
1814 | MASK_MFCRF | MASK_POPCNTB},
1815 {"power5+", PROCESSOR_POWER5,
1816 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
1817 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND},
1818 {"power6", PROCESSOR_POWER6,
1819 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
1820 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP
1821 | MASK_RECIP_PRECISION},
1822 {"power6x", PROCESSOR_POWER6,
1823 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
1824 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP
1825 | MASK_MFPGPR | MASK_RECIP_PRECISION},
1826 {"power7", PROCESSOR_POWER7, /* Don't add MASK_ISEL by default */
1827 POWERPC_7400_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_MFCRF
1828 | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP | MASK_POPCNTD
1829 | MASK_VSX | MASK_RECIP_PRECISION},
1830 {"powerpc", PROCESSOR_POWERPC, POWERPC_BASE_MASK},
1831 {"powerpc64", PROCESSOR_POWERPC64,
1832 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
1833 {"rios", PROCESSOR_RIOS1, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
1834 {"rios1", PROCESSOR_RIOS1, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
1835 {"rios2", PROCESSOR_RIOS2,
1836 MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING},
1837 {"rsc", PROCESSOR_PPC601, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
1838 {"rsc1", PROCESSOR_PPC601, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
1839 {"rs64", PROCESSOR_RS64A,
1840 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64}
1843 /* Look up a processor name for -mcpu=xxx and -mtune=xxx. Return -1 if the
1844 name is invalid. */
1846 static int
1847 rs6000_cpu_name_lookup (const char *name)
1849 size_t i;
1851 if (name != NULL)
1853 for (i = 0; i < ARRAY_SIZE (processor_target_table); i++)
1854 if (! strcmp (name, processor_target_table[i].name))
1855 return (int)i;
1858 return -1;
1862 /* Return number of consecutive hard regs needed starting at reg REGNO
1863 to hold something of mode MODE.
1864 This is ordinarily the length in words of a value of mode MODE
1865 but can be less for certain modes in special long registers.
1867 For the SPE, GPRs are 64 bits but only 32 bits are visible in
1868 scalar instructions. The upper 32 bits are only available to the
1869 SIMD instructions.
1871 POWER and PowerPC GPRs hold 32 bits worth;
1872 PowerPC64 GPRs and FPRs point register holds 64 bits worth. */
1874 static int
1875 rs6000_hard_regno_nregs_internal (int regno, enum machine_mode mode)
1877 unsigned HOST_WIDE_INT reg_size;
1879 if (FP_REGNO_P (regno))
1880 reg_size = (VECTOR_MEM_VSX_P (mode)
1881 ? UNITS_PER_VSX_WORD
1882 : UNITS_PER_FP_WORD);
1884 else if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode))
1885 reg_size = UNITS_PER_SPE_WORD;
1887 else if (ALTIVEC_REGNO_P (regno))
1888 reg_size = UNITS_PER_ALTIVEC_WORD;
1890 /* The value returned for SCmode in the E500 double case is 2 for
1891 ABI compatibility; storing an SCmode value in a single register
1892 would require function_arg and rs6000_spe_function_arg to handle
1893 SCmode so as to pass the value correctly in a pair of
1894 registers. */
1895 else if (TARGET_E500_DOUBLE && FLOAT_MODE_P (mode) && mode != SCmode
1896 && !DECIMAL_FLOAT_MODE_P (mode))
1897 reg_size = UNITS_PER_FP_WORD;
1899 else
1900 reg_size = UNITS_PER_WORD;
1902 return (GET_MODE_SIZE (mode) + reg_size - 1) / reg_size;
1905 /* Value is 1 if hard register REGNO can hold a value of machine-mode
1906 MODE. */
1907 static int
1908 rs6000_hard_regno_mode_ok (int regno, enum machine_mode mode)
1910 int last_regno = regno + rs6000_hard_regno_nregs[mode][regno] - 1;
1912 /* VSX registers that overlap the FPR registers are larger than for non-VSX
1913 implementations. Don't allow an item to be split between a FP register
1914 and an Altivec register. */
1915 if (VECTOR_MEM_VSX_P (mode))
1917 if (FP_REGNO_P (regno))
1918 return FP_REGNO_P (last_regno);
1920 if (ALTIVEC_REGNO_P (regno))
1921 return ALTIVEC_REGNO_P (last_regno);
1924 /* The GPRs can hold any mode, but values bigger than one register
1925 cannot go past R31. */
1926 if (INT_REGNO_P (regno))
1927 return INT_REGNO_P (last_regno);
1929 /* The float registers (except for VSX vector modes) can only hold floating
1930 modes and DImode. This excludes the 32-bit decimal float mode for
1931 now. */
1932 if (FP_REGNO_P (regno))
1934 if (SCALAR_FLOAT_MODE_P (mode)
1935 && (mode != TDmode || (regno % 2) == 0)
1936 && FP_REGNO_P (last_regno))
1937 return 1;
1939 if (GET_MODE_CLASS (mode) == MODE_INT
1940 && GET_MODE_SIZE (mode) == UNITS_PER_FP_WORD)
1941 return 1;
1943 if (PAIRED_SIMD_REGNO_P (regno) && TARGET_PAIRED_FLOAT
1944 && PAIRED_VECTOR_MODE (mode))
1945 return 1;
1947 return 0;
1950 /* The CR register can only hold CC modes. */
1951 if (CR_REGNO_P (regno))
1952 return GET_MODE_CLASS (mode) == MODE_CC;
1954 if (CA_REGNO_P (regno))
1955 return mode == BImode;
1957 /* AltiVec only in AldyVec registers. */
1958 if (ALTIVEC_REGNO_P (regno))
1959 return VECTOR_MEM_ALTIVEC_OR_VSX_P (mode);
1961 /* ...but GPRs can hold SIMD data on the SPE in one register. */
1962 if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode))
1963 return 1;
1965 /* We cannot put TImode anywhere except general register and it must be able
1966 to fit within the register set. In the future, allow TImode in the
1967 Altivec or VSX registers. */
1969 return GET_MODE_SIZE (mode) <= UNITS_PER_WORD;
1972 /* Print interesting facts about registers. */
1973 static void
1974 rs6000_debug_reg_print (int first_regno, int last_regno, const char *reg_name)
1976 int r, m;
1978 for (r = first_regno; r <= last_regno; ++r)
1980 const char *comma = "";
1981 int len;
1983 if (first_regno == last_regno)
1984 fprintf (stderr, "%s:\t", reg_name);
1985 else
1986 fprintf (stderr, "%s%d:\t", reg_name, r - first_regno);
1988 len = 8;
1989 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1990 if (rs6000_hard_regno_mode_ok_p[m][r] && rs6000_hard_regno_nregs[m][r])
1992 if (len > 70)
1994 fprintf (stderr, ",\n\t");
1995 len = 8;
1996 comma = "";
1999 if (rs6000_hard_regno_nregs[m][r] > 1)
2000 len += fprintf (stderr, "%s%s/%d", comma, GET_MODE_NAME (m),
2001 rs6000_hard_regno_nregs[m][r]);
2002 else
2003 len += fprintf (stderr, "%s%s", comma, GET_MODE_NAME (m));
2005 comma = ", ";
2008 if (call_used_regs[r])
2010 if (len > 70)
2012 fprintf (stderr, ",\n\t");
2013 len = 8;
2014 comma = "";
2017 len += fprintf (stderr, "%s%s", comma, "call-used");
2018 comma = ", ";
2021 if (fixed_regs[r])
2023 if (len > 70)
2025 fprintf (stderr, ",\n\t");
2026 len = 8;
2027 comma = "";
2030 len += fprintf (stderr, "%s%s", comma, "fixed");
2031 comma = ", ";
2034 if (len > 70)
2036 fprintf (stderr, ",\n\t");
2037 comma = "";
2040 fprintf (stderr, "%sregno = %d\n", comma, r);
2044 #define DEBUG_FMT_D "%-32s= %d\n"
2045 #define DEBUG_FMT_S "%-32s= %s\n"
2047 /* Print various interesting information with -mdebug=reg. */
2048 static void
2049 rs6000_debug_reg_global (void)
2051 static const char *const tf[2] = { "false", "true" };
2052 const char *nl = (const char *)0;
2053 int m;
2054 char costly_num[20];
2055 char nop_num[20];
2056 const char *costly_str;
2057 const char *nop_str;
2058 const char *trace_str;
2059 const char *abi_str;
2060 const char *cmodel_str;
2062 /* Map enum rs6000_vector to string. */
2063 static const char *rs6000_debug_vector_unit[] = {
2064 "none",
2065 "altivec",
2066 "vsx",
2067 "paired",
2068 "spe",
2069 "other"
2072 fprintf (stderr, "Register information: (last virtual reg = %d)\n",
2073 LAST_VIRTUAL_REGISTER);
2074 rs6000_debug_reg_print (0, 31, "gr");
2075 rs6000_debug_reg_print (32, 63, "fp");
2076 rs6000_debug_reg_print (FIRST_ALTIVEC_REGNO,
2077 LAST_ALTIVEC_REGNO,
2078 "vs");
2079 rs6000_debug_reg_print (LR_REGNO, LR_REGNO, "lr");
2080 rs6000_debug_reg_print (CTR_REGNO, CTR_REGNO, "ctr");
2081 rs6000_debug_reg_print (CR0_REGNO, CR7_REGNO, "cr");
2082 rs6000_debug_reg_print (MQ_REGNO, MQ_REGNO, "mq");
2083 rs6000_debug_reg_print (CA_REGNO, CA_REGNO, "ca");
2084 rs6000_debug_reg_print (VRSAVE_REGNO, VRSAVE_REGNO, "vrsave");
2085 rs6000_debug_reg_print (VSCR_REGNO, VSCR_REGNO, "vscr");
2086 rs6000_debug_reg_print (SPE_ACC_REGNO, SPE_ACC_REGNO, "spe_a");
2087 rs6000_debug_reg_print (SPEFSCR_REGNO, SPEFSCR_REGNO, "spe_f");
2089 fprintf (stderr,
2090 "\n"
2091 "d reg_class = %s\n"
2092 "f reg_class = %s\n"
2093 "v reg_class = %s\n"
2094 "wa reg_class = %s\n"
2095 "wd reg_class = %s\n"
2096 "wf reg_class = %s\n"
2097 "ws reg_class = %s\n\n",
2098 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_d]],
2099 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_f]],
2100 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_v]],
2101 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wa]],
2102 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wd]],
2103 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wf]],
2104 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_ws]]);
2106 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2107 if (rs6000_vector_unit[m] || rs6000_vector_mem[m])
2109 nl = "\n";
2110 fprintf (stderr, "Vector mode: %-5s arithmetic: %-8s move: %-8s\n",
2111 GET_MODE_NAME (m),
2112 rs6000_debug_vector_unit[ rs6000_vector_unit[m] ],
2113 rs6000_debug_vector_unit[ rs6000_vector_mem[m] ]);
2116 if (nl)
2117 fputs (nl, stderr);
2119 if (rs6000_recip_control)
2121 fprintf (stderr, "\nReciprocal mask = 0x%x\n", rs6000_recip_control);
2123 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2124 if (rs6000_recip_bits[m])
2126 fprintf (stderr,
2127 "Reciprocal estimate mode: %-5s divide: %s rsqrt: %s\n",
2128 GET_MODE_NAME (m),
2129 (RS6000_RECIP_AUTO_RE_P (m)
2130 ? "auto"
2131 : (RS6000_RECIP_HAVE_RE_P (m) ? "have" : "none")),
2132 (RS6000_RECIP_AUTO_RSQRTE_P (m)
2133 ? "auto"
2134 : (RS6000_RECIP_HAVE_RSQRTE_P (m) ? "have" : "none")));
2137 fputs ("\n", stderr);
2140 if (rs6000_cpu_index >= 0)
2141 fprintf (stderr, DEBUG_FMT_S, "cpu",
2142 processor_target_table[rs6000_cpu_index].name);
2144 if (rs6000_tune_index >= 0)
2145 fprintf (stderr, DEBUG_FMT_S, "tune",
2146 processor_target_table[rs6000_tune_index].name);
2148 switch (rs6000_sched_costly_dep)
2150 case max_dep_latency:
2151 costly_str = "max_dep_latency";
2152 break;
2154 case no_dep_costly:
2155 costly_str = "no_dep_costly";
2156 break;
2158 case all_deps_costly:
2159 costly_str = "all_deps_costly";
2160 break;
2162 case true_store_to_load_dep_costly:
2163 costly_str = "true_store_to_load_dep_costly";
2164 break;
2166 case store_to_load_dep_costly:
2167 costly_str = "store_to_load_dep_costly";
2168 break;
2170 default:
2171 costly_str = costly_num;
2172 sprintf (costly_num, "%d", (int)rs6000_sched_costly_dep);
2173 break;
2176 fprintf (stderr, DEBUG_FMT_S, "sched_costly_dep", costly_str);
2178 switch (rs6000_sched_insert_nops)
2180 case sched_finish_regroup_exact:
2181 nop_str = "sched_finish_regroup_exact";
2182 break;
2184 case sched_finish_pad_groups:
2185 nop_str = "sched_finish_pad_groups";
2186 break;
2188 case sched_finish_none:
2189 nop_str = "sched_finish_none";
2190 break;
2192 default:
2193 nop_str = nop_num;
2194 sprintf (nop_num, "%d", (int)rs6000_sched_insert_nops);
2195 break;
2198 fprintf (stderr, DEBUG_FMT_S, "sched_insert_nops", nop_str);
2200 switch (rs6000_sdata)
2202 default:
2203 case SDATA_NONE:
2204 break;
2206 case SDATA_DATA:
2207 fprintf (stderr, DEBUG_FMT_S, "sdata", "data");
2208 break;
2210 case SDATA_SYSV:
2211 fprintf (stderr, DEBUG_FMT_S, "sdata", "sysv");
2212 break;
2214 case SDATA_EABI:
2215 fprintf (stderr, DEBUG_FMT_S, "sdata", "eabi");
2216 break;
2220 switch (rs6000_traceback)
2222 case traceback_default: trace_str = "default"; break;
2223 case traceback_none: trace_str = "none"; break;
2224 case traceback_part: trace_str = "part"; break;
2225 case traceback_full: trace_str = "full"; break;
2226 default: trace_str = "unknown"; break;
2229 fprintf (stderr, DEBUG_FMT_S, "traceback", trace_str);
2231 switch (rs6000_current_cmodel)
2233 case CMODEL_SMALL: cmodel_str = "small"; break;
2234 case CMODEL_MEDIUM: cmodel_str = "medium"; break;
2235 case CMODEL_LARGE: cmodel_str = "large"; break;
2236 default: cmodel_str = "unknown"; break;
2239 fprintf (stderr, DEBUG_FMT_S, "cmodel", cmodel_str);
2241 switch (rs6000_current_abi)
2243 case ABI_NONE: abi_str = "none"; break;
2244 case ABI_AIX: abi_str = "aix"; break;
2245 case ABI_V4: abi_str = "V4"; break;
2246 case ABI_DARWIN: abi_str = "darwin"; break;
2247 default: abi_str = "unknown"; break;
2250 fprintf (stderr, DEBUG_FMT_S, "abi", abi_str);
2252 if (rs6000_altivec_abi)
2253 fprintf (stderr, DEBUG_FMT_S, "altivec_abi", "true");
2255 if (rs6000_spe_abi)
2256 fprintf (stderr, DEBUG_FMT_S, "spe_abi", "true");
2258 if (rs6000_darwin64_abi)
2259 fprintf (stderr, DEBUG_FMT_S, "darwin64_abi", "true");
2261 if (rs6000_float_gprs)
2262 fprintf (stderr, DEBUG_FMT_S, "float_gprs", "true");
2264 fprintf (stderr, DEBUG_FMT_S, "always_hint", tf[!!rs6000_always_hint]);
2265 fprintf (stderr, DEBUG_FMT_S, "align_branch",
2266 tf[!!rs6000_align_branch_targets]);
2267 fprintf (stderr, DEBUG_FMT_D, "tls_size", rs6000_tls_size);
2268 fprintf (stderr, DEBUG_FMT_D, "long_double_size",
2269 rs6000_long_double_type_size);
2270 fprintf (stderr, DEBUG_FMT_D, "sched_restricted_insns_priority",
2271 (int)rs6000_sched_restricted_insns_priority);
2274 /* Initialize the various global tables that are based on register size. */
2275 static void
2276 rs6000_init_hard_regno_mode_ok (bool global_init_p)
2278 int r, m, c;
2279 int align64;
2280 int align32;
2282 /* Precalculate REGNO_REG_CLASS. */
2283 rs6000_regno_regclass[0] = GENERAL_REGS;
2284 for (r = 1; r < 32; ++r)
2285 rs6000_regno_regclass[r] = BASE_REGS;
2287 for (r = 32; r < 64; ++r)
2288 rs6000_regno_regclass[r] = FLOAT_REGS;
2290 for (r = 64; r < FIRST_PSEUDO_REGISTER; ++r)
2291 rs6000_regno_regclass[r] = NO_REGS;
2293 for (r = FIRST_ALTIVEC_REGNO; r <= LAST_ALTIVEC_REGNO; ++r)
2294 rs6000_regno_regclass[r] = ALTIVEC_REGS;
2296 rs6000_regno_regclass[CR0_REGNO] = CR0_REGS;
2297 for (r = CR1_REGNO; r <= CR7_REGNO; ++r)
2298 rs6000_regno_regclass[r] = CR_REGS;
2300 rs6000_regno_regclass[MQ_REGNO] = MQ_REGS;
2301 rs6000_regno_regclass[LR_REGNO] = LINK_REGS;
2302 rs6000_regno_regclass[CTR_REGNO] = CTR_REGS;
2303 rs6000_regno_regclass[CA_REGNO] = CA_REGS;
2304 rs6000_regno_regclass[VRSAVE_REGNO] = VRSAVE_REGS;
2305 rs6000_regno_regclass[VSCR_REGNO] = VRSAVE_REGS;
2306 rs6000_regno_regclass[SPE_ACC_REGNO] = SPE_ACC_REGS;
2307 rs6000_regno_regclass[SPEFSCR_REGNO] = SPEFSCR_REGS;
2308 rs6000_regno_regclass[ARG_POINTER_REGNUM] = BASE_REGS;
2309 rs6000_regno_regclass[FRAME_POINTER_REGNUM] = BASE_REGS;
2311 /* Precalculate vector information, this must be set up before the
2312 rs6000_hard_regno_nregs_internal below. */
2313 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2315 rs6000_vector_unit[m] = rs6000_vector_mem[m] = VECTOR_NONE;
2316 rs6000_vector_reload[m][0] = CODE_FOR_nothing;
2317 rs6000_vector_reload[m][1] = CODE_FOR_nothing;
2320 for (c = 0; c < (int)(int)RS6000_CONSTRAINT_MAX; c++)
2321 rs6000_constraints[c] = NO_REGS;
2323 /* The VSX hardware allows native alignment for vectors, but control whether the compiler
2324 believes it can use native alignment or still uses 128-bit alignment. */
2325 if (TARGET_VSX && !TARGET_VSX_ALIGN_128)
2327 align64 = 64;
2328 align32 = 32;
2330 else
2332 align64 = 128;
2333 align32 = 128;
2336 /* V2DF mode, VSX only. */
2337 if (TARGET_VSX)
2339 rs6000_vector_unit[V2DFmode] = VECTOR_VSX;
2340 rs6000_vector_mem[V2DFmode] = VECTOR_VSX;
2341 rs6000_vector_align[V2DFmode] = align64;
2344 /* V4SF mode, either VSX or Altivec. */
2345 if (TARGET_VSX)
2347 rs6000_vector_unit[V4SFmode] = VECTOR_VSX;
2348 rs6000_vector_mem[V4SFmode] = VECTOR_VSX;
2349 rs6000_vector_align[V4SFmode] = align32;
2351 else if (TARGET_ALTIVEC)
2353 rs6000_vector_unit[V4SFmode] = VECTOR_ALTIVEC;
2354 rs6000_vector_mem[V4SFmode] = VECTOR_ALTIVEC;
2355 rs6000_vector_align[V4SFmode] = align32;
2358 /* V16QImode, V8HImode, V4SImode are Altivec only, but possibly do VSX loads
2359 and stores. */
2360 if (TARGET_ALTIVEC)
2362 rs6000_vector_unit[V4SImode] = VECTOR_ALTIVEC;
2363 rs6000_vector_unit[V8HImode] = VECTOR_ALTIVEC;
2364 rs6000_vector_unit[V16QImode] = VECTOR_ALTIVEC;
2365 rs6000_vector_align[V4SImode] = align32;
2366 rs6000_vector_align[V8HImode] = align32;
2367 rs6000_vector_align[V16QImode] = align32;
2369 if (TARGET_VSX)
2371 rs6000_vector_mem[V4SImode] = VECTOR_VSX;
2372 rs6000_vector_mem[V8HImode] = VECTOR_VSX;
2373 rs6000_vector_mem[V16QImode] = VECTOR_VSX;
2375 else
2377 rs6000_vector_mem[V4SImode] = VECTOR_ALTIVEC;
2378 rs6000_vector_mem[V8HImode] = VECTOR_ALTIVEC;
2379 rs6000_vector_mem[V16QImode] = VECTOR_ALTIVEC;
2383 /* V2DImode, only allow under VSX, which can do V2DI insert/splat/extract.
2384 Altivec doesn't have 64-bit support. */
2385 if (TARGET_VSX)
2387 rs6000_vector_mem[V2DImode] = VECTOR_VSX;
2388 rs6000_vector_unit[V2DImode] = VECTOR_NONE;
2389 rs6000_vector_align[V2DImode] = align64;
2392 /* DFmode, see if we want to use the VSX unit. */
2393 if (TARGET_VSX && TARGET_VSX_SCALAR_DOUBLE)
2395 rs6000_vector_unit[DFmode] = VECTOR_VSX;
2396 rs6000_vector_mem[DFmode]
2397 = (TARGET_VSX_SCALAR_MEMORY ? VECTOR_VSX : VECTOR_NONE);
2398 rs6000_vector_align[DFmode] = align64;
2401 /* TODO add SPE and paired floating point vector support. */
2403 /* Register class constaints for the constraints that depend on compile
2404 switches. */
2405 if (TARGET_HARD_FLOAT && TARGET_FPRS)
2406 rs6000_constraints[RS6000_CONSTRAINT_f] = FLOAT_REGS;
2408 if (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
2409 rs6000_constraints[RS6000_CONSTRAINT_d] = FLOAT_REGS;
2411 if (TARGET_VSX)
2413 /* At present, we just use VSX_REGS, but we have different constraints
2414 based on the use, in case we want to fine tune the default register
2415 class used. wa = any VSX register, wf = register class to use for
2416 V4SF, wd = register class to use for V2DF, and ws = register classs to
2417 use for DF scalars. */
2418 rs6000_constraints[RS6000_CONSTRAINT_wa] = VSX_REGS;
2419 rs6000_constraints[RS6000_CONSTRAINT_wf] = VSX_REGS;
2420 rs6000_constraints[RS6000_CONSTRAINT_wd] = VSX_REGS;
2421 rs6000_constraints[RS6000_CONSTRAINT_ws] = (TARGET_VSX_SCALAR_MEMORY
2422 ? VSX_REGS
2423 : FLOAT_REGS);
2426 if (TARGET_ALTIVEC)
2427 rs6000_constraints[RS6000_CONSTRAINT_v] = ALTIVEC_REGS;
2429 /* Set up the reload helper functions. */
2430 if (TARGET_VSX || TARGET_ALTIVEC)
2432 if (TARGET_64BIT)
2434 rs6000_vector_reload[V16QImode][0] = CODE_FOR_reload_v16qi_di_store;
2435 rs6000_vector_reload[V16QImode][1] = CODE_FOR_reload_v16qi_di_load;
2436 rs6000_vector_reload[V8HImode][0] = CODE_FOR_reload_v8hi_di_store;
2437 rs6000_vector_reload[V8HImode][1] = CODE_FOR_reload_v8hi_di_load;
2438 rs6000_vector_reload[V4SImode][0] = CODE_FOR_reload_v4si_di_store;
2439 rs6000_vector_reload[V4SImode][1] = CODE_FOR_reload_v4si_di_load;
2440 rs6000_vector_reload[V2DImode][0] = CODE_FOR_reload_v2di_di_store;
2441 rs6000_vector_reload[V2DImode][1] = CODE_FOR_reload_v2di_di_load;
2442 rs6000_vector_reload[V4SFmode][0] = CODE_FOR_reload_v4sf_di_store;
2443 rs6000_vector_reload[V4SFmode][1] = CODE_FOR_reload_v4sf_di_load;
2444 rs6000_vector_reload[V2DFmode][0] = CODE_FOR_reload_v2df_di_store;
2445 rs6000_vector_reload[V2DFmode][1] = CODE_FOR_reload_v2df_di_load;
2447 else
2449 rs6000_vector_reload[V16QImode][0] = CODE_FOR_reload_v16qi_si_store;
2450 rs6000_vector_reload[V16QImode][1] = CODE_FOR_reload_v16qi_si_load;
2451 rs6000_vector_reload[V8HImode][0] = CODE_FOR_reload_v8hi_si_store;
2452 rs6000_vector_reload[V8HImode][1] = CODE_FOR_reload_v8hi_si_load;
2453 rs6000_vector_reload[V4SImode][0] = CODE_FOR_reload_v4si_si_store;
2454 rs6000_vector_reload[V4SImode][1] = CODE_FOR_reload_v4si_si_load;
2455 rs6000_vector_reload[V2DImode][0] = CODE_FOR_reload_v2di_si_store;
2456 rs6000_vector_reload[V2DImode][1] = CODE_FOR_reload_v2di_si_load;
2457 rs6000_vector_reload[V4SFmode][0] = CODE_FOR_reload_v4sf_si_store;
2458 rs6000_vector_reload[V4SFmode][1] = CODE_FOR_reload_v4sf_si_load;
2459 rs6000_vector_reload[V2DFmode][0] = CODE_FOR_reload_v2df_si_store;
2460 rs6000_vector_reload[V2DFmode][1] = CODE_FOR_reload_v2df_si_load;
2464 /* Precalculate HARD_REGNO_NREGS. */
2465 for (r = 0; r < FIRST_PSEUDO_REGISTER; ++r)
2466 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2467 rs6000_hard_regno_nregs[m][r]
2468 = rs6000_hard_regno_nregs_internal (r, (enum machine_mode)m);
2470 /* Precalculate HARD_REGNO_MODE_OK. */
2471 for (r = 0; r < FIRST_PSEUDO_REGISTER; ++r)
2472 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2473 if (rs6000_hard_regno_mode_ok (r, (enum machine_mode)m))
2474 rs6000_hard_regno_mode_ok_p[m][r] = true;
2476 /* Precalculate CLASS_MAX_NREGS sizes. */
2477 for (c = 0; c < LIM_REG_CLASSES; ++c)
2479 int reg_size;
2481 if (TARGET_VSX && VSX_REG_CLASS_P (c))
2482 reg_size = UNITS_PER_VSX_WORD;
2484 else if (c == ALTIVEC_REGS)
2485 reg_size = UNITS_PER_ALTIVEC_WORD;
2487 else if (c == FLOAT_REGS)
2488 reg_size = UNITS_PER_FP_WORD;
2490 else
2491 reg_size = UNITS_PER_WORD;
2493 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2494 rs6000_class_max_nregs[m][c]
2495 = (GET_MODE_SIZE (m) + reg_size - 1) / reg_size;
2498 if (TARGET_E500_DOUBLE)
2499 rs6000_class_max_nregs[DFmode][GENERAL_REGS] = 1;
2501 /* Calculate which modes to automatically generate code to use a the
2502 reciprocal divide and square root instructions. In the future, possibly
2503 automatically generate the instructions even if the user did not specify
2504 -mrecip. The older machines double precision reciprocal sqrt estimate is
2505 not accurate enough. */
2506 memset (rs6000_recip_bits, 0, sizeof (rs6000_recip_bits));
2507 if (TARGET_FRES)
2508 rs6000_recip_bits[SFmode] = RS6000_RECIP_MASK_HAVE_RE;
2509 if (TARGET_FRE)
2510 rs6000_recip_bits[DFmode] = RS6000_RECIP_MASK_HAVE_RE;
2511 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode))
2512 rs6000_recip_bits[V4SFmode] = RS6000_RECIP_MASK_HAVE_RE;
2513 if (VECTOR_UNIT_VSX_P (V2DFmode))
2514 rs6000_recip_bits[V2DFmode] = RS6000_RECIP_MASK_HAVE_RE;
2516 if (TARGET_FRSQRTES)
2517 rs6000_recip_bits[SFmode] |= RS6000_RECIP_MASK_HAVE_RSQRTE;
2518 if (TARGET_FRSQRTE)
2519 rs6000_recip_bits[DFmode] |= RS6000_RECIP_MASK_HAVE_RSQRTE;
2520 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode))
2521 rs6000_recip_bits[V4SFmode] |= RS6000_RECIP_MASK_HAVE_RSQRTE;
2522 if (VECTOR_UNIT_VSX_P (V2DFmode))
2523 rs6000_recip_bits[V2DFmode] |= RS6000_RECIP_MASK_HAVE_RSQRTE;
2525 if (rs6000_recip_control)
2527 if (!flag_finite_math_only)
2528 warning (0, "-mrecip requires -ffinite-math or -ffast-math");
2529 if (flag_trapping_math)
2530 warning (0, "-mrecip requires -fno-trapping-math or -ffast-math");
2531 if (!flag_reciprocal_math)
2532 warning (0, "-mrecip requires -freciprocal-math or -ffast-math");
2533 if (flag_finite_math_only && !flag_trapping_math && flag_reciprocal_math)
2535 if (RS6000_RECIP_HAVE_RE_P (SFmode)
2536 && (rs6000_recip_control & RECIP_SF_DIV) != 0)
2537 rs6000_recip_bits[SFmode] |= RS6000_RECIP_MASK_AUTO_RE;
2539 if (RS6000_RECIP_HAVE_RE_P (DFmode)
2540 && (rs6000_recip_control & RECIP_DF_DIV) != 0)
2541 rs6000_recip_bits[DFmode] |= RS6000_RECIP_MASK_AUTO_RE;
2543 if (RS6000_RECIP_HAVE_RE_P (V4SFmode)
2544 && (rs6000_recip_control & RECIP_V4SF_DIV) != 0)
2545 rs6000_recip_bits[V4SFmode] |= RS6000_RECIP_MASK_AUTO_RE;
2547 if (RS6000_RECIP_HAVE_RE_P (V2DFmode)
2548 && (rs6000_recip_control & RECIP_V2DF_DIV) != 0)
2549 rs6000_recip_bits[V2DFmode] |= RS6000_RECIP_MASK_AUTO_RE;
2551 if (RS6000_RECIP_HAVE_RSQRTE_P (SFmode)
2552 && (rs6000_recip_control & RECIP_SF_RSQRT) != 0)
2553 rs6000_recip_bits[SFmode] |= RS6000_RECIP_MASK_AUTO_RSQRTE;
2555 if (RS6000_RECIP_HAVE_RSQRTE_P (DFmode)
2556 && (rs6000_recip_control & RECIP_DF_RSQRT) != 0)
2557 rs6000_recip_bits[DFmode] |= RS6000_RECIP_MASK_AUTO_RSQRTE;
2559 if (RS6000_RECIP_HAVE_RSQRTE_P (V4SFmode)
2560 && (rs6000_recip_control & RECIP_V4SF_RSQRT) != 0)
2561 rs6000_recip_bits[V4SFmode] |= RS6000_RECIP_MASK_AUTO_RSQRTE;
2563 if (RS6000_RECIP_HAVE_RSQRTE_P (V2DFmode)
2564 && (rs6000_recip_control & RECIP_V2DF_RSQRT) != 0)
2565 rs6000_recip_bits[V2DFmode] |= RS6000_RECIP_MASK_AUTO_RSQRTE;
2569 if (global_init_p || TARGET_DEBUG_TARGET)
2571 if (TARGET_DEBUG_REG)
2572 rs6000_debug_reg_global ();
2574 if (TARGET_DEBUG_COST || TARGET_DEBUG_REG)
2575 fprintf (stderr,
2576 "SImode variable mult cost = %d\n"
2577 "SImode constant mult cost = %d\n"
2578 "SImode short constant mult cost = %d\n"
2579 "DImode multipliciation cost = %d\n"
2580 "SImode division cost = %d\n"
2581 "DImode division cost = %d\n"
2582 "Simple fp operation cost = %d\n"
2583 "DFmode multiplication cost = %d\n"
2584 "SFmode division cost = %d\n"
2585 "DFmode division cost = %d\n"
2586 "cache line size = %d\n"
2587 "l1 cache size = %d\n"
2588 "l2 cache size = %d\n"
2589 "simultaneous prefetches = %d\n"
2590 "\n",
2591 rs6000_cost->mulsi,
2592 rs6000_cost->mulsi_const,
2593 rs6000_cost->mulsi_const9,
2594 rs6000_cost->muldi,
2595 rs6000_cost->divsi,
2596 rs6000_cost->divdi,
2597 rs6000_cost->fp,
2598 rs6000_cost->dmul,
2599 rs6000_cost->sdiv,
2600 rs6000_cost->ddiv,
2601 rs6000_cost->cache_line_size,
2602 rs6000_cost->l1_cache_size,
2603 rs6000_cost->l2_cache_size,
2604 rs6000_cost->simultaneous_prefetches);
2608 #if TARGET_MACHO
2609 /* The Darwin version of SUBTARGET_OVERRIDE_OPTIONS. */
2611 static void
2612 darwin_rs6000_override_options (void)
2614 /* The Darwin ABI always includes AltiVec, can't be (validly) turned
2615 off. */
2616 rs6000_altivec_abi = 1;
2617 TARGET_ALTIVEC_VRSAVE = 1;
2619 if (DEFAULT_ABI == ABI_DARWIN
2620 && TARGET_64BIT)
2621 darwin_one_byte_bool = 1;
2623 if (TARGET_64BIT && ! TARGET_POWERPC64)
2625 target_flags |= MASK_POWERPC64;
2626 warning (0, "-m64 requires PowerPC64 architecture, enabling");
2628 if (flag_mkernel)
2630 rs6000_default_long_calls = 1;
2631 target_flags |= MASK_SOFT_FLOAT;
2634 /* Make -m64 imply -maltivec. Darwin's 64-bit ABI includes
2635 Altivec. */
2636 if (!flag_mkernel && !flag_apple_kext
2637 && TARGET_64BIT
2638 && ! (target_flags_explicit & MASK_ALTIVEC))
2639 target_flags |= MASK_ALTIVEC;
2641 /* Unless the user (not the configurer) has explicitly overridden
2642 it with -mcpu=G3 or -mno-altivec, then 10.5+ targets default to
2643 G4 unless targetting the kernel. */
2644 if (!flag_mkernel
2645 && !flag_apple_kext
2646 && strverscmp (darwin_macosx_version_min, "10.5") >= 0
2647 && ! (target_flags_explicit & MASK_ALTIVEC)
2648 && ! rs6000_select[1].string)
2650 target_flags |= MASK_ALTIVEC;
2653 #endif
2655 /* If not otherwise specified by a target, make 'long double' equivalent to
2656 'double'. */
2658 #ifndef RS6000_DEFAULT_LONG_DOUBLE_SIZE
2659 #define RS6000_DEFAULT_LONG_DOUBLE_SIZE 64
2660 #endif
2662 /* Override command line options. Mostly we process the processor type and
2663 sometimes adjust other TARGET_ options. */
2665 static bool
2666 rs6000_option_override_internal (bool global_init_p)
2668 bool ret = true;
2669 const char *default_cpu = OPTION_TARGET_CPU_DEFAULT;
2670 int set_masks;
2671 int cpu_index;
2672 int tune_index;
2673 struct cl_target_option *main_target_opt
2674 = ((global_init_p || target_option_default_node == NULL)
2675 ? NULL : TREE_TARGET_OPTION (target_option_default_node));
2677 /* Numerous experiment shows that IRA based loop pressure
2678 calculation works better for RTL loop invariant motion on targets
2679 with enough (>= 32) registers. It is an expensive optimization.
2680 So it is on only for peak performance. */
2681 if (optimize >= 3 && global_init_p)
2682 flag_ira_loop_pressure = 1;
2684 /* Set the pointer size. */
2685 if (TARGET_64BIT)
2687 rs6000_pmode = (int)DImode;
2688 rs6000_pointer_size = 64;
2690 else
2692 rs6000_pmode = (int)SImode;
2693 rs6000_pointer_size = 32;
2696 set_masks = POWER_MASKS | POWERPC_MASKS | MASK_SOFT_FLOAT;
2697 #ifdef OS_MISSING_POWERPC64
2698 if (OS_MISSING_POWERPC64)
2699 set_masks &= ~MASK_POWERPC64;
2700 #endif
2701 #ifdef OS_MISSING_ALTIVEC
2702 if (OS_MISSING_ALTIVEC)
2703 set_masks &= ~MASK_ALTIVEC;
2704 #endif
2706 /* Don't override by the processor default if given explicitly. */
2707 set_masks &= ~target_flags_explicit;
2709 /* Identify the processor type. */
2710 if (!default_cpu)
2712 if (TARGET_POWERPC64)
2713 default_cpu = "powerpc64";
2714 else if (TARGET_POWERPC)
2715 default_cpu = "powerpc";
2718 /* Process the -mcpu=<xxx> and -mtune=<xxx> argument. If the user changed
2719 the cpu in a target attribute or pragma, but did not specify a tuning
2720 option, use the cpu for the tuning option rather than the option specified
2721 with -mtune on the command line. */
2722 if (rs6000_cpu_index > 0)
2723 cpu_index = rs6000_cpu_index;
2724 else if (main_target_opt != NULL && main_target_opt->x_rs6000_cpu_index > 0)
2725 rs6000_cpu_index = cpu_index = main_target_opt->x_rs6000_cpu_index;
2726 else
2727 rs6000_cpu_index = cpu_index = rs6000_cpu_name_lookup (default_cpu);
2729 if (rs6000_tune_index > 0)
2730 tune_index = rs6000_tune_index;
2731 else
2732 rs6000_tune_index = tune_index = cpu_index;
2734 if (cpu_index >= 0)
2736 target_flags &= ~set_masks;
2737 target_flags |= (processor_target_table[cpu_index].target_enable
2738 & set_masks);
2741 rs6000_cpu = ((tune_index >= 0)
2742 ? processor_target_table[tune_index].processor
2743 : (TARGET_POWERPC64
2744 ? PROCESSOR_DEFAULT64
2745 : PROCESSOR_DEFAULT));
2747 if (rs6000_cpu == PROCESSOR_PPCE300C2 || rs6000_cpu == PROCESSOR_PPCE300C3
2748 || rs6000_cpu == PROCESSOR_PPCE500MC || rs6000_cpu == PROCESSOR_PPCE500MC64)
2750 if (TARGET_ALTIVEC)
2751 error ("AltiVec not supported in this target");
2752 if (TARGET_SPE)
2753 error ("SPE not supported in this target");
2756 /* Disable Cell microcode if we are optimizing for the Cell
2757 and not optimizing for size. */
2758 if (rs6000_gen_cell_microcode == -1)
2759 rs6000_gen_cell_microcode = !(rs6000_cpu == PROCESSOR_CELL
2760 && !optimize_size);
2762 /* If we are optimizing big endian systems for space and it's OK to
2763 use instructions that would be microcoded on the Cell, use the
2764 load/store multiple and string instructions. */
2765 if (BYTES_BIG_ENDIAN && optimize_size && rs6000_gen_cell_microcode)
2766 target_flags |= ~target_flags_explicit & (MASK_MULTIPLE | MASK_STRING);
2768 /* Don't allow -mmultiple or -mstring on little endian systems
2769 unless the cpu is a 750, because the hardware doesn't support the
2770 instructions used in little endian mode, and causes an alignment
2771 trap. The 750 does not cause an alignment trap (except when the
2772 target is unaligned). */
2774 if (!BYTES_BIG_ENDIAN && rs6000_cpu != PROCESSOR_PPC750)
2776 if (TARGET_MULTIPLE)
2778 target_flags &= ~MASK_MULTIPLE;
2779 if ((target_flags_explicit & MASK_MULTIPLE) != 0)
2780 warning (0, "-mmultiple is not supported on little endian systems");
2783 if (TARGET_STRING)
2785 target_flags &= ~MASK_STRING;
2786 if ((target_flags_explicit & MASK_STRING) != 0)
2787 warning (0, "-mstring is not supported on little endian systems");
2791 /* Add some warnings for VSX. */
2792 if (TARGET_VSX)
2794 const char *msg = NULL;
2795 if (!TARGET_HARD_FLOAT || !TARGET_FPRS
2796 || !TARGET_SINGLE_FLOAT || !TARGET_DOUBLE_FLOAT)
2798 if (target_flags_explicit & MASK_VSX)
2799 msg = N_("-mvsx requires hardware floating point");
2800 else
2801 target_flags &= ~ MASK_VSX;
2803 else if (TARGET_PAIRED_FLOAT)
2804 msg = N_("-mvsx and -mpaired are incompatible");
2805 /* The hardware will allow VSX and little endian, but until we make sure
2806 things like vector select, etc. work don't allow VSX on little endian
2807 systems at this point. */
2808 else if (!BYTES_BIG_ENDIAN)
2809 msg = N_("-mvsx used with little endian code");
2810 else if (TARGET_AVOID_XFORM > 0)
2811 msg = N_("-mvsx needs indexed addressing");
2812 else if (!TARGET_ALTIVEC && (target_flags_explicit & MASK_ALTIVEC))
2814 if (target_flags_explicit & MASK_VSX)
2815 msg = N_("-mvsx and -mno-altivec are incompatible");
2816 else
2817 msg = N_("-mno-altivec disables vsx");
2820 if (msg)
2822 warning (0, msg);
2823 target_flags &= ~ MASK_VSX;
2824 target_flags_explicit |= MASK_VSX;
2828 /* For the newer switches (vsx, dfp, etc.) set some of the older options,
2829 unless the user explicitly used the -mno-<option> to disable the code. */
2830 if (TARGET_VSX)
2831 target_flags |= (ISA_2_6_MASKS_SERVER & ~target_flags_explicit);
2832 else if (TARGET_POPCNTD)
2833 target_flags |= (ISA_2_6_MASKS_EMBEDDED & ~target_flags_explicit);
2834 else if (TARGET_DFP)
2835 target_flags |= (ISA_2_5_MASKS_SERVER & ~target_flags_explicit);
2836 else if (TARGET_CMPB)
2837 target_flags |= (ISA_2_5_MASKS_EMBEDDED & ~target_flags_explicit);
2838 else if (TARGET_FPRND)
2839 target_flags |= (ISA_2_4_MASKS & ~target_flags_explicit);
2840 else if (TARGET_POPCNTB)
2841 target_flags |= (ISA_2_2_MASKS & ~target_flags_explicit);
2842 else if (TARGET_ALTIVEC)
2843 target_flags |= (MASK_PPC_GFXOPT & ~target_flags_explicit);
2845 /* E500mc does "better" if we inline more aggressively. Respect the
2846 user's opinion, though. */
2847 if (rs6000_block_move_inline_limit == 0
2848 && (rs6000_cpu == PROCESSOR_PPCE500MC
2849 || rs6000_cpu == PROCESSOR_PPCE500MC64))
2850 rs6000_block_move_inline_limit = 128;
2852 /* store_one_arg depends on expand_block_move to handle at least the
2853 size of reg_parm_stack_space. */
2854 if (rs6000_block_move_inline_limit < (TARGET_POWERPC64 ? 64 : 32))
2855 rs6000_block_move_inline_limit = (TARGET_POWERPC64 ? 64 : 32);
2857 if (global_init_p)
2859 /* If the appropriate debug option is enabled, replace the target hooks
2860 with debug versions that call the real version and then prints
2861 debugging information. */
2862 if (TARGET_DEBUG_COST)
2864 targetm.rtx_costs = rs6000_debug_rtx_costs;
2865 targetm.address_cost = rs6000_debug_address_cost;
2866 targetm.sched.adjust_cost = rs6000_debug_adjust_cost;
2869 if (TARGET_DEBUG_ADDR)
2871 targetm.legitimate_address_p = rs6000_debug_legitimate_address_p;
2872 targetm.legitimize_address = rs6000_debug_legitimize_address;
2873 rs6000_secondary_reload_class_ptr
2874 = rs6000_debug_secondary_reload_class;
2875 rs6000_secondary_memory_needed_ptr
2876 = rs6000_debug_secondary_memory_needed;
2877 rs6000_cannot_change_mode_class_ptr
2878 = rs6000_debug_cannot_change_mode_class;
2879 rs6000_preferred_reload_class_ptr
2880 = rs6000_debug_preferred_reload_class;
2881 rs6000_legitimize_reload_address_ptr
2882 = rs6000_debug_legitimize_reload_address;
2883 rs6000_mode_dependent_address_ptr
2884 = rs6000_debug_mode_dependent_address;
2887 if (rs6000_veclibabi_name)
2889 if (strcmp (rs6000_veclibabi_name, "mass") == 0)
2890 rs6000_veclib_handler = rs6000_builtin_vectorized_libmass;
2891 else
2893 error ("unknown vectorization library ABI type (%s) for "
2894 "-mveclibabi= switch", rs6000_veclibabi_name);
2895 ret = false;
2900 if (!rs6000_explicit_options.long_double)
2902 if (main_target_opt != NULL
2903 && (main_target_opt->x_rs6000_long_double_type_size
2904 != RS6000_DEFAULT_LONG_DOUBLE_SIZE))
2905 error ("target attribute or pragma changes long double size");
2906 else
2907 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
2910 #ifndef POWERPC_LINUX
2911 if (!rs6000_explicit_options.ieee)
2912 rs6000_ieeequad = 1;
2913 #endif
2915 /* Disable VSX and Altivec silently if the user switched cpus to power7 in a
2916 target attribute or pragma which automatically enables both options,
2917 unless the altivec ABI was set. This is set by default for 64-bit, but
2918 not for 32-bit. */
2919 if (main_target_opt != NULL && !main_target_opt->x_rs6000_altivec_abi)
2920 target_flags &= ~((MASK_VSX | MASK_ALTIVEC) & ~target_flags_explicit);
2922 /* Enable Altivec ABI for AIX -maltivec. */
2923 if (TARGET_XCOFF && (TARGET_ALTIVEC || TARGET_VSX))
2925 if (main_target_opt != NULL && !main_target_opt->x_rs6000_altivec_abi)
2926 error ("target attribute or pragma changes AltiVec ABI");
2927 else
2928 rs6000_altivec_abi = 1;
2931 /* The AltiVec ABI is the default for PowerPC-64 GNU/Linux. For
2932 PowerPC-32 GNU/Linux, -maltivec implies the AltiVec ABI. It can
2933 be explicitly overridden in either case. */
2934 if (TARGET_ELF)
2936 if (!rs6000_explicit_options.altivec_abi
2937 && (TARGET_64BIT || TARGET_ALTIVEC || TARGET_VSX))
2939 if (main_target_opt != NULL &&
2940 !main_target_opt->x_rs6000_altivec_abi)
2941 error ("target attribute or pragma changes AltiVec ABI");
2942 else
2943 rs6000_altivec_abi = 1;
2946 /* Enable VRSAVE for AltiVec ABI, unless explicitly overridden. */
2947 if (!rs6000_explicit_options.vrsave)
2948 TARGET_ALTIVEC_VRSAVE = rs6000_altivec_abi;
2951 /* Set the Darwin64 ABI as default for 64-bit Darwin.
2952 So far, the only darwin64 targets are also MACH-O. */
2953 if (TARGET_MACHO
2954 && DEFAULT_ABI == ABI_DARWIN
2955 && TARGET_64BIT)
2957 if (main_target_opt != NULL && !main_target_opt->x_rs6000_darwin64_abi)
2958 error ("target attribute or pragma changes darwin64 ABI");
2959 else
2961 rs6000_darwin64_abi = 1;
2962 /* Default to natural alignment, for better performance. */
2963 rs6000_alignment_flags = MASK_ALIGN_NATURAL;
2967 /* Place FP constants in the constant pool instead of TOC
2968 if section anchors enabled. */
2969 if (flag_section_anchors)
2970 TARGET_NO_FP_IN_TOC = 1;
2972 #ifdef SUBTARGET_OVERRIDE_OPTIONS
2973 SUBTARGET_OVERRIDE_OPTIONS;
2974 #endif
2975 #ifdef SUBSUBTARGET_OVERRIDE_OPTIONS
2976 SUBSUBTARGET_OVERRIDE_OPTIONS;
2977 #endif
2978 #ifdef SUB3TARGET_OVERRIDE_OPTIONS
2979 SUB3TARGET_OVERRIDE_OPTIONS;
2980 #endif
2982 if (TARGET_E500 || rs6000_cpu == PROCESSOR_PPCE500MC
2983 || rs6000_cpu == PROCESSOR_PPCE500MC64)
2985 /* The e500 and e500mc do not have string instructions, and we set
2986 MASK_STRING above when optimizing for size. */
2987 if ((target_flags & MASK_STRING) != 0)
2988 target_flags = target_flags & ~MASK_STRING;
2990 else if (rs6000_select[1].string != NULL)
2992 /* For the powerpc-eabispe configuration, we set all these by
2993 default, so let's unset them if we manually set another
2994 CPU that is not the E500. */
2995 if (main_target_opt != NULL
2996 && ((main_target_opt->x_rs6000_spe_abi != rs6000_spe_abi)
2997 || (main_target_opt->x_rs6000_spe != rs6000_spe)
2998 || (main_target_opt->x_rs6000_float_gprs != rs6000_float_gprs)))
2999 error ("target attribute or pragma changes SPE ABI");
3000 else
3002 if (!rs6000_explicit_options.spe_abi)
3003 rs6000_spe_abi = 0;
3004 if (!rs6000_explicit_options.spe)
3005 rs6000_spe = 0;
3006 if (!rs6000_explicit_options.float_gprs)
3007 rs6000_float_gprs = 0;
3009 if (!(target_flags_explicit & MASK_ISEL))
3010 target_flags &= ~MASK_ISEL;
3013 /* Detect invalid option combinations with E500. */
3014 CHECK_E500_OPTIONS;
3016 rs6000_always_hint = (rs6000_cpu != PROCESSOR_POWER4
3017 && rs6000_cpu != PROCESSOR_POWER5
3018 && rs6000_cpu != PROCESSOR_POWER6
3019 && rs6000_cpu != PROCESSOR_POWER7
3020 && rs6000_cpu != PROCESSOR_PPCA2
3021 && rs6000_cpu != PROCESSOR_CELL);
3022 rs6000_sched_groups = (rs6000_cpu == PROCESSOR_POWER4
3023 || rs6000_cpu == PROCESSOR_POWER5
3024 || rs6000_cpu == PROCESSOR_POWER7);
3025 rs6000_align_branch_targets = (rs6000_cpu == PROCESSOR_POWER4
3026 || rs6000_cpu == PROCESSOR_POWER5
3027 || rs6000_cpu == PROCESSOR_POWER6
3028 || rs6000_cpu == PROCESSOR_POWER7
3029 || rs6000_cpu == PROCESSOR_PPCE500MC
3030 || rs6000_cpu == PROCESSOR_PPCE500MC64);
3032 /* Allow debug switches to override the above settings. These are set to -1
3033 in rs6000.opt to indicate the user hasn't directly set the switch. */
3034 if (TARGET_ALWAYS_HINT >= 0)
3035 rs6000_always_hint = TARGET_ALWAYS_HINT;
3037 if (TARGET_SCHED_GROUPS >= 0)
3038 rs6000_sched_groups = TARGET_SCHED_GROUPS;
3040 if (TARGET_ALIGN_BRANCH_TARGETS >= 0)
3041 rs6000_align_branch_targets = TARGET_ALIGN_BRANCH_TARGETS;
3043 rs6000_sched_restricted_insns_priority
3044 = (rs6000_sched_groups ? 1 : 0);
3046 /* Handle -msched-costly-dep option. */
3047 rs6000_sched_costly_dep
3048 = (rs6000_sched_groups ? store_to_load_dep_costly : no_dep_costly);
3050 if (rs6000_sched_costly_dep_str)
3052 if (! strcmp (rs6000_sched_costly_dep_str, "no"))
3053 rs6000_sched_costly_dep = no_dep_costly;
3054 else if (! strcmp (rs6000_sched_costly_dep_str, "all"))
3055 rs6000_sched_costly_dep = all_deps_costly;
3056 else if (! strcmp (rs6000_sched_costly_dep_str, "true_store_to_load"))
3057 rs6000_sched_costly_dep = true_store_to_load_dep_costly;
3058 else if (! strcmp (rs6000_sched_costly_dep_str, "store_to_load"))
3059 rs6000_sched_costly_dep = store_to_load_dep_costly;
3060 else
3061 rs6000_sched_costly_dep = ((enum rs6000_dependence_cost)
3062 atoi (rs6000_sched_costly_dep_str));
3065 /* Handle -minsert-sched-nops option. */
3066 rs6000_sched_insert_nops
3067 = (rs6000_sched_groups ? sched_finish_regroup_exact : sched_finish_none);
3069 if (rs6000_sched_insert_nops_str)
3071 if (! strcmp (rs6000_sched_insert_nops_str, "no"))
3072 rs6000_sched_insert_nops = sched_finish_none;
3073 else if (! strcmp (rs6000_sched_insert_nops_str, "pad"))
3074 rs6000_sched_insert_nops = sched_finish_pad_groups;
3075 else if (! strcmp (rs6000_sched_insert_nops_str, "regroup_exact"))
3076 rs6000_sched_insert_nops = sched_finish_regroup_exact;
3077 else
3078 rs6000_sched_insert_nops = ((enum rs6000_nop_insertion)
3079 atoi (rs6000_sched_insert_nops_str));
3082 if (global_init_p)
3084 #ifdef TARGET_REGNAMES
3085 /* If the user desires alternate register names, copy in the
3086 alternate names now. */
3087 if (TARGET_REGNAMES)
3088 memcpy (rs6000_reg_names, alt_reg_names, sizeof (rs6000_reg_names));
3089 #endif
3091 /* Set aix_struct_return last, after the ABI is determined.
3092 If -maix-struct-return or -msvr4-struct-return was explicitly
3093 used, don't override with the ABI default. */
3094 if (!rs6000_explicit_options.aix_struct_ret)
3095 aix_struct_return = (DEFAULT_ABI != ABI_V4 || DRAFT_V4_STRUCT_RET);
3097 #if 0
3098 /* IBM XL compiler defaults to unsigned bitfields. */
3099 if (TARGET_XL_COMPAT)
3100 flag_signed_bitfields = 0;
3101 #endif
3103 if (TARGET_LONG_DOUBLE_128 && !TARGET_IEEEQUAD)
3104 REAL_MODE_FORMAT (TFmode) = &ibm_extended_format;
3106 if (TARGET_TOC)
3107 ASM_GENERATE_INTERNAL_LABEL (toc_label_name, "LCTOC", 1);
3109 /* We can only guarantee the availability of DI pseudo-ops when
3110 assembling for 64-bit targets. */
3111 if (!TARGET_64BIT)
3113 targetm.asm_out.aligned_op.di = NULL;
3114 targetm.asm_out.unaligned_op.di = NULL;
3118 /* Set branch target alignment, if not optimizing for size. */
3119 if (!optimize_size)
3121 /* Cell wants to be aligned 8byte for dual issue. Titan wants to be
3122 aligned 8byte to avoid misprediction by the branch predictor. */
3123 if (rs6000_cpu == PROCESSOR_TITAN
3124 || rs6000_cpu == PROCESSOR_CELL)
3126 if (align_functions <= 0)
3127 align_functions = 8;
3128 if (align_jumps <= 0)
3129 align_jumps = 8;
3130 if (align_loops <= 0)
3131 align_loops = 8;
3133 if (rs6000_align_branch_targets)
3135 if (align_functions <= 0)
3136 align_functions = 16;
3137 if (align_jumps <= 0)
3138 align_jumps = 16;
3139 if (align_loops <= 0)
3141 can_override_loop_align = 1;
3142 align_loops = 16;
3145 if (align_jumps_max_skip <= 0)
3146 align_jumps_max_skip = 15;
3147 if (align_loops_max_skip <= 0)
3148 align_loops_max_skip = 15;
3151 /* Arrange to save and restore machine status around nested functions. */
3152 init_machine_status = rs6000_init_machine_status;
3154 /* We should always be splitting complex arguments, but we can't break
3155 Linux and Darwin ABIs at the moment. For now, only AIX is fixed. */
3156 if (DEFAULT_ABI != ABI_AIX)
3157 targetm.calls.split_complex_arg = NULL;
3160 /* Initialize rs6000_cost with the appropriate target costs. */
3161 if (optimize_size)
3162 rs6000_cost = TARGET_POWERPC64 ? &size64_cost : &size32_cost;
3163 else
3164 switch (rs6000_cpu)
3166 case PROCESSOR_RIOS1:
3167 rs6000_cost = &rios1_cost;
3168 break;
3170 case PROCESSOR_RIOS2:
3171 rs6000_cost = &rios2_cost;
3172 break;
3174 case PROCESSOR_RS64A:
3175 rs6000_cost = &rs64a_cost;
3176 break;
3178 case PROCESSOR_MPCCORE:
3179 rs6000_cost = &mpccore_cost;
3180 break;
3182 case PROCESSOR_PPC403:
3183 rs6000_cost = &ppc403_cost;
3184 break;
3186 case PROCESSOR_PPC405:
3187 rs6000_cost = &ppc405_cost;
3188 break;
3190 case PROCESSOR_PPC440:
3191 rs6000_cost = &ppc440_cost;
3192 break;
3194 case PROCESSOR_PPC476:
3195 rs6000_cost = &ppc476_cost;
3196 break;
3198 case PROCESSOR_PPC601:
3199 rs6000_cost = &ppc601_cost;
3200 break;
3202 case PROCESSOR_PPC603:
3203 rs6000_cost = &ppc603_cost;
3204 break;
3206 case PROCESSOR_PPC604:
3207 rs6000_cost = &ppc604_cost;
3208 break;
3210 case PROCESSOR_PPC604e:
3211 rs6000_cost = &ppc604e_cost;
3212 break;
3214 case PROCESSOR_PPC620:
3215 rs6000_cost = &ppc620_cost;
3216 break;
3218 case PROCESSOR_PPC630:
3219 rs6000_cost = &ppc630_cost;
3220 break;
3222 case PROCESSOR_CELL:
3223 rs6000_cost = &ppccell_cost;
3224 break;
3226 case PROCESSOR_PPC750:
3227 case PROCESSOR_PPC7400:
3228 rs6000_cost = &ppc750_cost;
3229 break;
3231 case PROCESSOR_PPC7450:
3232 rs6000_cost = &ppc7450_cost;
3233 break;
3235 case PROCESSOR_PPC8540:
3236 rs6000_cost = &ppc8540_cost;
3237 break;
3239 case PROCESSOR_PPCE300C2:
3240 case PROCESSOR_PPCE300C3:
3241 rs6000_cost = &ppce300c2c3_cost;
3242 break;
3244 case PROCESSOR_PPCE500MC:
3245 rs6000_cost = &ppce500mc_cost;
3246 break;
3248 case PROCESSOR_PPCE500MC64:
3249 rs6000_cost = &ppce500mc64_cost;
3250 break;
3252 case PROCESSOR_TITAN:
3253 rs6000_cost = &titan_cost;
3254 break;
3256 case PROCESSOR_POWER4:
3257 case PROCESSOR_POWER5:
3258 rs6000_cost = &power4_cost;
3259 break;
3261 case PROCESSOR_POWER6:
3262 rs6000_cost = &power6_cost;
3263 break;
3265 case PROCESSOR_POWER7:
3266 rs6000_cost = &power7_cost;
3267 break;
3269 case PROCESSOR_PPCA2:
3270 rs6000_cost = &ppca2_cost;
3271 break;
3273 default:
3274 gcc_unreachable ();
3277 if (global_init_p)
3279 maybe_set_param_value (PARAM_SIMULTANEOUS_PREFETCHES,
3280 rs6000_cost->simultaneous_prefetches,
3281 global_options.x_param_values,
3282 global_options_set.x_param_values);
3283 maybe_set_param_value (PARAM_L1_CACHE_SIZE, rs6000_cost->l1_cache_size,
3284 global_options.x_param_values,
3285 global_options_set.x_param_values);
3286 maybe_set_param_value (PARAM_L1_CACHE_LINE_SIZE,
3287 rs6000_cost->cache_line_size,
3288 global_options.x_param_values,
3289 global_options_set.x_param_values);
3290 maybe_set_param_value (PARAM_L2_CACHE_SIZE, rs6000_cost->l2_cache_size,
3291 global_options.x_param_values,
3292 global_options_set.x_param_values);
3294 /* If using typedef char *va_list, signal that
3295 __builtin_va_start (&ap, 0) can be optimized to
3296 ap = __builtin_next_arg (0). */
3297 if (DEFAULT_ABI != ABI_V4)
3298 targetm.expand_builtin_va_start = NULL;
3301 /* Set up single/double float flags.
3302 If TARGET_HARD_FLOAT is set, but neither single or double is set,
3303 then set both flags. */
3304 if (TARGET_HARD_FLOAT && TARGET_FPRS
3305 && rs6000_single_float == 0 && rs6000_double_float == 0)
3306 rs6000_single_float = rs6000_double_float = 1;
3308 /* Reset single and double FP flags if target is E500. */
3309 if (TARGET_E500)
3311 rs6000_single_float = rs6000_double_float = 0;
3312 if (TARGET_E500_SINGLE)
3313 rs6000_single_float = 1;
3314 if (TARGET_E500_DOUBLE)
3315 rs6000_single_float = rs6000_double_float = 1;
3318 if (main_target_opt)
3320 if (main_target_opt->x_rs6000_single_float != rs6000_single_float)
3321 error ("target attribute or pragma changes single precision floating "
3322 "point");
3323 if (main_target_opt->x_rs6000_double_float != rs6000_double_float)
3324 error ("target attribute or pragma changes double precision floating "
3325 "point");
3328 /* If not explicitly specified via option, decide whether to generate indexed
3329 load/store instructions. */
3330 if (TARGET_AVOID_XFORM == -1)
3331 /* Avoid indexed addressing when targeting Power6 in order to avoid the
3332 DERAT mispredict penalty. However the LVE and STVE altivec instructions
3333 need indexed accesses and the type used is the scalar type of the element
3334 being loaded or stored. */
3335 TARGET_AVOID_XFORM = (rs6000_cpu == PROCESSOR_POWER6 && TARGET_CMPB
3336 && !TARGET_ALTIVEC);
3338 /* Set the -mrecip options. */
3339 if (rs6000_recip_name)
3341 char *p = ASTRDUP (rs6000_recip_name);
3342 char *q;
3343 unsigned int mask, i;
3344 bool invert;
3346 while ((q = strtok (p, ",")) != NULL)
3348 p = NULL;
3349 if (*q == '!')
3351 invert = true;
3352 q++;
3354 else
3355 invert = false;
3357 if (!strcmp (q, "default"))
3358 mask = ((TARGET_RECIP_PRECISION)
3359 ? RECIP_HIGH_PRECISION : RECIP_LOW_PRECISION);
3360 else
3362 for (i = 0; i < ARRAY_SIZE (recip_options); i++)
3363 if (!strcmp (q, recip_options[i].string))
3365 mask = recip_options[i].mask;
3366 break;
3369 if (i == ARRAY_SIZE (recip_options))
3371 error ("unknown option for -mrecip=%s", q);
3372 invert = false;
3373 mask = 0;
3374 ret = false;
3378 if (invert)
3379 rs6000_recip_control &= ~mask;
3380 else
3381 rs6000_recip_control |= mask;
3385 rs6000_init_hard_regno_mode_ok (global_init_p);
3387 /* Save the initial options in case the user does function specific options */
3388 if (global_init_p)
3389 target_option_default_node = target_option_current_node
3390 = build_target_option_node ();
3392 return ret;
3395 /* Implement TARGET_OPTION_OVERRIDE. On the RS/6000 this is used to
3396 define the target cpu type. */
3398 static void
3399 rs6000_option_override (void)
3401 (void) rs6000_option_override_internal (true);
3405 /* Implement targetm.vectorize.builtin_mask_for_load. */
3406 static tree
3407 rs6000_builtin_mask_for_load (void)
3409 if (TARGET_ALTIVEC || TARGET_VSX)
3410 return altivec_builtin_mask_for_load;
3411 else
3412 return 0;
3415 /* Implement LOOP_ALIGN. */
3417 rs6000_loop_align (rtx label)
3419 basic_block bb;
3420 int ninsns;
3422 /* Don't override loop alignment if -falign-loops was specified. */
3423 if (!can_override_loop_align)
3424 return align_loops_log;
3426 bb = BLOCK_FOR_INSN (label);
3427 ninsns = num_loop_insns(bb->loop_father);
3429 /* Align small loops to 32 bytes to fit in an icache sector, otherwise return default. */
3430 if (ninsns > 4 && ninsns <= 8
3431 && (rs6000_cpu == PROCESSOR_POWER4
3432 || rs6000_cpu == PROCESSOR_POWER5
3433 || rs6000_cpu == PROCESSOR_POWER6
3434 || rs6000_cpu == PROCESSOR_POWER7))
3435 return 5;
3436 else
3437 return align_loops_log;
3440 /* Implement TARGET_LOOP_ALIGN_MAX_SKIP. */
3441 static int
3442 rs6000_loop_align_max_skip (rtx label)
3444 return (1 << rs6000_loop_align (label)) - 1;
3447 /* Implement targetm.vectorize.builtin_conversion.
3448 Returns a decl of a function that implements conversion of an integer vector
3449 into a floating-point vector, or vice-versa. DEST_TYPE is the
3450 destination type and SRC_TYPE the source type of the conversion.
3451 Return NULL_TREE if it is not available. */
3452 static tree
3453 rs6000_builtin_conversion (unsigned int tcode, tree dest_type, tree src_type)
3455 enum tree_code code = (enum tree_code) tcode;
3457 switch (code)
3459 case FIX_TRUNC_EXPR:
3460 switch (TYPE_MODE (dest_type))
3462 case V2DImode:
3463 if (!VECTOR_UNIT_VSX_P (V2DFmode))
3464 return NULL_TREE;
3466 return TYPE_UNSIGNED (dest_type)
3467 ? rs6000_builtin_decls[VSX_BUILTIN_XVCVDPUXDS_UNS]
3468 : rs6000_builtin_decls[VSX_BUILTIN_XVCVDPSXDS];
3470 case V4SImode:
3471 if (VECTOR_UNIT_NONE_P (V4SImode) || VECTOR_UNIT_NONE_P (V4SFmode))
3472 return NULL_TREE;
3474 return TYPE_UNSIGNED (dest_type)
3475 ? rs6000_builtin_decls[VECTOR_BUILTIN_FIXUNS_V4SF_V4SI]
3476 : rs6000_builtin_decls[VECTOR_BUILTIN_FIX_V4SF_V4SI];
3478 default:
3479 return NULL_TREE;
3482 case FLOAT_EXPR:
3483 switch (TYPE_MODE (src_type))
3485 case V2DImode:
3486 if (!VECTOR_UNIT_VSX_P (V2DFmode))
3487 return NULL_TREE;
3489 return TYPE_UNSIGNED (src_type)
3490 ? rs6000_builtin_decls[VSX_BUILTIN_XVCVUXDDP]
3491 : rs6000_builtin_decls[VSX_BUILTIN_XVCVSXDDP];
3493 case V4SImode:
3494 if (VECTOR_UNIT_NONE_P (V4SImode) || VECTOR_UNIT_NONE_P (V4SFmode))
3495 return NULL_TREE;
3497 return TYPE_UNSIGNED (src_type)
3498 ? rs6000_builtin_decls[VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF]
3499 : rs6000_builtin_decls[VECTOR_BUILTIN_FLOAT_V4SI_V4SF];
3501 default:
3502 return NULL_TREE;
3505 default:
3506 return NULL_TREE;
3510 /* Implement targetm.vectorize.builtin_mul_widen_even. */
3511 static tree
3512 rs6000_builtin_mul_widen_even (tree type)
3514 if (!TARGET_ALTIVEC)
3515 return NULL_TREE;
3517 switch (TYPE_MODE (type))
3519 case V8HImode:
3520 return TYPE_UNSIGNED (type)
3521 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULEUH_UNS]
3522 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULESH];
3524 case V16QImode:
3525 return TYPE_UNSIGNED (type)
3526 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULEUB_UNS]
3527 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULESB];
3528 default:
3529 return NULL_TREE;
3533 /* Implement targetm.vectorize.builtin_mul_widen_odd. */
3534 static tree
3535 rs6000_builtin_mul_widen_odd (tree type)
3537 if (!TARGET_ALTIVEC)
3538 return NULL_TREE;
3540 switch (TYPE_MODE (type))
3542 case V8HImode:
3543 return TYPE_UNSIGNED (type)
3544 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOUH_UNS]
3545 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOSH];
3547 case V16QImode:
3548 return TYPE_UNSIGNED (type)
3549 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOUB_UNS]
3550 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOSB];
3551 default:
3552 return NULL_TREE;
3557 /* Return true iff, data reference of TYPE can reach vector alignment (16)
3558 after applying N number of iterations. This routine does not determine
3559 how may iterations are required to reach desired alignment. */
3561 static bool
3562 rs6000_vector_alignment_reachable (const_tree type ATTRIBUTE_UNUSED, bool is_packed)
3564 if (is_packed)
3565 return false;
3567 if (TARGET_32BIT)
3569 if (rs6000_alignment_flags == MASK_ALIGN_NATURAL)
3570 return true;
3572 if (rs6000_alignment_flags == MASK_ALIGN_POWER)
3573 return true;
3575 return false;
3577 else
3579 if (TARGET_MACHO)
3580 return false;
3582 /* Assuming that all other types are naturally aligned. CHECKME! */
3583 return true;
3587 /* Return true if the vector misalignment factor is supported by the
3588 target. */
3589 bool
3590 rs6000_builtin_support_vector_misalignment (enum machine_mode mode,
3591 const_tree type,
3592 int misalignment,
3593 bool is_packed)
3595 if (TARGET_VSX)
3597 /* Return if movmisalign pattern is not supported for this mode. */
3598 if (optab_handler (movmisalign_optab, mode) == CODE_FOR_nothing)
3599 return false;
3601 if (misalignment == -1)
3603 /* Misalignment factor is unknown at compile time but we know
3604 it's word aligned. */
3605 if (rs6000_vector_alignment_reachable (type, is_packed))
3607 int element_size = TREE_INT_CST_LOW (TYPE_SIZE (type));
3609 if (element_size == 64 || element_size == 32)
3610 return true;
3613 return false;
3616 /* VSX supports word-aligned vector. */
3617 if (misalignment % 4 == 0)
3618 return true;
3620 return false;
3623 /* Implement targetm.vectorize.builtin_vec_perm. */
3624 tree
3625 rs6000_builtin_vec_perm (tree type, tree *mask_element_type)
3627 tree inner_type = TREE_TYPE (type);
3628 bool uns_p = TYPE_UNSIGNED (inner_type);
3629 tree d;
3631 *mask_element_type = unsigned_char_type_node;
3633 switch (TYPE_MODE (type))
3635 case V16QImode:
3636 d = (uns_p
3637 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_16QI_UNS]
3638 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_16QI]);
3639 break;
3641 case V8HImode:
3642 d = (uns_p
3643 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_8HI_UNS]
3644 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_8HI]);
3645 break;
3647 case V4SImode:
3648 d = (uns_p
3649 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SI_UNS]
3650 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SI]);
3651 break;
3653 case V4SFmode:
3654 d = rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SF];
3655 break;
3657 case V2DFmode:
3658 if (!TARGET_ALLOW_DF_PERMUTE)
3659 return NULL_TREE;
3661 d = rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DF];
3662 break;
3664 case V2DImode:
3665 if (!TARGET_ALLOW_DF_PERMUTE)
3666 return NULL_TREE;
3668 d = (uns_p
3669 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DI_UNS]
3670 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DI]);
3671 break;
3673 default:
3674 return NULL_TREE;
3677 gcc_assert (d);
3678 return d;
3682 /* Implement targetm.vectorize.builtin_vectorization_cost. */
3683 static int
3684 rs6000_builtin_vectorization_cost (enum vect_cost_for_stmt type_of_cost,
3685 tree vectype, int misalign)
3687 unsigned elements;
3689 switch (type_of_cost)
3691 case scalar_stmt:
3692 case scalar_load:
3693 case scalar_store:
3694 case vector_stmt:
3695 case vector_load:
3696 case vector_store:
3697 case vec_to_scalar:
3698 case scalar_to_vec:
3699 case cond_branch_not_taken:
3700 case vec_perm:
3701 return 1;
3703 case cond_branch_taken:
3704 return 3;
3706 case unaligned_load:
3707 if (TARGET_VSX && TARGET_ALLOW_MOVMISALIGN)
3709 elements = TYPE_VECTOR_SUBPARTS (vectype);
3710 if (elements == 2)
3711 /* Double word aligned. */
3712 return 2;
3714 if (elements == 4)
3716 switch (misalign)
3718 case 8:
3719 /* Double word aligned. */
3720 return 2;
3722 case -1:
3723 /* Unknown misalignment. */
3724 case 4:
3725 case 12:
3726 /* Word aligned. */
3727 return 22;
3729 default:
3730 gcc_unreachable ();
3735 if (TARGET_ALTIVEC)
3736 /* Misaligned loads are not supported. */
3737 gcc_unreachable ();
3739 return 2;
3741 case unaligned_store:
3742 if (TARGET_VSX && TARGET_ALLOW_MOVMISALIGN)
3744 elements = TYPE_VECTOR_SUBPARTS (vectype);
3745 if (elements == 2)
3746 /* Double word aligned. */
3747 return 2;
3749 if (elements == 4)
3751 switch (misalign)
3753 case 8:
3754 /* Double word aligned. */
3755 return 2;
3757 case -1:
3758 /* Unknown misalignment. */
3759 case 4:
3760 case 12:
3761 /* Word aligned. */
3762 return 23;
3764 default:
3765 gcc_unreachable ();
3770 if (TARGET_ALTIVEC)
3771 /* Misaligned stores are not supported. */
3772 gcc_unreachable ();
3774 return 2;
3776 default:
3777 gcc_unreachable ();
3781 /* Implement targetm.vectorize.preferred_simd_mode. */
3783 static enum machine_mode
3784 rs6000_preferred_simd_mode (enum machine_mode mode)
3786 if (TARGET_VSX)
3787 switch (mode)
3789 case DFmode:
3790 return V2DFmode;
3791 default:;
3793 if (TARGET_ALTIVEC || TARGET_VSX)
3794 switch (mode)
3796 case SFmode:
3797 return V4SFmode;
3798 case DImode:
3799 return V2DImode;
3800 case SImode:
3801 return V4SImode;
3802 case HImode:
3803 return V8HImode;
3804 case QImode:
3805 return V16QImode;
3806 default:;
3808 if (TARGET_SPE)
3809 switch (mode)
3811 case SFmode:
3812 return V2SFmode;
3813 case SImode:
3814 return V2SImode;
3815 default:;
3817 if (TARGET_PAIRED_FLOAT
3818 && mode == SFmode)
3819 return V2SFmode;
3820 return word_mode;
3823 /* Handle generic options of the form -mfoo=yes/no.
3824 NAME is the option name.
3825 VALUE is the option value.
3826 FLAG is the pointer to the flag where to store a 1 or 0, depending on
3827 whether the option value is 'yes' or 'no' respectively. */
3828 static void
3829 rs6000_parse_yes_no_option (const char *name, const char *value, int *flag)
3831 if (value == 0)
3832 return;
3833 else if (!strcmp (value, "yes"))
3834 *flag = 1;
3835 else if (!strcmp (value, "no"))
3836 *flag = 0;
3837 else
3838 error ("unknown -m%s= option specified: '%s'", name, value);
3841 /* Implement TARGET_OPTION_INIT_STRUCT. */
3843 static void
3844 rs6000_option_init_struct (struct gcc_options *opts)
3846 if (DEFAULT_ABI == ABI_DARWIN)
3847 /* The Darwin libraries never set errno, so we might as well
3848 avoid calling them when that's the only reason we would. */
3849 opts->x_flag_errno_math = 0;
3851 /* Enable section anchors by default. */
3852 if (!TARGET_MACHO)
3853 opts->x_flag_section_anchors = 1;
3856 /* Implement TARGET_OPTION_DEFAULT_PARAMS. */
3858 static void
3859 rs6000_option_default_params (void)
3861 /* Double growth factor to counter reduced min jump length. */
3862 set_default_param_value (PARAM_MAX_GROW_COPY_BB_INSNS, 16);
3865 static enum fpu_type_t
3866 rs6000_parse_fpu_option (const char *option)
3868 if (!strcmp("none", option)) return FPU_NONE;
3869 if (!strcmp("sp_lite", option)) return FPU_SF_LITE;
3870 if (!strcmp("dp_lite", option)) return FPU_DF_LITE;
3871 if (!strcmp("sp_full", option)) return FPU_SF_FULL;
3872 if (!strcmp("dp_full", option)) return FPU_DF_FULL;
3873 error("unknown value %s for -mfpu", option);
3874 return FPU_NONE;
3878 /* Handler for the Mathematical Acceleration Subsystem (mass) interface to a
3879 library with vectorized intrinsics. */
3881 static tree
3882 rs6000_builtin_vectorized_libmass (tree fndecl, tree type_out, tree type_in)
3884 char name[32];
3885 const char *suffix = NULL;
3886 tree fntype, new_fndecl, bdecl = NULL_TREE;
3887 int n_args = 1;
3888 const char *bname;
3889 enum machine_mode el_mode, in_mode;
3890 int n, in_n;
3892 /* Libmass is suitable for unsafe math only as it does not correctly support
3893 parts of IEEE with the required precision such as denormals. Only support
3894 it if we have VSX to use the simd d2 or f4 functions.
3895 XXX: Add variable length support. */
3896 if (!flag_unsafe_math_optimizations || !TARGET_VSX)
3897 return NULL_TREE;
3899 el_mode = TYPE_MODE (TREE_TYPE (type_out));
3900 n = TYPE_VECTOR_SUBPARTS (type_out);
3901 in_mode = TYPE_MODE (TREE_TYPE (type_in));
3902 in_n = TYPE_VECTOR_SUBPARTS (type_in);
3903 if (el_mode != in_mode
3904 || n != in_n)
3905 return NULL_TREE;
3907 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
3909 enum built_in_function fn = DECL_FUNCTION_CODE (fndecl);
3910 switch (fn)
3912 case BUILT_IN_ATAN2:
3913 case BUILT_IN_HYPOT:
3914 case BUILT_IN_POW:
3915 n_args = 2;
3916 /* fall through */
3918 case BUILT_IN_ACOS:
3919 case BUILT_IN_ACOSH:
3920 case BUILT_IN_ASIN:
3921 case BUILT_IN_ASINH:
3922 case BUILT_IN_ATAN:
3923 case BUILT_IN_ATANH:
3924 case BUILT_IN_CBRT:
3925 case BUILT_IN_COS:
3926 case BUILT_IN_COSH:
3927 case BUILT_IN_ERF:
3928 case BUILT_IN_ERFC:
3929 case BUILT_IN_EXP2:
3930 case BUILT_IN_EXP:
3931 case BUILT_IN_EXPM1:
3932 case BUILT_IN_LGAMMA:
3933 case BUILT_IN_LOG10:
3934 case BUILT_IN_LOG1P:
3935 case BUILT_IN_LOG2:
3936 case BUILT_IN_LOG:
3937 case BUILT_IN_SIN:
3938 case BUILT_IN_SINH:
3939 case BUILT_IN_SQRT:
3940 case BUILT_IN_TAN:
3941 case BUILT_IN_TANH:
3942 bdecl = implicit_built_in_decls[fn];
3943 suffix = "d2"; /* pow -> powd2 */
3944 if (el_mode != DFmode
3945 || n != 2)
3946 return NULL_TREE;
3947 break;
3949 case BUILT_IN_ATAN2F:
3950 case BUILT_IN_HYPOTF:
3951 case BUILT_IN_POWF:
3952 n_args = 2;
3953 /* fall through */
3955 case BUILT_IN_ACOSF:
3956 case BUILT_IN_ACOSHF:
3957 case BUILT_IN_ASINF:
3958 case BUILT_IN_ASINHF:
3959 case BUILT_IN_ATANF:
3960 case BUILT_IN_ATANHF:
3961 case BUILT_IN_CBRTF:
3962 case BUILT_IN_COSF:
3963 case BUILT_IN_COSHF:
3964 case BUILT_IN_ERFF:
3965 case BUILT_IN_ERFCF:
3966 case BUILT_IN_EXP2F:
3967 case BUILT_IN_EXPF:
3968 case BUILT_IN_EXPM1F:
3969 case BUILT_IN_LGAMMAF:
3970 case BUILT_IN_LOG10F:
3971 case BUILT_IN_LOG1PF:
3972 case BUILT_IN_LOG2F:
3973 case BUILT_IN_LOGF:
3974 case BUILT_IN_SINF:
3975 case BUILT_IN_SINHF:
3976 case BUILT_IN_SQRTF:
3977 case BUILT_IN_TANF:
3978 case BUILT_IN_TANHF:
3979 bdecl = implicit_built_in_decls[fn];
3980 suffix = "4"; /* powf -> powf4 */
3981 if (el_mode != SFmode
3982 || n != 4)
3983 return NULL_TREE;
3984 break;
3986 default:
3987 return NULL_TREE;
3990 else
3991 return NULL_TREE;
3993 gcc_assert (suffix != NULL);
3994 bname = IDENTIFIER_POINTER (DECL_NAME (bdecl));
3995 strcpy (name, bname + sizeof ("__builtin_") - 1);
3996 strcat (name, suffix);
3998 if (n_args == 1)
3999 fntype = build_function_type_list (type_out, type_in, NULL);
4000 else if (n_args == 2)
4001 fntype = build_function_type_list (type_out, type_in, type_in, NULL);
4002 else
4003 gcc_unreachable ();
4005 /* Build a function declaration for the vectorized function. */
4006 new_fndecl = build_decl (BUILTINS_LOCATION,
4007 FUNCTION_DECL, get_identifier (name), fntype);
4008 TREE_PUBLIC (new_fndecl) = 1;
4009 DECL_EXTERNAL (new_fndecl) = 1;
4010 DECL_IS_NOVOPS (new_fndecl) = 1;
4011 TREE_READONLY (new_fndecl) = 1;
4013 return new_fndecl;
4016 /* Returns a function decl for a vectorized version of the builtin function
4017 with builtin function code FN and the result vector type TYPE, or NULL_TREE
4018 if it is not available. */
4020 static tree
4021 rs6000_builtin_vectorized_function (tree fndecl, tree type_out,
4022 tree type_in)
4024 enum machine_mode in_mode, out_mode;
4025 int in_n, out_n;
4027 if (TREE_CODE (type_out) != VECTOR_TYPE
4028 || TREE_CODE (type_in) != VECTOR_TYPE
4029 || !TARGET_VECTORIZE_BUILTINS)
4030 return NULL_TREE;
4032 out_mode = TYPE_MODE (TREE_TYPE (type_out));
4033 out_n = TYPE_VECTOR_SUBPARTS (type_out);
4034 in_mode = TYPE_MODE (TREE_TYPE (type_in));
4035 in_n = TYPE_VECTOR_SUBPARTS (type_in);
4037 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
4039 enum built_in_function fn = DECL_FUNCTION_CODE (fndecl);
4040 switch (fn)
4042 case BUILT_IN_COPYSIGN:
4043 if (VECTOR_UNIT_VSX_P (V2DFmode)
4044 && out_mode == DFmode && out_n == 2
4045 && in_mode == DFmode && in_n == 2)
4046 return rs6000_builtin_decls[VSX_BUILTIN_CPSGNDP];
4047 break;
4048 case BUILT_IN_COPYSIGNF:
4049 if (out_mode != SFmode || out_n != 4
4050 || in_mode != SFmode || in_n != 4)
4051 break;
4052 if (VECTOR_UNIT_VSX_P (V4SFmode))
4053 return rs6000_builtin_decls[VSX_BUILTIN_CPSGNSP];
4054 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
4055 return rs6000_builtin_decls[ALTIVEC_BUILTIN_COPYSIGN_V4SF];
4056 break;
4057 case BUILT_IN_SQRT:
4058 if (VECTOR_UNIT_VSX_P (V2DFmode)
4059 && out_mode == DFmode && out_n == 2
4060 && in_mode == DFmode && in_n == 2)
4061 return rs6000_builtin_decls[VSX_BUILTIN_XVSQRTDP];
4062 break;
4063 case BUILT_IN_SQRTF:
4064 if (VECTOR_UNIT_VSX_P (V4SFmode)
4065 && out_mode == SFmode && out_n == 4
4066 && in_mode == SFmode && in_n == 4)
4067 return rs6000_builtin_decls[VSX_BUILTIN_XVSQRTSP];
4068 break;
4069 case BUILT_IN_CEIL:
4070 if (VECTOR_UNIT_VSX_P (V2DFmode)
4071 && out_mode == DFmode && out_n == 2
4072 && in_mode == DFmode && in_n == 2)
4073 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIP];
4074 break;
4075 case BUILT_IN_CEILF:
4076 if (out_mode != SFmode || out_n != 4
4077 || in_mode != SFmode || in_n != 4)
4078 break;
4079 if (VECTOR_UNIT_VSX_P (V4SFmode))
4080 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIP];
4081 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
4082 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIP];
4083 break;
4084 case BUILT_IN_FLOOR:
4085 if (VECTOR_UNIT_VSX_P (V2DFmode)
4086 && out_mode == DFmode && out_n == 2
4087 && in_mode == DFmode && in_n == 2)
4088 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIM];
4089 break;
4090 case BUILT_IN_FLOORF:
4091 if (out_mode != SFmode || out_n != 4
4092 || in_mode != SFmode || in_n != 4)
4093 break;
4094 if (VECTOR_UNIT_VSX_P (V4SFmode))
4095 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIM];
4096 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
4097 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIM];
4098 break;
4099 case BUILT_IN_FMA:
4100 if (VECTOR_UNIT_VSX_P (V2DFmode)
4101 && out_mode == DFmode && out_n == 2
4102 && in_mode == DFmode && in_n == 2)
4103 return rs6000_builtin_decls[VSX_BUILTIN_XVMADDDP];
4104 break;
4105 case BUILT_IN_FMAF:
4106 if (VECTOR_UNIT_VSX_P (V4SFmode)
4107 && out_mode == SFmode && out_n == 4
4108 && in_mode == SFmode && in_n == 4)
4109 return rs6000_builtin_decls[VSX_BUILTIN_XVMADDSP];
4110 else if (VECTOR_UNIT_ALTIVEC_P (V4SFmode)
4111 && out_mode == SFmode && out_n == 4
4112 && in_mode == SFmode && in_n == 4)
4113 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VMADDFP];
4114 break;
4115 case BUILT_IN_TRUNC:
4116 if (VECTOR_UNIT_VSX_P (V2DFmode)
4117 && out_mode == DFmode && out_n == 2
4118 && in_mode == DFmode && in_n == 2)
4119 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIZ];
4120 break;
4121 case BUILT_IN_TRUNCF:
4122 if (out_mode != SFmode || out_n != 4
4123 || in_mode != SFmode || in_n != 4)
4124 break;
4125 if (VECTOR_UNIT_VSX_P (V4SFmode))
4126 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIZ];
4127 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
4128 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIZ];
4129 break;
4130 case BUILT_IN_NEARBYINT:
4131 if (VECTOR_UNIT_VSX_P (V2DFmode)
4132 && flag_unsafe_math_optimizations
4133 && out_mode == DFmode && out_n == 2
4134 && in_mode == DFmode && in_n == 2)
4135 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPI];
4136 break;
4137 case BUILT_IN_NEARBYINTF:
4138 if (VECTOR_UNIT_VSX_P (V4SFmode)
4139 && flag_unsafe_math_optimizations
4140 && out_mode == SFmode && out_n == 4
4141 && in_mode == SFmode && in_n == 4)
4142 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPI];
4143 break;
4144 case BUILT_IN_RINT:
4145 if (VECTOR_UNIT_VSX_P (V2DFmode)
4146 && !flag_trapping_math
4147 && out_mode == DFmode && out_n == 2
4148 && in_mode == DFmode && in_n == 2)
4149 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIC];
4150 break;
4151 case BUILT_IN_RINTF:
4152 if (VECTOR_UNIT_VSX_P (V4SFmode)
4153 && !flag_trapping_math
4154 && out_mode == SFmode && out_n == 4
4155 && in_mode == SFmode && in_n == 4)
4156 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIC];
4157 break;
4158 default:
4159 break;
4163 else if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
4165 enum rs6000_builtins fn
4166 = (enum rs6000_builtins)DECL_FUNCTION_CODE (fndecl);
4167 switch (fn)
4169 case RS6000_BUILTIN_RSQRTF:
4170 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)
4171 && out_mode == SFmode && out_n == 4
4172 && in_mode == SFmode && in_n == 4)
4173 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRSQRTFP];
4174 break;
4175 case RS6000_BUILTIN_RSQRT:
4176 if (VECTOR_UNIT_VSX_P (V2DFmode)
4177 && out_mode == DFmode && out_n == 2
4178 && in_mode == DFmode && in_n == 2)
4179 return rs6000_builtin_decls[VSX_BUILTIN_VEC_RSQRT_V2DF];
4180 break;
4181 case RS6000_BUILTIN_RECIPF:
4182 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)
4183 && out_mode == SFmode && out_n == 4
4184 && in_mode == SFmode && in_n == 4)
4185 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRECIPFP];
4186 break;
4187 case RS6000_BUILTIN_RECIP:
4188 if (VECTOR_UNIT_VSX_P (V2DFmode)
4189 && out_mode == DFmode && out_n == 2
4190 && in_mode == DFmode && in_n == 2)
4191 return rs6000_builtin_decls[VSX_BUILTIN_RECIP_V2DF];
4192 break;
4193 default:
4194 break;
4198 /* Generate calls to libmass if appropriate. */
4199 if (rs6000_veclib_handler)
4200 return rs6000_veclib_handler (fndecl, type_out, type_in);
4202 return NULL_TREE;
4206 /* Implement TARGET_HANDLE_OPTION. */
4208 static bool
4209 rs6000_handle_option (struct gcc_options *opts, struct gcc_options *opts_set,
4210 const struct cl_decoded_option *decoded,
4211 location_t loc ATTRIBUTE_UNUSED)
4213 enum fpu_type_t fpu_type = FPU_NONE;
4214 int isel;
4215 char *p, *q;
4216 size_t code = decoded->opt_index;
4217 const char *arg = decoded->arg;
4218 int value = decoded->value;
4220 gcc_assert (opts == &global_options);
4221 gcc_assert (opts_set == &global_options_set);
4223 switch (code)
4225 case OPT_mno_power:
4226 target_flags &= ~(MASK_POWER | MASK_POWER2
4227 | MASK_MULTIPLE | MASK_STRING);
4228 target_flags_explicit |= (MASK_POWER | MASK_POWER2
4229 | MASK_MULTIPLE | MASK_STRING);
4230 break;
4231 case OPT_mno_powerpc:
4232 target_flags &= ~(MASK_POWERPC | MASK_PPC_GPOPT
4233 | MASK_PPC_GFXOPT | MASK_POWERPC64);
4234 target_flags_explicit |= (MASK_POWERPC | MASK_PPC_GPOPT
4235 | MASK_PPC_GFXOPT | MASK_POWERPC64);
4236 break;
4237 case OPT_mfull_toc:
4238 target_flags &= ~MASK_MINIMAL_TOC;
4239 TARGET_NO_FP_IN_TOC = 0;
4240 TARGET_NO_SUM_IN_TOC = 0;
4241 target_flags_explicit |= MASK_MINIMAL_TOC;
4242 #ifdef TARGET_USES_SYSV4_OPT
4243 /* Note, V.4 no longer uses a normal TOC, so make -mfull-toc, be
4244 just the same as -mminimal-toc. */
4245 target_flags |= MASK_MINIMAL_TOC;
4246 target_flags_explicit |= MASK_MINIMAL_TOC;
4247 #endif
4248 break;
4250 #ifdef TARGET_USES_SYSV4_OPT
4251 case OPT_mtoc:
4252 /* Make -mtoc behave like -mminimal-toc. */
4253 target_flags |= MASK_MINIMAL_TOC;
4254 target_flags_explicit |= MASK_MINIMAL_TOC;
4255 break;
4256 #endif
4258 #if defined (HAVE_LD_LARGE_TOC) && defined (TARGET_USES_LINUX64_OPT)
4259 case OPT_mcmodel_:
4260 if (strcmp (arg, "small") == 0)
4261 rs6000_current_cmodel = CMODEL_SMALL;
4262 else if (strcmp (arg, "medium") == 0)
4263 rs6000_current_cmodel = CMODEL_MEDIUM;
4264 else if (strcmp (arg, "large") == 0)
4265 rs6000_current_cmodel = CMODEL_LARGE;
4266 else
4268 error ("invalid option for -mcmodel: '%s'", arg);
4269 return false;
4271 rs6000_explicit_options.cmodel = true;
4272 #endif
4274 #ifdef TARGET_USES_AIX64_OPT
4275 case OPT_maix64:
4276 #else
4277 case OPT_m64:
4278 #endif
4279 target_flags |= MASK_POWERPC64 | MASK_POWERPC;
4280 target_flags |= ~target_flags_explicit & MASK_PPC_GFXOPT;
4281 target_flags_explicit |= MASK_POWERPC64 | MASK_POWERPC;
4282 break;
4284 #ifdef TARGET_USES_AIX64_OPT
4285 case OPT_maix32:
4286 #else
4287 case OPT_m32:
4288 #endif
4289 target_flags &= ~MASK_POWERPC64;
4290 target_flags_explicit |= MASK_POWERPC64;
4291 break;
4293 case OPT_minsert_sched_nops_:
4294 rs6000_sched_insert_nops_str = arg;
4295 break;
4297 case OPT_mminimal_toc:
4298 if (value == 1)
4300 TARGET_NO_FP_IN_TOC = 0;
4301 TARGET_NO_SUM_IN_TOC = 0;
4303 break;
4305 case OPT_mpower:
4306 if (value == 1)
4308 target_flags |= (MASK_MULTIPLE | MASK_STRING);
4309 target_flags_explicit |= (MASK_MULTIPLE | MASK_STRING);
4311 break;
4313 case OPT_mpower2:
4314 if (value == 1)
4316 target_flags |= (MASK_POWER | MASK_MULTIPLE | MASK_STRING);
4317 target_flags_explicit |= (MASK_POWER | MASK_MULTIPLE | MASK_STRING);
4319 break;
4321 case OPT_mpowerpc_gpopt:
4322 case OPT_mpowerpc_gfxopt:
4323 if (value == 1)
4325 target_flags |= MASK_POWERPC;
4326 target_flags_explicit |= MASK_POWERPC;
4328 break;
4330 case OPT_maix_struct_return:
4331 case OPT_msvr4_struct_return:
4332 rs6000_explicit_options.aix_struct_ret = true;
4333 break;
4335 case OPT_mvrsave:
4336 rs6000_explicit_options.vrsave = true;
4337 TARGET_ALTIVEC_VRSAVE = value;
4338 break;
4340 case OPT_mvrsave_:
4341 rs6000_explicit_options.vrsave = true;
4342 rs6000_parse_yes_no_option ("vrsave", arg, &(TARGET_ALTIVEC_VRSAVE));
4343 break;
4345 case OPT_misel_:
4346 target_flags_explicit |= MASK_ISEL;
4347 isel = 0;
4348 rs6000_parse_yes_no_option ("isel", arg, &isel);
4349 if (isel)
4350 target_flags |= MASK_ISEL;
4351 else
4352 target_flags &= ~MASK_ISEL;
4353 break;
4355 case OPT_mspe:
4356 rs6000_explicit_options.spe = true;
4357 rs6000_spe = value;
4358 break;
4360 case OPT_mspe_:
4361 rs6000_explicit_options.spe = true;
4362 rs6000_parse_yes_no_option ("spe", arg, &(rs6000_spe));
4363 break;
4365 case OPT_mdebug_:
4366 p = ASTRDUP (arg);
4367 rs6000_debug = 0;
4369 while ((q = strtok (p, ",")) != NULL)
4371 unsigned mask = 0;
4372 bool invert;
4374 p = NULL;
4375 if (*q == '!')
4377 invert = true;
4378 q++;
4380 else
4381 invert = false;
4383 if (! strcmp (q, "all"))
4384 mask = MASK_DEBUG_ALL;
4385 else if (! strcmp (q, "stack"))
4386 mask = MASK_DEBUG_STACK;
4387 else if (! strcmp (q, "arg"))
4388 mask = MASK_DEBUG_ARG;
4389 else if (! strcmp (q, "reg"))
4390 mask = MASK_DEBUG_REG;
4391 else if (! strcmp (q, "addr"))
4392 mask = MASK_DEBUG_ADDR;
4393 else if (! strcmp (q, "cost"))
4394 mask = MASK_DEBUG_COST;
4395 else if (! strcmp (q, "target"))
4396 mask = MASK_DEBUG_TARGET;
4397 else
4398 error ("unknown -mdebug-%s switch", q);
4400 if (invert)
4401 rs6000_debug &= ~mask;
4402 else
4403 rs6000_debug |= mask;
4405 break;
4407 #ifdef TARGET_USES_SYSV4_OPT
4408 case OPT_mcall_:
4409 rs6000_abi_name = arg;
4410 break;
4412 case OPT_msdata_:
4413 rs6000_sdata_name = arg;
4414 break;
4416 case OPT_mtls_size_:
4417 if (strcmp (arg, "16") == 0)
4418 rs6000_tls_size = 16;
4419 else if (strcmp (arg, "32") == 0)
4420 rs6000_tls_size = 32;
4421 else if (strcmp (arg, "64") == 0)
4422 rs6000_tls_size = 64;
4423 else
4424 error ("bad value %qs for -mtls-size switch", arg);
4425 break;
4427 case OPT_mrelocatable:
4428 if (value == 1)
4430 target_flags |= MASK_MINIMAL_TOC;
4431 target_flags_explicit |= MASK_MINIMAL_TOC;
4432 TARGET_NO_FP_IN_TOC = 1;
4434 break;
4436 case OPT_mrelocatable_lib:
4437 if (value == 1)
4439 target_flags |= MASK_RELOCATABLE | MASK_MINIMAL_TOC;
4440 target_flags_explicit |= MASK_RELOCATABLE | MASK_MINIMAL_TOC;
4441 TARGET_NO_FP_IN_TOC = 1;
4443 else
4445 target_flags &= ~MASK_RELOCATABLE;
4446 target_flags_explicit |= MASK_RELOCATABLE;
4448 break;
4449 #endif
4451 case OPT_mabi_:
4452 if (!strcmp (arg, "altivec"))
4454 rs6000_explicit_options.altivec_abi = true;
4455 rs6000_altivec_abi = 1;
4457 /* Enabling the AltiVec ABI turns off the SPE ABI. */
4458 rs6000_spe_abi = 0;
4460 else if (! strcmp (arg, "no-altivec"))
4462 rs6000_explicit_options.altivec_abi = true;
4463 rs6000_altivec_abi = 0;
4465 else if (! strcmp (arg, "spe"))
4467 rs6000_explicit_options.spe_abi = true;
4468 rs6000_spe_abi = 1;
4469 rs6000_altivec_abi = 0;
4470 if (!TARGET_SPE_ABI)
4471 error ("not configured for ABI: '%s'", arg);
4473 else if (! strcmp (arg, "no-spe"))
4475 rs6000_explicit_options.spe_abi = true;
4476 rs6000_spe_abi = 0;
4479 /* These are here for testing during development only, do not
4480 document in the manual please. */
4481 else if (! strcmp (arg, "d64"))
4483 rs6000_darwin64_abi = 1;
4484 warning (0, "using darwin64 ABI");
4486 else if (! strcmp (arg, "d32"))
4488 rs6000_darwin64_abi = 0;
4489 warning (0, "using old darwin ABI");
4492 else if (! strcmp (arg, "ibmlongdouble"))
4494 rs6000_explicit_options.ieee = true;
4495 rs6000_ieeequad = 0;
4496 warning (0, "using IBM extended precision long double");
4498 else if (! strcmp (arg, "ieeelongdouble"))
4500 rs6000_explicit_options.ieee = true;
4501 rs6000_ieeequad = 1;
4502 warning (0, "using IEEE extended precision long double");
4505 else
4507 error ("unknown ABI specified: '%s'", arg);
4508 return false;
4510 break;
4512 case OPT_mcpu_:
4513 rs6000_select[1].string = arg;
4514 rs6000_cpu_index = rs6000_cpu_name_lookup (arg);
4515 if (rs6000_cpu_index < 0)
4516 error ("bad value (%s) for -mcpu", arg);
4517 break;
4519 case OPT_mtune_:
4520 rs6000_select[2].string = arg;
4521 rs6000_tune_index = rs6000_cpu_name_lookup (arg);
4522 if (rs6000_tune_index < 0)
4523 error ("bad value (%s) for -mtune", arg);
4524 break;
4526 case OPT_mtraceback_:
4527 if (! strncmp (arg, "full", 4))
4528 rs6000_traceback = traceback_full;
4529 else if (! strncmp (arg, "part", 4))
4530 rs6000_traceback = traceback_part;
4531 else if (! strncmp (arg, "no", 2))
4532 rs6000_traceback = traceback_none;
4533 else
4534 error ("unknown -mtraceback arg %qs; expecting %<full%>, "
4535 "%<partial%> or %<none%>", arg);
4536 break;
4538 case OPT_mfloat_gprs_:
4539 rs6000_explicit_options.float_gprs = true;
4540 if (! strcmp (arg, "yes") || ! strcmp (arg, "single"))
4541 rs6000_float_gprs = 1;
4542 else if (! strcmp (arg, "double"))
4543 rs6000_float_gprs = 2;
4544 else if (! strcmp (arg, "no"))
4545 rs6000_float_gprs = 0;
4546 else
4548 error ("invalid option for -mfloat-gprs: '%s'", arg);
4549 return false;
4551 break;
4553 case OPT_mlong_double_:
4554 rs6000_explicit_options.long_double = true;
4555 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
4556 if (value != 64 && value != 128)
4558 error ("unknown switch -mlong-double-%s", arg);
4559 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
4560 return false;
4562 else
4563 rs6000_long_double_type_size = value;
4564 break;
4566 case OPT_msched_costly_dep_:
4567 rs6000_sched_costly_dep_str = arg;
4568 break;
4570 case OPT_malign_:
4571 rs6000_explicit_options.alignment = true;
4572 if (! strcmp (arg, "power"))
4574 /* On 64-bit Darwin, power alignment is ABI-incompatible with
4575 some C library functions, so warn about it. The flag may be
4576 useful for performance studies from time to time though, so
4577 don't disable it entirely. */
4578 if (DEFAULT_ABI == ABI_DARWIN && TARGET_64BIT)
4579 warning (0, "-malign-power is not supported for 64-bit Darwin;"
4580 " it is incompatible with the installed C and C++ libraries");
4581 rs6000_alignment_flags = MASK_ALIGN_POWER;
4583 else if (! strcmp (arg, "natural"))
4584 rs6000_alignment_flags = MASK_ALIGN_NATURAL;
4585 else
4587 error ("unknown -malign-XXXXX option specified: '%s'", arg);
4588 return false;
4590 break;
4592 case OPT_msingle_float:
4593 if (!TARGET_SINGLE_FPU)
4594 warning (0, "-msingle-float option equivalent to -mhard-float");
4595 /* -msingle-float implies -mno-double-float and TARGET_HARD_FLOAT. */
4596 rs6000_double_float = 0;
4597 target_flags &= ~MASK_SOFT_FLOAT;
4598 target_flags_explicit |= MASK_SOFT_FLOAT;
4599 break;
4601 case OPT_mdouble_float:
4602 /* -mdouble-float implies -msingle-float and TARGET_HARD_FLOAT. */
4603 rs6000_single_float = 1;
4604 target_flags &= ~MASK_SOFT_FLOAT;
4605 target_flags_explicit |= MASK_SOFT_FLOAT;
4606 break;
4608 case OPT_msimple_fpu:
4609 if (!TARGET_SINGLE_FPU)
4610 warning (0, "-msimple-fpu option ignored");
4611 break;
4613 case OPT_mhard_float:
4614 /* -mhard_float implies -msingle-float and -mdouble-float. */
4615 rs6000_single_float = rs6000_double_float = 1;
4616 break;
4618 case OPT_msoft_float:
4619 /* -msoft_float implies -mnosingle-float and -mnodouble-float. */
4620 rs6000_single_float = rs6000_double_float = 0;
4621 break;
4623 case OPT_mfpu_:
4624 fpu_type = rs6000_parse_fpu_option(arg);
4625 if (fpu_type != FPU_NONE)
4626 /* If -mfpu is not none, then turn off SOFT_FLOAT, turn on HARD_FLOAT. */
4628 target_flags &= ~MASK_SOFT_FLOAT;
4629 target_flags_explicit |= MASK_SOFT_FLOAT;
4630 rs6000_xilinx_fpu = 1;
4631 if (fpu_type == FPU_SF_LITE || fpu_type == FPU_SF_FULL)
4632 rs6000_single_float = 1;
4633 if (fpu_type == FPU_DF_LITE || fpu_type == FPU_DF_FULL)
4634 rs6000_single_float = rs6000_double_float = 1;
4635 if (fpu_type == FPU_SF_LITE || fpu_type == FPU_DF_LITE)
4636 rs6000_simple_fpu = 1;
4638 else
4640 /* -mfpu=none is equivalent to -msoft-float */
4641 target_flags |= MASK_SOFT_FLOAT;
4642 target_flags_explicit |= MASK_SOFT_FLOAT;
4643 rs6000_single_float = rs6000_double_float = 0;
4646 case OPT_mrecip:
4647 rs6000_recip_name = (value) ? "default" : "none";
4648 break;
4650 case OPT_mrecip_:
4651 rs6000_recip_name = arg;
4652 break;
4654 return true;
4657 /* Do anything needed at the start of the asm file. */
4659 static void
4660 rs6000_file_start (void)
4662 size_t i;
4663 char buffer[80];
4664 const char *start = buffer;
4665 struct rs6000_cpu_select *ptr;
4666 const char *default_cpu = TARGET_CPU_DEFAULT;
4667 FILE *file = asm_out_file;
4669 default_file_start ();
4671 #ifdef TARGET_BI_ARCH
4672 if ((TARGET_DEFAULT ^ target_flags) & MASK_64BIT)
4673 default_cpu = 0;
4674 #endif
4676 if (flag_verbose_asm)
4678 sprintf (buffer, "\n%s rs6000/powerpc options:", ASM_COMMENT_START);
4679 rs6000_select[0].string = default_cpu;
4681 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
4683 ptr = &rs6000_select[i];
4684 if (ptr->string != (char *)0 && ptr->string[0] != '\0')
4686 fprintf (file, "%s %s%s", start, ptr->name, ptr->string);
4687 start = "";
4691 if (PPC405_ERRATUM77)
4693 fprintf (file, "%s PPC405CR_ERRATUM77", start);
4694 start = "";
4697 #ifdef USING_ELFOS_H
4698 switch (rs6000_sdata)
4700 case SDATA_NONE: fprintf (file, "%s -msdata=none", start); start = ""; break;
4701 case SDATA_DATA: fprintf (file, "%s -msdata=data", start); start = ""; break;
4702 case SDATA_SYSV: fprintf (file, "%s -msdata=sysv", start); start = ""; break;
4703 case SDATA_EABI: fprintf (file, "%s -msdata=eabi", start); start = ""; break;
4706 if (rs6000_sdata && g_switch_value)
4708 fprintf (file, "%s -G %d", start,
4709 g_switch_value);
4710 start = "";
4712 #endif
4714 if (*start == '\0')
4715 putc ('\n', file);
4718 if (DEFAULT_ABI == ABI_AIX || (TARGET_ELF && flag_pic == 2))
4720 switch_to_section (toc_section);
4721 switch_to_section (text_section);
4726 /* Return nonzero if this function is known to have a null epilogue. */
4729 direct_return (void)
4731 if (reload_completed)
4733 rs6000_stack_t *info = rs6000_stack_info ();
4735 if (info->first_gp_reg_save == 32
4736 && info->first_fp_reg_save == 64
4737 && info->first_altivec_reg_save == LAST_ALTIVEC_REGNO + 1
4738 && ! info->lr_save_p
4739 && ! info->cr_save_p
4740 && info->vrsave_mask == 0
4741 && ! info->push_p)
4742 return 1;
4745 return 0;
4748 /* Return the number of instructions it takes to form a constant in an
4749 integer register. */
4752 num_insns_constant_wide (HOST_WIDE_INT value)
4754 /* signed constant loadable with {cal|addi} */
4755 if ((unsigned HOST_WIDE_INT) (value + 0x8000) < 0x10000)
4756 return 1;
4758 /* constant loadable with {cau|addis} */
4759 else if ((value & 0xffff) == 0
4760 && (value >> 31 == -1 || value >> 31 == 0))
4761 return 1;
4763 #if HOST_BITS_PER_WIDE_INT == 64
4764 else if (TARGET_POWERPC64)
4766 HOST_WIDE_INT low = ((value & 0xffffffff) ^ 0x80000000) - 0x80000000;
4767 HOST_WIDE_INT high = value >> 31;
4769 if (high == 0 || high == -1)
4770 return 2;
4772 high >>= 1;
4774 if (low == 0)
4775 return num_insns_constant_wide (high) + 1;
4776 else if (high == 0)
4777 return num_insns_constant_wide (low) + 1;
4778 else
4779 return (num_insns_constant_wide (high)
4780 + num_insns_constant_wide (low) + 1);
4782 #endif
4784 else
4785 return 2;
4789 num_insns_constant (rtx op, enum machine_mode mode)
4791 HOST_WIDE_INT low, high;
4793 switch (GET_CODE (op))
4795 case CONST_INT:
4796 #if HOST_BITS_PER_WIDE_INT == 64
4797 if ((INTVAL (op) >> 31) != 0 && (INTVAL (op) >> 31) != -1
4798 && mask64_operand (op, mode))
4799 return 2;
4800 else
4801 #endif
4802 return num_insns_constant_wide (INTVAL (op));
4804 case CONST_DOUBLE:
4805 if (mode == SFmode || mode == SDmode)
4807 long l;
4808 REAL_VALUE_TYPE rv;
4810 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
4811 if (DECIMAL_FLOAT_MODE_P (mode))
4812 REAL_VALUE_TO_TARGET_DECIMAL32 (rv, l);
4813 else
4814 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
4815 return num_insns_constant_wide ((HOST_WIDE_INT) l);
4818 if (mode == VOIDmode || mode == DImode)
4820 high = CONST_DOUBLE_HIGH (op);
4821 low = CONST_DOUBLE_LOW (op);
4823 else
4825 long l[2];
4826 REAL_VALUE_TYPE rv;
4828 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
4829 if (DECIMAL_FLOAT_MODE_P (mode))
4830 REAL_VALUE_TO_TARGET_DECIMAL64 (rv, l);
4831 else
4832 REAL_VALUE_TO_TARGET_DOUBLE (rv, l);
4833 high = l[WORDS_BIG_ENDIAN == 0];
4834 low = l[WORDS_BIG_ENDIAN != 0];
4837 if (TARGET_32BIT)
4838 return (num_insns_constant_wide (low)
4839 + num_insns_constant_wide (high));
4840 else
4842 if ((high == 0 && low >= 0)
4843 || (high == -1 && low < 0))
4844 return num_insns_constant_wide (low);
4846 else if (mask64_operand (op, mode))
4847 return 2;
4849 else if (low == 0)
4850 return num_insns_constant_wide (high) + 1;
4852 else
4853 return (num_insns_constant_wide (high)
4854 + num_insns_constant_wide (low) + 1);
4857 default:
4858 gcc_unreachable ();
4862 /* Interpret element ELT of the CONST_VECTOR OP as an integer value.
4863 If the mode of OP is MODE_VECTOR_INT, this simply returns the
4864 corresponding element of the vector, but for V4SFmode and V2SFmode,
4865 the corresponding "float" is interpreted as an SImode integer. */
4867 HOST_WIDE_INT
4868 const_vector_elt_as_int (rtx op, unsigned int elt)
4870 rtx tmp;
4872 /* We can't handle V2DImode and V2DFmode vector constants here yet. */
4873 gcc_assert (GET_MODE (op) != V2DImode
4874 && GET_MODE (op) != V2DFmode);
4876 tmp = CONST_VECTOR_ELT (op, elt);
4877 if (GET_MODE (op) == V4SFmode
4878 || GET_MODE (op) == V2SFmode)
4879 tmp = gen_lowpart (SImode, tmp);
4880 return INTVAL (tmp);
4883 /* Return true if OP can be synthesized with a particular vspltisb, vspltish
4884 or vspltisw instruction. OP is a CONST_VECTOR. Which instruction is used
4885 depends on STEP and COPIES, one of which will be 1. If COPIES > 1,
4886 all items are set to the same value and contain COPIES replicas of the
4887 vsplt's operand; if STEP > 1, one in STEP elements is set to the vsplt's
4888 operand and the others are set to the value of the operand's msb. */
4890 static bool
4891 vspltis_constant (rtx op, unsigned step, unsigned copies)
4893 enum machine_mode mode = GET_MODE (op);
4894 enum machine_mode inner = GET_MODE_INNER (mode);
4896 unsigned i;
4897 unsigned nunits;
4898 unsigned bitsize;
4899 unsigned mask;
4901 HOST_WIDE_INT val;
4902 HOST_WIDE_INT splat_val;
4903 HOST_WIDE_INT msb_val;
4905 if (mode == V2DImode || mode == V2DFmode)
4906 return false;
4908 nunits = GET_MODE_NUNITS (mode);
4909 bitsize = GET_MODE_BITSIZE (inner);
4910 mask = GET_MODE_MASK (inner);
4912 val = const_vector_elt_as_int (op, nunits - 1);
4913 splat_val = val;
4914 msb_val = val > 0 ? 0 : -1;
4916 /* Construct the value to be splatted, if possible. If not, return 0. */
4917 for (i = 2; i <= copies; i *= 2)
4919 HOST_WIDE_INT small_val;
4920 bitsize /= 2;
4921 small_val = splat_val >> bitsize;
4922 mask >>= bitsize;
4923 if (splat_val != ((small_val << bitsize) | (small_val & mask)))
4924 return false;
4925 splat_val = small_val;
4928 /* Check if SPLAT_VAL can really be the operand of a vspltis[bhw]. */
4929 if (EASY_VECTOR_15 (splat_val))
4932 /* Also check if we can splat, and then add the result to itself. Do so if
4933 the value is positive, of if the splat instruction is using OP's mode;
4934 for splat_val < 0, the splat and the add should use the same mode. */
4935 else if (EASY_VECTOR_15_ADD_SELF (splat_val)
4936 && (splat_val >= 0 || (step == 1 && copies == 1)))
4939 /* Also check if are loading up the most significant bit which can be done by
4940 loading up -1 and shifting the value left by -1. */
4941 else if (EASY_VECTOR_MSB (splat_val, inner))
4944 else
4945 return false;
4947 /* Check if VAL is present in every STEP-th element, and the
4948 other elements are filled with its most significant bit. */
4949 for (i = 0; i < nunits - 1; ++i)
4951 HOST_WIDE_INT desired_val;
4952 if (((i + 1) & (step - 1)) == 0)
4953 desired_val = val;
4954 else
4955 desired_val = msb_val;
4957 if (desired_val != const_vector_elt_as_int (op, i))
4958 return false;
4961 return true;
4965 /* Return true if OP is of the given MODE and can be synthesized
4966 with a vspltisb, vspltish or vspltisw. */
4968 bool
4969 easy_altivec_constant (rtx op, enum machine_mode mode)
4971 unsigned step, copies;
4973 if (mode == VOIDmode)
4974 mode = GET_MODE (op);
4975 else if (mode != GET_MODE (op))
4976 return false;
4978 /* V2DI/V2DF was added with VSX. Only allow 0 and all 1's as easy
4979 constants. */
4980 if (mode == V2DFmode)
4981 return zero_constant (op, mode);
4983 if (mode == V2DImode)
4985 /* In case the compiler is built 32-bit, CONST_DOUBLE constants are not
4986 easy. */
4987 if (GET_CODE (CONST_VECTOR_ELT (op, 0)) != CONST_INT
4988 || GET_CODE (CONST_VECTOR_ELT (op, 1)) != CONST_INT)
4989 return false;
4991 if (zero_constant (op, mode))
4992 return true;
4994 if (INTVAL (CONST_VECTOR_ELT (op, 0)) == -1
4995 && INTVAL (CONST_VECTOR_ELT (op, 1)) == -1)
4996 return true;
4998 return false;
5001 /* Start with a vspltisw. */
5002 step = GET_MODE_NUNITS (mode) / 4;
5003 copies = 1;
5005 if (vspltis_constant (op, step, copies))
5006 return true;
5008 /* Then try with a vspltish. */
5009 if (step == 1)
5010 copies <<= 1;
5011 else
5012 step >>= 1;
5014 if (vspltis_constant (op, step, copies))
5015 return true;
5017 /* And finally a vspltisb. */
5018 if (step == 1)
5019 copies <<= 1;
5020 else
5021 step >>= 1;
5023 if (vspltis_constant (op, step, copies))
5024 return true;
5026 return false;
5029 /* Generate a VEC_DUPLICATE representing a vspltis[bhw] instruction whose
5030 result is OP. Abort if it is not possible. */
5033 gen_easy_altivec_constant (rtx op)
5035 enum machine_mode mode = GET_MODE (op);
5036 int nunits = GET_MODE_NUNITS (mode);
5037 rtx last = CONST_VECTOR_ELT (op, nunits - 1);
5038 unsigned step = nunits / 4;
5039 unsigned copies = 1;
5041 /* Start with a vspltisw. */
5042 if (vspltis_constant (op, step, copies))
5043 return gen_rtx_VEC_DUPLICATE (V4SImode, gen_lowpart (SImode, last));
5045 /* Then try with a vspltish. */
5046 if (step == 1)
5047 copies <<= 1;
5048 else
5049 step >>= 1;
5051 if (vspltis_constant (op, step, copies))
5052 return gen_rtx_VEC_DUPLICATE (V8HImode, gen_lowpart (HImode, last));
5054 /* And finally a vspltisb. */
5055 if (step == 1)
5056 copies <<= 1;
5057 else
5058 step >>= 1;
5060 if (vspltis_constant (op, step, copies))
5061 return gen_rtx_VEC_DUPLICATE (V16QImode, gen_lowpart (QImode, last));
5063 gcc_unreachable ();
5066 const char *
5067 output_vec_const_move (rtx *operands)
5069 int cst, cst2;
5070 enum machine_mode mode;
5071 rtx dest, vec;
5073 dest = operands[0];
5074 vec = operands[1];
5075 mode = GET_MODE (dest);
5077 if (TARGET_VSX)
5079 if (zero_constant (vec, mode))
5080 return "xxlxor %x0,%x0,%x0";
5082 if (mode == V2DImode
5083 && INTVAL (CONST_VECTOR_ELT (vec, 0)) == -1
5084 && INTVAL (CONST_VECTOR_ELT (vec, 1)) == -1)
5085 return "vspltisw %0,-1";
5088 if (TARGET_ALTIVEC)
5090 rtx splat_vec;
5091 if (zero_constant (vec, mode))
5092 return "vxor %0,%0,%0";
5094 splat_vec = gen_easy_altivec_constant (vec);
5095 gcc_assert (GET_CODE (splat_vec) == VEC_DUPLICATE);
5096 operands[1] = XEXP (splat_vec, 0);
5097 if (!EASY_VECTOR_15 (INTVAL (operands[1])))
5098 return "#";
5100 switch (GET_MODE (splat_vec))
5102 case V4SImode:
5103 return "vspltisw %0,%1";
5105 case V8HImode:
5106 return "vspltish %0,%1";
5108 case V16QImode:
5109 return "vspltisb %0,%1";
5111 default:
5112 gcc_unreachable ();
5116 gcc_assert (TARGET_SPE);
5118 /* Vector constant 0 is handled as a splitter of V2SI, and in the
5119 pattern of V1DI, V4HI, and V2SF.
5121 FIXME: We should probably return # and add post reload
5122 splitters for these, but this way is so easy ;-). */
5123 cst = INTVAL (CONST_VECTOR_ELT (vec, 0));
5124 cst2 = INTVAL (CONST_VECTOR_ELT (vec, 1));
5125 operands[1] = CONST_VECTOR_ELT (vec, 0);
5126 operands[2] = CONST_VECTOR_ELT (vec, 1);
5127 if (cst == cst2)
5128 return "li %0,%1\n\tevmergelo %0,%0,%0";
5129 else
5130 return "li %0,%1\n\tevmergelo %0,%0,%0\n\tli %0,%2";
5133 /* Initialize TARGET of vector PAIRED to VALS. */
5135 void
5136 paired_expand_vector_init (rtx target, rtx vals)
5138 enum machine_mode mode = GET_MODE (target);
5139 int n_elts = GET_MODE_NUNITS (mode);
5140 int n_var = 0;
5141 rtx x, new_rtx, tmp, constant_op, op1, op2;
5142 int i;
5144 for (i = 0; i < n_elts; ++i)
5146 x = XVECEXP (vals, 0, i);
5147 if (!CONSTANT_P (x))
5148 ++n_var;
5150 if (n_var == 0)
5152 /* Load from constant pool. */
5153 emit_move_insn (target, gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0)));
5154 return;
5157 if (n_var == 2)
5159 /* The vector is initialized only with non-constants. */
5160 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, XVECEXP (vals, 0, 0),
5161 XVECEXP (vals, 0, 1));
5163 emit_move_insn (target, new_rtx);
5164 return;
5167 /* One field is non-constant and the other one is a constant. Load the
5168 constant from the constant pool and use ps_merge instruction to
5169 construct the whole vector. */
5170 op1 = XVECEXP (vals, 0, 0);
5171 op2 = XVECEXP (vals, 0, 1);
5173 constant_op = (CONSTANT_P (op1)) ? op1 : op2;
5175 tmp = gen_reg_rtx (GET_MODE (constant_op));
5176 emit_move_insn (tmp, constant_op);
5178 if (CONSTANT_P (op1))
5179 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, tmp, op2);
5180 else
5181 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, op1, tmp);
5183 emit_move_insn (target, new_rtx);
5186 void
5187 paired_expand_vector_move (rtx operands[])
5189 rtx op0 = operands[0], op1 = operands[1];
5191 emit_move_insn (op0, op1);
5194 /* Emit vector compare for code RCODE. DEST is destination, OP1 and
5195 OP2 are two VEC_COND_EXPR operands, CC_OP0 and CC_OP1 are the two
5196 operands for the relation operation COND. This is a recursive
5197 function. */
5199 static void
5200 paired_emit_vector_compare (enum rtx_code rcode,
5201 rtx dest, rtx op0, rtx op1,
5202 rtx cc_op0, rtx cc_op1)
5204 rtx tmp = gen_reg_rtx (V2SFmode);
5205 rtx tmp1, max, min;
5207 gcc_assert (TARGET_PAIRED_FLOAT);
5208 gcc_assert (GET_MODE (op0) == GET_MODE (op1));
5210 switch (rcode)
5212 case LT:
5213 case LTU:
5214 paired_emit_vector_compare (GE, dest, op1, op0, cc_op0, cc_op1);
5215 return;
5216 case GE:
5217 case GEU:
5218 emit_insn (gen_subv2sf3 (tmp, cc_op0, cc_op1));
5219 emit_insn (gen_selv2sf4 (dest, tmp, op0, op1, CONST0_RTX (SFmode)));
5220 return;
5221 case LE:
5222 case LEU:
5223 paired_emit_vector_compare (GE, dest, op0, op1, cc_op1, cc_op0);
5224 return;
5225 case GT:
5226 paired_emit_vector_compare (LE, dest, op1, op0, cc_op0, cc_op1);
5227 return;
5228 case EQ:
5229 tmp1 = gen_reg_rtx (V2SFmode);
5230 max = gen_reg_rtx (V2SFmode);
5231 min = gen_reg_rtx (V2SFmode);
5232 gen_reg_rtx (V2SFmode);
5234 emit_insn (gen_subv2sf3 (tmp, cc_op0, cc_op1));
5235 emit_insn (gen_selv2sf4
5236 (max, tmp, cc_op0, cc_op1, CONST0_RTX (SFmode)));
5237 emit_insn (gen_subv2sf3 (tmp, cc_op1, cc_op0));
5238 emit_insn (gen_selv2sf4
5239 (min, tmp, cc_op0, cc_op1, CONST0_RTX (SFmode)));
5240 emit_insn (gen_subv2sf3 (tmp1, min, max));
5241 emit_insn (gen_selv2sf4 (dest, tmp1, op0, op1, CONST0_RTX (SFmode)));
5242 return;
5243 case NE:
5244 paired_emit_vector_compare (EQ, dest, op1, op0, cc_op0, cc_op1);
5245 return;
5246 case UNLE:
5247 paired_emit_vector_compare (LE, dest, op1, op0, cc_op0, cc_op1);
5248 return;
5249 case UNLT:
5250 paired_emit_vector_compare (LT, dest, op1, op0, cc_op0, cc_op1);
5251 return;
5252 case UNGE:
5253 paired_emit_vector_compare (GE, dest, op1, op0, cc_op0, cc_op1);
5254 return;
5255 case UNGT:
5256 paired_emit_vector_compare (GT, dest, op1, op0, cc_op0, cc_op1);
5257 return;
5258 default:
5259 gcc_unreachable ();
5262 return;
5265 /* Emit vector conditional expression.
5266 DEST is destination. OP1 and OP2 are two VEC_COND_EXPR operands.
5267 CC_OP0 and CC_OP1 are the two operands for the relation operation COND. */
5270 paired_emit_vector_cond_expr (rtx dest, rtx op1, rtx op2,
5271 rtx cond, rtx cc_op0, rtx cc_op1)
5273 enum rtx_code rcode = GET_CODE (cond);
5275 if (!TARGET_PAIRED_FLOAT)
5276 return 0;
5278 paired_emit_vector_compare (rcode, dest, op1, op2, cc_op0, cc_op1);
5280 return 1;
5283 /* Initialize vector TARGET to VALS. */
5285 void
5286 rs6000_expand_vector_init (rtx target, rtx vals)
5288 enum machine_mode mode = GET_MODE (target);
5289 enum machine_mode inner_mode = GET_MODE_INNER (mode);
5290 int n_elts = GET_MODE_NUNITS (mode);
5291 int n_var = 0, one_var = -1;
5292 bool all_same = true, all_const_zero = true;
5293 rtx x, mem;
5294 int i;
5296 for (i = 0; i < n_elts; ++i)
5298 x = XVECEXP (vals, 0, i);
5299 if (!CONSTANT_P (x))
5300 ++n_var, one_var = i;
5301 else if (x != CONST0_RTX (inner_mode))
5302 all_const_zero = false;
5304 if (i > 0 && !rtx_equal_p (x, XVECEXP (vals, 0, 0)))
5305 all_same = false;
5308 if (n_var == 0)
5310 rtx const_vec = gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0));
5311 bool int_vector_p = (GET_MODE_CLASS (mode) == MODE_VECTOR_INT);
5312 if ((int_vector_p || TARGET_VSX) && all_const_zero)
5314 /* Zero register. */
5315 emit_insn (gen_rtx_SET (VOIDmode, target,
5316 gen_rtx_XOR (mode, target, target)));
5317 return;
5319 else if (int_vector_p && easy_vector_constant (const_vec, mode))
5321 /* Splat immediate. */
5322 emit_insn (gen_rtx_SET (VOIDmode, target, const_vec));
5323 return;
5325 else
5327 /* Load from constant pool. */
5328 emit_move_insn (target, const_vec);
5329 return;
5333 /* Double word values on VSX can use xxpermdi or lxvdsx. */
5334 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
5336 if (all_same)
5338 rtx element = XVECEXP (vals, 0, 0);
5339 if (mode == V2DFmode)
5340 emit_insn (gen_vsx_splat_v2df (target, element));
5341 else
5342 emit_insn (gen_vsx_splat_v2di (target, element));
5344 else
5346 if (mode == V2DFmode)
5348 rtx op0 = copy_to_mode_reg (DFmode, XVECEXP (vals, 0, 0));
5349 rtx op1 = copy_to_mode_reg (DFmode, XVECEXP (vals, 0, 1));
5350 emit_insn (gen_vsx_concat_v2df (target, op0, op1));
5352 else
5354 rtx op0 = copy_to_mode_reg (DImode, XVECEXP (vals, 0, 0));
5355 rtx op1 = copy_to_mode_reg (DImode, XVECEXP (vals, 0, 1));
5356 emit_insn (gen_vsx_concat_v2di (target, op0, op1));
5359 return;
5362 /* With single precision floating point on VSX, know that internally single
5363 precision is actually represented as a double, and either make 2 V2DF
5364 vectors, and convert these vectors to single precision, or do one
5365 conversion, and splat the result to the other elements. */
5366 if (mode == V4SFmode && VECTOR_MEM_VSX_P (mode))
5368 if (all_same)
5370 rtx freg = gen_reg_rtx (V4SFmode);
5371 rtx sreg = copy_to_reg (XVECEXP (vals, 0, 0));
5373 emit_insn (gen_vsx_xscvdpsp_scalar (freg, sreg));
5374 emit_insn (gen_vsx_xxspltw_v4sf (target, freg, const0_rtx));
5376 else
5378 rtx dbl_even = gen_reg_rtx (V2DFmode);
5379 rtx dbl_odd = gen_reg_rtx (V2DFmode);
5380 rtx flt_even = gen_reg_rtx (V4SFmode);
5381 rtx flt_odd = gen_reg_rtx (V4SFmode);
5383 emit_insn (gen_vsx_concat_v2sf (dbl_even,
5384 copy_to_reg (XVECEXP (vals, 0, 0)),
5385 copy_to_reg (XVECEXP (vals, 0, 1))));
5386 emit_insn (gen_vsx_concat_v2sf (dbl_odd,
5387 copy_to_reg (XVECEXP (vals, 0, 2)),
5388 copy_to_reg (XVECEXP (vals, 0, 3))));
5389 emit_insn (gen_vsx_xvcvdpsp (flt_even, dbl_even));
5390 emit_insn (gen_vsx_xvcvdpsp (flt_odd, dbl_odd));
5391 emit_insn (gen_vec_extract_evenv4sf (target, flt_even, flt_odd));
5393 return;
5396 /* Store value to stack temp. Load vector element. Splat. However, splat
5397 of 64-bit items is not supported on Altivec. */
5398 if (all_same && GET_MODE_SIZE (mode) <= 4)
5400 mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0);
5401 emit_move_insn (adjust_address_nv (mem, inner_mode, 0),
5402 XVECEXP (vals, 0, 0));
5403 x = gen_rtx_UNSPEC (VOIDmode,
5404 gen_rtvec (1, const0_rtx), UNSPEC_LVE);
5405 emit_insn (gen_rtx_PARALLEL (VOIDmode,
5406 gen_rtvec (2,
5407 gen_rtx_SET (VOIDmode,
5408 target, mem),
5409 x)));
5410 x = gen_rtx_VEC_SELECT (inner_mode, target,
5411 gen_rtx_PARALLEL (VOIDmode,
5412 gen_rtvec (1, const0_rtx)));
5413 emit_insn (gen_rtx_SET (VOIDmode, target,
5414 gen_rtx_VEC_DUPLICATE (mode, x)));
5415 return;
5418 /* One field is non-constant. Load constant then overwrite
5419 varying field. */
5420 if (n_var == 1)
5422 rtx copy = copy_rtx (vals);
5424 /* Load constant part of vector, substitute neighboring value for
5425 varying element. */
5426 XVECEXP (copy, 0, one_var) = XVECEXP (vals, 0, (one_var + 1) % n_elts);
5427 rs6000_expand_vector_init (target, copy);
5429 /* Insert variable. */
5430 rs6000_expand_vector_set (target, XVECEXP (vals, 0, one_var), one_var);
5431 return;
5434 /* Construct the vector in memory one field at a time
5435 and load the whole vector. */
5436 mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
5437 for (i = 0; i < n_elts; i++)
5438 emit_move_insn (adjust_address_nv (mem, inner_mode,
5439 i * GET_MODE_SIZE (inner_mode)),
5440 XVECEXP (vals, 0, i));
5441 emit_move_insn (target, mem);
5444 /* Set field ELT of TARGET to VAL. */
5446 void
5447 rs6000_expand_vector_set (rtx target, rtx val, int elt)
5449 enum machine_mode mode = GET_MODE (target);
5450 enum machine_mode inner_mode = GET_MODE_INNER (mode);
5451 rtx reg = gen_reg_rtx (mode);
5452 rtx mask, mem, x;
5453 int width = GET_MODE_SIZE (inner_mode);
5454 int i;
5456 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
5458 rtx (*set_func) (rtx, rtx, rtx, rtx)
5459 = ((mode == V2DFmode) ? gen_vsx_set_v2df : gen_vsx_set_v2di);
5460 emit_insn (set_func (target, target, val, GEN_INT (elt)));
5461 return;
5464 /* Load single variable value. */
5465 mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0);
5466 emit_move_insn (adjust_address_nv (mem, inner_mode, 0), val);
5467 x = gen_rtx_UNSPEC (VOIDmode,
5468 gen_rtvec (1, const0_rtx), UNSPEC_LVE);
5469 emit_insn (gen_rtx_PARALLEL (VOIDmode,
5470 gen_rtvec (2,
5471 gen_rtx_SET (VOIDmode,
5472 reg, mem),
5473 x)));
5475 /* Linear sequence. */
5476 mask = gen_rtx_PARALLEL (V16QImode, rtvec_alloc (16));
5477 for (i = 0; i < 16; ++i)
5478 XVECEXP (mask, 0, i) = GEN_INT (i);
5480 /* Set permute mask to insert element into target. */
5481 for (i = 0; i < width; ++i)
5482 XVECEXP (mask, 0, elt*width + i)
5483 = GEN_INT (i + 0x10);
5484 x = gen_rtx_CONST_VECTOR (V16QImode, XVEC (mask, 0));
5485 x = gen_rtx_UNSPEC (mode,
5486 gen_rtvec (3, target, reg,
5487 force_reg (V16QImode, x)),
5488 UNSPEC_VPERM);
5489 emit_insn (gen_rtx_SET (VOIDmode, target, x));
5492 /* Extract field ELT from VEC into TARGET. */
5494 void
5495 rs6000_expand_vector_extract (rtx target, rtx vec, int elt)
5497 enum machine_mode mode = GET_MODE (vec);
5498 enum machine_mode inner_mode = GET_MODE_INNER (mode);
5499 rtx mem;
5501 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
5503 rtx (*extract_func) (rtx, rtx, rtx)
5504 = ((mode == V2DFmode) ? gen_vsx_extract_v2df : gen_vsx_extract_v2di);
5505 emit_insn (extract_func (target, vec, GEN_INT (elt)));
5506 return;
5509 /* Allocate mode-sized buffer. */
5510 mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
5512 emit_move_insn (mem, vec);
5514 /* Add offset to field within buffer matching vector element. */
5515 mem = adjust_address_nv (mem, inner_mode, elt * GET_MODE_SIZE (inner_mode));
5517 emit_move_insn (target, adjust_address_nv (mem, inner_mode, 0));
5520 /* Generates shifts and masks for a pair of rldicl or rldicr insns to
5521 implement ANDing by the mask IN. */
5522 void
5523 build_mask64_2_operands (rtx in, rtx *out)
5525 #if HOST_BITS_PER_WIDE_INT >= 64
5526 unsigned HOST_WIDE_INT c, lsb, m1, m2;
5527 int shift;
5529 gcc_assert (GET_CODE (in) == CONST_INT);
5531 c = INTVAL (in);
5532 if (c & 1)
5534 /* Assume c initially something like 0x00fff000000fffff. The idea
5535 is to rotate the word so that the middle ^^^^^^ group of zeros
5536 is at the MS end and can be cleared with an rldicl mask. We then
5537 rotate back and clear off the MS ^^ group of zeros with a
5538 second rldicl. */
5539 c = ~c; /* c == 0xff000ffffff00000 */
5540 lsb = c & -c; /* lsb == 0x0000000000100000 */
5541 m1 = -lsb; /* m1 == 0xfffffffffff00000 */
5542 c = ~c; /* c == 0x00fff000000fffff */
5543 c &= -lsb; /* c == 0x00fff00000000000 */
5544 lsb = c & -c; /* lsb == 0x0000100000000000 */
5545 c = ~c; /* c == 0xff000fffffffffff */
5546 c &= -lsb; /* c == 0xff00000000000000 */
5547 shift = 0;
5548 while ((lsb >>= 1) != 0)
5549 shift++; /* shift == 44 on exit from loop */
5550 m1 <<= 64 - shift; /* m1 == 0xffffff0000000000 */
5551 m1 = ~m1; /* m1 == 0x000000ffffffffff */
5552 m2 = ~c; /* m2 == 0x00ffffffffffffff */
5554 else
5556 /* Assume c initially something like 0xff000f0000000000. The idea
5557 is to rotate the word so that the ^^^ middle group of zeros
5558 is at the LS end and can be cleared with an rldicr mask. We then
5559 rotate back and clear off the LS group of ^^^^^^^^^^ zeros with
5560 a second rldicr. */
5561 lsb = c & -c; /* lsb == 0x0000010000000000 */
5562 m2 = -lsb; /* m2 == 0xffffff0000000000 */
5563 c = ~c; /* c == 0x00fff0ffffffffff */
5564 c &= -lsb; /* c == 0x00fff00000000000 */
5565 lsb = c & -c; /* lsb == 0x0000100000000000 */
5566 c = ~c; /* c == 0xff000fffffffffff */
5567 c &= -lsb; /* c == 0xff00000000000000 */
5568 shift = 0;
5569 while ((lsb >>= 1) != 0)
5570 shift++; /* shift == 44 on exit from loop */
5571 m1 = ~c; /* m1 == 0x00ffffffffffffff */
5572 m1 >>= shift; /* m1 == 0x0000000000000fff */
5573 m1 = ~m1; /* m1 == 0xfffffffffffff000 */
5576 /* Note that when we only have two 0->1 and 1->0 transitions, one of the
5577 masks will be all 1's. We are guaranteed more than one transition. */
5578 out[0] = GEN_INT (64 - shift);
5579 out[1] = GEN_INT (m1);
5580 out[2] = GEN_INT (shift);
5581 out[3] = GEN_INT (m2);
5582 #else
5583 (void)in;
5584 (void)out;
5585 gcc_unreachable ();
5586 #endif
5589 /* Return TRUE if OP is an invalid SUBREG operation on the e500. */
5591 bool
5592 invalid_e500_subreg (rtx op, enum machine_mode mode)
5594 if (TARGET_E500_DOUBLE)
5596 /* Reject (subreg:SI (reg:DF)); likewise with subreg:DI or
5597 subreg:TI and reg:TF. Decimal float modes are like integer
5598 modes (only low part of each register used) for this
5599 purpose. */
5600 if (GET_CODE (op) == SUBREG
5601 && (mode == SImode || mode == DImode || mode == TImode
5602 || mode == DDmode || mode == TDmode)
5603 && REG_P (SUBREG_REG (op))
5604 && (GET_MODE (SUBREG_REG (op)) == DFmode
5605 || GET_MODE (SUBREG_REG (op)) == TFmode))
5606 return true;
5608 /* Reject (subreg:DF (reg:DI)); likewise with subreg:TF and
5609 reg:TI. */
5610 if (GET_CODE (op) == SUBREG
5611 && (mode == DFmode || mode == TFmode)
5612 && REG_P (SUBREG_REG (op))
5613 && (GET_MODE (SUBREG_REG (op)) == DImode
5614 || GET_MODE (SUBREG_REG (op)) == TImode
5615 || GET_MODE (SUBREG_REG (op)) == DDmode
5616 || GET_MODE (SUBREG_REG (op)) == TDmode))
5617 return true;
5620 if (TARGET_SPE
5621 && GET_CODE (op) == SUBREG
5622 && mode == SImode
5623 && REG_P (SUBREG_REG (op))
5624 && SPE_VECTOR_MODE (GET_MODE (SUBREG_REG (op))))
5625 return true;
5627 return false;
5630 /* AIX increases natural record alignment to doubleword if the first
5631 field is an FP double while the FP fields remain word aligned. */
5633 unsigned int
5634 rs6000_special_round_type_align (tree type, unsigned int computed,
5635 unsigned int specified)
5637 unsigned int align = MAX (computed, specified);
5638 tree field = TYPE_FIELDS (type);
5640 /* Skip all non field decls */
5641 while (field != NULL && TREE_CODE (field) != FIELD_DECL)
5642 field = DECL_CHAIN (field);
5644 if (field != NULL && field != type)
5646 type = TREE_TYPE (field);
5647 while (TREE_CODE (type) == ARRAY_TYPE)
5648 type = TREE_TYPE (type);
5650 if (type != error_mark_node && TYPE_MODE (type) == DFmode)
5651 align = MAX (align, 64);
5654 return align;
5657 /* Darwin increases record alignment to the natural alignment of
5658 the first field. */
5660 unsigned int
5661 darwin_rs6000_special_round_type_align (tree type, unsigned int computed,
5662 unsigned int specified)
5664 unsigned int align = MAX (computed, specified);
5666 if (TYPE_PACKED (type))
5667 return align;
5669 /* Find the first field, looking down into aggregates. */
5670 do {
5671 tree field = TYPE_FIELDS (type);
5672 /* Skip all non field decls */
5673 while (field != NULL && TREE_CODE (field) != FIELD_DECL)
5674 field = DECL_CHAIN (field);
5675 if (! field)
5676 break;
5677 /* A packed field does not contribute any extra alignment. */
5678 if (DECL_PACKED (field))
5679 return align;
5680 type = TREE_TYPE (field);
5681 while (TREE_CODE (type) == ARRAY_TYPE)
5682 type = TREE_TYPE (type);
5683 } while (AGGREGATE_TYPE_P (type));
5685 if (! AGGREGATE_TYPE_P (type) && type != error_mark_node)
5686 align = MAX (align, TYPE_ALIGN (type));
5688 return align;
5691 /* Return 1 for an operand in small memory on V.4/eabi. */
5694 small_data_operand (rtx op ATTRIBUTE_UNUSED,
5695 enum machine_mode mode ATTRIBUTE_UNUSED)
5697 #if TARGET_ELF
5698 rtx sym_ref;
5700 if (rs6000_sdata == SDATA_NONE || rs6000_sdata == SDATA_DATA)
5701 return 0;
5703 if (DEFAULT_ABI != ABI_V4)
5704 return 0;
5706 /* Vector and float memory instructions have a limited offset on the
5707 SPE, so using a vector or float variable directly as an operand is
5708 not useful. */
5709 if (TARGET_SPE
5710 && (SPE_VECTOR_MODE (mode) || FLOAT_MODE_P (mode)))
5711 return 0;
5713 if (GET_CODE (op) == SYMBOL_REF)
5714 sym_ref = op;
5716 else if (GET_CODE (op) != CONST
5717 || GET_CODE (XEXP (op, 0)) != PLUS
5718 || GET_CODE (XEXP (XEXP (op, 0), 0)) != SYMBOL_REF
5719 || GET_CODE (XEXP (XEXP (op, 0), 1)) != CONST_INT)
5720 return 0;
5722 else
5724 rtx sum = XEXP (op, 0);
5725 HOST_WIDE_INT summand;
5727 /* We have to be careful here, because it is the referenced address
5728 that must be 32k from _SDA_BASE_, not just the symbol. */
5729 summand = INTVAL (XEXP (sum, 1));
5730 if (summand < 0 || summand > g_switch_value)
5731 return 0;
5733 sym_ref = XEXP (sum, 0);
5736 return SYMBOL_REF_SMALL_P (sym_ref);
5737 #else
5738 return 0;
5739 #endif
5742 /* Return true if either operand is a general purpose register. */
5744 bool
5745 gpr_or_gpr_p (rtx op0, rtx op1)
5747 return ((REG_P (op0) && INT_REGNO_P (REGNO (op0)))
5748 || (REG_P (op1) && INT_REGNO_P (REGNO (op1))));
5752 /* Subroutines of rs6000_legitimize_address and rs6000_legitimate_address_p. */
5754 static bool
5755 reg_offset_addressing_ok_p (enum machine_mode mode)
5757 switch (mode)
5759 case V16QImode:
5760 case V8HImode:
5761 case V4SFmode:
5762 case V4SImode:
5763 case V2DFmode:
5764 case V2DImode:
5765 /* AltiVec/VSX vector modes. Only reg+reg addressing is valid. */
5766 if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode))
5767 return false;
5768 break;
5770 case V4HImode:
5771 case V2SImode:
5772 case V1DImode:
5773 case V2SFmode:
5774 /* Paired vector modes. Only reg+reg addressing is valid. */
5775 if (TARGET_PAIRED_FLOAT)
5776 return false;
5777 break;
5779 default:
5780 break;
5783 return true;
5786 static bool
5787 virtual_stack_registers_memory_p (rtx op)
5789 int regnum;
5791 if (GET_CODE (op) == REG)
5792 regnum = REGNO (op);
5794 else if (GET_CODE (op) == PLUS
5795 && GET_CODE (XEXP (op, 0)) == REG
5796 && GET_CODE (XEXP (op, 1)) == CONST_INT)
5797 regnum = REGNO (XEXP (op, 0));
5799 else
5800 return false;
5802 return (regnum >= FIRST_VIRTUAL_REGISTER
5803 && regnum <= LAST_VIRTUAL_POINTER_REGISTER);
5806 /* Return true if memory accesses to OP are known to never straddle
5807 a 32k boundary. */
5809 static bool
5810 offsettable_ok_by_alignment (rtx op, HOST_WIDE_INT offset,
5811 enum machine_mode mode)
5813 tree decl, type;
5814 unsigned HOST_WIDE_INT dsize, dalign;
5816 if (GET_CODE (op) != SYMBOL_REF)
5817 return false;
5819 decl = SYMBOL_REF_DECL (op);
5820 if (!decl)
5822 if (GET_MODE_SIZE (mode) == 0)
5823 return false;
5825 /* -fsection-anchors loses the original SYMBOL_REF_DECL when
5826 replacing memory addresses with an anchor plus offset. We
5827 could find the decl by rummaging around in the block->objects
5828 VEC for the given offset but that seems like too much work. */
5829 dalign = 1;
5830 if (SYMBOL_REF_HAS_BLOCK_INFO_P (op)
5831 && SYMBOL_REF_ANCHOR_P (op)
5832 && SYMBOL_REF_BLOCK (op) != NULL)
5834 struct object_block *block = SYMBOL_REF_BLOCK (op);
5835 HOST_WIDE_INT lsb, mask;
5837 /* Given the alignment of the block.. */
5838 dalign = block->alignment;
5839 mask = dalign / BITS_PER_UNIT - 1;
5841 /* ..and the combined offset of the anchor and any offset
5842 to this block object.. */
5843 offset += SYMBOL_REF_BLOCK_OFFSET (op);
5844 lsb = offset & -offset;
5846 /* ..find how many bits of the alignment we know for the
5847 object. */
5848 mask &= lsb - 1;
5849 dalign = mask + 1;
5851 return dalign >= GET_MODE_SIZE (mode);
5854 if (DECL_P (decl))
5856 if (TREE_CODE (decl) == FUNCTION_DECL)
5857 return true;
5859 if (!DECL_SIZE_UNIT (decl))
5860 return false;
5862 if (!host_integerp (DECL_SIZE_UNIT (decl), 1))
5863 return false;
5865 dsize = tree_low_cst (DECL_SIZE_UNIT (decl), 1);
5866 if (dsize > 32768)
5867 return false;
5869 dalign = DECL_ALIGN_UNIT (decl);
5870 return dalign >= dsize;
5873 type = TREE_TYPE (decl);
5875 if (TREE_CODE (decl) == STRING_CST)
5876 dsize = TREE_STRING_LENGTH (decl);
5877 else if (TYPE_SIZE_UNIT (type)
5878 && host_integerp (TYPE_SIZE_UNIT (type), 1))
5879 dsize = tree_low_cst (TYPE_SIZE_UNIT (type), 1);
5880 else
5881 return false;
5882 if (dsize > 32768)
5883 return false;
5885 dalign = TYPE_ALIGN (type);
5886 if (CONSTANT_CLASS_P (decl))
5887 dalign = CONSTANT_ALIGNMENT (decl, dalign);
5888 else
5889 dalign = DATA_ALIGNMENT (decl, dalign);
5890 dalign /= BITS_PER_UNIT;
5891 return dalign >= dsize;
5894 static bool
5895 constant_pool_expr_p (rtx op)
5897 rtx base, offset;
5899 split_const (op, &base, &offset);
5900 return (GET_CODE (base) == SYMBOL_REF
5901 && CONSTANT_POOL_ADDRESS_P (base)
5902 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (base), Pmode));
5905 static rtx tocrel_base, tocrel_offset;
5907 bool
5908 toc_relative_expr_p (rtx op)
5910 if (GET_CODE (op) != CONST)
5911 return false;
5913 split_const (op, &tocrel_base, &tocrel_offset);
5914 return (GET_CODE (tocrel_base) == UNSPEC
5915 && XINT (tocrel_base, 1) == UNSPEC_TOCREL);
5918 /* Return true if X is a constant pool address, and also for cmodel=medium
5919 if X is a toc-relative address known to be offsettable within MODE. */
5921 bool
5922 legitimate_constant_pool_address_p (const_rtx x, enum machine_mode mode,
5923 bool strict)
5925 return (TARGET_TOC
5926 && (GET_CODE (x) == PLUS || GET_CODE (x) == LO_SUM)
5927 && GET_CODE (XEXP (x, 0)) == REG
5928 && (REGNO (XEXP (x, 0)) == TOC_REGISTER
5929 || ((TARGET_MINIMAL_TOC
5930 || TARGET_CMODEL != CMODEL_SMALL)
5931 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict)))
5932 && toc_relative_expr_p (XEXP (x, 1))
5933 && (TARGET_CMODEL != CMODEL_MEDIUM
5934 || constant_pool_expr_p (XVECEXP (tocrel_base, 0, 0))
5935 || mode == QImode
5936 || offsettable_ok_by_alignment (XVECEXP (tocrel_base, 0, 0),
5937 INTVAL (tocrel_offset), mode)));
5940 static bool
5941 legitimate_small_data_p (enum machine_mode mode, rtx x)
5943 return (DEFAULT_ABI == ABI_V4
5944 && !flag_pic && !TARGET_TOC
5945 && (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST)
5946 && small_data_operand (x, mode));
5949 /* SPE offset addressing is limited to 5-bits worth of double words. */
5950 #define SPE_CONST_OFFSET_OK(x) (((x) & ~0xf8) == 0)
5952 bool
5953 rs6000_legitimate_offset_address_p (enum machine_mode mode, rtx x, int strict)
5955 unsigned HOST_WIDE_INT offset, extra;
5957 if (GET_CODE (x) != PLUS)
5958 return false;
5959 if (GET_CODE (XEXP (x, 0)) != REG)
5960 return false;
5961 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
5962 return false;
5963 if (!reg_offset_addressing_ok_p (mode))
5964 return virtual_stack_registers_memory_p (x);
5965 if (legitimate_constant_pool_address_p (x, mode, strict))
5966 return true;
5967 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5968 return false;
5970 offset = INTVAL (XEXP (x, 1));
5971 extra = 0;
5972 switch (mode)
5974 case V4HImode:
5975 case V2SImode:
5976 case V1DImode:
5977 case V2SFmode:
5978 /* SPE vector modes. */
5979 return SPE_CONST_OFFSET_OK (offset);
5981 case DFmode:
5982 if (TARGET_E500_DOUBLE)
5983 return SPE_CONST_OFFSET_OK (offset);
5985 /* If we are using VSX scalar loads, restrict ourselves to reg+reg
5986 addressing. */
5987 if (VECTOR_MEM_VSX_P (DFmode))
5988 return false;
5990 case DDmode:
5991 case DImode:
5992 /* On e500v2, we may have:
5994 (subreg:DF (mem:DI (plus (reg) (const_int))) 0).
5996 Which gets addressed with evldd instructions. */
5997 if (TARGET_E500_DOUBLE)
5998 return SPE_CONST_OFFSET_OK (offset);
6000 if (mode == DFmode || mode == DDmode || !TARGET_POWERPC64)
6001 extra = 4;
6002 else if (offset & 3)
6003 return false;
6004 break;
6006 case TFmode:
6007 if (TARGET_E500_DOUBLE)
6008 return (SPE_CONST_OFFSET_OK (offset)
6009 && SPE_CONST_OFFSET_OK (offset + 8));
6011 case TDmode:
6012 case TImode:
6013 if (mode == TFmode || mode == TDmode || !TARGET_POWERPC64)
6014 extra = 12;
6015 else if (offset & 3)
6016 return false;
6017 else
6018 extra = 8;
6019 break;
6021 default:
6022 break;
6025 offset += 0x8000;
6026 return (offset < 0x10000) && (offset + extra < 0x10000);
6029 bool
6030 legitimate_indexed_address_p (rtx x, int strict)
6032 rtx op0, op1;
6034 if (GET_CODE (x) != PLUS)
6035 return false;
6037 op0 = XEXP (x, 0);
6038 op1 = XEXP (x, 1);
6040 /* Recognize the rtl generated by reload which we know will later be
6041 replaced with proper base and index regs. */
6042 if (!strict
6043 && reload_in_progress
6044 && (REG_P (op0) || GET_CODE (op0) == PLUS)
6045 && REG_P (op1))
6046 return true;
6048 return (REG_P (op0) && REG_P (op1)
6049 && ((INT_REG_OK_FOR_BASE_P (op0, strict)
6050 && INT_REG_OK_FOR_INDEX_P (op1, strict))
6051 || (INT_REG_OK_FOR_BASE_P (op1, strict)
6052 && INT_REG_OK_FOR_INDEX_P (op0, strict))));
6055 bool
6056 avoiding_indexed_address_p (enum machine_mode mode)
6058 /* Avoid indexed addressing for modes that have non-indexed
6059 load/store instruction forms. */
6060 return (TARGET_AVOID_XFORM && VECTOR_MEM_NONE_P (mode));
6063 inline bool
6064 legitimate_indirect_address_p (rtx x, int strict)
6066 return GET_CODE (x) == REG && INT_REG_OK_FOR_BASE_P (x, strict);
6069 bool
6070 macho_lo_sum_memory_operand (rtx x, enum machine_mode mode)
6072 if (!TARGET_MACHO || !flag_pic
6073 || mode != SImode || GET_CODE (x) != MEM)
6074 return false;
6075 x = XEXP (x, 0);
6077 if (GET_CODE (x) != LO_SUM)
6078 return false;
6079 if (GET_CODE (XEXP (x, 0)) != REG)
6080 return false;
6081 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 0))
6082 return false;
6083 x = XEXP (x, 1);
6085 return CONSTANT_P (x);
6088 static bool
6089 legitimate_lo_sum_address_p (enum machine_mode mode, rtx x, int strict)
6091 if (GET_CODE (x) != LO_SUM)
6092 return false;
6093 if (GET_CODE (XEXP (x, 0)) != REG)
6094 return false;
6095 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
6096 return false;
6097 /* Restrict addressing for DI because of our SUBREG hackery. */
6098 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
6099 || mode == DDmode || mode == TDmode
6100 || mode == DImode))
6101 return false;
6102 x = XEXP (x, 1);
6104 if (TARGET_ELF || TARGET_MACHO)
6106 if (DEFAULT_ABI != ABI_AIX && DEFAULT_ABI != ABI_DARWIN && flag_pic)
6107 return false;
6108 if (TARGET_TOC)
6109 return false;
6110 if (GET_MODE_NUNITS (mode) != 1)
6111 return false;
6112 if (GET_MODE_BITSIZE (mode) > 64
6113 || (GET_MODE_BITSIZE (mode) > 32 && !TARGET_POWERPC64
6114 && !(TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
6115 && (mode == DFmode || mode == DDmode))))
6116 return false;
6118 return CONSTANT_P (x);
6121 return false;
6125 /* Try machine-dependent ways of modifying an illegitimate address
6126 to be legitimate. If we find one, return the new, valid address.
6127 This is used from only one place: `memory_address' in explow.c.
6129 OLDX is the address as it was before break_out_memory_refs was
6130 called. In some cases it is useful to look at this to decide what
6131 needs to be done.
6133 It is always safe for this function to do nothing. It exists to
6134 recognize opportunities to optimize the output.
6136 On RS/6000, first check for the sum of a register with a constant
6137 integer that is out of range. If so, generate code to add the
6138 constant with the low-order 16 bits masked to the register and force
6139 this result into another register (this can be done with `cau').
6140 Then generate an address of REG+(CONST&0xffff), allowing for the
6141 possibility of bit 16 being a one.
6143 Then check for the sum of a register and something not constant, try to
6144 load the other things into a register and return the sum. */
6146 static rtx
6147 rs6000_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
6148 enum machine_mode mode)
6150 unsigned int extra = 0;
6152 if (!reg_offset_addressing_ok_p (mode))
6154 if (virtual_stack_registers_memory_p (x))
6155 return x;
6157 /* In theory we should not be seeing addresses of the form reg+0,
6158 but just in case it is generated, optimize it away. */
6159 if (GET_CODE (x) == PLUS && XEXP (x, 1) == const0_rtx)
6160 return force_reg (Pmode, XEXP (x, 0));
6162 /* Make sure both operands are registers. */
6163 else if (GET_CODE (x) == PLUS)
6164 return gen_rtx_PLUS (Pmode,
6165 force_reg (Pmode, XEXP (x, 0)),
6166 force_reg (Pmode, XEXP (x, 1)));
6167 else
6168 return force_reg (Pmode, x);
6170 if (GET_CODE (x) == SYMBOL_REF)
6172 enum tls_model model = SYMBOL_REF_TLS_MODEL (x);
6173 if (model != 0)
6174 return rs6000_legitimize_tls_address (x, model);
6177 switch (mode)
6179 case DFmode:
6180 case DDmode:
6181 extra = 4;
6182 break;
6183 case DImode:
6184 if (!TARGET_POWERPC64)
6185 extra = 4;
6186 break;
6187 case TFmode:
6188 case TDmode:
6189 extra = 12;
6190 break;
6191 case TImode:
6192 extra = TARGET_POWERPC64 ? 8 : 12;
6193 break;
6194 default:
6195 break;
6198 if (GET_CODE (x) == PLUS
6199 && GET_CODE (XEXP (x, 0)) == REG
6200 && GET_CODE (XEXP (x, 1)) == CONST_INT
6201 && ((unsigned HOST_WIDE_INT) (INTVAL (XEXP (x, 1)) + 0x8000)
6202 >= 0x10000 - extra)
6203 && !((TARGET_POWERPC64
6204 && (mode == DImode || mode == TImode)
6205 && (INTVAL (XEXP (x, 1)) & 3) != 0)
6206 || SPE_VECTOR_MODE (mode)
6207 || (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
6208 || mode == DImode || mode == DDmode
6209 || mode == TDmode))))
6211 HOST_WIDE_INT high_int, low_int;
6212 rtx sum;
6213 low_int = ((INTVAL (XEXP (x, 1)) & 0xffff) ^ 0x8000) - 0x8000;
6214 if (low_int >= 0x8000 - extra)
6215 low_int = 0;
6216 high_int = INTVAL (XEXP (x, 1)) - low_int;
6217 sum = force_operand (gen_rtx_PLUS (Pmode, XEXP (x, 0),
6218 GEN_INT (high_int)), 0);
6219 return plus_constant (sum, low_int);
6221 else if (GET_CODE (x) == PLUS
6222 && GET_CODE (XEXP (x, 0)) == REG
6223 && GET_CODE (XEXP (x, 1)) != CONST_INT
6224 && GET_MODE_NUNITS (mode) == 1
6225 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
6226 || TARGET_POWERPC64
6227 || ((mode != DImode && mode != DFmode && mode != DDmode)
6228 || (TARGET_E500_DOUBLE && mode != DDmode)))
6229 && (TARGET_POWERPC64 || mode != DImode)
6230 && !avoiding_indexed_address_p (mode)
6231 && mode != TImode
6232 && mode != TFmode
6233 && mode != TDmode)
6235 return gen_rtx_PLUS (Pmode, XEXP (x, 0),
6236 force_reg (Pmode, force_operand (XEXP (x, 1), 0)));
6238 else if (SPE_VECTOR_MODE (mode)
6239 || (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
6240 || mode == DDmode || mode == TDmode
6241 || mode == DImode)))
6243 if (mode == DImode)
6244 return x;
6245 /* We accept [reg + reg] and [reg + OFFSET]. */
6247 if (GET_CODE (x) == PLUS)
6249 rtx op1 = XEXP (x, 0);
6250 rtx op2 = XEXP (x, 1);
6251 rtx y;
6253 op1 = force_reg (Pmode, op1);
6255 if (GET_CODE (op2) != REG
6256 && (GET_CODE (op2) != CONST_INT
6257 || !SPE_CONST_OFFSET_OK (INTVAL (op2))
6258 || (GET_MODE_SIZE (mode) > 8
6259 && !SPE_CONST_OFFSET_OK (INTVAL (op2) + 8))))
6260 op2 = force_reg (Pmode, op2);
6262 /* We can't always do [reg + reg] for these, because [reg +
6263 reg + offset] is not a legitimate addressing mode. */
6264 y = gen_rtx_PLUS (Pmode, op1, op2);
6266 if ((GET_MODE_SIZE (mode) > 8 || mode == DDmode) && REG_P (op2))
6267 return force_reg (Pmode, y);
6268 else
6269 return y;
6272 return force_reg (Pmode, x);
6274 else if (TARGET_ELF
6275 && TARGET_32BIT
6276 && TARGET_NO_TOC
6277 && ! flag_pic
6278 && GET_CODE (x) != CONST_INT
6279 && GET_CODE (x) != CONST_DOUBLE
6280 && CONSTANT_P (x)
6281 && GET_MODE_NUNITS (mode) == 1
6282 && (GET_MODE_BITSIZE (mode) <= 32
6283 || ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
6284 && (mode == DFmode || mode == DDmode))))
6286 rtx reg = gen_reg_rtx (Pmode);
6287 emit_insn (gen_elf_high (reg, x));
6288 return gen_rtx_LO_SUM (Pmode, reg, x);
6290 else if (TARGET_MACHO && TARGET_32BIT && TARGET_NO_TOC
6291 && ! flag_pic
6292 #if TARGET_MACHO
6293 && ! MACHO_DYNAMIC_NO_PIC_P
6294 #endif
6295 && GET_CODE (x) != CONST_INT
6296 && GET_CODE (x) != CONST_DOUBLE
6297 && CONSTANT_P (x)
6298 && GET_MODE_NUNITS (mode) == 1
6299 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
6300 || (mode != DFmode && mode != DDmode))
6301 && mode != DImode
6302 && mode != TImode)
6304 rtx reg = gen_reg_rtx (Pmode);
6305 emit_insn (gen_macho_high (reg, x));
6306 return gen_rtx_LO_SUM (Pmode, reg, x);
6308 else if (TARGET_TOC
6309 && GET_CODE (x) == SYMBOL_REF
6310 && constant_pool_expr_p (x)
6311 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), Pmode))
6313 rtx reg = TARGET_CMODEL != CMODEL_SMALL ? gen_reg_rtx (Pmode) : NULL_RTX;
6314 return create_TOC_reference (x, reg);
6316 else
6317 return x;
6320 /* Debug version of rs6000_legitimize_address. */
6321 static rtx
6322 rs6000_debug_legitimize_address (rtx x, rtx oldx, enum machine_mode mode)
6324 rtx ret;
6325 rtx insns;
6327 start_sequence ();
6328 ret = rs6000_legitimize_address (x, oldx, mode);
6329 insns = get_insns ();
6330 end_sequence ();
6332 if (ret != x)
6334 fprintf (stderr,
6335 "\nrs6000_legitimize_address: mode %s, old code %s, "
6336 "new code %s, modified\n",
6337 GET_MODE_NAME (mode), GET_RTX_NAME (GET_CODE (x)),
6338 GET_RTX_NAME (GET_CODE (ret)));
6340 fprintf (stderr, "Original address:\n");
6341 debug_rtx (x);
6343 fprintf (stderr, "oldx:\n");
6344 debug_rtx (oldx);
6346 fprintf (stderr, "New address:\n");
6347 debug_rtx (ret);
6349 if (insns)
6351 fprintf (stderr, "Insns added:\n");
6352 debug_rtx_list (insns, 20);
6355 else
6357 fprintf (stderr,
6358 "\nrs6000_legitimize_address: mode %s, code %s, no change:\n",
6359 GET_MODE_NAME (mode), GET_RTX_NAME (GET_CODE (x)));
6361 debug_rtx (x);
6364 if (insns)
6365 emit_insn (insns);
6367 return ret;
6370 /* This is called from dwarf2out.c via TARGET_ASM_OUTPUT_DWARF_DTPREL.
6371 We need to emit DTP-relative relocations. */
6373 static void
6374 rs6000_output_dwarf_dtprel (FILE *file, int size, rtx x)
6376 switch (size)
6378 case 4:
6379 fputs ("\t.long\t", file);
6380 break;
6381 case 8:
6382 fputs (DOUBLE_INT_ASM_OP, file);
6383 break;
6384 default:
6385 gcc_unreachable ();
6387 output_addr_const (file, x);
6388 fputs ("@dtprel+0x8000", file);
6391 /* In the name of slightly smaller debug output, and to cater to
6392 general assembler lossage, recognize various UNSPEC sequences
6393 and turn them back into a direct symbol reference. */
6395 static rtx
6396 rs6000_delegitimize_address (rtx orig_x)
6398 rtx x, y;
6400 orig_x = delegitimize_mem_from_attrs (orig_x);
6401 x = orig_x;
6402 if (MEM_P (x))
6403 x = XEXP (x, 0);
6405 if (GET_CODE (x) == (TARGET_CMODEL != CMODEL_SMALL ? LO_SUM : PLUS)
6406 && GET_CODE (XEXP (x, 1)) == CONST)
6408 y = XEXP (XEXP (x, 1), 0);
6409 if (GET_CODE (y) == UNSPEC
6410 && XINT (y, 1) == UNSPEC_TOCREL
6411 && ((GET_CODE (XEXP (x, 0)) == REG
6412 && (REGNO (XEXP (x, 0)) == TOC_REGISTER
6413 || TARGET_MINIMAL_TOC
6414 || TARGET_CMODEL != CMODEL_SMALL))
6415 || (TARGET_CMODEL != CMODEL_SMALL
6416 && GET_CODE (XEXP (x, 0)) == PLUS
6417 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
6418 && REGNO (XEXP (XEXP (x, 0), 0)) == TOC_REGISTER
6419 && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH
6420 && rtx_equal_p (XEXP (x, 1),
6421 XEXP (XEXP (XEXP (x, 0), 1), 0)))))
6423 y = XVECEXP (y, 0, 0);
6424 if (!MEM_P (orig_x))
6425 return y;
6426 else
6427 return replace_equiv_address_nv (orig_x, y);
6431 if (TARGET_MACHO
6432 && GET_CODE (orig_x) == LO_SUM
6433 && GET_CODE (XEXP (x, 1)) == CONST)
6435 y = XEXP (XEXP (x, 1), 0);
6436 if (GET_CODE (y) == UNSPEC
6437 && XINT (y, 1) == UNSPEC_MACHOPIC_OFFSET)
6438 return XVECEXP (y, 0, 0);
6441 return orig_x;
6444 /* Construct the SYMBOL_REF for the tls_get_addr function. */
6446 static GTY(()) rtx rs6000_tls_symbol;
6447 static rtx
6448 rs6000_tls_get_addr (void)
6450 if (!rs6000_tls_symbol)
6451 rs6000_tls_symbol = init_one_libfunc ("__tls_get_addr");
6453 return rs6000_tls_symbol;
6456 /* Construct the SYMBOL_REF for TLS GOT references. */
6458 static GTY(()) rtx rs6000_got_symbol;
6459 static rtx
6460 rs6000_got_sym (void)
6462 if (!rs6000_got_symbol)
6464 rs6000_got_symbol = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
6465 SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_LOCAL;
6466 SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_EXTERNAL;
6469 return rs6000_got_symbol;
6472 /* ADDR contains a thread-local SYMBOL_REF. Generate code to compute
6473 this (thread-local) address. */
6475 static rtx
6476 rs6000_legitimize_tls_address (rtx addr, enum tls_model model)
6478 rtx dest, insn;
6480 dest = gen_reg_rtx (Pmode);
6481 if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 16)
6483 rtx tlsreg;
6485 if (TARGET_64BIT)
6487 tlsreg = gen_rtx_REG (Pmode, 13);
6488 insn = gen_tls_tprel_64 (dest, tlsreg, addr);
6490 else
6492 tlsreg = gen_rtx_REG (Pmode, 2);
6493 insn = gen_tls_tprel_32 (dest, tlsreg, addr);
6495 emit_insn (insn);
6497 else if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 32)
6499 rtx tlsreg, tmp;
6501 tmp = gen_reg_rtx (Pmode);
6502 if (TARGET_64BIT)
6504 tlsreg = gen_rtx_REG (Pmode, 13);
6505 insn = gen_tls_tprel_ha_64 (tmp, tlsreg, addr);
6507 else
6509 tlsreg = gen_rtx_REG (Pmode, 2);
6510 insn = gen_tls_tprel_ha_32 (tmp, tlsreg, addr);
6512 emit_insn (insn);
6513 if (TARGET_64BIT)
6514 insn = gen_tls_tprel_lo_64 (dest, tmp, addr);
6515 else
6516 insn = gen_tls_tprel_lo_32 (dest, tmp, addr);
6517 emit_insn (insn);
6519 else
6521 rtx r3, got, tga, tmp1, tmp2, call_insn;
6523 /* We currently use relocations like @got@tlsgd for tls, which
6524 means the linker will handle allocation of tls entries, placing
6525 them in the .got section. So use a pointer to the .got section,
6526 not one to secondary TOC sections used by 64-bit -mminimal-toc,
6527 or to secondary GOT sections used by 32-bit -fPIC. */
6528 if (TARGET_64BIT)
6529 got = gen_rtx_REG (Pmode, 2);
6530 else
6532 if (flag_pic == 1)
6533 got = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
6534 else
6536 rtx gsym = rs6000_got_sym ();
6537 got = gen_reg_rtx (Pmode);
6538 if (flag_pic == 0)
6539 rs6000_emit_move (got, gsym, Pmode);
6540 else
6542 rtx mem, lab, last;
6544 tmp1 = gen_reg_rtx (Pmode);
6545 tmp2 = gen_reg_rtx (Pmode);
6546 mem = gen_const_mem (Pmode, tmp1);
6547 lab = gen_label_rtx ();
6548 emit_insn (gen_load_toc_v4_PIC_1b (gsym, lab));
6549 emit_move_insn (tmp1, gen_rtx_REG (Pmode, LR_REGNO));
6550 emit_move_insn (tmp2, mem);
6551 last = emit_insn (gen_addsi3 (got, tmp1, tmp2));
6552 set_unique_reg_note (last, REG_EQUAL, gsym);
6557 if (model == TLS_MODEL_GLOBAL_DYNAMIC)
6559 r3 = gen_rtx_REG (Pmode, 3);
6560 tga = rs6000_tls_get_addr ();
6561 emit_library_call_value (tga, dest, LCT_CONST, Pmode, 1, r3, Pmode);
6563 if (DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
6564 insn = gen_tls_gd_aix64 (r3, got, addr, tga, const0_rtx);
6565 else if (DEFAULT_ABI == ABI_AIX && !TARGET_64BIT)
6566 insn = gen_tls_gd_aix32 (r3, got, addr, tga, const0_rtx);
6567 else if (DEFAULT_ABI == ABI_V4)
6568 insn = gen_tls_gd_sysvsi (r3, got, addr, tga, const0_rtx);
6569 else
6570 gcc_unreachable ();
6571 call_insn = last_call_insn ();
6572 PATTERN (call_insn) = insn;
6573 if (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
6574 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn),
6575 pic_offset_table_rtx);
6577 else if (model == TLS_MODEL_LOCAL_DYNAMIC)
6579 r3 = gen_rtx_REG (Pmode, 3);
6580 tga = rs6000_tls_get_addr ();
6581 tmp1 = gen_reg_rtx (Pmode);
6582 emit_library_call_value (tga, tmp1, LCT_CONST, Pmode, 1, r3, Pmode);
6584 if (DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
6585 insn = gen_tls_ld_aix64 (r3, got, tga, const0_rtx);
6586 else if (DEFAULT_ABI == ABI_AIX && !TARGET_64BIT)
6587 insn = gen_tls_ld_aix32 (r3, got, tga, const0_rtx);
6588 else if (DEFAULT_ABI == ABI_V4)
6589 insn = gen_tls_ld_sysvsi (r3, got, tga, const0_rtx);
6590 else
6591 gcc_unreachable ();
6592 call_insn = last_call_insn ();
6593 PATTERN (call_insn) = insn;
6594 if (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
6595 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn),
6596 pic_offset_table_rtx);
6598 if (rs6000_tls_size == 16)
6600 if (TARGET_64BIT)
6601 insn = gen_tls_dtprel_64 (dest, tmp1, addr);
6602 else
6603 insn = gen_tls_dtprel_32 (dest, tmp1, addr);
6605 else if (rs6000_tls_size == 32)
6607 tmp2 = gen_reg_rtx (Pmode);
6608 if (TARGET_64BIT)
6609 insn = gen_tls_dtprel_ha_64 (tmp2, tmp1, addr);
6610 else
6611 insn = gen_tls_dtprel_ha_32 (tmp2, tmp1, addr);
6612 emit_insn (insn);
6613 if (TARGET_64BIT)
6614 insn = gen_tls_dtprel_lo_64 (dest, tmp2, addr);
6615 else
6616 insn = gen_tls_dtprel_lo_32 (dest, tmp2, addr);
6618 else
6620 tmp2 = gen_reg_rtx (Pmode);
6621 if (TARGET_64BIT)
6622 insn = gen_tls_got_dtprel_64 (tmp2, got, addr);
6623 else
6624 insn = gen_tls_got_dtprel_32 (tmp2, got, addr);
6625 emit_insn (insn);
6626 insn = gen_rtx_SET (Pmode, dest,
6627 gen_rtx_PLUS (Pmode, tmp2, tmp1));
6629 emit_insn (insn);
6631 else
6633 /* IE, or 64-bit offset LE. */
6634 tmp2 = gen_reg_rtx (Pmode);
6635 if (TARGET_64BIT)
6636 insn = gen_tls_got_tprel_64 (tmp2, got, addr);
6637 else
6638 insn = gen_tls_got_tprel_32 (tmp2, got, addr);
6639 emit_insn (insn);
6640 if (TARGET_64BIT)
6641 insn = gen_tls_tls_64 (dest, tmp2, addr);
6642 else
6643 insn = gen_tls_tls_32 (dest, tmp2, addr);
6644 emit_insn (insn);
6648 return dest;
6651 /* Return 1 if X contains a thread-local symbol. */
6653 bool
6654 rs6000_tls_referenced_p (rtx x)
6656 if (! TARGET_HAVE_TLS)
6657 return false;
6659 return for_each_rtx (&x, &rs6000_tls_symbol_ref_1, 0);
6662 /* Return 1 if *X is a thread-local symbol. This is the same as
6663 rs6000_tls_symbol_ref except for the type of the unused argument. */
6665 static int
6666 rs6000_tls_symbol_ref_1 (rtx *x, void *data ATTRIBUTE_UNUSED)
6668 return RS6000_SYMBOL_REF_TLS_P (*x);
6671 /* Our implementation of LEGITIMIZE_RELOAD_ADDRESS. Returns a value to
6672 replace the input X, or the original X if no replacement is called for.
6673 The output parameter *WIN is 1 if the calling macro should goto WIN,
6674 0 if it should not.
6676 For RS/6000, we wish to handle large displacements off a base
6677 register by splitting the addend across an addiu/addis and the mem insn.
6678 This cuts number of extra insns needed from 3 to 1.
6680 On Darwin, we use this to generate code for floating point constants.
6681 A movsf_low is generated so we wind up with 2 instructions rather than 3.
6682 The Darwin code is inside #if TARGET_MACHO because only then are the
6683 machopic_* functions defined. */
6684 static rtx
6685 rs6000_legitimize_reload_address (rtx x, enum machine_mode mode,
6686 int opnum, int type,
6687 int ind_levels ATTRIBUTE_UNUSED, int *win)
6689 bool reg_offset_p = reg_offset_addressing_ok_p (mode);
6691 /* Nasty hack for vsx_splat_V2DF/V2DI load from mem, which takes a
6692 DFmode/DImode MEM. */
6693 if (reg_offset_p
6694 && opnum == 1
6695 && ((mode == DFmode && recog_data.operand_mode[0] == V2DFmode)
6696 || (mode == DImode && recog_data.operand_mode[0] == V2DImode)))
6697 reg_offset_p = false;
6699 /* We must recognize output that we have already generated ourselves. */
6700 if (GET_CODE (x) == PLUS
6701 && GET_CODE (XEXP (x, 0)) == PLUS
6702 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
6703 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
6704 && GET_CODE (XEXP (x, 1)) == CONST_INT)
6706 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6707 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
6708 opnum, (enum reload_type)type);
6709 *win = 1;
6710 return x;
6713 /* Likewise for (lo_sum (high ...) ...) output we have generated. */
6714 if (GET_CODE (x) == LO_SUM
6715 && GET_CODE (XEXP (x, 0)) == HIGH)
6717 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6718 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6719 opnum, (enum reload_type)type);
6720 *win = 1;
6721 return x;
6724 #if TARGET_MACHO
6725 if (DEFAULT_ABI == ABI_DARWIN && flag_pic
6726 && GET_CODE (x) == LO_SUM
6727 && GET_CODE (XEXP (x, 0)) == PLUS
6728 && XEXP (XEXP (x, 0), 0) == pic_offset_table_rtx
6729 && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH
6730 && XEXP (XEXP (XEXP (x, 0), 1), 0) == XEXP (x, 1)
6731 && machopic_operand_p (XEXP (x, 1)))
6733 /* Result of previous invocation of this function on Darwin
6734 floating point constant. */
6735 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6736 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6737 opnum, (enum reload_type)type);
6738 *win = 1;
6739 return x;
6741 #endif
6743 if (TARGET_CMODEL != CMODEL_SMALL
6744 && GET_CODE (x) == LO_SUM
6745 && GET_CODE (XEXP (x, 0)) == PLUS
6746 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
6747 && REGNO (XEXP (XEXP (x, 0), 0)) == TOC_REGISTER
6748 && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH
6749 && GET_CODE (XEXP (x, 1)) == CONST
6750 && GET_CODE (XEXP (XEXP (x, 1), 0)) == UNSPEC
6751 && XINT (XEXP (XEXP (x, 1), 0), 1) == UNSPEC_TOCREL
6752 && rtx_equal_p (XEXP (XEXP (XEXP (x, 0), 1), 0), XEXP (x, 1)))
6754 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6755 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6756 opnum, (enum reload_type) type);
6757 *win = 1;
6758 return x;
6761 /* Force ld/std non-word aligned offset into base register by wrapping
6762 in offset 0. */
6763 if (GET_CODE (x) == PLUS
6764 && GET_CODE (XEXP (x, 0)) == REG
6765 && REGNO (XEXP (x, 0)) < 32
6766 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 1)
6767 && GET_CODE (XEXP (x, 1)) == CONST_INT
6768 && reg_offset_p
6769 && (INTVAL (XEXP (x, 1)) & 3) != 0
6770 && VECTOR_MEM_NONE_P (mode)
6771 && GET_MODE_SIZE (mode) >= UNITS_PER_WORD
6772 && TARGET_POWERPC64)
6774 x = gen_rtx_PLUS (GET_MODE (x), x, GEN_INT (0));
6775 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6776 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
6777 opnum, (enum reload_type) type);
6778 *win = 1;
6779 return x;
6782 if (GET_CODE (x) == PLUS
6783 && GET_CODE (XEXP (x, 0)) == REG
6784 && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER
6785 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 1)
6786 && GET_CODE (XEXP (x, 1)) == CONST_INT
6787 && reg_offset_p
6788 && !SPE_VECTOR_MODE (mode)
6789 && !(TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
6790 || mode == DDmode || mode == TDmode
6791 || mode == DImode))
6792 && VECTOR_MEM_NONE_P (mode))
6794 HOST_WIDE_INT val = INTVAL (XEXP (x, 1));
6795 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
6796 HOST_WIDE_INT high
6797 = (((val - low) & 0xffffffff) ^ 0x80000000) - 0x80000000;
6799 /* Check for 32-bit overflow. */
6800 if (high + low != val)
6802 *win = 0;
6803 return x;
6806 /* Reload the high part into a base reg; leave the low part
6807 in the mem directly. */
6809 x = gen_rtx_PLUS (GET_MODE (x),
6810 gen_rtx_PLUS (GET_MODE (x), XEXP (x, 0),
6811 GEN_INT (high)),
6812 GEN_INT (low));
6814 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6815 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
6816 opnum, (enum reload_type)type);
6817 *win = 1;
6818 return x;
6821 if (GET_CODE (x) == SYMBOL_REF
6822 && reg_offset_p
6823 && VECTOR_MEM_NONE_P (mode)
6824 && !SPE_VECTOR_MODE (mode)
6825 #if TARGET_MACHO
6826 && DEFAULT_ABI == ABI_DARWIN
6827 && (flag_pic || MACHO_DYNAMIC_NO_PIC_P)
6828 #else
6829 && DEFAULT_ABI == ABI_V4
6830 && !flag_pic
6831 #endif
6832 /* Don't do this for TFmode or TDmode, since the result isn't offsettable.
6833 The same goes for DImode without 64-bit gprs and DFmode and DDmode
6834 without fprs. */
6835 && mode != TFmode
6836 && mode != TDmode
6837 && (mode != DImode || TARGET_POWERPC64)
6838 && ((mode != DFmode && mode != DDmode) || TARGET_POWERPC64
6839 || (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)))
6841 #if TARGET_MACHO
6842 if (flag_pic)
6844 rtx offset = machopic_gen_offset (x);
6845 x = gen_rtx_LO_SUM (GET_MODE (x),
6846 gen_rtx_PLUS (Pmode, pic_offset_table_rtx,
6847 gen_rtx_HIGH (Pmode, offset)), offset);
6849 else
6850 #endif
6851 x = gen_rtx_LO_SUM (GET_MODE (x),
6852 gen_rtx_HIGH (Pmode, x), x);
6854 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6855 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6856 opnum, (enum reload_type)type);
6857 *win = 1;
6858 return x;
6861 /* Reload an offset address wrapped by an AND that represents the
6862 masking of the lower bits. Strip the outer AND and let reload
6863 convert the offset address into an indirect address. For VSX,
6864 force reload to create the address with an AND in a separate
6865 register, because we can't guarantee an altivec register will
6866 be used. */
6867 if (VECTOR_MEM_ALTIVEC_P (mode)
6868 && GET_CODE (x) == AND
6869 && GET_CODE (XEXP (x, 0)) == PLUS
6870 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
6871 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
6872 && GET_CODE (XEXP (x, 1)) == CONST_INT
6873 && INTVAL (XEXP (x, 1)) == -16)
6875 x = XEXP (x, 0);
6876 *win = 1;
6877 return x;
6880 if (TARGET_TOC
6881 && reg_offset_p
6882 && GET_CODE (x) == SYMBOL_REF
6883 && constant_pool_expr_p (x)
6884 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), mode))
6886 x = create_TOC_reference (x, NULL_RTX);
6887 if (TARGET_CMODEL != CMODEL_SMALL)
6888 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6889 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6890 opnum, (enum reload_type) type);
6891 *win = 1;
6892 return x;
6894 *win = 0;
6895 return x;
6898 /* Debug version of rs6000_legitimize_reload_address. */
6899 static rtx
6900 rs6000_debug_legitimize_reload_address (rtx x, enum machine_mode mode,
6901 int opnum, int type,
6902 int ind_levels, int *win)
6904 rtx ret = rs6000_legitimize_reload_address (x, mode, opnum, type,
6905 ind_levels, win);
6906 fprintf (stderr,
6907 "\nrs6000_legitimize_reload_address: mode = %s, opnum = %d, "
6908 "type = %d, ind_levels = %d, win = %d, original addr:\n",
6909 GET_MODE_NAME (mode), opnum, type, ind_levels, *win);
6910 debug_rtx (x);
6912 if (x == ret)
6913 fprintf (stderr, "Same address returned\n");
6914 else if (!ret)
6915 fprintf (stderr, "NULL returned\n");
6916 else
6918 fprintf (stderr, "New address:\n");
6919 debug_rtx (ret);
6922 return ret;
6925 /* TARGET_LEGITIMATE_ADDRESS_P recognizes an RTL expression
6926 that is a valid memory address for an instruction.
6927 The MODE argument is the machine mode for the MEM expression
6928 that wants to use this address.
6930 On the RS/6000, there are four valid address: a SYMBOL_REF that
6931 refers to a constant pool entry of an address (or the sum of it
6932 plus a constant), a short (16-bit signed) constant plus a register,
6933 the sum of two registers, or a register indirect, possibly with an
6934 auto-increment. For DFmode, DDmode and DImode with a constant plus
6935 register, we must ensure that both words are addressable or PowerPC64
6936 with offset word aligned.
6938 For modes spanning multiple registers (DFmode and DDmode in 32-bit GPRs,
6939 32-bit DImode, TImode, TFmode, TDmode), indexed addressing cannot be used
6940 because adjacent memory cells are accessed by adding word-sized offsets
6941 during assembly output. */
6942 bool
6943 rs6000_legitimate_address_p (enum machine_mode mode, rtx x, bool reg_ok_strict)
6945 bool reg_offset_p = reg_offset_addressing_ok_p (mode);
6947 /* If this is an unaligned stvx/ldvx type address, discard the outer AND. */
6948 if (VECTOR_MEM_ALTIVEC_P (mode)
6949 && GET_CODE (x) == AND
6950 && GET_CODE (XEXP (x, 1)) == CONST_INT
6951 && INTVAL (XEXP (x, 1)) == -16)
6952 x = XEXP (x, 0);
6954 if (RS6000_SYMBOL_REF_TLS_P (x))
6955 return 0;
6956 if (legitimate_indirect_address_p (x, reg_ok_strict))
6957 return 1;
6958 if ((GET_CODE (x) == PRE_INC || GET_CODE (x) == PRE_DEC)
6959 && !VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)
6960 && !SPE_VECTOR_MODE (mode)
6961 && mode != TFmode
6962 && mode != TDmode
6963 /* Restrict addressing for DI because of our SUBREG hackery. */
6964 && !(TARGET_E500_DOUBLE
6965 && (mode == DFmode || mode == DDmode || mode == DImode))
6966 && TARGET_UPDATE
6967 && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict))
6968 return 1;
6969 if (virtual_stack_registers_memory_p (x))
6970 return 1;
6971 if (reg_offset_p && legitimate_small_data_p (mode, x))
6972 return 1;
6973 if (reg_offset_p
6974 && legitimate_constant_pool_address_p (x, mode, reg_ok_strict))
6975 return 1;
6976 /* If not REG_OK_STRICT (before reload) let pass any stack offset. */
6977 if (! reg_ok_strict
6978 && reg_offset_p
6979 && GET_CODE (x) == PLUS
6980 && GET_CODE (XEXP (x, 0)) == REG
6981 && (XEXP (x, 0) == virtual_stack_vars_rtx
6982 || XEXP (x, 0) == arg_pointer_rtx)
6983 && GET_CODE (XEXP (x, 1)) == CONST_INT)
6984 return 1;
6985 if (rs6000_legitimate_offset_address_p (mode, x, reg_ok_strict))
6986 return 1;
6987 if (mode != TImode
6988 && mode != TFmode
6989 && mode != TDmode
6990 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
6991 || TARGET_POWERPC64
6992 || (mode != DFmode && mode != DDmode)
6993 || (TARGET_E500_DOUBLE && mode != DDmode))
6994 && (TARGET_POWERPC64 || mode != DImode)
6995 && !avoiding_indexed_address_p (mode)
6996 && legitimate_indexed_address_p (x, reg_ok_strict))
6997 return 1;
6998 if (GET_CODE (x) == PRE_MODIFY
6999 && mode != TImode
7000 && mode != TFmode
7001 && mode != TDmode
7002 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
7003 || TARGET_POWERPC64
7004 || ((mode != DFmode && mode != DDmode) || TARGET_E500_DOUBLE))
7005 && (TARGET_POWERPC64 || mode != DImode)
7006 && !VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)
7007 && !SPE_VECTOR_MODE (mode)
7008 /* Restrict addressing for DI because of our SUBREG hackery. */
7009 && !(TARGET_E500_DOUBLE
7010 && (mode == DFmode || mode == DDmode || mode == DImode))
7011 && TARGET_UPDATE
7012 && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict)
7013 && (rs6000_legitimate_offset_address_p (mode, XEXP (x, 1), reg_ok_strict)
7014 || (!avoiding_indexed_address_p (mode)
7015 && legitimate_indexed_address_p (XEXP (x, 1), reg_ok_strict)))
7016 && rtx_equal_p (XEXP (XEXP (x, 1), 0), XEXP (x, 0)))
7017 return 1;
7018 if (reg_offset_p && legitimate_lo_sum_address_p (mode, x, reg_ok_strict))
7019 return 1;
7020 return 0;
7023 /* Debug version of rs6000_legitimate_address_p. */
7024 static bool
7025 rs6000_debug_legitimate_address_p (enum machine_mode mode, rtx x,
7026 bool reg_ok_strict)
7028 bool ret = rs6000_legitimate_address_p (mode, x, reg_ok_strict);
7029 fprintf (stderr,
7030 "\nrs6000_legitimate_address_p: return = %s, mode = %s, "
7031 "strict = %d, code = %s\n",
7032 ret ? "true" : "false",
7033 GET_MODE_NAME (mode),
7034 reg_ok_strict,
7035 GET_RTX_NAME (GET_CODE (x)));
7036 debug_rtx (x);
7038 return ret;
7041 /* Implement TARGET_MODE_DEPENDENT_ADDRESS_P. */
7043 static bool
7044 rs6000_mode_dependent_address_p (const_rtx addr)
7046 return rs6000_mode_dependent_address_ptr (addr);
7049 /* Go to LABEL if ADDR (a legitimate address expression)
7050 has an effect that depends on the machine mode it is used for.
7052 On the RS/6000 this is true of all integral offsets (since AltiVec
7053 and VSX modes don't allow them) or is a pre-increment or decrement.
7055 ??? Except that due to conceptual problems in offsettable_address_p
7056 we can't really report the problems of integral offsets. So leave
7057 this assuming that the adjustable offset must be valid for the
7058 sub-words of a TFmode operand, which is what we had before. */
7060 static bool
7061 rs6000_mode_dependent_address (const_rtx addr)
7063 switch (GET_CODE (addr))
7065 case PLUS:
7066 /* Any offset from virtual_stack_vars_rtx and arg_pointer_rtx
7067 is considered a legitimate address before reload, so there
7068 are no offset restrictions in that case. Note that this
7069 condition is safe in strict mode because any address involving
7070 virtual_stack_vars_rtx or arg_pointer_rtx would already have
7071 been rejected as illegitimate. */
7072 if (XEXP (addr, 0) != virtual_stack_vars_rtx
7073 && XEXP (addr, 0) != arg_pointer_rtx
7074 && GET_CODE (XEXP (addr, 1)) == CONST_INT)
7076 unsigned HOST_WIDE_INT val = INTVAL (XEXP (addr, 1));
7077 return val + 12 + 0x8000 >= 0x10000;
7079 break;
7081 case LO_SUM:
7082 /* Anything in the constant pool is sufficiently aligned that
7083 all bytes have the same high part address. */
7084 return !legitimate_constant_pool_address_p (addr, QImode, false);
7086 /* Auto-increment cases are now treated generically in recog.c. */
7087 case PRE_MODIFY:
7088 return TARGET_UPDATE;
7090 /* AND is only allowed in Altivec loads. */
7091 case AND:
7092 return true;
7094 default:
7095 break;
7098 return false;
7101 /* Debug version of rs6000_mode_dependent_address. */
7102 static bool
7103 rs6000_debug_mode_dependent_address (const_rtx addr)
7105 bool ret = rs6000_mode_dependent_address (addr);
7107 fprintf (stderr, "\nrs6000_mode_dependent_address: ret = %s\n",
7108 ret ? "true" : "false");
7109 debug_rtx (addr);
7111 return ret;
7114 /* Implement FIND_BASE_TERM. */
7117 rs6000_find_base_term (rtx op)
7119 rtx base, offset;
7121 split_const (op, &base, &offset);
7122 if (GET_CODE (base) == UNSPEC)
7123 switch (XINT (base, 1))
7125 case UNSPEC_TOCREL:
7126 case UNSPEC_MACHOPIC_OFFSET:
7127 /* OP represents SYM [+ OFFSET] - ANCHOR. SYM is the base term
7128 for aliasing purposes. */
7129 return XVECEXP (base, 0, 0);
7132 return op;
7135 /* More elaborate version of recog's offsettable_memref_p predicate
7136 that works around the ??? note of rs6000_mode_dependent_address.
7137 In particular it accepts
7139 (mem:DI (plus:SI (reg/f:SI 31 31) (const_int 32760 [0x7ff8])))
7141 in 32-bit mode, that the recog predicate rejects. */
7143 bool
7144 rs6000_offsettable_memref_p (rtx op)
7146 if (!MEM_P (op))
7147 return false;
7149 /* First mimic offsettable_memref_p. */
7150 if (offsettable_address_p (1, GET_MODE (op), XEXP (op, 0)))
7151 return true;
7153 /* offsettable_address_p invokes rs6000_mode_dependent_address, but
7154 the latter predicate knows nothing about the mode of the memory
7155 reference and, therefore, assumes that it is the largest supported
7156 mode (TFmode). As a consequence, legitimate offsettable memory
7157 references are rejected. rs6000_legitimate_offset_address_p contains
7158 the correct logic for the PLUS case of rs6000_mode_dependent_address. */
7159 return rs6000_legitimate_offset_address_p (GET_MODE (op), XEXP (op, 0), 1);
7162 /* Change register usage conditional on target flags. */
7163 static void
7164 rs6000_conditional_register_usage (void)
7166 int i;
7168 if (TARGET_DEBUG_TARGET)
7169 fprintf (stderr, "rs6000_conditional_register_usage called\n");
7171 /* Set MQ register fixed (already call_used) if not POWER
7172 architecture (RIOS1, RIOS2, RSC, and PPC601) so that it will not
7173 be allocated. */
7174 if (! TARGET_POWER)
7175 fixed_regs[64] = 1;
7177 /* 64-bit AIX and Linux reserve GPR13 for thread-private data. */
7178 if (TARGET_64BIT)
7179 fixed_regs[13] = call_used_regs[13]
7180 = call_really_used_regs[13] = 1;
7182 /* Conditionally disable FPRs. */
7183 if (TARGET_SOFT_FLOAT || !TARGET_FPRS)
7184 for (i = 32; i < 64; i++)
7185 fixed_regs[i] = call_used_regs[i]
7186 = call_really_used_regs[i] = 1;
7188 /* The TOC register is not killed across calls in a way that is
7189 visible to the compiler. */
7190 if (DEFAULT_ABI == ABI_AIX)
7191 call_really_used_regs[2] = 0;
7193 if (DEFAULT_ABI == ABI_V4
7194 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
7195 && flag_pic == 2)
7196 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
7198 if (DEFAULT_ABI == ABI_V4
7199 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
7200 && flag_pic == 1)
7201 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
7202 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
7203 = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
7205 if (DEFAULT_ABI == ABI_DARWIN
7206 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM)
7207 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
7208 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
7209 = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
7211 if (TARGET_TOC && TARGET_MINIMAL_TOC)
7212 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
7213 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
7215 if (TARGET_SPE)
7217 global_regs[SPEFSCR_REGNO] = 1;
7218 /* We used to use r14 as FIXED_SCRATCH to address SPE 64-bit
7219 registers in prologues and epilogues. We no longer use r14
7220 for FIXED_SCRATCH, but we're keeping r14 out of the allocation
7221 pool for link-compatibility with older versions of GCC. Once
7222 "old" code has died out, we can return r14 to the allocation
7223 pool. */
7224 fixed_regs[14]
7225 = call_used_regs[14]
7226 = call_really_used_regs[14] = 1;
7229 if (!TARGET_ALTIVEC && !TARGET_VSX)
7231 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
7232 fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1;
7233 call_really_used_regs[VRSAVE_REGNO] = 1;
7236 if (TARGET_ALTIVEC || TARGET_VSX)
7237 global_regs[VSCR_REGNO] = 1;
7239 if (TARGET_ALTIVEC_ABI)
7241 for (i = FIRST_ALTIVEC_REGNO; i < FIRST_ALTIVEC_REGNO + 20; ++i)
7242 call_used_regs[i] = call_really_used_regs[i] = 1;
7244 /* AIX reserves VR20:31 in non-extended ABI mode. */
7245 if (TARGET_XCOFF)
7246 for (i = FIRST_ALTIVEC_REGNO + 20; i < FIRST_ALTIVEC_REGNO + 32; ++i)
7247 fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1;
7251 /* Try to output insns to set TARGET equal to the constant C if it can
7252 be done in less than N insns. Do all computations in MODE.
7253 Returns the place where the output has been placed if it can be
7254 done and the insns have been emitted. If it would take more than N
7255 insns, zero is returned and no insns and emitted. */
7258 rs6000_emit_set_const (rtx dest, enum machine_mode mode,
7259 rtx source, int n ATTRIBUTE_UNUSED)
7261 rtx result, insn, set;
7262 HOST_WIDE_INT c0, c1;
7264 switch (mode)
7266 case QImode:
7267 case HImode:
7268 if (dest == NULL)
7269 dest = gen_reg_rtx (mode);
7270 emit_insn (gen_rtx_SET (VOIDmode, dest, source));
7271 return dest;
7273 case SImode:
7274 result = !can_create_pseudo_p () ? dest : gen_reg_rtx (SImode);
7276 emit_insn (gen_rtx_SET (VOIDmode, copy_rtx (result),
7277 GEN_INT (INTVAL (source)
7278 & (~ (HOST_WIDE_INT) 0xffff))));
7279 emit_insn (gen_rtx_SET (VOIDmode, dest,
7280 gen_rtx_IOR (SImode, copy_rtx (result),
7281 GEN_INT (INTVAL (source) & 0xffff))));
7282 result = dest;
7283 break;
7285 case DImode:
7286 switch (GET_CODE (source))
7288 case CONST_INT:
7289 c0 = INTVAL (source);
7290 c1 = -(c0 < 0);
7291 break;
7293 case CONST_DOUBLE:
7294 #if HOST_BITS_PER_WIDE_INT >= 64
7295 c0 = CONST_DOUBLE_LOW (source);
7296 c1 = -(c0 < 0);
7297 #else
7298 c0 = CONST_DOUBLE_LOW (source);
7299 c1 = CONST_DOUBLE_HIGH (source);
7300 #endif
7301 break;
7303 default:
7304 gcc_unreachable ();
7307 result = rs6000_emit_set_long_const (dest, c0, c1);
7308 break;
7310 default:
7311 gcc_unreachable ();
7314 insn = get_last_insn ();
7315 set = single_set (insn);
7316 if (! CONSTANT_P (SET_SRC (set)))
7317 set_unique_reg_note (insn, REG_EQUAL, source);
7319 return result;
7322 /* Having failed to find a 3 insn sequence in rs6000_emit_set_const,
7323 fall back to a straight forward decomposition. We do this to avoid
7324 exponential run times encountered when looking for longer sequences
7325 with rs6000_emit_set_const. */
7326 static rtx
7327 rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c1, HOST_WIDE_INT c2)
7329 if (!TARGET_POWERPC64)
7331 rtx operand1, operand2;
7333 operand1 = operand_subword_force (dest, WORDS_BIG_ENDIAN == 0,
7334 DImode);
7335 operand2 = operand_subword_force (copy_rtx (dest), WORDS_BIG_ENDIAN != 0,
7336 DImode);
7337 emit_move_insn (operand1, GEN_INT (c1));
7338 emit_move_insn (operand2, GEN_INT (c2));
7340 else
7342 HOST_WIDE_INT ud1, ud2, ud3, ud4;
7344 ud1 = c1 & 0xffff;
7345 ud2 = (c1 & 0xffff0000) >> 16;
7346 #if HOST_BITS_PER_WIDE_INT >= 64
7347 c2 = c1 >> 32;
7348 #endif
7349 ud3 = c2 & 0xffff;
7350 ud4 = (c2 & 0xffff0000) >> 16;
7352 if ((ud4 == 0xffff && ud3 == 0xffff && ud2 == 0xffff && (ud1 & 0x8000))
7353 || (ud4 == 0 && ud3 == 0 && ud2 == 0 && ! (ud1 & 0x8000)))
7355 if (ud1 & 0x8000)
7356 emit_move_insn (dest, GEN_INT (((ud1 ^ 0x8000) - 0x8000)));
7357 else
7358 emit_move_insn (dest, GEN_INT (ud1));
7361 else if ((ud4 == 0xffff && ud3 == 0xffff && (ud2 & 0x8000))
7362 || (ud4 == 0 && ud3 == 0 && ! (ud2 & 0x8000)))
7364 if (ud2 & 0x8000)
7365 emit_move_insn (dest, GEN_INT (((ud2 << 16) ^ 0x80000000)
7366 - 0x80000000));
7367 else
7368 emit_move_insn (dest, GEN_INT (ud2 << 16));
7369 if (ud1 != 0)
7370 emit_move_insn (copy_rtx (dest),
7371 gen_rtx_IOR (DImode, copy_rtx (dest),
7372 GEN_INT (ud1)));
7374 else if (ud3 == 0 && ud4 == 0)
7376 gcc_assert (ud2 & 0x8000);
7377 emit_move_insn (dest, GEN_INT (((ud2 << 16) ^ 0x80000000)
7378 - 0x80000000));
7379 if (ud1 != 0)
7380 emit_move_insn (copy_rtx (dest),
7381 gen_rtx_IOR (DImode, copy_rtx (dest),
7382 GEN_INT (ud1)));
7383 emit_move_insn (copy_rtx (dest),
7384 gen_rtx_ZERO_EXTEND (DImode,
7385 gen_lowpart (SImode,
7386 copy_rtx (dest))));
7388 else if ((ud4 == 0xffff && (ud3 & 0x8000))
7389 || (ud4 == 0 && ! (ud3 & 0x8000)))
7391 if (ud3 & 0x8000)
7392 emit_move_insn (dest, GEN_INT (((ud3 << 16) ^ 0x80000000)
7393 - 0x80000000));
7394 else
7395 emit_move_insn (dest, GEN_INT (ud3 << 16));
7397 if (ud2 != 0)
7398 emit_move_insn (copy_rtx (dest),
7399 gen_rtx_IOR (DImode, copy_rtx (dest),
7400 GEN_INT (ud2)));
7401 emit_move_insn (copy_rtx (dest),
7402 gen_rtx_ASHIFT (DImode, copy_rtx (dest),
7403 GEN_INT (16)));
7404 if (ud1 != 0)
7405 emit_move_insn (copy_rtx (dest),
7406 gen_rtx_IOR (DImode, copy_rtx (dest),
7407 GEN_INT (ud1)));
7409 else
7411 if (ud4 & 0x8000)
7412 emit_move_insn (dest, GEN_INT (((ud4 << 16) ^ 0x80000000)
7413 - 0x80000000));
7414 else
7415 emit_move_insn (dest, GEN_INT (ud4 << 16));
7417 if (ud3 != 0)
7418 emit_move_insn (copy_rtx (dest),
7419 gen_rtx_IOR (DImode, copy_rtx (dest),
7420 GEN_INT (ud3)));
7422 emit_move_insn (copy_rtx (dest),
7423 gen_rtx_ASHIFT (DImode, copy_rtx (dest),
7424 GEN_INT (32)));
7425 if (ud2 != 0)
7426 emit_move_insn (copy_rtx (dest),
7427 gen_rtx_IOR (DImode, copy_rtx (dest),
7428 GEN_INT (ud2 << 16)));
7429 if (ud1 != 0)
7430 emit_move_insn (copy_rtx (dest),
7431 gen_rtx_IOR (DImode, copy_rtx (dest), GEN_INT (ud1)));
7434 return dest;
7437 /* Helper for the following. Get rid of [r+r] memory refs
7438 in cases where it won't work (TImode, TFmode, TDmode). */
7440 static void
7441 rs6000_eliminate_indexed_memrefs (rtx operands[2])
7443 if (reload_in_progress)
7444 return;
7446 if (GET_CODE (operands[0]) == MEM
7447 && GET_CODE (XEXP (operands[0], 0)) != REG
7448 && ! legitimate_constant_pool_address_p (XEXP (operands[0], 0),
7449 GET_MODE (operands[0]), false))
7450 operands[0]
7451 = replace_equiv_address (operands[0],
7452 copy_addr_to_reg (XEXP (operands[0], 0)));
7454 if (GET_CODE (operands[1]) == MEM
7455 && GET_CODE (XEXP (operands[1], 0)) != REG
7456 && ! legitimate_constant_pool_address_p (XEXP (operands[1], 0),
7457 GET_MODE (operands[1]), false))
7458 operands[1]
7459 = replace_equiv_address (operands[1],
7460 copy_addr_to_reg (XEXP (operands[1], 0)));
7463 /* Emit a move from SOURCE to DEST in mode MODE. */
7464 void
7465 rs6000_emit_move (rtx dest, rtx source, enum machine_mode mode)
7467 rtx operands[2];
7468 operands[0] = dest;
7469 operands[1] = source;
7471 if (TARGET_DEBUG_ADDR)
7473 fprintf (stderr,
7474 "\nrs6000_emit_move: mode = %s, reload_in_progress = %d, "
7475 "reload_completed = %d, can_create_pseudos = %d.\ndest:\n",
7476 GET_MODE_NAME (mode),
7477 reload_in_progress,
7478 reload_completed,
7479 can_create_pseudo_p ());
7480 debug_rtx (dest);
7481 fprintf (stderr, "source:\n");
7482 debug_rtx (source);
7485 /* Sanity checks. Check that we get CONST_DOUBLE only when we should. */
7486 if (GET_CODE (operands[1]) == CONST_DOUBLE
7487 && ! FLOAT_MODE_P (mode)
7488 && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
7490 /* FIXME. This should never happen. */
7491 /* Since it seems that it does, do the safe thing and convert
7492 to a CONST_INT. */
7493 operands[1] = gen_int_mode (CONST_DOUBLE_LOW (operands[1]), mode);
7495 gcc_assert (GET_CODE (operands[1]) != CONST_DOUBLE
7496 || FLOAT_MODE_P (mode)
7497 || ((CONST_DOUBLE_HIGH (operands[1]) != 0
7498 || CONST_DOUBLE_LOW (operands[1]) < 0)
7499 && (CONST_DOUBLE_HIGH (operands[1]) != -1
7500 || CONST_DOUBLE_LOW (operands[1]) >= 0)));
7502 /* Check if GCC is setting up a block move that will end up using FP
7503 registers as temporaries. We must make sure this is acceptable. */
7504 if (GET_CODE (operands[0]) == MEM
7505 && GET_CODE (operands[1]) == MEM
7506 && mode == DImode
7507 && (SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[0]))
7508 || SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[1])))
7509 && ! (SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[0]) > 32
7510 ? 32 : MEM_ALIGN (operands[0])))
7511 || SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[1]) > 32
7512 ? 32
7513 : MEM_ALIGN (operands[1]))))
7514 && ! MEM_VOLATILE_P (operands [0])
7515 && ! MEM_VOLATILE_P (operands [1]))
7517 emit_move_insn (adjust_address (operands[0], SImode, 0),
7518 adjust_address (operands[1], SImode, 0));
7519 emit_move_insn (adjust_address (copy_rtx (operands[0]), SImode, 4),
7520 adjust_address (copy_rtx (operands[1]), SImode, 4));
7521 return;
7524 if (can_create_pseudo_p () && GET_CODE (operands[0]) == MEM
7525 && !gpc_reg_operand (operands[1], mode))
7526 operands[1] = force_reg (mode, operands[1]);
7528 if (mode == SFmode && ! TARGET_POWERPC
7529 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
7530 && GET_CODE (operands[0]) == MEM)
7532 int regnum;
7534 if (reload_in_progress || reload_completed)
7535 regnum = true_regnum (operands[1]);
7536 else if (GET_CODE (operands[1]) == REG)
7537 regnum = REGNO (operands[1]);
7538 else
7539 regnum = -1;
7541 /* If operands[1] is a register, on POWER it may have
7542 double-precision data in it, so truncate it to single
7543 precision. */
7544 if (FP_REGNO_P (regnum) || regnum >= FIRST_PSEUDO_REGISTER)
7546 rtx newreg;
7547 newreg = (!can_create_pseudo_p () ? copy_rtx (operands[1])
7548 : gen_reg_rtx (mode));
7549 emit_insn (gen_aux_truncdfsf2 (newreg, operands[1]));
7550 operands[1] = newreg;
7554 /* Recognize the case where operand[1] is a reference to thread-local
7555 data and load its address to a register. */
7556 if (rs6000_tls_referenced_p (operands[1]))
7558 enum tls_model model;
7559 rtx tmp = operands[1];
7560 rtx addend = NULL;
7562 if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
7564 addend = XEXP (XEXP (tmp, 0), 1);
7565 tmp = XEXP (XEXP (tmp, 0), 0);
7568 gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
7569 model = SYMBOL_REF_TLS_MODEL (tmp);
7570 gcc_assert (model != 0);
7572 tmp = rs6000_legitimize_tls_address (tmp, model);
7573 if (addend)
7575 tmp = gen_rtx_PLUS (mode, tmp, addend);
7576 tmp = force_operand (tmp, operands[0]);
7578 operands[1] = tmp;
7581 /* Handle the case where reload calls us with an invalid address. */
7582 if (reload_in_progress && mode == Pmode
7583 && (! general_operand (operands[1], mode)
7584 || ! nonimmediate_operand (operands[0], mode)))
7585 goto emit_set;
7587 /* 128-bit constant floating-point values on Darwin should really be
7588 loaded as two parts. */
7589 if (!TARGET_IEEEQUAD && TARGET_LONG_DOUBLE_128
7590 && mode == TFmode && GET_CODE (operands[1]) == CONST_DOUBLE)
7592 /* DImode is used, not DFmode, because simplify_gen_subreg doesn't
7593 know how to get a DFmode SUBREG of a TFmode. */
7594 enum machine_mode imode = (TARGET_E500_DOUBLE ? DFmode : DImode);
7595 rs6000_emit_move (simplify_gen_subreg (imode, operands[0], mode, 0),
7596 simplify_gen_subreg (imode, operands[1], mode, 0),
7597 imode);
7598 rs6000_emit_move (simplify_gen_subreg (imode, operands[0], mode,
7599 GET_MODE_SIZE (imode)),
7600 simplify_gen_subreg (imode, operands[1], mode,
7601 GET_MODE_SIZE (imode)),
7602 imode);
7603 return;
7606 if (reload_in_progress && cfun->machine->sdmode_stack_slot != NULL_RTX)
7607 cfun->machine->sdmode_stack_slot =
7608 eliminate_regs (cfun->machine->sdmode_stack_slot, VOIDmode, NULL_RTX);
7610 if (reload_in_progress
7611 && mode == SDmode
7612 && MEM_P (operands[0])
7613 && rtx_equal_p (operands[0], cfun->machine->sdmode_stack_slot)
7614 && REG_P (operands[1]))
7616 if (FP_REGNO_P (REGNO (operands[1])))
7618 rtx mem = adjust_address_nv (operands[0], DDmode, 0);
7619 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
7620 emit_insn (gen_movsd_store (mem, operands[1]));
7622 else if (INT_REGNO_P (REGNO (operands[1])))
7624 rtx mem = adjust_address_nv (operands[0], mode, 4);
7625 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
7626 emit_insn (gen_movsd_hardfloat (mem, operands[1]));
7628 else
7629 gcc_unreachable();
7630 return;
7632 if (reload_in_progress
7633 && mode == SDmode
7634 && REG_P (operands[0])
7635 && MEM_P (operands[1])
7636 && rtx_equal_p (operands[1], cfun->machine->sdmode_stack_slot))
7638 if (FP_REGNO_P (REGNO (operands[0])))
7640 rtx mem = adjust_address_nv (operands[1], DDmode, 0);
7641 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
7642 emit_insn (gen_movsd_load (operands[0], mem));
7644 else if (INT_REGNO_P (REGNO (operands[0])))
7646 rtx mem = adjust_address_nv (operands[1], mode, 4);
7647 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
7648 emit_insn (gen_movsd_hardfloat (operands[0], mem));
7650 else
7651 gcc_unreachable();
7652 return;
7655 /* FIXME: In the long term, this switch statement should go away
7656 and be replaced by a sequence of tests based on things like
7657 mode == Pmode. */
7658 switch (mode)
7660 case HImode:
7661 case QImode:
7662 if (CONSTANT_P (operands[1])
7663 && GET_CODE (operands[1]) != CONST_INT)
7664 operands[1] = force_const_mem (mode, operands[1]);
7665 break;
7667 case TFmode:
7668 case TDmode:
7669 rs6000_eliminate_indexed_memrefs (operands);
7670 /* fall through */
7672 case DFmode:
7673 case DDmode:
7674 case SFmode:
7675 case SDmode:
7676 if (CONSTANT_P (operands[1])
7677 && ! easy_fp_constant (operands[1], mode))
7678 operands[1] = force_const_mem (mode, operands[1]);
7679 break;
7681 case V16QImode:
7682 case V8HImode:
7683 case V4SFmode:
7684 case V4SImode:
7685 case V4HImode:
7686 case V2SFmode:
7687 case V2SImode:
7688 case V1DImode:
7689 case V2DFmode:
7690 case V2DImode:
7691 if (CONSTANT_P (operands[1])
7692 && !easy_vector_constant (operands[1], mode))
7693 operands[1] = force_const_mem (mode, operands[1]);
7694 break;
7696 case SImode:
7697 case DImode:
7698 /* Use default pattern for address of ELF small data */
7699 if (TARGET_ELF
7700 && mode == Pmode
7701 && DEFAULT_ABI == ABI_V4
7702 && (GET_CODE (operands[1]) == SYMBOL_REF
7703 || GET_CODE (operands[1]) == CONST)
7704 && small_data_operand (operands[1], mode))
7706 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
7707 return;
7710 if (DEFAULT_ABI == ABI_V4
7711 && mode == Pmode && mode == SImode
7712 && flag_pic == 1 && got_operand (operands[1], mode))
7714 emit_insn (gen_movsi_got (operands[0], operands[1]));
7715 return;
7718 if ((TARGET_ELF || DEFAULT_ABI == ABI_DARWIN)
7719 && TARGET_NO_TOC
7720 && ! flag_pic
7721 && mode == Pmode
7722 && CONSTANT_P (operands[1])
7723 && GET_CODE (operands[1]) != HIGH
7724 && GET_CODE (operands[1]) != CONST_INT)
7726 rtx target = (!can_create_pseudo_p ()
7727 ? operands[0]
7728 : gen_reg_rtx (mode));
7730 /* If this is a function address on -mcall-aixdesc,
7731 convert it to the address of the descriptor. */
7732 if (DEFAULT_ABI == ABI_AIX
7733 && GET_CODE (operands[1]) == SYMBOL_REF
7734 && XSTR (operands[1], 0)[0] == '.')
7736 const char *name = XSTR (operands[1], 0);
7737 rtx new_ref;
7738 while (*name == '.')
7739 name++;
7740 new_ref = gen_rtx_SYMBOL_REF (Pmode, name);
7741 CONSTANT_POOL_ADDRESS_P (new_ref)
7742 = CONSTANT_POOL_ADDRESS_P (operands[1]);
7743 SYMBOL_REF_FLAGS (new_ref) = SYMBOL_REF_FLAGS (operands[1]);
7744 SYMBOL_REF_USED (new_ref) = SYMBOL_REF_USED (operands[1]);
7745 SYMBOL_REF_DATA (new_ref) = SYMBOL_REF_DATA (operands[1]);
7746 operands[1] = new_ref;
7749 if (DEFAULT_ABI == ABI_DARWIN)
7751 #if TARGET_MACHO
7752 if (MACHO_DYNAMIC_NO_PIC_P)
7754 /* Take care of any required data indirection. */
7755 operands[1] = rs6000_machopic_legitimize_pic_address (
7756 operands[1], mode, operands[0]);
7757 if (operands[0] != operands[1])
7758 emit_insn (gen_rtx_SET (VOIDmode,
7759 operands[0], operands[1]));
7760 return;
7762 #endif
7763 emit_insn (gen_macho_high (target, operands[1]));
7764 emit_insn (gen_macho_low (operands[0], target, operands[1]));
7765 return;
7768 emit_insn (gen_elf_high (target, operands[1]));
7769 emit_insn (gen_elf_low (operands[0], target, operands[1]));
7770 return;
7773 /* If this is a SYMBOL_REF that refers to a constant pool entry,
7774 and we have put it in the TOC, we just need to make a TOC-relative
7775 reference to it. */
7776 if ((TARGET_TOC
7777 && GET_CODE (operands[1]) == SYMBOL_REF
7778 && constant_pool_expr_p (operands[1])
7779 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (operands[1]),
7780 get_pool_mode (operands[1])))
7781 || (TARGET_CMODEL == CMODEL_MEDIUM
7782 && GET_CODE (operands[1]) == SYMBOL_REF
7783 && !CONSTANT_POOL_ADDRESS_P (operands[1])
7784 && SYMBOL_REF_LOCAL_P (operands[1])))
7786 rtx reg = NULL_RTX;
7787 if (TARGET_CMODEL != CMODEL_SMALL)
7789 if (can_create_pseudo_p ())
7790 reg = gen_reg_rtx (Pmode);
7791 else
7792 reg = operands[0];
7794 operands[1] = create_TOC_reference (operands[1], reg);
7796 else if (mode == Pmode
7797 && CONSTANT_P (operands[1])
7798 && ((GET_CODE (operands[1]) != CONST_INT
7799 && ! easy_fp_constant (operands[1], mode))
7800 || (GET_CODE (operands[1]) == CONST_INT
7801 && (num_insns_constant (operands[1], mode)
7802 > (TARGET_CMODEL != CMODEL_SMALL ? 3 : 2)))
7803 || (GET_CODE (operands[0]) == REG
7804 && FP_REGNO_P (REGNO (operands[0]))))
7805 && GET_CODE (operands[1]) != HIGH
7806 && ! legitimate_constant_pool_address_p (operands[1], mode,
7807 false)
7808 && ! toc_relative_expr_p (operands[1])
7809 && (TARGET_CMODEL == CMODEL_SMALL
7810 || can_create_pseudo_p ()
7811 || (REG_P (operands[0])
7812 && INT_REG_OK_FOR_BASE_P (operands[0], true))))
7815 #if TARGET_MACHO
7816 /* Darwin uses a special PIC legitimizer. */
7817 if (DEFAULT_ABI == ABI_DARWIN && MACHOPIC_INDIRECT)
7819 operands[1] =
7820 rs6000_machopic_legitimize_pic_address (operands[1], mode,
7821 operands[0]);
7822 if (operands[0] != operands[1])
7823 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
7824 return;
7826 #endif
7828 /* If we are to limit the number of things we put in the TOC and
7829 this is a symbol plus a constant we can add in one insn,
7830 just put the symbol in the TOC and add the constant. Don't do
7831 this if reload is in progress. */
7832 if (GET_CODE (operands[1]) == CONST
7833 && TARGET_NO_SUM_IN_TOC && ! reload_in_progress
7834 && GET_CODE (XEXP (operands[1], 0)) == PLUS
7835 && add_operand (XEXP (XEXP (operands[1], 0), 1), mode)
7836 && (GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == LABEL_REF
7837 || GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == SYMBOL_REF)
7838 && ! side_effects_p (operands[0]))
7840 rtx sym =
7841 force_const_mem (mode, XEXP (XEXP (operands[1], 0), 0));
7842 rtx other = XEXP (XEXP (operands[1], 0), 1);
7844 sym = force_reg (mode, sym);
7845 emit_insn (gen_add3_insn (operands[0], sym, other));
7846 return;
7849 operands[1] = force_const_mem (mode, operands[1]);
7851 if (TARGET_TOC
7852 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
7853 && constant_pool_expr_p (XEXP (operands[1], 0))
7854 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (
7855 get_pool_constant (XEXP (operands[1], 0)),
7856 get_pool_mode (XEXP (operands[1], 0))))
7858 rtx tocref;
7859 rtx reg = NULL_RTX;
7860 if (TARGET_CMODEL != CMODEL_SMALL)
7862 if (can_create_pseudo_p ())
7863 reg = gen_reg_rtx (Pmode);
7864 else
7865 reg = operands[0];
7867 tocref = create_TOC_reference (XEXP (operands[1], 0), reg);
7868 operands[1] = gen_const_mem (mode, tocref);
7869 set_mem_alias_set (operands[1], get_TOC_alias_set ());
7872 break;
7874 case TImode:
7875 rs6000_eliminate_indexed_memrefs (operands);
7877 if (TARGET_POWER)
7879 emit_insn (gen_rtx_PARALLEL (VOIDmode,
7880 gen_rtvec (2,
7881 gen_rtx_SET (VOIDmode,
7882 operands[0], operands[1]),
7883 gen_rtx_CLOBBER (VOIDmode,
7884 gen_rtx_SCRATCH (SImode)))));
7885 return;
7887 break;
7889 default:
7890 fatal_insn ("bad move", gen_rtx_SET (VOIDmode, dest, source));
7893 /* Above, we may have called force_const_mem which may have returned
7894 an invalid address. If we can, fix this up; otherwise, reload will
7895 have to deal with it. */
7896 if (GET_CODE (operands[1]) == MEM && ! reload_in_progress)
7897 operands[1] = validize_mem (operands[1]);
7899 emit_set:
7900 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
7903 /* Nonzero if we can use a floating-point register to pass this arg. */
7904 #define USE_FP_FOR_ARG_P(CUM,MODE,TYPE) \
7905 (SCALAR_FLOAT_MODE_P (MODE) \
7906 && (CUM)->fregno <= FP_ARG_MAX_REG \
7907 && TARGET_HARD_FLOAT && TARGET_FPRS)
7909 /* Nonzero if we can use an AltiVec register to pass this arg. */
7910 #define USE_ALTIVEC_FOR_ARG_P(CUM,MODE,TYPE,NAMED) \
7911 ((ALTIVEC_VECTOR_MODE (MODE) || VSX_VECTOR_MODE (MODE)) \
7912 && (CUM)->vregno <= ALTIVEC_ARG_MAX_REG \
7913 && TARGET_ALTIVEC_ABI \
7914 && (NAMED))
7916 /* Return a nonzero value to say to return the function value in
7917 memory, just as large structures are always returned. TYPE will be
7918 the data type of the value, and FNTYPE will be the type of the
7919 function doing the returning, or @code{NULL} for libcalls.
7921 The AIX ABI for the RS/6000 specifies that all structures are
7922 returned in memory. The Darwin ABI does the same.
7924 For the Darwin 64 Bit ABI, a function result can be returned in
7925 registers or in memory, depending on the size of the return data
7926 type. If it is returned in registers, the value occupies the same
7927 registers as it would if it were the first and only function
7928 argument. Otherwise, the function places its result in memory at
7929 the location pointed to by GPR3.
7931 The SVR4 ABI specifies that structures <= 8 bytes are returned in r3/r4,
7932 but a draft put them in memory, and GCC used to implement the draft
7933 instead of the final standard. Therefore, aix_struct_return
7934 controls this instead of DEFAULT_ABI; V.4 targets needing backward
7935 compatibility can change DRAFT_V4_STRUCT_RET to override the
7936 default, and -m switches get the final word. See
7937 rs6000_option_override_internal for more details.
7939 The PPC32 SVR4 ABI uses IEEE double extended for long double, if 128-bit
7940 long double support is enabled. These values are returned in memory.
7942 int_size_in_bytes returns -1 for variable size objects, which go in
7943 memory always. The cast to unsigned makes -1 > 8. */
7945 static bool
7946 rs6000_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
7948 /* For the Darwin64 ABI, test if we can fit the return value in regs. */
7949 if (TARGET_MACHO
7950 && rs6000_darwin64_abi
7951 && TREE_CODE (type) == RECORD_TYPE
7952 && int_size_in_bytes (type) > 0)
7954 CUMULATIVE_ARGS valcum;
7955 rtx valret;
7957 valcum.words = 0;
7958 valcum.fregno = FP_ARG_MIN_REG;
7959 valcum.vregno = ALTIVEC_ARG_MIN_REG;
7960 /* Do a trial code generation as if this were going to be passed
7961 as an argument; if any part goes in memory, we return NULL. */
7962 valret = rs6000_darwin64_record_arg (&valcum, type, true, true);
7963 if (valret)
7964 return false;
7965 /* Otherwise fall through to more conventional ABI rules. */
7968 if (AGGREGATE_TYPE_P (type)
7969 && (aix_struct_return
7970 || (unsigned HOST_WIDE_INT) int_size_in_bytes (type) > 8))
7971 return true;
7973 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
7974 modes only exist for GCC vector types if -maltivec. */
7975 if (TARGET_32BIT && !TARGET_ALTIVEC_ABI
7976 && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
7977 return false;
7979 /* Return synthetic vectors in memory. */
7980 if (TREE_CODE (type) == VECTOR_TYPE
7981 && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
7983 static bool warned_for_return_big_vectors = false;
7984 if (!warned_for_return_big_vectors)
7986 warning (0, "GCC vector returned by reference: "
7987 "non-standard ABI extension with no compatibility guarantee");
7988 warned_for_return_big_vectors = true;
7990 return true;
7993 if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && TYPE_MODE (type) == TFmode)
7994 return true;
7996 return false;
7999 #ifdef HAVE_AS_GNU_ATTRIBUTE
8000 /* Return TRUE if a call to function FNDECL may be one that
8001 potentially affects the function calling ABI of the object file. */
8003 static bool
8004 call_ABI_of_interest (tree fndecl)
8006 if (cgraph_state == CGRAPH_STATE_EXPANSION)
8008 struct cgraph_node *c_node;
8010 /* Libcalls are always interesting. */
8011 if (fndecl == NULL_TREE)
8012 return true;
8014 /* Any call to an external function is interesting. */
8015 if (DECL_EXTERNAL (fndecl))
8016 return true;
8018 /* Interesting functions that we are emitting in this object file. */
8019 c_node = cgraph_node (fndecl);
8020 return !cgraph_only_called_directly_p (c_node);
8022 return false;
8024 #endif
8026 /* Initialize a variable CUM of type CUMULATIVE_ARGS
8027 for a call to a function whose data type is FNTYPE.
8028 For a library call, FNTYPE is 0 and RETURN_MODE the return value mode.
8030 For incoming args we set the number of arguments in the prototype large
8031 so we never return a PARALLEL. */
8033 void
8034 init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype,
8035 rtx libname ATTRIBUTE_UNUSED, int incoming,
8036 int libcall, int n_named_args,
8037 tree fndecl ATTRIBUTE_UNUSED,
8038 enum machine_mode return_mode ATTRIBUTE_UNUSED)
8040 static CUMULATIVE_ARGS zero_cumulative;
8042 *cum = zero_cumulative;
8043 cum->words = 0;
8044 cum->fregno = FP_ARG_MIN_REG;
8045 cum->vregno = ALTIVEC_ARG_MIN_REG;
8046 cum->prototype = (fntype && prototype_p (fntype));
8047 cum->call_cookie = ((DEFAULT_ABI == ABI_V4 && libcall)
8048 ? CALL_LIBCALL : CALL_NORMAL);
8049 cum->sysv_gregno = GP_ARG_MIN_REG;
8050 cum->stdarg = stdarg_p (fntype);
8052 cum->nargs_prototype = 0;
8053 if (incoming || cum->prototype)
8054 cum->nargs_prototype = n_named_args;
8056 /* Check for a longcall attribute. */
8057 if ((!fntype && rs6000_default_long_calls)
8058 || (fntype
8059 && lookup_attribute ("longcall", TYPE_ATTRIBUTES (fntype))
8060 && !lookup_attribute ("shortcall", TYPE_ATTRIBUTES (fntype))))
8061 cum->call_cookie |= CALL_LONG;
8063 if (TARGET_DEBUG_ARG)
8065 fprintf (stderr, "\ninit_cumulative_args:");
8066 if (fntype)
8068 tree ret_type = TREE_TYPE (fntype);
8069 fprintf (stderr, " ret code = %s,",
8070 tree_code_name[ (int)TREE_CODE (ret_type) ]);
8073 if (cum->call_cookie & CALL_LONG)
8074 fprintf (stderr, " longcall,");
8076 fprintf (stderr, " proto = %d, nargs = %d\n",
8077 cum->prototype, cum->nargs_prototype);
8080 #ifdef HAVE_AS_GNU_ATTRIBUTE
8081 if (DEFAULT_ABI == ABI_V4)
8083 cum->escapes = call_ABI_of_interest (fndecl);
8084 if (cum->escapes)
8086 tree return_type;
8088 if (fntype)
8090 return_type = TREE_TYPE (fntype);
8091 return_mode = TYPE_MODE (return_type);
8093 else
8094 return_type = lang_hooks.types.type_for_mode (return_mode, 0);
8096 if (return_type != NULL)
8098 if (TREE_CODE (return_type) == RECORD_TYPE
8099 && TYPE_TRANSPARENT_AGGR (return_type))
8101 return_type = TREE_TYPE (first_field (return_type));
8102 return_mode = TYPE_MODE (return_type);
8104 if (AGGREGATE_TYPE_P (return_type)
8105 && ((unsigned HOST_WIDE_INT) int_size_in_bytes (return_type)
8106 <= 8))
8107 rs6000_returns_struct = true;
8109 if (SCALAR_FLOAT_MODE_P (return_mode))
8110 rs6000_passes_float = true;
8111 else if (ALTIVEC_VECTOR_MODE (return_mode)
8112 || VSX_VECTOR_MODE (return_mode)
8113 || SPE_VECTOR_MODE (return_mode))
8114 rs6000_passes_vector = true;
8117 #endif
8119 if (fntype
8120 && !TARGET_ALTIVEC
8121 && TARGET_ALTIVEC_ABI
8122 && ALTIVEC_VECTOR_MODE (TYPE_MODE (TREE_TYPE (fntype))))
8124 error ("cannot return value in vector register because"
8125 " altivec instructions are disabled, use -maltivec"
8126 " to enable them");
8130 /* Return true if TYPE must be passed on the stack and not in registers. */
8132 static bool
8133 rs6000_must_pass_in_stack (enum machine_mode mode, const_tree type)
8135 if (DEFAULT_ABI == ABI_AIX || TARGET_64BIT)
8136 return must_pass_in_stack_var_size (mode, type);
8137 else
8138 return must_pass_in_stack_var_size_or_pad (mode, type);
8141 /* If defined, a C expression which determines whether, and in which
8142 direction, to pad out an argument with extra space. The value
8143 should be of type `enum direction': either `upward' to pad above
8144 the argument, `downward' to pad below, or `none' to inhibit
8145 padding.
8147 For the AIX ABI structs are always stored left shifted in their
8148 argument slot. */
8150 enum direction
8151 function_arg_padding (enum machine_mode mode, const_tree type)
8153 #ifndef AGGREGATE_PADDING_FIXED
8154 #define AGGREGATE_PADDING_FIXED 0
8155 #endif
8156 #ifndef AGGREGATES_PAD_UPWARD_ALWAYS
8157 #define AGGREGATES_PAD_UPWARD_ALWAYS 0
8158 #endif
8160 if (!AGGREGATE_PADDING_FIXED)
8162 /* GCC used to pass structures of the same size as integer types as
8163 if they were in fact integers, ignoring FUNCTION_ARG_PADDING.
8164 i.e. Structures of size 1 or 2 (or 4 when TARGET_64BIT) were
8165 passed padded downward, except that -mstrict-align further
8166 muddied the water in that multi-component structures of 2 and 4
8167 bytes in size were passed padded upward.
8169 The following arranges for best compatibility with previous
8170 versions of gcc, but removes the -mstrict-align dependency. */
8171 if (BYTES_BIG_ENDIAN)
8173 HOST_WIDE_INT size = 0;
8175 if (mode == BLKmode)
8177 if (type && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST)
8178 size = int_size_in_bytes (type);
8180 else
8181 size = GET_MODE_SIZE (mode);
8183 if (size == 1 || size == 2 || size == 4)
8184 return downward;
8186 return upward;
8189 if (AGGREGATES_PAD_UPWARD_ALWAYS)
8191 if (type != 0 && AGGREGATE_TYPE_P (type))
8192 return upward;
8195 /* Fall back to the default. */
8196 return DEFAULT_FUNCTION_ARG_PADDING (mode, type);
8199 /* If defined, a C expression that gives the alignment boundary, in bits,
8200 of an argument with the specified mode and type. If it is not defined,
8201 PARM_BOUNDARY is used for all arguments.
8203 V.4 wants long longs and doubles to be double word aligned. Just
8204 testing the mode size is a boneheaded way to do this as it means
8205 that other types such as complex int are also double word aligned.
8206 However, we're stuck with this because changing the ABI might break
8207 existing library interfaces.
8209 Doubleword align SPE vectors.
8210 Quadword align Altivec vectors.
8211 Quadword align large synthetic vector types. */
8213 static unsigned int
8214 rs6000_function_arg_boundary (enum machine_mode mode, const_tree type)
8216 if (DEFAULT_ABI == ABI_V4
8217 && (GET_MODE_SIZE (mode) == 8
8218 || (TARGET_HARD_FLOAT
8219 && TARGET_FPRS
8220 && (mode == TFmode || mode == TDmode))))
8221 return 64;
8222 else if (SPE_VECTOR_MODE (mode)
8223 || (type && TREE_CODE (type) == VECTOR_TYPE
8224 && int_size_in_bytes (type) >= 8
8225 && int_size_in_bytes (type) < 16))
8226 return 64;
8227 else if ((ALTIVEC_VECTOR_MODE (mode) || VSX_VECTOR_MODE (mode))
8228 || (type && TREE_CODE (type) == VECTOR_TYPE
8229 && int_size_in_bytes (type) >= 16))
8230 return 128;
8231 else if (TARGET_MACHO
8232 && rs6000_darwin64_abi
8233 && mode == BLKmode
8234 && type && TYPE_ALIGN (type) > 64)
8235 return 128;
8236 else
8237 return PARM_BOUNDARY;
8240 /* For a function parm of MODE and TYPE, return the starting word in
8241 the parameter area. NWORDS of the parameter area are already used. */
8243 static unsigned int
8244 rs6000_parm_start (enum machine_mode mode, const_tree type,
8245 unsigned int nwords)
8247 unsigned int align;
8248 unsigned int parm_offset;
8250 align = rs6000_function_arg_boundary (mode, type) / PARM_BOUNDARY - 1;
8251 parm_offset = DEFAULT_ABI == ABI_V4 ? 2 : 6;
8252 return nwords + (-(parm_offset + nwords) & align);
8255 /* Compute the size (in words) of a function argument. */
8257 static unsigned long
8258 rs6000_arg_size (enum machine_mode mode, const_tree type)
8260 unsigned long size;
8262 if (mode != BLKmode)
8263 size = GET_MODE_SIZE (mode);
8264 else
8265 size = int_size_in_bytes (type);
8267 if (TARGET_32BIT)
8268 return (size + 3) >> 2;
8269 else
8270 return (size + 7) >> 3;
8273 /* Use this to flush pending int fields. */
8275 static void
8276 rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS *cum,
8277 HOST_WIDE_INT bitpos, int final)
8279 unsigned int startbit, endbit;
8280 int intregs, intoffset;
8281 enum machine_mode mode;
8283 /* Handle the situations where a float is taking up the first half
8284 of the GPR, and the other half is empty (typically due to
8285 alignment restrictions). We can detect this by a 8-byte-aligned
8286 int field, or by seeing that this is the final flush for this
8287 argument. Count the word and continue on. */
8288 if (cum->floats_in_gpr == 1
8289 && (cum->intoffset % 64 == 0
8290 || (cum->intoffset == -1 && final)))
8292 cum->words++;
8293 cum->floats_in_gpr = 0;
8296 if (cum->intoffset == -1)
8297 return;
8299 intoffset = cum->intoffset;
8300 cum->intoffset = -1;
8301 cum->floats_in_gpr = 0;
8303 if (intoffset % BITS_PER_WORD != 0)
8305 mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD,
8306 MODE_INT, 0);
8307 if (mode == BLKmode)
8309 /* We couldn't find an appropriate mode, which happens,
8310 e.g., in packed structs when there are 3 bytes to load.
8311 Back intoffset back to the beginning of the word in this
8312 case. */
8313 intoffset = intoffset & -BITS_PER_WORD;
8317 startbit = intoffset & -BITS_PER_WORD;
8318 endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD;
8319 intregs = (endbit - startbit) / BITS_PER_WORD;
8320 cum->words += intregs;
8321 /* words should be unsigned. */
8322 if ((unsigned)cum->words < (endbit/BITS_PER_WORD))
8324 int pad = (endbit/BITS_PER_WORD) - cum->words;
8325 cum->words += pad;
8329 /* The darwin64 ABI calls for us to recurse down through structs,
8330 looking for elements passed in registers. Unfortunately, we have
8331 to track int register count here also because of misalignments
8332 in powerpc alignment mode. */
8334 static void
8335 rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS *cum,
8336 const_tree type,
8337 HOST_WIDE_INT startbitpos)
8339 tree f;
8341 for (f = TYPE_FIELDS (type); f ; f = DECL_CHAIN (f))
8342 if (TREE_CODE (f) == FIELD_DECL)
8344 HOST_WIDE_INT bitpos = startbitpos;
8345 tree ftype = TREE_TYPE (f);
8346 enum machine_mode mode;
8347 if (ftype == error_mark_node)
8348 continue;
8349 mode = TYPE_MODE (ftype);
8351 if (DECL_SIZE (f) != 0
8352 && host_integerp (bit_position (f), 1))
8353 bitpos += int_bit_position (f);
8355 /* ??? FIXME: else assume zero offset. */
8357 if (TREE_CODE (ftype) == RECORD_TYPE)
8358 rs6000_darwin64_record_arg_advance_recurse (cum, ftype, bitpos);
8359 else if (USE_FP_FOR_ARG_P (cum, mode, ftype))
8361 unsigned n_fpregs = (GET_MODE_SIZE (mode) + 7) >> 3;
8362 rs6000_darwin64_record_arg_advance_flush (cum, bitpos, 0);
8363 cum->fregno += n_fpregs;
8364 /* Single-precision floats present a special problem for
8365 us, because they are smaller than an 8-byte GPR, and so
8366 the structure-packing rules combined with the standard
8367 varargs behavior mean that we want to pack float/float
8368 and float/int combinations into a single register's
8369 space. This is complicated by the arg advance flushing,
8370 which works on arbitrarily large groups of int-type
8371 fields. */
8372 if (mode == SFmode)
8374 if (cum->floats_in_gpr == 1)
8376 /* Two floats in a word; count the word and reset
8377 the float count. */
8378 cum->words++;
8379 cum->floats_in_gpr = 0;
8381 else if (bitpos % 64 == 0)
8383 /* A float at the beginning of an 8-byte word;
8384 count it and put off adjusting cum->words until
8385 we see if a arg advance flush is going to do it
8386 for us. */
8387 cum->floats_in_gpr++;
8389 else
8391 /* The float is at the end of a word, preceded
8392 by integer fields, so the arg advance flush
8393 just above has already set cum->words and
8394 everything is taken care of. */
8397 else
8398 cum->words += n_fpregs;
8400 else if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, 1))
8402 rs6000_darwin64_record_arg_advance_flush (cum, bitpos, 0);
8403 cum->vregno++;
8404 cum->words += 2;
8406 else if (cum->intoffset == -1)
8407 cum->intoffset = bitpos;
8411 /* Check for an item that needs to be considered specially under the darwin 64
8412 bit ABI. These are record types where the mode is BLK or the structure is
8413 8 bytes in size. */
8414 static int
8415 rs6000_darwin64_struct_check_p (enum machine_mode mode, const_tree type)
8417 return rs6000_darwin64_abi
8418 && ((mode == BLKmode
8419 && TREE_CODE (type) == RECORD_TYPE
8420 && int_size_in_bytes (type) > 0)
8421 || (type && TREE_CODE (type) == RECORD_TYPE
8422 && int_size_in_bytes (type) == 8)) ? 1 : 0;
8425 /* Update the data in CUM to advance over an argument
8426 of mode MODE and data type TYPE.
8427 (TYPE is null for libcalls where that information may not be available.)
8429 Note that for args passed by reference, function_arg will be called
8430 with MODE and TYPE set to that of the pointer to the arg, not the arg
8431 itself. */
8433 static void
8434 rs6000_function_arg_advance_1 (CUMULATIVE_ARGS *cum, enum machine_mode mode,
8435 const_tree type, bool named, int depth)
8437 /* Only tick off an argument if we're not recursing. */
8438 if (depth == 0)
8439 cum->nargs_prototype--;
8441 #ifdef HAVE_AS_GNU_ATTRIBUTE
8442 if (DEFAULT_ABI == ABI_V4
8443 && cum->escapes)
8445 if (SCALAR_FLOAT_MODE_P (mode))
8446 rs6000_passes_float = true;
8447 else if (named && (ALTIVEC_VECTOR_MODE (mode) || VSX_VECTOR_MODE (mode)))
8448 rs6000_passes_vector = true;
8449 else if (SPE_VECTOR_MODE (mode)
8450 && !cum->stdarg
8451 && cum->sysv_gregno <= GP_ARG_MAX_REG)
8452 rs6000_passes_vector = true;
8454 #endif
8456 if (TARGET_ALTIVEC_ABI
8457 && (ALTIVEC_VECTOR_MODE (mode)
8458 || VSX_VECTOR_MODE (mode)
8459 || (type && TREE_CODE (type) == VECTOR_TYPE
8460 && int_size_in_bytes (type) == 16)))
8462 bool stack = false;
8464 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
8466 cum->vregno++;
8467 if (!TARGET_ALTIVEC)
8468 error ("cannot pass argument in vector register because"
8469 " altivec instructions are disabled, use -maltivec"
8470 " to enable them");
8472 /* PowerPC64 Linux and AIX allocate GPRs for a vector argument
8473 even if it is going to be passed in a vector register.
8474 Darwin does the same for variable-argument functions. */
8475 if ((DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
8476 || (cum->stdarg && DEFAULT_ABI != ABI_V4))
8477 stack = true;
8479 else
8480 stack = true;
8482 if (stack)
8484 int align;
8486 /* Vector parameters must be 16-byte aligned. This places
8487 them at 2 mod 4 in terms of words in 32-bit mode, since
8488 the parameter save area starts at offset 24 from the
8489 stack. In 64-bit mode, they just have to start on an
8490 even word, since the parameter save area is 16-byte
8491 aligned. Space for GPRs is reserved even if the argument
8492 will be passed in memory. */
8493 if (TARGET_32BIT)
8494 align = (2 - cum->words) & 3;
8495 else
8496 align = cum->words & 1;
8497 cum->words += align + rs6000_arg_size (mode, type);
8499 if (TARGET_DEBUG_ARG)
8501 fprintf (stderr, "function_adv: words = %2d, align=%d, ",
8502 cum->words, align);
8503 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s\n",
8504 cum->nargs_prototype, cum->prototype,
8505 GET_MODE_NAME (mode));
8509 else if (TARGET_SPE_ABI && TARGET_SPE && SPE_VECTOR_MODE (mode)
8510 && !cum->stdarg
8511 && cum->sysv_gregno <= GP_ARG_MAX_REG)
8512 cum->sysv_gregno++;
8514 else if (TARGET_MACHO && rs6000_darwin64_struct_check_p (mode, type))
8516 int size = int_size_in_bytes (type);
8517 /* Variable sized types have size == -1 and are
8518 treated as if consisting entirely of ints.
8519 Pad to 16 byte boundary if needed. */
8520 if (TYPE_ALIGN (type) >= 2 * BITS_PER_WORD
8521 && (cum->words % 2) != 0)
8522 cum->words++;
8523 /* For varargs, we can just go up by the size of the struct. */
8524 if (!named)
8525 cum->words += (size + 7) / 8;
8526 else
8528 /* It is tempting to say int register count just goes up by
8529 sizeof(type)/8, but this is wrong in a case such as
8530 { int; double; int; } [powerpc alignment]. We have to
8531 grovel through the fields for these too. */
8532 cum->intoffset = 0;
8533 cum->floats_in_gpr = 0;
8534 rs6000_darwin64_record_arg_advance_recurse (cum, type, 0);
8535 rs6000_darwin64_record_arg_advance_flush (cum,
8536 size * BITS_PER_UNIT, 1);
8538 if (TARGET_DEBUG_ARG)
8540 fprintf (stderr, "function_adv: words = %2d, align=%d, size=%d",
8541 cum->words, TYPE_ALIGN (type), size);
8542 fprintf (stderr,
8543 "nargs = %4d, proto = %d, mode = %4s (darwin64 abi)\n",
8544 cum->nargs_prototype, cum->prototype,
8545 GET_MODE_NAME (mode));
8548 else if (DEFAULT_ABI == ABI_V4)
8550 if (TARGET_HARD_FLOAT && TARGET_FPRS
8551 && ((TARGET_SINGLE_FLOAT && mode == SFmode)
8552 || (TARGET_DOUBLE_FLOAT && mode == DFmode)
8553 || (mode == TFmode && !TARGET_IEEEQUAD)
8554 || mode == SDmode || mode == DDmode || mode == TDmode))
8556 /* _Decimal128 must use an even/odd register pair. This assumes
8557 that the register number is odd when fregno is odd. */
8558 if (mode == TDmode && (cum->fregno % 2) == 1)
8559 cum->fregno++;
8561 if (cum->fregno + (mode == TFmode || mode == TDmode ? 1 : 0)
8562 <= FP_ARG_V4_MAX_REG)
8563 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
8564 else
8566 cum->fregno = FP_ARG_V4_MAX_REG + 1;
8567 if (mode == DFmode || mode == TFmode
8568 || mode == DDmode || mode == TDmode)
8569 cum->words += cum->words & 1;
8570 cum->words += rs6000_arg_size (mode, type);
8573 else
8575 int n_words = rs6000_arg_size (mode, type);
8576 int gregno = cum->sysv_gregno;
8578 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
8579 (r7,r8) or (r9,r10). As does any other 2 word item such
8580 as complex int due to a historical mistake. */
8581 if (n_words == 2)
8582 gregno += (1 - gregno) & 1;
8584 /* Multi-reg args are not split between registers and stack. */
8585 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
8587 /* Long long and SPE vectors are aligned on the stack.
8588 So are other 2 word items such as complex int due to
8589 a historical mistake. */
8590 if (n_words == 2)
8591 cum->words += cum->words & 1;
8592 cum->words += n_words;
8595 /* Note: continuing to accumulate gregno past when we've started
8596 spilling to the stack indicates the fact that we've started
8597 spilling to the stack to expand_builtin_saveregs. */
8598 cum->sysv_gregno = gregno + n_words;
8601 if (TARGET_DEBUG_ARG)
8603 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
8604 cum->words, cum->fregno);
8605 fprintf (stderr, "gregno = %2d, nargs = %4d, proto = %d, ",
8606 cum->sysv_gregno, cum->nargs_prototype, cum->prototype);
8607 fprintf (stderr, "mode = %4s, named = %d\n",
8608 GET_MODE_NAME (mode), named);
8611 else
8613 int n_words = rs6000_arg_size (mode, type);
8614 int start_words = cum->words;
8615 int align_words = rs6000_parm_start (mode, type, start_words);
8617 cum->words = align_words + n_words;
8619 if (SCALAR_FLOAT_MODE_P (mode)
8620 && TARGET_HARD_FLOAT && TARGET_FPRS)
8622 /* _Decimal128 must be passed in an even/odd float register pair.
8623 This assumes that the register number is odd when fregno is
8624 odd. */
8625 if (mode == TDmode && (cum->fregno % 2) == 1)
8626 cum->fregno++;
8627 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
8630 if (TARGET_DEBUG_ARG)
8632 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
8633 cum->words, cum->fregno);
8634 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s, ",
8635 cum->nargs_prototype, cum->prototype, GET_MODE_NAME (mode));
8636 fprintf (stderr, "named = %d, align = %d, depth = %d\n",
8637 named, align_words - start_words, depth);
8642 static void
8643 rs6000_function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
8644 const_tree type, bool named)
8646 rs6000_function_arg_advance_1 (cum, mode, type, named, 0);
8649 static rtx
8650 spe_build_register_parallel (enum machine_mode mode, int gregno)
8652 rtx r1, r3, r5, r7;
8654 switch (mode)
8656 case DFmode:
8657 r1 = gen_rtx_REG (DImode, gregno);
8658 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
8659 return gen_rtx_PARALLEL (mode, gen_rtvec (1, r1));
8661 case DCmode:
8662 case TFmode:
8663 r1 = gen_rtx_REG (DImode, gregno);
8664 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
8665 r3 = gen_rtx_REG (DImode, gregno + 2);
8666 r3 = gen_rtx_EXPR_LIST (VOIDmode, r3, GEN_INT (8));
8667 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r3));
8669 case TCmode:
8670 r1 = gen_rtx_REG (DImode, gregno);
8671 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
8672 r3 = gen_rtx_REG (DImode, gregno + 2);
8673 r3 = gen_rtx_EXPR_LIST (VOIDmode, r3, GEN_INT (8));
8674 r5 = gen_rtx_REG (DImode, gregno + 4);
8675 r5 = gen_rtx_EXPR_LIST (VOIDmode, r5, GEN_INT (16));
8676 r7 = gen_rtx_REG (DImode, gregno + 6);
8677 r7 = gen_rtx_EXPR_LIST (VOIDmode, r7, GEN_INT (24));
8678 return gen_rtx_PARALLEL (mode, gen_rtvec (4, r1, r3, r5, r7));
8680 default:
8681 gcc_unreachable ();
8685 /* Determine where to put a SIMD argument on the SPE. */
8686 static rtx
8687 rs6000_spe_function_arg (const CUMULATIVE_ARGS *cum, enum machine_mode mode,
8688 const_tree type)
8690 int gregno = cum->sysv_gregno;
8692 /* On E500 v2, double arithmetic is done on the full 64-bit GPR, but
8693 are passed and returned in a pair of GPRs for ABI compatibility. */
8694 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
8695 || mode == DCmode || mode == TCmode))
8697 int n_words = rs6000_arg_size (mode, type);
8699 /* Doubles go in an odd/even register pair (r5/r6, etc). */
8700 if (mode == DFmode)
8701 gregno += (1 - gregno) & 1;
8703 /* Multi-reg args are not split between registers and stack. */
8704 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
8705 return NULL_RTX;
8707 return spe_build_register_parallel (mode, gregno);
8709 if (cum->stdarg)
8711 int n_words = rs6000_arg_size (mode, type);
8713 /* SPE vectors are put in odd registers. */
8714 if (n_words == 2 && (gregno & 1) == 0)
8715 gregno += 1;
8717 if (gregno + n_words - 1 <= GP_ARG_MAX_REG)
8719 rtx r1, r2;
8720 enum machine_mode m = SImode;
8722 r1 = gen_rtx_REG (m, gregno);
8723 r1 = gen_rtx_EXPR_LIST (m, r1, const0_rtx);
8724 r2 = gen_rtx_REG (m, gregno + 1);
8725 r2 = gen_rtx_EXPR_LIST (m, r2, GEN_INT (4));
8726 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
8728 else
8729 return NULL_RTX;
8731 else
8733 if (gregno <= GP_ARG_MAX_REG)
8734 return gen_rtx_REG (mode, gregno);
8735 else
8736 return NULL_RTX;
8740 /* A subroutine of rs6000_darwin64_record_arg. Assign the bits of the
8741 structure between cum->intoffset and bitpos to integer registers. */
8743 static void
8744 rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS *cum,
8745 HOST_WIDE_INT bitpos, rtx rvec[], int *k)
8747 enum machine_mode mode;
8748 unsigned int regno;
8749 unsigned int startbit, endbit;
8750 int this_regno, intregs, intoffset;
8751 rtx reg;
8753 if (cum->intoffset == -1)
8754 return;
8756 intoffset = cum->intoffset;
8757 cum->intoffset = -1;
8759 /* If this is the trailing part of a word, try to only load that
8760 much into the register. Otherwise load the whole register. Note
8761 that in the latter case we may pick up unwanted bits. It's not a
8762 problem at the moment but may wish to revisit. */
8764 if (intoffset % BITS_PER_WORD != 0)
8766 mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD,
8767 MODE_INT, 0);
8768 if (mode == BLKmode)
8770 /* We couldn't find an appropriate mode, which happens,
8771 e.g., in packed structs when there are 3 bytes to load.
8772 Back intoffset back to the beginning of the word in this
8773 case. */
8774 intoffset = intoffset & -BITS_PER_WORD;
8775 mode = word_mode;
8778 else
8779 mode = word_mode;
8781 startbit = intoffset & -BITS_PER_WORD;
8782 endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD;
8783 intregs = (endbit - startbit) / BITS_PER_WORD;
8784 this_regno = cum->words + intoffset / BITS_PER_WORD;
8786 if (intregs > 0 && intregs > GP_ARG_NUM_REG - this_regno)
8787 cum->use_stack = 1;
8789 intregs = MIN (intregs, GP_ARG_NUM_REG - this_regno);
8790 if (intregs <= 0)
8791 return;
8793 intoffset /= BITS_PER_UNIT;
8796 regno = GP_ARG_MIN_REG + this_regno;
8797 reg = gen_rtx_REG (mode, regno);
8798 rvec[(*k)++] =
8799 gen_rtx_EXPR_LIST (VOIDmode, reg, GEN_INT (intoffset));
8801 this_regno += 1;
8802 intoffset = (intoffset | (UNITS_PER_WORD-1)) + 1;
8803 mode = word_mode;
8804 intregs -= 1;
8806 while (intregs > 0);
8809 /* Recursive workhorse for the following. */
8811 static void
8812 rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *cum, const_tree type,
8813 HOST_WIDE_INT startbitpos, rtx rvec[],
8814 int *k)
8816 tree f;
8818 for (f = TYPE_FIELDS (type); f ; f = DECL_CHAIN (f))
8819 if (TREE_CODE (f) == FIELD_DECL)
8821 HOST_WIDE_INT bitpos = startbitpos;
8822 tree ftype = TREE_TYPE (f);
8823 enum machine_mode mode;
8824 if (ftype == error_mark_node)
8825 continue;
8826 mode = TYPE_MODE (ftype);
8828 if (DECL_SIZE (f) != 0
8829 && host_integerp (bit_position (f), 1))
8830 bitpos += int_bit_position (f);
8832 /* ??? FIXME: else assume zero offset. */
8834 if (TREE_CODE (ftype) == RECORD_TYPE)
8835 rs6000_darwin64_record_arg_recurse (cum, ftype, bitpos, rvec, k);
8836 else if (cum->named && USE_FP_FOR_ARG_P (cum, mode, ftype))
8838 unsigned n_fpreg = (GET_MODE_SIZE (mode) + 7) >> 3;
8839 #if 0
8840 switch (mode)
8842 case SCmode: mode = SFmode; break;
8843 case DCmode: mode = DFmode; break;
8844 case TCmode: mode = TFmode; break;
8845 default: break;
8847 #endif
8848 rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
8849 if (cum->fregno + n_fpreg > FP_ARG_MAX_REG + 1)
8851 gcc_assert (cum->fregno == FP_ARG_MAX_REG
8852 && (mode == TFmode || mode == TDmode));
8853 /* Long double or _Decimal128 split over regs and memory. */
8854 mode = DECIMAL_FLOAT_MODE_P (mode) ? DDmode : DFmode;
8855 cum->use_stack=1;
8857 rvec[(*k)++]
8858 = gen_rtx_EXPR_LIST (VOIDmode,
8859 gen_rtx_REG (mode, cum->fregno++),
8860 GEN_INT (bitpos / BITS_PER_UNIT));
8861 if (mode == TFmode || mode == TDmode)
8862 cum->fregno++;
8864 else if (cum->named && USE_ALTIVEC_FOR_ARG_P (cum, mode, ftype, 1))
8866 rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
8867 rvec[(*k)++]
8868 = gen_rtx_EXPR_LIST (VOIDmode,
8869 gen_rtx_REG (mode, cum->vregno++),
8870 GEN_INT (bitpos / BITS_PER_UNIT));
8872 else if (cum->intoffset == -1)
8873 cum->intoffset = bitpos;
8877 /* For the darwin64 ABI, we want to construct a PARALLEL consisting of
8878 the register(s) to be used for each field and subfield of a struct
8879 being passed by value, along with the offset of where the
8880 register's value may be found in the block. FP fields go in FP
8881 register, vector fields go in vector registers, and everything
8882 else goes in int registers, packed as in memory.
8884 This code is also used for function return values. RETVAL indicates
8885 whether this is the case.
8887 Much of this is taken from the SPARC V9 port, which has a similar
8888 calling convention. */
8890 static rtx
8891 rs6000_darwin64_record_arg (CUMULATIVE_ARGS *orig_cum, const_tree type,
8892 bool named, bool retval)
8894 rtx rvec[FIRST_PSEUDO_REGISTER];
8895 int k = 1, kbase = 1;
8896 HOST_WIDE_INT typesize = int_size_in_bytes (type);
8897 /* This is a copy; modifications are not visible to our caller. */
8898 CUMULATIVE_ARGS copy_cum = *orig_cum;
8899 CUMULATIVE_ARGS *cum = &copy_cum;
8901 /* Pad to 16 byte boundary if needed. */
8902 if (!retval && TYPE_ALIGN (type) >= 2 * BITS_PER_WORD
8903 && (cum->words % 2) != 0)
8904 cum->words++;
8906 cum->intoffset = 0;
8907 cum->use_stack = 0;
8908 cum->named = named;
8910 /* Put entries into rvec[] for individual FP and vector fields, and
8911 for the chunks of memory that go in int regs. Note we start at
8912 element 1; 0 is reserved for an indication of using memory, and
8913 may or may not be filled in below. */
8914 rs6000_darwin64_record_arg_recurse (cum, type, /* startbit pos= */ 0, rvec, &k);
8915 rs6000_darwin64_record_arg_flush (cum, typesize * BITS_PER_UNIT, rvec, &k);
8917 /* If any part of the struct went on the stack put all of it there.
8918 This hack is because the generic code for
8919 FUNCTION_ARG_PARTIAL_NREGS cannot handle cases where the register
8920 parts of the struct are not at the beginning. */
8921 if (cum->use_stack)
8923 if (retval)
8924 return NULL_RTX; /* doesn't go in registers at all */
8925 kbase = 0;
8926 rvec[0] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
8928 if (k > 1 || cum->use_stack)
8929 return gen_rtx_PARALLEL (BLKmode, gen_rtvec_v (k - kbase, &rvec[kbase]));
8930 else
8931 return NULL_RTX;
8934 /* Determine where to place an argument in 64-bit mode with 32-bit ABI. */
8936 static rtx
8937 rs6000_mixed_function_arg (enum machine_mode mode, const_tree type,
8938 int align_words)
8940 int n_units;
8941 int i, k;
8942 rtx rvec[GP_ARG_NUM_REG + 1];
8944 if (align_words >= GP_ARG_NUM_REG)
8945 return NULL_RTX;
8947 n_units = rs6000_arg_size (mode, type);
8949 /* Optimize the simple case where the arg fits in one gpr, except in
8950 the case of BLKmode due to assign_parms assuming that registers are
8951 BITS_PER_WORD wide. */
8952 if (n_units == 0
8953 || (n_units == 1 && mode != BLKmode))
8954 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
8956 k = 0;
8957 if (align_words + n_units > GP_ARG_NUM_REG)
8958 /* Not all of the arg fits in gprs. Say that it goes in memory too,
8959 using a magic NULL_RTX component.
8960 This is not strictly correct. Only some of the arg belongs in
8961 memory, not all of it. However, the normal scheme using
8962 function_arg_partial_nregs can result in unusual subregs, eg.
8963 (subreg:SI (reg:DF) 4), which are not handled well. The code to
8964 store the whole arg to memory is often more efficient than code
8965 to store pieces, and we know that space is available in the right
8966 place for the whole arg. */
8967 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
8969 i = 0;
8972 rtx r = gen_rtx_REG (SImode, GP_ARG_MIN_REG + align_words);
8973 rtx off = GEN_INT (i++ * 4);
8974 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
8976 while (++align_words < GP_ARG_NUM_REG && --n_units != 0);
8978 return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
8981 /* Determine where to put an argument to a function.
8982 Value is zero to push the argument on the stack,
8983 or a hard register in which to store the argument.
8985 MODE is the argument's machine mode.
8986 TYPE is the data type of the argument (as a tree).
8987 This is null for libcalls where that information may
8988 not be available.
8989 CUM is a variable of type CUMULATIVE_ARGS which gives info about
8990 the preceding args and about the function being called. It is
8991 not modified in this routine.
8992 NAMED is nonzero if this argument is a named parameter
8993 (otherwise it is an extra parameter matching an ellipsis).
8995 On RS/6000 the first eight words of non-FP are normally in registers
8996 and the rest are pushed. Under AIX, the first 13 FP args are in registers.
8997 Under V.4, the first 8 FP args are in registers.
8999 If this is floating-point and no prototype is specified, we use
9000 both an FP and integer register (or possibly FP reg and stack). Library
9001 functions (when CALL_LIBCALL is set) always have the proper types for args,
9002 so we can pass the FP value just in one register. emit_library_function
9003 doesn't support PARALLEL anyway.
9005 Note that for args passed by reference, function_arg will be called
9006 with MODE and TYPE set to that of the pointer to the arg, not the arg
9007 itself. */
9009 static rtx
9010 rs6000_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
9011 const_tree type, bool named)
9013 enum rs6000_abi abi = DEFAULT_ABI;
9015 /* Return a marker to indicate whether CR1 needs to set or clear the
9016 bit that V.4 uses to say fp args were passed in registers.
9017 Assume that we don't need the marker for software floating point,
9018 or compiler generated library calls. */
9019 if (mode == VOIDmode)
9021 if (abi == ABI_V4
9022 && (cum->call_cookie & CALL_LIBCALL) == 0
9023 && (cum->stdarg
9024 || (cum->nargs_prototype < 0
9025 && (cum->prototype || TARGET_NO_PROTOTYPE))))
9027 /* For the SPE, we need to crxor CR6 always. */
9028 if (TARGET_SPE_ABI)
9029 return GEN_INT (cum->call_cookie | CALL_V4_SET_FP_ARGS);
9030 else if (TARGET_HARD_FLOAT && TARGET_FPRS)
9031 return GEN_INT (cum->call_cookie
9032 | ((cum->fregno == FP_ARG_MIN_REG)
9033 ? CALL_V4_SET_FP_ARGS
9034 : CALL_V4_CLEAR_FP_ARGS));
9037 return GEN_INT (cum->call_cookie);
9040 if (TARGET_MACHO && rs6000_darwin64_struct_check_p (mode, type))
9042 rtx rslt = rs6000_darwin64_record_arg (cum, type, named, /*retval= */false);
9043 if (rslt != NULL_RTX)
9044 return rslt;
9045 /* Else fall through to usual handling. */
9048 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
9049 if (TARGET_64BIT && ! cum->prototype)
9051 /* Vector parameters get passed in vector register
9052 and also in GPRs or memory, in absence of prototype. */
9053 int align_words;
9054 rtx slot;
9055 align_words = (cum->words + 1) & ~1;
9057 if (align_words >= GP_ARG_NUM_REG)
9059 slot = NULL_RTX;
9061 else
9063 slot = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
9065 return gen_rtx_PARALLEL (mode,
9066 gen_rtvec (2,
9067 gen_rtx_EXPR_LIST (VOIDmode,
9068 slot, const0_rtx),
9069 gen_rtx_EXPR_LIST (VOIDmode,
9070 gen_rtx_REG (mode, cum->vregno),
9071 const0_rtx)));
9073 else
9074 return gen_rtx_REG (mode, cum->vregno);
9075 else if (TARGET_ALTIVEC_ABI
9076 && (ALTIVEC_VECTOR_MODE (mode)
9077 || VSX_VECTOR_MODE (mode)
9078 || (type && TREE_CODE (type) == VECTOR_TYPE
9079 && int_size_in_bytes (type) == 16)))
9081 if (named || abi == ABI_V4)
9082 return NULL_RTX;
9083 else
9085 /* Vector parameters to varargs functions under AIX or Darwin
9086 get passed in memory and possibly also in GPRs. */
9087 int align, align_words, n_words;
9088 enum machine_mode part_mode;
9090 /* Vector parameters must be 16-byte aligned. This places them at
9091 2 mod 4 in terms of words in 32-bit mode, since the parameter
9092 save area starts at offset 24 from the stack. In 64-bit mode,
9093 they just have to start on an even word, since the parameter
9094 save area is 16-byte aligned. */
9095 if (TARGET_32BIT)
9096 align = (2 - cum->words) & 3;
9097 else
9098 align = cum->words & 1;
9099 align_words = cum->words + align;
9101 /* Out of registers? Memory, then. */
9102 if (align_words >= GP_ARG_NUM_REG)
9103 return NULL_RTX;
9105 if (TARGET_32BIT && TARGET_POWERPC64)
9106 return rs6000_mixed_function_arg (mode, type, align_words);
9108 /* The vector value goes in GPRs. Only the part of the
9109 value in GPRs is reported here. */
9110 part_mode = mode;
9111 n_words = rs6000_arg_size (mode, type);
9112 if (align_words + n_words > GP_ARG_NUM_REG)
9113 /* Fortunately, there are only two possibilities, the value
9114 is either wholly in GPRs or half in GPRs and half not. */
9115 part_mode = DImode;
9117 return gen_rtx_REG (part_mode, GP_ARG_MIN_REG + align_words);
9120 else if (TARGET_SPE_ABI && TARGET_SPE
9121 && (SPE_VECTOR_MODE (mode)
9122 || (TARGET_E500_DOUBLE && (mode == DFmode
9123 || mode == DCmode
9124 || mode == TFmode
9125 || mode == TCmode))))
9126 return rs6000_spe_function_arg (cum, mode, type);
9128 else if (abi == ABI_V4)
9130 if (TARGET_HARD_FLOAT && TARGET_FPRS
9131 && ((TARGET_SINGLE_FLOAT && mode == SFmode)
9132 || (TARGET_DOUBLE_FLOAT && mode == DFmode)
9133 || (mode == TFmode && !TARGET_IEEEQUAD)
9134 || mode == SDmode || mode == DDmode || mode == TDmode))
9136 /* _Decimal128 must use an even/odd register pair. This assumes
9137 that the register number is odd when fregno is odd. */
9138 if (mode == TDmode && (cum->fregno % 2) == 1)
9139 cum->fregno++;
9141 if (cum->fregno + (mode == TFmode || mode == TDmode ? 1 : 0)
9142 <= FP_ARG_V4_MAX_REG)
9143 return gen_rtx_REG (mode, cum->fregno);
9144 else
9145 return NULL_RTX;
9147 else
9149 int n_words = rs6000_arg_size (mode, type);
9150 int gregno = cum->sysv_gregno;
9152 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
9153 (r7,r8) or (r9,r10). As does any other 2 word item such
9154 as complex int due to a historical mistake. */
9155 if (n_words == 2)
9156 gregno += (1 - gregno) & 1;
9158 /* Multi-reg args are not split between registers and stack. */
9159 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
9160 return NULL_RTX;
9162 if (TARGET_32BIT && TARGET_POWERPC64)
9163 return rs6000_mixed_function_arg (mode, type,
9164 gregno - GP_ARG_MIN_REG);
9165 return gen_rtx_REG (mode, gregno);
9168 else
9170 int align_words = rs6000_parm_start (mode, type, cum->words);
9172 /* _Decimal128 must be passed in an even/odd float register pair.
9173 This assumes that the register number is odd when fregno is odd. */
9174 if (mode == TDmode && (cum->fregno % 2) == 1)
9175 cum->fregno++;
9177 if (USE_FP_FOR_ARG_P (cum, mode, type))
9179 rtx rvec[GP_ARG_NUM_REG + 1];
9180 rtx r;
9181 int k;
9182 bool needs_psave;
9183 enum machine_mode fmode = mode;
9184 unsigned long n_fpreg = (GET_MODE_SIZE (mode) + 7) >> 3;
9186 if (cum->fregno + n_fpreg > FP_ARG_MAX_REG + 1)
9188 /* Currently, we only ever need one reg here because complex
9189 doubles are split. */
9190 gcc_assert (cum->fregno == FP_ARG_MAX_REG
9191 && (fmode == TFmode || fmode == TDmode));
9193 /* Long double or _Decimal128 split over regs and memory. */
9194 fmode = DECIMAL_FLOAT_MODE_P (fmode) ? DDmode : DFmode;
9197 /* Do we also need to pass this arg in the parameter save
9198 area? */
9199 needs_psave = (type
9200 && (cum->nargs_prototype <= 0
9201 || (DEFAULT_ABI == ABI_AIX
9202 && TARGET_XL_COMPAT
9203 && align_words >= GP_ARG_NUM_REG)));
9205 if (!needs_psave && mode == fmode)
9206 return gen_rtx_REG (fmode, cum->fregno);
9208 k = 0;
9209 if (needs_psave)
9211 /* Describe the part that goes in gprs or the stack.
9212 This piece must come first, before the fprs. */
9213 if (align_words < GP_ARG_NUM_REG)
9215 unsigned long n_words = rs6000_arg_size (mode, type);
9217 if (align_words + n_words > GP_ARG_NUM_REG
9218 || (TARGET_32BIT && TARGET_POWERPC64))
9220 /* If this is partially on the stack, then we only
9221 include the portion actually in registers here. */
9222 enum machine_mode rmode = TARGET_32BIT ? SImode : DImode;
9223 rtx off;
9224 int i = 0;
9225 if (align_words + n_words > GP_ARG_NUM_REG)
9226 /* Not all of the arg fits in gprs. Say that it
9227 goes in memory too, using a magic NULL_RTX
9228 component. Also see comment in
9229 rs6000_mixed_function_arg for why the normal
9230 function_arg_partial_nregs scheme doesn't work
9231 in this case. */
9232 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX,
9233 const0_rtx);
9236 r = gen_rtx_REG (rmode,
9237 GP_ARG_MIN_REG + align_words);
9238 off = GEN_INT (i++ * GET_MODE_SIZE (rmode));
9239 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
9241 while (++align_words < GP_ARG_NUM_REG && --n_words != 0);
9243 else
9245 /* The whole arg fits in gprs. */
9246 r = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
9247 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
9250 else
9251 /* It's entirely in memory. */
9252 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
9255 /* Describe where this piece goes in the fprs. */
9256 r = gen_rtx_REG (fmode, cum->fregno);
9257 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
9259 return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
9261 else if (align_words < GP_ARG_NUM_REG)
9263 if (TARGET_32BIT && TARGET_POWERPC64)
9264 return rs6000_mixed_function_arg (mode, type, align_words);
9266 if (mode == BLKmode)
9267 mode = Pmode;
9269 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
9271 else
9272 return NULL_RTX;
9276 /* For an arg passed partly in registers and partly in memory, this is
9277 the number of bytes passed in registers. For args passed entirely in
9278 registers or entirely in memory, zero. When an arg is described by a
9279 PARALLEL, perhaps using more than one register type, this function
9280 returns the number of bytes used by the first element of the PARALLEL. */
9282 static int
9283 rs6000_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode,
9284 tree type, bool named)
9286 int ret = 0;
9287 int align_words;
9289 if (DEFAULT_ABI == ABI_V4)
9290 return 0;
9292 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named)
9293 && cum->nargs_prototype >= 0)
9294 return 0;
9296 /* In this complicated case we just disable the partial_nregs code. */
9297 if (TARGET_MACHO && rs6000_darwin64_struct_check_p (mode, type))
9298 return 0;
9300 align_words = rs6000_parm_start (mode, type, cum->words);
9302 if (USE_FP_FOR_ARG_P (cum, mode, type))
9304 /* If we are passing this arg in the fixed parameter save area
9305 (gprs or memory) as well as fprs, then this function should
9306 return the number of partial bytes passed in the parameter
9307 save area rather than partial bytes passed in fprs. */
9308 if (type
9309 && (cum->nargs_prototype <= 0
9310 || (DEFAULT_ABI == ABI_AIX
9311 && TARGET_XL_COMPAT
9312 && align_words >= GP_ARG_NUM_REG)))
9313 return 0;
9314 else if (cum->fregno + ((GET_MODE_SIZE (mode) + 7) >> 3)
9315 > FP_ARG_MAX_REG + 1)
9316 ret = (FP_ARG_MAX_REG + 1 - cum->fregno) * 8;
9317 else if (cum->nargs_prototype >= 0)
9318 return 0;
9321 if (align_words < GP_ARG_NUM_REG
9322 && GP_ARG_NUM_REG < align_words + rs6000_arg_size (mode, type))
9323 ret = (GP_ARG_NUM_REG - align_words) * (TARGET_32BIT ? 4 : 8);
9325 if (ret != 0 && TARGET_DEBUG_ARG)
9326 fprintf (stderr, "rs6000_arg_partial_bytes: %d\n", ret);
9328 return ret;
9331 /* A C expression that indicates when an argument must be passed by
9332 reference. If nonzero for an argument, a copy of that argument is
9333 made in memory and a pointer to the argument is passed instead of
9334 the argument itself. The pointer is passed in whatever way is
9335 appropriate for passing a pointer to that type.
9337 Under V.4, aggregates and long double are passed by reference.
9339 As an extension to all 32-bit ABIs, AltiVec vectors are passed by
9340 reference unless the AltiVec vector extension ABI is in force.
9342 As an extension to all ABIs, variable sized types are passed by
9343 reference. */
9345 static bool
9346 rs6000_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
9347 enum machine_mode mode, const_tree type,
9348 bool named ATTRIBUTE_UNUSED)
9350 if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && mode == TFmode)
9352 if (TARGET_DEBUG_ARG)
9353 fprintf (stderr, "function_arg_pass_by_reference: V4 long double\n");
9354 return 1;
9357 if (!type)
9358 return 0;
9360 if (DEFAULT_ABI == ABI_V4 && AGGREGATE_TYPE_P (type))
9362 if (TARGET_DEBUG_ARG)
9363 fprintf (stderr, "function_arg_pass_by_reference: V4 aggregate\n");
9364 return 1;
9367 if (int_size_in_bytes (type) < 0)
9369 if (TARGET_DEBUG_ARG)
9370 fprintf (stderr, "function_arg_pass_by_reference: variable size\n");
9371 return 1;
9374 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
9375 modes only exist for GCC vector types if -maltivec. */
9376 if (TARGET_32BIT && !TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
9378 if (TARGET_DEBUG_ARG)
9379 fprintf (stderr, "function_arg_pass_by_reference: AltiVec\n");
9380 return 1;
9383 /* Pass synthetic vectors in memory. */
9384 if (TREE_CODE (type) == VECTOR_TYPE
9385 && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
9387 static bool warned_for_pass_big_vectors = false;
9388 if (TARGET_DEBUG_ARG)
9389 fprintf (stderr, "function_arg_pass_by_reference: synthetic vector\n");
9390 if (!warned_for_pass_big_vectors)
9392 warning (0, "GCC vector passed by reference: "
9393 "non-standard ABI extension with no compatibility guarantee");
9394 warned_for_pass_big_vectors = true;
9396 return 1;
9399 return 0;
9402 static void
9403 rs6000_move_block_from_reg (int regno, rtx x, int nregs)
9405 int i;
9406 enum machine_mode reg_mode = TARGET_32BIT ? SImode : DImode;
9408 if (nregs == 0)
9409 return;
9411 for (i = 0; i < nregs; i++)
9413 rtx tem = adjust_address_nv (x, reg_mode, i * GET_MODE_SIZE (reg_mode));
9414 if (reload_completed)
9416 if (! strict_memory_address_p (reg_mode, XEXP (tem, 0)))
9417 tem = NULL_RTX;
9418 else
9419 tem = simplify_gen_subreg (reg_mode, x, BLKmode,
9420 i * GET_MODE_SIZE (reg_mode));
9422 else
9423 tem = replace_equiv_address (tem, XEXP (tem, 0));
9425 gcc_assert (tem);
9427 emit_move_insn (tem, gen_rtx_REG (reg_mode, regno + i));
9431 /* Perform any needed actions needed for a function that is receiving a
9432 variable number of arguments.
9434 CUM is as above.
9436 MODE and TYPE are the mode and type of the current parameter.
9438 PRETEND_SIZE is a variable that should be set to the amount of stack
9439 that must be pushed by the prolog to pretend that our caller pushed
9442 Normally, this macro will push all remaining incoming registers on the
9443 stack and set PRETEND_SIZE to the length of the registers pushed. */
9445 static void
9446 setup_incoming_varargs (CUMULATIVE_ARGS *cum, enum machine_mode mode,
9447 tree type, int *pretend_size ATTRIBUTE_UNUSED,
9448 int no_rtl)
9450 CUMULATIVE_ARGS next_cum;
9451 int reg_size = TARGET_32BIT ? 4 : 8;
9452 rtx save_area = NULL_RTX, mem;
9453 int first_reg_offset;
9454 alias_set_type set;
9456 /* Skip the last named argument. */
9457 next_cum = *cum;
9458 rs6000_function_arg_advance_1 (&next_cum, mode, type, true, 0);
9460 if (DEFAULT_ABI == ABI_V4)
9462 first_reg_offset = next_cum.sysv_gregno - GP_ARG_MIN_REG;
9464 if (! no_rtl)
9466 int gpr_reg_num = 0, gpr_size = 0, fpr_size = 0;
9467 HOST_WIDE_INT offset = 0;
9469 /* Try to optimize the size of the varargs save area.
9470 The ABI requires that ap.reg_save_area is doubleword
9471 aligned, but we don't need to allocate space for all
9472 the bytes, only those to which we actually will save
9473 anything. */
9474 if (cfun->va_list_gpr_size && first_reg_offset < GP_ARG_NUM_REG)
9475 gpr_reg_num = GP_ARG_NUM_REG - first_reg_offset;
9476 if (TARGET_HARD_FLOAT && TARGET_FPRS
9477 && next_cum.fregno <= FP_ARG_V4_MAX_REG
9478 && cfun->va_list_fpr_size)
9480 if (gpr_reg_num)
9481 fpr_size = (next_cum.fregno - FP_ARG_MIN_REG)
9482 * UNITS_PER_FP_WORD;
9483 if (cfun->va_list_fpr_size
9484 < FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
9485 fpr_size += cfun->va_list_fpr_size * UNITS_PER_FP_WORD;
9486 else
9487 fpr_size += (FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
9488 * UNITS_PER_FP_WORD;
9490 if (gpr_reg_num)
9492 offset = -((first_reg_offset * reg_size) & ~7);
9493 if (!fpr_size && gpr_reg_num > cfun->va_list_gpr_size)
9495 gpr_reg_num = cfun->va_list_gpr_size;
9496 if (reg_size == 4 && (first_reg_offset & 1))
9497 gpr_reg_num++;
9499 gpr_size = (gpr_reg_num * reg_size + 7) & ~7;
9501 else if (fpr_size)
9502 offset = - (int) (next_cum.fregno - FP_ARG_MIN_REG)
9503 * UNITS_PER_FP_WORD
9504 - (int) (GP_ARG_NUM_REG * reg_size);
9506 if (gpr_size + fpr_size)
9508 rtx reg_save_area
9509 = assign_stack_local (BLKmode, gpr_size + fpr_size, 64);
9510 gcc_assert (GET_CODE (reg_save_area) == MEM);
9511 reg_save_area = XEXP (reg_save_area, 0);
9512 if (GET_CODE (reg_save_area) == PLUS)
9514 gcc_assert (XEXP (reg_save_area, 0)
9515 == virtual_stack_vars_rtx);
9516 gcc_assert (GET_CODE (XEXP (reg_save_area, 1)) == CONST_INT);
9517 offset += INTVAL (XEXP (reg_save_area, 1));
9519 else
9520 gcc_assert (reg_save_area == virtual_stack_vars_rtx);
9523 cfun->machine->varargs_save_offset = offset;
9524 save_area = plus_constant (virtual_stack_vars_rtx, offset);
9527 else
9529 first_reg_offset = next_cum.words;
9530 save_area = virtual_incoming_args_rtx;
9532 if (targetm.calls.must_pass_in_stack (mode, type))
9533 first_reg_offset += rs6000_arg_size (TYPE_MODE (type), type);
9536 set = get_varargs_alias_set ();
9537 if (! no_rtl && first_reg_offset < GP_ARG_NUM_REG
9538 && cfun->va_list_gpr_size)
9540 int nregs = GP_ARG_NUM_REG - first_reg_offset;
9542 if (va_list_gpr_counter_field)
9544 /* V4 va_list_gpr_size counts number of registers needed. */
9545 if (nregs > cfun->va_list_gpr_size)
9546 nregs = cfun->va_list_gpr_size;
9548 else
9550 /* char * va_list instead counts number of bytes needed. */
9551 if (nregs > cfun->va_list_gpr_size / reg_size)
9552 nregs = cfun->va_list_gpr_size / reg_size;
9555 mem = gen_rtx_MEM (BLKmode,
9556 plus_constant (save_area,
9557 first_reg_offset * reg_size));
9558 MEM_NOTRAP_P (mem) = 1;
9559 set_mem_alias_set (mem, set);
9560 set_mem_align (mem, BITS_PER_WORD);
9562 rs6000_move_block_from_reg (GP_ARG_MIN_REG + first_reg_offset, mem,
9563 nregs);
9566 /* Save FP registers if needed. */
9567 if (DEFAULT_ABI == ABI_V4
9568 && TARGET_HARD_FLOAT && TARGET_FPRS
9569 && ! no_rtl
9570 && next_cum.fregno <= FP_ARG_V4_MAX_REG
9571 && cfun->va_list_fpr_size)
9573 int fregno = next_cum.fregno, nregs;
9574 rtx cr1 = gen_rtx_REG (CCmode, CR1_REGNO);
9575 rtx lab = gen_label_rtx ();
9576 int off = (GP_ARG_NUM_REG * reg_size) + ((fregno - FP_ARG_MIN_REG)
9577 * UNITS_PER_FP_WORD);
9579 emit_jump_insn
9580 (gen_rtx_SET (VOIDmode,
9581 pc_rtx,
9582 gen_rtx_IF_THEN_ELSE (VOIDmode,
9583 gen_rtx_NE (VOIDmode, cr1,
9584 const0_rtx),
9585 gen_rtx_LABEL_REF (VOIDmode, lab),
9586 pc_rtx)));
9588 for (nregs = 0;
9589 fregno <= FP_ARG_V4_MAX_REG && nregs < cfun->va_list_fpr_size;
9590 fregno++, off += UNITS_PER_FP_WORD, nregs++)
9592 mem = gen_rtx_MEM ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
9593 ? DFmode : SFmode,
9594 plus_constant (save_area, off));
9595 MEM_NOTRAP_P (mem) = 1;
9596 set_mem_alias_set (mem, set);
9597 set_mem_align (mem, GET_MODE_ALIGNMENT (
9598 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
9599 ? DFmode : SFmode));
9600 emit_move_insn (mem, gen_rtx_REG (
9601 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
9602 ? DFmode : SFmode, fregno));
9605 emit_label (lab);
9609 /* Create the va_list data type. */
9611 static tree
9612 rs6000_build_builtin_va_list (void)
9614 tree f_gpr, f_fpr, f_res, f_ovf, f_sav, record, type_decl;
9616 /* For AIX, prefer 'char *' because that's what the system
9617 header files like. */
9618 if (DEFAULT_ABI != ABI_V4)
9619 return build_pointer_type (char_type_node);
9621 record = (*lang_hooks.types.make_type) (RECORD_TYPE);
9622 type_decl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
9623 get_identifier ("__va_list_tag"), record);
9625 f_gpr = build_decl (BUILTINS_LOCATION, FIELD_DECL, get_identifier ("gpr"),
9626 unsigned_char_type_node);
9627 f_fpr = build_decl (BUILTINS_LOCATION, FIELD_DECL, get_identifier ("fpr"),
9628 unsigned_char_type_node);
9629 /* Give the two bytes of padding a name, so that -Wpadded won't warn on
9630 every user file. */
9631 f_res = build_decl (BUILTINS_LOCATION, FIELD_DECL,
9632 get_identifier ("reserved"), short_unsigned_type_node);
9633 f_ovf = build_decl (BUILTINS_LOCATION, FIELD_DECL,
9634 get_identifier ("overflow_arg_area"),
9635 ptr_type_node);
9636 f_sav = build_decl (BUILTINS_LOCATION, FIELD_DECL,
9637 get_identifier ("reg_save_area"),
9638 ptr_type_node);
9640 va_list_gpr_counter_field = f_gpr;
9641 va_list_fpr_counter_field = f_fpr;
9643 DECL_FIELD_CONTEXT (f_gpr) = record;
9644 DECL_FIELD_CONTEXT (f_fpr) = record;
9645 DECL_FIELD_CONTEXT (f_res) = record;
9646 DECL_FIELD_CONTEXT (f_ovf) = record;
9647 DECL_FIELD_CONTEXT (f_sav) = record;
9649 TYPE_STUB_DECL (record) = type_decl;
9650 TYPE_NAME (record) = type_decl;
9651 TYPE_FIELDS (record) = f_gpr;
9652 DECL_CHAIN (f_gpr) = f_fpr;
9653 DECL_CHAIN (f_fpr) = f_res;
9654 DECL_CHAIN (f_res) = f_ovf;
9655 DECL_CHAIN (f_ovf) = f_sav;
9657 layout_type (record);
9659 /* The correct type is an array type of one element. */
9660 return build_array_type (record, build_index_type (size_zero_node));
9663 /* Implement va_start. */
9665 static void
9666 rs6000_va_start (tree valist, rtx nextarg)
9668 HOST_WIDE_INT words, n_gpr, n_fpr;
9669 tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
9670 tree gpr, fpr, ovf, sav, t;
9672 /* Only SVR4 needs something special. */
9673 if (DEFAULT_ABI != ABI_V4)
9675 std_expand_builtin_va_start (valist, nextarg);
9676 return;
9679 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
9680 f_fpr = DECL_CHAIN (f_gpr);
9681 f_res = DECL_CHAIN (f_fpr);
9682 f_ovf = DECL_CHAIN (f_res);
9683 f_sav = DECL_CHAIN (f_ovf);
9685 valist = build_simple_mem_ref (valist);
9686 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
9687 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), unshare_expr (valist),
9688 f_fpr, NULL_TREE);
9689 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), unshare_expr (valist),
9690 f_ovf, NULL_TREE);
9691 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), unshare_expr (valist),
9692 f_sav, NULL_TREE);
9694 /* Count number of gp and fp argument registers used. */
9695 words = crtl->args.info.words;
9696 n_gpr = MIN (crtl->args.info.sysv_gregno - GP_ARG_MIN_REG,
9697 GP_ARG_NUM_REG);
9698 n_fpr = MIN (crtl->args.info.fregno - FP_ARG_MIN_REG,
9699 FP_ARG_NUM_REG);
9701 if (TARGET_DEBUG_ARG)
9702 fprintf (stderr, "va_start: words = "HOST_WIDE_INT_PRINT_DEC", n_gpr = "
9703 HOST_WIDE_INT_PRINT_DEC", n_fpr = "HOST_WIDE_INT_PRINT_DEC"\n",
9704 words, n_gpr, n_fpr);
9706 if (cfun->va_list_gpr_size)
9708 t = build2 (MODIFY_EXPR, TREE_TYPE (gpr), gpr,
9709 build_int_cst (NULL_TREE, n_gpr));
9710 TREE_SIDE_EFFECTS (t) = 1;
9711 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
9714 if (cfun->va_list_fpr_size)
9716 t = build2 (MODIFY_EXPR, TREE_TYPE (fpr), fpr,
9717 build_int_cst (NULL_TREE, n_fpr));
9718 TREE_SIDE_EFFECTS (t) = 1;
9719 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
9721 #ifdef HAVE_AS_GNU_ATTRIBUTE
9722 if (call_ABI_of_interest (cfun->decl))
9723 rs6000_passes_float = true;
9724 #endif
9727 /* Find the overflow area. */
9728 t = make_tree (TREE_TYPE (ovf), virtual_incoming_args_rtx);
9729 if (words != 0)
9730 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (ovf), t,
9731 size_int (words * UNITS_PER_WORD));
9732 t = build2 (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
9733 TREE_SIDE_EFFECTS (t) = 1;
9734 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
9736 /* If there were no va_arg invocations, don't set up the register
9737 save area. */
9738 if (!cfun->va_list_gpr_size
9739 && !cfun->va_list_fpr_size
9740 && n_gpr < GP_ARG_NUM_REG
9741 && n_fpr < FP_ARG_V4_MAX_REG)
9742 return;
9744 /* Find the register save area. */
9745 t = make_tree (TREE_TYPE (sav), virtual_stack_vars_rtx);
9746 if (cfun->machine->varargs_save_offset)
9747 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (sav), t,
9748 size_int (cfun->machine->varargs_save_offset));
9749 t = build2 (MODIFY_EXPR, TREE_TYPE (sav), sav, t);
9750 TREE_SIDE_EFFECTS (t) = 1;
9751 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
9754 /* Implement va_arg. */
9756 tree
9757 rs6000_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
9758 gimple_seq *post_p)
9760 tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
9761 tree gpr, fpr, ovf, sav, reg, t, u;
9762 int size, rsize, n_reg, sav_ofs, sav_scale;
9763 tree lab_false, lab_over, addr;
9764 int align;
9765 tree ptrtype = build_pointer_type_for_mode (type, ptr_mode, true);
9766 int regalign = 0;
9767 gimple stmt;
9769 if (pass_by_reference (NULL, TYPE_MODE (type), type, false))
9771 t = rs6000_gimplify_va_arg (valist, ptrtype, pre_p, post_p);
9772 return build_va_arg_indirect_ref (t);
9775 /* We need to deal with the fact that the darwin ppc64 ABI is defined by an
9776 earlier version of gcc, with the property that it always applied alignment
9777 adjustments to the va-args (even for zero-sized types). The cheapest way
9778 to deal with this is to replicate the effect of the part of
9779 std_gimplify_va_arg_expr that carries out the align adjust, for the case
9780 of relevance.
9781 We don't need to check for pass-by-reference because of the test above.
9782 We can return a simplifed answer, since we know there's no offset to add. */
9784 if (TARGET_MACHO
9785 && rs6000_darwin64_abi
9786 && integer_zerop (TYPE_SIZE (type)))
9788 unsigned HOST_WIDE_INT align, boundary;
9789 tree valist_tmp = get_initialized_tmp_var (valist, pre_p, NULL);
9790 align = PARM_BOUNDARY / BITS_PER_UNIT;
9791 boundary = rs6000_function_arg_boundary (TYPE_MODE (type), type);
9792 if (boundary > MAX_SUPPORTED_STACK_ALIGNMENT)
9793 boundary = MAX_SUPPORTED_STACK_ALIGNMENT;
9794 boundary /= BITS_PER_UNIT;
9795 if (boundary > align)
9797 tree t ;
9798 /* This updates arg ptr by the amount that would be necessary
9799 to align the zero-sized (but not zero-alignment) item. */
9800 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
9801 fold_build2 (POINTER_PLUS_EXPR,
9802 TREE_TYPE (valist),
9803 valist_tmp, size_int (boundary - 1)));
9804 gimplify_and_add (t, pre_p);
9806 t = fold_convert (sizetype, valist_tmp);
9807 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
9808 fold_convert (TREE_TYPE (valist),
9809 fold_build2 (BIT_AND_EXPR, sizetype, t,
9810 size_int (-boundary))));
9811 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist, t);
9812 gimplify_and_add (t, pre_p);
9814 /* Since it is zero-sized there's no increment for the item itself. */
9815 valist_tmp = fold_convert (build_pointer_type (type), valist_tmp);
9816 return build_va_arg_indirect_ref (valist_tmp);
9819 if (DEFAULT_ABI != ABI_V4)
9821 if (targetm.calls.split_complex_arg && TREE_CODE (type) == COMPLEX_TYPE)
9823 tree elem_type = TREE_TYPE (type);
9824 enum machine_mode elem_mode = TYPE_MODE (elem_type);
9825 int elem_size = GET_MODE_SIZE (elem_mode);
9827 if (elem_size < UNITS_PER_WORD)
9829 tree real_part, imag_part;
9830 gimple_seq post = NULL;
9832 real_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
9833 &post);
9834 /* Copy the value into a temporary, lest the formal temporary
9835 be reused out from under us. */
9836 real_part = get_initialized_tmp_var (real_part, pre_p, &post);
9837 gimple_seq_add_seq (pre_p, post);
9839 imag_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
9840 post_p);
9842 return build2 (COMPLEX_EXPR, type, real_part, imag_part);
9846 return std_gimplify_va_arg_expr (valist, type, pre_p, post_p);
9849 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
9850 f_fpr = DECL_CHAIN (f_gpr);
9851 f_res = DECL_CHAIN (f_fpr);
9852 f_ovf = DECL_CHAIN (f_res);
9853 f_sav = DECL_CHAIN (f_ovf);
9855 valist = build_va_arg_indirect_ref (valist);
9856 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
9857 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), unshare_expr (valist),
9858 f_fpr, NULL_TREE);
9859 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), unshare_expr (valist),
9860 f_ovf, NULL_TREE);
9861 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), unshare_expr (valist),
9862 f_sav, NULL_TREE);
9864 size = int_size_in_bytes (type);
9865 rsize = (size + 3) / 4;
9866 align = 1;
9868 if (TARGET_HARD_FLOAT && TARGET_FPRS
9869 && ((TARGET_SINGLE_FLOAT && TYPE_MODE (type) == SFmode)
9870 || (TARGET_DOUBLE_FLOAT
9871 && (TYPE_MODE (type) == DFmode
9872 || TYPE_MODE (type) == TFmode
9873 || TYPE_MODE (type) == SDmode
9874 || TYPE_MODE (type) == DDmode
9875 || TYPE_MODE (type) == TDmode))))
9877 /* FP args go in FP registers, if present. */
9878 reg = fpr;
9879 n_reg = (size + 7) / 8;
9880 sav_ofs = ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? 8 : 4) * 4;
9881 sav_scale = ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? 8 : 4);
9882 if (TYPE_MODE (type) != SFmode && TYPE_MODE (type) != SDmode)
9883 align = 8;
9885 else
9887 /* Otherwise into GP registers. */
9888 reg = gpr;
9889 n_reg = rsize;
9890 sav_ofs = 0;
9891 sav_scale = 4;
9892 if (n_reg == 2)
9893 align = 8;
9896 /* Pull the value out of the saved registers.... */
9898 lab_over = NULL;
9899 addr = create_tmp_var (ptr_type_node, "addr");
9901 /* AltiVec vectors never go in registers when -mabi=altivec. */
9902 if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
9903 align = 16;
9904 else
9906 lab_false = create_artificial_label (input_location);
9907 lab_over = create_artificial_label (input_location);
9909 /* Long long and SPE vectors are aligned in the registers.
9910 As are any other 2 gpr item such as complex int due to a
9911 historical mistake. */
9912 u = reg;
9913 if (n_reg == 2 && reg == gpr)
9915 regalign = 1;
9916 u = build2 (BIT_AND_EXPR, TREE_TYPE (reg), unshare_expr (reg),
9917 build_int_cst (TREE_TYPE (reg), n_reg - 1));
9918 u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg),
9919 unshare_expr (reg), u);
9921 /* _Decimal128 is passed in even/odd fpr pairs; the stored
9922 reg number is 0 for f1, so we want to make it odd. */
9923 else if (reg == fpr && TYPE_MODE (type) == TDmode)
9925 t = build2 (BIT_IOR_EXPR, TREE_TYPE (reg), unshare_expr (reg),
9926 build_int_cst (TREE_TYPE (reg), 1));
9927 u = build2 (MODIFY_EXPR, void_type_node, unshare_expr (reg), t);
9930 t = fold_convert (TREE_TYPE (reg), size_int (8 - n_reg + 1));
9931 t = build2 (GE_EXPR, boolean_type_node, u, t);
9932 u = build1 (GOTO_EXPR, void_type_node, lab_false);
9933 t = build3 (COND_EXPR, void_type_node, t, u, NULL_TREE);
9934 gimplify_and_add (t, pre_p);
9936 t = sav;
9937 if (sav_ofs)
9938 t = build2 (POINTER_PLUS_EXPR, ptr_type_node, sav, size_int (sav_ofs));
9940 u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg), unshare_expr (reg),
9941 build_int_cst (TREE_TYPE (reg), n_reg));
9942 u = fold_convert (sizetype, u);
9943 u = build2 (MULT_EXPR, sizetype, u, size_int (sav_scale));
9944 t = build2 (POINTER_PLUS_EXPR, ptr_type_node, t, u);
9946 /* _Decimal32 varargs are located in the second word of the 64-bit
9947 FP register for 32-bit binaries. */
9948 if (!TARGET_POWERPC64
9949 && TARGET_HARD_FLOAT && TARGET_FPRS
9950 && TYPE_MODE (type) == SDmode)
9951 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (size));
9953 gimplify_assign (addr, t, pre_p);
9955 gimple_seq_add_stmt (pre_p, gimple_build_goto (lab_over));
9957 stmt = gimple_build_label (lab_false);
9958 gimple_seq_add_stmt (pre_p, stmt);
9960 if ((n_reg == 2 && !regalign) || n_reg > 2)
9962 /* Ensure that we don't find any more args in regs.
9963 Alignment has taken care of for special cases. */
9964 gimplify_assign (reg, build_int_cst (TREE_TYPE (reg), 8), pre_p);
9968 /* ... otherwise out of the overflow area. */
9970 /* Care for on-stack alignment if needed. */
9971 t = ovf;
9972 if (align != 1)
9974 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (align - 1));
9975 t = fold_convert (sizetype, t);
9976 t = build2 (BIT_AND_EXPR, TREE_TYPE (t), t,
9977 size_int (-align));
9978 t = fold_convert (TREE_TYPE (ovf), t);
9980 gimplify_expr (&t, pre_p, NULL, is_gimple_val, fb_rvalue);
9982 gimplify_assign (unshare_expr (addr), t, pre_p);
9984 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (size));
9985 gimplify_assign (unshare_expr (ovf), t, pre_p);
9987 if (lab_over)
9989 stmt = gimple_build_label (lab_over);
9990 gimple_seq_add_stmt (pre_p, stmt);
9993 if (STRICT_ALIGNMENT
9994 && (TYPE_ALIGN (type)
9995 > (unsigned) BITS_PER_UNIT * (align < 4 ? 4 : align)))
9997 /* The value (of type complex double, for example) may not be
9998 aligned in memory in the saved registers, so copy via a
9999 temporary. (This is the same code as used for SPARC.) */
10000 tree tmp = create_tmp_var (type, "va_arg_tmp");
10001 tree dest_addr = build_fold_addr_expr (tmp);
10003 tree copy = build_call_expr (implicit_built_in_decls[BUILT_IN_MEMCPY],
10004 3, dest_addr, addr, size_int (rsize * 4));
10006 gimplify_and_add (copy, pre_p);
10007 addr = dest_addr;
10010 addr = fold_convert (ptrtype, addr);
10011 return build_va_arg_indirect_ref (addr);
10014 /* Builtins. */
10016 static void
10017 def_builtin (int mask, const char *name, tree type, int code)
10019 if ((mask & target_flags) || TARGET_PAIRED_FLOAT)
10021 tree t;
10022 if (rs6000_builtin_decls[code])
10023 fatal_error ("internal error: builtin function to %s already processed",
10024 name);
10026 rs6000_builtin_decls[code] = t =
10027 add_builtin_function (name, type, code, BUILT_IN_MD,
10028 NULL, NULL_TREE);
10030 gcc_assert (code >= 0 && code < (int)RS6000_BUILTIN_COUNT);
10031 switch (builtin_classify[code])
10033 default:
10034 gcc_unreachable ();
10036 /* assume builtin can do anything. */
10037 case RS6000_BTC_MISC:
10038 break;
10040 /* const function, function only depends on the inputs. */
10041 case RS6000_BTC_CONST:
10042 TREE_READONLY (t) = 1;
10043 TREE_NOTHROW (t) = 1;
10044 break;
10046 /* pure function, function can read global memory. */
10047 case RS6000_BTC_PURE:
10048 DECL_PURE_P (t) = 1;
10049 TREE_NOTHROW (t) = 1;
10050 break;
10052 /* Function is a math function. If rounding mode is on, then treat
10053 the function as not reading global memory, but it can have
10054 arbitrary side effects. If it is off, then assume the function is
10055 a const function. This mimics the ATTR_MATHFN_FPROUNDING
10056 attribute in builtin-attribute.def that is used for the math
10057 functions. */
10058 case RS6000_BTC_FP_PURE:
10059 TREE_NOTHROW (t) = 1;
10060 if (flag_rounding_math)
10062 DECL_PURE_P (t) = 1;
10063 DECL_IS_NOVOPS (t) = 1;
10065 else
10066 TREE_READONLY (t) = 1;
10067 break;
10072 /* Simple ternary operations: VECd = foo (VECa, VECb, VECc). */
10074 static const struct builtin_description bdesc_3arg[] =
10076 { MASK_ALTIVEC, CODE_FOR_fmav4sf4, "__builtin_altivec_vmaddfp", ALTIVEC_BUILTIN_VMADDFP },
10077 { MASK_ALTIVEC, CODE_FOR_altivec_vmhaddshs, "__builtin_altivec_vmhaddshs", ALTIVEC_BUILTIN_VMHADDSHS },
10078 { MASK_ALTIVEC, CODE_FOR_altivec_vmhraddshs, "__builtin_altivec_vmhraddshs", ALTIVEC_BUILTIN_VMHRADDSHS },
10079 { MASK_ALTIVEC, CODE_FOR_altivec_vmladduhm, "__builtin_altivec_vmladduhm", ALTIVEC_BUILTIN_VMLADDUHM},
10080 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumubm, "__builtin_altivec_vmsumubm", ALTIVEC_BUILTIN_VMSUMUBM },
10081 { MASK_ALTIVEC, CODE_FOR_altivec_vmsummbm, "__builtin_altivec_vmsummbm", ALTIVEC_BUILTIN_VMSUMMBM },
10082 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhm, "__builtin_altivec_vmsumuhm", ALTIVEC_BUILTIN_VMSUMUHM },
10083 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshm, "__builtin_altivec_vmsumshm", ALTIVEC_BUILTIN_VMSUMSHM },
10084 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhs, "__builtin_altivec_vmsumuhs", ALTIVEC_BUILTIN_VMSUMUHS },
10085 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshs, "__builtin_altivec_vmsumshs", ALTIVEC_BUILTIN_VMSUMSHS },
10086 { MASK_ALTIVEC, CODE_FOR_nfmsv4sf4, "__builtin_altivec_vnmsubfp", ALTIVEC_BUILTIN_VNMSUBFP },
10087 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2df, "__builtin_altivec_vperm_2df", ALTIVEC_BUILTIN_VPERM_2DF },
10088 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2di, "__builtin_altivec_vperm_2di", ALTIVEC_BUILTIN_VPERM_2DI },
10089 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4sf, "__builtin_altivec_vperm_4sf", ALTIVEC_BUILTIN_VPERM_4SF },
10090 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4si, "__builtin_altivec_vperm_4si", ALTIVEC_BUILTIN_VPERM_4SI },
10091 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v8hi, "__builtin_altivec_vperm_8hi", ALTIVEC_BUILTIN_VPERM_8HI },
10092 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_altivec_vperm_16qi", ALTIVEC_BUILTIN_VPERM_16QI },
10093 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2di_uns, "__builtin_altivec_vperm_2di_uns", ALTIVEC_BUILTIN_VPERM_2DI_UNS },
10094 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4si_uns, "__builtin_altivec_vperm_4si_uns", ALTIVEC_BUILTIN_VPERM_4SI_UNS },
10095 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v8hi_uns, "__builtin_altivec_vperm_8hi_uns", ALTIVEC_BUILTIN_VPERM_8HI_UNS },
10096 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_altivec_vperm_16qi_uns", ALTIVEC_BUILTIN_VPERM_16QI_UNS },
10097 { MASK_ALTIVEC, CODE_FOR_vector_select_v4sf, "__builtin_altivec_vsel_4sf", ALTIVEC_BUILTIN_VSEL_4SF },
10098 { MASK_ALTIVEC, CODE_FOR_vector_select_v4si, "__builtin_altivec_vsel_4si", ALTIVEC_BUILTIN_VSEL_4SI },
10099 { MASK_ALTIVEC, CODE_FOR_vector_select_v8hi, "__builtin_altivec_vsel_8hi", ALTIVEC_BUILTIN_VSEL_8HI },
10100 { MASK_ALTIVEC, CODE_FOR_vector_select_v16qi, "__builtin_altivec_vsel_16qi", ALTIVEC_BUILTIN_VSEL_16QI },
10101 { MASK_ALTIVEC, CODE_FOR_vector_select_v2df, "__builtin_altivec_vsel_2df", ALTIVEC_BUILTIN_VSEL_2DF },
10102 { MASK_ALTIVEC, CODE_FOR_vector_select_v2di, "__builtin_altivec_vsel_2di", ALTIVEC_BUILTIN_VSEL_2DI },
10103 { MASK_ALTIVEC, CODE_FOR_vector_select_v4si_uns, "__builtin_altivec_vsel_4si_uns", ALTIVEC_BUILTIN_VSEL_4SI_UNS },
10104 { MASK_ALTIVEC, CODE_FOR_vector_select_v8hi_uns, "__builtin_altivec_vsel_8hi_uns", ALTIVEC_BUILTIN_VSEL_8HI_UNS },
10105 { MASK_ALTIVEC, CODE_FOR_vector_select_v16qi_uns, "__builtin_altivec_vsel_16qi_uns", ALTIVEC_BUILTIN_VSEL_16QI_UNS },
10106 { MASK_ALTIVEC, CODE_FOR_vector_select_v2di_uns, "__builtin_altivec_vsel_2di_uns", ALTIVEC_BUILTIN_VSEL_2DI_UNS },
10107 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v16qi, "__builtin_altivec_vsldoi_16qi", ALTIVEC_BUILTIN_VSLDOI_16QI },
10108 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v8hi, "__builtin_altivec_vsldoi_8hi", ALTIVEC_BUILTIN_VSLDOI_8HI },
10109 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v4si, "__builtin_altivec_vsldoi_4si", ALTIVEC_BUILTIN_VSLDOI_4SI },
10110 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v4sf, "__builtin_altivec_vsldoi_4sf", ALTIVEC_BUILTIN_VSLDOI_4SF },
10112 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_madd", ALTIVEC_BUILTIN_VEC_MADD },
10113 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_madds", ALTIVEC_BUILTIN_VEC_MADDS },
10114 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mladd", ALTIVEC_BUILTIN_VEC_MLADD },
10115 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mradds", ALTIVEC_BUILTIN_VEC_MRADDS },
10116 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msum", ALTIVEC_BUILTIN_VEC_MSUM },
10117 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumshm", ALTIVEC_BUILTIN_VEC_VMSUMSHM },
10118 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumuhm", ALTIVEC_BUILTIN_VEC_VMSUMUHM },
10119 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsummbm", ALTIVEC_BUILTIN_VEC_VMSUMMBM },
10120 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumubm", ALTIVEC_BUILTIN_VEC_VMSUMUBM },
10121 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msums", ALTIVEC_BUILTIN_VEC_MSUMS },
10122 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumshs", ALTIVEC_BUILTIN_VEC_VMSUMSHS },
10123 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumuhs", ALTIVEC_BUILTIN_VEC_VMSUMUHS },
10124 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nmsub", ALTIVEC_BUILTIN_VEC_NMSUB },
10125 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_perm", ALTIVEC_BUILTIN_VEC_PERM },
10126 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sel", ALTIVEC_BUILTIN_VEC_SEL },
10128 { MASK_VSX, CODE_FOR_fmav2df4, "__builtin_vsx_xvmadddp", VSX_BUILTIN_XVMADDDP },
10129 { MASK_VSX, CODE_FOR_fmsv2df4, "__builtin_vsx_xvmsubdp", VSX_BUILTIN_XVMSUBDP },
10130 { MASK_VSX, CODE_FOR_nfmav2df4, "__builtin_vsx_xvnmadddp", VSX_BUILTIN_XVNMADDDP },
10131 { MASK_VSX, CODE_FOR_nfmsv2df4, "__builtin_vsx_xvnmsubdp", VSX_BUILTIN_XVNMSUBDP },
10133 { MASK_VSX, CODE_FOR_fmav4sf4, "__builtin_vsx_xvmaddsp", VSX_BUILTIN_XVMADDSP },
10134 { MASK_VSX, CODE_FOR_fmsv4sf4, "__builtin_vsx_xvmsubsp", VSX_BUILTIN_XVMSUBSP },
10135 { MASK_VSX, CODE_FOR_nfmav4sf4, "__builtin_vsx_xvnmaddsp", VSX_BUILTIN_XVNMADDSP },
10136 { MASK_VSX, CODE_FOR_nfmsv4sf4, "__builtin_vsx_xvnmsubsp", VSX_BUILTIN_XVNMSUBSP },
10138 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msub", VSX_BUILTIN_VEC_MSUB },
10139 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nmadd", VSX_BUILTIN_VEC_NMADD },
10141 { MASK_VSX, CODE_FOR_vector_select_v2di, "__builtin_vsx_xxsel_2di", VSX_BUILTIN_XXSEL_2DI },
10142 { MASK_VSX, CODE_FOR_vector_select_v2df, "__builtin_vsx_xxsel_2df", VSX_BUILTIN_XXSEL_2DF },
10143 { MASK_VSX, CODE_FOR_vector_select_v4sf, "__builtin_vsx_xxsel_4sf", VSX_BUILTIN_XXSEL_4SF },
10144 { MASK_VSX, CODE_FOR_vector_select_v4si, "__builtin_vsx_xxsel_4si", VSX_BUILTIN_XXSEL_4SI },
10145 { MASK_VSX, CODE_FOR_vector_select_v8hi, "__builtin_vsx_xxsel_8hi", VSX_BUILTIN_XXSEL_8HI },
10146 { MASK_VSX, CODE_FOR_vector_select_v16qi, "__builtin_vsx_xxsel_16qi", VSX_BUILTIN_XXSEL_16QI },
10147 { MASK_VSX, CODE_FOR_vector_select_v2di_uns, "__builtin_vsx_xxsel_2di_uns", VSX_BUILTIN_XXSEL_2DI_UNS },
10148 { MASK_VSX, CODE_FOR_vector_select_v4si_uns, "__builtin_vsx_xxsel_4si_uns", VSX_BUILTIN_XXSEL_4SI_UNS },
10149 { MASK_VSX, CODE_FOR_vector_select_v8hi_uns, "__builtin_vsx_xxsel_8hi_uns", VSX_BUILTIN_XXSEL_8HI_UNS },
10150 { MASK_VSX, CODE_FOR_vector_select_v16qi_uns, "__builtin_vsx_xxsel_16qi_uns", VSX_BUILTIN_XXSEL_16QI_UNS },
10152 { MASK_VSX, CODE_FOR_altivec_vperm_v2di, "__builtin_vsx_vperm_2di", VSX_BUILTIN_VPERM_2DI },
10153 { MASK_VSX, CODE_FOR_altivec_vperm_v2df, "__builtin_vsx_vperm_2df", VSX_BUILTIN_VPERM_2DF },
10154 { MASK_VSX, CODE_FOR_altivec_vperm_v4sf, "__builtin_vsx_vperm_4sf", VSX_BUILTIN_VPERM_4SF },
10155 { MASK_VSX, CODE_FOR_altivec_vperm_v4si, "__builtin_vsx_vperm_4si", VSX_BUILTIN_VPERM_4SI },
10156 { MASK_VSX, CODE_FOR_altivec_vperm_v8hi, "__builtin_vsx_vperm_8hi", VSX_BUILTIN_VPERM_8HI },
10157 { MASK_VSX, CODE_FOR_altivec_vperm_v16qi, "__builtin_vsx_vperm_16qi", VSX_BUILTIN_VPERM_16QI },
10158 { MASK_VSX, CODE_FOR_altivec_vperm_v2di_uns, "__builtin_vsx_vperm_2di_uns", VSX_BUILTIN_VPERM_2DI_UNS },
10159 { MASK_VSX, CODE_FOR_altivec_vperm_v4si_uns, "__builtin_vsx_vperm_4si_uns", VSX_BUILTIN_VPERM_4SI_UNS },
10160 { MASK_VSX, CODE_FOR_altivec_vperm_v8hi_uns, "__builtin_vsx_vperm_8hi_uns", VSX_BUILTIN_VPERM_8HI_UNS },
10161 { MASK_VSX, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_vsx_vperm_16qi_uns", VSX_BUILTIN_VPERM_16QI_UNS },
10163 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v2df, "__builtin_vsx_xxpermdi_2df", VSX_BUILTIN_XXPERMDI_2DF },
10164 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v2di, "__builtin_vsx_xxpermdi_2di", VSX_BUILTIN_XXPERMDI_2DI },
10165 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v4sf, "__builtin_vsx_xxpermdi_4sf", VSX_BUILTIN_XXPERMDI_4SF },
10166 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v4si, "__builtin_vsx_xxpermdi_4si", VSX_BUILTIN_XXPERMDI_4SI },
10167 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v8hi, "__builtin_vsx_xxpermdi_8hi", VSX_BUILTIN_XXPERMDI_8HI },
10168 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v16qi, "__builtin_vsx_xxpermdi_16qi", VSX_BUILTIN_XXPERMDI_16QI },
10169 { MASK_VSX, CODE_FOR_nothing, "__builtin_vsx_xxpermdi", VSX_BUILTIN_VEC_XXPERMDI },
10170 { MASK_VSX, CODE_FOR_vsx_set_v2df, "__builtin_vsx_set_2df", VSX_BUILTIN_SET_2DF },
10171 { MASK_VSX, CODE_FOR_vsx_set_v2di, "__builtin_vsx_set_2di", VSX_BUILTIN_SET_2DI },
10173 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v2di, "__builtin_vsx_xxsldwi_2di", VSX_BUILTIN_XXSLDWI_2DI },
10174 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v2df, "__builtin_vsx_xxsldwi_2df", VSX_BUILTIN_XXSLDWI_2DF },
10175 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v4sf, "__builtin_vsx_xxsldwi_4sf", VSX_BUILTIN_XXSLDWI_4SF },
10176 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v4si, "__builtin_vsx_xxsldwi_4si", VSX_BUILTIN_XXSLDWI_4SI },
10177 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v8hi, "__builtin_vsx_xxsldwi_8hi", VSX_BUILTIN_XXSLDWI_8HI },
10178 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v16qi, "__builtin_vsx_xxsldwi_16qi", VSX_BUILTIN_XXSLDWI_16QI },
10179 { MASK_VSX, CODE_FOR_nothing, "__builtin_vsx_xxsldwi", VSX_BUILTIN_VEC_XXSLDWI },
10181 { 0, CODE_FOR_fmsv2sf4, "__builtin_paired_msub", PAIRED_BUILTIN_MSUB },
10182 { 0, CODE_FOR_fmav2sf4, "__builtin_paired_madd", PAIRED_BUILTIN_MADD },
10183 { 0, CODE_FOR_paired_madds0, "__builtin_paired_madds0", PAIRED_BUILTIN_MADDS0 },
10184 { 0, CODE_FOR_paired_madds1, "__builtin_paired_madds1", PAIRED_BUILTIN_MADDS1 },
10185 { 0, CODE_FOR_nfmsv2sf4, "__builtin_paired_nmsub", PAIRED_BUILTIN_NMSUB },
10186 { 0, CODE_FOR_nfmav2sf4, "__builtin_paired_nmadd", PAIRED_BUILTIN_NMADD },
10187 { 0, CODE_FOR_paired_sum0, "__builtin_paired_sum0", PAIRED_BUILTIN_SUM0 },
10188 { 0, CODE_FOR_paired_sum1, "__builtin_paired_sum1", PAIRED_BUILTIN_SUM1 },
10189 { 0, CODE_FOR_selv2sf4, "__builtin_paired_selv2sf4", PAIRED_BUILTIN_SELV2SF4 },
10192 /* DST operations: void foo (void *, const int, const char). */
10194 static const struct builtin_description bdesc_dst[] =
10196 { MASK_ALTIVEC, CODE_FOR_altivec_dst, "__builtin_altivec_dst", ALTIVEC_BUILTIN_DST },
10197 { MASK_ALTIVEC, CODE_FOR_altivec_dstt, "__builtin_altivec_dstt", ALTIVEC_BUILTIN_DSTT },
10198 { MASK_ALTIVEC, CODE_FOR_altivec_dstst, "__builtin_altivec_dstst", ALTIVEC_BUILTIN_DSTST },
10199 { MASK_ALTIVEC, CODE_FOR_altivec_dststt, "__builtin_altivec_dststt", ALTIVEC_BUILTIN_DSTSTT },
10201 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dst", ALTIVEC_BUILTIN_VEC_DST },
10202 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dstt", ALTIVEC_BUILTIN_VEC_DSTT },
10203 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dstst", ALTIVEC_BUILTIN_VEC_DSTST },
10204 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dststt", ALTIVEC_BUILTIN_VEC_DSTSTT }
10207 /* Simple binary operations: VECc = foo (VECa, VECb). */
10209 static struct builtin_description bdesc_2arg[] =
10211 { MASK_ALTIVEC, CODE_FOR_addv16qi3, "__builtin_altivec_vaddubm", ALTIVEC_BUILTIN_VADDUBM },
10212 { MASK_ALTIVEC, CODE_FOR_addv8hi3, "__builtin_altivec_vadduhm", ALTIVEC_BUILTIN_VADDUHM },
10213 { MASK_ALTIVEC, CODE_FOR_addv4si3, "__builtin_altivec_vadduwm", ALTIVEC_BUILTIN_VADDUWM },
10214 { MASK_ALTIVEC, CODE_FOR_addv4sf3, "__builtin_altivec_vaddfp", ALTIVEC_BUILTIN_VADDFP },
10215 { MASK_ALTIVEC, CODE_FOR_altivec_vaddcuw, "__builtin_altivec_vaddcuw", ALTIVEC_BUILTIN_VADDCUW },
10216 { MASK_ALTIVEC, CODE_FOR_altivec_vaddubs, "__builtin_altivec_vaddubs", ALTIVEC_BUILTIN_VADDUBS },
10217 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsbs, "__builtin_altivec_vaddsbs", ALTIVEC_BUILTIN_VADDSBS },
10218 { MASK_ALTIVEC, CODE_FOR_altivec_vadduhs, "__builtin_altivec_vadduhs", ALTIVEC_BUILTIN_VADDUHS },
10219 { MASK_ALTIVEC, CODE_FOR_altivec_vaddshs, "__builtin_altivec_vaddshs", ALTIVEC_BUILTIN_VADDSHS },
10220 { MASK_ALTIVEC, CODE_FOR_altivec_vadduws, "__builtin_altivec_vadduws", ALTIVEC_BUILTIN_VADDUWS },
10221 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsws, "__builtin_altivec_vaddsws", ALTIVEC_BUILTIN_VADDSWS },
10222 { MASK_ALTIVEC, CODE_FOR_andv4si3, "__builtin_altivec_vand", ALTIVEC_BUILTIN_VAND },
10223 { MASK_ALTIVEC, CODE_FOR_andcv4si3, "__builtin_altivec_vandc", ALTIVEC_BUILTIN_VANDC },
10224 { MASK_ALTIVEC, CODE_FOR_altivec_vavgub, "__builtin_altivec_vavgub", ALTIVEC_BUILTIN_VAVGUB },
10225 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsb, "__builtin_altivec_vavgsb", ALTIVEC_BUILTIN_VAVGSB },
10226 { MASK_ALTIVEC, CODE_FOR_altivec_vavguh, "__builtin_altivec_vavguh", ALTIVEC_BUILTIN_VAVGUH },
10227 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsh, "__builtin_altivec_vavgsh", ALTIVEC_BUILTIN_VAVGSH },
10228 { MASK_ALTIVEC, CODE_FOR_altivec_vavguw, "__builtin_altivec_vavguw", ALTIVEC_BUILTIN_VAVGUW },
10229 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsw, "__builtin_altivec_vavgsw", ALTIVEC_BUILTIN_VAVGSW },
10230 { MASK_ALTIVEC, CODE_FOR_altivec_vcfux, "__builtin_altivec_vcfux", ALTIVEC_BUILTIN_VCFUX },
10231 { MASK_ALTIVEC, CODE_FOR_altivec_vcfsx, "__builtin_altivec_vcfsx", ALTIVEC_BUILTIN_VCFSX },
10232 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpbfp, "__builtin_altivec_vcmpbfp", ALTIVEC_BUILTIN_VCMPBFP },
10233 { MASK_ALTIVEC, CODE_FOR_vector_eqv16qi, "__builtin_altivec_vcmpequb", ALTIVEC_BUILTIN_VCMPEQUB },
10234 { MASK_ALTIVEC, CODE_FOR_vector_eqv8hi, "__builtin_altivec_vcmpequh", ALTIVEC_BUILTIN_VCMPEQUH },
10235 { MASK_ALTIVEC, CODE_FOR_vector_eqv4si, "__builtin_altivec_vcmpequw", ALTIVEC_BUILTIN_VCMPEQUW },
10236 { MASK_ALTIVEC, CODE_FOR_vector_eqv4sf, "__builtin_altivec_vcmpeqfp", ALTIVEC_BUILTIN_VCMPEQFP },
10237 { MASK_ALTIVEC, CODE_FOR_vector_gev4sf, "__builtin_altivec_vcmpgefp", ALTIVEC_BUILTIN_VCMPGEFP },
10238 { MASK_ALTIVEC, CODE_FOR_vector_gtuv16qi, "__builtin_altivec_vcmpgtub", ALTIVEC_BUILTIN_VCMPGTUB },
10239 { MASK_ALTIVEC, CODE_FOR_vector_gtv16qi, "__builtin_altivec_vcmpgtsb", ALTIVEC_BUILTIN_VCMPGTSB },
10240 { MASK_ALTIVEC, CODE_FOR_vector_gtuv8hi, "__builtin_altivec_vcmpgtuh", ALTIVEC_BUILTIN_VCMPGTUH },
10241 { MASK_ALTIVEC, CODE_FOR_vector_gtv8hi, "__builtin_altivec_vcmpgtsh", ALTIVEC_BUILTIN_VCMPGTSH },
10242 { MASK_ALTIVEC, CODE_FOR_vector_gtuv4si, "__builtin_altivec_vcmpgtuw", ALTIVEC_BUILTIN_VCMPGTUW },
10243 { MASK_ALTIVEC, CODE_FOR_vector_gtv4si, "__builtin_altivec_vcmpgtsw", ALTIVEC_BUILTIN_VCMPGTSW },
10244 { MASK_ALTIVEC, CODE_FOR_vector_gtv4sf, "__builtin_altivec_vcmpgtfp", ALTIVEC_BUILTIN_VCMPGTFP },
10245 { MASK_ALTIVEC, CODE_FOR_altivec_vctsxs, "__builtin_altivec_vctsxs", ALTIVEC_BUILTIN_VCTSXS },
10246 { MASK_ALTIVEC, CODE_FOR_altivec_vctuxs, "__builtin_altivec_vctuxs", ALTIVEC_BUILTIN_VCTUXS },
10247 { MASK_ALTIVEC, CODE_FOR_umaxv16qi3, "__builtin_altivec_vmaxub", ALTIVEC_BUILTIN_VMAXUB },
10248 { MASK_ALTIVEC, CODE_FOR_smaxv16qi3, "__builtin_altivec_vmaxsb", ALTIVEC_BUILTIN_VMAXSB },
10249 { MASK_ALTIVEC, CODE_FOR_umaxv8hi3, "__builtin_altivec_vmaxuh", ALTIVEC_BUILTIN_VMAXUH },
10250 { MASK_ALTIVEC, CODE_FOR_smaxv8hi3, "__builtin_altivec_vmaxsh", ALTIVEC_BUILTIN_VMAXSH },
10251 { MASK_ALTIVEC, CODE_FOR_umaxv4si3, "__builtin_altivec_vmaxuw", ALTIVEC_BUILTIN_VMAXUW },
10252 { MASK_ALTIVEC, CODE_FOR_smaxv4si3, "__builtin_altivec_vmaxsw", ALTIVEC_BUILTIN_VMAXSW },
10253 { MASK_ALTIVEC, CODE_FOR_smaxv4sf3, "__builtin_altivec_vmaxfp", ALTIVEC_BUILTIN_VMAXFP },
10254 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghb, "__builtin_altivec_vmrghb", ALTIVEC_BUILTIN_VMRGHB },
10255 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghh, "__builtin_altivec_vmrghh", ALTIVEC_BUILTIN_VMRGHH },
10256 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghw, "__builtin_altivec_vmrghw", ALTIVEC_BUILTIN_VMRGHW },
10257 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglb, "__builtin_altivec_vmrglb", ALTIVEC_BUILTIN_VMRGLB },
10258 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglh, "__builtin_altivec_vmrglh", ALTIVEC_BUILTIN_VMRGLH },
10259 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglw, "__builtin_altivec_vmrglw", ALTIVEC_BUILTIN_VMRGLW },
10260 { MASK_ALTIVEC, CODE_FOR_uminv16qi3, "__builtin_altivec_vminub", ALTIVEC_BUILTIN_VMINUB },
10261 { MASK_ALTIVEC, CODE_FOR_sminv16qi3, "__builtin_altivec_vminsb", ALTIVEC_BUILTIN_VMINSB },
10262 { MASK_ALTIVEC, CODE_FOR_uminv8hi3, "__builtin_altivec_vminuh", ALTIVEC_BUILTIN_VMINUH },
10263 { MASK_ALTIVEC, CODE_FOR_sminv8hi3, "__builtin_altivec_vminsh", ALTIVEC_BUILTIN_VMINSH },
10264 { MASK_ALTIVEC, CODE_FOR_uminv4si3, "__builtin_altivec_vminuw", ALTIVEC_BUILTIN_VMINUW },
10265 { MASK_ALTIVEC, CODE_FOR_sminv4si3, "__builtin_altivec_vminsw", ALTIVEC_BUILTIN_VMINSW },
10266 { MASK_ALTIVEC, CODE_FOR_sminv4sf3, "__builtin_altivec_vminfp", ALTIVEC_BUILTIN_VMINFP },
10267 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleub, "__builtin_altivec_vmuleub", ALTIVEC_BUILTIN_VMULEUB },
10268 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleub, "__builtin_altivec_vmuleub_uns", ALTIVEC_BUILTIN_VMULEUB_UNS },
10269 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesb, "__builtin_altivec_vmulesb", ALTIVEC_BUILTIN_VMULESB },
10270 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleuh, "__builtin_altivec_vmuleuh", ALTIVEC_BUILTIN_VMULEUH },
10271 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleuh, "__builtin_altivec_vmuleuh_uns", ALTIVEC_BUILTIN_VMULEUH_UNS },
10272 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesh, "__builtin_altivec_vmulesh", ALTIVEC_BUILTIN_VMULESH },
10273 { MASK_ALTIVEC, CODE_FOR_altivec_vmuloub, "__builtin_altivec_vmuloub", ALTIVEC_BUILTIN_VMULOUB },
10274 { MASK_ALTIVEC, CODE_FOR_altivec_vmuloub, "__builtin_altivec_vmuloub_uns", ALTIVEC_BUILTIN_VMULOUB_UNS },
10275 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosb, "__builtin_altivec_vmulosb", ALTIVEC_BUILTIN_VMULOSB },
10276 { MASK_ALTIVEC, CODE_FOR_altivec_vmulouh, "__builtin_altivec_vmulouh", ALTIVEC_BUILTIN_VMULOUH },
10277 { MASK_ALTIVEC, CODE_FOR_altivec_vmulouh, "__builtin_altivec_vmulouh_uns", ALTIVEC_BUILTIN_VMULOUH_UNS },
10278 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosh, "__builtin_altivec_vmulosh", ALTIVEC_BUILTIN_VMULOSH },
10279 { MASK_ALTIVEC, CODE_FOR_norv4si3, "__builtin_altivec_vnor", ALTIVEC_BUILTIN_VNOR },
10280 { MASK_ALTIVEC, CODE_FOR_iorv4si3, "__builtin_altivec_vor", ALTIVEC_BUILTIN_VOR },
10281 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhum, "__builtin_altivec_vpkuhum", ALTIVEC_BUILTIN_VPKUHUM },
10282 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwum, "__builtin_altivec_vpkuwum", ALTIVEC_BUILTIN_VPKUWUM },
10283 { MASK_ALTIVEC, CODE_FOR_altivec_vpkpx, "__builtin_altivec_vpkpx", ALTIVEC_BUILTIN_VPKPX },
10284 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshss, "__builtin_altivec_vpkshss", ALTIVEC_BUILTIN_VPKSHSS },
10285 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswss, "__builtin_altivec_vpkswss", ALTIVEC_BUILTIN_VPKSWSS },
10286 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhus, "__builtin_altivec_vpkuhus", ALTIVEC_BUILTIN_VPKUHUS },
10287 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshus, "__builtin_altivec_vpkshus", ALTIVEC_BUILTIN_VPKSHUS },
10288 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwus, "__builtin_altivec_vpkuwus", ALTIVEC_BUILTIN_VPKUWUS },
10289 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswus, "__builtin_altivec_vpkswus", ALTIVEC_BUILTIN_VPKSWUS },
10290 { MASK_ALTIVEC, CODE_FOR_recipv4sf3, "__builtin_altivec_vrecipdivfp", ALTIVEC_BUILTIN_VRECIPFP },
10291 { MASK_ALTIVEC, CODE_FOR_vrotlv16qi3, "__builtin_altivec_vrlb", ALTIVEC_BUILTIN_VRLB },
10292 { MASK_ALTIVEC, CODE_FOR_vrotlv8hi3, "__builtin_altivec_vrlh", ALTIVEC_BUILTIN_VRLH },
10293 { MASK_ALTIVEC, CODE_FOR_vrotlv4si3, "__builtin_altivec_vrlw", ALTIVEC_BUILTIN_VRLW },
10294 { MASK_ALTIVEC, CODE_FOR_vashlv16qi3, "__builtin_altivec_vslb", ALTIVEC_BUILTIN_VSLB },
10295 { MASK_ALTIVEC, CODE_FOR_vashlv8hi3, "__builtin_altivec_vslh", ALTIVEC_BUILTIN_VSLH },
10296 { MASK_ALTIVEC, CODE_FOR_vashlv4si3, "__builtin_altivec_vslw", ALTIVEC_BUILTIN_VSLW },
10297 { MASK_ALTIVEC, CODE_FOR_altivec_vsl, "__builtin_altivec_vsl", ALTIVEC_BUILTIN_VSL },
10298 { MASK_ALTIVEC, CODE_FOR_altivec_vslo, "__builtin_altivec_vslo", ALTIVEC_BUILTIN_VSLO },
10299 { MASK_ALTIVEC, CODE_FOR_altivec_vspltb, "__builtin_altivec_vspltb", ALTIVEC_BUILTIN_VSPLTB },
10300 { MASK_ALTIVEC, CODE_FOR_altivec_vsplth, "__builtin_altivec_vsplth", ALTIVEC_BUILTIN_VSPLTH },
10301 { MASK_ALTIVEC, CODE_FOR_altivec_vspltw, "__builtin_altivec_vspltw", ALTIVEC_BUILTIN_VSPLTW },
10302 { MASK_ALTIVEC, CODE_FOR_vlshrv16qi3, "__builtin_altivec_vsrb", ALTIVEC_BUILTIN_VSRB },
10303 { MASK_ALTIVEC, CODE_FOR_vlshrv8hi3, "__builtin_altivec_vsrh", ALTIVEC_BUILTIN_VSRH },
10304 { MASK_ALTIVEC, CODE_FOR_vlshrv4si3, "__builtin_altivec_vsrw", ALTIVEC_BUILTIN_VSRW },
10305 { MASK_ALTIVEC, CODE_FOR_vashrv16qi3, "__builtin_altivec_vsrab", ALTIVEC_BUILTIN_VSRAB },
10306 { MASK_ALTIVEC, CODE_FOR_vashrv8hi3, "__builtin_altivec_vsrah", ALTIVEC_BUILTIN_VSRAH },
10307 { MASK_ALTIVEC, CODE_FOR_vashrv4si3, "__builtin_altivec_vsraw", ALTIVEC_BUILTIN_VSRAW },
10308 { MASK_ALTIVEC, CODE_FOR_altivec_vsr, "__builtin_altivec_vsr", ALTIVEC_BUILTIN_VSR },
10309 { MASK_ALTIVEC, CODE_FOR_altivec_vsro, "__builtin_altivec_vsro", ALTIVEC_BUILTIN_VSRO },
10310 { MASK_ALTIVEC, CODE_FOR_subv16qi3, "__builtin_altivec_vsububm", ALTIVEC_BUILTIN_VSUBUBM },
10311 { MASK_ALTIVEC, CODE_FOR_subv8hi3, "__builtin_altivec_vsubuhm", ALTIVEC_BUILTIN_VSUBUHM },
10312 { MASK_ALTIVEC, CODE_FOR_subv4si3, "__builtin_altivec_vsubuwm", ALTIVEC_BUILTIN_VSUBUWM },
10313 { MASK_ALTIVEC, CODE_FOR_subv4sf3, "__builtin_altivec_vsubfp", ALTIVEC_BUILTIN_VSUBFP },
10314 { MASK_ALTIVEC, CODE_FOR_altivec_vsubcuw, "__builtin_altivec_vsubcuw", ALTIVEC_BUILTIN_VSUBCUW },
10315 { MASK_ALTIVEC, CODE_FOR_altivec_vsububs, "__builtin_altivec_vsububs", ALTIVEC_BUILTIN_VSUBUBS },
10316 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsbs, "__builtin_altivec_vsubsbs", ALTIVEC_BUILTIN_VSUBSBS },
10317 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuhs, "__builtin_altivec_vsubuhs", ALTIVEC_BUILTIN_VSUBUHS },
10318 { MASK_ALTIVEC, CODE_FOR_altivec_vsubshs, "__builtin_altivec_vsubshs", ALTIVEC_BUILTIN_VSUBSHS },
10319 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuws, "__builtin_altivec_vsubuws", ALTIVEC_BUILTIN_VSUBUWS },
10320 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsws, "__builtin_altivec_vsubsws", ALTIVEC_BUILTIN_VSUBSWS },
10321 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4ubs, "__builtin_altivec_vsum4ubs", ALTIVEC_BUILTIN_VSUM4UBS },
10322 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4sbs, "__builtin_altivec_vsum4sbs", ALTIVEC_BUILTIN_VSUM4SBS },
10323 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4shs, "__builtin_altivec_vsum4shs", ALTIVEC_BUILTIN_VSUM4SHS },
10324 { MASK_ALTIVEC, CODE_FOR_altivec_vsum2sws, "__builtin_altivec_vsum2sws", ALTIVEC_BUILTIN_VSUM2SWS },
10325 { MASK_ALTIVEC, CODE_FOR_altivec_vsumsws, "__builtin_altivec_vsumsws", ALTIVEC_BUILTIN_VSUMSWS },
10326 { MASK_ALTIVEC, CODE_FOR_xorv4si3, "__builtin_altivec_vxor", ALTIVEC_BUILTIN_VXOR },
10327 { MASK_ALTIVEC, CODE_FOR_vector_copysignv4sf3, "__builtin_altivec_copysignfp", ALTIVEC_BUILTIN_COPYSIGN_V4SF },
10329 { MASK_VSX, CODE_FOR_addv2df3, "__builtin_vsx_xvadddp", VSX_BUILTIN_XVADDDP },
10330 { MASK_VSX, CODE_FOR_subv2df3, "__builtin_vsx_xvsubdp", VSX_BUILTIN_XVSUBDP },
10331 { MASK_VSX, CODE_FOR_mulv2df3, "__builtin_vsx_xvmuldp", VSX_BUILTIN_XVMULDP },
10332 { MASK_VSX, CODE_FOR_divv2df3, "__builtin_vsx_xvdivdp", VSX_BUILTIN_XVDIVDP },
10333 { MASK_VSX, CODE_FOR_recipv2df3, "__builtin_vsx_xvrecipdivdp", VSX_BUILTIN_RECIP_V2DF },
10334 { MASK_VSX, CODE_FOR_sminv2df3, "__builtin_vsx_xvmindp", VSX_BUILTIN_XVMINDP },
10335 { MASK_VSX, CODE_FOR_smaxv2df3, "__builtin_vsx_xvmaxdp", VSX_BUILTIN_XVMAXDP },
10336 { MASK_VSX, CODE_FOR_vsx_tdivv2df3_fe, "__builtin_vsx_xvtdivdp_fe", VSX_BUILTIN_XVTDIVDP_FE },
10337 { MASK_VSX, CODE_FOR_vsx_tdivv2df3_fg, "__builtin_vsx_xvtdivdp_fg", VSX_BUILTIN_XVTDIVDP_FG },
10338 { MASK_VSX, CODE_FOR_vector_eqv2df, "__builtin_vsx_xvcmpeqdp", VSX_BUILTIN_XVCMPEQDP },
10339 { MASK_VSX, CODE_FOR_vector_gtv2df, "__builtin_vsx_xvcmpgtdp", VSX_BUILTIN_XVCMPGTDP },
10340 { MASK_VSX, CODE_FOR_vector_gev2df, "__builtin_vsx_xvcmpgedp", VSX_BUILTIN_XVCMPGEDP },
10342 { MASK_VSX, CODE_FOR_addv4sf3, "__builtin_vsx_xvaddsp", VSX_BUILTIN_XVADDSP },
10343 { MASK_VSX, CODE_FOR_subv4sf3, "__builtin_vsx_xvsubsp", VSX_BUILTIN_XVSUBSP },
10344 { MASK_VSX, CODE_FOR_mulv4sf3, "__builtin_vsx_xvmulsp", VSX_BUILTIN_XVMULSP },
10345 { MASK_VSX, CODE_FOR_divv4sf3, "__builtin_vsx_xvdivsp", VSX_BUILTIN_XVDIVSP },
10346 { MASK_VSX, CODE_FOR_recipv4sf3, "__builtin_vsx_xvrecipdivsp", VSX_BUILTIN_RECIP_V4SF },
10347 { MASK_VSX, CODE_FOR_sminv4sf3, "__builtin_vsx_xvminsp", VSX_BUILTIN_XVMINSP },
10348 { MASK_VSX, CODE_FOR_smaxv4sf3, "__builtin_vsx_xvmaxsp", VSX_BUILTIN_XVMAXSP },
10349 { MASK_VSX, CODE_FOR_vsx_tdivv4sf3_fe, "__builtin_vsx_xvtdivsp_fe", VSX_BUILTIN_XVTDIVSP_FE },
10350 { MASK_VSX, CODE_FOR_vsx_tdivv4sf3_fg, "__builtin_vsx_xvtdivsp_fg", VSX_BUILTIN_XVTDIVSP_FG },
10351 { MASK_VSX, CODE_FOR_vector_eqv4sf, "__builtin_vsx_xvcmpeqsp", VSX_BUILTIN_XVCMPEQSP },
10352 { MASK_VSX, CODE_FOR_vector_gtv4sf, "__builtin_vsx_xvcmpgtsp", VSX_BUILTIN_XVCMPGTSP },
10353 { MASK_VSX, CODE_FOR_vector_gev4sf, "__builtin_vsx_xvcmpgesp", VSX_BUILTIN_XVCMPGESP },
10355 { MASK_VSX, CODE_FOR_smindf3, "__builtin_vsx_xsmindp", VSX_BUILTIN_XSMINDP },
10356 { MASK_VSX, CODE_FOR_smaxdf3, "__builtin_vsx_xsmaxdp", VSX_BUILTIN_XSMAXDP },
10357 { MASK_VSX, CODE_FOR_vsx_tdivdf3_fe, "__builtin_vsx_xstdivdp_fe", VSX_BUILTIN_XSTDIVDP_FE },
10358 { MASK_VSX, CODE_FOR_vsx_tdivdf3_fg, "__builtin_vsx_xstdivdp_fg", VSX_BUILTIN_XSTDIVDP_FG },
10359 { MASK_VSX, CODE_FOR_vector_copysignv2df3, "__builtin_vsx_cpsgndp", VSX_BUILTIN_CPSGNDP },
10360 { MASK_VSX, CODE_FOR_vector_copysignv4sf3, "__builtin_vsx_cpsgnsp", VSX_BUILTIN_CPSGNSP },
10362 { MASK_VSX, CODE_FOR_vsx_concat_v2df, "__builtin_vsx_concat_2df", VSX_BUILTIN_CONCAT_2DF },
10363 { MASK_VSX, CODE_FOR_vsx_concat_v2di, "__builtin_vsx_concat_2di", VSX_BUILTIN_CONCAT_2DI },
10364 { MASK_VSX, CODE_FOR_vsx_splat_v2df, "__builtin_vsx_splat_2df", VSX_BUILTIN_SPLAT_2DF },
10365 { MASK_VSX, CODE_FOR_vsx_splat_v2di, "__builtin_vsx_splat_2di", VSX_BUILTIN_SPLAT_2DI },
10366 { MASK_VSX, CODE_FOR_vsx_xxmrghw_v4sf, "__builtin_vsx_xxmrghw", VSX_BUILTIN_XXMRGHW_4SF },
10367 { MASK_VSX, CODE_FOR_vsx_xxmrghw_v4si, "__builtin_vsx_xxmrghw_4si", VSX_BUILTIN_XXMRGHW_4SI },
10368 { MASK_VSX, CODE_FOR_vsx_xxmrglw_v4sf, "__builtin_vsx_xxmrglw", VSX_BUILTIN_XXMRGLW_4SF },
10369 { MASK_VSX, CODE_FOR_vsx_xxmrglw_v4si, "__builtin_vsx_xxmrglw_4si", VSX_BUILTIN_XXMRGLW_4SI },
10370 { MASK_VSX, CODE_FOR_vec_interleave_lowv2df, "__builtin_vsx_mergel_2df", VSX_BUILTIN_VEC_MERGEL_V2DF },
10371 { MASK_VSX, CODE_FOR_vec_interleave_lowv2di, "__builtin_vsx_mergel_2di", VSX_BUILTIN_VEC_MERGEL_V2DI },
10372 { MASK_VSX, CODE_FOR_vec_interleave_highv2df, "__builtin_vsx_mergeh_2df", VSX_BUILTIN_VEC_MERGEH_V2DF },
10373 { MASK_VSX, CODE_FOR_vec_interleave_highv2di, "__builtin_vsx_mergeh_2di", VSX_BUILTIN_VEC_MERGEH_V2DI },
10375 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_add", ALTIVEC_BUILTIN_VEC_ADD },
10376 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vaddfp", ALTIVEC_BUILTIN_VEC_VADDFP },
10377 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduwm", ALTIVEC_BUILTIN_VEC_VADDUWM },
10378 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhm", ALTIVEC_BUILTIN_VEC_VADDUHM },
10379 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubm", ALTIVEC_BUILTIN_VEC_VADDUBM },
10380 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_addc", ALTIVEC_BUILTIN_VEC_ADDC },
10381 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_adds", ALTIVEC_BUILTIN_VEC_ADDS },
10382 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddsws", ALTIVEC_BUILTIN_VEC_VADDSWS },
10383 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduws", ALTIVEC_BUILTIN_VEC_VADDUWS },
10384 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddshs", ALTIVEC_BUILTIN_VEC_VADDSHS },
10385 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhs", ALTIVEC_BUILTIN_VEC_VADDUHS },
10386 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddsbs", ALTIVEC_BUILTIN_VEC_VADDSBS },
10387 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubs", ALTIVEC_BUILTIN_VEC_VADDUBS },
10388 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_and", ALTIVEC_BUILTIN_VEC_AND },
10389 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_andc", ALTIVEC_BUILTIN_VEC_ANDC },
10390 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_avg", ALTIVEC_BUILTIN_VEC_AVG },
10391 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsw", ALTIVEC_BUILTIN_VEC_VAVGSW },
10392 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavguw", ALTIVEC_BUILTIN_VEC_VAVGUW },
10393 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsh", ALTIVEC_BUILTIN_VEC_VAVGSH },
10394 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavguh", ALTIVEC_BUILTIN_VEC_VAVGUH },
10395 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsb", ALTIVEC_BUILTIN_VEC_VAVGSB },
10396 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgub", ALTIVEC_BUILTIN_VEC_VAVGUB },
10397 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpb", ALTIVEC_BUILTIN_VEC_CMPB },
10398 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpeq", ALTIVEC_BUILTIN_VEC_CMPEQ },
10399 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpeqfp", ALTIVEC_BUILTIN_VEC_VCMPEQFP },
10400 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequw", ALTIVEC_BUILTIN_VEC_VCMPEQUW },
10401 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequh", ALTIVEC_BUILTIN_VEC_VCMPEQUH },
10402 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequb", ALTIVEC_BUILTIN_VEC_VCMPEQUB },
10403 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpge", ALTIVEC_BUILTIN_VEC_CMPGE },
10404 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpgt", ALTIVEC_BUILTIN_VEC_CMPGT },
10405 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtfp", ALTIVEC_BUILTIN_VEC_VCMPGTFP },
10406 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsw", ALTIVEC_BUILTIN_VEC_VCMPGTSW },
10407 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtuw", ALTIVEC_BUILTIN_VEC_VCMPGTUW },
10408 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsh", ALTIVEC_BUILTIN_VEC_VCMPGTSH },
10409 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtuh", ALTIVEC_BUILTIN_VEC_VCMPGTUH },
10410 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsb", ALTIVEC_BUILTIN_VEC_VCMPGTSB },
10411 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtub", ALTIVEC_BUILTIN_VEC_VCMPGTUB },
10412 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmple", ALTIVEC_BUILTIN_VEC_CMPLE },
10413 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmplt", ALTIVEC_BUILTIN_VEC_CMPLT },
10414 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_copysign", ALTIVEC_BUILTIN_VEC_COPYSIGN },
10415 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_max", ALTIVEC_BUILTIN_VEC_MAX },
10416 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vmaxfp", ALTIVEC_BUILTIN_VEC_VMAXFP },
10417 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsw", ALTIVEC_BUILTIN_VEC_VMAXSW },
10418 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxuw", ALTIVEC_BUILTIN_VEC_VMAXUW },
10419 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsh", ALTIVEC_BUILTIN_VEC_VMAXSH },
10420 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxuh", ALTIVEC_BUILTIN_VEC_VMAXUH },
10421 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsb", ALTIVEC_BUILTIN_VEC_VMAXSB },
10422 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxub", ALTIVEC_BUILTIN_VEC_VMAXUB },
10423 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mergeh", ALTIVEC_BUILTIN_VEC_MERGEH },
10424 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghw", ALTIVEC_BUILTIN_VEC_VMRGHW },
10425 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghh", ALTIVEC_BUILTIN_VEC_VMRGHH },
10426 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghb", ALTIVEC_BUILTIN_VEC_VMRGHB },
10427 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mergel", ALTIVEC_BUILTIN_VEC_MERGEL },
10428 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglw", ALTIVEC_BUILTIN_VEC_VMRGLW },
10429 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglh", ALTIVEC_BUILTIN_VEC_VMRGLH },
10430 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglb", ALTIVEC_BUILTIN_VEC_VMRGLB },
10431 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_min", ALTIVEC_BUILTIN_VEC_MIN },
10432 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vminfp", ALTIVEC_BUILTIN_VEC_VMINFP },
10433 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsw", ALTIVEC_BUILTIN_VEC_VMINSW },
10434 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminuw", ALTIVEC_BUILTIN_VEC_VMINUW },
10435 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsh", ALTIVEC_BUILTIN_VEC_VMINSH },
10436 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminuh", ALTIVEC_BUILTIN_VEC_VMINUH },
10437 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsb", ALTIVEC_BUILTIN_VEC_VMINSB },
10438 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminub", ALTIVEC_BUILTIN_VEC_VMINUB },
10439 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mule", ALTIVEC_BUILTIN_VEC_MULE },
10440 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuleub", ALTIVEC_BUILTIN_VEC_VMULEUB },
10441 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulesb", ALTIVEC_BUILTIN_VEC_VMULESB },
10442 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuleuh", ALTIVEC_BUILTIN_VEC_VMULEUH },
10443 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulesh", ALTIVEC_BUILTIN_VEC_VMULESH },
10444 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mulo", ALTIVEC_BUILTIN_VEC_MULO },
10445 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulosh", ALTIVEC_BUILTIN_VEC_VMULOSH },
10446 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulouh", ALTIVEC_BUILTIN_VEC_VMULOUH },
10447 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulosb", ALTIVEC_BUILTIN_VEC_VMULOSB },
10448 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuloub", ALTIVEC_BUILTIN_VEC_VMULOUB },
10449 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_nor", ALTIVEC_BUILTIN_VEC_NOR },
10450 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_or", ALTIVEC_BUILTIN_VEC_OR },
10451 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_pack", ALTIVEC_BUILTIN_VEC_PACK },
10452 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuwum", ALTIVEC_BUILTIN_VEC_VPKUWUM },
10453 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuhum", ALTIVEC_BUILTIN_VEC_VPKUHUM },
10454 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packpx", ALTIVEC_BUILTIN_VEC_PACKPX },
10455 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packs", ALTIVEC_BUILTIN_VEC_PACKS },
10456 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkswss", ALTIVEC_BUILTIN_VEC_VPKSWSS },
10457 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuwus", ALTIVEC_BUILTIN_VEC_VPKUWUS },
10458 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkshss", ALTIVEC_BUILTIN_VEC_VPKSHSS },
10459 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuhus", ALTIVEC_BUILTIN_VEC_VPKUHUS },
10460 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packsu", ALTIVEC_BUILTIN_VEC_PACKSU },
10461 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkswus", ALTIVEC_BUILTIN_VEC_VPKSWUS },
10462 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkshus", ALTIVEC_BUILTIN_VEC_VPKSHUS },
10463 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_recipdiv", ALTIVEC_BUILTIN_VEC_RECIP },
10464 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rl", ALTIVEC_BUILTIN_VEC_RL },
10465 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlw", ALTIVEC_BUILTIN_VEC_VRLW },
10466 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlh", ALTIVEC_BUILTIN_VEC_VRLH },
10467 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlb", ALTIVEC_BUILTIN_VEC_VRLB },
10468 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sl", ALTIVEC_BUILTIN_VEC_SL },
10469 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslw", ALTIVEC_BUILTIN_VEC_VSLW },
10470 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslh", ALTIVEC_BUILTIN_VEC_VSLH },
10471 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslb", ALTIVEC_BUILTIN_VEC_VSLB },
10472 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sll", ALTIVEC_BUILTIN_VEC_SLL },
10473 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_slo", ALTIVEC_BUILTIN_VEC_SLO },
10474 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sr", ALTIVEC_BUILTIN_VEC_SR },
10475 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrw", ALTIVEC_BUILTIN_VEC_VSRW },
10476 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrh", ALTIVEC_BUILTIN_VEC_VSRH },
10477 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrb", ALTIVEC_BUILTIN_VEC_VSRB },
10478 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sra", ALTIVEC_BUILTIN_VEC_SRA },
10479 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsraw", ALTIVEC_BUILTIN_VEC_VSRAW },
10480 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrah", ALTIVEC_BUILTIN_VEC_VSRAH },
10481 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrab", ALTIVEC_BUILTIN_VEC_VSRAB },
10482 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_srl", ALTIVEC_BUILTIN_VEC_SRL },
10483 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sro", ALTIVEC_BUILTIN_VEC_SRO },
10484 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_sub", ALTIVEC_BUILTIN_VEC_SUB },
10485 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vsubfp", ALTIVEC_BUILTIN_VEC_VSUBFP },
10486 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuwm", ALTIVEC_BUILTIN_VEC_VSUBUWM },
10487 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuhm", ALTIVEC_BUILTIN_VEC_VSUBUHM },
10488 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsububm", ALTIVEC_BUILTIN_VEC_VSUBUBM },
10489 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_subc", ALTIVEC_BUILTIN_VEC_SUBC },
10490 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_subs", ALTIVEC_BUILTIN_VEC_SUBS },
10491 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubsws", ALTIVEC_BUILTIN_VEC_VSUBSWS },
10492 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuws", ALTIVEC_BUILTIN_VEC_VSUBUWS },
10493 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubshs", ALTIVEC_BUILTIN_VEC_VSUBSHS },
10494 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuhs", ALTIVEC_BUILTIN_VEC_VSUBUHS },
10495 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubsbs", ALTIVEC_BUILTIN_VEC_VSUBSBS },
10496 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsububs", ALTIVEC_BUILTIN_VEC_VSUBUBS },
10497 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sum4s", ALTIVEC_BUILTIN_VEC_SUM4S },
10498 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4shs", ALTIVEC_BUILTIN_VEC_VSUM4SHS },
10499 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4sbs", ALTIVEC_BUILTIN_VEC_VSUM4SBS },
10500 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4ubs", ALTIVEC_BUILTIN_VEC_VSUM4UBS },
10501 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sum2s", ALTIVEC_BUILTIN_VEC_SUM2S },
10502 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sums", ALTIVEC_BUILTIN_VEC_SUMS },
10503 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_xor", ALTIVEC_BUILTIN_VEC_XOR },
10505 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_mul", VSX_BUILTIN_VEC_MUL },
10506 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_div", VSX_BUILTIN_VEC_DIV },
10508 { 0, CODE_FOR_paired_divv2sf3, "__builtin_paired_divv2sf3", PAIRED_BUILTIN_DIVV2SF3 },
10509 { 0, CODE_FOR_paired_addv2sf3, "__builtin_paired_addv2sf3", PAIRED_BUILTIN_ADDV2SF3 },
10510 { 0, CODE_FOR_paired_subv2sf3, "__builtin_paired_subv2sf3", PAIRED_BUILTIN_SUBV2SF3 },
10511 { 0, CODE_FOR_paired_mulv2sf3, "__builtin_paired_mulv2sf3", PAIRED_BUILTIN_MULV2SF3 },
10512 { 0, CODE_FOR_paired_muls0, "__builtin_paired_muls0", PAIRED_BUILTIN_MULS0 },
10513 { 0, CODE_FOR_paired_muls1, "__builtin_paired_muls1", PAIRED_BUILTIN_MULS1 },
10514 { 0, CODE_FOR_paired_merge00, "__builtin_paired_merge00", PAIRED_BUILTIN_MERGE00 },
10515 { 0, CODE_FOR_paired_merge01, "__builtin_paired_merge01", PAIRED_BUILTIN_MERGE01 },
10516 { 0, CODE_FOR_paired_merge10, "__builtin_paired_merge10", PAIRED_BUILTIN_MERGE10 },
10517 { 0, CODE_FOR_paired_merge11, "__builtin_paired_merge11", PAIRED_BUILTIN_MERGE11 },
10519 /* Place holder, leave as first spe builtin. */
10520 { 0, CODE_FOR_addv2si3, "__builtin_spe_evaddw", SPE_BUILTIN_EVADDW },
10521 { 0, CODE_FOR_andv2si3, "__builtin_spe_evand", SPE_BUILTIN_EVAND },
10522 { 0, CODE_FOR_spe_evandc, "__builtin_spe_evandc", SPE_BUILTIN_EVANDC },
10523 { 0, CODE_FOR_divv2si3, "__builtin_spe_evdivws", SPE_BUILTIN_EVDIVWS },
10524 { 0, CODE_FOR_spe_evdivwu, "__builtin_spe_evdivwu", SPE_BUILTIN_EVDIVWU },
10525 { 0, CODE_FOR_spe_eveqv, "__builtin_spe_eveqv", SPE_BUILTIN_EVEQV },
10526 { 0, CODE_FOR_spe_evfsadd, "__builtin_spe_evfsadd", SPE_BUILTIN_EVFSADD },
10527 { 0, CODE_FOR_spe_evfsdiv, "__builtin_spe_evfsdiv", SPE_BUILTIN_EVFSDIV },
10528 { 0, CODE_FOR_spe_evfsmul, "__builtin_spe_evfsmul", SPE_BUILTIN_EVFSMUL },
10529 { 0, CODE_FOR_spe_evfssub, "__builtin_spe_evfssub", SPE_BUILTIN_EVFSSUB },
10530 { 0, CODE_FOR_spe_evmergehi, "__builtin_spe_evmergehi", SPE_BUILTIN_EVMERGEHI },
10531 { 0, CODE_FOR_spe_evmergehilo, "__builtin_spe_evmergehilo", SPE_BUILTIN_EVMERGEHILO },
10532 { 0, CODE_FOR_spe_evmergelo, "__builtin_spe_evmergelo", SPE_BUILTIN_EVMERGELO },
10533 { 0, CODE_FOR_spe_evmergelohi, "__builtin_spe_evmergelohi", SPE_BUILTIN_EVMERGELOHI },
10534 { 0, CODE_FOR_spe_evmhegsmfaa, "__builtin_spe_evmhegsmfaa", SPE_BUILTIN_EVMHEGSMFAA },
10535 { 0, CODE_FOR_spe_evmhegsmfan, "__builtin_spe_evmhegsmfan", SPE_BUILTIN_EVMHEGSMFAN },
10536 { 0, CODE_FOR_spe_evmhegsmiaa, "__builtin_spe_evmhegsmiaa", SPE_BUILTIN_EVMHEGSMIAA },
10537 { 0, CODE_FOR_spe_evmhegsmian, "__builtin_spe_evmhegsmian", SPE_BUILTIN_EVMHEGSMIAN },
10538 { 0, CODE_FOR_spe_evmhegumiaa, "__builtin_spe_evmhegumiaa", SPE_BUILTIN_EVMHEGUMIAA },
10539 { 0, CODE_FOR_spe_evmhegumian, "__builtin_spe_evmhegumian", SPE_BUILTIN_EVMHEGUMIAN },
10540 { 0, CODE_FOR_spe_evmhesmf, "__builtin_spe_evmhesmf", SPE_BUILTIN_EVMHESMF },
10541 { 0, CODE_FOR_spe_evmhesmfa, "__builtin_spe_evmhesmfa", SPE_BUILTIN_EVMHESMFA },
10542 { 0, CODE_FOR_spe_evmhesmfaaw, "__builtin_spe_evmhesmfaaw", SPE_BUILTIN_EVMHESMFAAW },
10543 { 0, CODE_FOR_spe_evmhesmfanw, "__builtin_spe_evmhesmfanw", SPE_BUILTIN_EVMHESMFANW },
10544 { 0, CODE_FOR_spe_evmhesmi, "__builtin_spe_evmhesmi", SPE_BUILTIN_EVMHESMI },
10545 { 0, CODE_FOR_spe_evmhesmia, "__builtin_spe_evmhesmia", SPE_BUILTIN_EVMHESMIA },
10546 { 0, CODE_FOR_spe_evmhesmiaaw, "__builtin_spe_evmhesmiaaw", SPE_BUILTIN_EVMHESMIAAW },
10547 { 0, CODE_FOR_spe_evmhesmianw, "__builtin_spe_evmhesmianw", SPE_BUILTIN_EVMHESMIANW },
10548 { 0, CODE_FOR_spe_evmhessf, "__builtin_spe_evmhessf", SPE_BUILTIN_EVMHESSF },
10549 { 0, CODE_FOR_spe_evmhessfa, "__builtin_spe_evmhessfa", SPE_BUILTIN_EVMHESSFA },
10550 { 0, CODE_FOR_spe_evmhessfaaw, "__builtin_spe_evmhessfaaw", SPE_BUILTIN_EVMHESSFAAW },
10551 { 0, CODE_FOR_spe_evmhessfanw, "__builtin_spe_evmhessfanw", SPE_BUILTIN_EVMHESSFANW },
10552 { 0, CODE_FOR_spe_evmhessiaaw, "__builtin_spe_evmhessiaaw", SPE_BUILTIN_EVMHESSIAAW },
10553 { 0, CODE_FOR_spe_evmhessianw, "__builtin_spe_evmhessianw", SPE_BUILTIN_EVMHESSIANW },
10554 { 0, CODE_FOR_spe_evmheumi, "__builtin_spe_evmheumi", SPE_BUILTIN_EVMHEUMI },
10555 { 0, CODE_FOR_spe_evmheumia, "__builtin_spe_evmheumia", SPE_BUILTIN_EVMHEUMIA },
10556 { 0, CODE_FOR_spe_evmheumiaaw, "__builtin_spe_evmheumiaaw", SPE_BUILTIN_EVMHEUMIAAW },
10557 { 0, CODE_FOR_spe_evmheumianw, "__builtin_spe_evmheumianw", SPE_BUILTIN_EVMHEUMIANW },
10558 { 0, CODE_FOR_spe_evmheusiaaw, "__builtin_spe_evmheusiaaw", SPE_BUILTIN_EVMHEUSIAAW },
10559 { 0, CODE_FOR_spe_evmheusianw, "__builtin_spe_evmheusianw", SPE_BUILTIN_EVMHEUSIANW },
10560 { 0, CODE_FOR_spe_evmhogsmfaa, "__builtin_spe_evmhogsmfaa", SPE_BUILTIN_EVMHOGSMFAA },
10561 { 0, CODE_FOR_spe_evmhogsmfan, "__builtin_spe_evmhogsmfan", SPE_BUILTIN_EVMHOGSMFAN },
10562 { 0, CODE_FOR_spe_evmhogsmiaa, "__builtin_spe_evmhogsmiaa", SPE_BUILTIN_EVMHOGSMIAA },
10563 { 0, CODE_FOR_spe_evmhogsmian, "__builtin_spe_evmhogsmian", SPE_BUILTIN_EVMHOGSMIAN },
10564 { 0, CODE_FOR_spe_evmhogumiaa, "__builtin_spe_evmhogumiaa", SPE_BUILTIN_EVMHOGUMIAA },
10565 { 0, CODE_FOR_spe_evmhogumian, "__builtin_spe_evmhogumian", SPE_BUILTIN_EVMHOGUMIAN },
10566 { 0, CODE_FOR_spe_evmhosmf, "__builtin_spe_evmhosmf", SPE_BUILTIN_EVMHOSMF },
10567 { 0, CODE_FOR_spe_evmhosmfa, "__builtin_spe_evmhosmfa", SPE_BUILTIN_EVMHOSMFA },
10568 { 0, CODE_FOR_spe_evmhosmfaaw, "__builtin_spe_evmhosmfaaw", SPE_BUILTIN_EVMHOSMFAAW },
10569 { 0, CODE_FOR_spe_evmhosmfanw, "__builtin_spe_evmhosmfanw", SPE_BUILTIN_EVMHOSMFANW },
10570 { 0, CODE_FOR_spe_evmhosmi, "__builtin_spe_evmhosmi", SPE_BUILTIN_EVMHOSMI },
10571 { 0, CODE_FOR_spe_evmhosmia, "__builtin_spe_evmhosmia", SPE_BUILTIN_EVMHOSMIA },
10572 { 0, CODE_FOR_spe_evmhosmiaaw, "__builtin_spe_evmhosmiaaw", SPE_BUILTIN_EVMHOSMIAAW },
10573 { 0, CODE_FOR_spe_evmhosmianw, "__builtin_spe_evmhosmianw", SPE_BUILTIN_EVMHOSMIANW },
10574 { 0, CODE_FOR_spe_evmhossf, "__builtin_spe_evmhossf", SPE_BUILTIN_EVMHOSSF },
10575 { 0, CODE_FOR_spe_evmhossfa, "__builtin_spe_evmhossfa", SPE_BUILTIN_EVMHOSSFA },
10576 { 0, CODE_FOR_spe_evmhossfaaw, "__builtin_spe_evmhossfaaw", SPE_BUILTIN_EVMHOSSFAAW },
10577 { 0, CODE_FOR_spe_evmhossfanw, "__builtin_spe_evmhossfanw", SPE_BUILTIN_EVMHOSSFANW },
10578 { 0, CODE_FOR_spe_evmhossiaaw, "__builtin_spe_evmhossiaaw", SPE_BUILTIN_EVMHOSSIAAW },
10579 { 0, CODE_FOR_spe_evmhossianw, "__builtin_spe_evmhossianw", SPE_BUILTIN_EVMHOSSIANW },
10580 { 0, CODE_FOR_spe_evmhoumi, "__builtin_spe_evmhoumi", SPE_BUILTIN_EVMHOUMI },
10581 { 0, CODE_FOR_spe_evmhoumia, "__builtin_spe_evmhoumia", SPE_BUILTIN_EVMHOUMIA },
10582 { 0, CODE_FOR_spe_evmhoumiaaw, "__builtin_spe_evmhoumiaaw", SPE_BUILTIN_EVMHOUMIAAW },
10583 { 0, CODE_FOR_spe_evmhoumianw, "__builtin_spe_evmhoumianw", SPE_BUILTIN_EVMHOUMIANW },
10584 { 0, CODE_FOR_spe_evmhousiaaw, "__builtin_spe_evmhousiaaw", SPE_BUILTIN_EVMHOUSIAAW },
10585 { 0, CODE_FOR_spe_evmhousianw, "__builtin_spe_evmhousianw", SPE_BUILTIN_EVMHOUSIANW },
10586 { 0, CODE_FOR_spe_evmwhsmf, "__builtin_spe_evmwhsmf", SPE_BUILTIN_EVMWHSMF },
10587 { 0, CODE_FOR_spe_evmwhsmfa, "__builtin_spe_evmwhsmfa", SPE_BUILTIN_EVMWHSMFA },
10588 { 0, CODE_FOR_spe_evmwhsmi, "__builtin_spe_evmwhsmi", SPE_BUILTIN_EVMWHSMI },
10589 { 0, CODE_FOR_spe_evmwhsmia, "__builtin_spe_evmwhsmia", SPE_BUILTIN_EVMWHSMIA },
10590 { 0, CODE_FOR_spe_evmwhssf, "__builtin_spe_evmwhssf", SPE_BUILTIN_EVMWHSSF },
10591 { 0, CODE_FOR_spe_evmwhssfa, "__builtin_spe_evmwhssfa", SPE_BUILTIN_EVMWHSSFA },
10592 { 0, CODE_FOR_spe_evmwhumi, "__builtin_spe_evmwhumi", SPE_BUILTIN_EVMWHUMI },
10593 { 0, CODE_FOR_spe_evmwhumia, "__builtin_spe_evmwhumia", SPE_BUILTIN_EVMWHUMIA },
10594 { 0, CODE_FOR_spe_evmwlsmiaaw, "__builtin_spe_evmwlsmiaaw", SPE_BUILTIN_EVMWLSMIAAW },
10595 { 0, CODE_FOR_spe_evmwlsmianw, "__builtin_spe_evmwlsmianw", SPE_BUILTIN_EVMWLSMIANW },
10596 { 0, CODE_FOR_spe_evmwlssiaaw, "__builtin_spe_evmwlssiaaw", SPE_BUILTIN_EVMWLSSIAAW },
10597 { 0, CODE_FOR_spe_evmwlssianw, "__builtin_spe_evmwlssianw", SPE_BUILTIN_EVMWLSSIANW },
10598 { 0, CODE_FOR_spe_evmwlumi, "__builtin_spe_evmwlumi", SPE_BUILTIN_EVMWLUMI },
10599 { 0, CODE_FOR_spe_evmwlumia, "__builtin_spe_evmwlumia", SPE_BUILTIN_EVMWLUMIA },
10600 { 0, CODE_FOR_spe_evmwlumiaaw, "__builtin_spe_evmwlumiaaw", SPE_BUILTIN_EVMWLUMIAAW },
10601 { 0, CODE_FOR_spe_evmwlumianw, "__builtin_spe_evmwlumianw", SPE_BUILTIN_EVMWLUMIANW },
10602 { 0, CODE_FOR_spe_evmwlusiaaw, "__builtin_spe_evmwlusiaaw", SPE_BUILTIN_EVMWLUSIAAW },
10603 { 0, CODE_FOR_spe_evmwlusianw, "__builtin_spe_evmwlusianw", SPE_BUILTIN_EVMWLUSIANW },
10604 { 0, CODE_FOR_spe_evmwsmf, "__builtin_spe_evmwsmf", SPE_BUILTIN_EVMWSMF },
10605 { 0, CODE_FOR_spe_evmwsmfa, "__builtin_spe_evmwsmfa", SPE_BUILTIN_EVMWSMFA },
10606 { 0, CODE_FOR_spe_evmwsmfaa, "__builtin_spe_evmwsmfaa", SPE_BUILTIN_EVMWSMFAA },
10607 { 0, CODE_FOR_spe_evmwsmfan, "__builtin_spe_evmwsmfan", SPE_BUILTIN_EVMWSMFAN },
10608 { 0, CODE_FOR_spe_evmwsmi, "__builtin_spe_evmwsmi", SPE_BUILTIN_EVMWSMI },
10609 { 0, CODE_FOR_spe_evmwsmia, "__builtin_spe_evmwsmia", SPE_BUILTIN_EVMWSMIA },
10610 { 0, CODE_FOR_spe_evmwsmiaa, "__builtin_spe_evmwsmiaa", SPE_BUILTIN_EVMWSMIAA },
10611 { 0, CODE_FOR_spe_evmwsmian, "__builtin_spe_evmwsmian", SPE_BUILTIN_EVMWSMIAN },
10612 { 0, CODE_FOR_spe_evmwssf, "__builtin_spe_evmwssf", SPE_BUILTIN_EVMWSSF },
10613 { 0, CODE_FOR_spe_evmwssfa, "__builtin_spe_evmwssfa", SPE_BUILTIN_EVMWSSFA },
10614 { 0, CODE_FOR_spe_evmwssfaa, "__builtin_spe_evmwssfaa", SPE_BUILTIN_EVMWSSFAA },
10615 { 0, CODE_FOR_spe_evmwssfan, "__builtin_spe_evmwssfan", SPE_BUILTIN_EVMWSSFAN },
10616 { 0, CODE_FOR_spe_evmwumi, "__builtin_spe_evmwumi", SPE_BUILTIN_EVMWUMI },
10617 { 0, CODE_FOR_spe_evmwumia, "__builtin_spe_evmwumia", SPE_BUILTIN_EVMWUMIA },
10618 { 0, CODE_FOR_spe_evmwumiaa, "__builtin_spe_evmwumiaa", SPE_BUILTIN_EVMWUMIAA },
10619 { 0, CODE_FOR_spe_evmwumian, "__builtin_spe_evmwumian", SPE_BUILTIN_EVMWUMIAN },
10620 { 0, CODE_FOR_spe_evnand, "__builtin_spe_evnand", SPE_BUILTIN_EVNAND },
10621 { 0, CODE_FOR_spe_evnor, "__builtin_spe_evnor", SPE_BUILTIN_EVNOR },
10622 { 0, CODE_FOR_spe_evor, "__builtin_spe_evor", SPE_BUILTIN_EVOR },
10623 { 0, CODE_FOR_spe_evorc, "__builtin_spe_evorc", SPE_BUILTIN_EVORC },
10624 { 0, CODE_FOR_spe_evrlw, "__builtin_spe_evrlw", SPE_BUILTIN_EVRLW },
10625 { 0, CODE_FOR_spe_evslw, "__builtin_spe_evslw", SPE_BUILTIN_EVSLW },
10626 { 0, CODE_FOR_spe_evsrws, "__builtin_spe_evsrws", SPE_BUILTIN_EVSRWS },
10627 { 0, CODE_FOR_spe_evsrwu, "__builtin_spe_evsrwu", SPE_BUILTIN_EVSRWU },
10628 { 0, CODE_FOR_subv2si3, "__builtin_spe_evsubfw", SPE_BUILTIN_EVSUBFW },
10630 /* SPE binary operations expecting a 5-bit unsigned literal. */
10631 { 0, CODE_FOR_spe_evaddiw, "__builtin_spe_evaddiw", SPE_BUILTIN_EVADDIW },
10633 { 0, CODE_FOR_spe_evrlwi, "__builtin_spe_evrlwi", SPE_BUILTIN_EVRLWI },
10634 { 0, CODE_FOR_spe_evslwi, "__builtin_spe_evslwi", SPE_BUILTIN_EVSLWI },
10635 { 0, CODE_FOR_spe_evsrwis, "__builtin_spe_evsrwis", SPE_BUILTIN_EVSRWIS },
10636 { 0, CODE_FOR_spe_evsrwiu, "__builtin_spe_evsrwiu", SPE_BUILTIN_EVSRWIU },
10637 { 0, CODE_FOR_spe_evsubifw, "__builtin_spe_evsubifw", SPE_BUILTIN_EVSUBIFW },
10638 { 0, CODE_FOR_spe_evmwhssfaa, "__builtin_spe_evmwhssfaa", SPE_BUILTIN_EVMWHSSFAA },
10639 { 0, CODE_FOR_spe_evmwhssmaa, "__builtin_spe_evmwhssmaa", SPE_BUILTIN_EVMWHSSMAA },
10640 { 0, CODE_FOR_spe_evmwhsmfaa, "__builtin_spe_evmwhsmfaa", SPE_BUILTIN_EVMWHSMFAA },
10641 { 0, CODE_FOR_spe_evmwhsmiaa, "__builtin_spe_evmwhsmiaa", SPE_BUILTIN_EVMWHSMIAA },
10642 { 0, CODE_FOR_spe_evmwhusiaa, "__builtin_spe_evmwhusiaa", SPE_BUILTIN_EVMWHUSIAA },
10643 { 0, CODE_FOR_spe_evmwhumiaa, "__builtin_spe_evmwhumiaa", SPE_BUILTIN_EVMWHUMIAA },
10644 { 0, CODE_FOR_spe_evmwhssfan, "__builtin_spe_evmwhssfan", SPE_BUILTIN_EVMWHSSFAN },
10645 { 0, CODE_FOR_spe_evmwhssian, "__builtin_spe_evmwhssian", SPE_BUILTIN_EVMWHSSIAN },
10646 { 0, CODE_FOR_spe_evmwhsmfan, "__builtin_spe_evmwhsmfan", SPE_BUILTIN_EVMWHSMFAN },
10647 { 0, CODE_FOR_spe_evmwhsmian, "__builtin_spe_evmwhsmian", SPE_BUILTIN_EVMWHSMIAN },
10648 { 0, CODE_FOR_spe_evmwhusian, "__builtin_spe_evmwhusian", SPE_BUILTIN_EVMWHUSIAN },
10649 { 0, CODE_FOR_spe_evmwhumian, "__builtin_spe_evmwhumian", SPE_BUILTIN_EVMWHUMIAN },
10650 { 0, CODE_FOR_spe_evmwhgssfaa, "__builtin_spe_evmwhgssfaa", SPE_BUILTIN_EVMWHGSSFAA },
10651 { 0, CODE_FOR_spe_evmwhgsmfaa, "__builtin_spe_evmwhgsmfaa", SPE_BUILTIN_EVMWHGSMFAA },
10652 { 0, CODE_FOR_spe_evmwhgsmiaa, "__builtin_spe_evmwhgsmiaa", SPE_BUILTIN_EVMWHGSMIAA },
10653 { 0, CODE_FOR_spe_evmwhgumiaa, "__builtin_spe_evmwhgumiaa", SPE_BUILTIN_EVMWHGUMIAA },
10654 { 0, CODE_FOR_spe_evmwhgssfan, "__builtin_spe_evmwhgssfan", SPE_BUILTIN_EVMWHGSSFAN },
10655 { 0, CODE_FOR_spe_evmwhgsmfan, "__builtin_spe_evmwhgsmfan", SPE_BUILTIN_EVMWHGSMFAN },
10656 { 0, CODE_FOR_spe_evmwhgsmian, "__builtin_spe_evmwhgsmian", SPE_BUILTIN_EVMWHGSMIAN },
10657 { 0, CODE_FOR_spe_evmwhgumian, "__builtin_spe_evmwhgumian", SPE_BUILTIN_EVMWHGUMIAN },
10658 { 0, CODE_FOR_spe_brinc, "__builtin_spe_brinc", SPE_BUILTIN_BRINC },
10660 /* Place-holder. Leave as last binary SPE builtin. */
10661 { 0, CODE_FOR_xorv2si3, "__builtin_spe_evxor", SPE_BUILTIN_EVXOR }
10664 /* AltiVec predicates. */
10666 struct builtin_description_predicates
10668 const unsigned int mask;
10669 const enum insn_code icode;
10670 const char *const name;
10671 const enum rs6000_builtins code;
10674 static const struct builtin_description_predicates bdesc_altivec_preds[] =
10676 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpbfp_p, "__builtin_altivec_vcmpbfp_p",
10677 ALTIVEC_BUILTIN_VCMPBFP_P },
10678 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_eq_v4sf_p,
10679 "__builtin_altivec_vcmpeqfp_p", ALTIVEC_BUILTIN_VCMPEQFP_P },
10680 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_ge_v4sf_p,
10681 "__builtin_altivec_vcmpgefp_p", ALTIVEC_BUILTIN_VCMPGEFP_P },
10682 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_gt_v4sf_p,
10683 "__builtin_altivec_vcmpgtfp_p", ALTIVEC_BUILTIN_VCMPGTFP_P },
10684 { MASK_ALTIVEC, CODE_FOR_vector_eq_v4si_p, "__builtin_altivec_vcmpequw_p",
10685 ALTIVEC_BUILTIN_VCMPEQUW_P },
10686 { MASK_ALTIVEC, CODE_FOR_vector_gt_v4si_p, "__builtin_altivec_vcmpgtsw_p",
10687 ALTIVEC_BUILTIN_VCMPGTSW_P },
10688 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v4si_p, "__builtin_altivec_vcmpgtuw_p",
10689 ALTIVEC_BUILTIN_VCMPGTUW_P },
10690 { MASK_ALTIVEC, CODE_FOR_vector_eq_v8hi_p, "__builtin_altivec_vcmpequh_p",
10691 ALTIVEC_BUILTIN_VCMPEQUH_P },
10692 { MASK_ALTIVEC, CODE_FOR_vector_gt_v8hi_p, "__builtin_altivec_vcmpgtsh_p",
10693 ALTIVEC_BUILTIN_VCMPGTSH_P },
10694 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v8hi_p, "__builtin_altivec_vcmpgtuh_p",
10695 ALTIVEC_BUILTIN_VCMPGTUH_P },
10696 { MASK_ALTIVEC, CODE_FOR_vector_eq_v16qi_p, "__builtin_altivec_vcmpequb_p",
10697 ALTIVEC_BUILTIN_VCMPEQUB_P },
10698 { MASK_ALTIVEC, CODE_FOR_vector_gt_v16qi_p, "__builtin_altivec_vcmpgtsb_p",
10699 ALTIVEC_BUILTIN_VCMPGTSB_P },
10700 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v16qi_p, "__builtin_altivec_vcmpgtub_p",
10701 ALTIVEC_BUILTIN_VCMPGTUB_P },
10703 { MASK_VSX, CODE_FOR_vector_eq_v4sf_p, "__builtin_vsx_xvcmpeqsp_p",
10704 VSX_BUILTIN_XVCMPEQSP_P },
10705 { MASK_VSX, CODE_FOR_vector_ge_v4sf_p, "__builtin_vsx_xvcmpgesp_p",
10706 VSX_BUILTIN_XVCMPGESP_P },
10707 { MASK_VSX, CODE_FOR_vector_gt_v4sf_p, "__builtin_vsx_xvcmpgtsp_p",
10708 VSX_BUILTIN_XVCMPGTSP_P },
10709 { MASK_VSX, CODE_FOR_vector_eq_v2df_p, "__builtin_vsx_xvcmpeqdp_p",
10710 VSX_BUILTIN_XVCMPEQDP_P },
10711 { MASK_VSX, CODE_FOR_vector_ge_v2df_p, "__builtin_vsx_xvcmpgedp_p",
10712 VSX_BUILTIN_XVCMPGEDP_P },
10713 { MASK_VSX, CODE_FOR_vector_gt_v2df_p, "__builtin_vsx_xvcmpgtdp_p",
10714 VSX_BUILTIN_XVCMPGTDP_P },
10716 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpeq_p",
10717 ALTIVEC_BUILTIN_VCMPEQ_P },
10718 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpgt_p",
10719 ALTIVEC_BUILTIN_VCMPGT_P },
10720 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpge_p",
10721 ALTIVEC_BUILTIN_VCMPGE_P }
10724 /* SPE predicates. */
10725 static struct builtin_description bdesc_spe_predicates[] =
10727 /* Place-holder. Leave as first. */
10728 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evcmpeq", SPE_BUILTIN_EVCMPEQ },
10729 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evcmpgts", SPE_BUILTIN_EVCMPGTS },
10730 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evcmpgtu", SPE_BUILTIN_EVCMPGTU },
10731 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evcmplts", SPE_BUILTIN_EVCMPLTS },
10732 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evcmpltu", SPE_BUILTIN_EVCMPLTU },
10733 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evfscmpeq", SPE_BUILTIN_EVFSCMPEQ },
10734 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evfscmpgt", SPE_BUILTIN_EVFSCMPGT },
10735 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evfscmplt", SPE_BUILTIN_EVFSCMPLT },
10736 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evfststeq", SPE_BUILTIN_EVFSTSTEQ },
10737 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evfststgt", SPE_BUILTIN_EVFSTSTGT },
10738 /* Place-holder. Leave as last. */
10739 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evfststlt", SPE_BUILTIN_EVFSTSTLT },
10742 /* SPE evsel predicates. */
10743 static struct builtin_description bdesc_spe_evsel[] =
10745 /* Place-holder. Leave as first. */
10746 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evsel_gts", SPE_BUILTIN_EVSEL_CMPGTS },
10747 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evsel_gtu", SPE_BUILTIN_EVSEL_CMPGTU },
10748 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evsel_lts", SPE_BUILTIN_EVSEL_CMPLTS },
10749 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evsel_ltu", SPE_BUILTIN_EVSEL_CMPLTU },
10750 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evsel_eq", SPE_BUILTIN_EVSEL_CMPEQ },
10751 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evsel_fsgt", SPE_BUILTIN_EVSEL_FSCMPGT },
10752 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evsel_fslt", SPE_BUILTIN_EVSEL_FSCMPLT },
10753 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evsel_fseq", SPE_BUILTIN_EVSEL_FSCMPEQ },
10754 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evsel_fststgt", SPE_BUILTIN_EVSEL_FSTSTGT },
10755 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evsel_fststlt", SPE_BUILTIN_EVSEL_FSTSTLT },
10756 /* Place-holder. Leave as last. */
10757 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evsel_fststeq", SPE_BUILTIN_EVSEL_FSTSTEQ },
10760 /* PAIRED predicates. */
10761 static const struct builtin_description bdesc_paired_preds[] =
10763 /* Place-holder. Leave as first. */
10764 { 0, CODE_FOR_paired_cmpu0, "__builtin_paired_cmpu0", PAIRED_BUILTIN_CMPU0 },
10765 /* Place-holder. Leave as last. */
10766 { 0, CODE_FOR_paired_cmpu1, "__builtin_paired_cmpu1", PAIRED_BUILTIN_CMPU1 },
10769 /* ABS* operations. */
10771 static const struct builtin_description bdesc_abs[] =
10773 { MASK_ALTIVEC, CODE_FOR_absv4si2, "__builtin_altivec_abs_v4si", ALTIVEC_BUILTIN_ABS_V4SI },
10774 { MASK_ALTIVEC, CODE_FOR_absv8hi2, "__builtin_altivec_abs_v8hi", ALTIVEC_BUILTIN_ABS_V8HI },
10775 { MASK_ALTIVEC, CODE_FOR_absv4sf2, "__builtin_altivec_abs_v4sf", ALTIVEC_BUILTIN_ABS_V4SF },
10776 { MASK_ALTIVEC, CODE_FOR_absv16qi2, "__builtin_altivec_abs_v16qi", ALTIVEC_BUILTIN_ABS_V16QI },
10777 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v4si, "__builtin_altivec_abss_v4si", ALTIVEC_BUILTIN_ABSS_V4SI },
10778 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v8hi, "__builtin_altivec_abss_v8hi", ALTIVEC_BUILTIN_ABSS_V8HI },
10779 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v16qi, "__builtin_altivec_abss_v16qi", ALTIVEC_BUILTIN_ABSS_V16QI },
10780 { MASK_VSX, CODE_FOR_absv2df2, "__builtin_vsx_xvabsdp", VSX_BUILTIN_XVABSDP },
10781 { MASK_VSX, CODE_FOR_vsx_nabsv2df2, "__builtin_vsx_xvnabsdp", VSX_BUILTIN_XVNABSDP },
10782 { MASK_VSX, CODE_FOR_absv4sf2, "__builtin_vsx_xvabssp", VSX_BUILTIN_XVABSSP },
10783 { MASK_VSX, CODE_FOR_vsx_nabsv4sf2, "__builtin_vsx_xvnabssp", VSX_BUILTIN_XVNABSSP },
10786 /* Simple unary operations: VECb = foo (unsigned literal) or VECb =
10787 foo (VECa). */
10789 static struct builtin_description bdesc_1arg[] =
10791 { MASK_ALTIVEC, CODE_FOR_altivec_vexptefp, "__builtin_altivec_vexptefp", ALTIVEC_BUILTIN_VEXPTEFP },
10792 { MASK_ALTIVEC, CODE_FOR_altivec_vlogefp, "__builtin_altivec_vlogefp", ALTIVEC_BUILTIN_VLOGEFP },
10793 { MASK_ALTIVEC, CODE_FOR_rev4sf2, "__builtin_altivec_vrefp", ALTIVEC_BUILTIN_VREFP },
10794 { MASK_ALTIVEC, CODE_FOR_vector_floorv4sf2, "__builtin_altivec_vrfim", ALTIVEC_BUILTIN_VRFIM },
10795 { MASK_ALTIVEC, CODE_FOR_altivec_vrfin, "__builtin_altivec_vrfin", ALTIVEC_BUILTIN_VRFIN },
10796 { MASK_ALTIVEC, CODE_FOR_vector_ceilv4sf2, "__builtin_altivec_vrfip", ALTIVEC_BUILTIN_VRFIP },
10797 { MASK_ALTIVEC, CODE_FOR_vector_btruncv4sf2, "__builtin_altivec_vrfiz", ALTIVEC_BUILTIN_VRFIZ },
10798 { MASK_ALTIVEC, CODE_FOR_rsqrtv4sf2, "__builtin_altivec_vrsqrtfp", ALTIVEC_BUILTIN_VRSQRTFP },
10799 { MASK_ALTIVEC, CODE_FOR_rsqrtev4sf2, "__builtin_altivec_vrsqrtefp", ALTIVEC_BUILTIN_VRSQRTEFP },
10800 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisb, "__builtin_altivec_vspltisb", ALTIVEC_BUILTIN_VSPLTISB },
10801 { MASK_ALTIVEC, CODE_FOR_altivec_vspltish, "__builtin_altivec_vspltish", ALTIVEC_BUILTIN_VSPLTISH },
10802 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisw, "__builtin_altivec_vspltisw", ALTIVEC_BUILTIN_VSPLTISW },
10803 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsb, "__builtin_altivec_vupkhsb", ALTIVEC_BUILTIN_VUPKHSB },
10804 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhpx, "__builtin_altivec_vupkhpx", ALTIVEC_BUILTIN_VUPKHPX },
10805 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsh, "__builtin_altivec_vupkhsh", ALTIVEC_BUILTIN_VUPKHSH },
10806 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsb, "__builtin_altivec_vupklsb", ALTIVEC_BUILTIN_VUPKLSB },
10807 { MASK_ALTIVEC, CODE_FOR_altivec_vupklpx, "__builtin_altivec_vupklpx", ALTIVEC_BUILTIN_VUPKLPX },
10808 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsh, "__builtin_altivec_vupklsh", ALTIVEC_BUILTIN_VUPKLSH },
10810 { MASK_VSX, CODE_FOR_negv2df2, "__builtin_vsx_xvnegdp", VSX_BUILTIN_XVNEGDP },
10811 { MASK_VSX, CODE_FOR_sqrtv2df2, "__builtin_vsx_xvsqrtdp", VSX_BUILTIN_XVSQRTDP },
10812 { MASK_VSX, CODE_FOR_rsqrtv2df2, "__builtin_vsx_xvrsqrtdp", VSX_BUILTIN_VEC_RSQRT_V2DF },
10813 { MASK_VSX, CODE_FOR_rsqrtev2df2, "__builtin_vsx_xvrsqrtedp", VSX_BUILTIN_XVRSQRTEDP },
10814 { MASK_VSX, CODE_FOR_vsx_tsqrtv2df2_fe, "__builtin_vsx_xvtsqrtdp_fe", VSX_BUILTIN_XVTSQRTDP_FE },
10815 { MASK_VSX, CODE_FOR_vsx_tsqrtv2df2_fg, "__builtin_vsx_xvtsqrtdp_fg", VSX_BUILTIN_XVTSQRTDP_FG },
10816 { MASK_VSX, CODE_FOR_vsx_frev2df2, "__builtin_vsx_xvredp", VSX_BUILTIN_XVREDP },
10818 { MASK_VSX, CODE_FOR_negv4sf2, "__builtin_vsx_xvnegsp", VSX_BUILTIN_XVNEGSP },
10819 { MASK_VSX, CODE_FOR_sqrtv4sf2, "__builtin_vsx_xvsqrtsp", VSX_BUILTIN_XVSQRTSP },
10820 { MASK_VSX, CODE_FOR_rsqrtv4sf2, "__builtin_vsx_xvrsqrtsp", VSX_BUILTIN_VEC_RSQRT_V4SF },
10821 { MASK_VSX, CODE_FOR_rsqrtev4sf2, "__builtin_vsx_xvrsqrtesp", VSX_BUILTIN_XVRSQRTESP },
10822 { MASK_VSX, CODE_FOR_vsx_tsqrtv4sf2_fe, "__builtin_vsx_xvtsqrtsp_fe", VSX_BUILTIN_XVTSQRTSP_FE },
10823 { MASK_VSX, CODE_FOR_vsx_tsqrtv4sf2_fg, "__builtin_vsx_xvtsqrtsp_fg", VSX_BUILTIN_XVTSQRTSP_FG },
10824 { MASK_VSX, CODE_FOR_vsx_frev4sf2, "__builtin_vsx_xvresp", VSX_BUILTIN_XVRESP },
10826 { MASK_VSX, CODE_FOR_vsx_xscvdpsp, "__builtin_vsx_xscvdpsp", VSX_BUILTIN_XSCVDPSP },
10827 { MASK_VSX, CODE_FOR_vsx_xscvdpsp, "__builtin_vsx_xscvspdp", VSX_BUILTIN_XSCVSPDP },
10828 { MASK_VSX, CODE_FOR_vsx_xvcvdpsp, "__builtin_vsx_xvcvdpsp", VSX_BUILTIN_XVCVDPSP },
10829 { MASK_VSX, CODE_FOR_vsx_xvcvspdp, "__builtin_vsx_xvcvspdp", VSX_BUILTIN_XVCVSPDP },
10830 { MASK_VSX, CODE_FOR_vsx_tsqrtdf2_fe, "__builtin_vsx_xstsqrtdp_fe", VSX_BUILTIN_XSTSQRTDP_FE },
10831 { MASK_VSX, CODE_FOR_vsx_tsqrtdf2_fg, "__builtin_vsx_xstsqrtdp_fg", VSX_BUILTIN_XSTSQRTDP_FG },
10833 { MASK_VSX, CODE_FOR_vsx_fix_truncv2dfv2di2, "__builtin_vsx_xvcvdpsxds", VSX_BUILTIN_XVCVDPSXDS },
10834 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv2dfv2di2, "__builtin_vsx_xvcvdpuxds", VSX_BUILTIN_XVCVDPUXDS },
10835 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv2dfv2di2, "__builtin_vsx_xvcvdpuxds_uns", VSX_BUILTIN_XVCVDPUXDS_UNS },
10836 { MASK_VSX, CODE_FOR_vsx_floatv2div2df2, "__builtin_vsx_xvcvsxddp", VSX_BUILTIN_XVCVSXDDP },
10837 { MASK_VSX, CODE_FOR_vsx_floatunsv2div2df2, "__builtin_vsx_xvcvuxddp", VSX_BUILTIN_XVCVUXDDP },
10838 { MASK_VSX, CODE_FOR_vsx_floatunsv2div2df2, "__builtin_vsx_xvcvuxddp_uns", VSX_BUILTIN_XVCVUXDDP_UNS },
10840 { MASK_VSX, CODE_FOR_vsx_fix_truncv4sfv4si2, "__builtin_vsx_xvcvspsxws", VSX_BUILTIN_XVCVSPSXWS },
10841 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv4sfv4si2, "__builtin_vsx_xvcvspuxws", VSX_BUILTIN_XVCVSPUXWS },
10842 { MASK_VSX, CODE_FOR_vsx_floatv4siv4sf2, "__builtin_vsx_xvcvsxwsp", VSX_BUILTIN_XVCVSXWSP },
10843 { MASK_VSX, CODE_FOR_vsx_floatunsv4siv4sf2, "__builtin_vsx_xvcvuxwsp", VSX_BUILTIN_XVCVUXWSP },
10845 { MASK_VSX, CODE_FOR_vsx_xvcvdpsxws, "__builtin_vsx_xvcvdpsxws", VSX_BUILTIN_XVCVDPSXWS },
10846 { MASK_VSX, CODE_FOR_vsx_xvcvdpuxws, "__builtin_vsx_xvcvdpuxws", VSX_BUILTIN_XVCVDPUXWS },
10847 { MASK_VSX, CODE_FOR_vsx_xvcvsxwdp, "__builtin_vsx_xvcvsxwdp", VSX_BUILTIN_XVCVSXWDP },
10848 { MASK_VSX, CODE_FOR_vsx_xvcvuxwdp, "__builtin_vsx_xvcvuxwdp", VSX_BUILTIN_XVCVUXWDP },
10849 { MASK_VSX, CODE_FOR_vsx_xvrdpi, "__builtin_vsx_xvrdpi", VSX_BUILTIN_XVRDPI },
10850 { MASK_VSX, CODE_FOR_vsx_xvrdpic, "__builtin_vsx_xvrdpic", VSX_BUILTIN_XVRDPIC },
10851 { MASK_VSX, CODE_FOR_vsx_floorv2df2, "__builtin_vsx_xvrdpim", VSX_BUILTIN_XVRDPIM },
10852 { MASK_VSX, CODE_FOR_vsx_ceilv2df2, "__builtin_vsx_xvrdpip", VSX_BUILTIN_XVRDPIP },
10853 { MASK_VSX, CODE_FOR_vsx_btruncv2df2, "__builtin_vsx_xvrdpiz", VSX_BUILTIN_XVRDPIZ },
10855 { MASK_VSX, CODE_FOR_vsx_xvcvspsxds, "__builtin_vsx_xvcvspsxds", VSX_BUILTIN_XVCVSPSXDS },
10856 { MASK_VSX, CODE_FOR_vsx_xvcvspuxds, "__builtin_vsx_xvcvspuxds", VSX_BUILTIN_XVCVSPUXDS },
10857 { MASK_VSX, CODE_FOR_vsx_xvcvsxdsp, "__builtin_vsx_xvcvsxdsp", VSX_BUILTIN_XVCVSXDSP },
10858 { MASK_VSX, CODE_FOR_vsx_xvcvuxdsp, "__builtin_vsx_xvcvuxdsp", VSX_BUILTIN_XVCVUXDSP },
10859 { MASK_VSX, CODE_FOR_vsx_xvrspi, "__builtin_vsx_xvrspi", VSX_BUILTIN_XVRSPI },
10860 { MASK_VSX, CODE_FOR_vsx_xvrspic, "__builtin_vsx_xvrspic", VSX_BUILTIN_XVRSPIC },
10861 { MASK_VSX, CODE_FOR_vsx_floorv4sf2, "__builtin_vsx_xvrspim", VSX_BUILTIN_XVRSPIM },
10862 { MASK_VSX, CODE_FOR_vsx_ceilv4sf2, "__builtin_vsx_xvrspip", VSX_BUILTIN_XVRSPIP },
10863 { MASK_VSX, CODE_FOR_vsx_btruncv4sf2, "__builtin_vsx_xvrspiz", VSX_BUILTIN_XVRSPIZ },
10865 { MASK_VSX, CODE_FOR_vsx_xsrdpi, "__builtin_vsx_xsrdpi", VSX_BUILTIN_XSRDPI },
10866 { MASK_VSX, CODE_FOR_vsx_xsrdpic, "__builtin_vsx_xsrdpic", VSX_BUILTIN_XSRDPIC },
10867 { MASK_VSX, CODE_FOR_vsx_floordf2, "__builtin_vsx_xsrdpim", VSX_BUILTIN_XSRDPIM },
10868 { MASK_VSX, CODE_FOR_vsx_ceildf2, "__builtin_vsx_xsrdpip", VSX_BUILTIN_XSRDPIP },
10869 { MASK_VSX, CODE_FOR_vsx_btruncdf2, "__builtin_vsx_xsrdpiz", VSX_BUILTIN_XSRDPIZ },
10871 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abs", ALTIVEC_BUILTIN_VEC_ABS },
10872 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abss", ALTIVEC_BUILTIN_VEC_ABSS },
10873 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_ceil", ALTIVEC_BUILTIN_VEC_CEIL },
10874 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_expte", ALTIVEC_BUILTIN_VEC_EXPTE },
10875 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_floor", ALTIVEC_BUILTIN_VEC_FLOOR },
10876 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_loge", ALTIVEC_BUILTIN_VEC_LOGE },
10877 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mtvscr", ALTIVEC_BUILTIN_VEC_MTVSCR },
10878 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_re", ALTIVEC_BUILTIN_VEC_RE },
10879 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_round", ALTIVEC_BUILTIN_VEC_ROUND },
10880 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rsqrt", ALTIVEC_BUILTIN_VEC_RSQRT },
10881 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rsqrte", ALTIVEC_BUILTIN_VEC_RSQRTE },
10882 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_trunc", ALTIVEC_BUILTIN_VEC_TRUNC },
10883 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_unpackh", ALTIVEC_BUILTIN_VEC_UNPACKH },
10884 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhsh", ALTIVEC_BUILTIN_VEC_VUPKHSH },
10885 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhpx", ALTIVEC_BUILTIN_VEC_VUPKHPX },
10886 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhsb", ALTIVEC_BUILTIN_VEC_VUPKHSB },
10887 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_unpackl", ALTIVEC_BUILTIN_VEC_UNPACKL },
10888 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklpx", ALTIVEC_BUILTIN_VEC_VUPKLPX },
10889 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsh", ALTIVEC_BUILTIN_VEC_VUPKLSH },
10890 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsb", ALTIVEC_BUILTIN_VEC_VUPKLSB },
10892 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_nearbyint", ALTIVEC_BUILTIN_VEC_NEARBYINT },
10893 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_rint", ALTIVEC_BUILTIN_VEC_RINT },
10894 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_sqrt", ALTIVEC_BUILTIN_VEC_SQRT },
10896 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_floatv4siv4sf2, "__builtin_vec_float_sisf", VECTOR_BUILTIN_FLOAT_V4SI_V4SF },
10897 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_unsigned_floatv4siv4sf2, "__builtin_vec_uns_float_sisf", VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF },
10898 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_fix_truncv4sfv4si2, "__builtin_vec_fix_sfsi", VECTOR_BUILTIN_FIX_V4SF_V4SI },
10899 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_fixuns_truncv4sfv4si2, "__builtin_vec_fixuns_sfsi", VECTOR_BUILTIN_FIXUNS_V4SF_V4SI },
10901 /* The SPE unary builtins must start with SPE_BUILTIN_EVABS and
10902 end with SPE_BUILTIN_EVSUBFUSIAAW. */
10903 { 0, CODE_FOR_absv2si2, "__builtin_spe_evabs", SPE_BUILTIN_EVABS },
10904 { 0, CODE_FOR_spe_evaddsmiaaw, "__builtin_spe_evaddsmiaaw", SPE_BUILTIN_EVADDSMIAAW },
10905 { 0, CODE_FOR_spe_evaddssiaaw, "__builtin_spe_evaddssiaaw", SPE_BUILTIN_EVADDSSIAAW },
10906 { 0, CODE_FOR_spe_evaddumiaaw, "__builtin_spe_evaddumiaaw", SPE_BUILTIN_EVADDUMIAAW },
10907 { 0, CODE_FOR_spe_evaddusiaaw, "__builtin_spe_evaddusiaaw", SPE_BUILTIN_EVADDUSIAAW },
10908 { 0, CODE_FOR_spe_evcntlsw, "__builtin_spe_evcntlsw", SPE_BUILTIN_EVCNTLSW },
10909 { 0, CODE_FOR_spe_evcntlzw, "__builtin_spe_evcntlzw", SPE_BUILTIN_EVCNTLZW },
10910 { 0, CODE_FOR_spe_evextsb, "__builtin_spe_evextsb", SPE_BUILTIN_EVEXTSB },
10911 { 0, CODE_FOR_spe_evextsh, "__builtin_spe_evextsh", SPE_BUILTIN_EVEXTSH },
10912 { 0, CODE_FOR_spe_evfsabs, "__builtin_spe_evfsabs", SPE_BUILTIN_EVFSABS },
10913 { 0, CODE_FOR_spe_evfscfsf, "__builtin_spe_evfscfsf", SPE_BUILTIN_EVFSCFSF },
10914 { 0, CODE_FOR_spe_evfscfsi, "__builtin_spe_evfscfsi", SPE_BUILTIN_EVFSCFSI },
10915 { 0, CODE_FOR_spe_evfscfuf, "__builtin_spe_evfscfuf", SPE_BUILTIN_EVFSCFUF },
10916 { 0, CODE_FOR_spe_evfscfui, "__builtin_spe_evfscfui", SPE_BUILTIN_EVFSCFUI },
10917 { 0, CODE_FOR_spe_evfsctsf, "__builtin_spe_evfsctsf", SPE_BUILTIN_EVFSCTSF },
10918 { 0, CODE_FOR_spe_evfsctsi, "__builtin_spe_evfsctsi", SPE_BUILTIN_EVFSCTSI },
10919 { 0, CODE_FOR_spe_evfsctsiz, "__builtin_spe_evfsctsiz", SPE_BUILTIN_EVFSCTSIZ },
10920 { 0, CODE_FOR_spe_evfsctuf, "__builtin_spe_evfsctuf", SPE_BUILTIN_EVFSCTUF },
10921 { 0, CODE_FOR_spe_evfsctui, "__builtin_spe_evfsctui", SPE_BUILTIN_EVFSCTUI },
10922 { 0, CODE_FOR_spe_evfsctuiz, "__builtin_spe_evfsctuiz", SPE_BUILTIN_EVFSCTUIZ },
10923 { 0, CODE_FOR_spe_evfsnabs, "__builtin_spe_evfsnabs", SPE_BUILTIN_EVFSNABS },
10924 { 0, CODE_FOR_spe_evfsneg, "__builtin_spe_evfsneg", SPE_BUILTIN_EVFSNEG },
10925 { 0, CODE_FOR_spe_evmra, "__builtin_spe_evmra", SPE_BUILTIN_EVMRA },
10926 { 0, CODE_FOR_negv2si2, "__builtin_spe_evneg", SPE_BUILTIN_EVNEG },
10927 { 0, CODE_FOR_spe_evrndw, "__builtin_spe_evrndw", SPE_BUILTIN_EVRNDW },
10928 { 0, CODE_FOR_spe_evsubfsmiaaw, "__builtin_spe_evsubfsmiaaw", SPE_BUILTIN_EVSUBFSMIAAW },
10929 { 0, CODE_FOR_spe_evsubfssiaaw, "__builtin_spe_evsubfssiaaw", SPE_BUILTIN_EVSUBFSSIAAW },
10930 { 0, CODE_FOR_spe_evsubfumiaaw, "__builtin_spe_evsubfumiaaw", SPE_BUILTIN_EVSUBFUMIAAW },
10932 /* Place-holder. Leave as last unary SPE builtin. */
10933 { 0, CODE_FOR_spe_evsubfusiaaw, "__builtin_spe_evsubfusiaaw", SPE_BUILTIN_EVSUBFUSIAAW },
10935 { 0, CODE_FOR_paired_absv2sf2, "__builtin_paired_absv2sf2", PAIRED_BUILTIN_ABSV2SF2 },
10936 { 0, CODE_FOR_nabsv2sf2, "__builtin_paired_nabsv2sf2", PAIRED_BUILTIN_NABSV2SF2 },
10937 { 0, CODE_FOR_paired_negv2sf2, "__builtin_paired_negv2sf2", PAIRED_BUILTIN_NEGV2SF2 },
10938 { 0, CODE_FOR_sqrtv2sf2, "__builtin_paired_sqrtv2sf2", PAIRED_BUILTIN_SQRTV2SF2 },
10939 { 0, CODE_FOR_resv2sf2, "__builtin_paired_resv2sf2", PAIRED_BUILTIN_RESV2SF2 }
10942 static rtx
10943 rs6000_expand_unop_builtin (enum insn_code icode, tree exp, rtx target)
10945 rtx pat;
10946 tree arg0 = CALL_EXPR_ARG (exp, 0);
10947 rtx op0 = expand_normal (arg0);
10948 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10949 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10951 if (icode == CODE_FOR_nothing)
10952 /* Builtin not supported on this processor. */
10953 return 0;
10955 /* If we got invalid arguments bail out before generating bad rtl. */
10956 if (arg0 == error_mark_node)
10957 return const0_rtx;
10959 if (icode == CODE_FOR_altivec_vspltisb
10960 || icode == CODE_FOR_altivec_vspltish
10961 || icode == CODE_FOR_altivec_vspltisw
10962 || icode == CODE_FOR_spe_evsplatfi
10963 || icode == CODE_FOR_spe_evsplati)
10965 /* Only allow 5-bit *signed* literals. */
10966 if (GET_CODE (op0) != CONST_INT
10967 || INTVAL (op0) > 15
10968 || INTVAL (op0) < -16)
10970 error ("argument 1 must be a 5-bit signed literal");
10971 return const0_rtx;
10975 if (target == 0
10976 || GET_MODE (target) != tmode
10977 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10978 target = gen_reg_rtx (tmode);
10980 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10981 op0 = copy_to_mode_reg (mode0, op0);
10983 pat = GEN_FCN (icode) (target, op0);
10984 if (! pat)
10985 return 0;
10986 emit_insn (pat);
10988 return target;
10991 static rtx
10992 altivec_expand_abs_builtin (enum insn_code icode, tree exp, rtx target)
10994 rtx pat, scratch1, scratch2;
10995 tree arg0 = CALL_EXPR_ARG (exp, 0);
10996 rtx op0 = expand_normal (arg0);
10997 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10998 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
11000 /* If we have invalid arguments, bail out before generating bad rtl. */
11001 if (arg0 == error_mark_node)
11002 return const0_rtx;
11004 if (target == 0
11005 || GET_MODE (target) != tmode
11006 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11007 target = gen_reg_rtx (tmode);
11009 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
11010 op0 = copy_to_mode_reg (mode0, op0);
11012 scratch1 = gen_reg_rtx (mode0);
11013 scratch2 = gen_reg_rtx (mode0);
11015 pat = GEN_FCN (icode) (target, op0, scratch1, scratch2);
11016 if (! pat)
11017 return 0;
11018 emit_insn (pat);
11020 return target;
11023 static rtx
11024 rs6000_expand_binop_builtin (enum insn_code icode, tree exp, rtx target)
11026 rtx pat;
11027 tree arg0 = CALL_EXPR_ARG (exp, 0);
11028 tree arg1 = CALL_EXPR_ARG (exp, 1);
11029 rtx op0 = expand_normal (arg0);
11030 rtx op1 = expand_normal (arg1);
11031 enum machine_mode tmode = insn_data[icode].operand[0].mode;
11032 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
11033 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
11035 if (icode == CODE_FOR_nothing)
11036 /* Builtin not supported on this processor. */
11037 return 0;
11039 /* If we got invalid arguments bail out before generating bad rtl. */
11040 if (arg0 == error_mark_node || arg1 == error_mark_node)
11041 return const0_rtx;
11043 if (icode == CODE_FOR_altivec_vcfux
11044 || icode == CODE_FOR_altivec_vcfsx
11045 || icode == CODE_FOR_altivec_vctsxs
11046 || icode == CODE_FOR_altivec_vctuxs
11047 || icode == CODE_FOR_altivec_vspltb
11048 || icode == CODE_FOR_altivec_vsplth
11049 || icode == CODE_FOR_altivec_vspltw
11050 || icode == CODE_FOR_spe_evaddiw
11051 || icode == CODE_FOR_spe_evldd
11052 || icode == CODE_FOR_spe_evldh
11053 || icode == CODE_FOR_spe_evldw
11054 || icode == CODE_FOR_spe_evlhhesplat
11055 || icode == CODE_FOR_spe_evlhhossplat
11056 || icode == CODE_FOR_spe_evlhhousplat
11057 || icode == CODE_FOR_spe_evlwhe
11058 || icode == CODE_FOR_spe_evlwhos
11059 || icode == CODE_FOR_spe_evlwhou
11060 || icode == CODE_FOR_spe_evlwhsplat
11061 || icode == CODE_FOR_spe_evlwwsplat
11062 || icode == CODE_FOR_spe_evrlwi
11063 || icode == CODE_FOR_spe_evslwi
11064 || icode == CODE_FOR_spe_evsrwis
11065 || icode == CODE_FOR_spe_evsubifw
11066 || icode == CODE_FOR_spe_evsrwiu)
11068 /* Only allow 5-bit unsigned literals. */
11069 STRIP_NOPS (arg1);
11070 if (TREE_CODE (arg1) != INTEGER_CST
11071 || TREE_INT_CST_LOW (arg1) & ~0x1f)
11073 error ("argument 2 must be a 5-bit unsigned literal");
11074 return const0_rtx;
11078 if (target == 0
11079 || GET_MODE (target) != tmode
11080 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11081 target = gen_reg_rtx (tmode);
11083 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
11084 op0 = copy_to_mode_reg (mode0, op0);
11085 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
11086 op1 = copy_to_mode_reg (mode1, op1);
11088 pat = GEN_FCN (icode) (target, op0, op1);
11089 if (! pat)
11090 return 0;
11091 emit_insn (pat);
11093 return target;
11096 static rtx
11097 altivec_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
11099 rtx pat, scratch;
11100 tree cr6_form = CALL_EXPR_ARG (exp, 0);
11101 tree arg0 = CALL_EXPR_ARG (exp, 1);
11102 tree arg1 = CALL_EXPR_ARG (exp, 2);
11103 rtx op0 = expand_normal (arg0);
11104 rtx op1 = expand_normal (arg1);
11105 enum machine_mode tmode = SImode;
11106 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
11107 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
11108 int cr6_form_int;
11110 if (TREE_CODE (cr6_form) != INTEGER_CST)
11112 error ("argument 1 of __builtin_altivec_predicate must be a constant");
11113 return const0_rtx;
11115 else
11116 cr6_form_int = TREE_INT_CST_LOW (cr6_form);
11118 gcc_assert (mode0 == mode1);
11120 /* If we have invalid arguments, bail out before generating bad rtl. */
11121 if (arg0 == error_mark_node || arg1 == error_mark_node)
11122 return const0_rtx;
11124 if (target == 0
11125 || GET_MODE (target) != tmode
11126 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11127 target = gen_reg_rtx (tmode);
11129 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
11130 op0 = copy_to_mode_reg (mode0, op0);
11131 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
11132 op1 = copy_to_mode_reg (mode1, op1);
11134 scratch = gen_reg_rtx (mode0);
11136 pat = GEN_FCN (icode) (scratch, op0, op1);
11137 if (! pat)
11138 return 0;
11139 emit_insn (pat);
11141 /* The vec_any* and vec_all* predicates use the same opcodes for two
11142 different operations, but the bits in CR6 will be different
11143 depending on what information we want. So we have to play tricks
11144 with CR6 to get the right bits out.
11146 If you think this is disgusting, look at the specs for the
11147 AltiVec predicates. */
11149 switch (cr6_form_int)
11151 case 0:
11152 emit_insn (gen_cr6_test_for_zero (target));
11153 break;
11154 case 1:
11155 emit_insn (gen_cr6_test_for_zero_reverse (target));
11156 break;
11157 case 2:
11158 emit_insn (gen_cr6_test_for_lt (target));
11159 break;
11160 case 3:
11161 emit_insn (gen_cr6_test_for_lt_reverse (target));
11162 break;
11163 default:
11164 error ("argument 1 of __builtin_altivec_predicate is out of range");
11165 break;
11168 return target;
11171 static rtx
11172 paired_expand_lv_builtin (enum insn_code icode, tree exp, rtx target)
11174 rtx pat, addr;
11175 tree arg0 = CALL_EXPR_ARG (exp, 0);
11176 tree arg1 = CALL_EXPR_ARG (exp, 1);
11177 enum machine_mode tmode = insn_data[icode].operand[0].mode;
11178 enum machine_mode mode0 = Pmode;
11179 enum machine_mode mode1 = Pmode;
11180 rtx op0 = expand_normal (arg0);
11181 rtx op1 = expand_normal (arg1);
11183 if (icode == CODE_FOR_nothing)
11184 /* Builtin not supported on this processor. */
11185 return 0;
11187 /* If we got invalid arguments bail out before generating bad rtl. */
11188 if (arg0 == error_mark_node || arg1 == error_mark_node)
11189 return const0_rtx;
11191 if (target == 0
11192 || GET_MODE (target) != tmode
11193 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11194 target = gen_reg_rtx (tmode);
11196 op1 = copy_to_mode_reg (mode1, op1);
11198 if (op0 == const0_rtx)
11200 addr = gen_rtx_MEM (tmode, op1);
11202 else
11204 op0 = copy_to_mode_reg (mode0, op0);
11205 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op0, op1));
11208 pat = GEN_FCN (icode) (target, addr);
11210 if (! pat)
11211 return 0;
11212 emit_insn (pat);
11214 return target;
11217 static rtx
11218 altivec_expand_lv_builtin (enum insn_code icode, tree exp, rtx target, bool blk)
11220 rtx pat, addr;
11221 tree arg0 = CALL_EXPR_ARG (exp, 0);
11222 tree arg1 = CALL_EXPR_ARG (exp, 1);
11223 enum machine_mode tmode = insn_data[icode].operand[0].mode;
11224 enum machine_mode mode0 = Pmode;
11225 enum machine_mode mode1 = Pmode;
11226 rtx op0 = expand_normal (arg0);
11227 rtx op1 = expand_normal (arg1);
11229 if (icode == CODE_FOR_nothing)
11230 /* Builtin not supported on this processor. */
11231 return 0;
11233 /* If we got invalid arguments bail out before generating bad rtl. */
11234 if (arg0 == error_mark_node || arg1 == error_mark_node)
11235 return const0_rtx;
11237 if (target == 0
11238 || GET_MODE (target) != tmode
11239 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11240 target = gen_reg_rtx (tmode);
11242 op1 = copy_to_mode_reg (mode1, op1);
11244 if (op0 == const0_rtx)
11246 addr = gen_rtx_MEM (blk ? BLKmode : tmode, op1);
11248 else
11250 op0 = copy_to_mode_reg (mode0, op0);
11251 addr = gen_rtx_MEM (blk ? BLKmode : tmode, gen_rtx_PLUS (Pmode, op0, op1));
11254 pat = GEN_FCN (icode) (target, addr);
11256 if (! pat)
11257 return 0;
11258 emit_insn (pat);
11260 return target;
11263 static rtx
11264 spe_expand_stv_builtin (enum insn_code icode, tree exp)
11266 tree arg0 = CALL_EXPR_ARG (exp, 0);
11267 tree arg1 = CALL_EXPR_ARG (exp, 1);
11268 tree arg2 = CALL_EXPR_ARG (exp, 2);
11269 rtx op0 = expand_normal (arg0);
11270 rtx op1 = expand_normal (arg1);
11271 rtx op2 = expand_normal (arg2);
11272 rtx pat;
11273 enum machine_mode mode0 = insn_data[icode].operand[0].mode;
11274 enum machine_mode mode1 = insn_data[icode].operand[1].mode;
11275 enum machine_mode mode2 = insn_data[icode].operand[2].mode;
11277 /* Invalid arguments. Bail before doing anything stoopid! */
11278 if (arg0 == error_mark_node
11279 || arg1 == error_mark_node
11280 || arg2 == error_mark_node)
11281 return const0_rtx;
11283 if (! (*insn_data[icode].operand[2].predicate) (op0, mode2))
11284 op0 = copy_to_mode_reg (mode2, op0);
11285 if (! (*insn_data[icode].operand[0].predicate) (op1, mode0))
11286 op1 = copy_to_mode_reg (mode0, op1);
11287 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
11288 op2 = copy_to_mode_reg (mode1, op2);
11290 pat = GEN_FCN (icode) (op1, op2, op0);
11291 if (pat)
11292 emit_insn (pat);
11293 return NULL_RTX;
11296 static rtx
11297 paired_expand_stv_builtin (enum insn_code icode, tree exp)
11299 tree arg0 = CALL_EXPR_ARG (exp, 0);
11300 tree arg1 = CALL_EXPR_ARG (exp, 1);
11301 tree arg2 = CALL_EXPR_ARG (exp, 2);
11302 rtx op0 = expand_normal (arg0);
11303 rtx op1 = expand_normal (arg1);
11304 rtx op2 = expand_normal (arg2);
11305 rtx pat, addr;
11306 enum machine_mode tmode = insn_data[icode].operand[0].mode;
11307 enum machine_mode mode1 = Pmode;
11308 enum machine_mode mode2 = Pmode;
11310 /* Invalid arguments. Bail before doing anything stoopid! */
11311 if (arg0 == error_mark_node
11312 || arg1 == error_mark_node
11313 || arg2 == error_mark_node)
11314 return const0_rtx;
11316 if (! (*insn_data[icode].operand[1].predicate) (op0, tmode))
11317 op0 = copy_to_mode_reg (tmode, op0);
11319 op2 = copy_to_mode_reg (mode2, op2);
11321 if (op1 == const0_rtx)
11323 addr = gen_rtx_MEM (tmode, op2);
11325 else
11327 op1 = copy_to_mode_reg (mode1, op1);
11328 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op1, op2));
11331 pat = GEN_FCN (icode) (addr, op0);
11332 if (pat)
11333 emit_insn (pat);
11334 return NULL_RTX;
11337 static rtx
11338 altivec_expand_stv_builtin (enum insn_code icode, tree exp)
11340 tree arg0 = CALL_EXPR_ARG (exp, 0);
11341 tree arg1 = CALL_EXPR_ARG (exp, 1);
11342 tree arg2 = CALL_EXPR_ARG (exp, 2);
11343 rtx op0 = expand_normal (arg0);
11344 rtx op1 = expand_normal (arg1);
11345 rtx op2 = expand_normal (arg2);
11346 rtx pat, addr;
11347 enum machine_mode tmode = insn_data[icode].operand[0].mode;
11348 enum machine_mode smode = insn_data[icode].operand[1].mode;
11349 enum machine_mode mode1 = Pmode;
11350 enum machine_mode mode2 = Pmode;
11352 /* Invalid arguments. Bail before doing anything stoopid! */
11353 if (arg0 == error_mark_node
11354 || arg1 == error_mark_node
11355 || arg2 == error_mark_node)
11356 return const0_rtx;
11358 if (! (*insn_data[icode].operand[1].predicate) (op0, smode))
11359 op0 = copy_to_mode_reg (smode, op0);
11361 op2 = copy_to_mode_reg (mode2, op2);
11363 if (op1 == const0_rtx)
11365 addr = gen_rtx_MEM (tmode, op2);
11367 else
11369 op1 = copy_to_mode_reg (mode1, op1);
11370 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op1, op2));
11373 pat = GEN_FCN (icode) (addr, op0);
11374 if (pat)
11375 emit_insn (pat);
11376 return NULL_RTX;
11379 static rtx
11380 rs6000_expand_ternop_builtin (enum insn_code icode, tree exp, rtx target)
11382 rtx pat;
11383 tree arg0 = CALL_EXPR_ARG (exp, 0);
11384 tree arg1 = CALL_EXPR_ARG (exp, 1);
11385 tree arg2 = CALL_EXPR_ARG (exp, 2);
11386 rtx op0 = expand_normal (arg0);
11387 rtx op1 = expand_normal (arg1);
11388 rtx op2 = expand_normal (arg2);
11389 enum machine_mode tmode = insn_data[icode].operand[0].mode;
11390 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
11391 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
11392 enum machine_mode mode2 = insn_data[icode].operand[3].mode;
11394 if (icode == CODE_FOR_nothing)
11395 /* Builtin not supported on this processor. */
11396 return 0;
11398 /* If we got invalid arguments bail out before generating bad rtl. */
11399 if (arg0 == error_mark_node
11400 || arg1 == error_mark_node
11401 || arg2 == error_mark_node)
11402 return const0_rtx;
11404 /* Check and prepare argument depending on the instruction code.
11406 Note that a switch statement instead of the sequence of tests
11407 would be incorrect as many of the CODE_FOR values could be
11408 CODE_FOR_nothing and that would yield multiple alternatives
11409 with identical values. We'd never reach here at runtime in
11410 this case. */
11411 if (icode == CODE_FOR_altivec_vsldoi_v4sf
11412 || icode == CODE_FOR_altivec_vsldoi_v4si
11413 || icode == CODE_FOR_altivec_vsldoi_v8hi
11414 || icode == CODE_FOR_altivec_vsldoi_v16qi)
11416 /* Only allow 4-bit unsigned literals. */
11417 STRIP_NOPS (arg2);
11418 if (TREE_CODE (arg2) != INTEGER_CST
11419 || TREE_INT_CST_LOW (arg2) & ~0xf)
11421 error ("argument 3 must be a 4-bit unsigned literal");
11422 return const0_rtx;
11425 else if (icode == CODE_FOR_vsx_xxpermdi_v2df
11426 || icode == CODE_FOR_vsx_xxpermdi_v2di
11427 || icode == CODE_FOR_vsx_xxsldwi_v16qi
11428 || icode == CODE_FOR_vsx_xxsldwi_v8hi
11429 || icode == CODE_FOR_vsx_xxsldwi_v4si
11430 || icode == CODE_FOR_vsx_xxsldwi_v4sf
11431 || icode == CODE_FOR_vsx_xxsldwi_v2di
11432 || icode == CODE_FOR_vsx_xxsldwi_v2df)
11434 /* Only allow 2-bit unsigned literals. */
11435 STRIP_NOPS (arg2);
11436 if (TREE_CODE (arg2) != INTEGER_CST
11437 || TREE_INT_CST_LOW (arg2) & ~0x3)
11439 error ("argument 3 must be a 2-bit unsigned literal");
11440 return const0_rtx;
11443 else if (icode == CODE_FOR_vsx_set_v2df
11444 || icode == CODE_FOR_vsx_set_v2di)
11446 /* Only allow 1-bit unsigned literals. */
11447 STRIP_NOPS (arg2);
11448 if (TREE_CODE (arg2) != INTEGER_CST
11449 || TREE_INT_CST_LOW (arg2) & ~0x1)
11451 error ("argument 3 must be a 1-bit unsigned literal");
11452 return const0_rtx;
11456 if (target == 0
11457 || GET_MODE (target) != tmode
11458 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11459 target = gen_reg_rtx (tmode);
11461 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
11462 op0 = copy_to_mode_reg (mode0, op0);
11463 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
11464 op1 = copy_to_mode_reg (mode1, op1);
11465 if (! (*insn_data[icode].operand[3].predicate) (op2, mode2))
11466 op2 = copy_to_mode_reg (mode2, op2);
11468 if (TARGET_PAIRED_FLOAT && icode == CODE_FOR_selv2sf4)
11469 pat = GEN_FCN (icode) (target, op0, op1, op2, CONST0_RTX (SFmode));
11470 else
11471 pat = GEN_FCN (icode) (target, op0, op1, op2);
11472 if (! pat)
11473 return 0;
11474 emit_insn (pat);
11476 return target;
11479 /* Expand the lvx builtins. */
11480 static rtx
11481 altivec_expand_ld_builtin (tree exp, rtx target, bool *expandedp)
11483 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11484 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11485 tree arg0;
11486 enum machine_mode tmode, mode0;
11487 rtx pat, op0;
11488 enum insn_code icode;
11490 switch (fcode)
11492 case ALTIVEC_BUILTIN_LD_INTERNAL_16qi:
11493 icode = CODE_FOR_vector_altivec_load_v16qi;
11494 break;
11495 case ALTIVEC_BUILTIN_LD_INTERNAL_8hi:
11496 icode = CODE_FOR_vector_altivec_load_v8hi;
11497 break;
11498 case ALTIVEC_BUILTIN_LD_INTERNAL_4si:
11499 icode = CODE_FOR_vector_altivec_load_v4si;
11500 break;
11501 case ALTIVEC_BUILTIN_LD_INTERNAL_4sf:
11502 icode = CODE_FOR_vector_altivec_load_v4sf;
11503 break;
11504 case ALTIVEC_BUILTIN_LD_INTERNAL_2df:
11505 icode = CODE_FOR_vector_altivec_load_v2df;
11506 break;
11507 case ALTIVEC_BUILTIN_LD_INTERNAL_2di:
11508 icode = CODE_FOR_vector_altivec_load_v2di;
11509 break;
11510 default:
11511 *expandedp = false;
11512 return NULL_RTX;
11515 *expandedp = true;
11517 arg0 = CALL_EXPR_ARG (exp, 0);
11518 op0 = expand_normal (arg0);
11519 tmode = insn_data[icode].operand[0].mode;
11520 mode0 = insn_data[icode].operand[1].mode;
11522 if (target == 0
11523 || GET_MODE (target) != tmode
11524 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11525 target = gen_reg_rtx (tmode);
11527 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
11528 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
11530 pat = GEN_FCN (icode) (target, op0);
11531 if (! pat)
11532 return 0;
11533 emit_insn (pat);
11534 return target;
11537 /* Expand the stvx builtins. */
11538 static rtx
11539 altivec_expand_st_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
11540 bool *expandedp)
11542 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11543 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11544 tree arg0, arg1;
11545 enum machine_mode mode0, mode1;
11546 rtx pat, op0, op1;
11547 enum insn_code icode;
11549 switch (fcode)
11551 case ALTIVEC_BUILTIN_ST_INTERNAL_16qi:
11552 icode = CODE_FOR_vector_altivec_store_v16qi;
11553 break;
11554 case ALTIVEC_BUILTIN_ST_INTERNAL_8hi:
11555 icode = CODE_FOR_vector_altivec_store_v8hi;
11556 break;
11557 case ALTIVEC_BUILTIN_ST_INTERNAL_4si:
11558 icode = CODE_FOR_vector_altivec_store_v4si;
11559 break;
11560 case ALTIVEC_BUILTIN_ST_INTERNAL_4sf:
11561 icode = CODE_FOR_vector_altivec_store_v4sf;
11562 break;
11563 case ALTIVEC_BUILTIN_ST_INTERNAL_2df:
11564 icode = CODE_FOR_vector_altivec_store_v2df;
11565 break;
11566 case ALTIVEC_BUILTIN_ST_INTERNAL_2di:
11567 icode = CODE_FOR_vector_altivec_store_v2di;
11568 break;
11569 default:
11570 *expandedp = false;
11571 return NULL_RTX;
11574 arg0 = CALL_EXPR_ARG (exp, 0);
11575 arg1 = CALL_EXPR_ARG (exp, 1);
11576 op0 = expand_normal (arg0);
11577 op1 = expand_normal (arg1);
11578 mode0 = insn_data[icode].operand[0].mode;
11579 mode1 = insn_data[icode].operand[1].mode;
11581 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
11582 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
11583 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
11584 op1 = copy_to_mode_reg (mode1, op1);
11586 pat = GEN_FCN (icode) (op0, op1);
11587 if (pat)
11588 emit_insn (pat);
11590 *expandedp = true;
11591 return NULL_RTX;
11594 /* Expand the dst builtins. */
11595 static rtx
11596 altivec_expand_dst_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
11597 bool *expandedp)
11599 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11600 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11601 tree arg0, arg1, arg2;
11602 enum machine_mode mode0, mode1;
11603 rtx pat, op0, op1, op2;
11604 const struct builtin_description *d;
11605 size_t i;
11607 *expandedp = false;
11609 /* Handle DST variants. */
11610 d = bdesc_dst;
11611 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
11612 if (d->code == fcode)
11614 arg0 = CALL_EXPR_ARG (exp, 0);
11615 arg1 = CALL_EXPR_ARG (exp, 1);
11616 arg2 = CALL_EXPR_ARG (exp, 2);
11617 op0 = expand_normal (arg0);
11618 op1 = expand_normal (arg1);
11619 op2 = expand_normal (arg2);
11620 mode0 = insn_data[d->icode].operand[0].mode;
11621 mode1 = insn_data[d->icode].operand[1].mode;
11623 /* Invalid arguments, bail out before generating bad rtl. */
11624 if (arg0 == error_mark_node
11625 || arg1 == error_mark_node
11626 || arg2 == error_mark_node)
11627 return const0_rtx;
11629 *expandedp = true;
11630 STRIP_NOPS (arg2);
11631 if (TREE_CODE (arg2) != INTEGER_CST
11632 || TREE_INT_CST_LOW (arg2) & ~0x3)
11634 error ("argument to %qs must be a 2-bit unsigned literal", d->name);
11635 return const0_rtx;
11638 if (! (*insn_data[d->icode].operand[0].predicate) (op0, mode0))
11639 op0 = copy_to_mode_reg (Pmode, op0);
11640 if (! (*insn_data[d->icode].operand[1].predicate) (op1, mode1))
11641 op1 = copy_to_mode_reg (mode1, op1);
11643 pat = GEN_FCN (d->icode) (op0, op1, op2);
11644 if (pat != 0)
11645 emit_insn (pat);
11647 return NULL_RTX;
11650 return NULL_RTX;
11653 /* Expand vec_init builtin. */
11654 static rtx
11655 altivec_expand_vec_init_builtin (tree type, tree exp, rtx target)
11657 enum machine_mode tmode = TYPE_MODE (type);
11658 enum machine_mode inner_mode = GET_MODE_INNER (tmode);
11659 int i, n_elt = GET_MODE_NUNITS (tmode);
11660 rtvec v = rtvec_alloc (n_elt);
11662 gcc_assert (VECTOR_MODE_P (tmode));
11663 gcc_assert (n_elt == call_expr_nargs (exp));
11665 for (i = 0; i < n_elt; ++i)
11667 rtx x = expand_normal (CALL_EXPR_ARG (exp, i));
11668 RTVEC_ELT (v, i) = gen_lowpart (inner_mode, x);
11671 if (!target || !register_operand (target, tmode))
11672 target = gen_reg_rtx (tmode);
11674 rs6000_expand_vector_init (target, gen_rtx_PARALLEL (tmode, v));
11675 return target;
11678 /* Return the integer constant in ARG. Constrain it to be in the range
11679 of the subparts of VEC_TYPE; issue an error if not. */
11681 static int
11682 get_element_number (tree vec_type, tree arg)
11684 unsigned HOST_WIDE_INT elt, max = TYPE_VECTOR_SUBPARTS (vec_type) - 1;
11686 if (!host_integerp (arg, 1)
11687 || (elt = tree_low_cst (arg, 1), elt > max))
11689 error ("selector must be an integer constant in the range 0..%wi", max);
11690 return 0;
11693 return elt;
11696 /* Expand vec_set builtin. */
11697 static rtx
11698 altivec_expand_vec_set_builtin (tree exp)
11700 enum machine_mode tmode, mode1;
11701 tree arg0, arg1, arg2;
11702 int elt;
11703 rtx op0, op1;
11705 arg0 = CALL_EXPR_ARG (exp, 0);
11706 arg1 = CALL_EXPR_ARG (exp, 1);
11707 arg2 = CALL_EXPR_ARG (exp, 2);
11709 tmode = TYPE_MODE (TREE_TYPE (arg0));
11710 mode1 = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
11711 gcc_assert (VECTOR_MODE_P (tmode));
11713 op0 = expand_expr (arg0, NULL_RTX, tmode, EXPAND_NORMAL);
11714 op1 = expand_expr (arg1, NULL_RTX, mode1, EXPAND_NORMAL);
11715 elt = get_element_number (TREE_TYPE (arg0), arg2);
11717 if (GET_MODE (op1) != mode1 && GET_MODE (op1) != VOIDmode)
11718 op1 = convert_modes (mode1, GET_MODE (op1), op1, true);
11720 op0 = force_reg (tmode, op0);
11721 op1 = force_reg (mode1, op1);
11723 rs6000_expand_vector_set (op0, op1, elt);
11725 return op0;
11728 /* Expand vec_ext builtin. */
11729 static rtx
11730 altivec_expand_vec_ext_builtin (tree exp, rtx target)
11732 enum machine_mode tmode, mode0;
11733 tree arg0, arg1;
11734 int elt;
11735 rtx op0;
11737 arg0 = CALL_EXPR_ARG (exp, 0);
11738 arg1 = CALL_EXPR_ARG (exp, 1);
11740 op0 = expand_normal (arg0);
11741 elt = get_element_number (TREE_TYPE (arg0), arg1);
11743 tmode = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
11744 mode0 = TYPE_MODE (TREE_TYPE (arg0));
11745 gcc_assert (VECTOR_MODE_P (mode0));
11747 op0 = force_reg (mode0, op0);
11749 if (optimize || !target || !register_operand (target, tmode))
11750 target = gen_reg_rtx (tmode);
11752 rs6000_expand_vector_extract (target, op0, elt);
11754 return target;
11757 /* Expand the builtin in EXP and store the result in TARGET. Store
11758 true in *EXPANDEDP if we found a builtin to expand. */
11759 static rtx
11760 altivec_expand_builtin (tree exp, rtx target, bool *expandedp)
11762 const struct builtin_description *d;
11763 const struct builtin_description_predicates *dp;
11764 size_t i;
11765 enum insn_code icode;
11766 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11767 tree arg0;
11768 rtx op0, pat;
11769 enum machine_mode tmode, mode0;
11770 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11772 if ((fcode >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
11773 && fcode <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
11774 || (fcode >= VSX_BUILTIN_OVERLOADED_FIRST
11775 && fcode <= VSX_BUILTIN_OVERLOADED_LAST))
11777 *expandedp = true;
11778 error ("unresolved overload for Altivec builtin %qF", fndecl);
11779 return const0_rtx;
11782 target = altivec_expand_ld_builtin (exp, target, expandedp);
11783 if (*expandedp)
11784 return target;
11786 target = altivec_expand_st_builtin (exp, target, expandedp);
11787 if (*expandedp)
11788 return target;
11790 target = altivec_expand_dst_builtin (exp, target, expandedp);
11791 if (*expandedp)
11792 return target;
11794 *expandedp = true;
11796 switch (fcode)
11798 case ALTIVEC_BUILTIN_STVX:
11799 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx_v4si, exp);
11800 case ALTIVEC_BUILTIN_STVEBX:
11801 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvebx, exp);
11802 case ALTIVEC_BUILTIN_STVEHX:
11803 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvehx, exp);
11804 case ALTIVEC_BUILTIN_STVEWX:
11805 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvewx, exp);
11806 case ALTIVEC_BUILTIN_STVXL:
11807 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvxl, exp);
11809 case ALTIVEC_BUILTIN_STVLX:
11810 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlx, exp);
11811 case ALTIVEC_BUILTIN_STVLXL:
11812 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlxl, exp);
11813 case ALTIVEC_BUILTIN_STVRX:
11814 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrx, exp);
11815 case ALTIVEC_BUILTIN_STVRXL:
11816 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrxl, exp);
11818 case VSX_BUILTIN_STXVD2X_V2DF:
11819 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v2df, exp);
11820 case VSX_BUILTIN_STXVD2X_V2DI:
11821 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v2di, exp);
11822 case VSX_BUILTIN_STXVW4X_V4SF:
11823 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v4sf, exp);
11824 case VSX_BUILTIN_STXVW4X_V4SI:
11825 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v4si, exp);
11826 case VSX_BUILTIN_STXVW4X_V8HI:
11827 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v8hi, exp);
11828 case VSX_BUILTIN_STXVW4X_V16QI:
11829 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v16qi, exp);
11831 case ALTIVEC_BUILTIN_MFVSCR:
11832 icode = CODE_FOR_altivec_mfvscr;
11833 tmode = insn_data[icode].operand[0].mode;
11835 if (target == 0
11836 || GET_MODE (target) != tmode
11837 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11838 target = gen_reg_rtx (tmode);
11840 pat = GEN_FCN (icode) (target);
11841 if (! pat)
11842 return 0;
11843 emit_insn (pat);
11844 return target;
11846 case ALTIVEC_BUILTIN_MTVSCR:
11847 icode = CODE_FOR_altivec_mtvscr;
11848 arg0 = CALL_EXPR_ARG (exp, 0);
11849 op0 = expand_normal (arg0);
11850 mode0 = insn_data[icode].operand[0].mode;
11852 /* If we got invalid arguments bail out before generating bad rtl. */
11853 if (arg0 == error_mark_node)
11854 return const0_rtx;
11856 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
11857 op0 = copy_to_mode_reg (mode0, op0);
11859 pat = GEN_FCN (icode) (op0);
11860 if (pat)
11861 emit_insn (pat);
11862 return NULL_RTX;
11864 case ALTIVEC_BUILTIN_DSSALL:
11865 emit_insn (gen_altivec_dssall ());
11866 return NULL_RTX;
11868 case ALTIVEC_BUILTIN_DSS:
11869 icode = CODE_FOR_altivec_dss;
11870 arg0 = CALL_EXPR_ARG (exp, 0);
11871 STRIP_NOPS (arg0);
11872 op0 = expand_normal (arg0);
11873 mode0 = insn_data[icode].operand[0].mode;
11875 /* If we got invalid arguments bail out before generating bad rtl. */
11876 if (arg0 == error_mark_node)
11877 return const0_rtx;
11879 if (TREE_CODE (arg0) != INTEGER_CST
11880 || TREE_INT_CST_LOW (arg0) & ~0x3)
11882 error ("argument to dss must be a 2-bit unsigned literal");
11883 return const0_rtx;
11886 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
11887 op0 = copy_to_mode_reg (mode0, op0);
11889 emit_insn (gen_altivec_dss (op0));
11890 return NULL_RTX;
11892 case ALTIVEC_BUILTIN_VEC_INIT_V4SI:
11893 case ALTIVEC_BUILTIN_VEC_INIT_V8HI:
11894 case ALTIVEC_BUILTIN_VEC_INIT_V16QI:
11895 case ALTIVEC_BUILTIN_VEC_INIT_V4SF:
11896 case VSX_BUILTIN_VEC_INIT_V2DF:
11897 case VSX_BUILTIN_VEC_INIT_V2DI:
11898 return altivec_expand_vec_init_builtin (TREE_TYPE (exp), exp, target);
11900 case ALTIVEC_BUILTIN_VEC_SET_V4SI:
11901 case ALTIVEC_BUILTIN_VEC_SET_V8HI:
11902 case ALTIVEC_BUILTIN_VEC_SET_V16QI:
11903 case ALTIVEC_BUILTIN_VEC_SET_V4SF:
11904 case VSX_BUILTIN_VEC_SET_V2DF:
11905 case VSX_BUILTIN_VEC_SET_V2DI:
11906 return altivec_expand_vec_set_builtin (exp);
11908 case ALTIVEC_BUILTIN_VEC_EXT_V4SI:
11909 case ALTIVEC_BUILTIN_VEC_EXT_V8HI:
11910 case ALTIVEC_BUILTIN_VEC_EXT_V16QI:
11911 case ALTIVEC_BUILTIN_VEC_EXT_V4SF:
11912 case VSX_BUILTIN_VEC_EXT_V2DF:
11913 case VSX_BUILTIN_VEC_EXT_V2DI:
11914 return altivec_expand_vec_ext_builtin (exp, target);
11916 default:
11917 break;
11918 /* Fall through. */
11921 /* Expand abs* operations. */
11922 d = bdesc_abs;
11923 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
11924 if (d->code == fcode)
11925 return altivec_expand_abs_builtin (d->icode, exp, target);
11927 /* Expand the AltiVec predicates. */
11928 dp = bdesc_altivec_preds;
11929 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
11930 if (dp->code == fcode)
11931 return altivec_expand_predicate_builtin (dp->icode, exp, target);
11933 /* LV* are funky. We initialized them differently. */
11934 switch (fcode)
11936 case ALTIVEC_BUILTIN_LVSL:
11937 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsl,
11938 exp, target, false);
11939 case ALTIVEC_BUILTIN_LVSR:
11940 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsr,
11941 exp, target, false);
11942 case ALTIVEC_BUILTIN_LVEBX:
11943 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvebx,
11944 exp, target, false);
11945 case ALTIVEC_BUILTIN_LVEHX:
11946 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvehx,
11947 exp, target, false);
11948 case ALTIVEC_BUILTIN_LVEWX:
11949 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvewx,
11950 exp, target, false);
11951 case ALTIVEC_BUILTIN_LVXL:
11952 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvxl,
11953 exp, target, false);
11954 case ALTIVEC_BUILTIN_LVX:
11955 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx_v4si,
11956 exp, target, false);
11957 case ALTIVEC_BUILTIN_LVLX:
11958 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlx,
11959 exp, target, true);
11960 case ALTIVEC_BUILTIN_LVLXL:
11961 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlxl,
11962 exp, target, true);
11963 case ALTIVEC_BUILTIN_LVRX:
11964 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrx,
11965 exp, target, true);
11966 case ALTIVEC_BUILTIN_LVRXL:
11967 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrxl,
11968 exp, target, true);
11969 case VSX_BUILTIN_LXVD2X_V2DF:
11970 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v2df,
11971 exp, target, false);
11972 case VSX_BUILTIN_LXVD2X_V2DI:
11973 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v2di,
11974 exp, target, false);
11975 case VSX_BUILTIN_LXVW4X_V4SF:
11976 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v4sf,
11977 exp, target, false);
11978 case VSX_BUILTIN_LXVW4X_V4SI:
11979 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v4si,
11980 exp, target, false);
11981 case VSX_BUILTIN_LXVW4X_V8HI:
11982 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v8hi,
11983 exp, target, false);
11984 case VSX_BUILTIN_LXVW4X_V16QI:
11985 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v16qi,
11986 exp, target, false);
11987 break;
11988 default:
11989 break;
11990 /* Fall through. */
11993 *expandedp = false;
11994 return NULL_RTX;
11997 /* Expand the builtin in EXP and store the result in TARGET. Store
11998 true in *EXPANDEDP if we found a builtin to expand. */
11999 static rtx
12000 paired_expand_builtin (tree exp, rtx target, bool * expandedp)
12002 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
12003 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
12004 const struct builtin_description *d;
12005 size_t i;
12007 *expandedp = true;
12009 switch (fcode)
12011 case PAIRED_BUILTIN_STX:
12012 return paired_expand_stv_builtin (CODE_FOR_paired_stx, exp);
12013 case PAIRED_BUILTIN_LX:
12014 return paired_expand_lv_builtin (CODE_FOR_paired_lx, exp, target);
12015 default:
12016 break;
12017 /* Fall through. */
12020 /* Expand the paired predicates. */
12021 d = bdesc_paired_preds;
12022 for (i = 0; i < ARRAY_SIZE (bdesc_paired_preds); i++, d++)
12023 if (d->code == fcode)
12024 return paired_expand_predicate_builtin (d->icode, exp, target);
12026 *expandedp = false;
12027 return NULL_RTX;
12030 /* Binops that need to be initialized manually, but can be expanded
12031 automagically by rs6000_expand_binop_builtin. */
12032 static struct builtin_description bdesc_2arg_spe[] =
12034 { 0, CODE_FOR_spe_evlddx, "__builtin_spe_evlddx", SPE_BUILTIN_EVLDDX },
12035 { 0, CODE_FOR_spe_evldwx, "__builtin_spe_evldwx", SPE_BUILTIN_EVLDWX },
12036 { 0, CODE_FOR_spe_evldhx, "__builtin_spe_evldhx", SPE_BUILTIN_EVLDHX },
12037 { 0, CODE_FOR_spe_evlwhex, "__builtin_spe_evlwhex", SPE_BUILTIN_EVLWHEX },
12038 { 0, CODE_FOR_spe_evlwhoux, "__builtin_spe_evlwhoux", SPE_BUILTIN_EVLWHOUX },
12039 { 0, CODE_FOR_spe_evlwhosx, "__builtin_spe_evlwhosx", SPE_BUILTIN_EVLWHOSX },
12040 { 0, CODE_FOR_spe_evlwwsplatx, "__builtin_spe_evlwwsplatx", SPE_BUILTIN_EVLWWSPLATX },
12041 { 0, CODE_FOR_spe_evlwhsplatx, "__builtin_spe_evlwhsplatx", SPE_BUILTIN_EVLWHSPLATX },
12042 { 0, CODE_FOR_spe_evlhhesplatx, "__builtin_spe_evlhhesplatx", SPE_BUILTIN_EVLHHESPLATX },
12043 { 0, CODE_FOR_spe_evlhhousplatx, "__builtin_spe_evlhhousplatx", SPE_BUILTIN_EVLHHOUSPLATX },
12044 { 0, CODE_FOR_spe_evlhhossplatx, "__builtin_spe_evlhhossplatx", SPE_BUILTIN_EVLHHOSSPLATX },
12045 { 0, CODE_FOR_spe_evldd, "__builtin_spe_evldd", SPE_BUILTIN_EVLDD },
12046 { 0, CODE_FOR_spe_evldw, "__builtin_spe_evldw", SPE_BUILTIN_EVLDW },
12047 { 0, CODE_FOR_spe_evldh, "__builtin_spe_evldh", SPE_BUILTIN_EVLDH },
12048 { 0, CODE_FOR_spe_evlwhe, "__builtin_spe_evlwhe", SPE_BUILTIN_EVLWHE },
12049 { 0, CODE_FOR_spe_evlwhou, "__builtin_spe_evlwhou", SPE_BUILTIN_EVLWHOU },
12050 { 0, CODE_FOR_spe_evlwhos, "__builtin_spe_evlwhos", SPE_BUILTIN_EVLWHOS },
12051 { 0, CODE_FOR_spe_evlwwsplat, "__builtin_spe_evlwwsplat", SPE_BUILTIN_EVLWWSPLAT },
12052 { 0, CODE_FOR_spe_evlwhsplat, "__builtin_spe_evlwhsplat", SPE_BUILTIN_EVLWHSPLAT },
12053 { 0, CODE_FOR_spe_evlhhesplat, "__builtin_spe_evlhhesplat", SPE_BUILTIN_EVLHHESPLAT },
12054 { 0, CODE_FOR_spe_evlhhousplat, "__builtin_spe_evlhhousplat", SPE_BUILTIN_EVLHHOUSPLAT },
12055 { 0, CODE_FOR_spe_evlhhossplat, "__builtin_spe_evlhhossplat", SPE_BUILTIN_EVLHHOSSPLAT }
12058 /* Expand the builtin in EXP and store the result in TARGET. Store
12059 true in *EXPANDEDP if we found a builtin to expand.
12061 This expands the SPE builtins that are not simple unary and binary
12062 operations. */
12063 static rtx
12064 spe_expand_builtin (tree exp, rtx target, bool *expandedp)
12066 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
12067 tree arg1, arg0;
12068 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
12069 enum insn_code icode;
12070 enum machine_mode tmode, mode0;
12071 rtx pat, op0;
12072 struct builtin_description *d;
12073 size_t i;
12075 *expandedp = true;
12077 /* Syntax check for a 5-bit unsigned immediate. */
12078 switch (fcode)
12080 case SPE_BUILTIN_EVSTDD:
12081 case SPE_BUILTIN_EVSTDH:
12082 case SPE_BUILTIN_EVSTDW:
12083 case SPE_BUILTIN_EVSTWHE:
12084 case SPE_BUILTIN_EVSTWHO:
12085 case SPE_BUILTIN_EVSTWWE:
12086 case SPE_BUILTIN_EVSTWWO:
12087 arg1 = CALL_EXPR_ARG (exp, 2);
12088 if (TREE_CODE (arg1) != INTEGER_CST
12089 || TREE_INT_CST_LOW (arg1) & ~0x1f)
12091 error ("argument 2 must be a 5-bit unsigned literal");
12092 return const0_rtx;
12094 break;
12095 default:
12096 break;
12099 /* The evsplat*i instructions are not quite generic. */
12100 switch (fcode)
12102 case SPE_BUILTIN_EVSPLATFI:
12103 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplatfi,
12104 exp, target);
12105 case SPE_BUILTIN_EVSPLATI:
12106 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplati,
12107 exp, target);
12108 default:
12109 break;
12112 d = (struct builtin_description *) bdesc_2arg_spe;
12113 for (i = 0; i < ARRAY_SIZE (bdesc_2arg_spe); ++i, ++d)
12114 if (d->code == fcode)
12115 return rs6000_expand_binop_builtin (d->icode, exp, target);
12117 d = (struct builtin_description *) bdesc_spe_predicates;
12118 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, ++d)
12119 if (d->code == fcode)
12120 return spe_expand_predicate_builtin (d->icode, exp, target);
12122 d = (struct builtin_description *) bdesc_spe_evsel;
12123 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, ++d)
12124 if (d->code == fcode)
12125 return spe_expand_evsel_builtin (d->icode, exp, target);
12127 switch (fcode)
12129 case SPE_BUILTIN_EVSTDDX:
12130 return spe_expand_stv_builtin (CODE_FOR_spe_evstddx, exp);
12131 case SPE_BUILTIN_EVSTDHX:
12132 return spe_expand_stv_builtin (CODE_FOR_spe_evstdhx, exp);
12133 case SPE_BUILTIN_EVSTDWX:
12134 return spe_expand_stv_builtin (CODE_FOR_spe_evstdwx, exp);
12135 case SPE_BUILTIN_EVSTWHEX:
12136 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhex, exp);
12137 case SPE_BUILTIN_EVSTWHOX:
12138 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhox, exp);
12139 case SPE_BUILTIN_EVSTWWEX:
12140 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwex, exp);
12141 case SPE_BUILTIN_EVSTWWOX:
12142 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwox, exp);
12143 case SPE_BUILTIN_EVSTDD:
12144 return spe_expand_stv_builtin (CODE_FOR_spe_evstdd, exp);
12145 case SPE_BUILTIN_EVSTDH:
12146 return spe_expand_stv_builtin (CODE_FOR_spe_evstdh, exp);
12147 case SPE_BUILTIN_EVSTDW:
12148 return spe_expand_stv_builtin (CODE_FOR_spe_evstdw, exp);
12149 case SPE_BUILTIN_EVSTWHE:
12150 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhe, exp);
12151 case SPE_BUILTIN_EVSTWHO:
12152 return spe_expand_stv_builtin (CODE_FOR_spe_evstwho, exp);
12153 case SPE_BUILTIN_EVSTWWE:
12154 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwe, exp);
12155 case SPE_BUILTIN_EVSTWWO:
12156 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwo, exp);
12157 case SPE_BUILTIN_MFSPEFSCR:
12158 icode = CODE_FOR_spe_mfspefscr;
12159 tmode = insn_data[icode].operand[0].mode;
12161 if (target == 0
12162 || GET_MODE (target) != tmode
12163 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
12164 target = gen_reg_rtx (tmode);
12166 pat = GEN_FCN (icode) (target);
12167 if (! pat)
12168 return 0;
12169 emit_insn (pat);
12170 return target;
12171 case SPE_BUILTIN_MTSPEFSCR:
12172 icode = CODE_FOR_spe_mtspefscr;
12173 arg0 = CALL_EXPR_ARG (exp, 0);
12174 op0 = expand_normal (arg0);
12175 mode0 = insn_data[icode].operand[0].mode;
12177 if (arg0 == error_mark_node)
12178 return const0_rtx;
12180 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
12181 op0 = copy_to_mode_reg (mode0, op0);
12183 pat = GEN_FCN (icode) (op0);
12184 if (pat)
12185 emit_insn (pat);
12186 return NULL_RTX;
12187 default:
12188 break;
12191 *expandedp = false;
12192 return NULL_RTX;
12195 static rtx
12196 paired_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
12198 rtx pat, scratch, tmp;
12199 tree form = CALL_EXPR_ARG (exp, 0);
12200 tree arg0 = CALL_EXPR_ARG (exp, 1);
12201 tree arg1 = CALL_EXPR_ARG (exp, 2);
12202 rtx op0 = expand_normal (arg0);
12203 rtx op1 = expand_normal (arg1);
12204 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
12205 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
12206 int form_int;
12207 enum rtx_code code;
12209 if (TREE_CODE (form) != INTEGER_CST)
12211 error ("argument 1 of __builtin_paired_predicate must be a constant");
12212 return const0_rtx;
12214 else
12215 form_int = TREE_INT_CST_LOW (form);
12217 gcc_assert (mode0 == mode1);
12219 if (arg0 == error_mark_node || arg1 == error_mark_node)
12220 return const0_rtx;
12222 if (target == 0
12223 || GET_MODE (target) != SImode
12224 || !(*insn_data[icode].operand[0].predicate) (target, SImode))
12225 target = gen_reg_rtx (SImode);
12226 if (!(*insn_data[icode].operand[1].predicate) (op0, mode0))
12227 op0 = copy_to_mode_reg (mode0, op0);
12228 if (!(*insn_data[icode].operand[2].predicate) (op1, mode1))
12229 op1 = copy_to_mode_reg (mode1, op1);
12231 scratch = gen_reg_rtx (CCFPmode);
12233 pat = GEN_FCN (icode) (scratch, op0, op1);
12234 if (!pat)
12235 return const0_rtx;
12237 emit_insn (pat);
12239 switch (form_int)
12241 /* LT bit. */
12242 case 0:
12243 code = LT;
12244 break;
12245 /* GT bit. */
12246 case 1:
12247 code = GT;
12248 break;
12249 /* EQ bit. */
12250 case 2:
12251 code = EQ;
12252 break;
12253 /* UN bit. */
12254 case 3:
12255 emit_insn (gen_move_from_CR_ov_bit (target, scratch));
12256 return target;
12257 default:
12258 error ("argument 1 of __builtin_paired_predicate is out of range");
12259 return const0_rtx;
12262 tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx);
12263 emit_move_insn (target, tmp);
12264 return target;
12267 static rtx
12268 spe_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
12270 rtx pat, scratch, tmp;
12271 tree form = CALL_EXPR_ARG (exp, 0);
12272 tree arg0 = CALL_EXPR_ARG (exp, 1);
12273 tree arg1 = CALL_EXPR_ARG (exp, 2);
12274 rtx op0 = expand_normal (arg0);
12275 rtx op1 = expand_normal (arg1);
12276 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
12277 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
12278 int form_int;
12279 enum rtx_code code;
12281 if (TREE_CODE (form) != INTEGER_CST)
12283 error ("argument 1 of __builtin_spe_predicate must be a constant");
12284 return const0_rtx;
12286 else
12287 form_int = TREE_INT_CST_LOW (form);
12289 gcc_assert (mode0 == mode1);
12291 if (arg0 == error_mark_node || arg1 == error_mark_node)
12292 return const0_rtx;
12294 if (target == 0
12295 || GET_MODE (target) != SImode
12296 || ! (*insn_data[icode].operand[0].predicate) (target, SImode))
12297 target = gen_reg_rtx (SImode);
12299 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
12300 op0 = copy_to_mode_reg (mode0, op0);
12301 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
12302 op1 = copy_to_mode_reg (mode1, op1);
12304 scratch = gen_reg_rtx (CCmode);
12306 pat = GEN_FCN (icode) (scratch, op0, op1);
12307 if (! pat)
12308 return const0_rtx;
12309 emit_insn (pat);
12311 /* There are 4 variants for each predicate: _any_, _all_, _upper_,
12312 _lower_. We use one compare, but look in different bits of the
12313 CR for each variant.
12315 There are 2 elements in each SPE simd type (upper/lower). The CR
12316 bits are set as follows:
12318 BIT0 | BIT 1 | BIT 2 | BIT 3
12319 U | L | (U | L) | (U & L)
12321 So, for an "all" relationship, BIT 3 would be set.
12322 For an "any" relationship, BIT 2 would be set. Etc.
12324 Following traditional nomenclature, these bits map to:
12326 BIT0 | BIT 1 | BIT 2 | BIT 3
12327 LT | GT | EQ | OV
12329 Later, we will generate rtl to look in the LT/EQ/EQ/OV bits.
12332 switch (form_int)
12334 /* All variant. OV bit. */
12335 case 0:
12336 /* We need to get to the OV bit, which is the ORDERED bit. We
12337 could generate (ordered:SI (reg:CC xx) (const_int 0)), but
12338 that's ugly and will make validate_condition_mode die.
12339 So let's just use another pattern. */
12340 emit_insn (gen_move_from_CR_ov_bit (target, scratch));
12341 return target;
12342 /* Any variant. EQ bit. */
12343 case 1:
12344 code = EQ;
12345 break;
12346 /* Upper variant. LT bit. */
12347 case 2:
12348 code = LT;
12349 break;
12350 /* Lower variant. GT bit. */
12351 case 3:
12352 code = GT;
12353 break;
12354 default:
12355 error ("argument 1 of __builtin_spe_predicate is out of range");
12356 return const0_rtx;
12359 tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx);
12360 emit_move_insn (target, tmp);
12362 return target;
12365 /* The evsel builtins look like this:
12367 e = __builtin_spe_evsel_OP (a, b, c, d);
12369 and work like this:
12371 e[upper] = a[upper] *OP* b[upper] ? c[upper] : d[upper];
12372 e[lower] = a[lower] *OP* b[lower] ? c[lower] : d[lower];
12375 static rtx
12376 spe_expand_evsel_builtin (enum insn_code icode, tree exp, rtx target)
12378 rtx pat, scratch;
12379 tree arg0 = CALL_EXPR_ARG (exp, 0);
12380 tree arg1 = CALL_EXPR_ARG (exp, 1);
12381 tree arg2 = CALL_EXPR_ARG (exp, 2);
12382 tree arg3 = CALL_EXPR_ARG (exp, 3);
12383 rtx op0 = expand_normal (arg0);
12384 rtx op1 = expand_normal (arg1);
12385 rtx op2 = expand_normal (arg2);
12386 rtx op3 = expand_normal (arg3);
12387 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
12388 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
12390 gcc_assert (mode0 == mode1);
12392 if (arg0 == error_mark_node || arg1 == error_mark_node
12393 || arg2 == error_mark_node || arg3 == error_mark_node)
12394 return const0_rtx;
12396 if (target == 0
12397 || GET_MODE (target) != mode0
12398 || ! (*insn_data[icode].operand[0].predicate) (target, mode0))
12399 target = gen_reg_rtx (mode0);
12401 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
12402 op0 = copy_to_mode_reg (mode0, op0);
12403 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
12404 op1 = copy_to_mode_reg (mode0, op1);
12405 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
12406 op2 = copy_to_mode_reg (mode0, op2);
12407 if (! (*insn_data[icode].operand[1].predicate) (op3, mode1))
12408 op3 = copy_to_mode_reg (mode0, op3);
12410 /* Generate the compare. */
12411 scratch = gen_reg_rtx (CCmode);
12412 pat = GEN_FCN (icode) (scratch, op0, op1);
12413 if (! pat)
12414 return const0_rtx;
12415 emit_insn (pat);
12417 if (mode0 == V2SImode)
12418 emit_insn (gen_spe_evsel (target, op2, op3, scratch));
12419 else
12420 emit_insn (gen_spe_evsel_fs (target, op2, op3, scratch));
12422 return target;
12425 /* Expand an expression EXP that calls a built-in function,
12426 with result going to TARGET if that's convenient
12427 (and in mode MODE if that's convenient).
12428 SUBTARGET may be used as the target for computing one of EXP's operands.
12429 IGNORE is nonzero if the value is to be ignored. */
12431 static rtx
12432 rs6000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
12433 enum machine_mode mode ATTRIBUTE_UNUSED,
12434 int ignore ATTRIBUTE_UNUSED)
12436 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
12437 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
12438 const struct builtin_description *d;
12439 size_t i;
12440 rtx ret;
12441 bool success;
12443 switch (fcode)
12445 case RS6000_BUILTIN_RECIP:
12446 return rs6000_expand_binop_builtin (CODE_FOR_recipdf3, exp, target);
12448 case RS6000_BUILTIN_RECIPF:
12449 return rs6000_expand_binop_builtin (CODE_FOR_recipsf3, exp, target);
12451 case RS6000_BUILTIN_RSQRTF:
12452 return rs6000_expand_unop_builtin (CODE_FOR_rsqrtsf2, exp, target);
12454 case RS6000_BUILTIN_RSQRT:
12455 return rs6000_expand_unop_builtin (CODE_FOR_rsqrtdf2, exp, target);
12457 case RS6000_BUILTIN_BSWAP_HI:
12458 return rs6000_expand_unop_builtin (CODE_FOR_bswaphi2, exp, target);
12460 case POWER7_BUILTIN_BPERMD:
12461 return rs6000_expand_binop_builtin (((TARGET_64BIT)
12462 ? CODE_FOR_bpermd_di
12463 : CODE_FOR_bpermd_si), exp, target);
12465 case ALTIVEC_BUILTIN_MASK_FOR_LOAD:
12466 case ALTIVEC_BUILTIN_MASK_FOR_STORE:
12468 int icode = (int) CODE_FOR_altivec_lvsr;
12469 enum machine_mode tmode = insn_data[icode].operand[0].mode;
12470 enum machine_mode mode = insn_data[icode].operand[1].mode;
12471 tree arg;
12472 rtx op, addr, pat;
12474 gcc_assert (TARGET_ALTIVEC);
12476 arg = CALL_EXPR_ARG (exp, 0);
12477 gcc_assert (POINTER_TYPE_P (TREE_TYPE (arg)));
12478 op = expand_expr (arg, NULL_RTX, Pmode, EXPAND_NORMAL);
12479 addr = memory_address (mode, op);
12480 if (fcode == ALTIVEC_BUILTIN_MASK_FOR_STORE)
12481 op = addr;
12482 else
12484 /* For the load case need to negate the address. */
12485 op = gen_reg_rtx (GET_MODE (addr));
12486 emit_insn (gen_rtx_SET (VOIDmode, op,
12487 gen_rtx_NEG (GET_MODE (addr), addr)));
12489 op = gen_rtx_MEM (mode, op);
12491 if (target == 0
12492 || GET_MODE (target) != tmode
12493 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
12494 target = gen_reg_rtx (tmode);
12496 /*pat = gen_altivec_lvsr (target, op);*/
12497 pat = GEN_FCN (icode) (target, op);
12498 if (!pat)
12499 return 0;
12500 emit_insn (pat);
12502 return target;
12505 case ALTIVEC_BUILTIN_VCFUX:
12506 case ALTIVEC_BUILTIN_VCFSX:
12507 case ALTIVEC_BUILTIN_VCTUXS:
12508 case ALTIVEC_BUILTIN_VCTSXS:
12509 /* FIXME: There's got to be a nicer way to handle this case than
12510 constructing a new CALL_EXPR. */
12511 if (call_expr_nargs (exp) == 1)
12513 exp = build_call_nary (TREE_TYPE (exp), CALL_EXPR_FN (exp),
12514 2, CALL_EXPR_ARG (exp, 0), integer_zero_node);
12516 break;
12518 default:
12519 break;
12522 if (TARGET_ALTIVEC)
12524 ret = altivec_expand_builtin (exp, target, &success);
12526 if (success)
12527 return ret;
12529 if (TARGET_SPE)
12531 ret = spe_expand_builtin (exp, target, &success);
12533 if (success)
12534 return ret;
12536 if (TARGET_PAIRED_FLOAT)
12538 ret = paired_expand_builtin (exp, target, &success);
12540 if (success)
12541 return ret;
12544 gcc_assert (TARGET_ALTIVEC || TARGET_VSX || TARGET_SPE || TARGET_PAIRED_FLOAT);
12546 /* Handle simple unary operations. */
12547 d = (struct builtin_description *) bdesc_1arg;
12548 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
12549 if (d->code == fcode)
12550 return rs6000_expand_unop_builtin (d->icode, exp, target);
12552 /* Handle simple binary operations. */
12553 d = (struct builtin_description *) bdesc_2arg;
12554 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
12555 if (d->code == fcode)
12556 return rs6000_expand_binop_builtin (d->icode, exp, target);
12558 /* Handle simple ternary operations. */
12559 d = bdesc_3arg;
12560 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
12561 if (d->code == fcode)
12562 return rs6000_expand_ternop_builtin (d->icode, exp, target);
12564 gcc_unreachable ();
12567 static void
12568 rs6000_init_builtins (void)
12570 tree tdecl;
12571 tree ftype;
12573 V2SI_type_node = build_vector_type (intSI_type_node, 2);
12574 V2SF_type_node = build_vector_type (float_type_node, 2);
12575 V2DI_type_node = build_vector_type (intDI_type_node, 2);
12576 V2DF_type_node = build_vector_type (double_type_node, 2);
12577 V4HI_type_node = build_vector_type (intHI_type_node, 4);
12578 V4SI_type_node = build_vector_type (intSI_type_node, 4);
12579 V4SF_type_node = build_vector_type (float_type_node, 4);
12580 V8HI_type_node = build_vector_type (intHI_type_node, 8);
12581 V16QI_type_node = build_vector_type (intQI_type_node, 16);
12583 unsigned_V16QI_type_node = build_vector_type (unsigned_intQI_type_node, 16);
12584 unsigned_V8HI_type_node = build_vector_type (unsigned_intHI_type_node, 8);
12585 unsigned_V4SI_type_node = build_vector_type (unsigned_intSI_type_node, 4);
12586 unsigned_V2DI_type_node = build_vector_type (unsigned_intDI_type_node, 2);
12588 opaque_V2SF_type_node = build_opaque_vector_type (float_type_node, 2);
12589 opaque_V2SI_type_node = build_opaque_vector_type (intSI_type_node, 2);
12590 opaque_p_V2SI_type_node = build_pointer_type (opaque_V2SI_type_node);
12591 opaque_V4SI_type_node = build_opaque_vector_type (intSI_type_node, 4);
12593 /* The 'vector bool ...' types must be kept distinct from 'vector unsigned ...'
12594 types, especially in C++ land. Similarly, 'vector pixel' is distinct from
12595 'vector unsigned short'. */
12597 bool_char_type_node = build_distinct_type_copy (unsigned_intQI_type_node);
12598 bool_short_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
12599 bool_int_type_node = build_distinct_type_copy (unsigned_intSI_type_node);
12600 bool_long_type_node = build_distinct_type_copy (unsigned_intDI_type_node);
12601 pixel_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
12603 long_integer_type_internal_node = long_integer_type_node;
12604 long_unsigned_type_internal_node = long_unsigned_type_node;
12605 long_long_integer_type_internal_node = long_long_integer_type_node;
12606 long_long_unsigned_type_internal_node = long_long_unsigned_type_node;
12607 intQI_type_internal_node = intQI_type_node;
12608 uintQI_type_internal_node = unsigned_intQI_type_node;
12609 intHI_type_internal_node = intHI_type_node;
12610 uintHI_type_internal_node = unsigned_intHI_type_node;
12611 intSI_type_internal_node = intSI_type_node;
12612 uintSI_type_internal_node = unsigned_intSI_type_node;
12613 intDI_type_internal_node = intDI_type_node;
12614 uintDI_type_internal_node = unsigned_intDI_type_node;
12615 float_type_internal_node = float_type_node;
12616 double_type_internal_node = double_type_node;
12617 void_type_internal_node = void_type_node;
12619 /* Initialize the modes for builtin_function_type, mapping a machine mode to
12620 tree type node. */
12621 builtin_mode_to_type[QImode][0] = integer_type_node;
12622 builtin_mode_to_type[HImode][0] = integer_type_node;
12623 builtin_mode_to_type[SImode][0] = intSI_type_node;
12624 builtin_mode_to_type[SImode][1] = unsigned_intSI_type_node;
12625 builtin_mode_to_type[DImode][0] = intDI_type_node;
12626 builtin_mode_to_type[DImode][1] = unsigned_intDI_type_node;
12627 builtin_mode_to_type[SFmode][0] = float_type_node;
12628 builtin_mode_to_type[DFmode][0] = double_type_node;
12629 builtin_mode_to_type[V2SImode][0] = V2SI_type_node;
12630 builtin_mode_to_type[V2SFmode][0] = V2SF_type_node;
12631 builtin_mode_to_type[V2DImode][0] = V2DI_type_node;
12632 builtin_mode_to_type[V2DImode][1] = unsigned_V2DI_type_node;
12633 builtin_mode_to_type[V2DFmode][0] = V2DF_type_node;
12634 builtin_mode_to_type[V4HImode][0] = V4HI_type_node;
12635 builtin_mode_to_type[V4SImode][0] = V4SI_type_node;
12636 builtin_mode_to_type[V4SImode][1] = unsigned_V4SI_type_node;
12637 builtin_mode_to_type[V4SFmode][0] = V4SF_type_node;
12638 builtin_mode_to_type[V8HImode][0] = V8HI_type_node;
12639 builtin_mode_to_type[V8HImode][1] = unsigned_V8HI_type_node;
12640 builtin_mode_to_type[V16QImode][0] = V16QI_type_node;
12641 builtin_mode_to_type[V16QImode][1] = unsigned_V16QI_type_node;
12643 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12644 get_identifier ("__bool char"),
12645 bool_char_type_node);
12646 TYPE_NAME (bool_char_type_node) = tdecl;
12647 (*lang_hooks.decls.pushdecl) (tdecl);
12648 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12649 get_identifier ("__bool short"),
12650 bool_short_type_node);
12651 TYPE_NAME (bool_short_type_node) = tdecl;
12652 (*lang_hooks.decls.pushdecl) (tdecl);
12653 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12654 get_identifier ("__bool int"),
12655 bool_int_type_node);
12656 TYPE_NAME (bool_int_type_node) = tdecl;
12657 (*lang_hooks.decls.pushdecl) (tdecl);
12658 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL, get_identifier ("__pixel"),
12659 pixel_type_node);
12660 TYPE_NAME (pixel_type_node) = tdecl;
12661 (*lang_hooks.decls.pushdecl) (tdecl);
12663 bool_V16QI_type_node = build_vector_type (bool_char_type_node, 16);
12664 bool_V8HI_type_node = build_vector_type (bool_short_type_node, 8);
12665 bool_V4SI_type_node = build_vector_type (bool_int_type_node, 4);
12666 bool_V2DI_type_node = build_vector_type (bool_long_type_node, 2);
12667 pixel_V8HI_type_node = build_vector_type (pixel_type_node, 8);
12669 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12670 get_identifier ("__vector unsigned char"),
12671 unsigned_V16QI_type_node);
12672 TYPE_NAME (unsigned_V16QI_type_node) = tdecl;
12673 (*lang_hooks.decls.pushdecl) (tdecl);
12674 tdecl = build_decl (BUILTINS_LOCATION,
12675 TYPE_DECL, get_identifier ("__vector signed char"),
12676 V16QI_type_node);
12677 TYPE_NAME (V16QI_type_node) = tdecl;
12678 (*lang_hooks.decls.pushdecl) (tdecl);
12679 tdecl = build_decl (BUILTINS_LOCATION,
12680 TYPE_DECL, get_identifier ("__vector __bool char"),
12681 bool_V16QI_type_node);
12682 TYPE_NAME ( bool_V16QI_type_node) = tdecl;
12683 (*lang_hooks.decls.pushdecl) (tdecl);
12685 tdecl = build_decl (BUILTINS_LOCATION,
12686 TYPE_DECL, get_identifier ("__vector unsigned short"),
12687 unsigned_V8HI_type_node);
12688 TYPE_NAME (unsigned_V8HI_type_node) = tdecl;
12689 (*lang_hooks.decls.pushdecl) (tdecl);
12690 tdecl = build_decl (BUILTINS_LOCATION,
12691 TYPE_DECL, get_identifier ("__vector signed short"),
12692 V8HI_type_node);
12693 TYPE_NAME (V8HI_type_node) = tdecl;
12694 (*lang_hooks.decls.pushdecl) (tdecl);
12695 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12696 get_identifier ("__vector __bool short"),
12697 bool_V8HI_type_node);
12698 TYPE_NAME (bool_V8HI_type_node) = tdecl;
12699 (*lang_hooks.decls.pushdecl) (tdecl);
12701 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12702 get_identifier ("__vector unsigned int"),
12703 unsigned_V4SI_type_node);
12704 TYPE_NAME (unsigned_V4SI_type_node) = tdecl;
12705 (*lang_hooks.decls.pushdecl) (tdecl);
12706 tdecl = build_decl (BUILTINS_LOCATION,
12707 TYPE_DECL, get_identifier ("__vector signed int"),
12708 V4SI_type_node);
12709 TYPE_NAME (V4SI_type_node) = tdecl;
12710 (*lang_hooks.decls.pushdecl) (tdecl);
12711 tdecl = build_decl (BUILTINS_LOCATION,
12712 TYPE_DECL, get_identifier ("__vector __bool int"),
12713 bool_V4SI_type_node);
12714 TYPE_NAME (bool_V4SI_type_node) = tdecl;
12715 (*lang_hooks.decls.pushdecl) (tdecl);
12717 tdecl = build_decl (BUILTINS_LOCATION,
12718 TYPE_DECL, get_identifier ("__vector float"),
12719 V4SF_type_node);
12720 TYPE_NAME (V4SF_type_node) = tdecl;
12721 (*lang_hooks.decls.pushdecl) (tdecl);
12722 tdecl = build_decl (BUILTINS_LOCATION,
12723 TYPE_DECL, get_identifier ("__vector __pixel"),
12724 pixel_V8HI_type_node);
12725 TYPE_NAME (pixel_V8HI_type_node) = tdecl;
12726 (*lang_hooks.decls.pushdecl) (tdecl);
12728 if (TARGET_VSX)
12730 tdecl = build_decl (BUILTINS_LOCATION,
12731 TYPE_DECL, get_identifier ("__vector double"),
12732 V2DF_type_node);
12733 TYPE_NAME (V2DF_type_node) = tdecl;
12734 (*lang_hooks.decls.pushdecl) (tdecl);
12736 tdecl = build_decl (BUILTINS_LOCATION,
12737 TYPE_DECL, get_identifier ("__vector long"),
12738 V2DI_type_node);
12739 TYPE_NAME (V2DI_type_node) = tdecl;
12740 (*lang_hooks.decls.pushdecl) (tdecl);
12742 tdecl = build_decl (BUILTINS_LOCATION,
12743 TYPE_DECL, get_identifier ("__vector unsigned long"),
12744 unsigned_V2DI_type_node);
12745 TYPE_NAME (unsigned_V2DI_type_node) = tdecl;
12746 (*lang_hooks.decls.pushdecl) (tdecl);
12748 tdecl = build_decl (BUILTINS_LOCATION,
12749 TYPE_DECL, get_identifier ("__vector __bool long"),
12750 bool_V2DI_type_node);
12751 TYPE_NAME (bool_V2DI_type_node) = tdecl;
12752 (*lang_hooks.decls.pushdecl) (tdecl);
12755 if (TARGET_PAIRED_FLOAT)
12756 paired_init_builtins ();
12757 if (TARGET_SPE)
12758 spe_init_builtins ();
12759 if (TARGET_ALTIVEC)
12760 altivec_init_builtins ();
12761 if (TARGET_ALTIVEC || TARGET_SPE || TARGET_PAIRED_FLOAT || TARGET_VSX)
12762 rs6000_common_init_builtins ();
12763 if (TARGET_FRE)
12765 ftype = builtin_function_type (DFmode, DFmode, DFmode, VOIDmode,
12766 RS6000_BUILTIN_RECIP,
12767 "__builtin_recipdiv");
12768 def_builtin (MASK_POPCNTB, "__builtin_recipdiv", ftype,
12769 RS6000_BUILTIN_RECIP);
12771 if (TARGET_FRES)
12773 ftype = builtin_function_type (SFmode, SFmode, SFmode, VOIDmode,
12774 RS6000_BUILTIN_RECIPF,
12775 "__builtin_recipdivf");
12776 def_builtin (MASK_PPC_GFXOPT, "__builtin_recipdivf", ftype,
12777 RS6000_BUILTIN_RECIPF);
12779 if (TARGET_FRSQRTE)
12781 ftype = builtin_function_type (DFmode, DFmode, VOIDmode, VOIDmode,
12782 RS6000_BUILTIN_RSQRT,
12783 "__builtin_rsqrt");
12784 def_builtin (MASK_PPC_GFXOPT, "__builtin_rsqrt", ftype,
12785 RS6000_BUILTIN_RSQRT);
12787 if (TARGET_FRSQRTES)
12789 ftype = builtin_function_type (SFmode, SFmode, VOIDmode, VOIDmode,
12790 RS6000_BUILTIN_RSQRTF,
12791 "__builtin_rsqrtf");
12792 def_builtin (MASK_PPC_GFXOPT, "__builtin_rsqrtf", ftype,
12793 RS6000_BUILTIN_RSQRTF);
12795 if (TARGET_POPCNTD)
12797 enum machine_mode mode = (TARGET_64BIT) ? DImode : SImode;
12798 tree ftype = builtin_function_type (mode, mode, mode, VOIDmode,
12799 POWER7_BUILTIN_BPERMD,
12800 "__builtin_bpermd");
12801 def_builtin (MASK_POPCNTD, "__builtin_bpermd", ftype,
12802 POWER7_BUILTIN_BPERMD);
12804 if (TARGET_POWERPC)
12806 /* Don't use builtin_function_type here, as it maps HI/QI to SI. */
12807 tree ftype = build_function_type_list (unsigned_intHI_type_node,
12808 unsigned_intHI_type_node,
12809 NULL_TREE);
12810 def_builtin (MASK_POWERPC, "__builtin_bswap16", ftype,
12811 RS6000_BUILTIN_BSWAP_HI);
12814 #if TARGET_XCOFF
12815 /* AIX libm provides clog as __clog. */
12816 if (built_in_decls [BUILT_IN_CLOG])
12817 set_user_assembler_name (built_in_decls [BUILT_IN_CLOG], "__clog");
12818 #endif
12820 #ifdef SUBTARGET_INIT_BUILTINS
12821 SUBTARGET_INIT_BUILTINS;
12822 #endif
12825 /* Returns the rs6000 builtin decl for CODE. */
12827 static tree
12828 rs6000_builtin_decl (unsigned code, bool initialize_p ATTRIBUTE_UNUSED)
12830 if (code >= RS6000_BUILTIN_COUNT)
12831 return error_mark_node;
12833 return rs6000_builtin_decls[code];
12836 /* Search through a set of builtins and enable the mask bits.
12837 DESC is an array of builtins.
12838 SIZE is the total number of builtins.
12839 START is the builtin enum at which to start.
12840 END is the builtin enum at which to end. */
12841 static void
12842 enable_mask_for_builtins (struct builtin_description *desc, int size,
12843 enum rs6000_builtins start,
12844 enum rs6000_builtins end)
12846 int i;
12848 for (i = 0; i < size; ++i)
12849 if (desc[i].code == start)
12850 break;
12852 if (i == size)
12853 return;
12855 for (; i < size; ++i)
12857 /* Flip all the bits on. */
12858 desc[i].mask = target_flags;
12859 if (desc[i].code == end)
12860 break;
12864 static void
12865 spe_init_builtins (void)
12867 tree endlink = void_list_node;
12868 tree puint_type_node = build_pointer_type (unsigned_type_node);
12869 tree pushort_type_node = build_pointer_type (short_unsigned_type_node);
12870 struct builtin_description *d;
12871 size_t i;
12873 tree v2si_ftype_4_v2si
12874 = build_function_type
12875 (opaque_V2SI_type_node,
12876 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12877 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12878 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12879 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12880 endlink)))));
12882 tree v2sf_ftype_4_v2sf
12883 = build_function_type
12884 (opaque_V2SF_type_node,
12885 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12886 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12887 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12888 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12889 endlink)))));
12891 tree int_ftype_int_v2si_v2si
12892 = build_function_type
12893 (integer_type_node,
12894 tree_cons (NULL_TREE, integer_type_node,
12895 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12896 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12897 endlink))));
12899 tree int_ftype_int_v2sf_v2sf
12900 = build_function_type
12901 (integer_type_node,
12902 tree_cons (NULL_TREE, integer_type_node,
12903 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12904 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12905 endlink))));
12907 tree void_ftype_v2si_puint_int
12908 = build_function_type (void_type_node,
12909 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12910 tree_cons (NULL_TREE, puint_type_node,
12911 tree_cons (NULL_TREE,
12912 integer_type_node,
12913 endlink))));
12915 tree void_ftype_v2si_puint_char
12916 = build_function_type (void_type_node,
12917 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12918 tree_cons (NULL_TREE, puint_type_node,
12919 tree_cons (NULL_TREE,
12920 char_type_node,
12921 endlink))));
12923 tree void_ftype_v2si_pv2si_int
12924 = build_function_type (void_type_node,
12925 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12926 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
12927 tree_cons (NULL_TREE,
12928 integer_type_node,
12929 endlink))));
12931 tree void_ftype_v2si_pv2si_char
12932 = build_function_type (void_type_node,
12933 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12934 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
12935 tree_cons (NULL_TREE,
12936 char_type_node,
12937 endlink))));
12939 tree void_ftype_int
12940 = build_function_type (void_type_node,
12941 tree_cons (NULL_TREE, integer_type_node, endlink));
12943 tree int_ftype_void
12944 = build_function_type (integer_type_node, endlink);
12946 tree v2si_ftype_pv2si_int
12947 = build_function_type (opaque_V2SI_type_node,
12948 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
12949 tree_cons (NULL_TREE, integer_type_node,
12950 endlink)));
12952 tree v2si_ftype_puint_int
12953 = build_function_type (opaque_V2SI_type_node,
12954 tree_cons (NULL_TREE, puint_type_node,
12955 tree_cons (NULL_TREE, integer_type_node,
12956 endlink)));
12958 tree v2si_ftype_pushort_int
12959 = build_function_type (opaque_V2SI_type_node,
12960 tree_cons (NULL_TREE, pushort_type_node,
12961 tree_cons (NULL_TREE, integer_type_node,
12962 endlink)));
12964 tree v2si_ftype_signed_char
12965 = build_function_type (opaque_V2SI_type_node,
12966 tree_cons (NULL_TREE, signed_char_type_node,
12967 endlink));
12969 /* The initialization of the simple binary and unary builtins is
12970 done in rs6000_common_init_builtins, but we have to enable the
12971 mask bits here manually because we have run out of `target_flags'
12972 bits. We really need to redesign this mask business. */
12974 enable_mask_for_builtins ((struct builtin_description *) bdesc_2arg,
12975 ARRAY_SIZE (bdesc_2arg),
12976 SPE_BUILTIN_EVADDW,
12977 SPE_BUILTIN_EVXOR);
12978 enable_mask_for_builtins ((struct builtin_description *) bdesc_1arg,
12979 ARRAY_SIZE (bdesc_1arg),
12980 SPE_BUILTIN_EVABS,
12981 SPE_BUILTIN_EVSUBFUSIAAW);
12982 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_predicates,
12983 ARRAY_SIZE (bdesc_spe_predicates),
12984 SPE_BUILTIN_EVCMPEQ,
12985 SPE_BUILTIN_EVFSTSTLT);
12986 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_evsel,
12987 ARRAY_SIZE (bdesc_spe_evsel),
12988 SPE_BUILTIN_EVSEL_CMPGTS,
12989 SPE_BUILTIN_EVSEL_FSTSTEQ);
12991 (*lang_hooks.decls.pushdecl)
12992 (build_decl (BUILTINS_LOCATION, TYPE_DECL,
12993 get_identifier ("__ev64_opaque__"),
12994 opaque_V2SI_type_node));
12996 /* Initialize irregular SPE builtins. */
12998 def_builtin (target_flags, "__builtin_spe_mtspefscr", void_ftype_int, SPE_BUILTIN_MTSPEFSCR);
12999 def_builtin (target_flags, "__builtin_spe_mfspefscr", int_ftype_void, SPE_BUILTIN_MFSPEFSCR);
13000 def_builtin (target_flags, "__builtin_spe_evstddx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDDX);
13001 def_builtin (target_flags, "__builtin_spe_evstdhx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDHX);
13002 def_builtin (target_flags, "__builtin_spe_evstdwx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDWX);
13003 def_builtin (target_flags, "__builtin_spe_evstwhex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHEX);
13004 def_builtin (target_flags, "__builtin_spe_evstwhox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHOX);
13005 def_builtin (target_flags, "__builtin_spe_evstwwex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWEX);
13006 def_builtin (target_flags, "__builtin_spe_evstwwox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWOX);
13007 def_builtin (target_flags, "__builtin_spe_evstdd", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDD);
13008 def_builtin (target_flags, "__builtin_spe_evstdh", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDH);
13009 def_builtin (target_flags, "__builtin_spe_evstdw", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDW);
13010 def_builtin (target_flags, "__builtin_spe_evstwhe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHE);
13011 def_builtin (target_flags, "__builtin_spe_evstwho", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHO);
13012 def_builtin (target_flags, "__builtin_spe_evstwwe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWE);
13013 def_builtin (target_flags, "__builtin_spe_evstwwo", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWO);
13014 def_builtin (target_flags, "__builtin_spe_evsplatfi", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATFI);
13015 def_builtin (target_flags, "__builtin_spe_evsplati", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATI);
13017 /* Loads. */
13018 def_builtin (target_flags, "__builtin_spe_evlddx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDDX);
13019 def_builtin (target_flags, "__builtin_spe_evldwx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDWX);
13020 def_builtin (target_flags, "__builtin_spe_evldhx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDHX);
13021 def_builtin (target_flags, "__builtin_spe_evlwhex", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHEX);
13022 def_builtin (target_flags, "__builtin_spe_evlwhoux", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOUX);
13023 def_builtin (target_flags, "__builtin_spe_evlwhosx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOSX);
13024 def_builtin (target_flags, "__builtin_spe_evlwwsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLATX);
13025 def_builtin (target_flags, "__builtin_spe_evlwhsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLATX);
13026 def_builtin (target_flags, "__builtin_spe_evlhhesplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLATX);
13027 def_builtin (target_flags, "__builtin_spe_evlhhousplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLATX);
13028 def_builtin (target_flags, "__builtin_spe_evlhhossplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLATX);
13029 def_builtin (target_flags, "__builtin_spe_evldd", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDD);
13030 def_builtin (target_flags, "__builtin_spe_evldw", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDW);
13031 def_builtin (target_flags, "__builtin_spe_evldh", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDH);
13032 def_builtin (target_flags, "__builtin_spe_evlhhesplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLAT);
13033 def_builtin (target_flags, "__builtin_spe_evlhhossplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLAT);
13034 def_builtin (target_flags, "__builtin_spe_evlhhousplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLAT);
13035 def_builtin (target_flags, "__builtin_spe_evlwhe", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHE);
13036 def_builtin (target_flags, "__builtin_spe_evlwhos", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOS);
13037 def_builtin (target_flags, "__builtin_spe_evlwhou", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOU);
13038 def_builtin (target_flags, "__builtin_spe_evlwhsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLAT);
13039 def_builtin (target_flags, "__builtin_spe_evlwwsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLAT);
13041 /* Predicates. */
13042 d = (struct builtin_description *) bdesc_spe_predicates;
13043 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, d++)
13045 tree type;
13047 switch (insn_data[d->icode].operand[1].mode)
13049 case V2SImode:
13050 type = int_ftype_int_v2si_v2si;
13051 break;
13052 case V2SFmode:
13053 type = int_ftype_int_v2sf_v2sf;
13054 break;
13055 default:
13056 gcc_unreachable ();
13059 def_builtin (d->mask, d->name, type, d->code);
13062 /* Evsel predicates. */
13063 d = (struct builtin_description *) bdesc_spe_evsel;
13064 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, d++)
13066 tree type;
13068 switch (insn_data[d->icode].operand[1].mode)
13070 case V2SImode:
13071 type = v2si_ftype_4_v2si;
13072 break;
13073 case V2SFmode:
13074 type = v2sf_ftype_4_v2sf;
13075 break;
13076 default:
13077 gcc_unreachable ();
13080 def_builtin (d->mask, d->name, type, d->code);
13084 static void
13085 paired_init_builtins (void)
13087 const struct builtin_description *d;
13088 size_t i;
13089 tree endlink = void_list_node;
13091 tree int_ftype_int_v2sf_v2sf
13092 = build_function_type
13093 (integer_type_node,
13094 tree_cons (NULL_TREE, integer_type_node,
13095 tree_cons (NULL_TREE, V2SF_type_node,
13096 tree_cons (NULL_TREE, V2SF_type_node,
13097 endlink))));
13098 tree pcfloat_type_node =
13099 build_pointer_type (build_qualified_type
13100 (float_type_node, TYPE_QUAL_CONST));
13102 tree v2sf_ftype_long_pcfloat = build_function_type_list (V2SF_type_node,
13103 long_integer_type_node,
13104 pcfloat_type_node,
13105 NULL_TREE);
13106 tree void_ftype_v2sf_long_pcfloat =
13107 build_function_type_list (void_type_node,
13108 V2SF_type_node,
13109 long_integer_type_node,
13110 pcfloat_type_node,
13111 NULL_TREE);
13114 def_builtin (0, "__builtin_paired_lx", v2sf_ftype_long_pcfloat,
13115 PAIRED_BUILTIN_LX);
13118 def_builtin (0, "__builtin_paired_stx", void_ftype_v2sf_long_pcfloat,
13119 PAIRED_BUILTIN_STX);
13121 /* Predicates. */
13122 d = bdesc_paired_preds;
13123 for (i = 0; i < ARRAY_SIZE (bdesc_paired_preds); ++i, d++)
13125 tree type;
13127 switch (insn_data[d->icode].operand[1].mode)
13129 case V2SFmode:
13130 type = int_ftype_int_v2sf_v2sf;
13131 break;
13132 default:
13133 gcc_unreachable ();
13136 def_builtin (d->mask, d->name, type, d->code);
13140 static void
13141 altivec_init_builtins (void)
13143 const struct builtin_description *d;
13144 const struct builtin_description_predicates *dp;
13145 size_t i;
13146 tree ftype;
13148 tree pvoid_type_node = build_pointer_type (void_type_node);
13150 tree pcvoid_type_node
13151 = build_pointer_type (build_qualified_type (void_type_node,
13152 TYPE_QUAL_CONST));
13154 tree int_ftype_opaque
13155 = build_function_type_list (integer_type_node,
13156 opaque_V4SI_type_node, NULL_TREE);
13157 tree opaque_ftype_opaque
13158 = build_function_type (integer_type_node,
13159 NULL_TREE);
13160 tree opaque_ftype_opaque_int
13161 = build_function_type_list (opaque_V4SI_type_node,
13162 opaque_V4SI_type_node, integer_type_node, NULL_TREE);
13163 tree opaque_ftype_opaque_opaque_int
13164 = build_function_type_list (opaque_V4SI_type_node,
13165 opaque_V4SI_type_node, opaque_V4SI_type_node,
13166 integer_type_node, NULL_TREE);
13167 tree int_ftype_int_opaque_opaque
13168 = build_function_type_list (integer_type_node,
13169 integer_type_node, opaque_V4SI_type_node,
13170 opaque_V4SI_type_node, NULL_TREE);
13171 tree int_ftype_int_v4si_v4si
13172 = build_function_type_list (integer_type_node,
13173 integer_type_node, V4SI_type_node,
13174 V4SI_type_node, NULL_TREE);
13175 tree void_ftype_v4si
13176 = build_function_type_list (void_type_node, V4SI_type_node, NULL_TREE);
13177 tree v8hi_ftype_void
13178 = build_function_type (V8HI_type_node, void_list_node);
13179 tree void_ftype_void
13180 = build_function_type (void_type_node, void_list_node);
13181 tree void_ftype_int
13182 = build_function_type_list (void_type_node, integer_type_node, NULL_TREE);
13184 tree opaque_ftype_long_pcvoid
13185 = build_function_type_list (opaque_V4SI_type_node,
13186 long_integer_type_node, pcvoid_type_node,
13187 NULL_TREE);
13188 tree v16qi_ftype_long_pcvoid
13189 = build_function_type_list (V16QI_type_node,
13190 long_integer_type_node, pcvoid_type_node,
13191 NULL_TREE);
13192 tree v8hi_ftype_long_pcvoid
13193 = build_function_type_list (V8HI_type_node,
13194 long_integer_type_node, pcvoid_type_node,
13195 NULL_TREE);
13196 tree v4si_ftype_long_pcvoid
13197 = build_function_type_list (V4SI_type_node,
13198 long_integer_type_node, pcvoid_type_node,
13199 NULL_TREE);
13200 tree v4sf_ftype_long_pcvoid
13201 = build_function_type_list (V4SF_type_node,
13202 long_integer_type_node, pcvoid_type_node,
13203 NULL_TREE);
13204 tree v2df_ftype_long_pcvoid
13205 = build_function_type_list (V2DF_type_node,
13206 long_integer_type_node, pcvoid_type_node,
13207 NULL_TREE);
13208 tree v2di_ftype_long_pcvoid
13209 = build_function_type_list (V2DI_type_node,
13210 long_integer_type_node, pcvoid_type_node,
13211 NULL_TREE);
13213 tree void_ftype_opaque_long_pvoid
13214 = build_function_type_list (void_type_node,
13215 opaque_V4SI_type_node, long_integer_type_node,
13216 pvoid_type_node, NULL_TREE);
13217 tree void_ftype_v4si_long_pvoid
13218 = build_function_type_list (void_type_node,
13219 V4SI_type_node, long_integer_type_node,
13220 pvoid_type_node, NULL_TREE);
13221 tree void_ftype_v16qi_long_pvoid
13222 = build_function_type_list (void_type_node,
13223 V16QI_type_node, long_integer_type_node,
13224 pvoid_type_node, NULL_TREE);
13225 tree void_ftype_v8hi_long_pvoid
13226 = build_function_type_list (void_type_node,
13227 V8HI_type_node, long_integer_type_node,
13228 pvoid_type_node, NULL_TREE);
13229 tree void_ftype_v4sf_long_pvoid
13230 = build_function_type_list (void_type_node,
13231 V4SF_type_node, long_integer_type_node,
13232 pvoid_type_node, NULL_TREE);
13233 tree void_ftype_v2df_long_pvoid
13234 = build_function_type_list (void_type_node,
13235 V2DF_type_node, long_integer_type_node,
13236 pvoid_type_node, NULL_TREE);
13237 tree void_ftype_v2di_long_pvoid
13238 = build_function_type_list (void_type_node,
13239 V2DI_type_node, long_integer_type_node,
13240 pvoid_type_node, NULL_TREE);
13241 tree int_ftype_int_v8hi_v8hi
13242 = build_function_type_list (integer_type_node,
13243 integer_type_node, V8HI_type_node,
13244 V8HI_type_node, NULL_TREE);
13245 tree int_ftype_int_v16qi_v16qi
13246 = build_function_type_list (integer_type_node,
13247 integer_type_node, V16QI_type_node,
13248 V16QI_type_node, NULL_TREE);
13249 tree int_ftype_int_v4sf_v4sf
13250 = build_function_type_list (integer_type_node,
13251 integer_type_node, V4SF_type_node,
13252 V4SF_type_node, NULL_TREE);
13253 tree int_ftype_int_v2df_v2df
13254 = build_function_type_list (integer_type_node,
13255 integer_type_node, V2DF_type_node,
13256 V2DF_type_node, NULL_TREE);
13257 tree v4si_ftype_v4si
13258 = build_function_type_list (V4SI_type_node, V4SI_type_node, NULL_TREE);
13259 tree v8hi_ftype_v8hi
13260 = build_function_type_list (V8HI_type_node, V8HI_type_node, NULL_TREE);
13261 tree v16qi_ftype_v16qi
13262 = build_function_type_list (V16QI_type_node, V16QI_type_node, NULL_TREE);
13263 tree v4sf_ftype_v4sf
13264 = build_function_type_list (V4SF_type_node, V4SF_type_node, NULL_TREE);
13265 tree v2df_ftype_v2df
13266 = build_function_type_list (V2DF_type_node, V2DF_type_node, NULL_TREE);
13267 tree void_ftype_pcvoid_int_int
13268 = build_function_type_list (void_type_node,
13269 pcvoid_type_node, integer_type_node,
13270 integer_type_node, NULL_TREE);
13272 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mtvscr", void_ftype_v4si, ALTIVEC_BUILTIN_MTVSCR);
13273 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mfvscr", v8hi_ftype_void, ALTIVEC_BUILTIN_MFVSCR);
13274 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dssall", void_ftype_void, ALTIVEC_BUILTIN_DSSALL);
13275 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dss", void_ftype_int, ALTIVEC_BUILTIN_DSS);
13276 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSL);
13277 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSR);
13278 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEBX);
13279 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEHX);
13280 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEWX);
13281 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvxl", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVXL);
13282 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVX);
13283 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVX);
13284 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvewx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVEWX);
13285 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvxl", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVXL);
13286 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvebx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVEBX);
13287 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvehx", void_ftype_v8hi_long_pvoid, ALTIVEC_BUILTIN_STVEHX);
13288 def_builtin (MASK_ALTIVEC, "__builtin_vec_ld", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LD);
13289 def_builtin (MASK_ALTIVEC, "__builtin_vec_lde", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDE);
13290 def_builtin (MASK_ALTIVEC, "__builtin_vec_ldl", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDL);
13291 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSL);
13292 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSR);
13293 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEBX);
13294 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEHX);
13295 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEWX);
13296 def_builtin (MASK_ALTIVEC, "__builtin_vec_st", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_ST);
13297 def_builtin (MASK_ALTIVEC, "__builtin_vec_ste", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STE);
13298 def_builtin (MASK_ALTIVEC, "__builtin_vec_stl", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STL);
13299 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvewx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEWX);
13300 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvebx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEBX);
13301 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvehx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEHX);
13303 def_builtin (MASK_VSX, "__builtin_vsx_lxvd2x_v2df", v2df_ftype_long_pcvoid,
13304 VSX_BUILTIN_LXVD2X_V2DF);
13305 def_builtin (MASK_VSX, "__builtin_vsx_lxvd2x_v2di", v2di_ftype_long_pcvoid,
13306 VSX_BUILTIN_LXVD2X_V2DI);
13307 def_builtin (MASK_VSX, "__builtin_vsx_lxvw4x_v4sf", v4sf_ftype_long_pcvoid,
13308 VSX_BUILTIN_LXVW4X_V4SF);
13309 def_builtin (MASK_VSX, "__builtin_vsx_lxvw4x_v4si", v4si_ftype_long_pcvoid,
13310 VSX_BUILTIN_LXVW4X_V4SI);
13311 def_builtin (MASK_VSX, "__builtin_vsx_lxvw4x_v8hi",
13312 v8hi_ftype_long_pcvoid, VSX_BUILTIN_LXVW4X_V8HI);
13313 def_builtin (MASK_VSX, "__builtin_vsx_lxvw4x_v16qi",
13314 v16qi_ftype_long_pcvoid, VSX_BUILTIN_LXVW4X_V16QI);
13315 def_builtin (MASK_VSX, "__builtin_vsx_stxvd2x_v2df",
13316 void_ftype_v2df_long_pvoid, VSX_BUILTIN_STXVD2X_V2DF);
13317 def_builtin (MASK_VSX, "__builtin_vsx_stxvd2x_v2di",
13318 void_ftype_v2di_long_pvoid, VSX_BUILTIN_STXVD2X_V2DI);
13319 def_builtin (MASK_VSX, "__builtin_vsx_stxvw4x_v4sf",
13320 void_ftype_v4sf_long_pvoid, VSX_BUILTIN_STXVW4X_V4SF);
13321 def_builtin (MASK_VSX, "__builtin_vsx_stxvw4x_v4si",
13322 void_ftype_v4si_long_pvoid, VSX_BUILTIN_STXVW4X_V4SI);
13323 def_builtin (MASK_VSX, "__builtin_vsx_stxvw4x_v8hi",
13324 void_ftype_v8hi_long_pvoid, VSX_BUILTIN_STXVW4X_V8HI);
13325 def_builtin (MASK_VSX, "__builtin_vsx_stxvw4x_v16qi",
13326 void_ftype_v16qi_long_pvoid, VSX_BUILTIN_STXVW4X_V16QI);
13327 def_builtin (MASK_VSX, "__builtin_vec_vsx_ld", opaque_ftype_long_pcvoid,
13328 VSX_BUILTIN_VEC_LD);
13329 def_builtin (MASK_VSX, "__builtin_vec_vsx_st", void_ftype_opaque_long_pvoid,
13330 VSX_BUILTIN_VEC_ST);
13332 if (rs6000_cpu == PROCESSOR_CELL)
13334 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvlx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVLX);
13335 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvlxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVLXL);
13336 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvrx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVRX);
13337 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvrxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVRXL);
13339 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvlx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVLX);
13340 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvlxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVLXL);
13341 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvrx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVRX);
13342 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvrxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVRXL);
13344 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvlx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVLX);
13345 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvlxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVLXL);
13346 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvrx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVRX);
13347 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvrxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVRXL);
13349 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvlx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVLX);
13350 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvlxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVLXL);
13351 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvrx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVRX);
13352 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvrxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVRXL);
13354 def_builtin (MASK_ALTIVEC, "__builtin_vec_step", int_ftype_opaque, ALTIVEC_BUILTIN_VEC_STEP);
13355 def_builtin (MASK_ALTIVEC, "__builtin_vec_splats", opaque_ftype_opaque, ALTIVEC_BUILTIN_VEC_SPLATS);
13356 def_builtin (MASK_ALTIVEC, "__builtin_vec_promote", opaque_ftype_opaque, ALTIVEC_BUILTIN_VEC_PROMOTE);
13358 def_builtin (MASK_ALTIVEC, "__builtin_vec_sld", opaque_ftype_opaque_opaque_int, ALTIVEC_BUILTIN_VEC_SLD);
13359 def_builtin (MASK_ALTIVEC, "__builtin_vec_splat", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_SPLAT);
13360 def_builtin (MASK_ALTIVEC, "__builtin_vec_extract", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_EXTRACT);
13361 def_builtin (MASK_ALTIVEC, "__builtin_vec_insert", opaque_ftype_opaque_opaque_int, ALTIVEC_BUILTIN_VEC_INSERT);
13362 def_builtin (MASK_ALTIVEC, "__builtin_vec_vspltw", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTW);
13363 def_builtin (MASK_ALTIVEC, "__builtin_vec_vsplth", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTH);
13364 def_builtin (MASK_ALTIVEC, "__builtin_vec_vspltb", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTB);
13365 def_builtin (MASK_ALTIVEC, "__builtin_vec_ctf", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTF);
13366 def_builtin (MASK_ALTIVEC, "__builtin_vec_vcfsx", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFSX);
13367 def_builtin (MASK_ALTIVEC, "__builtin_vec_vcfux", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFUX);
13368 def_builtin (MASK_ALTIVEC, "__builtin_vec_cts", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTS);
13369 def_builtin (MASK_ALTIVEC, "__builtin_vec_ctu", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTU);
13371 /* Add the DST variants. */
13372 d = bdesc_dst;
13373 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
13374 def_builtin (d->mask, d->name, void_ftype_pcvoid_int_int, d->code);
13376 /* Initialize the predicates. */
13377 dp = bdesc_altivec_preds;
13378 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
13380 enum machine_mode mode1;
13381 tree type;
13382 bool is_overloaded = ((dp->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
13383 && dp->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
13384 || (dp->code >= VSX_BUILTIN_OVERLOADED_FIRST
13385 && dp->code <= VSX_BUILTIN_OVERLOADED_LAST));
13387 if (is_overloaded)
13388 mode1 = VOIDmode;
13389 else
13390 mode1 = insn_data[dp->icode].operand[1].mode;
13392 switch (mode1)
13394 case VOIDmode:
13395 type = int_ftype_int_opaque_opaque;
13396 break;
13397 case V4SImode:
13398 type = int_ftype_int_v4si_v4si;
13399 break;
13400 case V8HImode:
13401 type = int_ftype_int_v8hi_v8hi;
13402 break;
13403 case V16QImode:
13404 type = int_ftype_int_v16qi_v16qi;
13405 break;
13406 case V4SFmode:
13407 type = int_ftype_int_v4sf_v4sf;
13408 break;
13409 case V2DFmode:
13410 type = int_ftype_int_v2df_v2df;
13411 break;
13412 default:
13413 gcc_unreachable ();
13416 def_builtin (dp->mask, dp->name, type, dp->code);
13419 /* Initialize the abs* operators. */
13420 d = bdesc_abs;
13421 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
13423 enum machine_mode mode0;
13424 tree type;
13426 mode0 = insn_data[d->icode].operand[0].mode;
13428 switch (mode0)
13430 case V4SImode:
13431 type = v4si_ftype_v4si;
13432 break;
13433 case V8HImode:
13434 type = v8hi_ftype_v8hi;
13435 break;
13436 case V16QImode:
13437 type = v16qi_ftype_v16qi;
13438 break;
13439 case V4SFmode:
13440 type = v4sf_ftype_v4sf;
13441 break;
13442 case V2DFmode:
13443 type = v2df_ftype_v2df;
13444 break;
13445 default:
13446 gcc_unreachable ();
13449 def_builtin (d->mask, d->name, type, d->code);
13452 if (TARGET_ALTIVEC)
13454 tree decl;
13456 /* Initialize target builtin that implements
13457 targetm.vectorize.builtin_mask_for_load. */
13459 decl = add_builtin_function ("__builtin_altivec_mask_for_load",
13460 v16qi_ftype_long_pcvoid,
13461 ALTIVEC_BUILTIN_MASK_FOR_LOAD,
13462 BUILT_IN_MD, NULL, NULL_TREE);
13463 TREE_READONLY (decl) = 1;
13464 /* Record the decl. Will be used by rs6000_builtin_mask_for_load. */
13465 altivec_builtin_mask_for_load = decl;
13468 /* Access to the vec_init patterns. */
13469 ftype = build_function_type_list (V4SI_type_node, integer_type_node,
13470 integer_type_node, integer_type_node,
13471 integer_type_node, NULL_TREE);
13472 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v4si", ftype,
13473 ALTIVEC_BUILTIN_VEC_INIT_V4SI);
13475 ftype = build_function_type_list (V8HI_type_node, short_integer_type_node,
13476 short_integer_type_node,
13477 short_integer_type_node,
13478 short_integer_type_node,
13479 short_integer_type_node,
13480 short_integer_type_node,
13481 short_integer_type_node,
13482 short_integer_type_node, NULL_TREE);
13483 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v8hi", ftype,
13484 ALTIVEC_BUILTIN_VEC_INIT_V8HI);
13486 ftype = build_function_type_list (V16QI_type_node, char_type_node,
13487 char_type_node, char_type_node,
13488 char_type_node, char_type_node,
13489 char_type_node, char_type_node,
13490 char_type_node, char_type_node,
13491 char_type_node, char_type_node,
13492 char_type_node, char_type_node,
13493 char_type_node, char_type_node,
13494 char_type_node, NULL_TREE);
13495 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v16qi", ftype,
13496 ALTIVEC_BUILTIN_VEC_INIT_V16QI);
13498 ftype = build_function_type_list (V4SF_type_node, float_type_node,
13499 float_type_node, float_type_node,
13500 float_type_node, NULL_TREE);
13501 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v4sf", ftype,
13502 ALTIVEC_BUILTIN_VEC_INIT_V4SF);
13504 if (TARGET_VSX)
13506 ftype = build_function_type_list (V2DF_type_node, double_type_node,
13507 double_type_node, NULL_TREE);
13508 def_builtin (MASK_VSX, "__builtin_vec_init_v2df", ftype,
13509 VSX_BUILTIN_VEC_INIT_V2DF);
13511 ftype = build_function_type_list (V2DI_type_node, intDI_type_node,
13512 intDI_type_node, NULL_TREE);
13513 def_builtin (MASK_VSX, "__builtin_vec_init_v2di", ftype,
13514 VSX_BUILTIN_VEC_INIT_V2DI);
13517 /* Access to the vec_set patterns. */
13518 ftype = build_function_type_list (V4SI_type_node, V4SI_type_node,
13519 intSI_type_node,
13520 integer_type_node, NULL_TREE);
13521 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v4si", ftype,
13522 ALTIVEC_BUILTIN_VEC_SET_V4SI);
13524 ftype = build_function_type_list (V8HI_type_node, V8HI_type_node,
13525 intHI_type_node,
13526 integer_type_node, NULL_TREE);
13527 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v8hi", ftype,
13528 ALTIVEC_BUILTIN_VEC_SET_V8HI);
13530 ftype = build_function_type_list (V16QI_type_node, V16QI_type_node,
13531 intQI_type_node,
13532 integer_type_node, NULL_TREE);
13533 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v16qi", ftype,
13534 ALTIVEC_BUILTIN_VEC_SET_V16QI);
13536 ftype = build_function_type_list (V4SF_type_node, V4SF_type_node,
13537 float_type_node,
13538 integer_type_node, NULL_TREE);
13539 def_builtin (MASK_ALTIVEC|MASK_VSX, "__builtin_vec_set_v4sf", ftype,
13540 ALTIVEC_BUILTIN_VEC_SET_V4SF);
13542 if (TARGET_VSX)
13544 ftype = build_function_type_list (V2DF_type_node, V2DF_type_node,
13545 double_type_node,
13546 integer_type_node, NULL_TREE);
13547 def_builtin (MASK_VSX, "__builtin_vec_set_v2df", ftype,
13548 VSX_BUILTIN_VEC_SET_V2DF);
13550 ftype = build_function_type_list (V2DI_type_node, V2DI_type_node,
13551 intDI_type_node,
13552 integer_type_node, NULL_TREE);
13553 def_builtin (MASK_VSX, "__builtin_vec_set_v2di", ftype,
13554 VSX_BUILTIN_VEC_SET_V2DI);
13557 /* Access to the vec_extract patterns. */
13558 ftype = build_function_type_list (intSI_type_node, V4SI_type_node,
13559 integer_type_node, NULL_TREE);
13560 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v4si", ftype,
13561 ALTIVEC_BUILTIN_VEC_EXT_V4SI);
13563 ftype = build_function_type_list (intHI_type_node, V8HI_type_node,
13564 integer_type_node, NULL_TREE);
13565 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v8hi", ftype,
13566 ALTIVEC_BUILTIN_VEC_EXT_V8HI);
13568 ftype = build_function_type_list (intQI_type_node, V16QI_type_node,
13569 integer_type_node, NULL_TREE);
13570 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v16qi", ftype,
13571 ALTIVEC_BUILTIN_VEC_EXT_V16QI);
13573 ftype = build_function_type_list (float_type_node, V4SF_type_node,
13574 integer_type_node, NULL_TREE);
13575 def_builtin (MASK_ALTIVEC|MASK_VSX, "__builtin_vec_ext_v4sf", ftype,
13576 ALTIVEC_BUILTIN_VEC_EXT_V4SF);
13578 if (TARGET_VSX)
13580 ftype = build_function_type_list (double_type_node, V2DF_type_node,
13581 integer_type_node, NULL_TREE);
13582 def_builtin (MASK_VSX, "__builtin_vec_ext_v2df", ftype,
13583 VSX_BUILTIN_VEC_EXT_V2DF);
13585 ftype = build_function_type_list (intDI_type_node, V2DI_type_node,
13586 integer_type_node, NULL_TREE);
13587 def_builtin (MASK_VSX, "__builtin_vec_ext_v2di", ftype,
13588 VSX_BUILTIN_VEC_EXT_V2DI);
13592 /* Hash function for builtin functions with up to 3 arguments and a return
13593 type. */
13594 static unsigned
13595 builtin_hash_function (const void *hash_entry)
13597 unsigned ret = 0;
13598 int i;
13599 const struct builtin_hash_struct *bh =
13600 (const struct builtin_hash_struct *) hash_entry;
13602 for (i = 0; i < 4; i++)
13604 ret = (ret * (unsigned)MAX_MACHINE_MODE) + ((unsigned)bh->mode[i]);
13605 ret = (ret * 2) + bh->uns_p[i];
13608 return ret;
13611 /* Compare builtin hash entries H1 and H2 for equivalence. */
13612 static int
13613 builtin_hash_eq (const void *h1, const void *h2)
13615 const struct builtin_hash_struct *p1 = (const struct builtin_hash_struct *) h1;
13616 const struct builtin_hash_struct *p2 = (const struct builtin_hash_struct *) h2;
13618 return ((p1->mode[0] == p2->mode[0])
13619 && (p1->mode[1] == p2->mode[1])
13620 && (p1->mode[2] == p2->mode[2])
13621 && (p1->mode[3] == p2->mode[3])
13622 && (p1->uns_p[0] == p2->uns_p[0])
13623 && (p1->uns_p[1] == p2->uns_p[1])
13624 && (p1->uns_p[2] == p2->uns_p[2])
13625 && (p1->uns_p[3] == p2->uns_p[3]));
13628 /* Map types for builtin functions with an explicit return type and up to 3
13629 arguments. Functions with fewer than 3 arguments use VOIDmode as the type
13630 of the argument. */
13631 static tree
13632 builtin_function_type (enum machine_mode mode_ret, enum machine_mode mode_arg0,
13633 enum machine_mode mode_arg1, enum machine_mode mode_arg2,
13634 enum rs6000_builtins builtin, const char *name)
13636 struct builtin_hash_struct h;
13637 struct builtin_hash_struct *h2;
13638 void **found;
13639 int num_args = 3;
13640 int i;
13641 tree ret_type = NULL_TREE;
13642 tree arg_type[3] = { NULL_TREE, NULL_TREE, NULL_TREE };
13643 tree args;
13645 /* Create builtin_hash_table. */
13646 if (builtin_hash_table == NULL)
13647 builtin_hash_table = htab_create_ggc (1500, builtin_hash_function,
13648 builtin_hash_eq, NULL);
13650 h.type = NULL_TREE;
13651 h.mode[0] = mode_ret;
13652 h.mode[1] = mode_arg0;
13653 h.mode[2] = mode_arg1;
13654 h.mode[3] = mode_arg2;
13655 h.uns_p[0] = 0;
13656 h.uns_p[1] = 0;
13657 h.uns_p[2] = 0;
13658 h.uns_p[3] = 0;
13660 /* If the builtin is a type that produces unsigned results or takes unsigned
13661 arguments, and it is returned as a decl for the vectorizer (such as
13662 widening multiplies, permute), make sure the arguments and return value
13663 are type correct. */
13664 switch (builtin)
13666 /* unsigned 2 argument functions. */
13667 case ALTIVEC_BUILTIN_VMULEUB_UNS:
13668 case ALTIVEC_BUILTIN_VMULEUH_UNS:
13669 case ALTIVEC_BUILTIN_VMULOUB_UNS:
13670 case ALTIVEC_BUILTIN_VMULOUH_UNS:
13671 h.uns_p[0] = 1;
13672 h.uns_p[1] = 1;
13673 h.uns_p[2] = 1;
13674 break;
13676 /* unsigned 3 argument functions. */
13677 case ALTIVEC_BUILTIN_VPERM_16QI_UNS:
13678 case ALTIVEC_BUILTIN_VPERM_8HI_UNS:
13679 case ALTIVEC_BUILTIN_VPERM_4SI_UNS:
13680 case ALTIVEC_BUILTIN_VPERM_2DI_UNS:
13681 case ALTIVEC_BUILTIN_VSEL_16QI_UNS:
13682 case ALTIVEC_BUILTIN_VSEL_8HI_UNS:
13683 case ALTIVEC_BUILTIN_VSEL_4SI_UNS:
13684 case ALTIVEC_BUILTIN_VSEL_2DI_UNS:
13685 case VSX_BUILTIN_VPERM_16QI_UNS:
13686 case VSX_BUILTIN_VPERM_8HI_UNS:
13687 case VSX_BUILTIN_VPERM_4SI_UNS:
13688 case VSX_BUILTIN_VPERM_2DI_UNS:
13689 case VSX_BUILTIN_XXSEL_16QI_UNS:
13690 case VSX_BUILTIN_XXSEL_8HI_UNS:
13691 case VSX_BUILTIN_XXSEL_4SI_UNS:
13692 case VSX_BUILTIN_XXSEL_2DI_UNS:
13693 h.uns_p[0] = 1;
13694 h.uns_p[1] = 1;
13695 h.uns_p[2] = 1;
13696 h.uns_p[3] = 1;
13697 break;
13699 /* signed permute functions with unsigned char mask. */
13700 case ALTIVEC_BUILTIN_VPERM_16QI:
13701 case ALTIVEC_BUILTIN_VPERM_8HI:
13702 case ALTIVEC_BUILTIN_VPERM_4SI:
13703 case ALTIVEC_BUILTIN_VPERM_4SF:
13704 case ALTIVEC_BUILTIN_VPERM_2DI:
13705 case ALTIVEC_BUILTIN_VPERM_2DF:
13706 case VSX_BUILTIN_VPERM_16QI:
13707 case VSX_BUILTIN_VPERM_8HI:
13708 case VSX_BUILTIN_VPERM_4SI:
13709 case VSX_BUILTIN_VPERM_4SF:
13710 case VSX_BUILTIN_VPERM_2DI:
13711 case VSX_BUILTIN_VPERM_2DF:
13712 h.uns_p[3] = 1;
13713 break;
13715 /* unsigned args, signed return. */
13716 case VSX_BUILTIN_XVCVUXDDP_UNS:
13717 case VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF:
13718 h.uns_p[1] = 1;
13719 break;
13721 /* signed args, unsigned return. */
13722 case VSX_BUILTIN_XVCVDPUXDS_UNS:
13723 case VECTOR_BUILTIN_FIXUNS_V4SF_V4SI:
13724 h.uns_p[0] = 1;
13725 break;
13727 default:
13728 break;
13731 /* Figure out how many args are present. */
13732 while (num_args > 0 && h.mode[num_args] == VOIDmode)
13733 num_args--;
13735 if (num_args == 0)
13736 fatal_error ("internal error: builtin function %s had no type", name);
13738 ret_type = builtin_mode_to_type[h.mode[0]][h.uns_p[0]];
13739 if (!ret_type && h.uns_p[0])
13740 ret_type = builtin_mode_to_type[h.mode[0]][0];
13742 if (!ret_type)
13743 fatal_error ("internal error: builtin function %s had an unexpected "
13744 "return type %s", name, GET_MODE_NAME (h.mode[0]));
13746 for (i = 0; i < num_args; i++)
13748 int m = (int) h.mode[i+1];
13749 int uns_p = h.uns_p[i+1];
13751 arg_type[i] = builtin_mode_to_type[m][uns_p];
13752 if (!arg_type[i] && uns_p)
13753 arg_type[i] = builtin_mode_to_type[m][0];
13755 if (!arg_type[i])
13756 fatal_error ("internal error: builtin function %s, argument %d "
13757 "had unexpected argument type %s", name, i,
13758 GET_MODE_NAME (m));
13761 found = htab_find_slot (builtin_hash_table, &h, INSERT);
13762 if (*found == NULL)
13764 h2 = ggc_alloc_builtin_hash_struct ();
13765 *h2 = h;
13766 *found = (void *)h2;
13767 args = void_list_node;
13769 for (i = num_args - 1; i >= 0; i--)
13770 args = tree_cons (NULL_TREE, arg_type[i], args);
13772 h2->type = build_function_type (ret_type, args);
13775 return ((struct builtin_hash_struct *)(*found))->type;
13778 static void
13779 rs6000_common_init_builtins (void)
13781 const struct builtin_description *d;
13782 size_t i;
13784 tree opaque_ftype_opaque = NULL_TREE;
13785 tree opaque_ftype_opaque_opaque = NULL_TREE;
13786 tree opaque_ftype_opaque_opaque_opaque = NULL_TREE;
13787 tree v2si_ftype_qi = NULL_TREE;
13788 tree v2si_ftype_v2si_qi = NULL_TREE;
13789 tree v2si_ftype_int_qi = NULL_TREE;
13791 if (!TARGET_PAIRED_FLOAT)
13793 builtin_mode_to_type[V2SImode][0] = opaque_V2SI_type_node;
13794 builtin_mode_to_type[V2SFmode][0] = opaque_V2SF_type_node;
13797 /* Add the ternary operators. */
13798 d = bdesc_3arg;
13799 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
13801 tree type;
13802 int mask = d->mask;
13804 if ((mask != 0 && (mask & target_flags) == 0)
13805 || (mask == 0 && !TARGET_PAIRED_FLOAT))
13806 continue;
13808 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
13809 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
13810 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
13811 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
13813 if (! (type = opaque_ftype_opaque_opaque_opaque))
13814 type = opaque_ftype_opaque_opaque_opaque
13815 = build_function_type_list (opaque_V4SI_type_node,
13816 opaque_V4SI_type_node,
13817 opaque_V4SI_type_node,
13818 opaque_V4SI_type_node,
13819 NULL_TREE);
13821 else
13823 enum insn_code icode = d->icode;
13824 if (d->name == 0 || icode == CODE_FOR_nothing)
13825 continue;
13827 type = builtin_function_type (insn_data[icode].operand[0].mode,
13828 insn_data[icode].operand[1].mode,
13829 insn_data[icode].operand[2].mode,
13830 insn_data[icode].operand[3].mode,
13831 d->code, d->name);
13834 def_builtin (d->mask, d->name, type, d->code);
13837 /* Add the binary operators. */
13838 d = bdesc_2arg;
13839 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
13841 enum machine_mode mode0, mode1, mode2;
13842 tree type;
13843 int mask = d->mask;
13845 if ((mask != 0 && (mask & target_flags) == 0)
13846 || (mask == 0 && !TARGET_PAIRED_FLOAT))
13847 continue;
13849 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
13850 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
13851 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
13852 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
13854 if (! (type = opaque_ftype_opaque_opaque))
13855 type = opaque_ftype_opaque_opaque
13856 = build_function_type_list (opaque_V4SI_type_node,
13857 opaque_V4SI_type_node,
13858 opaque_V4SI_type_node,
13859 NULL_TREE);
13861 else
13863 enum insn_code icode = d->icode;
13864 if (d->name == 0 || icode == CODE_FOR_nothing)
13865 continue;
13867 mode0 = insn_data[icode].operand[0].mode;
13868 mode1 = insn_data[icode].operand[1].mode;
13869 mode2 = insn_data[icode].operand[2].mode;
13871 if (mode0 == V2SImode && mode1 == V2SImode && mode2 == QImode)
13873 if (! (type = v2si_ftype_v2si_qi))
13874 type = v2si_ftype_v2si_qi
13875 = build_function_type_list (opaque_V2SI_type_node,
13876 opaque_V2SI_type_node,
13877 char_type_node,
13878 NULL_TREE);
13881 else if (mode0 == V2SImode && GET_MODE_CLASS (mode1) == MODE_INT
13882 && mode2 == QImode)
13884 if (! (type = v2si_ftype_int_qi))
13885 type = v2si_ftype_int_qi
13886 = build_function_type_list (opaque_V2SI_type_node,
13887 integer_type_node,
13888 char_type_node,
13889 NULL_TREE);
13892 else
13893 type = builtin_function_type (mode0, mode1, mode2, VOIDmode,
13894 d->code, d->name);
13897 def_builtin (d->mask, d->name, type, d->code);
13900 /* Add the simple unary operators. */
13901 d = (struct builtin_description *) bdesc_1arg;
13902 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
13904 enum machine_mode mode0, mode1;
13905 tree type;
13906 int mask = d->mask;
13908 if ((mask != 0 && (mask & target_flags) == 0)
13909 || (mask == 0 && !TARGET_PAIRED_FLOAT))
13910 continue;
13912 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
13913 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
13914 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
13915 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
13917 if (! (type = opaque_ftype_opaque))
13918 type = opaque_ftype_opaque
13919 = build_function_type_list (opaque_V4SI_type_node,
13920 opaque_V4SI_type_node,
13921 NULL_TREE);
13923 else
13925 enum insn_code icode = d->icode;
13926 if (d->name == 0 || icode == CODE_FOR_nothing)
13927 continue;
13929 mode0 = insn_data[icode].operand[0].mode;
13930 mode1 = insn_data[icode].operand[1].mode;
13932 if (mode0 == V2SImode && mode1 == QImode)
13934 if (! (type = v2si_ftype_qi))
13935 type = v2si_ftype_qi
13936 = build_function_type_list (opaque_V2SI_type_node,
13937 char_type_node,
13938 NULL_TREE);
13941 else
13942 type = builtin_function_type (mode0, mode1, VOIDmode, VOIDmode,
13943 d->code, d->name);
13946 def_builtin (d->mask, d->name, type, d->code);
13950 static void
13951 rs6000_init_libfuncs (void)
13953 if (DEFAULT_ABI != ABI_V4 && TARGET_XCOFF
13954 && !TARGET_POWER2 && !TARGET_POWERPC)
13956 /* AIX library routines for float->int conversion. */
13957 set_conv_libfunc (sfix_optab, SImode, DFmode, "__itrunc");
13958 set_conv_libfunc (ufix_optab, SImode, DFmode, "__uitrunc");
13959 set_conv_libfunc (sfix_optab, SImode, TFmode, "_qitrunc");
13960 set_conv_libfunc (ufix_optab, SImode, TFmode, "_quitrunc");
13963 if (!TARGET_IEEEQUAD)
13964 /* AIX/Darwin/64-bit Linux quad floating point routines. */
13965 if (!TARGET_XL_COMPAT)
13967 set_optab_libfunc (add_optab, TFmode, "__gcc_qadd");
13968 set_optab_libfunc (sub_optab, TFmode, "__gcc_qsub");
13969 set_optab_libfunc (smul_optab, TFmode, "__gcc_qmul");
13970 set_optab_libfunc (sdiv_optab, TFmode, "__gcc_qdiv");
13972 if (!(TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)))
13974 set_optab_libfunc (neg_optab, TFmode, "__gcc_qneg");
13975 set_optab_libfunc (eq_optab, TFmode, "__gcc_qeq");
13976 set_optab_libfunc (ne_optab, TFmode, "__gcc_qne");
13977 set_optab_libfunc (gt_optab, TFmode, "__gcc_qgt");
13978 set_optab_libfunc (ge_optab, TFmode, "__gcc_qge");
13979 set_optab_libfunc (lt_optab, TFmode, "__gcc_qlt");
13980 set_optab_libfunc (le_optab, TFmode, "__gcc_qle");
13982 set_conv_libfunc (sext_optab, TFmode, SFmode, "__gcc_stoq");
13983 set_conv_libfunc (sext_optab, TFmode, DFmode, "__gcc_dtoq");
13984 set_conv_libfunc (trunc_optab, SFmode, TFmode, "__gcc_qtos");
13985 set_conv_libfunc (trunc_optab, DFmode, TFmode, "__gcc_qtod");
13986 set_conv_libfunc (sfix_optab, SImode, TFmode, "__gcc_qtoi");
13987 set_conv_libfunc (ufix_optab, SImode, TFmode, "__gcc_qtou");
13988 set_conv_libfunc (sfloat_optab, TFmode, SImode, "__gcc_itoq");
13989 set_conv_libfunc (ufloat_optab, TFmode, SImode, "__gcc_utoq");
13992 if (!(TARGET_HARD_FLOAT && TARGET_FPRS))
13993 set_optab_libfunc (unord_optab, TFmode, "__gcc_qunord");
13995 else
13997 set_optab_libfunc (add_optab, TFmode, "_xlqadd");
13998 set_optab_libfunc (sub_optab, TFmode, "_xlqsub");
13999 set_optab_libfunc (smul_optab, TFmode, "_xlqmul");
14000 set_optab_libfunc (sdiv_optab, TFmode, "_xlqdiv");
14002 else
14004 /* 32-bit SVR4 quad floating point routines. */
14006 set_optab_libfunc (add_optab, TFmode, "_q_add");
14007 set_optab_libfunc (sub_optab, TFmode, "_q_sub");
14008 set_optab_libfunc (neg_optab, TFmode, "_q_neg");
14009 set_optab_libfunc (smul_optab, TFmode, "_q_mul");
14010 set_optab_libfunc (sdiv_optab, TFmode, "_q_div");
14011 if (TARGET_PPC_GPOPT || TARGET_POWER2)
14012 set_optab_libfunc (sqrt_optab, TFmode, "_q_sqrt");
14014 set_optab_libfunc (eq_optab, TFmode, "_q_feq");
14015 set_optab_libfunc (ne_optab, TFmode, "_q_fne");
14016 set_optab_libfunc (gt_optab, TFmode, "_q_fgt");
14017 set_optab_libfunc (ge_optab, TFmode, "_q_fge");
14018 set_optab_libfunc (lt_optab, TFmode, "_q_flt");
14019 set_optab_libfunc (le_optab, TFmode, "_q_fle");
14021 set_conv_libfunc (sext_optab, TFmode, SFmode, "_q_stoq");
14022 set_conv_libfunc (sext_optab, TFmode, DFmode, "_q_dtoq");
14023 set_conv_libfunc (trunc_optab, SFmode, TFmode, "_q_qtos");
14024 set_conv_libfunc (trunc_optab, DFmode, TFmode, "_q_qtod");
14025 set_conv_libfunc (sfix_optab, SImode, TFmode, "_q_qtoi");
14026 set_conv_libfunc (ufix_optab, SImode, TFmode, "_q_qtou");
14027 set_conv_libfunc (sfloat_optab, TFmode, SImode, "_q_itoq");
14028 set_conv_libfunc (ufloat_optab, TFmode, SImode, "_q_utoq");
14033 /* Expand a block clear operation, and return 1 if successful. Return 0
14034 if we should let the compiler generate normal code.
14036 operands[0] is the destination
14037 operands[1] is the length
14038 operands[3] is the alignment */
14041 expand_block_clear (rtx operands[])
14043 rtx orig_dest = operands[0];
14044 rtx bytes_rtx = operands[1];
14045 rtx align_rtx = operands[3];
14046 bool constp = (GET_CODE (bytes_rtx) == CONST_INT);
14047 HOST_WIDE_INT align;
14048 HOST_WIDE_INT bytes;
14049 int offset;
14050 int clear_bytes;
14051 int clear_step;
14053 /* If this is not a fixed size move, just call memcpy */
14054 if (! constp)
14055 return 0;
14057 /* This must be a fixed size alignment */
14058 gcc_assert (GET_CODE (align_rtx) == CONST_INT);
14059 align = INTVAL (align_rtx) * BITS_PER_UNIT;
14061 /* Anything to clear? */
14062 bytes = INTVAL (bytes_rtx);
14063 if (bytes <= 0)
14064 return 1;
14066 /* Use the builtin memset after a point, to avoid huge code bloat.
14067 When optimize_size, avoid any significant code bloat; calling
14068 memset is about 4 instructions, so allow for one instruction to
14069 load zero and three to do clearing. */
14070 if (TARGET_ALTIVEC && align >= 128)
14071 clear_step = 16;
14072 else if (TARGET_POWERPC64 && align >= 32)
14073 clear_step = 8;
14074 else if (TARGET_SPE && align >= 64)
14075 clear_step = 8;
14076 else
14077 clear_step = 4;
14079 if (optimize_size && bytes > 3 * clear_step)
14080 return 0;
14081 if (! optimize_size && bytes > 8 * clear_step)
14082 return 0;
14084 for (offset = 0; bytes > 0; offset += clear_bytes, bytes -= clear_bytes)
14086 enum machine_mode mode = BLKmode;
14087 rtx dest;
14089 if (bytes >= 16 && TARGET_ALTIVEC && align >= 128)
14091 clear_bytes = 16;
14092 mode = V4SImode;
14094 else if (bytes >= 8 && TARGET_SPE && align >= 64)
14096 clear_bytes = 8;
14097 mode = V2SImode;
14099 else if (bytes >= 8 && TARGET_POWERPC64
14100 /* 64-bit loads and stores require word-aligned
14101 displacements. */
14102 && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
14104 clear_bytes = 8;
14105 mode = DImode;
14107 else if (bytes >= 4 && (align >= 32 || !STRICT_ALIGNMENT))
14108 { /* move 4 bytes */
14109 clear_bytes = 4;
14110 mode = SImode;
14112 else if (bytes >= 2 && (align >= 16 || !STRICT_ALIGNMENT))
14113 { /* move 2 bytes */
14114 clear_bytes = 2;
14115 mode = HImode;
14117 else /* move 1 byte at a time */
14119 clear_bytes = 1;
14120 mode = QImode;
14123 dest = adjust_address (orig_dest, mode, offset);
14125 emit_move_insn (dest, CONST0_RTX (mode));
14128 return 1;
14132 /* Expand a block move operation, and return 1 if successful. Return 0
14133 if we should let the compiler generate normal code.
14135 operands[0] is the destination
14136 operands[1] is the source
14137 operands[2] is the length
14138 operands[3] is the alignment */
14140 #define MAX_MOVE_REG 4
14143 expand_block_move (rtx operands[])
14145 rtx orig_dest = operands[0];
14146 rtx orig_src = operands[1];
14147 rtx bytes_rtx = operands[2];
14148 rtx align_rtx = operands[3];
14149 int constp = (GET_CODE (bytes_rtx) == CONST_INT);
14150 int align;
14151 int bytes;
14152 int offset;
14153 int move_bytes;
14154 rtx stores[MAX_MOVE_REG];
14155 int num_reg = 0;
14157 /* If this is not a fixed size move, just call memcpy */
14158 if (! constp)
14159 return 0;
14161 /* This must be a fixed size alignment */
14162 gcc_assert (GET_CODE (align_rtx) == CONST_INT);
14163 align = INTVAL (align_rtx) * BITS_PER_UNIT;
14165 /* Anything to move? */
14166 bytes = INTVAL (bytes_rtx);
14167 if (bytes <= 0)
14168 return 1;
14170 if (bytes > rs6000_block_move_inline_limit)
14171 return 0;
14173 for (offset = 0; bytes > 0; offset += move_bytes, bytes -= move_bytes)
14175 union {
14176 rtx (*movmemsi) (rtx, rtx, rtx, rtx);
14177 rtx (*mov) (rtx, rtx);
14178 } gen_func;
14179 enum machine_mode mode = BLKmode;
14180 rtx src, dest;
14182 /* Altivec first, since it will be faster than a string move
14183 when it applies, and usually not significantly larger. */
14184 if (TARGET_ALTIVEC && bytes >= 16 && align >= 128)
14186 move_bytes = 16;
14187 mode = V4SImode;
14188 gen_func.mov = gen_movv4si;
14190 else if (TARGET_SPE && bytes >= 8 && align >= 64)
14192 move_bytes = 8;
14193 mode = V2SImode;
14194 gen_func.mov = gen_movv2si;
14196 else if (TARGET_STRING
14197 && bytes > 24 /* move up to 32 bytes at a time */
14198 && ! fixed_regs[5]
14199 && ! fixed_regs[6]
14200 && ! fixed_regs[7]
14201 && ! fixed_regs[8]
14202 && ! fixed_regs[9]
14203 && ! fixed_regs[10]
14204 && ! fixed_regs[11]
14205 && ! fixed_regs[12])
14207 move_bytes = (bytes > 32) ? 32 : bytes;
14208 gen_func.movmemsi = gen_movmemsi_8reg;
14210 else if (TARGET_STRING
14211 && bytes > 16 /* move up to 24 bytes at a time */
14212 && ! fixed_regs[5]
14213 && ! fixed_regs[6]
14214 && ! fixed_regs[7]
14215 && ! fixed_regs[8]
14216 && ! fixed_regs[9]
14217 && ! fixed_regs[10])
14219 move_bytes = (bytes > 24) ? 24 : bytes;
14220 gen_func.movmemsi = gen_movmemsi_6reg;
14222 else if (TARGET_STRING
14223 && bytes > 8 /* move up to 16 bytes at a time */
14224 && ! fixed_regs[5]
14225 && ! fixed_regs[6]
14226 && ! fixed_regs[7]
14227 && ! fixed_regs[8])
14229 move_bytes = (bytes > 16) ? 16 : bytes;
14230 gen_func.movmemsi = gen_movmemsi_4reg;
14232 else if (bytes >= 8 && TARGET_POWERPC64
14233 /* 64-bit loads and stores require word-aligned
14234 displacements. */
14235 && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
14237 move_bytes = 8;
14238 mode = DImode;
14239 gen_func.mov = gen_movdi;
14241 else if (TARGET_STRING && bytes > 4 && !TARGET_POWERPC64)
14242 { /* move up to 8 bytes at a time */
14243 move_bytes = (bytes > 8) ? 8 : bytes;
14244 gen_func.movmemsi = gen_movmemsi_2reg;
14246 else if (bytes >= 4 && (align >= 32 || !STRICT_ALIGNMENT))
14247 { /* move 4 bytes */
14248 move_bytes = 4;
14249 mode = SImode;
14250 gen_func.mov = gen_movsi;
14252 else if (bytes >= 2 && (align >= 16 || !STRICT_ALIGNMENT))
14253 { /* move 2 bytes */
14254 move_bytes = 2;
14255 mode = HImode;
14256 gen_func.mov = gen_movhi;
14258 else if (TARGET_STRING && bytes > 1)
14259 { /* move up to 4 bytes at a time */
14260 move_bytes = (bytes > 4) ? 4 : bytes;
14261 gen_func.movmemsi = gen_movmemsi_1reg;
14263 else /* move 1 byte at a time */
14265 move_bytes = 1;
14266 mode = QImode;
14267 gen_func.mov = gen_movqi;
14270 src = adjust_address (orig_src, mode, offset);
14271 dest = adjust_address (orig_dest, mode, offset);
14273 if (mode != BLKmode)
14275 rtx tmp_reg = gen_reg_rtx (mode);
14277 emit_insn ((*gen_func.mov) (tmp_reg, src));
14278 stores[num_reg++] = (*gen_func.mov) (dest, tmp_reg);
14281 if (mode == BLKmode || num_reg >= MAX_MOVE_REG || bytes == move_bytes)
14283 int i;
14284 for (i = 0; i < num_reg; i++)
14285 emit_insn (stores[i]);
14286 num_reg = 0;
14289 if (mode == BLKmode)
14291 /* Move the address into scratch registers. The movmemsi
14292 patterns require zero offset. */
14293 if (!REG_P (XEXP (src, 0)))
14295 rtx src_reg = copy_addr_to_reg (XEXP (src, 0));
14296 src = replace_equiv_address (src, src_reg);
14298 set_mem_size (src, GEN_INT (move_bytes));
14300 if (!REG_P (XEXP (dest, 0)))
14302 rtx dest_reg = copy_addr_to_reg (XEXP (dest, 0));
14303 dest = replace_equiv_address (dest, dest_reg);
14305 set_mem_size (dest, GEN_INT (move_bytes));
14307 emit_insn ((*gen_func.movmemsi) (dest, src,
14308 GEN_INT (move_bytes & 31),
14309 align_rtx));
14313 return 1;
14317 /* Return a string to perform a load_multiple operation.
14318 operands[0] is the vector.
14319 operands[1] is the source address.
14320 operands[2] is the first destination register. */
14322 const char *
14323 rs6000_output_load_multiple (rtx operands[3])
14325 /* We have to handle the case where the pseudo used to contain the address
14326 is assigned to one of the output registers. */
14327 int i, j;
14328 int words = XVECLEN (operands[0], 0);
14329 rtx xop[10];
14331 if (XVECLEN (operands[0], 0) == 1)
14332 return "{l|lwz} %2,0(%1)";
14334 for (i = 0; i < words; i++)
14335 if (refers_to_regno_p (REGNO (operands[2]) + i,
14336 REGNO (operands[2]) + i + 1, operands[1], 0))
14338 if (i == words-1)
14340 xop[0] = GEN_INT (4 * (words-1));
14341 xop[1] = operands[1];
14342 xop[2] = operands[2];
14343 output_asm_insn ("{lsi|lswi} %2,%1,%0\n\t{l|lwz} %1,%0(%1)", xop);
14344 return "";
14346 else if (i == 0)
14348 xop[0] = GEN_INT (4 * (words-1));
14349 xop[1] = operands[1];
14350 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + 1);
14351 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);
14352 return "";
14354 else
14356 for (j = 0; j < words; j++)
14357 if (j != i)
14359 xop[0] = GEN_INT (j * 4);
14360 xop[1] = operands[1];
14361 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + j);
14362 output_asm_insn ("{l|lwz} %2,%0(%1)", xop);
14364 xop[0] = GEN_INT (i * 4);
14365 xop[1] = operands[1];
14366 output_asm_insn ("{l|lwz} %1,%0(%1)", xop);
14367 return "";
14371 return "{lsi|lswi} %2,%1,%N0";
14375 /* A validation routine: say whether CODE, a condition code, and MODE
14376 match. The other alternatives either don't make sense or should
14377 never be generated. */
14379 void
14380 validate_condition_mode (enum rtx_code code, enum machine_mode mode)
14382 gcc_assert ((GET_RTX_CLASS (code) == RTX_COMPARE
14383 || GET_RTX_CLASS (code) == RTX_COMM_COMPARE)
14384 && GET_MODE_CLASS (mode) == MODE_CC);
14386 /* These don't make sense. */
14387 gcc_assert ((code != GT && code != LT && code != GE && code != LE)
14388 || mode != CCUNSmode);
14390 gcc_assert ((code != GTU && code != LTU && code != GEU && code != LEU)
14391 || mode == CCUNSmode);
14393 gcc_assert (mode == CCFPmode
14394 || (code != ORDERED && code != UNORDERED
14395 && code != UNEQ && code != LTGT
14396 && code != UNGT && code != UNLT
14397 && code != UNGE && code != UNLE));
14399 /* These should never be generated except for
14400 flag_finite_math_only. */
14401 gcc_assert (mode != CCFPmode
14402 || flag_finite_math_only
14403 || (code != LE && code != GE
14404 && code != UNEQ && code != LTGT
14405 && code != UNGT && code != UNLT));
14407 /* These are invalid; the information is not there. */
14408 gcc_assert (mode != CCEQmode || code == EQ || code == NE);
14412 /* Return 1 if ANDOP is a mask that has no bits on that are not in the
14413 mask required to convert the result of a rotate insn into a shift
14414 left insn of SHIFTOP bits. Both are known to be SImode CONST_INT. */
14417 includes_lshift_p (rtx shiftop, rtx andop)
14419 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
14421 shift_mask <<= INTVAL (shiftop);
14423 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
14426 /* Similar, but for right shift. */
14429 includes_rshift_p (rtx shiftop, rtx andop)
14431 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
14433 shift_mask >>= INTVAL (shiftop);
14435 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
14438 /* Return 1 if ANDOP is a mask suitable for use with an rldic insn
14439 to perform a left shift. It must have exactly SHIFTOP least
14440 significant 0's, then one or more 1's, then zero or more 0's. */
14443 includes_rldic_lshift_p (rtx shiftop, rtx andop)
14445 if (GET_CODE (andop) == CONST_INT)
14447 HOST_WIDE_INT c, lsb, shift_mask;
14449 c = INTVAL (andop);
14450 if (c == 0 || c == ~0)
14451 return 0;
14453 shift_mask = ~0;
14454 shift_mask <<= INTVAL (shiftop);
14456 /* Find the least significant one bit. */
14457 lsb = c & -c;
14459 /* It must coincide with the LSB of the shift mask. */
14460 if (-lsb != shift_mask)
14461 return 0;
14463 /* Invert to look for the next transition (if any). */
14464 c = ~c;
14466 /* Remove the low group of ones (originally low group of zeros). */
14467 c &= -lsb;
14469 /* Again find the lsb, and check we have all 1's above. */
14470 lsb = c & -c;
14471 return c == -lsb;
14473 else if (GET_CODE (andop) == CONST_DOUBLE
14474 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
14476 HOST_WIDE_INT low, high, lsb;
14477 HOST_WIDE_INT shift_mask_low, shift_mask_high;
14479 low = CONST_DOUBLE_LOW (andop);
14480 if (HOST_BITS_PER_WIDE_INT < 64)
14481 high = CONST_DOUBLE_HIGH (andop);
14483 if ((low == 0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == 0))
14484 || (low == ~0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0)))
14485 return 0;
14487 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
14489 shift_mask_high = ~0;
14490 if (INTVAL (shiftop) > 32)
14491 shift_mask_high <<= INTVAL (shiftop) - 32;
14493 lsb = high & -high;
14495 if (-lsb != shift_mask_high || INTVAL (shiftop) < 32)
14496 return 0;
14498 high = ~high;
14499 high &= -lsb;
14501 lsb = high & -high;
14502 return high == -lsb;
14505 shift_mask_low = ~0;
14506 shift_mask_low <<= INTVAL (shiftop);
14508 lsb = low & -low;
14510 if (-lsb != shift_mask_low)
14511 return 0;
14513 if (HOST_BITS_PER_WIDE_INT < 64)
14514 high = ~high;
14515 low = ~low;
14516 low &= -lsb;
14518 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
14520 lsb = high & -high;
14521 return high == -lsb;
14524 lsb = low & -low;
14525 return low == -lsb && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0);
14527 else
14528 return 0;
14531 /* Return 1 if ANDOP is a mask suitable for use with an rldicr insn
14532 to perform a left shift. It must have SHIFTOP or more least
14533 significant 0's, with the remainder of the word 1's. */
14536 includes_rldicr_lshift_p (rtx shiftop, rtx andop)
14538 if (GET_CODE (andop) == CONST_INT)
14540 HOST_WIDE_INT c, lsb, shift_mask;
14542 shift_mask = ~0;
14543 shift_mask <<= INTVAL (shiftop);
14544 c = INTVAL (andop);
14546 /* Find the least significant one bit. */
14547 lsb = c & -c;
14549 /* It must be covered by the shift mask.
14550 This test also rejects c == 0. */
14551 if ((lsb & shift_mask) == 0)
14552 return 0;
14554 /* Check we have all 1's above the transition, and reject all 1's. */
14555 return c == -lsb && lsb != 1;
14557 else if (GET_CODE (andop) == CONST_DOUBLE
14558 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
14560 HOST_WIDE_INT low, lsb, shift_mask_low;
14562 low = CONST_DOUBLE_LOW (andop);
14564 if (HOST_BITS_PER_WIDE_INT < 64)
14566 HOST_WIDE_INT high, shift_mask_high;
14568 high = CONST_DOUBLE_HIGH (andop);
14570 if (low == 0)
14572 shift_mask_high = ~0;
14573 if (INTVAL (shiftop) > 32)
14574 shift_mask_high <<= INTVAL (shiftop) - 32;
14576 lsb = high & -high;
14578 if ((lsb & shift_mask_high) == 0)
14579 return 0;
14581 return high == -lsb;
14583 if (high != ~0)
14584 return 0;
14587 shift_mask_low = ~0;
14588 shift_mask_low <<= INTVAL (shiftop);
14590 lsb = low & -low;
14592 if ((lsb & shift_mask_low) == 0)
14593 return 0;
14595 return low == -lsb && lsb != 1;
14597 else
14598 return 0;
14601 /* Return 1 if operands will generate a valid arguments to rlwimi
14602 instruction for insert with right shift in 64-bit mode. The mask may
14603 not start on the first bit or stop on the last bit because wrap-around
14604 effects of instruction do not correspond to semantics of RTL insn. */
14607 insvdi_rshift_rlwimi_p (rtx sizeop, rtx startop, rtx shiftop)
14609 if (INTVAL (startop) > 32
14610 && INTVAL (startop) < 64
14611 && INTVAL (sizeop) > 1
14612 && INTVAL (sizeop) + INTVAL (startop) < 64
14613 && INTVAL (shiftop) > 0
14614 && INTVAL (sizeop) + INTVAL (shiftop) < 32
14615 && (64 - (INTVAL (shiftop) & 63)) >= INTVAL (sizeop))
14616 return 1;
14618 return 0;
14621 /* Return 1 if REGNO (reg1) == REGNO (reg2) - 1 making them candidates
14622 for lfq and stfq insns iff the registers are hard registers. */
14625 registers_ok_for_quad_peep (rtx reg1, rtx reg2)
14627 /* We might have been passed a SUBREG. */
14628 if (GET_CODE (reg1) != REG || GET_CODE (reg2) != REG)
14629 return 0;
14631 /* We might have been passed non floating point registers. */
14632 if (!FP_REGNO_P (REGNO (reg1))
14633 || !FP_REGNO_P (REGNO (reg2)))
14634 return 0;
14636 return (REGNO (reg1) == REGNO (reg2) - 1);
14639 /* Return 1 if addr1 and addr2 are suitable for lfq or stfq insn.
14640 addr1 and addr2 must be in consecutive memory locations
14641 (addr2 == addr1 + 8). */
14644 mems_ok_for_quad_peep (rtx mem1, rtx mem2)
14646 rtx addr1, addr2;
14647 unsigned int reg1, reg2;
14648 int offset1, offset2;
14650 /* The mems cannot be volatile. */
14651 if (MEM_VOLATILE_P (mem1) || MEM_VOLATILE_P (mem2))
14652 return 0;
14654 addr1 = XEXP (mem1, 0);
14655 addr2 = XEXP (mem2, 0);
14657 /* Extract an offset (if used) from the first addr. */
14658 if (GET_CODE (addr1) == PLUS)
14660 /* If not a REG, return zero. */
14661 if (GET_CODE (XEXP (addr1, 0)) != REG)
14662 return 0;
14663 else
14665 reg1 = REGNO (XEXP (addr1, 0));
14666 /* The offset must be constant! */
14667 if (GET_CODE (XEXP (addr1, 1)) != CONST_INT)
14668 return 0;
14669 offset1 = INTVAL (XEXP (addr1, 1));
14672 else if (GET_CODE (addr1) != REG)
14673 return 0;
14674 else
14676 reg1 = REGNO (addr1);
14677 /* This was a simple (mem (reg)) expression. Offset is 0. */
14678 offset1 = 0;
14681 /* And now for the second addr. */
14682 if (GET_CODE (addr2) == PLUS)
14684 /* If not a REG, return zero. */
14685 if (GET_CODE (XEXP (addr2, 0)) != REG)
14686 return 0;
14687 else
14689 reg2 = REGNO (XEXP (addr2, 0));
14690 /* The offset must be constant. */
14691 if (GET_CODE (XEXP (addr2, 1)) != CONST_INT)
14692 return 0;
14693 offset2 = INTVAL (XEXP (addr2, 1));
14696 else if (GET_CODE (addr2) != REG)
14697 return 0;
14698 else
14700 reg2 = REGNO (addr2);
14701 /* This was a simple (mem (reg)) expression. Offset is 0. */
14702 offset2 = 0;
14705 /* Both of these must have the same base register. */
14706 if (reg1 != reg2)
14707 return 0;
14709 /* The offset for the second addr must be 8 more than the first addr. */
14710 if (offset2 != offset1 + 8)
14711 return 0;
14713 /* All the tests passed. addr1 and addr2 are valid for lfq or stfq
14714 instructions. */
14715 return 1;
14720 rs6000_secondary_memory_needed_rtx (enum machine_mode mode)
14722 static bool eliminated = false;
14723 rtx ret;
14725 if (mode != SDmode)
14726 ret = assign_stack_local (mode, GET_MODE_SIZE (mode), 0);
14727 else
14729 rtx mem = cfun->machine->sdmode_stack_slot;
14730 gcc_assert (mem != NULL_RTX);
14732 if (!eliminated)
14734 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
14735 cfun->machine->sdmode_stack_slot = mem;
14736 eliminated = true;
14738 ret = mem;
14741 if (TARGET_DEBUG_ADDR)
14743 fprintf (stderr, "\nrs6000_secondary_memory_needed_rtx, mode %s, rtx:\n",
14744 GET_MODE_NAME (mode));
14745 if (!ret)
14746 fprintf (stderr, "\tNULL_RTX\n");
14747 else
14748 debug_rtx (ret);
14751 return ret;
14754 static tree
14755 rs6000_check_sdmode (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
14757 /* Don't walk into types. */
14758 if (*tp == NULL_TREE || *tp == error_mark_node || TYPE_P (*tp))
14760 *walk_subtrees = 0;
14761 return NULL_TREE;
14764 switch (TREE_CODE (*tp))
14766 case VAR_DECL:
14767 case PARM_DECL:
14768 case FIELD_DECL:
14769 case RESULT_DECL:
14770 case SSA_NAME:
14771 case REAL_CST:
14772 case MEM_REF:
14773 case VIEW_CONVERT_EXPR:
14774 if (TYPE_MODE (TREE_TYPE (*tp)) == SDmode)
14775 return *tp;
14776 break;
14777 default:
14778 break;
14781 return NULL_TREE;
14784 enum reload_reg_type {
14785 GPR_REGISTER_TYPE,
14786 VECTOR_REGISTER_TYPE,
14787 OTHER_REGISTER_TYPE
14790 static enum reload_reg_type
14791 rs6000_reload_register_type (enum reg_class rclass)
14793 switch (rclass)
14795 case GENERAL_REGS:
14796 case BASE_REGS:
14797 return GPR_REGISTER_TYPE;
14799 case FLOAT_REGS:
14800 case ALTIVEC_REGS:
14801 case VSX_REGS:
14802 return VECTOR_REGISTER_TYPE;
14804 default:
14805 return OTHER_REGISTER_TYPE;
14809 /* Inform reload about cases where moving X with a mode MODE to a register in
14810 RCLASS requires an extra scratch or immediate register. Return the class
14811 needed for the immediate register.
14813 For VSX and Altivec, we may need a register to convert sp+offset into
14814 reg+sp.
14816 For misaligned 64-bit gpr loads and stores we need a register to
14817 convert an offset address to indirect. */
14819 static reg_class_t
14820 rs6000_secondary_reload (bool in_p,
14821 rtx x,
14822 reg_class_t rclass_i,
14823 enum machine_mode mode,
14824 secondary_reload_info *sri)
14826 enum reg_class rclass = (enum reg_class) rclass_i;
14827 reg_class_t ret = ALL_REGS;
14828 enum insn_code icode;
14829 bool default_p = false;
14831 sri->icode = CODE_FOR_nothing;
14833 /* Convert vector loads and stores into gprs to use an additional base
14834 register. */
14835 icode = rs6000_vector_reload[mode][in_p != false];
14836 if (icode != CODE_FOR_nothing)
14838 ret = NO_REGS;
14839 sri->icode = CODE_FOR_nothing;
14840 sri->extra_cost = 0;
14842 if (GET_CODE (x) == MEM)
14844 rtx addr = XEXP (x, 0);
14846 /* Loads to and stores from gprs can do reg+offset, and wouldn't need
14847 an extra register in that case, but it would need an extra
14848 register if the addressing is reg+reg or (reg+reg)&(-16). */
14849 if (rclass == GENERAL_REGS || rclass == BASE_REGS)
14851 if (!legitimate_indirect_address_p (addr, false)
14852 && !rs6000_legitimate_offset_address_p (TImode, addr, false))
14854 sri->icode = icode;
14855 /* account for splitting the loads, and converting the
14856 address from reg+reg to reg. */
14857 sri->extra_cost = (((TARGET_64BIT) ? 3 : 5)
14858 + ((GET_CODE (addr) == AND) ? 1 : 0));
14861 /* Loads to and stores from vector registers can only do reg+reg
14862 addressing. Altivec registers can also do (reg+reg)&(-16). */
14863 else if (rclass == VSX_REGS || rclass == ALTIVEC_REGS
14864 || rclass == FLOAT_REGS || rclass == NO_REGS)
14866 if (!VECTOR_MEM_ALTIVEC_P (mode)
14867 && GET_CODE (addr) == AND
14868 && GET_CODE (XEXP (addr, 1)) == CONST_INT
14869 && INTVAL (XEXP (addr, 1)) == -16
14870 && (legitimate_indirect_address_p (XEXP (addr, 0), false)
14871 || legitimate_indexed_address_p (XEXP (addr, 0), false)))
14873 sri->icode = icode;
14874 sri->extra_cost = ((GET_CODE (XEXP (addr, 0)) == PLUS)
14875 ? 2 : 1);
14877 else if (!legitimate_indirect_address_p (addr, false)
14878 && (rclass == NO_REGS
14879 || !legitimate_indexed_address_p (addr, false)))
14881 sri->icode = icode;
14882 sri->extra_cost = 1;
14884 else
14885 icode = CODE_FOR_nothing;
14887 /* Any other loads, including to pseudo registers which haven't been
14888 assigned to a register yet, default to require a scratch
14889 register. */
14890 else
14892 sri->icode = icode;
14893 sri->extra_cost = 2;
14896 else if (REG_P (x))
14898 int regno = true_regnum (x);
14900 icode = CODE_FOR_nothing;
14901 if (regno < 0 || regno >= FIRST_PSEUDO_REGISTER)
14902 default_p = true;
14903 else
14905 enum reg_class xclass = REGNO_REG_CLASS (regno);
14906 enum reload_reg_type rtype1 = rs6000_reload_register_type (rclass);
14907 enum reload_reg_type rtype2 = rs6000_reload_register_type (xclass);
14909 /* If memory is needed, use default_secondary_reload to create the
14910 stack slot. */
14911 if (rtype1 != rtype2 || rtype1 == OTHER_REGISTER_TYPE)
14912 default_p = true;
14913 else
14914 ret = NO_REGS;
14917 else
14918 default_p = true;
14920 else if (TARGET_POWERPC64
14921 && rs6000_reload_register_type (rclass) == GPR_REGISTER_TYPE
14922 && MEM_P (x)
14923 && GET_MODE_SIZE (GET_MODE (x)) >= UNITS_PER_WORD)
14925 rtx addr = XEXP (x, 0);
14927 if (GET_CODE (addr) == PRE_MODIFY)
14928 addr = XEXP (addr, 1);
14929 else if (GET_CODE (addr) == LO_SUM
14930 && GET_CODE (XEXP (addr, 0)) == REG
14931 && GET_CODE (XEXP (addr, 1)) == CONST)
14932 addr = XEXP (XEXP (addr, 1), 0);
14934 if (GET_CODE (addr) == PLUS
14935 && GET_CODE (XEXP (addr, 1)) == CONST_INT
14936 && (INTVAL (XEXP (addr, 1)) & 3) != 0)
14938 if (in_p)
14939 sri->icode = CODE_FOR_reload_di_load;
14940 else
14941 sri->icode = CODE_FOR_reload_di_store;
14942 sri->extra_cost = 2;
14943 ret = NO_REGS;
14945 else
14946 default_p = true;
14948 else
14949 default_p = true;
14951 if (default_p)
14952 ret = default_secondary_reload (in_p, x, rclass, mode, sri);
14954 gcc_assert (ret != ALL_REGS);
14956 if (TARGET_DEBUG_ADDR)
14958 fprintf (stderr,
14959 "\nrs6000_secondary_reload, return %s, in_p = %s, rclass = %s, "
14960 "mode = %s",
14961 reg_class_names[ret],
14962 in_p ? "true" : "false",
14963 reg_class_names[rclass],
14964 GET_MODE_NAME (mode));
14966 if (default_p)
14967 fprintf (stderr, ", default secondary reload");
14969 if (sri->icode != CODE_FOR_nothing)
14970 fprintf (stderr, ", reload func = %s, extra cost = %d\n",
14971 insn_data[sri->icode].name, sri->extra_cost);
14972 else
14973 fprintf (stderr, "\n");
14975 debug_rtx (x);
14978 return ret;
14981 /* Fixup reload addresses for Altivec or VSX loads/stores to change SP+offset
14982 to SP+reg addressing. */
14984 void
14985 rs6000_secondary_reload_inner (rtx reg, rtx mem, rtx scratch, bool store_p)
14987 int regno = true_regnum (reg);
14988 enum machine_mode mode = GET_MODE (reg);
14989 enum reg_class rclass;
14990 rtx addr;
14991 rtx and_op2 = NULL_RTX;
14992 rtx addr_op1;
14993 rtx addr_op2;
14994 rtx scratch_or_premodify = scratch;
14995 rtx and_rtx;
14996 rtx cc_clobber;
14998 if (TARGET_DEBUG_ADDR)
15000 fprintf (stderr, "\nrs6000_secondary_reload_inner, type = %s\n",
15001 store_p ? "store" : "load");
15002 fprintf (stderr, "reg:\n");
15003 debug_rtx (reg);
15004 fprintf (stderr, "mem:\n");
15005 debug_rtx (mem);
15006 fprintf (stderr, "scratch:\n");
15007 debug_rtx (scratch);
15010 gcc_assert (regno >= 0 && regno < FIRST_PSEUDO_REGISTER);
15011 gcc_assert (GET_CODE (mem) == MEM);
15012 rclass = REGNO_REG_CLASS (regno);
15013 addr = XEXP (mem, 0);
15015 switch (rclass)
15017 /* GPRs can handle reg + small constant, all other addresses need to use
15018 the scratch register. */
15019 case GENERAL_REGS:
15020 case BASE_REGS:
15021 if (GET_CODE (addr) == AND)
15023 and_op2 = XEXP (addr, 1);
15024 addr = XEXP (addr, 0);
15027 if (GET_CODE (addr) == PRE_MODIFY)
15029 scratch_or_premodify = XEXP (addr, 0);
15030 gcc_assert (REG_P (scratch_or_premodify));
15031 gcc_assert (GET_CODE (XEXP (addr, 1)) == PLUS);
15032 addr = XEXP (addr, 1);
15035 if (GET_CODE (addr) == PLUS
15036 && (!rs6000_legitimate_offset_address_p (TImode, addr, false)
15037 || and_op2 != NULL_RTX))
15039 addr_op1 = XEXP (addr, 0);
15040 addr_op2 = XEXP (addr, 1);
15041 gcc_assert (legitimate_indirect_address_p (addr_op1, false));
15043 if (!REG_P (addr_op2)
15044 && (GET_CODE (addr_op2) != CONST_INT
15045 || !satisfies_constraint_I (addr_op2)))
15047 if (TARGET_DEBUG_ADDR)
15049 fprintf (stderr,
15050 "\nMove plus addr to register %s, mode = %s: ",
15051 rs6000_reg_names[REGNO (scratch)],
15052 GET_MODE_NAME (mode));
15053 debug_rtx (addr_op2);
15055 rs6000_emit_move (scratch, addr_op2, Pmode);
15056 addr_op2 = scratch;
15059 emit_insn (gen_rtx_SET (VOIDmode,
15060 scratch_or_premodify,
15061 gen_rtx_PLUS (Pmode,
15062 addr_op1,
15063 addr_op2)));
15065 addr = scratch_or_premodify;
15066 scratch_or_premodify = scratch;
15068 else if (!legitimate_indirect_address_p (addr, false)
15069 && !rs6000_legitimate_offset_address_p (TImode, addr, false))
15071 if (TARGET_DEBUG_ADDR)
15073 fprintf (stderr, "\nMove addr to register %s, mode = %s: ",
15074 rs6000_reg_names[REGNO (scratch_or_premodify)],
15075 GET_MODE_NAME (mode));
15076 debug_rtx (addr);
15078 rs6000_emit_move (scratch_or_premodify, addr, Pmode);
15079 addr = scratch_or_premodify;
15080 scratch_or_premodify = scratch;
15082 break;
15084 /* Float/Altivec registers can only handle reg+reg addressing. Move
15085 other addresses into a scratch register. */
15086 case FLOAT_REGS:
15087 case VSX_REGS:
15088 case ALTIVEC_REGS:
15090 /* With float regs, we need to handle the AND ourselves, since we can't
15091 use the Altivec instruction with an implicit AND -16. Allow scalar
15092 loads to float registers to use reg+offset even if VSX. */
15093 if (GET_CODE (addr) == AND
15094 && (rclass != ALTIVEC_REGS || GET_MODE_SIZE (mode) != 16
15095 || GET_CODE (XEXP (addr, 1)) != CONST_INT
15096 || INTVAL (XEXP (addr, 1)) != -16
15097 || !VECTOR_MEM_ALTIVEC_P (mode)))
15099 and_op2 = XEXP (addr, 1);
15100 addr = XEXP (addr, 0);
15103 /* If we aren't using a VSX load, save the PRE_MODIFY register and use it
15104 as the address later. */
15105 if (GET_CODE (addr) == PRE_MODIFY
15106 && (!VECTOR_MEM_VSX_P (mode)
15107 || and_op2 != NULL_RTX
15108 || !legitimate_indexed_address_p (XEXP (addr, 1), false)))
15110 scratch_or_premodify = XEXP (addr, 0);
15111 gcc_assert (legitimate_indirect_address_p (scratch_or_premodify,
15112 false));
15113 gcc_assert (GET_CODE (XEXP (addr, 1)) == PLUS);
15114 addr = XEXP (addr, 1);
15117 if (legitimate_indirect_address_p (addr, false) /* reg */
15118 || legitimate_indexed_address_p (addr, false) /* reg+reg */
15119 || GET_CODE (addr) == PRE_MODIFY /* VSX pre-modify */
15120 || (GET_CODE (addr) == AND /* Altivec memory */
15121 && GET_CODE (XEXP (addr, 1)) == CONST_INT
15122 && INTVAL (XEXP (addr, 1)) == -16
15123 && VECTOR_MEM_ALTIVEC_P (mode))
15124 || (rclass == FLOAT_REGS /* legacy float mem */
15125 && GET_MODE_SIZE (mode) == 8
15126 && and_op2 == NULL_RTX
15127 && scratch_or_premodify == scratch
15128 && rs6000_legitimate_offset_address_p (mode, addr, false)))
15131 else if (GET_CODE (addr) == PLUS)
15133 addr_op1 = XEXP (addr, 0);
15134 addr_op2 = XEXP (addr, 1);
15135 gcc_assert (REG_P (addr_op1));
15137 if (TARGET_DEBUG_ADDR)
15139 fprintf (stderr, "\nMove plus addr to register %s, mode = %s: ",
15140 rs6000_reg_names[REGNO (scratch)], GET_MODE_NAME (mode));
15141 debug_rtx (addr_op2);
15143 rs6000_emit_move (scratch, addr_op2, Pmode);
15144 emit_insn (gen_rtx_SET (VOIDmode,
15145 scratch_or_premodify,
15146 gen_rtx_PLUS (Pmode,
15147 addr_op1,
15148 scratch)));
15149 addr = scratch_or_premodify;
15150 scratch_or_premodify = scratch;
15153 else if (GET_CODE (addr) == SYMBOL_REF || GET_CODE (addr) == CONST
15154 || GET_CODE (addr) == CONST_INT || REG_P (addr))
15156 if (TARGET_DEBUG_ADDR)
15158 fprintf (stderr, "\nMove addr to register %s, mode = %s: ",
15159 rs6000_reg_names[REGNO (scratch_or_premodify)],
15160 GET_MODE_NAME (mode));
15161 debug_rtx (addr);
15164 rs6000_emit_move (scratch_or_premodify, addr, Pmode);
15165 addr = scratch_or_premodify;
15166 scratch_or_premodify = scratch;
15169 else
15170 gcc_unreachable ();
15172 break;
15174 default:
15175 gcc_unreachable ();
15178 /* If the original address involved a pre-modify that we couldn't use the VSX
15179 memory instruction with update, and we haven't taken care of already,
15180 store the address in the pre-modify register and use that as the
15181 address. */
15182 if (scratch_or_premodify != scratch && scratch_or_premodify != addr)
15184 emit_insn (gen_rtx_SET (VOIDmode, scratch_or_premodify, addr));
15185 addr = scratch_or_premodify;
15188 /* If the original address involved an AND -16 and we couldn't use an ALTIVEC
15189 memory instruction, recreate the AND now, including the clobber which is
15190 generated by the general ANDSI3/ANDDI3 patterns for the
15191 andi. instruction. */
15192 if (and_op2 != NULL_RTX)
15194 if (! legitimate_indirect_address_p (addr, false))
15196 emit_insn (gen_rtx_SET (VOIDmode, scratch, addr));
15197 addr = scratch;
15200 if (TARGET_DEBUG_ADDR)
15202 fprintf (stderr, "\nAnd addr to register %s, mode = %s: ",
15203 rs6000_reg_names[REGNO (scratch)], GET_MODE_NAME (mode));
15204 debug_rtx (and_op2);
15207 and_rtx = gen_rtx_SET (VOIDmode,
15208 scratch,
15209 gen_rtx_AND (Pmode,
15210 addr,
15211 and_op2));
15213 cc_clobber = gen_rtx_CLOBBER (CCmode, gen_rtx_SCRATCH (CCmode));
15214 emit_insn (gen_rtx_PARALLEL (VOIDmode,
15215 gen_rtvec (2, and_rtx, cc_clobber)));
15216 addr = scratch;
15219 /* Adjust the address if it changed. */
15220 if (addr != XEXP (mem, 0))
15222 mem = change_address (mem, mode, addr);
15223 if (TARGET_DEBUG_ADDR)
15224 fprintf (stderr, "\nrs6000_secondary_reload_inner, mem adjusted.\n");
15227 /* Now create the move. */
15228 if (store_p)
15229 emit_insn (gen_rtx_SET (VOIDmode, mem, reg));
15230 else
15231 emit_insn (gen_rtx_SET (VOIDmode, reg, mem));
15233 return;
15236 /* Convert reloads involving 64-bit gprs and misaligned offset
15237 addressing to use indirect addressing. */
15239 void
15240 rs6000_secondary_reload_ppc64 (rtx reg, rtx mem, rtx scratch, bool store_p)
15242 int regno = true_regnum (reg);
15243 enum reg_class rclass;
15244 rtx addr;
15245 rtx scratch_or_premodify = scratch;
15247 if (TARGET_DEBUG_ADDR)
15249 fprintf (stderr, "\nrs6000_secondary_reload_ppc64, type = %s\n",
15250 store_p ? "store" : "load");
15251 fprintf (stderr, "reg:\n");
15252 debug_rtx (reg);
15253 fprintf (stderr, "mem:\n");
15254 debug_rtx (mem);
15255 fprintf (stderr, "scratch:\n");
15256 debug_rtx (scratch);
15259 gcc_assert (regno >= 0 && regno < FIRST_PSEUDO_REGISTER);
15260 gcc_assert (GET_CODE (mem) == MEM);
15261 rclass = REGNO_REG_CLASS (regno);
15262 gcc_assert (rclass == GENERAL_REGS || rclass == BASE_REGS);
15263 addr = XEXP (mem, 0);
15265 if (GET_CODE (addr) == PRE_MODIFY)
15267 scratch_or_premodify = XEXP (addr, 0);
15268 gcc_assert (REG_P (scratch_or_premodify));
15269 addr = XEXP (addr, 1);
15271 gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM);
15273 rs6000_emit_move (scratch_or_premodify, addr, Pmode);
15275 mem = replace_equiv_address_nv (mem, scratch_or_premodify);
15277 /* Now create the move. */
15278 if (store_p)
15279 emit_insn (gen_rtx_SET (VOIDmode, mem, reg));
15280 else
15281 emit_insn (gen_rtx_SET (VOIDmode, reg, mem));
15283 return;
15286 /* Allocate a 64-bit stack slot to be used for copying SDmode
15287 values through if this function has any SDmode references. */
15289 static void
15290 rs6000_alloc_sdmode_stack_slot (void)
15292 tree t;
15293 basic_block bb;
15294 gimple_stmt_iterator gsi;
15296 gcc_assert (cfun->machine->sdmode_stack_slot == NULL_RTX);
15298 FOR_EACH_BB (bb)
15299 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
15301 tree ret = walk_gimple_op (gsi_stmt (gsi), rs6000_check_sdmode, NULL);
15302 if (ret)
15304 rtx stack = assign_stack_local (DDmode, GET_MODE_SIZE (DDmode), 0);
15305 cfun->machine->sdmode_stack_slot = adjust_address_nv (stack,
15306 SDmode, 0);
15307 return;
15311 /* Check for any SDmode parameters of the function. */
15312 for (t = DECL_ARGUMENTS (cfun->decl); t; t = DECL_CHAIN (t))
15314 if (TREE_TYPE (t) == error_mark_node)
15315 continue;
15317 if (TYPE_MODE (TREE_TYPE (t)) == SDmode
15318 || TYPE_MODE (DECL_ARG_TYPE (t)) == SDmode)
15320 rtx stack = assign_stack_local (DDmode, GET_MODE_SIZE (DDmode), 0);
15321 cfun->machine->sdmode_stack_slot = adjust_address_nv (stack,
15322 SDmode, 0);
15323 return;
15328 static void
15329 rs6000_instantiate_decls (void)
15331 if (cfun->machine->sdmode_stack_slot != NULL_RTX)
15332 instantiate_decl_rtl (cfun->machine->sdmode_stack_slot);
15335 /* Given an rtx X being reloaded into a reg required to be
15336 in class CLASS, return the class of reg to actually use.
15337 In general this is just CLASS; but on some machines
15338 in some cases it is preferable to use a more restrictive class.
15340 On the RS/6000, we have to return NO_REGS when we want to reload a
15341 floating-point CONST_DOUBLE to force it to be copied to memory.
15343 We also don't want to reload integer values into floating-point
15344 registers if we can at all help it. In fact, this can
15345 cause reload to die, if it tries to generate a reload of CTR
15346 into a FP register and discovers it doesn't have the memory location
15347 required.
15349 ??? Would it be a good idea to have reload do the converse, that is
15350 try to reload floating modes into FP registers if possible?
15353 static enum reg_class
15354 rs6000_preferred_reload_class (rtx x, enum reg_class rclass)
15356 enum machine_mode mode = GET_MODE (x);
15358 if (VECTOR_UNIT_VSX_P (mode)
15359 && x == CONST0_RTX (mode) && VSX_REG_CLASS_P (rclass))
15360 return rclass;
15362 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode)
15363 && (rclass == ALTIVEC_REGS || rclass == VSX_REGS)
15364 && easy_vector_constant (x, mode))
15365 return ALTIVEC_REGS;
15367 if (CONSTANT_P (x) && reg_classes_intersect_p (rclass, FLOAT_REGS))
15368 return NO_REGS;
15370 if (GET_MODE_CLASS (mode) == MODE_INT && rclass == NON_SPECIAL_REGS)
15371 return GENERAL_REGS;
15373 /* For VSX, prefer the traditional registers for 64-bit values because we can
15374 use the non-VSX loads. Prefer the Altivec registers if Altivec is
15375 handling the vector operations (i.e. V16QI, V8HI, and V4SI), or if we
15376 prefer Altivec loads.. */
15377 if (rclass == VSX_REGS)
15379 if (GET_MODE_SIZE (mode) <= 8)
15380 return FLOAT_REGS;
15382 if (VECTOR_UNIT_ALTIVEC_P (mode) || VECTOR_MEM_ALTIVEC_P (mode))
15383 return ALTIVEC_REGS;
15385 return rclass;
15388 return rclass;
15391 /* Debug version of rs6000_preferred_reload_class. */
15392 static enum reg_class
15393 rs6000_debug_preferred_reload_class (rtx x, enum reg_class rclass)
15395 enum reg_class ret = rs6000_preferred_reload_class (x, rclass);
15397 fprintf (stderr,
15398 "\nrs6000_preferred_reload_class, return %s, rclass = %s, "
15399 "mode = %s, x:\n",
15400 reg_class_names[ret], reg_class_names[rclass],
15401 GET_MODE_NAME (GET_MODE (x)));
15402 debug_rtx (x);
15404 return ret;
15407 /* If we are copying between FP or AltiVec registers and anything else, we need
15408 a memory location. The exception is when we are targeting ppc64 and the
15409 move to/from fpr to gpr instructions are available. Also, under VSX, you
15410 can copy vector registers from the FP register set to the Altivec register
15411 set and vice versa. */
15413 static bool
15414 rs6000_secondary_memory_needed (enum reg_class class1,
15415 enum reg_class class2,
15416 enum machine_mode mode)
15418 if (class1 == class2)
15419 return false;
15421 /* Under VSX, there are 3 register classes that values could be in (VSX_REGS,
15422 ALTIVEC_REGS, and FLOAT_REGS). We don't need to use memory to copy
15423 between these classes. But we need memory for other things that can go in
15424 FLOAT_REGS like SFmode. */
15425 if (TARGET_VSX
15426 && (VECTOR_MEM_VSX_P (mode) || VECTOR_UNIT_VSX_P (mode))
15427 && (class1 == VSX_REGS || class1 == ALTIVEC_REGS
15428 || class1 == FLOAT_REGS))
15429 return (class2 != VSX_REGS && class2 != ALTIVEC_REGS
15430 && class2 != FLOAT_REGS);
15432 if (class1 == VSX_REGS || class2 == VSX_REGS)
15433 return true;
15435 if (class1 == FLOAT_REGS
15436 && (!TARGET_MFPGPR || !TARGET_POWERPC64
15437 || ((mode != DFmode)
15438 && (mode != DDmode)
15439 && (mode != DImode))))
15440 return true;
15442 if (class2 == FLOAT_REGS
15443 && (!TARGET_MFPGPR || !TARGET_POWERPC64
15444 || ((mode != DFmode)
15445 && (mode != DDmode)
15446 && (mode != DImode))))
15447 return true;
15449 if (class1 == ALTIVEC_REGS || class2 == ALTIVEC_REGS)
15450 return true;
15452 return false;
15455 /* Debug version of rs6000_secondary_memory_needed. */
15456 static bool
15457 rs6000_debug_secondary_memory_needed (enum reg_class class1,
15458 enum reg_class class2,
15459 enum machine_mode mode)
15461 bool ret = rs6000_secondary_memory_needed (class1, class2, mode);
15463 fprintf (stderr,
15464 "rs6000_secondary_memory_needed, return: %s, class1 = %s, "
15465 "class2 = %s, mode = %s\n",
15466 ret ? "true" : "false", reg_class_names[class1],
15467 reg_class_names[class2], GET_MODE_NAME (mode));
15469 return ret;
15472 /* Return the register class of a scratch register needed to copy IN into
15473 or out of a register in RCLASS in MODE. If it can be done directly,
15474 NO_REGS is returned. */
15476 static enum reg_class
15477 rs6000_secondary_reload_class (enum reg_class rclass, enum machine_mode mode,
15478 rtx in)
15480 int regno;
15482 if (TARGET_ELF || (DEFAULT_ABI == ABI_DARWIN
15483 #if TARGET_MACHO
15484 && MACHOPIC_INDIRECT
15485 #endif
15488 /* We cannot copy a symbolic operand directly into anything
15489 other than BASE_REGS for TARGET_ELF. So indicate that a
15490 register from BASE_REGS is needed as an intermediate
15491 register.
15493 On Darwin, pic addresses require a load from memory, which
15494 needs a base register. */
15495 if (rclass != BASE_REGS
15496 && (GET_CODE (in) == SYMBOL_REF
15497 || GET_CODE (in) == HIGH
15498 || GET_CODE (in) == LABEL_REF
15499 || GET_CODE (in) == CONST))
15500 return BASE_REGS;
15503 if (GET_CODE (in) == REG)
15505 regno = REGNO (in);
15506 if (regno >= FIRST_PSEUDO_REGISTER)
15508 regno = true_regnum (in);
15509 if (regno >= FIRST_PSEUDO_REGISTER)
15510 regno = -1;
15513 else if (GET_CODE (in) == SUBREG)
15515 regno = true_regnum (in);
15516 if (regno >= FIRST_PSEUDO_REGISTER)
15517 regno = -1;
15519 else
15520 regno = -1;
15522 /* We can place anything into GENERAL_REGS and can put GENERAL_REGS
15523 into anything. */
15524 if (rclass == GENERAL_REGS || rclass == BASE_REGS
15525 || (regno >= 0 && INT_REGNO_P (regno)))
15526 return NO_REGS;
15528 /* Constants, memory, and FP registers can go into FP registers. */
15529 if ((regno == -1 || FP_REGNO_P (regno))
15530 && (rclass == FLOAT_REGS || rclass == NON_SPECIAL_REGS))
15531 return (mode != SDmode) ? NO_REGS : GENERAL_REGS;
15533 /* Memory, and FP/altivec registers can go into fp/altivec registers under
15534 VSX. */
15535 if (TARGET_VSX
15536 && (regno == -1 || VSX_REGNO_P (regno))
15537 && VSX_REG_CLASS_P (rclass))
15538 return NO_REGS;
15540 /* Memory, and AltiVec registers can go into AltiVec registers. */
15541 if ((regno == -1 || ALTIVEC_REGNO_P (regno))
15542 && rclass == ALTIVEC_REGS)
15543 return NO_REGS;
15545 /* We can copy among the CR registers. */
15546 if ((rclass == CR_REGS || rclass == CR0_REGS)
15547 && regno >= 0 && CR_REGNO_P (regno))
15548 return NO_REGS;
15550 /* Otherwise, we need GENERAL_REGS. */
15551 return GENERAL_REGS;
15554 /* Debug version of rs6000_secondary_reload_class. */
15555 static enum reg_class
15556 rs6000_debug_secondary_reload_class (enum reg_class rclass,
15557 enum machine_mode mode, rtx in)
15559 enum reg_class ret = rs6000_secondary_reload_class (rclass, mode, in);
15560 fprintf (stderr,
15561 "\nrs6000_secondary_reload_class, return %s, rclass = %s, "
15562 "mode = %s, input rtx:\n",
15563 reg_class_names[ret], reg_class_names[rclass],
15564 GET_MODE_NAME (mode));
15565 debug_rtx (in);
15567 return ret;
15570 /* Return nonzero if for CLASS a mode change from FROM to TO is invalid. */
15572 static bool
15573 rs6000_cannot_change_mode_class (enum machine_mode from,
15574 enum machine_mode to,
15575 enum reg_class rclass)
15577 unsigned from_size = GET_MODE_SIZE (from);
15578 unsigned to_size = GET_MODE_SIZE (to);
15580 if (from_size != to_size)
15582 enum reg_class xclass = (TARGET_VSX) ? VSX_REGS : FLOAT_REGS;
15583 return ((from_size < 8 || to_size < 8 || TARGET_IEEEQUAD)
15584 && reg_classes_intersect_p (xclass, rclass));
15587 if (TARGET_E500_DOUBLE
15588 && ((((to) == DFmode) + ((from) == DFmode)) == 1
15589 || (((to) == TFmode) + ((from) == TFmode)) == 1
15590 || (((to) == DDmode) + ((from) == DDmode)) == 1
15591 || (((to) == TDmode) + ((from) == TDmode)) == 1
15592 || (((to) == DImode) + ((from) == DImode)) == 1))
15593 return true;
15595 /* Since the VSX register set includes traditional floating point registers
15596 and altivec registers, just check for the size being different instead of
15597 trying to check whether the modes are vector modes. Otherwise it won't
15598 allow say DF and DI to change classes. */
15599 if (TARGET_VSX && VSX_REG_CLASS_P (rclass))
15600 return (from_size != 8 && from_size != 16);
15602 if (TARGET_ALTIVEC && rclass == ALTIVEC_REGS
15603 && (ALTIVEC_VECTOR_MODE (from) + ALTIVEC_VECTOR_MODE (to)) == 1)
15604 return true;
15606 if (TARGET_SPE && (SPE_VECTOR_MODE (from) + SPE_VECTOR_MODE (to)) == 1
15607 && reg_classes_intersect_p (GENERAL_REGS, rclass))
15608 return true;
15610 return false;
15613 /* Debug version of rs6000_cannot_change_mode_class. */
15614 static bool
15615 rs6000_debug_cannot_change_mode_class (enum machine_mode from,
15616 enum machine_mode to,
15617 enum reg_class rclass)
15619 bool ret = rs6000_cannot_change_mode_class (from, to, rclass);
15621 fprintf (stderr,
15622 "rs6000_cannot_change_mode_class, return %s, from = %s, "
15623 "to = %s, rclass = %s\n",
15624 ret ? "true" : "false",
15625 GET_MODE_NAME (from), GET_MODE_NAME (to),
15626 reg_class_names[rclass]);
15628 return ret;
15631 /* Given a comparison operation, return the bit number in CCR to test. We
15632 know this is a valid comparison.
15634 SCC_P is 1 if this is for an scc. That means that %D will have been
15635 used instead of %C, so the bits will be in different places.
15637 Return -1 if OP isn't a valid comparison for some reason. */
15640 ccr_bit (rtx op, int scc_p)
15642 enum rtx_code code = GET_CODE (op);
15643 enum machine_mode cc_mode;
15644 int cc_regnum;
15645 int base_bit;
15646 rtx reg;
15648 if (!COMPARISON_P (op))
15649 return -1;
15651 reg = XEXP (op, 0);
15653 gcc_assert (GET_CODE (reg) == REG && CR_REGNO_P (REGNO (reg)));
15655 cc_mode = GET_MODE (reg);
15656 cc_regnum = REGNO (reg);
15657 base_bit = 4 * (cc_regnum - CR0_REGNO);
15659 validate_condition_mode (code, cc_mode);
15661 /* When generating a sCOND operation, only positive conditions are
15662 allowed. */
15663 gcc_assert (!scc_p
15664 || code == EQ || code == GT || code == LT || code == UNORDERED
15665 || code == GTU || code == LTU);
15667 switch (code)
15669 case NE:
15670 return scc_p ? base_bit + 3 : base_bit + 2;
15671 case EQ:
15672 return base_bit + 2;
15673 case GT: case GTU: case UNLE:
15674 return base_bit + 1;
15675 case LT: case LTU: case UNGE:
15676 return base_bit;
15677 case ORDERED: case UNORDERED:
15678 return base_bit + 3;
15680 case GE: case GEU:
15681 /* If scc, we will have done a cror to put the bit in the
15682 unordered position. So test that bit. For integer, this is ! LT
15683 unless this is an scc insn. */
15684 return scc_p ? base_bit + 3 : base_bit;
15686 case LE: case LEU:
15687 return scc_p ? base_bit + 3 : base_bit + 1;
15689 default:
15690 gcc_unreachable ();
15694 /* Return the GOT register. */
15697 rs6000_got_register (rtx value ATTRIBUTE_UNUSED)
15699 /* The second flow pass currently (June 1999) can't update
15700 regs_ever_live without disturbing other parts of the compiler, so
15701 update it here to make the prolog/epilogue code happy. */
15702 if (!can_create_pseudo_p ()
15703 && !df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM))
15704 df_set_regs_ever_live (RS6000_PIC_OFFSET_TABLE_REGNUM, true);
15706 crtl->uses_pic_offset_table = 1;
15708 return pic_offset_table_rtx;
15711 static rs6000_stack_t stack_info;
15713 /* Function to init struct machine_function.
15714 This will be called, via a pointer variable,
15715 from push_function_context. */
15717 static struct machine_function *
15718 rs6000_init_machine_status (void)
15720 stack_info.reload_completed = 0;
15721 return ggc_alloc_cleared_machine_function ();
15724 /* These macros test for integers and extract the low-order bits. */
15725 #define INT_P(X) \
15726 ((GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST_DOUBLE) \
15727 && GET_MODE (X) == VOIDmode)
15729 #define INT_LOWPART(X) \
15730 (GET_CODE (X) == CONST_INT ? INTVAL (X) : CONST_DOUBLE_LOW (X))
15733 extract_MB (rtx op)
15735 int i;
15736 unsigned long val = INT_LOWPART (op);
15738 /* If the high bit is zero, the value is the first 1 bit we find
15739 from the left. */
15740 if ((val & 0x80000000) == 0)
15742 gcc_assert (val & 0xffffffff);
15744 i = 1;
15745 while (((val <<= 1) & 0x80000000) == 0)
15746 ++i;
15747 return i;
15750 /* If the high bit is set and the low bit is not, or the mask is all
15751 1's, the value is zero. */
15752 if ((val & 1) == 0 || (val & 0xffffffff) == 0xffffffff)
15753 return 0;
15755 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
15756 from the right. */
15757 i = 31;
15758 while (((val >>= 1) & 1) != 0)
15759 --i;
15761 return i;
15765 extract_ME (rtx op)
15767 int i;
15768 unsigned long val = INT_LOWPART (op);
15770 /* If the low bit is zero, the value is the first 1 bit we find from
15771 the right. */
15772 if ((val & 1) == 0)
15774 gcc_assert (val & 0xffffffff);
15776 i = 30;
15777 while (((val >>= 1) & 1) == 0)
15778 --i;
15780 return i;
15783 /* If the low bit is set and the high bit is not, or the mask is all
15784 1's, the value is 31. */
15785 if ((val & 0x80000000) == 0 || (val & 0xffffffff) == 0xffffffff)
15786 return 31;
15788 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
15789 from the left. */
15790 i = 0;
15791 while (((val <<= 1) & 0x80000000) != 0)
15792 ++i;
15794 return i;
15797 /* Locate some local-dynamic symbol still in use by this function
15798 so that we can print its name in some tls_ld pattern. */
15800 static const char *
15801 rs6000_get_some_local_dynamic_name (void)
15803 rtx insn;
15805 if (cfun->machine->some_ld_name)
15806 return cfun->machine->some_ld_name;
15808 for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
15809 if (INSN_P (insn)
15810 && for_each_rtx (&PATTERN (insn),
15811 rs6000_get_some_local_dynamic_name_1, 0))
15812 return cfun->machine->some_ld_name;
15814 gcc_unreachable ();
15817 /* Helper function for rs6000_get_some_local_dynamic_name. */
15819 static int
15820 rs6000_get_some_local_dynamic_name_1 (rtx *px, void *data ATTRIBUTE_UNUSED)
15822 rtx x = *px;
15824 if (GET_CODE (x) == SYMBOL_REF)
15826 const char *str = XSTR (x, 0);
15827 if (SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_DYNAMIC)
15829 cfun->machine->some_ld_name = str;
15830 return 1;
15834 return 0;
15837 /* Write out a function code label. */
15839 void
15840 rs6000_output_function_entry (FILE *file, const char *fname)
15842 if (fname[0] != '.')
15844 switch (DEFAULT_ABI)
15846 default:
15847 gcc_unreachable ();
15849 case ABI_AIX:
15850 if (DOT_SYMBOLS)
15851 putc ('.', file);
15852 else
15853 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "L.");
15854 break;
15856 case ABI_V4:
15857 case ABI_DARWIN:
15858 break;
15862 RS6000_OUTPUT_BASENAME (file, fname);
15865 /* Print an operand. Recognize special options, documented below. */
15867 #if TARGET_ELF
15868 #define SMALL_DATA_RELOC ((rs6000_sdata == SDATA_EABI) ? "sda21" : "sdarel")
15869 #define SMALL_DATA_REG ((rs6000_sdata == SDATA_EABI) ? 0 : 13)
15870 #else
15871 #define SMALL_DATA_RELOC "sda21"
15872 #define SMALL_DATA_REG 0
15873 #endif
15875 void
15876 print_operand (FILE *file, rtx x, int code)
15878 int i;
15879 HOST_WIDE_INT val;
15880 unsigned HOST_WIDE_INT uval;
15882 switch (code)
15884 case '.':
15885 /* Write out an instruction after the call which may be replaced
15886 with glue code by the loader. This depends on the AIX version. */
15887 asm_fprintf (file, RS6000_CALL_GLUE);
15888 return;
15890 /* %a is output_address. */
15892 case 'A':
15893 /* If X is a constant integer whose low-order 5 bits are zero,
15894 write 'l'. Otherwise, write 'r'. This is a kludge to fix a bug
15895 in the AIX assembler where "sri" with a zero shift count
15896 writes a trash instruction. */
15897 if (GET_CODE (x) == CONST_INT && (INTVAL (x) & 31) == 0)
15898 putc ('l', file);
15899 else
15900 putc ('r', file);
15901 return;
15903 case 'b':
15904 /* If constant, low-order 16 bits of constant, unsigned.
15905 Otherwise, write normally. */
15906 if (INT_P (x))
15907 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 0xffff);
15908 else
15909 print_operand (file, x, 0);
15910 return;
15912 case 'B':
15913 /* If the low-order bit is zero, write 'r'; otherwise, write 'l'
15914 for 64-bit mask direction. */
15915 putc (((INT_LOWPART (x) & 1) == 0 ? 'r' : 'l'), file);
15916 return;
15918 /* %c is output_addr_const if a CONSTANT_ADDRESS_P, otherwise
15919 output_operand. */
15921 case 'c':
15922 /* X is a CR register. Print the number of the GT bit of the CR. */
15923 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15924 output_operand_lossage ("invalid %%c value");
15925 else
15926 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 1);
15927 return;
15929 case 'D':
15930 /* Like 'J' but get to the GT bit only. */
15931 gcc_assert (GET_CODE (x) == REG);
15933 /* Bit 1 is GT bit. */
15934 i = 4 * (REGNO (x) - CR0_REGNO) + 1;
15936 /* Add one for shift count in rlinm for scc. */
15937 fprintf (file, "%d", i + 1);
15938 return;
15940 case 'E':
15941 /* X is a CR register. Print the number of the EQ bit of the CR */
15942 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15943 output_operand_lossage ("invalid %%E value");
15944 else
15945 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 2);
15946 return;
15948 case 'f':
15949 /* X is a CR register. Print the shift count needed to move it
15950 to the high-order four bits. */
15951 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15952 output_operand_lossage ("invalid %%f value");
15953 else
15954 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO));
15955 return;
15957 case 'F':
15958 /* Similar, but print the count for the rotate in the opposite
15959 direction. */
15960 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15961 output_operand_lossage ("invalid %%F value");
15962 else
15963 fprintf (file, "%d", 32 - 4 * (REGNO (x) - CR0_REGNO));
15964 return;
15966 case 'G':
15967 /* X is a constant integer. If it is negative, print "m",
15968 otherwise print "z". This is to make an aze or ame insn. */
15969 if (GET_CODE (x) != CONST_INT)
15970 output_operand_lossage ("invalid %%G value");
15971 else if (INTVAL (x) >= 0)
15972 putc ('z', file);
15973 else
15974 putc ('m', file);
15975 return;
15977 case 'h':
15978 /* If constant, output low-order five bits. Otherwise, write
15979 normally. */
15980 if (INT_P (x))
15981 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 31);
15982 else
15983 print_operand (file, x, 0);
15984 return;
15986 case 'H':
15987 /* If constant, output low-order six bits. Otherwise, write
15988 normally. */
15989 if (INT_P (x))
15990 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 63);
15991 else
15992 print_operand (file, x, 0);
15993 return;
15995 case 'I':
15996 /* Print `i' if this is a constant, else nothing. */
15997 if (INT_P (x))
15998 putc ('i', file);
15999 return;
16001 case 'j':
16002 /* Write the bit number in CCR for jump. */
16003 i = ccr_bit (x, 0);
16004 if (i == -1)
16005 output_operand_lossage ("invalid %%j code");
16006 else
16007 fprintf (file, "%d", i);
16008 return;
16010 case 'J':
16011 /* Similar, but add one for shift count in rlinm for scc and pass
16012 scc flag to `ccr_bit'. */
16013 i = ccr_bit (x, 1);
16014 if (i == -1)
16015 output_operand_lossage ("invalid %%J code");
16016 else
16017 /* If we want bit 31, write a shift count of zero, not 32. */
16018 fprintf (file, "%d", i == 31 ? 0 : i + 1);
16019 return;
16021 case 'k':
16022 /* X must be a constant. Write the 1's complement of the
16023 constant. */
16024 if (! INT_P (x))
16025 output_operand_lossage ("invalid %%k value");
16026 else
16027 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ~ INT_LOWPART (x));
16028 return;
16030 case 'K':
16031 /* X must be a symbolic constant on ELF. Write an
16032 expression suitable for an 'addi' that adds in the low 16
16033 bits of the MEM. */
16034 if (GET_CODE (x) == CONST)
16036 if (GET_CODE (XEXP (x, 0)) != PLUS
16037 || (GET_CODE (XEXP (XEXP (x, 0), 0)) != SYMBOL_REF
16038 && GET_CODE (XEXP (XEXP (x, 0), 0)) != LABEL_REF)
16039 || GET_CODE (XEXP (XEXP (x, 0), 1)) != CONST_INT)
16040 output_operand_lossage ("invalid %%K value");
16042 print_operand_address (file, x);
16043 fputs ("@l", file);
16044 return;
16046 /* %l is output_asm_label. */
16048 case 'L':
16049 /* Write second word of DImode or DFmode reference. Works on register
16050 or non-indexed memory only. */
16051 if (GET_CODE (x) == REG)
16052 fputs (reg_names[REGNO (x) + 1], file);
16053 else if (GET_CODE (x) == MEM)
16055 /* Handle possible auto-increment. Since it is pre-increment and
16056 we have already done it, we can just use an offset of word. */
16057 if (GET_CODE (XEXP (x, 0)) == PRE_INC
16058 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
16059 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
16060 UNITS_PER_WORD));
16061 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
16062 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
16063 UNITS_PER_WORD));
16064 else
16065 output_address (XEXP (adjust_address_nv (x, SImode,
16066 UNITS_PER_WORD),
16067 0));
16069 if (small_data_operand (x, GET_MODE (x)))
16070 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
16071 reg_names[SMALL_DATA_REG]);
16073 return;
16075 case 'm':
16076 /* MB value for a mask operand. */
16077 if (! mask_operand (x, SImode))
16078 output_operand_lossage ("invalid %%m value");
16080 fprintf (file, "%d", extract_MB (x));
16081 return;
16083 case 'M':
16084 /* ME value for a mask operand. */
16085 if (! mask_operand (x, SImode))
16086 output_operand_lossage ("invalid %%M value");
16088 fprintf (file, "%d", extract_ME (x));
16089 return;
16091 /* %n outputs the negative of its operand. */
16093 case 'N':
16094 /* Write the number of elements in the vector times 4. */
16095 if (GET_CODE (x) != PARALLEL)
16096 output_operand_lossage ("invalid %%N value");
16097 else
16098 fprintf (file, "%d", XVECLEN (x, 0) * 4);
16099 return;
16101 case 'O':
16102 /* Similar, but subtract 1 first. */
16103 if (GET_CODE (x) != PARALLEL)
16104 output_operand_lossage ("invalid %%O value");
16105 else
16106 fprintf (file, "%d", (XVECLEN (x, 0) - 1) * 4);
16107 return;
16109 case 'p':
16110 /* X is a CONST_INT that is a power of two. Output the logarithm. */
16111 if (! INT_P (x)
16112 || INT_LOWPART (x) < 0
16113 || (i = exact_log2 (INT_LOWPART (x))) < 0)
16114 output_operand_lossage ("invalid %%p value");
16115 else
16116 fprintf (file, "%d", i);
16117 return;
16119 case 'P':
16120 /* The operand must be an indirect memory reference. The result
16121 is the register name. */
16122 if (GET_CODE (x) != MEM || GET_CODE (XEXP (x, 0)) != REG
16123 || REGNO (XEXP (x, 0)) >= 32)
16124 output_operand_lossage ("invalid %%P value");
16125 else
16126 fputs (reg_names[REGNO (XEXP (x, 0))], file);
16127 return;
16129 case 'q':
16130 /* This outputs the logical code corresponding to a boolean
16131 expression. The expression may have one or both operands
16132 negated (if one, only the first one). For condition register
16133 logical operations, it will also treat the negated
16134 CR codes as NOTs, but not handle NOTs of them. */
16136 const char *const *t = 0;
16137 const char *s;
16138 enum rtx_code code = GET_CODE (x);
16139 static const char * const tbl[3][3] = {
16140 { "and", "andc", "nor" },
16141 { "or", "orc", "nand" },
16142 { "xor", "eqv", "xor" } };
16144 if (code == AND)
16145 t = tbl[0];
16146 else if (code == IOR)
16147 t = tbl[1];
16148 else if (code == XOR)
16149 t = tbl[2];
16150 else
16151 output_operand_lossage ("invalid %%q value");
16153 if (GET_CODE (XEXP (x, 0)) != NOT)
16154 s = t[0];
16155 else
16157 if (GET_CODE (XEXP (x, 1)) == NOT)
16158 s = t[2];
16159 else
16160 s = t[1];
16163 fputs (s, file);
16165 return;
16167 case 'Q':
16168 if (TARGET_MFCRF)
16169 fputc (',', file);
16170 /* FALLTHRU */
16171 else
16172 return;
16174 case 'R':
16175 /* X is a CR register. Print the mask for `mtcrf'. */
16176 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
16177 output_operand_lossage ("invalid %%R value");
16178 else
16179 fprintf (file, "%d", 128 >> (REGNO (x) - CR0_REGNO));
16180 return;
16182 case 's':
16183 /* Low 5 bits of 32 - value */
16184 if (! INT_P (x))
16185 output_operand_lossage ("invalid %%s value");
16186 else
16187 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (32 - INT_LOWPART (x)) & 31);
16188 return;
16190 case 'S':
16191 /* PowerPC64 mask position. All 0's is excluded.
16192 CONST_INT 32-bit mask is considered sign-extended so any
16193 transition must occur within the CONST_INT, not on the boundary. */
16194 if (! mask64_operand (x, DImode))
16195 output_operand_lossage ("invalid %%S value");
16197 uval = INT_LOWPART (x);
16199 if (uval & 1) /* Clear Left */
16201 #if HOST_BITS_PER_WIDE_INT > 64
16202 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
16203 #endif
16204 i = 64;
16206 else /* Clear Right */
16208 uval = ~uval;
16209 #if HOST_BITS_PER_WIDE_INT > 64
16210 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
16211 #endif
16212 i = 63;
16214 while (uval != 0)
16215 --i, uval >>= 1;
16216 gcc_assert (i >= 0);
16217 fprintf (file, "%d", i);
16218 return;
16220 case 't':
16221 /* Like 'J' but get to the OVERFLOW/UNORDERED bit. */
16222 gcc_assert (GET_CODE (x) == REG && GET_MODE (x) == CCmode);
16224 /* Bit 3 is OV bit. */
16225 i = 4 * (REGNO (x) - CR0_REGNO) + 3;
16227 /* If we want bit 31, write a shift count of zero, not 32. */
16228 fprintf (file, "%d", i == 31 ? 0 : i + 1);
16229 return;
16231 case 'T':
16232 /* Print the symbolic name of a branch target register. */
16233 if (GET_CODE (x) != REG || (REGNO (x) != LR_REGNO
16234 && REGNO (x) != CTR_REGNO))
16235 output_operand_lossage ("invalid %%T value");
16236 else if (REGNO (x) == LR_REGNO)
16237 fputs (TARGET_NEW_MNEMONICS ? "lr" : "r", file);
16238 else
16239 fputs ("ctr", file);
16240 return;
16242 case 'u':
16243 /* High-order 16 bits of constant for use in unsigned operand. */
16244 if (! INT_P (x))
16245 output_operand_lossage ("invalid %%u value");
16246 else
16247 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
16248 (INT_LOWPART (x) >> 16) & 0xffff);
16249 return;
16251 case 'v':
16252 /* High-order 16 bits of constant for use in signed operand. */
16253 if (! INT_P (x))
16254 output_operand_lossage ("invalid %%v value");
16255 else
16256 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
16257 (INT_LOWPART (x) >> 16) & 0xffff);
16258 return;
16260 case 'U':
16261 /* Print `u' if this has an auto-increment or auto-decrement. */
16262 if (GET_CODE (x) == MEM
16263 && (GET_CODE (XEXP (x, 0)) == PRE_INC
16264 || GET_CODE (XEXP (x, 0)) == PRE_DEC
16265 || GET_CODE (XEXP (x, 0)) == PRE_MODIFY))
16266 putc ('u', file);
16267 return;
16269 case 'V':
16270 /* Print the trap code for this operand. */
16271 switch (GET_CODE (x))
16273 case EQ:
16274 fputs ("eq", file); /* 4 */
16275 break;
16276 case NE:
16277 fputs ("ne", file); /* 24 */
16278 break;
16279 case LT:
16280 fputs ("lt", file); /* 16 */
16281 break;
16282 case LE:
16283 fputs ("le", file); /* 20 */
16284 break;
16285 case GT:
16286 fputs ("gt", file); /* 8 */
16287 break;
16288 case GE:
16289 fputs ("ge", file); /* 12 */
16290 break;
16291 case LTU:
16292 fputs ("llt", file); /* 2 */
16293 break;
16294 case LEU:
16295 fputs ("lle", file); /* 6 */
16296 break;
16297 case GTU:
16298 fputs ("lgt", file); /* 1 */
16299 break;
16300 case GEU:
16301 fputs ("lge", file); /* 5 */
16302 break;
16303 default:
16304 gcc_unreachable ();
16306 break;
16308 case 'w':
16309 /* If constant, low-order 16 bits of constant, signed. Otherwise, write
16310 normally. */
16311 if (INT_P (x))
16312 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
16313 ((INT_LOWPART (x) & 0xffff) ^ 0x8000) - 0x8000);
16314 else
16315 print_operand (file, x, 0);
16316 return;
16318 case 'W':
16319 /* MB value for a PowerPC64 rldic operand. */
16320 val = (GET_CODE (x) == CONST_INT
16321 ? INTVAL (x) : CONST_DOUBLE_HIGH (x));
16323 if (val < 0)
16324 i = -1;
16325 else
16326 for (i = 0; i < HOST_BITS_PER_WIDE_INT; i++)
16327 if ((val <<= 1) < 0)
16328 break;
16330 #if HOST_BITS_PER_WIDE_INT == 32
16331 if (GET_CODE (x) == CONST_INT && i >= 0)
16332 i += 32; /* zero-extend high-part was all 0's */
16333 else if (GET_CODE (x) == CONST_DOUBLE && i == 32)
16335 val = CONST_DOUBLE_LOW (x);
16337 gcc_assert (val);
16338 if (val < 0)
16339 --i;
16340 else
16341 for ( ; i < 64; i++)
16342 if ((val <<= 1) < 0)
16343 break;
16345 #endif
16347 fprintf (file, "%d", i + 1);
16348 return;
16350 case 'x':
16351 /* X is a FPR or Altivec register used in a VSX context. */
16352 if (GET_CODE (x) != REG || !VSX_REGNO_P (REGNO (x)))
16353 output_operand_lossage ("invalid %%x value");
16354 else
16356 int reg = REGNO (x);
16357 int vsx_reg = (FP_REGNO_P (reg)
16358 ? reg - 32
16359 : reg - FIRST_ALTIVEC_REGNO + 32);
16361 #ifdef TARGET_REGNAMES
16362 if (TARGET_REGNAMES)
16363 fprintf (file, "%%vs%d", vsx_reg);
16364 else
16365 #endif
16366 fprintf (file, "%d", vsx_reg);
16368 return;
16370 case 'X':
16371 if (GET_CODE (x) == MEM
16372 && (legitimate_indexed_address_p (XEXP (x, 0), 0)
16373 || (GET_CODE (XEXP (x, 0)) == PRE_MODIFY
16374 && legitimate_indexed_address_p (XEXP (XEXP (x, 0), 1), 0))))
16375 putc ('x', file);
16376 return;
16378 case 'Y':
16379 /* Like 'L', for third word of TImode */
16380 if (GET_CODE (x) == REG)
16381 fputs (reg_names[REGNO (x) + 2], file);
16382 else if (GET_CODE (x) == MEM)
16384 if (GET_CODE (XEXP (x, 0)) == PRE_INC
16385 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
16386 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
16387 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
16388 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
16389 else
16390 output_address (XEXP (adjust_address_nv (x, SImode, 8), 0));
16391 if (small_data_operand (x, GET_MODE (x)))
16392 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
16393 reg_names[SMALL_DATA_REG]);
16395 return;
16397 case 'z':
16398 /* X is a SYMBOL_REF. Write out the name preceded by a
16399 period and without any trailing data in brackets. Used for function
16400 names. If we are configured for System V (or the embedded ABI) on
16401 the PowerPC, do not emit the period, since those systems do not use
16402 TOCs and the like. */
16403 gcc_assert (GET_CODE (x) == SYMBOL_REF);
16405 /* Mark the decl as referenced so that cgraph will output the
16406 function. */
16407 if (SYMBOL_REF_DECL (x))
16408 mark_decl_referenced (SYMBOL_REF_DECL (x));
16410 /* For macho, check to see if we need a stub. */
16411 if (TARGET_MACHO)
16413 const char *name = XSTR (x, 0);
16414 #if TARGET_MACHO
16415 if (darwin_emit_branch_islands
16416 && MACHOPIC_INDIRECT
16417 && machopic_classify_symbol (x) == MACHOPIC_UNDEFINED_FUNCTION)
16418 name = machopic_indirection_name (x, /*stub_p=*/true);
16419 #endif
16420 assemble_name (file, name);
16422 else if (!DOT_SYMBOLS)
16423 assemble_name (file, XSTR (x, 0));
16424 else
16425 rs6000_output_function_entry (file, XSTR (x, 0));
16426 return;
16428 case 'Z':
16429 /* Like 'L', for last word of TImode. */
16430 if (GET_CODE (x) == REG)
16431 fputs (reg_names[REGNO (x) + 3], file);
16432 else if (GET_CODE (x) == MEM)
16434 if (GET_CODE (XEXP (x, 0)) == PRE_INC
16435 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
16436 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
16437 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
16438 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
16439 else
16440 output_address (XEXP (adjust_address_nv (x, SImode, 12), 0));
16441 if (small_data_operand (x, GET_MODE (x)))
16442 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
16443 reg_names[SMALL_DATA_REG]);
16445 return;
16447 /* Print AltiVec or SPE memory operand. */
16448 case 'y':
16450 rtx tmp;
16452 gcc_assert (GET_CODE (x) == MEM);
16454 tmp = XEXP (x, 0);
16456 /* Ugly hack because %y is overloaded. */
16457 if ((TARGET_SPE || TARGET_E500_DOUBLE)
16458 && (GET_MODE_SIZE (GET_MODE (x)) == 8
16459 || GET_MODE (x) == TFmode
16460 || GET_MODE (x) == TImode))
16462 /* Handle [reg]. */
16463 if (GET_CODE (tmp) == REG)
16465 fprintf (file, "0(%s)", reg_names[REGNO (tmp)]);
16466 break;
16468 /* Handle [reg+UIMM]. */
16469 else if (GET_CODE (tmp) == PLUS &&
16470 GET_CODE (XEXP (tmp, 1)) == CONST_INT)
16472 int x;
16474 gcc_assert (GET_CODE (XEXP (tmp, 0)) == REG);
16476 x = INTVAL (XEXP (tmp, 1));
16477 fprintf (file, "%d(%s)", x, reg_names[REGNO (XEXP (tmp, 0))]);
16478 break;
16481 /* Fall through. Must be [reg+reg]. */
16483 if (VECTOR_MEM_ALTIVEC_P (GET_MODE (x))
16484 && GET_CODE (tmp) == AND
16485 && GET_CODE (XEXP (tmp, 1)) == CONST_INT
16486 && INTVAL (XEXP (tmp, 1)) == -16)
16487 tmp = XEXP (tmp, 0);
16488 else if (VECTOR_MEM_VSX_P (GET_MODE (x))
16489 && GET_CODE (tmp) == PRE_MODIFY)
16490 tmp = XEXP (tmp, 1);
16491 if (GET_CODE (tmp) == REG)
16492 fprintf (file, "0,%s", reg_names[REGNO (tmp)]);
16493 else
16495 if (!GET_CODE (tmp) == PLUS
16496 || !REG_P (XEXP (tmp, 0))
16497 || !REG_P (XEXP (tmp, 1)))
16499 output_operand_lossage ("invalid %%y value, try using the 'Z' constraint");
16500 break;
16503 if (REGNO (XEXP (tmp, 0)) == 0)
16504 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 1)) ],
16505 reg_names[ REGNO (XEXP (tmp, 0)) ]);
16506 else
16507 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 0)) ],
16508 reg_names[ REGNO (XEXP (tmp, 1)) ]);
16510 break;
16513 case 0:
16514 if (GET_CODE (x) == REG)
16515 fprintf (file, "%s", reg_names[REGNO (x)]);
16516 else if (GET_CODE (x) == MEM)
16518 /* We need to handle PRE_INC and PRE_DEC here, since we need to
16519 know the width from the mode. */
16520 if (GET_CODE (XEXP (x, 0)) == PRE_INC)
16521 fprintf (file, "%d(%s)", GET_MODE_SIZE (GET_MODE (x)),
16522 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
16523 else if (GET_CODE (XEXP (x, 0)) == PRE_DEC)
16524 fprintf (file, "%d(%s)", - GET_MODE_SIZE (GET_MODE (x)),
16525 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
16526 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
16527 output_address (XEXP (XEXP (x, 0), 1));
16528 else
16529 output_address (XEXP (x, 0));
16531 else
16533 if (toc_relative_expr_p (x))
16534 /* This hack along with a corresponding hack in
16535 rs6000_output_addr_const_extra arranges to output addends
16536 where the assembler expects to find them. eg.
16537 (const (plus (unspec [symbol_ref ("x") tocrel]) 4))
16538 without this hack would be output as "x@toc+4". We
16539 want "x+4@toc". */
16540 output_addr_const (file, tocrel_base);
16541 else
16542 output_addr_const (file, x);
16544 return;
16546 case '&':
16547 assemble_name (file, rs6000_get_some_local_dynamic_name ());
16548 return;
16550 default:
16551 output_operand_lossage ("invalid %%xn code");
16555 /* Print the address of an operand. */
16557 void
16558 print_operand_address (FILE *file, rtx x)
16560 if (GET_CODE (x) == REG)
16561 fprintf (file, "0(%s)", reg_names[ REGNO (x) ]);
16562 else if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST
16563 || GET_CODE (x) == LABEL_REF)
16565 output_addr_const (file, x);
16566 if (small_data_operand (x, GET_MODE (x)))
16567 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
16568 reg_names[SMALL_DATA_REG]);
16569 else
16570 gcc_assert (!TARGET_TOC);
16572 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == REG)
16574 gcc_assert (REG_P (XEXP (x, 0)));
16575 if (REGNO (XEXP (x, 0)) == 0)
16576 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 1)) ],
16577 reg_names[ REGNO (XEXP (x, 0)) ]);
16578 else
16579 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 0)) ],
16580 reg_names[ REGNO (XEXP (x, 1)) ]);
16582 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == CONST_INT)
16583 fprintf (file, HOST_WIDE_INT_PRINT_DEC "(%s)",
16584 INTVAL (XEXP (x, 1)), reg_names[ REGNO (XEXP (x, 0)) ]);
16585 #if TARGET_MACHO
16586 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
16587 && CONSTANT_P (XEXP (x, 1)))
16589 fprintf (file, "lo16(");
16590 output_addr_const (file, XEXP (x, 1));
16591 fprintf (file, ")(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
16593 #endif
16594 else if (legitimate_constant_pool_address_p (x, QImode, true))
16596 /* This hack along with a corresponding hack in
16597 rs6000_output_addr_const_extra arranges to output addends
16598 where the assembler expects to find them. eg.
16599 (lo_sum (reg 9)
16600 . (const (plus (unspec [symbol_ref ("x") tocrel]) 8)))
16601 without this hack would be output as "x@toc+8@l(9)". We
16602 want "x+8@toc@l(9)". */
16603 output_addr_const (file, tocrel_base);
16604 if (GET_CODE (x) == LO_SUM)
16605 fprintf (file, "@l(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
16606 else
16607 fprintf (file, "(%s)", reg_names[REGNO (XEXP (x, 0))]);
16609 #if TARGET_ELF
16610 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
16611 && CONSTANT_P (XEXP (x, 1)))
16613 output_addr_const (file, XEXP (x, 1));
16614 fprintf (file, "@l(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
16616 #endif
16617 else
16618 gcc_unreachable ();
16621 /* Implement TARGET_OUTPUT_ADDR_CONST_EXTRA. */
16623 static bool
16624 rs6000_output_addr_const_extra (FILE *file, rtx x)
16626 if (GET_CODE (x) == UNSPEC)
16627 switch (XINT (x, 1))
16629 case UNSPEC_TOCREL:
16630 gcc_assert (GET_CODE (XVECEXP (x, 0, 0)) == SYMBOL_REF);
16631 output_addr_const (file, XVECEXP (x, 0, 0));
16632 if (x == tocrel_base && tocrel_offset != const0_rtx)
16634 if (INTVAL (tocrel_offset) >= 0)
16635 fprintf (file, "+");
16636 output_addr_const (file, tocrel_offset);
16638 if (!TARGET_AIX || (TARGET_ELF && TARGET_MINIMAL_TOC))
16640 putc ('-', file);
16641 assemble_name (file, toc_label_name);
16643 else if (TARGET_ELF)
16644 fputs ("@toc", file);
16645 return true;
16647 #if TARGET_MACHO
16648 case UNSPEC_MACHOPIC_OFFSET:
16649 output_addr_const (file, XVECEXP (x, 0, 0));
16650 putc ('-', file);
16651 machopic_output_function_base_name (file);
16652 return true;
16653 #endif
16655 return false;
16658 /* Target hook for assembling integer objects. The PowerPC version has
16659 to handle fixup entries for relocatable code if RELOCATABLE_NEEDS_FIXUP
16660 is defined. It also needs to handle DI-mode objects on 64-bit
16661 targets. */
16663 static bool
16664 rs6000_assemble_integer (rtx x, unsigned int size, int aligned_p)
16666 #ifdef RELOCATABLE_NEEDS_FIXUP
16667 /* Special handling for SI values. */
16668 if (RELOCATABLE_NEEDS_FIXUP && size == 4 && aligned_p)
16670 static int recurse = 0;
16672 /* For -mrelocatable, we mark all addresses that need to be fixed up
16673 in the .fixup section. */
16674 if (TARGET_RELOCATABLE
16675 && in_section != toc_section
16676 && in_section != text_section
16677 && !unlikely_text_section_p (in_section)
16678 && !recurse
16679 && GET_CODE (x) != CONST_INT
16680 && GET_CODE (x) != CONST_DOUBLE
16681 && CONSTANT_P (x))
16683 char buf[256];
16685 recurse = 1;
16686 ASM_GENERATE_INTERNAL_LABEL (buf, "LCP", fixuplabelno);
16687 fixuplabelno++;
16688 ASM_OUTPUT_LABEL (asm_out_file, buf);
16689 fprintf (asm_out_file, "\t.long\t(");
16690 output_addr_const (asm_out_file, x);
16691 fprintf (asm_out_file, ")@fixup\n");
16692 fprintf (asm_out_file, "\t.section\t\".fixup\",\"aw\"\n");
16693 ASM_OUTPUT_ALIGN (asm_out_file, 2);
16694 fprintf (asm_out_file, "\t.long\t");
16695 assemble_name (asm_out_file, buf);
16696 fprintf (asm_out_file, "\n\t.previous\n");
16697 recurse = 0;
16698 return true;
16700 /* Remove initial .'s to turn a -mcall-aixdesc function
16701 address into the address of the descriptor, not the function
16702 itself. */
16703 else if (GET_CODE (x) == SYMBOL_REF
16704 && XSTR (x, 0)[0] == '.'
16705 && DEFAULT_ABI == ABI_AIX)
16707 const char *name = XSTR (x, 0);
16708 while (*name == '.')
16709 name++;
16711 fprintf (asm_out_file, "\t.long\t%s\n", name);
16712 return true;
16715 #endif /* RELOCATABLE_NEEDS_FIXUP */
16716 return default_assemble_integer (x, size, aligned_p);
16719 #ifdef HAVE_GAS_HIDDEN
16720 /* Emit an assembler directive to set symbol visibility for DECL to
16721 VISIBILITY_TYPE. */
16723 static void
16724 rs6000_assemble_visibility (tree decl, int vis)
16726 /* Functions need to have their entry point symbol visibility set as
16727 well as their descriptor symbol visibility. */
16728 if (DEFAULT_ABI == ABI_AIX
16729 && DOT_SYMBOLS
16730 && TREE_CODE (decl) == FUNCTION_DECL)
16732 static const char * const visibility_types[] = {
16733 NULL, "internal", "hidden", "protected"
16736 const char *name, *type;
16738 name = ((* targetm.strip_name_encoding)
16739 (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))));
16740 type = visibility_types[vis];
16742 fprintf (asm_out_file, "\t.%s\t%s\n", type, name);
16743 fprintf (asm_out_file, "\t.%s\t.%s\n", type, name);
16745 else
16746 default_assemble_visibility (decl, vis);
16748 #endif
16750 enum rtx_code
16751 rs6000_reverse_condition (enum machine_mode mode, enum rtx_code code)
16753 /* Reversal of FP compares takes care -- an ordered compare
16754 becomes an unordered compare and vice versa. */
16755 if (mode == CCFPmode
16756 && (!flag_finite_math_only
16757 || code == UNLT || code == UNLE || code == UNGT || code == UNGE
16758 || code == UNEQ || code == LTGT))
16759 return reverse_condition_maybe_unordered (code);
16760 else
16761 return reverse_condition (code);
16764 /* Generate a compare for CODE. Return a brand-new rtx that
16765 represents the result of the compare. */
16767 static rtx
16768 rs6000_generate_compare (rtx cmp, enum machine_mode mode)
16770 enum machine_mode comp_mode;
16771 rtx compare_result;
16772 enum rtx_code code = GET_CODE (cmp);
16773 rtx op0 = XEXP (cmp, 0);
16774 rtx op1 = XEXP (cmp, 1);
16776 if (FLOAT_MODE_P (mode))
16777 comp_mode = CCFPmode;
16778 else if (code == GTU || code == LTU
16779 || code == GEU || code == LEU)
16780 comp_mode = CCUNSmode;
16781 else if ((code == EQ || code == NE)
16782 && GET_CODE (op0) == SUBREG
16783 && GET_CODE (op1) == SUBREG
16784 && SUBREG_PROMOTED_UNSIGNED_P (op0)
16785 && SUBREG_PROMOTED_UNSIGNED_P (op1))
16786 /* These are unsigned values, perhaps there will be a later
16787 ordering compare that can be shared with this one.
16788 Unfortunately we cannot detect the signedness of the operands
16789 for non-subregs. */
16790 comp_mode = CCUNSmode;
16791 else
16792 comp_mode = CCmode;
16794 /* First, the compare. */
16795 compare_result = gen_reg_rtx (comp_mode);
16797 /* E500 FP compare instructions on the GPRs. Yuck! */
16798 if ((!TARGET_FPRS && TARGET_HARD_FLOAT)
16799 && FLOAT_MODE_P (mode))
16801 rtx cmp, or_result, compare_result2;
16802 enum machine_mode op_mode = GET_MODE (op0);
16804 if (op_mode == VOIDmode)
16805 op_mode = GET_MODE (op1);
16807 /* The E500 FP compare instructions toggle the GT bit (CR bit 1) only.
16808 This explains the following mess. */
16810 switch (code)
16812 case EQ: case UNEQ: case NE: case LTGT:
16813 switch (op_mode)
16815 case SFmode:
16816 cmp = (flag_finite_math_only && !flag_trapping_math)
16817 ? gen_tstsfeq_gpr (compare_result, op0, op1)
16818 : gen_cmpsfeq_gpr (compare_result, op0, op1);
16819 break;
16821 case DFmode:
16822 cmp = (flag_finite_math_only && !flag_trapping_math)
16823 ? gen_tstdfeq_gpr (compare_result, op0, op1)
16824 : gen_cmpdfeq_gpr (compare_result, op0, op1);
16825 break;
16827 case TFmode:
16828 cmp = (flag_finite_math_only && !flag_trapping_math)
16829 ? gen_tsttfeq_gpr (compare_result, op0, op1)
16830 : gen_cmptfeq_gpr (compare_result, op0, op1);
16831 break;
16833 default:
16834 gcc_unreachable ();
16836 break;
16838 case GT: case GTU: case UNGT: case UNGE: case GE: case GEU:
16839 switch (op_mode)
16841 case SFmode:
16842 cmp = (flag_finite_math_only && !flag_trapping_math)
16843 ? gen_tstsfgt_gpr (compare_result, op0, op1)
16844 : gen_cmpsfgt_gpr (compare_result, op0, op1);
16845 break;
16847 case DFmode:
16848 cmp = (flag_finite_math_only && !flag_trapping_math)
16849 ? gen_tstdfgt_gpr (compare_result, op0, op1)
16850 : gen_cmpdfgt_gpr (compare_result, op0, op1);
16851 break;
16853 case TFmode:
16854 cmp = (flag_finite_math_only && !flag_trapping_math)
16855 ? gen_tsttfgt_gpr (compare_result, op0, op1)
16856 : gen_cmptfgt_gpr (compare_result, op0, op1);
16857 break;
16859 default:
16860 gcc_unreachable ();
16862 break;
16864 case LT: case LTU: case UNLT: case UNLE: case LE: case LEU:
16865 switch (op_mode)
16867 case SFmode:
16868 cmp = (flag_finite_math_only && !flag_trapping_math)
16869 ? gen_tstsflt_gpr (compare_result, op0, op1)
16870 : gen_cmpsflt_gpr (compare_result, op0, op1);
16871 break;
16873 case DFmode:
16874 cmp = (flag_finite_math_only && !flag_trapping_math)
16875 ? gen_tstdflt_gpr (compare_result, op0, op1)
16876 : gen_cmpdflt_gpr (compare_result, op0, op1);
16877 break;
16879 case TFmode:
16880 cmp = (flag_finite_math_only && !flag_trapping_math)
16881 ? gen_tsttflt_gpr (compare_result, op0, op1)
16882 : gen_cmptflt_gpr (compare_result, op0, op1);
16883 break;
16885 default:
16886 gcc_unreachable ();
16888 break;
16889 default:
16890 gcc_unreachable ();
16893 /* Synthesize LE and GE from LT/GT || EQ. */
16894 if (code == LE || code == GE || code == LEU || code == GEU)
16896 emit_insn (cmp);
16898 switch (code)
16900 case LE: code = LT; break;
16901 case GE: code = GT; break;
16902 case LEU: code = LT; break;
16903 case GEU: code = GT; break;
16904 default: gcc_unreachable ();
16907 compare_result2 = gen_reg_rtx (CCFPmode);
16909 /* Do the EQ. */
16910 switch (op_mode)
16912 case SFmode:
16913 cmp = (flag_finite_math_only && !flag_trapping_math)
16914 ? gen_tstsfeq_gpr (compare_result2, op0, op1)
16915 : gen_cmpsfeq_gpr (compare_result2, op0, op1);
16916 break;
16918 case DFmode:
16919 cmp = (flag_finite_math_only && !flag_trapping_math)
16920 ? gen_tstdfeq_gpr (compare_result2, op0, op1)
16921 : gen_cmpdfeq_gpr (compare_result2, op0, op1);
16922 break;
16924 case TFmode:
16925 cmp = (flag_finite_math_only && !flag_trapping_math)
16926 ? gen_tsttfeq_gpr (compare_result2, op0, op1)
16927 : gen_cmptfeq_gpr (compare_result2, op0, op1);
16928 break;
16930 default:
16931 gcc_unreachable ();
16933 emit_insn (cmp);
16935 /* OR them together. */
16936 or_result = gen_reg_rtx (CCFPmode);
16937 cmp = gen_e500_cr_ior_compare (or_result, compare_result,
16938 compare_result2);
16939 compare_result = or_result;
16940 code = EQ;
16942 else
16944 if (code == NE || code == LTGT)
16945 code = NE;
16946 else
16947 code = EQ;
16950 emit_insn (cmp);
16952 else
16954 /* Generate XLC-compatible TFmode compare as PARALLEL with extra
16955 CLOBBERs to match cmptf_internal2 pattern. */
16956 if (comp_mode == CCFPmode && TARGET_XL_COMPAT
16957 && GET_MODE (op0) == TFmode
16958 && !TARGET_IEEEQUAD
16959 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128)
16960 emit_insn (gen_rtx_PARALLEL (VOIDmode,
16961 gen_rtvec (10,
16962 gen_rtx_SET (VOIDmode,
16963 compare_result,
16964 gen_rtx_COMPARE (comp_mode, op0, op1)),
16965 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16966 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16967 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16968 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16969 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16970 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16971 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16972 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16973 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (Pmode)))));
16974 else if (GET_CODE (op1) == UNSPEC
16975 && XINT (op1, 1) == UNSPEC_SP_TEST)
16977 rtx op1b = XVECEXP (op1, 0, 0);
16978 comp_mode = CCEQmode;
16979 compare_result = gen_reg_rtx (CCEQmode);
16980 if (TARGET_64BIT)
16981 emit_insn (gen_stack_protect_testdi (compare_result, op0, op1b));
16982 else
16983 emit_insn (gen_stack_protect_testsi (compare_result, op0, op1b));
16985 else
16986 emit_insn (gen_rtx_SET (VOIDmode, compare_result,
16987 gen_rtx_COMPARE (comp_mode, op0, op1)));
16990 /* Some kinds of FP comparisons need an OR operation;
16991 under flag_finite_math_only we don't bother. */
16992 if (FLOAT_MODE_P (mode)
16993 && !flag_finite_math_only
16994 && !(TARGET_HARD_FLOAT && !TARGET_FPRS)
16995 && (code == LE || code == GE
16996 || code == UNEQ || code == LTGT
16997 || code == UNGT || code == UNLT))
16999 enum rtx_code or1, or2;
17000 rtx or1_rtx, or2_rtx, compare2_rtx;
17001 rtx or_result = gen_reg_rtx (CCEQmode);
17003 switch (code)
17005 case LE: or1 = LT; or2 = EQ; break;
17006 case GE: or1 = GT; or2 = EQ; break;
17007 case UNEQ: or1 = UNORDERED; or2 = EQ; break;
17008 case LTGT: or1 = LT; or2 = GT; break;
17009 case UNGT: or1 = UNORDERED; or2 = GT; break;
17010 case UNLT: or1 = UNORDERED; or2 = LT; break;
17011 default: gcc_unreachable ();
17013 validate_condition_mode (or1, comp_mode);
17014 validate_condition_mode (or2, comp_mode);
17015 or1_rtx = gen_rtx_fmt_ee (or1, SImode, compare_result, const0_rtx);
17016 or2_rtx = gen_rtx_fmt_ee (or2, SImode, compare_result, const0_rtx);
17017 compare2_rtx = gen_rtx_COMPARE (CCEQmode,
17018 gen_rtx_IOR (SImode, or1_rtx, or2_rtx),
17019 const_true_rtx);
17020 emit_insn (gen_rtx_SET (VOIDmode, or_result, compare2_rtx));
17022 compare_result = or_result;
17023 code = EQ;
17026 validate_condition_mode (code, GET_MODE (compare_result));
17028 return gen_rtx_fmt_ee (code, VOIDmode, compare_result, const0_rtx);
17032 /* Emit the RTL for an sISEL pattern. */
17034 void
17035 rs6000_emit_sISEL (enum machine_mode mode ATTRIBUTE_UNUSED, rtx operands[])
17037 rs6000_emit_int_cmove (operands[0], operands[1], const1_rtx, const0_rtx);
17040 void
17041 rs6000_emit_sCOND (enum machine_mode mode, rtx operands[])
17043 rtx condition_rtx;
17044 enum machine_mode op_mode;
17045 enum rtx_code cond_code;
17046 rtx result = operands[0];
17048 if (TARGET_ISEL && (mode == SImode || mode == DImode))
17050 rs6000_emit_sISEL (mode, operands);
17051 return;
17054 condition_rtx = rs6000_generate_compare (operands[1], mode);
17055 cond_code = GET_CODE (condition_rtx);
17057 if (FLOAT_MODE_P (mode)
17058 && !TARGET_FPRS && TARGET_HARD_FLOAT)
17060 rtx t;
17062 PUT_MODE (condition_rtx, SImode);
17063 t = XEXP (condition_rtx, 0);
17065 gcc_assert (cond_code == NE || cond_code == EQ);
17067 if (cond_code == NE)
17068 emit_insn (gen_e500_flip_gt_bit (t, t));
17070 emit_insn (gen_move_from_CR_gt_bit (result, t));
17071 return;
17074 if (cond_code == NE
17075 || cond_code == GE || cond_code == LE
17076 || cond_code == GEU || cond_code == LEU
17077 || cond_code == ORDERED || cond_code == UNGE || cond_code == UNLE)
17079 rtx not_result = gen_reg_rtx (CCEQmode);
17080 rtx not_op, rev_cond_rtx;
17081 enum machine_mode cc_mode;
17083 cc_mode = GET_MODE (XEXP (condition_rtx, 0));
17085 rev_cond_rtx = gen_rtx_fmt_ee (rs6000_reverse_condition (cc_mode, cond_code),
17086 SImode, XEXP (condition_rtx, 0), const0_rtx);
17087 not_op = gen_rtx_COMPARE (CCEQmode, rev_cond_rtx, const0_rtx);
17088 emit_insn (gen_rtx_SET (VOIDmode, not_result, not_op));
17089 condition_rtx = gen_rtx_EQ (VOIDmode, not_result, const0_rtx);
17092 op_mode = GET_MODE (XEXP (operands[1], 0));
17093 if (op_mode == VOIDmode)
17094 op_mode = GET_MODE (XEXP (operands[1], 1));
17096 if (TARGET_POWERPC64 && (op_mode == DImode || FLOAT_MODE_P (mode)))
17098 PUT_MODE (condition_rtx, DImode);
17099 convert_move (result, condition_rtx, 0);
17101 else
17103 PUT_MODE (condition_rtx, SImode);
17104 emit_insn (gen_rtx_SET (VOIDmode, result, condition_rtx));
17108 /* Emit a branch of kind CODE to location LOC. */
17110 void
17111 rs6000_emit_cbranch (enum machine_mode mode, rtx operands[])
17113 rtx condition_rtx, loc_ref;
17115 condition_rtx = rs6000_generate_compare (operands[0], mode);
17116 loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands[3]);
17117 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
17118 gen_rtx_IF_THEN_ELSE (VOIDmode, condition_rtx,
17119 loc_ref, pc_rtx)));
17122 /* Return the string to output a conditional branch to LABEL, which is
17123 the operand number of the label, or -1 if the branch is really a
17124 conditional return.
17126 OP is the conditional expression. XEXP (OP, 0) is assumed to be a
17127 condition code register and its mode specifies what kind of
17128 comparison we made.
17130 REVERSED is nonzero if we should reverse the sense of the comparison.
17132 INSN is the insn. */
17134 char *
17135 output_cbranch (rtx op, const char *label, int reversed, rtx insn)
17137 static char string[64];
17138 enum rtx_code code = GET_CODE (op);
17139 rtx cc_reg = XEXP (op, 0);
17140 enum machine_mode mode = GET_MODE (cc_reg);
17141 int cc_regno = REGNO (cc_reg) - CR0_REGNO;
17142 int need_longbranch = label != NULL && get_attr_length (insn) == 8;
17143 int really_reversed = reversed ^ need_longbranch;
17144 char *s = string;
17145 const char *ccode;
17146 const char *pred;
17147 rtx note;
17149 validate_condition_mode (code, mode);
17151 /* Work out which way this really branches. We could use
17152 reverse_condition_maybe_unordered here always but this
17153 makes the resulting assembler clearer. */
17154 if (really_reversed)
17156 /* Reversal of FP compares takes care -- an ordered compare
17157 becomes an unordered compare and vice versa. */
17158 if (mode == CCFPmode)
17159 code = reverse_condition_maybe_unordered (code);
17160 else
17161 code = reverse_condition (code);
17164 if ((!TARGET_FPRS && TARGET_HARD_FLOAT) && mode == CCFPmode)
17166 /* The efscmp/tst* instructions twiddle bit 2, which maps nicely
17167 to the GT bit. */
17168 switch (code)
17170 case EQ:
17171 /* Opposite of GT. */
17172 code = GT;
17173 break;
17175 case NE:
17176 code = UNLE;
17177 break;
17179 default:
17180 gcc_unreachable ();
17184 switch (code)
17186 /* Not all of these are actually distinct opcodes, but
17187 we distinguish them for clarity of the resulting assembler. */
17188 case NE: case LTGT:
17189 ccode = "ne"; break;
17190 case EQ: case UNEQ:
17191 ccode = "eq"; break;
17192 case GE: case GEU:
17193 ccode = "ge"; break;
17194 case GT: case GTU: case UNGT:
17195 ccode = "gt"; break;
17196 case LE: case LEU:
17197 ccode = "le"; break;
17198 case LT: case LTU: case UNLT:
17199 ccode = "lt"; break;
17200 case UNORDERED: ccode = "un"; break;
17201 case ORDERED: ccode = "nu"; break;
17202 case UNGE: ccode = "nl"; break;
17203 case UNLE: ccode = "ng"; break;
17204 default:
17205 gcc_unreachable ();
17208 /* Maybe we have a guess as to how likely the branch is.
17209 The old mnemonics don't have a way to specify this information. */
17210 pred = "";
17211 note = find_reg_note (insn, REG_BR_PROB, NULL_RTX);
17212 if (note != NULL_RTX)
17214 /* PROB is the difference from 50%. */
17215 int prob = INTVAL (XEXP (note, 0)) - REG_BR_PROB_BASE / 2;
17217 /* Only hint for highly probable/improbable branches on newer
17218 cpus as static prediction overrides processor dynamic
17219 prediction. For older cpus we may as well always hint, but
17220 assume not taken for branches that are very close to 50% as a
17221 mispredicted taken branch is more expensive than a
17222 mispredicted not-taken branch. */
17223 if (rs6000_always_hint
17224 || (abs (prob) > REG_BR_PROB_BASE / 100 * 48
17225 && br_prob_note_reliable_p (note)))
17227 if (abs (prob) > REG_BR_PROB_BASE / 20
17228 && ((prob > 0) ^ need_longbranch))
17229 pred = "+";
17230 else
17231 pred = "-";
17235 if (label == NULL)
17236 s += sprintf (s, "{b%sr|b%slr%s} ", ccode, ccode, pred);
17237 else
17238 s += sprintf (s, "{b%s|b%s%s} ", ccode, ccode, pred);
17240 /* We need to escape any '%' characters in the reg_names string.
17241 Assume they'd only be the first character.... */
17242 if (reg_names[cc_regno + CR0_REGNO][0] == '%')
17243 *s++ = '%';
17244 s += sprintf (s, "%s", reg_names[cc_regno + CR0_REGNO]);
17246 if (label != NULL)
17248 /* If the branch distance was too far, we may have to use an
17249 unconditional branch to go the distance. */
17250 if (need_longbranch)
17251 s += sprintf (s, ",$+8\n\tb %s", label);
17252 else
17253 s += sprintf (s, ",%s", label);
17256 return string;
17259 /* Return the string to flip the GT bit on a CR. */
17260 char *
17261 output_e500_flip_gt_bit (rtx dst, rtx src)
17263 static char string[64];
17264 int a, b;
17266 gcc_assert (GET_CODE (dst) == REG && CR_REGNO_P (REGNO (dst))
17267 && GET_CODE (src) == REG && CR_REGNO_P (REGNO (src)));
17269 /* GT bit. */
17270 a = 4 * (REGNO (dst) - CR0_REGNO) + 1;
17271 b = 4 * (REGNO (src) - CR0_REGNO) + 1;
17273 sprintf (string, "crnot %d,%d", a, b);
17274 return string;
17277 /* Return insn for VSX or Altivec comparisons. */
17279 static rtx
17280 rs6000_emit_vector_compare_inner (enum rtx_code code, rtx op0, rtx op1)
17282 rtx mask;
17283 enum machine_mode mode = GET_MODE (op0);
17285 switch (code)
17287 default:
17288 break;
17290 case GE:
17291 if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
17292 return NULL_RTX;
17294 case EQ:
17295 case GT:
17296 case GTU:
17297 mask = gen_reg_rtx (mode);
17298 emit_insn (gen_rtx_SET (VOIDmode,
17299 mask,
17300 gen_rtx_fmt_ee (code, mode, op0, op1)));
17301 return mask;
17304 return NULL_RTX;
17307 /* Emit vector compare for operands OP0 and OP1 using code RCODE.
17308 DMODE is expected destination mode. This is a recursive function. */
17310 static rtx
17311 rs6000_emit_vector_compare (enum rtx_code rcode,
17312 rtx op0, rtx op1,
17313 enum machine_mode dmode)
17315 rtx mask;
17316 bool swap_operands = false;
17317 bool try_again = false;
17319 gcc_assert (VECTOR_UNIT_ALTIVEC_OR_VSX_P (dmode));
17320 gcc_assert (GET_MODE (op0) == GET_MODE (op1));
17322 /* See if the comparison works as is. */
17323 mask = rs6000_emit_vector_compare_inner (rcode, op0, op1);
17324 if (mask)
17325 return mask;
17327 switch (rcode)
17329 case LT:
17330 rcode = GT;
17331 swap_operands = true;
17332 try_again = true;
17333 break;
17334 case LTU:
17335 rcode = GTU;
17336 swap_operands = true;
17337 try_again = true;
17338 break;
17339 case NE:
17340 case UNLE:
17341 case UNLT:
17342 case UNGE:
17343 case UNGT:
17344 /* Invert condition and try again.
17345 e.g., A != B becomes ~(A==B). */
17347 enum rtx_code rev_code;
17348 enum insn_code nor_code;
17349 rtx mask2;
17351 rev_code = reverse_condition_maybe_unordered (rcode);
17352 if (rev_code == UNKNOWN)
17353 return NULL_RTX;
17355 nor_code = optab_handler (one_cmpl_optab, dmode);
17356 if (nor_code == CODE_FOR_nothing)
17357 return NULL_RTX;
17359 mask2 = rs6000_emit_vector_compare (rev_code, op0, op1, dmode);
17360 if (!mask2)
17361 return NULL_RTX;
17363 mask = gen_reg_rtx (dmode);
17364 emit_insn (GEN_FCN (nor_code) (mask, mask2));
17365 return mask;
17367 break;
17368 case GE:
17369 case GEU:
17370 case LE:
17371 case LEU:
17372 /* Try GT/GTU/LT/LTU OR EQ */
17374 rtx c_rtx, eq_rtx;
17375 enum insn_code ior_code;
17376 enum rtx_code new_code;
17378 switch (rcode)
17380 case GE:
17381 new_code = GT;
17382 break;
17384 case GEU:
17385 new_code = GTU;
17386 break;
17388 case LE:
17389 new_code = LT;
17390 break;
17392 case LEU:
17393 new_code = LTU;
17394 break;
17396 default:
17397 gcc_unreachable ();
17400 ior_code = optab_handler (ior_optab, dmode);
17401 if (ior_code == CODE_FOR_nothing)
17402 return NULL_RTX;
17404 c_rtx = rs6000_emit_vector_compare (new_code, op0, op1, dmode);
17405 if (!c_rtx)
17406 return NULL_RTX;
17408 eq_rtx = rs6000_emit_vector_compare (EQ, op0, op1, dmode);
17409 if (!eq_rtx)
17410 return NULL_RTX;
17412 mask = gen_reg_rtx (dmode);
17413 emit_insn (GEN_FCN (ior_code) (mask, c_rtx, eq_rtx));
17414 return mask;
17416 break;
17417 default:
17418 return NULL_RTX;
17421 if (try_again)
17423 if (swap_operands)
17425 rtx tmp;
17426 tmp = op0;
17427 op0 = op1;
17428 op1 = tmp;
17431 mask = rs6000_emit_vector_compare_inner (rcode, op0, op1);
17432 if (mask)
17433 return mask;
17436 /* You only get two chances. */
17437 return NULL_RTX;
17440 /* Emit vector conditional expression. DEST is destination. OP_TRUE and
17441 OP_FALSE are two VEC_COND_EXPR operands. CC_OP0 and CC_OP1 are the two
17442 operands for the relation operation COND. */
17445 rs6000_emit_vector_cond_expr (rtx dest, rtx op_true, rtx op_false,
17446 rtx cond, rtx cc_op0, rtx cc_op1)
17448 enum machine_mode dest_mode = GET_MODE (dest);
17449 enum rtx_code rcode = GET_CODE (cond);
17450 enum machine_mode cc_mode = CCmode;
17451 rtx mask;
17452 rtx cond2;
17453 rtx tmp;
17454 bool invert_move = false;
17456 if (VECTOR_UNIT_NONE_P (dest_mode))
17457 return 0;
17459 switch (rcode)
17461 /* Swap operands if we can, and fall back to doing the operation as
17462 specified, and doing a NOR to invert the test. */
17463 case NE:
17464 case UNLE:
17465 case UNLT:
17466 case UNGE:
17467 case UNGT:
17468 /* Invert condition and try again.
17469 e.g., A = (B != C) ? D : E becomes A = (B == C) ? E : D. */
17470 invert_move = true;
17471 rcode = reverse_condition_maybe_unordered (rcode);
17472 if (rcode == UNKNOWN)
17473 return 0;
17474 break;
17476 /* Mark unsigned tests with CCUNSmode. */
17477 case GTU:
17478 case GEU:
17479 case LTU:
17480 case LEU:
17481 cc_mode = CCUNSmode;
17482 break;
17484 default:
17485 break;
17488 /* Get the vector mask for the given relational operations. */
17489 mask = rs6000_emit_vector_compare (rcode, cc_op0, cc_op1, dest_mode);
17491 if (!mask)
17492 return 0;
17494 if (invert_move)
17496 tmp = op_true;
17497 op_true = op_false;
17498 op_false = tmp;
17501 cond2 = gen_rtx_fmt_ee (NE, cc_mode, mask, const0_rtx);
17502 emit_insn (gen_rtx_SET (VOIDmode,
17503 dest,
17504 gen_rtx_IF_THEN_ELSE (dest_mode,
17505 cond2,
17506 op_true,
17507 op_false)));
17508 return 1;
17511 /* Emit a conditional move: move TRUE_COND to DEST if OP of the
17512 operands of the last comparison is nonzero/true, FALSE_COND if it
17513 is zero/false. Return 0 if the hardware has no such operation. */
17516 rs6000_emit_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
17518 enum rtx_code code = GET_CODE (op);
17519 rtx op0 = XEXP (op, 0);
17520 rtx op1 = XEXP (op, 1);
17521 REAL_VALUE_TYPE c1;
17522 enum machine_mode compare_mode = GET_MODE (op0);
17523 enum machine_mode result_mode = GET_MODE (dest);
17524 rtx temp;
17525 bool is_against_zero;
17527 /* These modes should always match. */
17528 if (GET_MODE (op1) != compare_mode
17529 /* In the isel case however, we can use a compare immediate, so
17530 op1 may be a small constant. */
17531 && (!TARGET_ISEL || !short_cint_operand (op1, VOIDmode)))
17532 return 0;
17533 if (GET_MODE (true_cond) != result_mode)
17534 return 0;
17535 if (GET_MODE (false_cond) != result_mode)
17536 return 0;
17538 /* First, work out if the hardware can do this at all, or
17539 if it's too slow.... */
17540 if (!FLOAT_MODE_P (compare_mode))
17542 if (TARGET_ISEL)
17543 return rs6000_emit_int_cmove (dest, op, true_cond, false_cond);
17544 return 0;
17546 else if (TARGET_HARD_FLOAT && !TARGET_FPRS
17547 && SCALAR_FLOAT_MODE_P (compare_mode))
17548 return 0;
17550 is_against_zero = op1 == CONST0_RTX (compare_mode);
17552 /* A floating-point subtract might overflow, underflow, or produce
17553 an inexact result, thus changing the floating-point flags, so it
17554 can't be generated if we care about that. It's safe if one side
17555 of the construct is zero, since then no subtract will be
17556 generated. */
17557 if (SCALAR_FLOAT_MODE_P (compare_mode)
17558 && flag_trapping_math && ! is_against_zero)
17559 return 0;
17561 /* Eliminate half of the comparisons by switching operands, this
17562 makes the remaining code simpler. */
17563 if (code == UNLT || code == UNGT || code == UNORDERED || code == NE
17564 || code == LTGT || code == LT || code == UNLE)
17566 code = reverse_condition_maybe_unordered (code);
17567 temp = true_cond;
17568 true_cond = false_cond;
17569 false_cond = temp;
17572 /* UNEQ and LTGT take four instructions for a comparison with zero,
17573 it'll probably be faster to use a branch here too. */
17574 if (code == UNEQ && HONOR_NANS (compare_mode))
17575 return 0;
17577 if (GET_CODE (op1) == CONST_DOUBLE)
17578 REAL_VALUE_FROM_CONST_DOUBLE (c1, op1);
17580 /* We're going to try to implement comparisons by performing
17581 a subtract, then comparing against zero. Unfortunately,
17582 Inf - Inf is NaN which is not zero, and so if we don't
17583 know that the operand is finite and the comparison
17584 would treat EQ different to UNORDERED, we can't do it. */
17585 if (HONOR_INFINITIES (compare_mode)
17586 && code != GT && code != UNGE
17587 && (GET_CODE (op1) != CONST_DOUBLE || real_isinf (&c1))
17588 /* Constructs of the form (a OP b ? a : b) are safe. */
17589 && ((! rtx_equal_p (op0, false_cond) && ! rtx_equal_p (op1, false_cond))
17590 || (! rtx_equal_p (op0, true_cond)
17591 && ! rtx_equal_p (op1, true_cond))))
17592 return 0;
17594 /* At this point we know we can use fsel. */
17596 /* Reduce the comparison to a comparison against zero. */
17597 if (! is_against_zero)
17599 temp = gen_reg_rtx (compare_mode);
17600 emit_insn (gen_rtx_SET (VOIDmode, temp,
17601 gen_rtx_MINUS (compare_mode, op0, op1)));
17602 op0 = temp;
17603 op1 = CONST0_RTX (compare_mode);
17606 /* If we don't care about NaNs we can reduce some of the comparisons
17607 down to faster ones. */
17608 if (! HONOR_NANS (compare_mode))
17609 switch (code)
17611 case GT:
17612 code = LE;
17613 temp = true_cond;
17614 true_cond = false_cond;
17615 false_cond = temp;
17616 break;
17617 case UNGE:
17618 code = GE;
17619 break;
17620 case UNEQ:
17621 code = EQ;
17622 break;
17623 default:
17624 break;
17627 /* Now, reduce everything down to a GE. */
17628 switch (code)
17630 case GE:
17631 break;
17633 case LE:
17634 temp = gen_reg_rtx (compare_mode);
17635 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
17636 op0 = temp;
17637 break;
17639 case ORDERED:
17640 temp = gen_reg_rtx (compare_mode);
17641 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_ABS (compare_mode, op0)));
17642 op0 = temp;
17643 break;
17645 case EQ:
17646 temp = gen_reg_rtx (compare_mode);
17647 emit_insn (gen_rtx_SET (VOIDmode, temp,
17648 gen_rtx_NEG (compare_mode,
17649 gen_rtx_ABS (compare_mode, op0))));
17650 op0 = temp;
17651 break;
17653 case UNGE:
17654 /* a UNGE 0 <-> (a GE 0 || -a UNLT 0) */
17655 temp = gen_reg_rtx (result_mode);
17656 emit_insn (gen_rtx_SET (VOIDmode, temp,
17657 gen_rtx_IF_THEN_ELSE (result_mode,
17658 gen_rtx_GE (VOIDmode,
17659 op0, op1),
17660 true_cond, false_cond)));
17661 false_cond = true_cond;
17662 true_cond = temp;
17664 temp = gen_reg_rtx (compare_mode);
17665 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
17666 op0 = temp;
17667 break;
17669 case GT:
17670 /* a GT 0 <-> (a GE 0 && -a UNLT 0) */
17671 temp = gen_reg_rtx (result_mode);
17672 emit_insn (gen_rtx_SET (VOIDmode, temp,
17673 gen_rtx_IF_THEN_ELSE (result_mode,
17674 gen_rtx_GE (VOIDmode,
17675 op0, op1),
17676 true_cond, false_cond)));
17677 true_cond = false_cond;
17678 false_cond = temp;
17680 temp = gen_reg_rtx (compare_mode);
17681 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
17682 op0 = temp;
17683 break;
17685 default:
17686 gcc_unreachable ();
17689 emit_insn (gen_rtx_SET (VOIDmode, dest,
17690 gen_rtx_IF_THEN_ELSE (result_mode,
17691 gen_rtx_GE (VOIDmode,
17692 op0, op1),
17693 true_cond, false_cond)));
17694 return 1;
17697 /* Same as above, but for ints (isel). */
17699 static int
17700 rs6000_emit_int_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
17702 rtx condition_rtx, cr;
17703 enum machine_mode mode = GET_MODE (dest);
17704 enum rtx_code cond_code;
17705 rtx (*isel_func) (rtx, rtx, rtx, rtx, rtx);
17706 bool signedp;
17708 if (mode != SImode && (!TARGET_POWERPC64 || mode != DImode))
17709 return 0;
17711 /* We still have to do the compare, because isel doesn't do a
17712 compare, it just looks at the CRx bits set by a previous compare
17713 instruction. */
17714 condition_rtx = rs6000_generate_compare (op, mode);
17715 cond_code = GET_CODE (condition_rtx);
17716 cr = XEXP (condition_rtx, 0);
17717 signedp = GET_MODE (cr) == CCmode;
17719 isel_func = (mode == SImode
17720 ? (signedp ? gen_isel_signed_si : gen_isel_unsigned_si)
17721 : (signedp ? gen_isel_signed_di : gen_isel_unsigned_di));
17723 switch (cond_code)
17725 case LT: case GT: case LTU: case GTU: case EQ:
17726 /* isel handles these directly. */
17727 break;
17729 default:
17730 /* We need to swap the sense of the comparison. */
17732 rtx t = true_cond;
17733 true_cond = false_cond;
17734 false_cond = t;
17735 PUT_CODE (condition_rtx, reverse_condition (cond_code));
17737 break;
17740 false_cond = force_reg (mode, false_cond);
17741 if (true_cond != const0_rtx)
17742 true_cond = force_reg (mode, true_cond);
17744 emit_insn (isel_func (dest, condition_rtx, true_cond, false_cond, cr));
17746 return 1;
17749 const char *
17750 output_isel (rtx *operands)
17752 enum rtx_code code;
17754 code = GET_CODE (operands[1]);
17756 if (code == GE || code == GEU || code == LE || code == LEU || code == NE)
17758 gcc_assert (GET_CODE (operands[2]) == REG
17759 && GET_CODE (operands[3]) == REG);
17760 PUT_CODE (operands[1], reverse_condition (code));
17761 return "isel %0,%3,%2,%j1";
17764 return "isel %0,%2,%3,%j1";
17767 void
17768 rs6000_emit_minmax (rtx dest, enum rtx_code code, rtx op0, rtx op1)
17770 enum machine_mode mode = GET_MODE (op0);
17771 enum rtx_code c;
17772 rtx target;
17774 /* VSX/altivec have direct min/max insns. */
17775 if ((code == SMAX || code == SMIN)
17776 && (VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode)
17777 || (mode == SFmode && VECTOR_UNIT_VSX_P (DFmode))))
17779 emit_insn (gen_rtx_SET (VOIDmode,
17780 dest,
17781 gen_rtx_fmt_ee (code, mode, op0, op1)));
17782 return;
17785 if (code == SMAX || code == SMIN)
17786 c = GE;
17787 else
17788 c = GEU;
17790 if (code == SMAX || code == UMAX)
17791 target = emit_conditional_move (dest, c, op0, op1, mode,
17792 op0, op1, mode, 0);
17793 else
17794 target = emit_conditional_move (dest, c, op0, op1, mode,
17795 op1, op0, mode, 0);
17796 gcc_assert (target);
17797 if (target != dest)
17798 emit_move_insn (dest, target);
17801 /* Emit instructions to perform a load-reserved/store-conditional operation.
17802 The operation performed is an atomic
17803 (set M (CODE:MODE M OP))
17804 If not NULL, BEFORE is atomically set to M before the operation, and
17805 AFTER is set to M after the operation (that is, (CODE:MODE M OP)).
17806 If SYNC_P then a memory barrier is emitted before the operation.
17807 Either OP or M may be wrapped in a NOT operation. */
17809 void
17810 rs6000_emit_sync (enum rtx_code code, enum machine_mode mode,
17811 rtx m, rtx op, rtx before_param, rtx after_param,
17812 bool sync_p)
17814 enum machine_mode used_mode;
17815 rtx the_op, set_before, set_after, set_atomic, cc_scratch, before, after;
17816 rtx used_m;
17817 rtvec vec;
17818 HOST_WIDE_INT imask = GET_MODE_MASK (mode);
17819 rtx shift = NULL_RTX;
17821 if (sync_p)
17822 emit_insn (gen_lwsync ());
17824 used_m = m;
17826 /* If this is smaller than SImode, we'll have to use SImode with
17827 adjustments. */
17828 if (mode == QImode || mode == HImode)
17830 rtx newop, oldop;
17832 if (MEM_ALIGN (used_m) >= 32)
17834 int ishift = 0;
17835 if (BYTES_BIG_ENDIAN)
17836 ishift = GET_MODE_BITSIZE (SImode) - GET_MODE_BITSIZE (mode);
17838 shift = GEN_INT (ishift);
17839 used_m = change_address (used_m, SImode, 0);
17841 else
17843 rtx addrSI, aligned_addr;
17844 int shift_mask = mode == QImode ? 0x18 : 0x10;
17846 addrSI = gen_lowpart_common (SImode,
17847 force_reg (Pmode, XEXP (used_m, 0)));
17848 addrSI = force_reg (SImode, addrSI);
17849 shift = gen_reg_rtx (SImode);
17851 emit_insn (gen_rlwinm (shift, addrSI, GEN_INT (3),
17852 GEN_INT (shift_mask)));
17853 emit_insn (gen_xorsi3 (shift, shift, GEN_INT (shift_mask)));
17855 aligned_addr = expand_binop (Pmode, and_optab,
17856 XEXP (used_m, 0),
17857 GEN_INT (-4), NULL_RTX,
17858 1, OPTAB_LIB_WIDEN);
17859 used_m = change_address (used_m, SImode, aligned_addr);
17860 set_mem_align (used_m, 32);
17862 /* It's safe to keep the old alias set of USED_M, because
17863 the operation is atomic and only affects the original
17864 USED_M. */
17865 m = used_m;
17867 if (GET_CODE (op) == NOT)
17869 oldop = lowpart_subreg (SImode, XEXP (op, 0), mode);
17870 oldop = gen_rtx_NOT (SImode, oldop);
17872 else
17873 oldop = lowpart_subreg (SImode, op, mode);
17875 switch (code)
17877 case IOR:
17878 case XOR:
17879 newop = expand_binop (SImode, and_optab,
17880 oldop, GEN_INT (imask), NULL_RTX,
17881 1, OPTAB_LIB_WIDEN);
17882 emit_insn (gen_ashlsi3 (newop, newop, shift));
17883 break;
17885 case NOT: /* NAND */
17886 newop = expand_binop (SImode, ior_optab,
17887 oldop, GEN_INT (~imask), NULL_RTX,
17888 1, OPTAB_LIB_WIDEN);
17889 emit_insn (gen_rotlsi3 (newop, newop, shift));
17890 break;
17892 case AND:
17893 newop = expand_binop (SImode, ior_optab,
17894 oldop, GEN_INT (~imask), NULL_RTX,
17895 1, OPTAB_LIB_WIDEN);
17896 emit_insn (gen_rotlsi3 (newop, newop, shift));
17897 break;
17899 case PLUS:
17900 case MINUS:
17902 rtx mask;
17904 newop = expand_binop (SImode, and_optab,
17905 oldop, GEN_INT (imask), NULL_RTX,
17906 1, OPTAB_LIB_WIDEN);
17907 emit_insn (gen_ashlsi3 (newop, newop, shift));
17909 mask = gen_reg_rtx (SImode);
17910 emit_move_insn (mask, GEN_INT (imask));
17911 emit_insn (gen_ashlsi3 (mask, mask, shift));
17913 if (code == PLUS)
17914 newop = gen_rtx_PLUS (SImode, m, newop);
17915 else
17916 newop = gen_rtx_MINUS (SImode, m, newop);
17917 newop = gen_rtx_AND (SImode, newop, mask);
17918 newop = gen_rtx_IOR (SImode, newop,
17919 gen_rtx_AND (SImode,
17920 gen_rtx_NOT (SImode, mask),
17921 m));
17922 break;
17925 default:
17926 gcc_unreachable ();
17929 op = newop;
17930 used_mode = SImode;
17931 before = gen_reg_rtx (used_mode);
17932 after = gen_reg_rtx (used_mode);
17934 else
17936 used_mode = mode;
17937 before = before_param;
17938 after = after_param;
17940 if (before == NULL_RTX)
17941 before = gen_reg_rtx (used_mode);
17942 if (after == NULL_RTX)
17943 after = gen_reg_rtx (used_mode);
17946 if ((code == PLUS || code == MINUS)
17947 && used_mode != mode)
17948 the_op = op; /* Computed above. */
17949 else if (GET_CODE (op) == NOT && GET_CODE (m) != NOT)
17950 the_op = gen_rtx_fmt_ee (code, used_mode, op, m);
17951 else if (code == NOT)
17952 the_op = gen_rtx_fmt_ee (IOR, used_mode,
17953 gen_rtx_NOT (used_mode, m),
17954 gen_rtx_NOT (used_mode, op));
17955 else
17956 the_op = gen_rtx_fmt_ee (code, used_mode, m, op);
17958 set_after = gen_rtx_SET (VOIDmode, after, the_op);
17959 set_before = gen_rtx_SET (VOIDmode, before, used_m);
17960 set_atomic = gen_rtx_SET (VOIDmode, used_m,
17961 gen_rtx_UNSPEC (used_mode,
17962 gen_rtvec (1, the_op),
17963 UNSPEC_SYNC_OP));
17964 cc_scratch = gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (CCmode));
17966 if ((code == PLUS || code == MINUS) && used_mode != mode)
17967 vec = gen_rtvec (5, set_after, set_before, set_atomic, cc_scratch,
17968 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (SImode)));
17969 else
17970 vec = gen_rtvec (4, set_after, set_before, set_atomic, cc_scratch);
17971 emit_insn (gen_rtx_PARALLEL (VOIDmode, vec));
17973 /* Shift and mask the return values properly. */
17974 if (used_mode != mode && before_param)
17976 emit_insn (gen_lshrsi3 (before, before, shift));
17977 convert_move (before_param, before, 1);
17980 if (used_mode != mode && after_param)
17982 emit_insn (gen_lshrsi3 (after, after, shift));
17983 convert_move (after_param, after, 1);
17986 /* The previous sequence will end with a branch that's dependent on
17987 the conditional store, so placing an isync will ensure that no
17988 other instructions (especially, no load or store instructions)
17989 can start before the atomic operation completes. */
17990 if (sync_p)
17991 emit_insn (gen_isync ());
17994 /* A subroutine of the atomic operation splitters. Jump to LABEL if
17995 COND is true. Mark the jump as unlikely to be taken. */
17997 static void
17998 emit_unlikely_jump (rtx cond, rtx label)
18000 rtx very_unlikely = GEN_INT (REG_BR_PROB_BASE / 100 - 1);
18001 rtx x;
18003 x = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, label, pc_rtx);
18004 x = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, x));
18005 add_reg_note (x, REG_BR_PROB, very_unlikely);
18008 /* A subroutine of the atomic operation splitters. Emit a load-locked
18009 instruction in MODE. */
18011 static void
18012 emit_load_locked (enum machine_mode mode, rtx reg, rtx mem)
18014 rtx (*fn) (rtx, rtx) = NULL;
18015 if (mode == SImode)
18016 fn = gen_load_locked_si;
18017 else if (mode == DImode)
18018 fn = gen_load_locked_di;
18019 emit_insn (fn (reg, mem));
18022 /* A subroutine of the atomic operation splitters. Emit a store-conditional
18023 instruction in MODE. */
18025 static void
18026 emit_store_conditional (enum machine_mode mode, rtx res, rtx mem, rtx val)
18028 rtx (*fn) (rtx, rtx, rtx) = NULL;
18029 if (mode == SImode)
18030 fn = gen_store_conditional_si;
18031 else if (mode == DImode)
18032 fn = gen_store_conditional_di;
18034 /* Emit sync before stwcx. to address PPC405 Erratum. */
18035 if (PPC405_ERRATUM77)
18036 emit_insn (gen_memory_barrier ());
18038 emit_insn (fn (res, mem, val));
18041 /* Expand an atomic fetch-and-operate pattern. CODE is the binary operation
18042 to perform. MEM is the memory on which to operate. VAL is the second
18043 operand of the binary operator. BEFORE and AFTER are optional locations to
18044 return the value of MEM either before of after the operation. SCRATCH is
18045 a scratch register. */
18047 void
18048 rs6000_split_atomic_op (enum rtx_code code, rtx mem, rtx val,
18049 rtx before, rtx after, rtx scratch)
18051 enum machine_mode mode = GET_MODE (mem);
18052 rtx label, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
18054 emit_insn (gen_lwsync ());
18056 label = gen_label_rtx ();
18057 emit_label (label);
18058 label = gen_rtx_LABEL_REF (VOIDmode, label);
18060 if (before == NULL_RTX)
18061 before = scratch;
18062 emit_load_locked (mode, before, mem);
18064 if (code == NOT)
18065 x = gen_rtx_IOR (mode,
18066 gen_rtx_NOT (mode, before),
18067 gen_rtx_NOT (mode, val));
18068 else if (code == AND)
18069 x = gen_rtx_UNSPEC (mode, gen_rtvec (2, before, val), UNSPEC_AND);
18070 else
18071 x = gen_rtx_fmt_ee (code, mode, before, val);
18073 if (after != NULL_RTX)
18074 emit_insn (gen_rtx_SET (VOIDmode, after, copy_rtx (x)));
18075 emit_insn (gen_rtx_SET (VOIDmode, scratch, x));
18077 emit_store_conditional (mode, cond, mem, scratch);
18079 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
18080 emit_unlikely_jump (x, label);
18082 emit_insn (gen_isync ());
18085 /* Expand an atomic compare and swap operation. MEM is the memory on which
18086 to operate. OLDVAL is the old value to be compared. NEWVAL is the new
18087 value to be stored. SCRATCH is a scratch GPR. */
18089 void
18090 rs6000_split_compare_and_swap (rtx retval, rtx mem, rtx oldval, rtx newval,
18091 rtx scratch)
18093 enum machine_mode mode = GET_MODE (mem);
18094 rtx label1, label2, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
18096 emit_insn (gen_lwsync ());
18098 label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
18099 label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
18100 emit_label (XEXP (label1, 0));
18102 emit_load_locked (mode, retval, mem);
18104 x = gen_rtx_COMPARE (CCmode, retval, oldval);
18105 emit_insn (gen_rtx_SET (VOIDmode, cond, x));
18107 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
18108 emit_unlikely_jump (x, label2);
18110 emit_move_insn (scratch, newval);
18111 emit_store_conditional (mode, cond, mem, scratch);
18113 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
18114 emit_unlikely_jump (x, label1);
18116 emit_insn (gen_isync ());
18117 emit_label (XEXP (label2, 0));
18120 /* Expand an atomic test and set operation. MEM is the memory on which
18121 to operate. VAL is the value set. SCRATCH is a scratch GPR. */
18123 void
18124 rs6000_split_lock_test_and_set (rtx retval, rtx mem, rtx val, rtx scratch)
18126 enum machine_mode mode = GET_MODE (mem);
18127 rtx label, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
18129 label = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
18130 emit_label (XEXP (label, 0));
18132 emit_load_locked (mode, retval, mem);
18133 emit_move_insn (scratch, val);
18134 emit_store_conditional (mode, cond, mem, scratch);
18136 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
18137 emit_unlikely_jump (x, label);
18139 emit_insn (gen_isync ());
18142 void
18143 rs6000_expand_compare_and_swapqhi (rtx dst, rtx mem, rtx oldval, rtx newval)
18145 enum machine_mode mode = GET_MODE (mem);
18146 rtx addrSI, align, wdst, shift, mask;
18147 HOST_WIDE_INT shift_mask = mode == QImode ? 0x18 : 0x10;
18148 HOST_WIDE_INT imask = GET_MODE_MASK (mode);
18150 /* Shift amount for subword relative to aligned word. */
18151 addrSI = force_reg (GET_MODE (XEXP (mem, 0)), XEXP (mem, 0));
18152 addrSI = force_reg (SImode, gen_lowpart_common (SImode, addrSI));
18153 shift = gen_reg_rtx (SImode);
18154 emit_insn (gen_rlwinm (shift, addrSI, GEN_INT (3),
18155 GEN_INT (shift_mask)));
18156 emit_insn (gen_xorsi3 (shift, shift, GEN_INT (shift_mask)));
18158 /* Shift and mask old value into position within word. */
18159 oldval = convert_modes (SImode, mode, oldval, 1);
18160 oldval = expand_binop (SImode, and_optab,
18161 oldval, GEN_INT (imask), NULL_RTX,
18162 1, OPTAB_LIB_WIDEN);
18163 emit_insn (gen_ashlsi3 (oldval, oldval, shift));
18165 /* Shift and mask new value into position within word. */
18166 newval = convert_modes (SImode, mode, newval, 1);
18167 newval = expand_binop (SImode, and_optab,
18168 newval, GEN_INT (imask), NULL_RTX,
18169 1, OPTAB_LIB_WIDEN);
18170 emit_insn (gen_ashlsi3 (newval, newval, shift));
18172 /* Mask for insertion. */
18173 mask = gen_reg_rtx (SImode);
18174 emit_move_insn (mask, GEN_INT (imask));
18175 emit_insn (gen_ashlsi3 (mask, mask, shift));
18177 /* Address of aligned word containing subword. */
18178 align = expand_binop (Pmode, and_optab, XEXP (mem, 0), GEN_INT (-4),
18179 NULL_RTX, 1, OPTAB_LIB_WIDEN);
18180 mem = change_address (mem, SImode, align);
18181 set_mem_align (mem, 32);
18182 MEM_VOLATILE_P (mem) = 1;
18184 wdst = gen_reg_rtx (SImode);
18185 emit_insn (gen_sync_compare_and_swapqhi_internal (wdst, mask,
18186 oldval, newval, mem));
18188 /* Shift the result back. */
18189 emit_insn (gen_lshrsi3 (wdst, wdst, shift));
18191 emit_move_insn (dst, gen_lowpart (mode, wdst));
18194 void
18195 rs6000_split_compare_and_swapqhi (rtx dest, rtx mask,
18196 rtx oldval, rtx newval, rtx mem,
18197 rtx scratch)
18199 rtx label1, label2, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
18201 emit_insn (gen_lwsync ());
18202 label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
18203 label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
18204 emit_label (XEXP (label1, 0));
18206 emit_load_locked (SImode, scratch, mem);
18208 /* Mask subword within loaded value for comparison with oldval.
18209 Use UNSPEC_AND to avoid clobber.*/
18210 emit_insn (gen_rtx_SET (SImode, dest,
18211 gen_rtx_UNSPEC (SImode,
18212 gen_rtvec (2, scratch, mask),
18213 UNSPEC_AND)));
18215 x = gen_rtx_COMPARE (CCmode, dest, oldval);
18216 emit_insn (gen_rtx_SET (VOIDmode, cond, x));
18218 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
18219 emit_unlikely_jump (x, label2);
18221 /* Clear subword within loaded value for insertion of new value. */
18222 emit_insn (gen_rtx_SET (SImode, scratch,
18223 gen_rtx_AND (SImode,
18224 gen_rtx_NOT (SImode, mask), scratch)));
18225 emit_insn (gen_iorsi3 (scratch, scratch, newval));
18226 emit_store_conditional (SImode, cond, mem, scratch);
18228 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
18229 emit_unlikely_jump (x, label1);
18231 emit_insn (gen_isync ());
18232 emit_label (XEXP (label2, 0));
18236 /* Emit instructions to move SRC to DST. Called by splitters for
18237 multi-register moves. It will emit at most one instruction for
18238 each register that is accessed; that is, it won't emit li/lis pairs
18239 (or equivalent for 64-bit code). One of SRC or DST must be a hard
18240 register. */
18242 void
18243 rs6000_split_multireg_move (rtx dst, rtx src)
18245 /* The register number of the first register being moved. */
18246 int reg;
18247 /* The mode that is to be moved. */
18248 enum machine_mode mode;
18249 /* The mode that the move is being done in, and its size. */
18250 enum machine_mode reg_mode;
18251 int reg_mode_size;
18252 /* The number of registers that will be moved. */
18253 int nregs;
18255 reg = REG_P (dst) ? REGNO (dst) : REGNO (src);
18256 mode = GET_MODE (dst);
18257 nregs = hard_regno_nregs[reg][mode];
18258 if (FP_REGNO_P (reg))
18259 reg_mode = DECIMAL_FLOAT_MODE_P (mode) ? DDmode :
18260 ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? DFmode : SFmode);
18261 else if (ALTIVEC_REGNO_P (reg))
18262 reg_mode = V16QImode;
18263 else if (TARGET_E500_DOUBLE && mode == TFmode)
18264 reg_mode = DFmode;
18265 else
18266 reg_mode = word_mode;
18267 reg_mode_size = GET_MODE_SIZE (reg_mode);
18269 gcc_assert (reg_mode_size * nregs == GET_MODE_SIZE (mode));
18271 if (REG_P (src) && REG_P (dst) && (REGNO (src) < REGNO (dst)))
18273 /* Move register range backwards, if we might have destructive
18274 overlap. */
18275 int i;
18276 for (i = nregs - 1; i >= 0; i--)
18277 emit_insn (gen_rtx_SET (VOIDmode,
18278 simplify_gen_subreg (reg_mode, dst, mode,
18279 i * reg_mode_size),
18280 simplify_gen_subreg (reg_mode, src, mode,
18281 i * reg_mode_size)));
18283 else
18285 int i;
18286 int j = -1;
18287 bool used_update = false;
18288 rtx restore_basereg = NULL_RTX;
18290 if (MEM_P (src) && INT_REGNO_P (reg))
18292 rtx breg;
18294 if (GET_CODE (XEXP (src, 0)) == PRE_INC
18295 || GET_CODE (XEXP (src, 0)) == PRE_DEC)
18297 rtx delta_rtx;
18298 breg = XEXP (XEXP (src, 0), 0);
18299 delta_rtx = (GET_CODE (XEXP (src, 0)) == PRE_INC
18300 ? GEN_INT (GET_MODE_SIZE (GET_MODE (src)))
18301 : GEN_INT (-GET_MODE_SIZE (GET_MODE (src))));
18302 emit_insn (gen_add3_insn (breg, breg, delta_rtx));
18303 src = replace_equiv_address (src, breg);
18305 else if (! rs6000_offsettable_memref_p (src))
18307 if (GET_CODE (XEXP (src, 0)) == PRE_MODIFY)
18309 rtx basereg = XEXP (XEXP (src, 0), 0);
18310 if (TARGET_UPDATE)
18312 rtx ndst = simplify_gen_subreg (reg_mode, dst, mode, 0);
18313 emit_insn (gen_rtx_SET (VOIDmode, ndst,
18314 gen_rtx_MEM (reg_mode, XEXP (src, 0))));
18315 used_update = true;
18317 else
18318 emit_insn (gen_rtx_SET (VOIDmode, basereg,
18319 XEXP (XEXP (src, 0), 1)));
18320 src = replace_equiv_address (src, basereg);
18322 else
18324 rtx basereg = gen_rtx_REG (Pmode, reg);
18325 emit_insn (gen_rtx_SET (VOIDmode, basereg, XEXP (src, 0)));
18326 src = replace_equiv_address (src, basereg);
18330 breg = XEXP (src, 0);
18331 if (GET_CODE (breg) == PLUS || GET_CODE (breg) == LO_SUM)
18332 breg = XEXP (breg, 0);
18334 /* If the base register we are using to address memory is
18335 also a destination reg, then change that register last. */
18336 if (REG_P (breg)
18337 && REGNO (breg) >= REGNO (dst)
18338 && REGNO (breg) < REGNO (dst) + nregs)
18339 j = REGNO (breg) - REGNO (dst);
18341 else if (MEM_P (dst) && INT_REGNO_P (reg))
18343 rtx breg;
18345 if (GET_CODE (XEXP (dst, 0)) == PRE_INC
18346 || GET_CODE (XEXP (dst, 0)) == PRE_DEC)
18348 rtx delta_rtx;
18349 breg = XEXP (XEXP (dst, 0), 0);
18350 delta_rtx = (GET_CODE (XEXP (dst, 0)) == PRE_INC
18351 ? GEN_INT (GET_MODE_SIZE (GET_MODE (dst)))
18352 : GEN_INT (-GET_MODE_SIZE (GET_MODE (dst))));
18354 /* We have to update the breg before doing the store.
18355 Use store with update, if available. */
18357 if (TARGET_UPDATE)
18359 rtx nsrc = simplify_gen_subreg (reg_mode, src, mode, 0);
18360 emit_insn (TARGET_32BIT
18361 ? (TARGET_POWERPC64
18362 ? gen_movdi_si_update (breg, breg, delta_rtx, nsrc)
18363 : gen_movsi_update (breg, breg, delta_rtx, nsrc))
18364 : gen_movdi_di_update (breg, breg, delta_rtx, nsrc));
18365 used_update = true;
18367 else
18368 emit_insn (gen_add3_insn (breg, breg, delta_rtx));
18369 dst = replace_equiv_address (dst, breg);
18371 else if (!rs6000_offsettable_memref_p (dst)
18372 && GET_CODE (XEXP (dst, 0)) != LO_SUM)
18374 if (GET_CODE (XEXP (dst, 0)) == PRE_MODIFY)
18376 rtx basereg = XEXP (XEXP (dst, 0), 0);
18377 if (TARGET_UPDATE)
18379 rtx nsrc = simplify_gen_subreg (reg_mode, src, mode, 0);
18380 emit_insn (gen_rtx_SET (VOIDmode,
18381 gen_rtx_MEM (reg_mode, XEXP (dst, 0)), nsrc));
18382 used_update = true;
18384 else
18385 emit_insn (gen_rtx_SET (VOIDmode, basereg,
18386 XEXP (XEXP (dst, 0), 1)));
18387 dst = replace_equiv_address (dst, basereg);
18389 else
18391 rtx basereg = XEXP (XEXP (dst, 0), 0);
18392 rtx offsetreg = XEXP (XEXP (dst, 0), 1);
18393 gcc_assert (GET_CODE (XEXP (dst, 0)) == PLUS
18394 && REG_P (basereg)
18395 && REG_P (offsetreg)
18396 && REGNO (basereg) != REGNO (offsetreg));
18397 if (REGNO (basereg) == 0)
18399 rtx tmp = offsetreg;
18400 offsetreg = basereg;
18401 basereg = tmp;
18403 emit_insn (gen_add3_insn (basereg, basereg, offsetreg));
18404 restore_basereg = gen_sub3_insn (basereg, basereg, offsetreg);
18405 dst = replace_equiv_address (dst, basereg);
18408 else if (GET_CODE (XEXP (dst, 0)) != LO_SUM)
18409 gcc_assert (rs6000_offsettable_memref_p (dst));
18412 for (i = 0; i < nregs; i++)
18414 /* Calculate index to next subword. */
18415 ++j;
18416 if (j == nregs)
18417 j = 0;
18419 /* If compiler already emitted move of first word by
18420 store with update, no need to do anything. */
18421 if (j == 0 && used_update)
18422 continue;
18424 emit_insn (gen_rtx_SET (VOIDmode,
18425 simplify_gen_subreg (reg_mode, dst, mode,
18426 j * reg_mode_size),
18427 simplify_gen_subreg (reg_mode, src, mode,
18428 j * reg_mode_size)));
18430 if (restore_basereg != NULL_RTX)
18431 emit_insn (restore_basereg);
18436 /* This page contains routines that are used to determine what the
18437 function prologue and epilogue code will do and write them out. */
18439 /* Return the first fixed-point register that is required to be
18440 saved. 32 if none. */
18443 first_reg_to_save (void)
18445 int first_reg;
18447 /* Find lowest numbered live register. */
18448 for (first_reg = 13; first_reg <= 31; first_reg++)
18449 if (df_regs_ever_live_p (first_reg)
18450 && (! call_used_regs[first_reg]
18451 || (first_reg == RS6000_PIC_OFFSET_TABLE_REGNUM
18452 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
18453 || (DEFAULT_ABI == ABI_DARWIN && flag_pic)
18454 || (TARGET_TOC && TARGET_MINIMAL_TOC)))))
18455 break;
18457 #if TARGET_MACHO
18458 if (flag_pic
18459 && crtl->uses_pic_offset_table
18460 && first_reg > RS6000_PIC_OFFSET_TABLE_REGNUM)
18461 return RS6000_PIC_OFFSET_TABLE_REGNUM;
18462 #endif
18464 return first_reg;
18467 /* Similar, for FP regs. */
18470 first_fp_reg_to_save (void)
18472 int first_reg;
18474 /* Find lowest numbered live register. */
18475 for (first_reg = 14 + 32; first_reg <= 63; first_reg++)
18476 if (df_regs_ever_live_p (first_reg))
18477 break;
18479 return first_reg;
18482 /* Similar, for AltiVec regs. */
18484 static int
18485 first_altivec_reg_to_save (void)
18487 int i;
18489 /* Stack frame remains as is unless we are in AltiVec ABI. */
18490 if (! TARGET_ALTIVEC_ABI)
18491 return LAST_ALTIVEC_REGNO + 1;
18493 /* On Darwin, the unwind routines are compiled without
18494 TARGET_ALTIVEC, and use save_world to save/restore the
18495 altivec registers when necessary. */
18496 if (DEFAULT_ABI == ABI_DARWIN && crtl->calls_eh_return
18497 && ! TARGET_ALTIVEC)
18498 return FIRST_ALTIVEC_REGNO + 20;
18500 /* Find lowest numbered live register. */
18501 for (i = FIRST_ALTIVEC_REGNO + 20; i <= LAST_ALTIVEC_REGNO; ++i)
18502 if (df_regs_ever_live_p (i))
18503 break;
18505 return i;
18508 /* Return a 32-bit mask of the AltiVec registers we need to set in
18509 VRSAVE. Bit n of the return value is 1 if Vn is live. The MSB in
18510 the 32-bit word is 0. */
18512 static unsigned int
18513 compute_vrsave_mask (void)
18515 unsigned int i, mask = 0;
18517 /* On Darwin, the unwind routines are compiled without
18518 TARGET_ALTIVEC, and use save_world to save/restore the
18519 call-saved altivec registers when necessary. */
18520 if (DEFAULT_ABI == ABI_DARWIN && crtl->calls_eh_return
18521 && ! TARGET_ALTIVEC)
18522 mask |= 0xFFF;
18524 /* First, find out if we use _any_ altivec registers. */
18525 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
18526 if (df_regs_ever_live_p (i))
18527 mask |= ALTIVEC_REG_BIT (i);
18529 if (mask == 0)
18530 return mask;
18532 /* Next, remove the argument registers from the set. These must
18533 be in the VRSAVE mask set by the caller, so we don't need to add
18534 them in again. More importantly, the mask we compute here is
18535 used to generate CLOBBERs in the set_vrsave insn, and we do not
18536 wish the argument registers to die. */
18537 for (i = crtl->args.info.vregno - 1; i >= ALTIVEC_ARG_MIN_REG; --i)
18538 mask &= ~ALTIVEC_REG_BIT (i);
18540 /* Similarly, remove the return value from the set. */
18542 bool yes = false;
18543 diddle_return_value (is_altivec_return_reg, &yes);
18544 if (yes)
18545 mask &= ~ALTIVEC_REG_BIT (ALTIVEC_ARG_RETURN);
18548 return mask;
18551 /* For a very restricted set of circumstances, we can cut down the
18552 size of prologues/epilogues by calling our own save/restore-the-world
18553 routines. */
18555 static void
18556 compute_save_world_info (rs6000_stack_t *info_ptr)
18558 info_ptr->world_save_p = 1;
18559 info_ptr->world_save_p
18560 = (WORLD_SAVE_P (info_ptr)
18561 && DEFAULT_ABI == ABI_DARWIN
18562 && ! (cfun->calls_setjmp && flag_exceptions)
18563 && info_ptr->first_fp_reg_save == FIRST_SAVED_FP_REGNO
18564 && info_ptr->first_gp_reg_save == FIRST_SAVED_GP_REGNO
18565 && info_ptr->first_altivec_reg_save == FIRST_SAVED_ALTIVEC_REGNO
18566 && info_ptr->cr_save_p);
18568 /* This will not work in conjunction with sibcalls. Make sure there
18569 are none. (This check is expensive, but seldom executed.) */
18570 if (WORLD_SAVE_P (info_ptr))
18572 rtx insn;
18573 for ( insn = get_last_insn_anywhere (); insn; insn = PREV_INSN (insn))
18574 if ( GET_CODE (insn) == CALL_INSN
18575 && SIBLING_CALL_P (insn))
18577 info_ptr->world_save_p = 0;
18578 break;
18582 if (WORLD_SAVE_P (info_ptr))
18584 /* Even if we're not touching VRsave, make sure there's room on the
18585 stack for it, if it looks like we're calling SAVE_WORLD, which
18586 will attempt to save it. */
18587 info_ptr->vrsave_size = 4;
18589 /* If we are going to save the world, we need to save the link register too. */
18590 info_ptr->lr_save_p = 1;
18592 /* "Save" the VRsave register too if we're saving the world. */
18593 if (info_ptr->vrsave_mask == 0)
18594 info_ptr->vrsave_mask = compute_vrsave_mask ();
18596 /* Because the Darwin register save/restore routines only handle
18597 F14 .. F31 and V20 .. V31 as per the ABI, perform a consistency
18598 check. */
18599 gcc_assert (info_ptr->first_fp_reg_save >= FIRST_SAVED_FP_REGNO
18600 && (info_ptr->first_altivec_reg_save
18601 >= FIRST_SAVED_ALTIVEC_REGNO));
18603 return;
18607 static void
18608 is_altivec_return_reg (rtx reg, void *xyes)
18610 bool *yes = (bool *) xyes;
18611 if (REGNO (reg) == ALTIVEC_ARG_RETURN)
18612 *yes = true;
18616 /* Determine the strategy for savings/restoring registers. */
18618 enum {
18619 SAVRES_MULTIPLE = 0x1,
18620 SAVE_INLINE_FPRS = 0x2,
18621 SAVE_INLINE_GPRS = 0x4,
18622 REST_INLINE_FPRS = 0x8,
18623 REST_INLINE_GPRS = 0x10,
18624 SAVE_NOINLINE_GPRS_SAVES_LR = 0x20,
18625 SAVE_NOINLINE_FPRS_SAVES_LR = 0x40,
18626 REST_NOINLINE_FPRS_DOESNT_RESTORE_LR = 0x80
18629 static int
18630 rs6000_savres_strategy (rs6000_stack_t *info,
18631 bool using_static_chain_p)
18633 int strategy = 0;
18635 if (TARGET_MULTIPLE
18636 && !TARGET_POWERPC64
18637 && !(TARGET_SPE_ABI && info->spe_64bit_regs_used)
18638 && info->first_gp_reg_save < 31
18639 && no_global_regs_above (info->first_gp_reg_save, /*gpr=*/true))
18640 strategy |= SAVRES_MULTIPLE;
18642 if (crtl->calls_eh_return
18643 || cfun->machine->ra_need_lr
18644 || info->total_size > 32767)
18645 strategy |= (SAVE_INLINE_FPRS | REST_INLINE_FPRS
18646 | SAVE_INLINE_GPRS | REST_INLINE_GPRS);
18648 if (info->first_fp_reg_save == 64
18649 || FP_SAVE_INLINE (info->first_fp_reg_save)
18650 /* The out-of-line FP routines use double-precision stores;
18651 we can't use those routines if we don't have such stores. */
18652 || (TARGET_HARD_FLOAT && !TARGET_DOUBLE_FLOAT)
18653 || !no_global_regs_above (info->first_fp_reg_save, /*gpr=*/false))
18654 strategy |= SAVE_INLINE_FPRS | REST_INLINE_FPRS;
18656 if (info->first_gp_reg_save == 32
18657 || GP_SAVE_INLINE (info->first_gp_reg_save)
18658 || !((strategy & SAVRES_MULTIPLE)
18659 || no_global_regs_above (info->first_gp_reg_save, /*gpr=*/true)))
18660 strategy |= SAVE_INLINE_GPRS | REST_INLINE_GPRS;
18662 /* Don't bother to try to save things out-of-line if r11 is occupied
18663 by the static chain. It would require too much fiddling and the
18664 static chain is rarely used anyway. */
18665 if (using_static_chain_p)
18666 strategy |= SAVE_INLINE_FPRS | SAVE_INLINE_GPRS;
18668 /* If we are going to use store multiple, then don't even bother
18669 with the out-of-line routines, since the store-multiple
18670 instruction will always be smaller. */
18671 if ((strategy & SAVRES_MULTIPLE))
18672 strategy |= SAVE_INLINE_GPRS;
18674 /* The situation is more complicated with load multiple. We'd
18675 prefer to use the out-of-line routines for restores, since the
18676 "exit" out-of-line routines can handle the restore of LR and the
18677 frame teardown. However if doesn't make sense to use the
18678 out-of-line routine if that is the only reason we'd need to save
18679 LR, and we can't use the "exit" out-of-line gpr restore if we
18680 have saved some fprs; In those cases it is advantageous to use
18681 load multiple when available. */
18682 if ((strategy & SAVRES_MULTIPLE)
18683 && (!info->lr_save_p
18684 || info->first_fp_reg_save != 64))
18685 strategy |= REST_INLINE_GPRS;
18687 /* We can only use load multiple or the out-of-line routines to
18688 restore if we've used store multiple or out-of-line routines
18689 in the prologue, i.e. if we've saved all the registers from
18690 first_gp_reg_save. Otherwise, we risk loading garbage. */
18691 if ((strategy & (SAVE_INLINE_GPRS | SAVRES_MULTIPLE)) == SAVE_INLINE_GPRS)
18692 strategy |= REST_INLINE_GPRS;
18694 /* Saving CR interferes with the exit routines used on the SPE, so
18695 just punt here. */
18696 if (TARGET_SPE_ABI
18697 && info->spe_64bit_regs_used
18698 && info->cr_save_p)
18699 strategy |= REST_INLINE_GPRS;
18701 #ifdef POWERPC_LINUX
18702 if (TARGET_64BIT)
18704 if (!(strategy & SAVE_INLINE_FPRS))
18705 strategy |= SAVE_NOINLINE_FPRS_SAVES_LR;
18706 else if (!(strategy & SAVE_INLINE_GPRS)
18707 && info->first_fp_reg_save == 64)
18708 strategy |= SAVE_NOINLINE_GPRS_SAVES_LR;
18710 #else
18711 if (TARGET_AIX && !(strategy & REST_INLINE_FPRS))
18712 strategy |= REST_NOINLINE_FPRS_DOESNT_RESTORE_LR;
18713 #endif
18714 return strategy;
18717 /* Calculate the stack information for the current function. This is
18718 complicated by having two separate calling sequences, the AIX calling
18719 sequence and the V.4 calling sequence.
18721 AIX (and Darwin/Mac OS X) stack frames look like:
18722 32-bit 64-bit
18723 SP----> +---------------------------------------+
18724 | back chain to caller | 0 0
18725 +---------------------------------------+
18726 | saved CR | 4 8 (8-11)
18727 +---------------------------------------+
18728 | saved LR | 8 16
18729 +---------------------------------------+
18730 | reserved for compilers | 12 24
18731 +---------------------------------------+
18732 | reserved for binders | 16 32
18733 +---------------------------------------+
18734 | saved TOC pointer | 20 40
18735 +---------------------------------------+
18736 | Parameter save area (P) | 24 48
18737 +---------------------------------------+
18738 | Alloca space (A) | 24+P etc.
18739 +---------------------------------------+
18740 | Local variable space (L) | 24+P+A
18741 +---------------------------------------+
18742 | Float/int conversion temporary (X) | 24+P+A+L
18743 +---------------------------------------+
18744 | Save area for AltiVec registers (W) | 24+P+A+L+X
18745 +---------------------------------------+
18746 | AltiVec alignment padding (Y) | 24+P+A+L+X+W
18747 +---------------------------------------+
18748 | Save area for VRSAVE register (Z) | 24+P+A+L+X+W+Y
18749 +---------------------------------------+
18750 | Save area for GP registers (G) | 24+P+A+X+L+X+W+Y+Z
18751 +---------------------------------------+
18752 | Save area for FP registers (F) | 24+P+A+X+L+X+W+Y+Z+G
18753 +---------------------------------------+
18754 old SP->| back chain to caller's caller |
18755 +---------------------------------------+
18757 The required alignment for AIX configurations is two words (i.e., 8
18758 or 16 bytes).
18761 V.4 stack frames look like:
18763 SP----> +---------------------------------------+
18764 | back chain to caller | 0
18765 +---------------------------------------+
18766 | caller's saved LR | 4
18767 +---------------------------------------+
18768 | Parameter save area (P) | 8
18769 +---------------------------------------+
18770 | Alloca space (A) | 8+P
18771 +---------------------------------------+
18772 | Varargs save area (V) | 8+P+A
18773 +---------------------------------------+
18774 | Local variable space (L) | 8+P+A+V
18775 +---------------------------------------+
18776 | Float/int conversion temporary (X) | 8+P+A+V+L
18777 +---------------------------------------+
18778 | Save area for AltiVec registers (W) | 8+P+A+V+L+X
18779 +---------------------------------------+
18780 | AltiVec alignment padding (Y) | 8+P+A+V+L+X+W
18781 +---------------------------------------+
18782 | Save area for VRSAVE register (Z) | 8+P+A+V+L+X+W+Y
18783 +---------------------------------------+
18784 | SPE: area for 64-bit GP registers |
18785 +---------------------------------------+
18786 | SPE alignment padding |
18787 +---------------------------------------+
18788 | saved CR (C) | 8+P+A+V+L+X+W+Y+Z
18789 +---------------------------------------+
18790 | Save area for GP registers (G) | 8+P+A+V+L+X+W+Y+Z+C
18791 +---------------------------------------+
18792 | Save area for FP registers (F) | 8+P+A+V+L+X+W+Y+Z+C+G
18793 +---------------------------------------+
18794 old SP->| back chain to caller's caller |
18795 +---------------------------------------+
18797 The required alignment for V.4 is 16 bytes, or 8 bytes if -meabi is
18798 given. (But note below and in sysv4.h that we require only 8 and
18799 may round up the size of our stack frame anyways. The historical
18800 reason is early versions of powerpc-linux which didn't properly
18801 align the stack at program startup. A happy side-effect is that
18802 -mno-eabi libraries can be used with -meabi programs.)
18804 The EABI configuration defaults to the V.4 layout. However,
18805 the stack alignment requirements may differ. If -mno-eabi is not
18806 given, the required stack alignment is 8 bytes; if -mno-eabi is
18807 given, the required alignment is 16 bytes. (But see V.4 comment
18808 above.) */
18810 #ifndef ABI_STACK_BOUNDARY
18811 #define ABI_STACK_BOUNDARY STACK_BOUNDARY
18812 #endif
18814 static rs6000_stack_t *
18815 rs6000_stack_info (void)
18817 #ifdef ENABLE_CHECKING
18818 static rs6000_stack_t info_save;
18819 #endif
18820 rs6000_stack_t *info_ptr = &stack_info;
18821 int reg_size = TARGET_32BIT ? 4 : 8;
18822 int ehrd_size;
18823 int save_align;
18824 int first_gp;
18825 HOST_WIDE_INT non_fixed_size;
18826 bool using_static_chain_p;
18828 #ifdef ENABLE_CHECKING
18829 memcpy (&info_save, &stack_info, sizeof stack_info);
18830 #else
18831 if (reload_completed && info_ptr->reload_completed)
18832 return info_ptr;
18833 #endif
18835 memset (&stack_info, 0, sizeof (stack_info));
18836 info_ptr->reload_completed = reload_completed;
18838 if (TARGET_SPE)
18840 /* Cache value so we don't rescan instruction chain over and over. */
18841 if (cfun->machine->insn_chain_scanned_p == 0)
18842 cfun->machine->insn_chain_scanned_p
18843 = spe_func_has_64bit_regs_p () + 1;
18844 info_ptr->spe_64bit_regs_used = cfun->machine->insn_chain_scanned_p - 1;
18847 /* Select which calling sequence. */
18848 info_ptr->abi = DEFAULT_ABI;
18850 /* Calculate which registers need to be saved & save area size. */
18851 info_ptr->first_gp_reg_save = first_reg_to_save ();
18852 /* Assume that we will have to save RS6000_PIC_OFFSET_TABLE_REGNUM,
18853 even if it currently looks like we won't. Reload may need it to
18854 get at a constant; if so, it will have already created a constant
18855 pool entry for it. */
18856 if (((TARGET_TOC && TARGET_MINIMAL_TOC)
18857 || (flag_pic == 1 && DEFAULT_ABI == ABI_V4)
18858 || (flag_pic && DEFAULT_ABI == ABI_DARWIN))
18859 && crtl->uses_const_pool
18860 && info_ptr->first_gp_reg_save > RS6000_PIC_OFFSET_TABLE_REGNUM)
18861 first_gp = RS6000_PIC_OFFSET_TABLE_REGNUM;
18862 else
18863 first_gp = info_ptr->first_gp_reg_save;
18865 info_ptr->gp_size = reg_size * (32 - first_gp);
18867 /* For the SPE, we have an additional upper 32-bits on each GPR.
18868 Ideally we should save the entire 64-bits only when the upper
18869 half is used in SIMD instructions. Since we only record
18870 registers live (not the size they are used in), this proves
18871 difficult because we'd have to traverse the instruction chain at
18872 the right time, taking reload into account. This is a real pain,
18873 so we opt to save the GPRs in 64-bits always if but one register
18874 gets used in 64-bits. Otherwise, all the registers in the frame
18875 get saved in 32-bits.
18877 So... since when we save all GPRs (except the SP) in 64-bits, the
18878 traditional GP save area will be empty. */
18879 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
18880 info_ptr->gp_size = 0;
18882 info_ptr->first_fp_reg_save = first_fp_reg_to_save ();
18883 info_ptr->fp_size = 8 * (64 - info_ptr->first_fp_reg_save);
18885 info_ptr->first_altivec_reg_save = first_altivec_reg_to_save ();
18886 info_ptr->altivec_size = 16 * (LAST_ALTIVEC_REGNO + 1
18887 - info_ptr->first_altivec_reg_save);
18889 /* Does this function call anything? */
18890 info_ptr->calls_p = (! current_function_is_leaf
18891 || cfun->machine->ra_needs_full_frame);
18893 /* Determine if we need to save the condition code registers. */
18894 if (df_regs_ever_live_p (CR2_REGNO)
18895 || df_regs_ever_live_p (CR3_REGNO)
18896 || df_regs_ever_live_p (CR4_REGNO))
18898 info_ptr->cr_save_p = 1;
18899 if (DEFAULT_ABI == ABI_V4)
18900 info_ptr->cr_size = reg_size;
18903 /* If the current function calls __builtin_eh_return, then we need
18904 to allocate stack space for registers that will hold data for
18905 the exception handler. */
18906 if (crtl->calls_eh_return)
18908 unsigned int i;
18909 for (i = 0; EH_RETURN_DATA_REGNO (i) != INVALID_REGNUM; ++i)
18910 continue;
18912 /* SPE saves EH registers in 64-bits. */
18913 ehrd_size = i * (TARGET_SPE_ABI
18914 && info_ptr->spe_64bit_regs_used != 0
18915 ? UNITS_PER_SPE_WORD : UNITS_PER_WORD);
18917 else
18918 ehrd_size = 0;
18920 /* Determine various sizes. */
18921 info_ptr->reg_size = reg_size;
18922 info_ptr->fixed_size = RS6000_SAVE_AREA;
18923 info_ptr->vars_size = RS6000_ALIGN (get_frame_size (), 8);
18924 info_ptr->parm_size = RS6000_ALIGN (crtl->outgoing_args_size,
18925 TARGET_ALTIVEC ? 16 : 8);
18926 if (FRAME_GROWS_DOWNWARD)
18927 info_ptr->vars_size
18928 += RS6000_ALIGN (info_ptr->fixed_size + info_ptr->vars_size
18929 + info_ptr->parm_size,
18930 ABI_STACK_BOUNDARY / BITS_PER_UNIT)
18931 - (info_ptr->fixed_size + info_ptr->vars_size
18932 + info_ptr->parm_size);
18934 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
18935 info_ptr->spe_gp_size = 8 * (32 - first_gp);
18936 else
18937 info_ptr->spe_gp_size = 0;
18939 if (TARGET_ALTIVEC_ABI)
18940 info_ptr->vrsave_mask = compute_vrsave_mask ();
18941 else
18942 info_ptr->vrsave_mask = 0;
18944 if (TARGET_ALTIVEC_VRSAVE && info_ptr->vrsave_mask)
18945 info_ptr->vrsave_size = 4;
18946 else
18947 info_ptr->vrsave_size = 0;
18949 compute_save_world_info (info_ptr);
18951 /* Calculate the offsets. */
18952 switch (DEFAULT_ABI)
18954 case ABI_NONE:
18955 default:
18956 gcc_unreachable ();
18958 case ABI_AIX:
18959 case ABI_DARWIN:
18960 info_ptr->fp_save_offset = - info_ptr->fp_size;
18961 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
18963 if (TARGET_ALTIVEC_ABI)
18965 info_ptr->vrsave_save_offset
18966 = info_ptr->gp_save_offset - info_ptr->vrsave_size;
18968 /* Align stack so vector save area is on a quadword boundary.
18969 The padding goes above the vectors. */
18970 if (info_ptr->altivec_size != 0)
18971 info_ptr->altivec_padding_size
18972 = info_ptr->vrsave_save_offset & 0xF;
18973 else
18974 info_ptr->altivec_padding_size = 0;
18976 info_ptr->altivec_save_offset
18977 = info_ptr->vrsave_save_offset
18978 - info_ptr->altivec_padding_size
18979 - info_ptr->altivec_size;
18980 gcc_assert (info_ptr->altivec_size == 0
18981 || info_ptr->altivec_save_offset % 16 == 0);
18983 /* Adjust for AltiVec case. */
18984 info_ptr->ehrd_offset = info_ptr->altivec_save_offset - ehrd_size;
18986 else
18987 info_ptr->ehrd_offset = info_ptr->gp_save_offset - ehrd_size;
18988 info_ptr->cr_save_offset = reg_size; /* first word when 64-bit. */
18989 info_ptr->lr_save_offset = 2*reg_size;
18990 break;
18992 case ABI_V4:
18993 info_ptr->fp_save_offset = - info_ptr->fp_size;
18994 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
18995 info_ptr->cr_save_offset = info_ptr->gp_save_offset - info_ptr->cr_size;
18997 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
18999 /* Align stack so SPE GPR save area is aligned on a
19000 double-word boundary. */
19001 if (info_ptr->spe_gp_size != 0 && info_ptr->cr_save_offset != 0)
19002 info_ptr->spe_padding_size
19003 = 8 - (-info_ptr->cr_save_offset % 8);
19004 else
19005 info_ptr->spe_padding_size = 0;
19007 info_ptr->spe_gp_save_offset
19008 = info_ptr->cr_save_offset
19009 - info_ptr->spe_padding_size
19010 - info_ptr->spe_gp_size;
19012 /* Adjust for SPE case. */
19013 info_ptr->ehrd_offset = info_ptr->spe_gp_save_offset;
19015 else if (TARGET_ALTIVEC_ABI)
19017 info_ptr->vrsave_save_offset
19018 = info_ptr->cr_save_offset - info_ptr->vrsave_size;
19020 /* Align stack so vector save area is on a quadword boundary. */
19021 if (info_ptr->altivec_size != 0)
19022 info_ptr->altivec_padding_size
19023 = 16 - (-info_ptr->vrsave_save_offset % 16);
19024 else
19025 info_ptr->altivec_padding_size = 0;
19027 info_ptr->altivec_save_offset
19028 = info_ptr->vrsave_save_offset
19029 - info_ptr->altivec_padding_size
19030 - info_ptr->altivec_size;
19032 /* Adjust for AltiVec case. */
19033 info_ptr->ehrd_offset = info_ptr->altivec_save_offset;
19035 else
19036 info_ptr->ehrd_offset = info_ptr->cr_save_offset;
19037 info_ptr->ehrd_offset -= ehrd_size;
19038 info_ptr->lr_save_offset = reg_size;
19039 break;
19042 save_align = (TARGET_ALTIVEC_ABI || DEFAULT_ABI == ABI_DARWIN) ? 16 : 8;
19043 info_ptr->save_size = RS6000_ALIGN (info_ptr->fp_size
19044 + info_ptr->gp_size
19045 + info_ptr->altivec_size
19046 + info_ptr->altivec_padding_size
19047 + info_ptr->spe_gp_size
19048 + info_ptr->spe_padding_size
19049 + ehrd_size
19050 + info_ptr->cr_size
19051 + info_ptr->vrsave_size,
19052 save_align);
19054 non_fixed_size = (info_ptr->vars_size
19055 + info_ptr->parm_size
19056 + info_ptr->save_size);
19058 info_ptr->total_size = RS6000_ALIGN (non_fixed_size + info_ptr->fixed_size,
19059 ABI_STACK_BOUNDARY / BITS_PER_UNIT);
19061 /* Determine if we need to save the link register. */
19062 if (info_ptr->calls_p
19063 || (DEFAULT_ABI == ABI_AIX
19064 && crtl->profile
19065 && !TARGET_PROFILE_KERNEL)
19066 || (DEFAULT_ABI == ABI_V4 && cfun->calls_alloca)
19067 #ifdef TARGET_RELOCATABLE
19068 || (TARGET_RELOCATABLE && (get_pool_size () != 0))
19069 #endif
19070 || rs6000_ra_ever_killed ())
19071 info_ptr->lr_save_p = 1;
19073 using_static_chain_p = (cfun->static_chain_decl != NULL_TREE
19074 && df_regs_ever_live_p (STATIC_CHAIN_REGNUM)
19075 && call_used_regs[STATIC_CHAIN_REGNUM]);
19076 info_ptr->savres_strategy = rs6000_savres_strategy (info_ptr,
19077 using_static_chain_p);
19079 if (!(info_ptr->savres_strategy & SAVE_INLINE_GPRS)
19080 || !(info_ptr->savres_strategy & SAVE_INLINE_FPRS)
19081 || !(info_ptr->savres_strategy & REST_INLINE_GPRS)
19082 || !(info_ptr->savres_strategy & REST_INLINE_FPRS))
19083 info_ptr->lr_save_p = 1;
19085 if (info_ptr->lr_save_p)
19086 df_set_regs_ever_live (LR_REGNO, true);
19088 /* Determine if we need to allocate any stack frame:
19090 For AIX we need to push the stack if a frame pointer is needed
19091 (because the stack might be dynamically adjusted), if we are
19092 debugging, if we make calls, or if the sum of fp_save, gp_save,
19093 and local variables are more than the space needed to save all
19094 non-volatile registers: 32-bit: 18*8 + 19*4 = 220 or 64-bit: 18*8
19095 + 18*8 = 288 (GPR13 reserved).
19097 For V.4 we don't have the stack cushion that AIX uses, but assume
19098 that the debugger can handle stackless frames. */
19100 if (info_ptr->calls_p)
19101 info_ptr->push_p = 1;
19103 else if (DEFAULT_ABI == ABI_V4)
19104 info_ptr->push_p = non_fixed_size != 0;
19106 else if (frame_pointer_needed)
19107 info_ptr->push_p = 1;
19109 else if (TARGET_XCOFF && write_symbols != NO_DEBUG)
19110 info_ptr->push_p = 1;
19112 else
19113 info_ptr->push_p = non_fixed_size > (TARGET_32BIT ? 220 : 288);
19115 /* Zero offsets if we're not saving those registers. */
19116 if (info_ptr->fp_size == 0)
19117 info_ptr->fp_save_offset = 0;
19119 if (info_ptr->gp_size == 0)
19120 info_ptr->gp_save_offset = 0;
19122 if (! TARGET_ALTIVEC_ABI || info_ptr->altivec_size == 0)
19123 info_ptr->altivec_save_offset = 0;
19125 if (! TARGET_ALTIVEC_ABI || info_ptr->vrsave_mask == 0)
19126 info_ptr->vrsave_save_offset = 0;
19128 if (! TARGET_SPE_ABI
19129 || info_ptr->spe_64bit_regs_used == 0
19130 || info_ptr->spe_gp_size == 0)
19131 info_ptr->spe_gp_save_offset = 0;
19133 if (! info_ptr->lr_save_p)
19134 info_ptr->lr_save_offset = 0;
19136 if (! info_ptr->cr_save_p)
19137 info_ptr->cr_save_offset = 0;
19139 #ifdef ENABLE_CHECKING
19140 gcc_assert (!(reload_completed && info_save.reload_completed)
19141 || memcmp (&info_save, &stack_info, sizeof stack_info) == 0);
19142 #endif
19143 return info_ptr;
19146 /* Return true if the current function uses any GPRs in 64-bit SIMD
19147 mode. */
19149 static bool
19150 spe_func_has_64bit_regs_p (void)
19152 rtx insns, insn;
19154 /* Functions that save and restore all the call-saved registers will
19155 need to save/restore the registers in 64-bits. */
19156 if (crtl->calls_eh_return
19157 || cfun->calls_setjmp
19158 || crtl->has_nonlocal_goto)
19159 return true;
19161 insns = get_insns ();
19163 for (insn = NEXT_INSN (insns); insn != NULL_RTX; insn = NEXT_INSN (insn))
19165 if (INSN_P (insn))
19167 rtx i;
19169 /* FIXME: This should be implemented with attributes...
19171 (set_attr "spe64" "true")....then,
19172 if (get_spe64(insn)) return true;
19174 It's the only reliable way to do the stuff below. */
19176 i = PATTERN (insn);
19177 if (GET_CODE (i) == SET)
19179 enum machine_mode mode = GET_MODE (SET_SRC (i));
19181 if (SPE_VECTOR_MODE (mode))
19182 return true;
19183 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode))
19184 return true;
19189 return false;
19192 static void
19193 debug_stack_info (rs6000_stack_t *info)
19195 const char *abi_string;
19197 if (! info)
19198 info = rs6000_stack_info ();
19200 fprintf (stderr, "\nStack information for function %s:\n",
19201 ((current_function_decl && DECL_NAME (current_function_decl))
19202 ? IDENTIFIER_POINTER (DECL_NAME (current_function_decl))
19203 : "<unknown>"));
19205 switch (info->abi)
19207 default: abi_string = "Unknown"; break;
19208 case ABI_NONE: abi_string = "NONE"; break;
19209 case ABI_AIX: abi_string = "AIX"; break;
19210 case ABI_DARWIN: abi_string = "Darwin"; break;
19211 case ABI_V4: abi_string = "V.4"; break;
19214 fprintf (stderr, "\tABI = %5s\n", abi_string);
19216 if (TARGET_ALTIVEC_ABI)
19217 fprintf (stderr, "\tALTIVEC ABI extensions enabled.\n");
19219 if (TARGET_SPE_ABI)
19220 fprintf (stderr, "\tSPE ABI extensions enabled.\n");
19222 if (info->first_gp_reg_save != 32)
19223 fprintf (stderr, "\tfirst_gp_reg_save = %5d\n", info->first_gp_reg_save);
19225 if (info->first_fp_reg_save != 64)
19226 fprintf (stderr, "\tfirst_fp_reg_save = %5d\n", info->first_fp_reg_save);
19228 if (info->first_altivec_reg_save <= LAST_ALTIVEC_REGNO)
19229 fprintf (stderr, "\tfirst_altivec_reg_save = %5d\n",
19230 info->first_altivec_reg_save);
19232 if (info->lr_save_p)
19233 fprintf (stderr, "\tlr_save_p = %5d\n", info->lr_save_p);
19235 if (info->cr_save_p)
19236 fprintf (stderr, "\tcr_save_p = %5d\n", info->cr_save_p);
19238 if (info->vrsave_mask)
19239 fprintf (stderr, "\tvrsave_mask = 0x%x\n", info->vrsave_mask);
19241 if (info->push_p)
19242 fprintf (stderr, "\tpush_p = %5d\n", info->push_p);
19244 if (info->calls_p)
19245 fprintf (stderr, "\tcalls_p = %5d\n", info->calls_p);
19247 if (info->gp_save_offset)
19248 fprintf (stderr, "\tgp_save_offset = %5d\n", info->gp_save_offset);
19250 if (info->fp_save_offset)
19251 fprintf (stderr, "\tfp_save_offset = %5d\n", info->fp_save_offset);
19253 if (info->altivec_save_offset)
19254 fprintf (stderr, "\taltivec_save_offset = %5d\n",
19255 info->altivec_save_offset);
19257 if (info->spe_gp_save_offset)
19258 fprintf (stderr, "\tspe_gp_save_offset = %5d\n",
19259 info->spe_gp_save_offset);
19261 if (info->vrsave_save_offset)
19262 fprintf (stderr, "\tvrsave_save_offset = %5d\n",
19263 info->vrsave_save_offset);
19265 if (info->lr_save_offset)
19266 fprintf (stderr, "\tlr_save_offset = %5d\n", info->lr_save_offset);
19268 if (info->cr_save_offset)
19269 fprintf (stderr, "\tcr_save_offset = %5d\n", info->cr_save_offset);
19271 if (info->varargs_save_offset)
19272 fprintf (stderr, "\tvarargs_save_offset = %5d\n", info->varargs_save_offset);
19274 if (info->total_size)
19275 fprintf (stderr, "\ttotal_size = "HOST_WIDE_INT_PRINT_DEC"\n",
19276 info->total_size);
19278 if (info->vars_size)
19279 fprintf (stderr, "\tvars_size = "HOST_WIDE_INT_PRINT_DEC"\n",
19280 info->vars_size);
19282 if (info->parm_size)
19283 fprintf (stderr, "\tparm_size = %5d\n", info->parm_size);
19285 if (info->fixed_size)
19286 fprintf (stderr, "\tfixed_size = %5d\n", info->fixed_size);
19288 if (info->gp_size)
19289 fprintf (stderr, "\tgp_size = %5d\n", info->gp_size);
19291 if (info->spe_gp_size)
19292 fprintf (stderr, "\tspe_gp_size = %5d\n", info->spe_gp_size);
19294 if (info->fp_size)
19295 fprintf (stderr, "\tfp_size = %5d\n", info->fp_size);
19297 if (info->altivec_size)
19298 fprintf (stderr, "\taltivec_size = %5d\n", info->altivec_size);
19300 if (info->vrsave_size)
19301 fprintf (stderr, "\tvrsave_size = %5d\n", info->vrsave_size);
19303 if (info->altivec_padding_size)
19304 fprintf (stderr, "\taltivec_padding_size= %5d\n",
19305 info->altivec_padding_size);
19307 if (info->spe_padding_size)
19308 fprintf (stderr, "\tspe_padding_size = %5d\n",
19309 info->spe_padding_size);
19311 if (info->cr_size)
19312 fprintf (stderr, "\tcr_size = %5d\n", info->cr_size);
19314 if (info->save_size)
19315 fprintf (stderr, "\tsave_size = %5d\n", info->save_size);
19317 if (info->reg_size != 4)
19318 fprintf (stderr, "\treg_size = %5d\n", info->reg_size);
19320 fprintf (stderr, "\n");
19324 rs6000_return_addr (int count, rtx frame)
19326 /* Currently we don't optimize very well between prolog and body
19327 code and for PIC code the code can be actually quite bad, so
19328 don't try to be too clever here. */
19329 if (count != 0 || (DEFAULT_ABI != ABI_AIX && flag_pic))
19331 cfun->machine->ra_needs_full_frame = 1;
19333 return
19334 gen_rtx_MEM
19335 (Pmode,
19336 memory_address
19337 (Pmode,
19338 plus_constant (copy_to_reg
19339 (gen_rtx_MEM (Pmode,
19340 memory_address (Pmode, frame))),
19341 RETURN_ADDRESS_OFFSET)));
19344 cfun->machine->ra_need_lr = 1;
19345 return get_hard_reg_initial_val (Pmode, LR_REGNO);
19348 /* Say whether a function is a candidate for sibcall handling or not.
19349 We do not allow indirect calls to be optimized into sibling calls.
19350 Also, we can't do it if there are any vector parameters; there's
19351 nowhere to put the VRsave code so it works; note that functions with
19352 vector parameters are required to have a prototype, so the argument
19353 type info must be available here. (The tail recursion case can work
19354 with vector parameters, but there's no way to distinguish here.) */
19355 static bool
19356 rs6000_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED)
19358 tree type;
19359 if (decl)
19361 if (TARGET_ALTIVEC_VRSAVE)
19363 for (type = TYPE_ARG_TYPES (TREE_TYPE (decl));
19364 type; type = TREE_CHAIN (type))
19366 if (TREE_CODE (TREE_VALUE (type)) == VECTOR_TYPE)
19367 return false;
19370 if (DEFAULT_ABI == ABI_DARWIN
19371 || ((*targetm.binds_local_p) (decl)
19372 && (DEFAULT_ABI != ABI_AIX || !DECL_EXTERNAL (decl))))
19374 tree attr_list = TYPE_ATTRIBUTES (TREE_TYPE (decl));
19376 if (!lookup_attribute ("longcall", attr_list)
19377 || lookup_attribute ("shortcall", attr_list))
19378 return true;
19381 return false;
19384 /* NULL if INSN insn is valid within a low-overhead loop.
19385 Otherwise return why doloop cannot be applied.
19386 PowerPC uses the COUNT register for branch on table instructions. */
19388 static const char *
19389 rs6000_invalid_within_doloop (const_rtx insn)
19391 if (CALL_P (insn))
19392 return "Function call in the loop.";
19394 if (JUMP_P (insn)
19395 && (GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC
19396 || GET_CODE (PATTERN (insn)) == ADDR_VEC))
19397 return "Computed branch in the loop.";
19399 return NULL;
19402 static int
19403 rs6000_ra_ever_killed (void)
19405 rtx top;
19406 rtx reg;
19407 rtx insn;
19409 if (cfun->is_thunk)
19410 return 0;
19412 if (cfun->machine->lr_save_state)
19413 return cfun->machine->lr_save_state - 1;
19415 /* regs_ever_live has LR marked as used if any sibcalls are present,
19416 but this should not force saving and restoring in the
19417 pro/epilogue. Likewise, reg_set_between_p thinks a sibcall
19418 clobbers LR, so that is inappropriate. */
19420 /* Also, the prologue can generate a store into LR that
19421 doesn't really count, like this:
19423 move LR->R0
19424 bcl to set PIC register
19425 move LR->R31
19426 move R0->LR
19428 When we're called from the epilogue, we need to avoid counting
19429 this as a store. */
19431 push_topmost_sequence ();
19432 top = get_insns ();
19433 pop_topmost_sequence ();
19434 reg = gen_rtx_REG (Pmode, LR_REGNO);
19436 for (insn = NEXT_INSN (top); insn != NULL_RTX; insn = NEXT_INSN (insn))
19438 if (INSN_P (insn))
19440 if (CALL_P (insn))
19442 if (!SIBLING_CALL_P (insn))
19443 return 1;
19445 else if (find_regno_note (insn, REG_INC, LR_REGNO))
19446 return 1;
19447 else if (set_of (reg, insn) != NULL_RTX
19448 && !prologue_epilogue_contains (insn))
19449 return 1;
19452 return 0;
19455 /* Emit instructions needed to load the TOC register.
19456 This is only needed when TARGET_TOC, TARGET_MINIMAL_TOC, and there is
19457 a constant pool; or for SVR4 -fpic. */
19459 void
19460 rs6000_emit_load_toc_table (int fromprolog)
19462 rtx dest;
19463 dest = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
19465 if (TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI != ABI_AIX && flag_pic)
19467 char buf[30];
19468 rtx lab, tmp1, tmp2, got;
19470 lab = gen_label_rtx ();
19471 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (lab));
19472 lab = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
19473 if (flag_pic == 2)
19474 got = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
19475 else
19476 got = rs6000_got_sym ();
19477 tmp1 = tmp2 = dest;
19478 if (!fromprolog)
19480 tmp1 = gen_reg_rtx (Pmode);
19481 tmp2 = gen_reg_rtx (Pmode);
19483 emit_insn (gen_load_toc_v4_PIC_1 (lab));
19484 emit_move_insn (tmp1, gen_rtx_REG (Pmode, LR_REGNO));
19485 emit_insn (gen_load_toc_v4_PIC_3b (tmp2, tmp1, got, lab));
19486 emit_insn (gen_load_toc_v4_PIC_3c (dest, tmp2, got, lab));
19488 else if (TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 1)
19490 emit_insn (gen_load_toc_v4_pic_si ());
19491 emit_move_insn (dest, gen_rtx_REG (Pmode, LR_REGNO));
19493 else if (TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2)
19495 char buf[30];
19496 rtx temp0 = (fromprolog
19497 ? gen_rtx_REG (Pmode, 0)
19498 : gen_reg_rtx (Pmode));
19500 if (fromprolog)
19502 rtx symF, symL;
19504 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
19505 symF = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
19507 ASM_GENERATE_INTERNAL_LABEL (buf, "LCL", rs6000_pic_labelno);
19508 symL = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
19510 emit_insn (gen_load_toc_v4_PIC_1 (symF));
19511 emit_move_insn (dest, gen_rtx_REG (Pmode, LR_REGNO));
19512 emit_insn (gen_load_toc_v4_PIC_2 (temp0, dest, symL, symF));
19514 else
19516 rtx tocsym, lab;
19518 tocsym = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
19519 lab = gen_label_rtx ();
19520 emit_insn (gen_load_toc_v4_PIC_1b (tocsym, lab));
19521 emit_move_insn (dest, gen_rtx_REG (Pmode, LR_REGNO));
19522 emit_move_insn (temp0, gen_rtx_MEM (Pmode, dest));
19524 emit_insn (gen_addsi3 (dest, temp0, dest));
19526 else if (TARGET_ELF && !TARGET_AIX && flag_pic == 0 && TARGET_MINIMAL_TOC)
19528 /* This is for AIX code running in non-PIC ELF32. */
19529 char buf[30];
19530 rtx realsym;
19531 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
19532 realsym = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
19534 emit_insn (gen_elf_high (dest, realsym));
19535 emit_insn (gen_elf_low (dest, dest, realsym));
19537 else
19539 gcc_assert (DEFAULT_ABI == ABI_AIX);
19541 if (TARGET_32BIT)
19542 emit_insn (gen_load_toc_aix_si (dest));
19543 else
19544 emit_insn (gen_load_toc_aix_di (dest));
19548 /* Emit instructions to restore the link register after determining where
19549 its value has been stored. */
19551 void
19552 rs6000_emit_eh_reg_restore (rtx source, rtx scratch)
19554 rs6000_stack_t *info = rs6000_stack_info ();
19555 rtx operands[2];
19557 operands[0] = source;
19558 operands[1] = scratch;
19560 if (info->lr_save_p)
19562 rtx frame_rtx = stack_pointer_rtx;
19563 HOST_WIDE_INT sp_offset = 0;
19564 rtx tmp;
19566 if (frame_pointer_needed
19567 || cfun->calls_alloca
19568 || info->total_size > 32767)
19570 tmp = gen_frame_mem (Pmode, frame_rtx);
19571 emit_move_insn (operands[1], tmp);
19572 frame_rtx = operands[1];
19574 else if (info->push_p)
19575 sp_offset = info->total_size;
19577 tmp = plus_constant (frame_rtx, info->lr_save_offset + sp_offset);
19578 tmp = gen_frame_mem (Pmode, tmp);
19579 emit_move_insn (tmp, operands[0]);
19581 else
19582 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO), operands[0]);
19584 /* Freeze lr_save_p. We've just emitted rtl that depends on the
19585 state of lr_save_p so any change from here on would be a bug. In
19586 particular, stop rs6000_ra_ever_killed from considering the SET
19587 of lr we may have added just above. */
19588 cfun->machine->lr_save_state = info->lr_save_p + 1;
19591 static GTY(()) alias_set_type set = -1;
19593 alias_set_type
19594 get_TOC_alias_set (void)
19596 if (set == -1)
19597 set = new_alias_set ();
19598 return set;
19601 /* This returns nonzero if the current function uses the TOC. This is
19602 determined by the presence of (use (unspec ... UNSPEC_TOC)), which
19603 is generated by the ABI_V4 load_toc_* patterns. */
19604 #if TARGET_ELF
19605 static int
19606 uses_TOC (void)
19608 rtx insn;
19610 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
19611 if (INSN_P (insn))
19613 rtx pat = PATTERN (insn);
19614 int i;
19616 if (GET_CODE (pat) == PARALLEL)
19617 for (i = 0; i < XVECLEN (pat, 0); i++)
19619 rtx sub = XVECEXP (pat, 0, i);
19620 if (GET_CODE (sub) == USE)
19622 sub = XEXP (sub, 0);
19623 if (GET_CODE (sub) == UNSPEC
19624 && XINT (sub, 1) == UNSPEC_TOC)
19625 return 1;
19629 return 0;
19631 #endif
19634 create_TOC_reference (rtx symbol, rtx largetoc_reg)
19636 rtx tocrel, tocreg;
19638 if (TARGET_DEBUG_ADDR)
19640 if (GET_CODE (symbol) == SYMBOL_REF)
19641 fprintf (stderr, "\ncreate_TOC_reference, (symbol_ref %s)\n",
19642 XSTR (symbol, 0));
19643 else
19645 fprintf (stderr, "\ncreate_TOC_reference, code %s:\n",
19646 GET_RTX_NAME (GET_CODE (symbol)));
19647 debug_rtx (symbol);
19651 if (!can_create_pseudo_p ())
19652 df_set_regs_ever_live (TOC_REGISTER, true);
19654 tocrel = gen_rtx_CONST (Pmode,
19655 gen_rtx_UNSPEC (Pmode, gen_rtvec (1, symbol),
19656 UNSPEC_TOCREL));
19657 tocreg = gen_rtx_REG (Pmode, TOC_REGISTER);
19658 if (TARGET_CMODEL != CMODEL_SMALL)
19660 rtx hi = gen_rtx_PLUS (Pmode, tocreg, gen_rtx_HIGH (Pmode, tocrel));
19661 if (largetoc_reg != NULL)
19663 emit_move_insn (largetoc_reg, hi);
19664 hi = largetoc_reg;
19666 return gen_rtx_LO_SUM (Pmode, hi, copy_rtx (tocrel));
19668 else
19669 return gen_rtx_PLUS (Pmode, tocreg, tocrel);
19672 /* Issue assembly directives that create a reference to the given DWARF
19673 FRAME_TABLE_LABEL from the current function section. */
19674 void
19675 rs6000_aix_asm_output_dwarf_table_ref (char * frame_table_label)
19677 fprintf (asm_out_file, "\t.ref %s\n",
19678 TARGET_STRIP_NAME_ENCODING (frame_table_label));
19681 /* This ties together stack memory (MEM with an alias set of frame_alias_set)
19682 and the change to the stack pointer. */
19684 static void
19685 rs6000_emit_stack_tie (void)
19687 rtx mem = gen_frame_mem (BLKmode,
19688 gen_rtx_REG (Pmode, STACK_POINTER_REGNUM));
19690 emit_insn (gen_stack_tie (mem));
19693 /* Emit the correct code for allocating stack space, as insns.
19694 If COPY_REG, make sure a copy of the old frame is left there.
19695 The generated code may use hard register 0 as a temporary. */
19697 static void
19698 rs6000_emit_allocate_stack (HOST_WIDE_INT size, rtx copy_reg)
19700 rtx insn;
19701 rtx stack_reg = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
19702 rtx tmp_reg = gen_rtx_REG (Pmode, 0);
19703 rtx todec = gen_int_mode (-size, Pmode);
19704 rtx par, set, mem;
19706 if (INTVAL (todec) != -size)
19708 warning (0, "stack frame too large");
19709 emit_insn (gen_trap ());
19710 return;
19713 if (crtl->limit_stack)
19715 if (REG_P (stack_limit_rtx)
19716 && REGNO (stack_limit_rtx) > 1
19717 && REGNO (stack_limit_rtx) <= 31)
19719 emit_insn (gen_add3_insn (tmp_reg, stack_limit_rtx, GEN_INT (size)));
19720 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
19721 const0_rtx));
19723 else if (GET_CODE (stack_limit_rtx) == SYMBOL_REF
19724 && TARGET_32BIT
19725 && DEFAULT_ABI == ABI_V4)
19727 rtx toload = gen_rtx_CONST (VOIDmode,
19728 gen_rtx_PLUS (Pmode,
19729 stack_limit_rtx,
19730 GEN_INT (size)));
19732 emit_insn (gen_elf_high (tmp_reg, toload));
19733 emit_insn (gen_elf_low (tmp_reg, tmp_reg, toload));
19734 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
19735 const0_rtx));
19737 else
19738 warning (0, "stack limit expression is not supported");
19741 if (copy_reg)
19742 emit_move_insn (copy_reg, stack_reg);
19744 if (size > 32767)
19746 /* Need a note here so that try_split doesn't get confused. */
19747 if (get_last_insn () == NULL_RTX)
19748 emit_note (NOTE_INSN_DELETED);
19749 insn = emit_move_insn (tmp_reg, todec);
19750 try_split (PATTERN (insn), insn, 0);
19751 todec = tmp_reg;
19754 insn = emit_insn (TARGET_32BIT
19755 ? gen_movsi_update_stack (stack_reg, stack_reg,
19756 todec, stack_reg)
19757 : gen_movdi_di_update_stack (stack_reg, stack_reg,
19758 todec, stack_reg));
19759 /* Since we didn't use gen_frame_mem to generate the MEM, grab
19760 it now and set the alias set/attributes. The above gen_*_update
19761 calls will generate a PARALLEL with the MEM set being the first
19762 operation. */
19763 par = PATTERN (insn);
19764 gcc_assert (GET_CODE (par) == PARALLEL);
19765 set = XVECEXP (par, 0, 0);
19766 gcc_assert (GET_CODE (set) == SET);
19767 mem = SET_DEST (set);
19768 gcc_assert (MEM_P (mem));
19769 MEM_NOTRAP_P (mem) = 1;
19770 set_mem_alias_set (mem, get_frame_alias_set ());
19772 RTX_FRAME_RELATED_P (insn) = 1;
19773 add_reg_note (insn, REG_FRAME_RELATED_EXPR,
19774 gen_rtx_SET (VOIDmode, stack_reg,
19775 gen_rtx_PLUS (Pmode, stack_reg,
19776 GEN_INT (-size))));
19779 #define PROBE_INTERVAL (1 << STACK_CHECK_PROBE_INTERVAL_EXP)
19781 #if PROBE_INTERVAL > 32768
19782 #error Cannot use indexed addressing mode for stack probing
19783 #endif
19785 /* Emit code to probe a range of stack addresses from FIRST to FIRST+SIZE,
19786 inclusive. These are offsets from the current stack pointer. */
19788 static void
19789 rs6000_emit_probe_stack_range (HOST_WIDE_INT first, HOST_WIDE_INT size)
19791 /* See if we have a constant small number of probes to generate. If so,
19792 that's the easy case. */
19793 if (first + size <= 32768)
19795 HOST_WIDE_INT i;
19797 /* Probe at FIRST + N * PROBE_INTERVAL for values of N from 1 until
19798 it exceeds SIZE. If only one probe is needed, this will not
19799 generate any code. Then probe at FIRST + SIZE. */
19800 for (i = PROBE_INTERVAL; i < size; i += PROBE_INTERVAL)
19801 emit_stack_probe (plus_constant (stack_pointer_rtx, -(first + i)));
19803 emit_stack_probe (plus_constant (stack_pointer_rtx, -(first + size)));
19806 /* Otherwise, do the same as above, but in a loop. Note that we must be
19807 extra careful with variables wrapping around because we might be at
19808 the very top (or the very bottom) of the address space and we have
19809 to be able to handle this case properly; in particular, we use an
19810 equality test for the loop condition. */
19811 else
19813 HOST_WIDE_INT rounded_size;
19814 rtx r12 = gen_rtx_REG (Pmode, 12);
19815 rtx r0 = gen_rtx_REG (Pmode, 0);
19817 /* Sanity check for the addressing mode we're going to use. */
19818 gcc_assert (first <= 32768);
19820 /* Step 1: round SIZE to the previous multiple of the interval. */
19822 rounded_size = size & -PROBE_INTERVAL;
19825 /* Step 2: compute initial and final value of the loop counter. */
19827 /* TEST_ADDR = SP + FIRST. */
19828 emit_insn (gen_rtx_SET (VOIDmode, r12,
19829 plus_constant (stack_pointer_rtx, -first)));
19831 /* LAST_ADDR = SP + FIRST + ROUNDED_SIZE. */
19832 if (rounded_size > 32768)
19834 emit_move_insn (r0, GEN_INT (-rounded_size));
19835 emit_insn (gen_rtx_SET (VOIDmode, r0,
19836 gen_rtx_PLUS (Pmode, r12, r0)));
19838 else
19839 emit_insn (gen_rtx_SET (VOIDmode, r0,
19840 plus_constant (r12, -rounded_size)));
19843 /* Step 3: the loop
19845 while (TEST_ADDR != LAST_ADDR)
19847 TEST_ADDR = TEST_ADDR + PROBE_INTERVAL
19848 probe at TEST_ADDR
19851 probes at FIRST + N * PROBE_INTERVAL for values of N from 1
19852 until it is equal to ROUNDED_SIZE. */
19854 if (TARGET_64BIT)
19855 emit_insn (gen_probe_stack_rangedi (r12, r12, r0));
19856 else
19857 emit_insn (gen_probe_stack_rangesi (r12, r12, r0));
19860 /* Step 4: probe at FIRST + SIZE if we cannot assert at compile-time
19861 that SIZE is equal to ROUNDED_SIZE. */
19863 if (size != rounded_size)
19864 emit_stack_probe (plus_constant (r12, rounded_size - size));
19868 /* Probe a range of stack addresses from REG1 to REG2 inclusive. These are
19869 absolute addresses. */
19871 const char *
19872 output_probe_stack_range (rtx reg1, rtx reg2)
19874 static int labelno = 0;
19875 char loop_lab[32], end_lab[32];
19876 rtx xops[2];
19878 ASM_GENERATE_INTERNAL_LABEL (loop_lab, "LPSRL", labelno);
19879 ASM_GENERATE_INTERNAL_LABEL (end_lab, "LPSRE", labelno++);
19881 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, loop_lab);
19883 /* Jump to END_LAB if TEST_ADDR == LAST_ADDR. */
19884 xops[0] = reg1;
19885 xops[1] = reg2;
19886 if (TARGET_64BIT)
19887 output_asm_insn ("{cmp|cmpd} 0,%0,%1", xops);
19888 else
19889 output_asm_insn ("{cmp|cmpw} 0,%0,%1", xops);
19891 fputs ("\tbeq 0,", asm_out_file);
19892 assemble_name_raw (asm_out_file, end_lab);
19893 fputc ('\n', asm_out_file);
19895 /* TEST_ADDR = TEST_ADDR + PROBE_INTERVAL. */
19896 xops[1] = GEN_INT (-PROBE_INTERVAL);
19897 output_asm_insn ("{cal %0,%1(%0)|addi %0,%0,%1}", xops);
19899 /* Probe at TEST_ADDR and branch. */
19900 output_asm_insn ("{st|stw} 0,0(%0)", xops);
19901 fprintf (asm_out_file, "\tb ");
19902 assemble_name_raw (asm_out_file, loop_lab);
19903 fputc ('\n', asm_out_file);
19905 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, end_lab);
19907 return "";
19910 /* Add to 'insn' a note which is PATTERN (INSN) but with REG replaced
19911 with (plus:P (reg 1) VAL), and with REG2 replaced with RREG if REG2
19912 is not NULL. It would be nice if dwarf2out_frame_debug_expr could
19913 deduce these equivalences by itself so it wasn't necessary to hold
19914 its hand so much. */
19916 static void
19917 rs6000_frame_related (rtx insn, rtx reg, HOST_WIDE_INT val,
19918 rtx reg2, rtx rreg)
19920 rtx real, temp;
19922 /* copy_rtx will not make unique copies of registers, so we need to
19923 ensure we don't have unwanted sharing here. */
19924 if (reg == reg2)
19925 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
19927 if (reg == rreg)
19928 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
19930 real = copy_rtx (PATTERN (insn));
19932 if (reg2 != NULL_RTX)
19933 real = replace_rtx (real, reg2, rreg);
19935 real = replace_rtx (real, reg,
19936 gen_rtx_PLUS (Pmode, gen_rtx_REG (Pmode,
19937 STACK_POINTER_REGNUM),
19938 GEN_INT (val)));
19940 /* We expect that 'real' is either a SET or a PARALLEL containing
19941 SETs (and possibly other stuff). In a PARALLEL, all the SETs
19942 are important so they all have to be marked RTX_FRAME_RELATED_P. */
19944 if (GET_CODE (real) == SET)
19946 rtx set = real;
19948 temp = simplify_rtx (SET_SRC (set));
19949 if (temp)
19950 SET_SRC (set) = temp;
19951 temp = simplify_rtx (SET_DEST (set));
19952 if (temp)
19953 SET_DEST (set) = temp;
19954 if (GET_CODE (SET_DEST (set)) == MEM)
19956 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
19957 if (temp)
19958 XEXP (SET_DEST (set), 0) = temp;
19961 else
19963 int i;
19965 gcc_assert (GET_CODE (real) == PARALLEL);
19966 for (i = 0; i < XVECLEN (real, 0); i++)
19967 if (GET_CODE (XVECEXP (real, 0, i)) == SET)
19969 rtx set = XVECEXP (real, 0, i);
19971 temp = simplify_rtx (SET_SRC (set));
19972 if (temp)
19973 SET_SRC (set) = temp;
19974 temp = simplify_rtx (SET_DEST (set));
19975 if (temp)
19976 SET_DEST (set) = temp;
19977 if (GET_CODE (SET_DEST (set)) == MEM)
19979 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
19980 if (temp)
19981 XEXP (SET_DEST (set), 0) = temp;
19983 RTX_FRAME_RELATED_P (set) = 1;
19987 RTX_FRAME_RELATED_P (insn) = 1;
19988 add_reg_note (insn, REG_FRAME_RELATED_EXPR, real);
19991 /* Returns an insn that has a vrsave set operation with the
19992 appropriate CLOBBERs. */
19994 static rtx
19995 generate_set_vrsave (rtx reg, rs6000_stack_t *info, int epiloguep)
19997 int nclobs, i;
19998 rtx insn, clobs[TOTAL_ALTIVEC_REGS + 1];
19999 rtx vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
20001 clobs[0]
20002 = gen_rtx_SET (VOIDmode,
20003 vrsave,
20004 gen_rtx_UNSPEC_VOLATILE (SImode,
20005 gen_rtvec (2, reg, vrsave),
20006 UNSPECV_SET_VRSAVE));
20008 nclobs = 1;
20010 /* We need to clobber the registers in the mask so the scheduler
20011 does not move sets to VRSAVE before sets of AltiVec registers.
20013 However, if the function receives nonlocal gotos, reload will set
20014 all call saved registers live. We will end up with:
20016 (set (reg 999) (mem))
20017 (parallel [ (set (reg vrsave) (unspec blah))
20018 (clobber (reg 999))])
20020 The clobber will cause the store into reg 999 to be dead, and
20021 flow will attempt to delete an epilogue insn. In this case, we
20022 need an unspec use/set of the register. */
20024 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
20025 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
20027 if (!epiloguep || call_used_regs [i])
20028 clobs[nclobs++] = gen_rtx_CLOBBER (VOIDmode,
20029 gen_rtx_REG (V4SImode, i));
20030 else
20032 rtx reg = gen_rtx_REG (V4SImode, i);
20034 clobs[nclobs++]
20035 = gen_rtx_SET (VOIDmode,
20036 reg,
20037 gen_rtx_UNSPEC (V4SImode,
20038 gen_rtvec (1, reg), 27));
20042 insn = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (nclobs));
20044 for (i = 0; i < nclobs; ++i)
20045 XVECEXP (insn, 0, i) = clobs[i];
20047 return insn;
20050 /* Save a register into the frame, and emit RTX_FRAME_RELATED_P notes.
20051 Save REGNO into [FRAME_REG + OFFSET] in mode MODE. */
20053 static void
20054 emit_frame_save (rtx frame_reg, rtx frame_ptr, enum machine_mode mode,
20055 unsigned int regno, int offset, HOST_WIDE_INT total_size)
20057 rtx reg, offset_rtx, insn, mem, addr, int_rtx;
20058 rtx replacea, replaceb;
20060 int_rtx = GEN_INT (offset);
20062 /* Some cases that need register indexed addressing. */
20063 if ((TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
20064 || (TARGET_VSX && VSX_VECTOR_MODE (mode))
20065 || (TARGET_E500_DOUBLE && mode == DFmode)
20066 || (TARGET_SPE_ABI
20067 && SPE_VECTOR_MODE (mode)
20068 && !SPE_CONST_OFFSET_OK (offset)))
20070 /* Whomever calls us must make sure r11 is available in the
20071 flow path of instructions in the prologue. */
20072 offset_rtx = gen_rtx_REG (Pmode, 11);
20073 emit_move_insn (offset_rtx, int_rtx);
20075 replacea = offset_rtx;
20076 replaceb = int_rtx;
20078 else
20080 offset_rtx = int_rtx;
20081 replacea = NULL_RTX;
20082 replaceb = NULL_RTX;
20085 reg = gen_rtx_REG (mode, regno);
20086 addr = gen_rtx_PLUS (Pmode, frame_reg, offset_rtx);
20087 mem = gen_frame_mem (mode, addr);
20089 insn = emit_move_insn (mem, reg);
20091 rs6000_frame_related (insn, frame_ptr, total_size, replacea, replaceb);
20094 /* Emit an offset memory reference suitable for a frame store, while
20095 converting to a valid addressing mode. */
20097 static rtx
20098 gen_frame_mem_offset (enum machine_mode mode, rtx reg, int offset)
20100 rtx int_rtx, offset_rtx;
20102 int_rtx = GEN_INT (offset);
20104 if ((TARGET_SPE_ABI && SPE_VECTOR_MODE (mode))
20105 || (TARGET_E500_DOUBLE && mode == DFmode))
20107 offset_rtx = gen_rtx_REG (Pmode, FIXED_SCRATCH);
20108 emit_move_insn (offset_rtx, int_rtx);
20110 else
20111 offset_rtx = int_rtx;
20113 return gen_frame_mem (mode, gen_rtx_PLUS (Pmode, reg, offset_rtx));
20116 /* Look for user-defined global regs. We should not save and restore these,
20117 and cannot use stmw/lmw if there are any in its range. */
20119 static bool
20120 no_global_regs_above (int first, bool gpr)
20122 int i;
20123 int last = gpr ? 32 : 64;
20124 for (i = first; i < last; i++)
20125 if (global_regs[i])
20126 return false;
20127 return true;
20130 #ifndef TARGET_FIX_AND_CONTINUE
20131 #define TARGET_FIX_AND_CONTINUE 0
20132 #endif
20134 /* It's really GPR 13 and FPR 14, but we need the smaller of the two. */
20135 #define FIRST_SAVRES_REGISTER FIRST_SAVED_GP_REGNO
20136 #define LAST_SAVRES_REGISTER 31
20137 #define N_SAVRES_REGISTERS (LAST_SAVRES_REGISTER - FIRST_SAVRES_REGISTER + 1)
20139 static GTY(()) rtx savres_routine_syms[N_SAVRES_REGISTERS][8];
20141 /* Temporary holding space for an out-of-line register save/restore
20142 routine name. */
20143 static char savres_routine_name[30];
20145 /* Return the name for an out-of-line register save/restore routine.
20146 We are saving/restoring GPRs if GPR is true. */
20148 static char *
20149 rs6000_savres_routine_name (rs6000_stack_t *info, int regno,
20150 bool savep, bool gpr, bool lr)
20152 const char *prefix = "";
20153 const char *suffix = "";
20155 /* Different targets are supposed to define
20156 {SAVE,RESTORE}_FP_{PREFIX,SUFFIX} with the idea that the needed
20157 routine name could be defined with:
20159 sprintf (name, "%s%d%s", SAVE_FP_PREFIX, regno, SAVE_FP_SUFFIX)
20161 This is a nice idea in practice, but in reality, things are
20162 complicated in several ways:
20164 - ELF targets have save/restore routines for GPRs.
20166 - SPE targets use different prefixes for 32/64-bit registers, and
20167 neither of them fit neatly in the FOO_{PREFIX,SUFFIX} regimen.
20169 - PPC64 ELF targets have routines for save/restore of GPRs that
20170 differ in what they do with the link register, so having a set
20171 prefix doesn't work. (We only use one of the save routines at
20172 the moment, though.)
20174 - PPC32 elf targets have "exit" versions of the restore routines
20175 that restore the link register and can save some extra space.
20176 These require an extra suffix. (There are also "tail" versions
20177 of the restore routines and "GOT" versions of the save routines,
20178 but we don't generate those at present. Same problems apply,
20179 though.)
20181 We deal with all this by synthesizing our own prefix/suffix and
20182 using that for the simple sprintf call shown above. */
20183 if (TARGET_SPE)
20185 /* No floating point saves on the SPE. */
20186 gcc_assert (gpr);
20188 if (savep)
20189 prefix = info->spe_64bit_regs_used ? "_save64gpr_" : "_save32gpr_";
20190 else
20191 prefix = info->spe_64bit_regs_used ? "_rest64gpr_" : "_rest32gpr_";
20193 if (lr)
20194 suffix = "_x";
20196 else if (DEFAULT_ABI == ABI_V4)
20198 if (TARGET_64BIT)
20199 goto aix_names;
20201 if (gpr)
20202 prefix = savep ? "_savegpr_" : "_restgpr_";
20203 else
20204 prefix = savep ? "_savefpr_" : "_restfpr_";
20206 if (lr)
20207 suffix = "_x";
20209 else if (DEFAULT_ABI == ABI_AIX)
20211 #ifndef POWERPC_LINUX
20212 /* No out-of-line save/restore routines for GPRs on AIX. */
20213 gcc_assert (!TARGET_AIX || !gpr);
20214 #endif
20216 aix_names:
20217 if (gpr)
20218 prefix = (savep
20219 ? (lr ? "_savegpr0_" : "_savegpr1_")
20220 : (lr ? "_restgpr0_" : "_restgpr1_"));
20221 #ifdef POWERPC_LINUX
20222 else if (lr)
20223 prefix = (savep ? "_savefpr_" : "_restfpr_");
20224 #endif
20225 else
20227 prefix = savep ? SAVE_FP_PREFIX : RESTORE_FP_PREFIX;
20228 suffix = savep ? SAVE_FP_SUFFIX : RESTORE_FP_SUFFIX;
20231 else if (DEFAULT_ABI == ABI_DARWIN)
20232 sorry ("out-of-line save/restore routines not supported on Darwin");
20234 sprintf (savres_routine_name, "%s%d%s", prefix, regno, suffix);
20236 return savres_routine_name;
20239 /* Return an RTL SYMBOL_REF for an out-of-line register save/restore routine.
20240 We are saving/restoring GPRs if GPR is true. */
20242 static rtx
20243 rs6000_savres_routine_sym (rs6000_stack_t *info, bool savep,
20244 bool gpr, bool lr)
20246 int regno = gpr ? info->first_gp_reg_save : (info->first_fp_reg_save - 32);
20247 rtx sym;
20248 int select = ((savep ? 1 : 0) << 2
20249 | ((TARGET_SPE_ABI
20250 /* On the SPE, we never have any FPRs, but we do have
20251 32/64-bit versions of the routines. */
20252 ? (info->spe_64bit_regs_used ? 1 : 0)
20253 : (gpr ? 1 : 0)) << 1)
20254 | (lr ? 1: 0));
20256 /* Don't generate bogus routine names. */
20257 gcc_assert (FIRST_SAVRES_REGISTER <= regno
20258 && regno <= LAST_SAVRES_REGISTER);
20260 sym = savres_routine_syms[regno-FIRST_SAVRES_REGISTER][select];
20262 if (sym == NULL)
20264 char *name;
20266 name = rs6000_savres_routine_name (info, regno, savep, gpr, lr);
20268 sym = savres_routine_syms[regno-FIRST_SAVRES_REGISTER][select]
20269 = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (name));
20270 SYMBOL_REF_FLAGS (sym) |= SYMBOL_FLAG_FUNCTION;
20273 return sym;
20276 /* Emit a sequence of insns, including a stack tie if needed, for
20277 resetting the stack pointer. If SAVRES is true, then don't reset the
20278 stack pointer, but move the base of the frame into r11 for use by
20279 out-of-line register restore routines. */
20281 static rtx
20282 rs6000_emit_stack_reset (rs6000_stack_t *info,
20283 rtx sp_reg_rtx, rtx frame_reg_rtx,
20284 int sp_offset, bool savres)
20286 /* This blockage is needed so that sched doesn't decide to move
20287 the sp change before the register restores. */
20288 if (frame_reg_rtx != sp_reg_rtx
20289 || (TARGET_SPE_ABI
20290 && info->spe_64bit_regs_used != 0
20291 && info->first_gp_reg_save != 32))
20292 rs6000_emit_stack_tie ();
20294 if (frame_reg_rtx != sp_reg_rtx)
20296 if (sp_offset != 0)
20298 rtx dest_reg = savres ? gen_rtx_REG (Pmode, 11) : sp_reg_rtx;
20299 return emit_insn (gen_add3_insn (dest_reg, frame_reg_rtx,
20300 GEN_INT (sp_offset)));
20302 else if (!savres)
20303 return emit_move_insn (sp_reg_rtx, frame_reg_rtx);
20305 else if (sp_offset != 0)
20307 /* If we are restoring registers out-of-line, we will be using the
20308 "exit" variants of the restore routines, which will reset the
20309 stack for us. But we do need to point r11 into the right place
20310 for those routines. */
20311 rtx dest_reg = (savres
20312 ? gen_rtx_REG (Pmode, 11)
20313 : sp_reg_rtx);
20315 rtx insn = emit_insn (gen_add3_insn (dest_reg, sp_reg_rtx,
20316 GEN_INT (sp_offset)));
20317 if (!savres)
20318 return insn;
20320 return NULL_RTX;
20323 /* Construct a parallel rtx describing the effect of a call to an
20324 out-of-line register save/restore routine. */
20326 static rtx
20327 rs6000_make_savres_rtx (rs6000_stack_t *info,
20328 rtx frame_reg_rtx, int save_area_offset,
20329 enum machine_mode reg_mode,
20330 bool savep, bool gpr, bool lr)
20332 int i;
20333 int offset, start_reg, end_reg, n_regs;
20334 int reg_size = GET_MODE_SIZE (reg_mode);
20335 rtx sym;
20336 rtvec p;
20338 offset = 0;
20339 start_reg = (gpr
20340 ? info->first_gp_reg_save
20341 : info->first_fp_reg_save);
20342 end_reg = gpr ? 32 : 64;
20343 n_regs = end_reg - start_reg;
20344 p = rtvec_alloc ((lr ? 4 : 3) + n_regs);
20346 if (!savep && lr)
20347 RTVEC_ELT (p, offset++) = gen_rtx_RETURN (VOIDmode);
20349 RTVEC_ELT (p, offset++)
20350 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 65));
20352 sym = rs6000_savres_routine_sym (info, savep, gpr, lr);
20353 RTVEC_ELT (p, offset++) = gen_rtx_USE (VOIDmode, sym);
20354 RTVEC_ELT (p, offset++)
20355 = gen_rtx_USE (VOIDmode,
20356 gen_rtx_REG (Pmode, DEFAULT_ABI != ABI_AIX ? 11
20357 : gpr && !lr ? 12
20358 : 1));
20360 for (i = 0; i < end_reg - start_reg; i++)
20362 rtx addr, reg, mem;
20363 reg = gen_rtx_REG (reg_mode, start_reg + i);
20364 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20365 GEN_INT (save_area_offset + reg_size*i));
20366 mem = gen_frame_mem (reg_mode, addr);
20368 RTVEC_ELT (p, i + offset) = gen_rtx_SET (VOIDmode,
20369 savep ? mem : reg,
20370 savep ? reg : mem);
20373 if (savep && lr)
20375 rtx addr, reg, mem;
20376 reg = gen_rtx_REG (Pmode, 0);
20377 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20378 GEN_INT (info->lr_save_offset));
20379 mem = gen_frame_mem (Pmode, addr);
20380 RTVEC_ELT (p, i + offset) = gen_rtx_SET (VOIDmode, mem, reg);
20383 return gen_rtx_PARALLEL (VOIDmode, p);
20386 /* Determine whether the gp REG is really used. */
20388 static bool
20389 rs6000_reg_live_or_pic_offset_p (int reg)
20391 /* If the function calls eh_return, claim used all the registers that would
20392 be checked for liveness otherwise. This is required for the PIC offset
20393 register with -mminimal-toc on AIX, as it is advertised as "fixed" for
20394 register allocation purposes in this case. */
20396 return (((crtl->calls_eh_return || df_regs_ever_live_p (reg))
20397 && (!call_used_regs[reg]
20398 || (reg == RS6000_PIC_OFFSET_TABLE_REGNUM
20399 && !TARGET_SINGLE_PIC_BASE
20400 && TARGET_TOC && TARGET_MINIMAL_TOC)))
20401 || (reg == RS6000_PIC_OFFSET_TABLE_REGNUM
20402 && !TARGET_SINGLE_PIC_BASE
20403 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
20404 || (DEFAULT_ABI == ABI_DARWIN && flag_pic))));
20407 /* Emit function prologue as insns. */
20409 void
20410 rs6000_emit_prologue (void)
20412 rs6000_stack_t *info = rs6000_stack_info ();
20413 enum machine_mode reg_mode = Pmode;
20414 int reg_size = TARGET_32BIT ? 4 : 8;
20415 rtx sp_reg_rtx = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
20416 rtx frame_ptr_rtx = gen_rtx_REG (Pmode, 12);
20417 rtx frame_reg_rtx = sp_reg_rtx;
20418 rtx cr_save_rtx = NULL_RTX;
20419 rtx insn;
20420 int strategy;
20421 int saving_FPRs_inline;
20422 int saving_GPRs_inline;
20423 int using_store_multiple;
20424 int using_static_chain_p = (cfun->static_chain_decl != NULL_TREE
20425 && df_regs_ever_live_p (STATIC_CHAIN_REGNUM)
20426 && call_used_regs[STATIC_CHAIN_REGNUM]);
20427 HOST_WIDE_INT sp_offset = 0;
20429 if (flag_stack_usage)
20430 current_function_static_stack_size = info->total_size;
20432 if (flag_stack_check == STATIC_BUILTIN_STACK_CHECK && info->total_size)
20433 rs6000_emit_probe_stack_range (STACK_CHECK_PROTECT, info->total_size);
20435 if (TARGET_FIX_AND_CONTINUE)
20437 /* gdb on darwin arranges to forward a function from the old
20438 address by modifying the first 5 instructions of the function
20439 to branch to the overriding function. This is necessary to
20440 permit function pointers that point to the old function to
20441 actually forward to the new function. */
20442 emit_insn (gen_nop ());
20443 emit_insn (gen_nop ());
20444 emit_insn (gen_nop ());
20445 emit_insn (gen_nop ());
20446 emit_insn (gen_nop ());
20449 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
20451 reg_mode = V2SImode;
20452 reg_size = 8;
20455 strategy = info->savres_strategy;
20456 using_store_multiple = strategy & SAVRES_MULTIPLE;
20457 saving_FPRs_inline = strategy & SAVE_INLINE_FPRS;
20458 saving_GPRs_inline = strategy & SAVE_INLINE_GPRS;
20460 /* For V.4, update stack before we do any saving and set back pointer. */
20461 if (! WORLD_SAVE_P (info)
20462 && info->push_p
20463 && (DEFAULT_ABI == ABI_V4
20464 || crtl->calls_eh_return))
20466 bool need_r11 = (TARGET_SPE
20467 ? (!saving_GPRs_inline
20468 && info->spe_64bit_regs_used == 0)
20469 : (!saving_FPRs_inline || !saving_GPRs_inline));
20470 rtx copy_reg = need_r11 ? gen_rtx_REG (Pmode, 11) : NULL;
20472 if (info->total_size < 32767)
20473 sp_offset = info->total_size;
20474 else if (need_r11)
20475 frame_reg_rtx = copy_reg;
20476 else if (info->cr_save_p
20477 || info->lr_save_p
20478 || info->first_fp_reg_save < 64
20479 || info->first_gp_reg_save < 32
20480 || info->altivec_size != 0
20481 || info->vrsave_mask != 0
20482 || crtl->calls_eh_return)
20484 copy_reg = frame_ptr_rtx;
20485 frame_reg_rtx = copy_reg;
20487 else
20489 /* The prologue won't be saving any regs so there is no need
20490 to set up a frame register to access any frame save area.
20491 We also won't be using sp_offset anywhere below, but set
20492 the correct value anyway to protect against future
20493 changes to this function. */
20494 sp_offset = info->total_size;
20496 rs6000_emit_allocate_stack (info->total_size, copy_reg);
20497 if (frame_reg_rtx != sp_reg_rtx)
20498 rs6000_emit_stack_tie ();
20501 /* Handle world saves specially here. */
20502 if (WORLD_SAVE_P (info))
20504 int i, j, sz;
20505 rtx treg;
20506 rtvec p;
20507 rtx reg0;
20509 /* save_world expects lr in r0. */
20510 reg0 = gen_rtx_REG (Pmode, 0);
20511 if (info->lr_save_p)
20513 insn = emit_move_insn (reg0,
20514 gen_rtx_REG (Pmode, LR_REGNO));
20515 RTX_FRAME_RELATED_P (insn) = 1;
20518 /* The SAVE_WORLD and RESTORE_WORLD routines make a number of
20519 assumptions about the offsets of various bits of the stack
20520 frame. */
20521 gcc_assert (info->gp_save_offset == -220
20522 && info->fp_save_offset == -144
20523 && info->lr_save_offset == 8
20524 && info->cr_save_offset == 4
20525 && info->push_p
20526 && info->lr_save_p
20527 && (!crtl->calls_eh_return
20528 || info->ehrd_offset == -432)
20529 && info->vrsave_save_offset == -224
20530 && info->altivec_save_offset == -416);
20532 treg = gen_rtx_REG (SImode, 11);
20533 emit_move_insn (treg, GEN_INT (-info->total_size));
20535 /* SAVE_WORLD takes the caller's LR in R0 and the frame size
20536 in R11. It also clobbers R12, so beware! */
20538 /* Preserve CR2 for save_world prologues */
20539 sz = 5;
20540 sz += 32 - info->first_gp_reg_save;
20541 sz += 64 - info->first_fp_reg_save;
20542 sz += LAST_ALTIVEC_REGNO - info->first_altivec_reg_save + 1;
20543 p = rtvec_alloc (sz);
20544 j = 0;
20545 RTVEC_ELT (p, j++) = gen_rtx_CLOBBER (VOIDmode,
20546 gen_rtx_REG (SImode,
20547 LR_REGNO));
20548 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
20549 gen_rtx_SYMBOL_REF (Pmode,
20550 "*save_world"));
20551 /* We do floats first so that the instruction pattern matches
20552 properly. */
20553 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
20555 rtx reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20556 ? DFmode : SFmode),
20557 info->first_fp_reg_save + i);
20558 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20559 GEN_INT (info->fp_save_offset
20560 + sp_offset + 8 * i));
20561 rtx mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20562 ? DFmode : SFmode), addr);
20564 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
20566 for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++)
20568 rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i);
20569 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20570 GEN_INT (info->altivec_save_offset
20571 + sp_offset + 16 * i));
20572 rtx mem = gen_frame_mem (V4SImode, addr);
20574 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
20576 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20578 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20579 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20580 GEN_INT (info->gp_save_offset
20581 + sp_offset + reg_size * i));
20582 rtx mem = gen_frame_mem (reg_mode, addr);
20584 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
20588 /* CR register traditionally saved as CR2. */
20589 rtx reg = gen_rtx_REG (reg_mode, CR2_REGNO);
20590 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20591 GEN_INT (info->cr_save_offset
20592 + sp_offset));
20593 rtx mem = gen_frame_mem (reg_mode, addr);
20595 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
20597 /* Explain about use of R0. */
20598 if (info->lr_save_p)
20600 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20601 GEN_INT (info->lr_save_offset
20602 + sp_offset));
20603 rtx mem = gen_frame_mem (reg_mode, addr);
20605 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg0);
20607 /* Explain what happens to the stack pointer. */
20609 rtx newval = gen_rtx_PLUS (Pmode, sp_reg_rtx, treg);
20610 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, sp_reg_rtx, newval);
20613 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
20614 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20615 treg, GEN_INT (-info->total_size));
20616 sp_offset = info->total_size;
20619 /* If we use the link register, get it into r0. */
20620 if (!WORLD_SAVE_P (info) && info->lr_save_p)
20622 rtx addr, reg, mem;
20624 insn = emit_move_insn (gen_rtx_REG (Pmode, 0),
20625 gen_rtx_REG (Pmode, LR_REGNO));
20626 RTX_FRAME_RELATED_P (insn) = 1;
20628 if (!(strategy & (SAVE_NOINLINE_GPRS_SAVES_LR
20629 | SAVE_NOINLINE_FPRS_SAVES_LR)))
20631 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20632 GEN_INT (info->lr_save_offset + sp_offset));
20633 reg = gen_rtx_REG (Pmode, 0);
20634 mem = gen_rtx_MEM (Pmode, addr);
20635 /* This should not be of rs6000_sr_alias_set, because of
20636 __builtin_return_address. */
20638 insn = emit_move_insn (mem, reg);
20639 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20640 NULL_RTX, NULL_RTX);
20644 /* If we need to save CR, put it into r12 or r11. */
20645 if (!WORLD_SAVE_P (info) && info->cr_save_p && frame_reg_rtx != frame_ptr_rtx)
20647 rtx set;
20649 cr_save_rtx
20650 = gen_rtx_REG (SImode, DEFAULT_ABI == ABI_AIX && !saving_GPRs_inline
20651 ? 11 : 12);
20652 insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
20653 RTX_FRAME_RELATED_P (insn) = 1;
20654 /* Now, there's no way that dwarf2out_frame_debug_expr is going
20655 to understand '(unspec:SI [(reg:CC 68) ...] UNSPEC_MOVESI_FROM_CR)'.
20656 But that's OK. All we have to do is specify that _one_ condition
20657 code register is saved in this stack slot. The thrower's epilogue
20658 will then restore all the call-saved registers.
20659 We use CR2_REGNO (70) to be compatible with gcc-2.95 on Linux. */
20660 set = gen_rtx_SET (VOIDmode, cr_save_rtx,
20661 gen_rtx_REG (SImode, CR2_REGNO));
20662 add_reg_note (insn, REG_FRAME_RELATED_EXPR, set);
20665 /* Do any required saving of fpr's. If only one or two to save, do
20666 it ourselves. Otherwise, call function. */
20667 if (!WORLD_SAVE_P (info) && saving_FPRs_inline)
20669 int i;
20670 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
20671 if ((df_regs_ever_live_p (info->first_fp_reg_save+i)
20672 && ! call_used_regs[info->first_fp_reg_save+i]))
20673 emit_frame_save (frame_reg_rtx, frame_ptr_rtx,
20674 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20675 ? DFmode : SFmode,
20676 info->first_fp_reg_save + i,
20677 info->fp_save_offset + sp_offset + 8 * i,
20678 info->total_size);
20680 else if (!WORLD_SAVE_P (info) && info->first_fp_reg_save != 64)
20682 rtx par;
20684 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
20685 info->fp_save_offset + sp_offset,
20686 DFmode,
20687 /*savep=*/true, /*gpr=*/false,
20688 /*lr=*/(strategy
20689 & SAVE_NOINLINE_FPRS_SAVES_LR)
20690 != 0);
20691 insn = emit_insn (par);
20692 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20693 NULL_RTX, NULL_RTX);
20696 /* Save GPRs. This is done as a PARALLEL if we are using
20697 the store-multiple instructions. */
20698 if (!WORLD_SAVE_P (info)
20699 && TARGET_SPE_ABI
20700 && info->spe_64bit_regs_used != 0
20701 && info->first_gp_reg_save != 32)
20703 int i;
20704 rtx spe_save_area_ptr;
20706 /* Determine whether we can address all of the registers that need
20707 to be saved with an offset from the stack pointer that fits in
20708 the small const field for SPE memory instructions. */
20709 int spe_regs_addressable_via_sp
20710 = (SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset
20711 + (32 - info->first_gp_reg_save - 1) * reg_size)
20712 && saving_GPRs_inline);
20713 int spe_offset;
20715 if (spe_regs_addressable_via_sp)
20717 spe_save_area_ptr = frame_reg_rtx;
20718 spe_offset = info->spe_gp_save_offset + sp_offset;
20720 else
20722 /* Make r11 point to the start of the SPE save area. We need
20723 to be careful here if r11 is holding the static chain. If
20724 it is, then temporarily save it in r0. We would use r0 as
20725 our base register here, but using r0 as a base register in
20726 loads and stores means something different from what we
20727 would like. */
20728 int ool_adjust = (saving_GPRs_inline
20730 : (info->first_gp_reg_save
20731 - (FIRST_SAVRES_REGISTER+1))*8);
20732 HOST_WIDE_INT offset = (info->spe_gp_save_offset
20733 + sp_offset - ool_adjust);
20735 if (using_static_chain_p)
20737 rtx r0 = gen_rtx_REG (Pmode, 0);
20738 gcc_assert (info->first_gp_reg_save > 11);
20740 emit_move_insn (r0, gen_rtx_REG (Pmode, 11));
20743 spe_save_area_ptr = gen_rtx_REG (Pmode, 11);
20744 insn = emit_insn (gen_addsi3 (spe_save_area_ptr,
20745 frame_reg_rtx,
20746 GEN_INT (offset)));
20747 /* We need to make sure the move to r11 gets noted for
20748 properly outputting unwind information. */
20749 if (!saving_GPRs_inline)
20750 rs6000_frame_related (insn, frame_reg_rtx, offset,
20751 NULL_RTX, NULL_RTX);
20752 spe_offset = 0;
20755 if (saving_GPRs_inline)
20757 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20758 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
20760 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20761 rtx offset, addr, mem;
20763 /* We're doing all this to ensure that the offset fits into
20764 the immediate offset of 'evstdd'. */
20765 gcc_assert (SPE_CONST_OFFSET_OK (reg_size * i + spe_offset));
20767 offset = GEN_INT (reg_size * i + spe_offset);
20768 addr = gen_rtx_PLUS (Pmode, spe_save_area_ptr, offset);
20769 mem = gen_rtx_MEM (V2SImode, addr);
20771 insn = emit_move_insn (mem, reg);
20773 rs6000_frame_related (insn, spe_save_area_ptr,
20774 info->spe_gp_save_offset
20775 + sp_offset + reg_size * i,
20776 offset, const0_rtx);
20779 else
20781 rtx par;
20783 par = rs6000_make_savres_rtx (info, gen_rtx_REG (Pmode, 11),
20784 0, reg_mode,
20785 /*savep=*/true, /*gpr=*/true,
20786 /*lr=*/false);
20787 insn = emit_insn (par);
20788 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20789 NULL_RTX, NULL_RTX);
20793 /* Move the static chain pointer back. */
20794 if (using_static_chain_p && !spe_regs_addressable_via_sp)
20795 emit_move_insn (gen_rtx_REG (Pmode, 11), gen_rtx_REG (Pmode, 0));
20797 else if (!WORLD_SAVE_P (info) && !saving_GPRs_inline)
20799 rtx par;
20801 /* Need to adjust r11 (r12) if we saved any FPRs. */
20802 if (info->first_fp_reg_save != 64)
20804 rtx dest_reg = gen_rtx_REG (reg_mode, DEFAULT_ABI == ABI_AIX
20805 ? 12 : 11);
20806 rtx offset = GEN_INT (sp_offset
20807 + (-8 * (64-info->first_fp_reg_save)));
20808 emit_insn (gen_add3_insn (dest_reg, frame_reg_rtx, offset));
20811 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
20812 info->gp_save_offset + sp_offset,
20813 reg_mode,
20814 /*savep=*/true, /*gpr=*/true,
20815 /*lr=*/(strategy
20816 & SAVE_NOINLINE_GPRS_SAVES_LR)
20817 != 0);
20818 insn = emit_insn (par);
20819 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20820 NULL_RTX, NULL_RTX);
20822 else if (!WORLD_SAVE_P (info) && using_store_multiple)
20824 rtvec p;
20825 int i;
20826 p = rtvec_alloc (32 - info->first_gp_reg_save);
20827 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20829 rtx addr, reg, mem;
20830 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20831 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20832 GEN_INT (info->gp_save_offset
20833 + sp_offset
20834 + reg_size * i));
20835 mem = gen_frame_mem (reg_mode, addr);
20837 RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, mem, reg);
20839 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
20840 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20841 NULL_RTX, NULL_RTX);
20843 else if (!WORLD_SAVE_P (info))
20845 int i;
20846 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20847 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
20849 rtx addr, reg, mem;
20850 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20852 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20853 GEN_INT (info->gp_save_offset
20854 + sp_offset
20855 + reg_size * i));
20856 mem = gen_frame_mem (reg_mode, addr);
20858 insn = emit_move_insn (mem, reg);
20859 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20860 NULL_RTX, NULL_RTX);
20864 /* ??? There's no need to emit actual instructions here, but it's the
20865 easiest way to get the frame unwind information emitted. */
20866 if (crtl->calls_eh_return)
20868 unsigned int i, regno;
20870 for (i = 0; ; ++i)
20872 regno = EH_RETURN_DATA_REGNO (i);
20873 if (regno == INVALID_REGNUM)
20874 break;
20876 emit_frame_save (frame_reg_rtx, frame_ptr_rtx, reg_mode, regno,
20877 info->ehrd_offset + sp_offset
20878 + reg_size * (int) i,
20879 info->total_size);
20883 /* In AIX ABI we need to make sure r2 is really saved. */
20884 if (TARGET_AIX && crtl->calls_eh_return)
20886 rtx tmp_reg, tmp_reg_si, hi, lo, compare_result, toc_save_done, jump;
20887 long toc_restore_insn;
20889 gcc_assert (frame_reg_rtx == frame_ptr_rtx
20890 || frame_reg_rtx == sp_reg_rtx);
20891 tmp_reg = gen_rtx_REG (Pmode, 11);
20892 tmp_reg_si = gen_rtx_REG (SImode, 11);
20893 if (using_static_chain_p)
20894 emit_move_insn (gen_rtx_REG (Pmode, 0), tmp_reg);
20895 gcc_assert (saving_GPRs_inline && saving_FPRs_inline);
20896 emit_move_insn (tmp_reg, gen_rtx_REG (Pmode, LR_REGNO));
20897 /* Peek at instruction to which this function returns. If it's
20898 restoring r2, then we know we've already saved r2. We can't
20899 unconditionally save r2 because the value we have will already
20900 be updated if we arrived at this function via a plt call or
20901 toc adjusting stub. */
20902 emit_move_insn (tmp_reg_si, gen_rtx_MEM (SImode, tmp_reg));
20903 toc_restore_insn = TARGET_32BIT ? 0x80410014 : 0xE8410028;
20904 hi = gen_int_mode (toc_restore_insn & ~0xffff, SImode);
20905 emit_insn (gen_xorsi3 (tmp_reg_si, tmp_reg_si, hi));
20906 compare_result = gen_rtx_REG (CCUNSmode, CR0_REGNO);
20907 validate_condition_mode (EQ, CCUNSmode);
20908 lo = gen_int_mode (toc_restore_insn & 0xffff, SImode);
20909 emit_insn (gen_rtx_SET (VOIDmode, compare_result,
20910 gen_rtx_COMPARE (CCUNSmode, tmp_reg_si, lo)));
20911 toc_save_done = gen_label_rtx ();
20912 jump = gen_rtx_IF_THEN_ELSE (VOIDmode,
20913 gen_rtx_EQ (VOIDmode, compare_result,
20914 const0_rtx),
20915 gen_rtx_LABEL_REF (VOIDmode, toc_save_done),
20916 pc_rtx);
20917 jump = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, jump));
20918 JUMP_LABEL (jump) = toc_save_done;
20919 LABEL_NUSES (toc_save_done) += 1;
20921 emit_frame_save (frame_reg_rtx, frame_ptr_rtx, reg_mode, 2,
20922 sp_offset + 5 * reg_size, info->total_size);
20923 emit_label (toc_save_done);
20924 if (using_static_chain_p)
20925 emit_move_insn (tmp_reg, gen_rtx_REG (Pmode, 0));
20928 /* Save CR if we use any that must be preserved. */
20929 if (!WORLD_SAVE_P (info) && info->cr_save_p)
20931 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20932 GEN_INT (info->cr_save_offset + sp_offset));
20933 rtx mem = gen_frame_mem (SImode, addr);
20934 /* See the large comment above about why CR2_REGNO is used. */
20935 rtx magic_eh_cr_reg = gen_rtx_REG (SImode, CR2_REGNO);
20937 /* If r12 was used to hold the original sp, copy cr into r0 now
20938 that it's free. */
20939 if (REGNO (frame_reg_rtx) == 12)
20941 rtx set;
20943 cr_save_rtx = gen_rtx_REG (SImode, 0);
20944 insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
20945 RTX_FRAME_RELATED_P (insn) = 1;
20946 set = gen_rtx_SET (VOIDmode, cr_save_rtx, magic_eh_cr_reg);
20947 add_reg_note (insn, REG_FRAME_RELATED_EXPR, set);
20949 insn = emit_move_insn (mem, cr_save_rtx);
20951 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20952 NULL_RTX, NULL_RTX);
20955 /* Update stack and set back pointer unless this is V.4,
20956 for which it was done previously. */
20957 if (!WORLD_SAVE_P (info) && info->push_p
20958 && !(DEFAULT_ABI == ABI_V4 || crtl->calls_eh_return))
20960 rtx copy_reg = NULL;
20962 if (info->total_size < 32767)
20963 sp_offset = info->total_size;
20964 else if (info->altivec_size != 0
20965 || info->vrsave_mask != 0)
20967 copy_reg = frame_ptr_rtx;
20968 frame_reg_rtx = copy_reg;
20970 else
20971 sp_offset = info->total_size;
20972 rs6000_emit_allocate_stack (info->total_size, copy_reg);
20973 if (frame_reg_rtx != sp_reg_rtx)
20974 rs6000_emit_stack_tie ();
20977 /* Set frame pointer, if needed. */
20978 if (frame_pointer_needed)
20980 insn = emit_move_insn (gen_rtx_REG (Pmode, HARD_FRAME_POINTER_REGNUM),
20981 sp_reg_rtx);
20982 RTX_FRAME_RELATED_P (insn) = 1;
20985 /* Save AltiVec registers if needed. Save here because the red zone does
20986 not include AltiVec registers. */
20987 if (!WORLD_SAVE_P (info) && TARGET_ALTIVEC_ABI && info->altivec_size != 0)
20989 int i;
20991 /* There should be a non inline version of this, for when we
20992 are saving lots of vector registers. */
20993 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
20994 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
20996 rtx areg, savereg, mem;
20997 int offset;
20999 offset = info->altivec_save_offset + sp_offset
21000 + 16 * (i - info->first_altivec_reg_save);
21002 savereg = gen_rtx_REG (V4SImode, i);
21004 areg = gen_rtx_REG (Pmode, 0);
21005 emit_move_insn (areg, GEN_INT (offset));
21007 /* AltiVec addressing mode is [reg+reg]. */
21008 mem = gen_frame_mem (V4SImode,
21009 gen_rtx_PLUS (Pmode, frame_reg_rtx, areg));
21011 insn = emit_move_insn (mem, savereg);
21013 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
21014 areg, GEN_INT (offset));
21018 /* VRSAVE is a bit vector representing which AltiVec registers
21019 are used. The OS uses this to determine which vector
21020 registers to save on a context switch. We need to save
21021 VRSAVE on the stack frame, add whatever AltiVec registers we
21022 used in this function, and do the corresponding magic in the
21023 epilogue. */
21025 if (TARGET_ALTIVEC && TARGET_ALTIVEC_VRSAVE
21026 && info->vrsave_mask != 0)
21028 rtx reg, mem, vrsave;
21029 int offset;
21031 /* Get VRSAVE onto a GPR. Note that ABI_V4 might be using r12
21032 as frame_reg_rtx and r11 as the static chain pointer for
21033 nested functions. */
21034 reg = gen_rtx_REG (SImode, 0);
21035 vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
21036 if (TARGET_MACHO)
21037 emit_insn (gen_get_vrsave_internal (reg));
21038 else
21039 emit_insn (gen_rtx_SET (VOIDmode, reg, vrsave));
21041 if (!WORLD_SAVE_P (info))
21043 /* Save VRSAVE. */
21044 offset = info->vrsave_save_offset + sp_offset;
21045 mem = gen_frame_mem (SImode,
21046 gen_rtx_PLUS (Pmode, frame_reg_rtx,
21047 GEN_INT (offset)));
21048 insn = emit_move_insn (mem, reg);
21051 /* Include the registers in the mask. */
21052 emit_insn (gen_iorsi3 (reg, reg, GEN_INT ((int) info->vrsave_mask)));
21054 insn = emit_insn (generate_set_vrsave (reg, info, 0));
21057 if (TARGET_SINGLE_PIC_BASE)
21058 return; /* Do not set PIC register */
21060 /* If we are using RS6000_PIC_OFFSET_TABLE_REGNUM, we need to set it up. */
21061 if ((TARGET_TOC && TARGET_MINIMAL_TOC && get_pool_size () != 0)
21062 || (DEFAULT_ABI == ABI_V4
21063 && (flag_pic == 1 || (flag_pic && TARGET_SECURE_PLT))
21064 && df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM)))
21066 /* If emit_load_toc_table will use the link register, we need to save
21067 it. We use R12 for this purpose because emit_load_toc_table
21068 can use register 0. This allows us to use a plain 'blr' to return
21069 from the procedure more often. */
21070 int save_LR_around_toc_setup = (TARGET_ELF
21071 && DEFAULT_ABI != ABI_AIX
21072 && flag_pic
21073 && ! info->lr_save_p
21074 && EDGE_COUNT (EXIT_BLOCK_PTR->preds) > 0);
21075 if (save_LR_around_toc_setup)
21077 rtx lr = gen_rtx_REG (Pmode, LR_REGNO);
21079 insn = emit_move_insn (frame_ptr_rtx, lr);
21080 RTX_FRAME_RELATED_P (insn) = 1;
21082 rs6000_emit_load_toc_table (TRUE);
21084 insn = emit_move_insn (lr, frame_ptr_rtx);
21085 RTX_FRAME_RELATED_P (insn) = 1;
21087 else
21088 rs6000_emit_load_toc_table (TRUE);
21091 #if TARGET_MACHO
21092 if (DEFAULT_ABI == ABI_DARWIN
21093 && flag_pic && crtl->uses_pic_offset_table)
21095 rtx lr = gen_rtx_REG (Pmode, LR_REGNO);
21096 rtx src = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
21098 /* Save and restore LR locally around this call (in R0). */
21099 if (!info->lr_save_p)
21100 emit_move_insn (gen_rtx_REG (Pmode, 0), lr);
21102 emit_insn (gen_load_macho_picbase (src));
21104 emit_move_insn (gen_rtx_REG (Pmode,
21105 RS6000_PIC_OFFSET_TABLE_REGNUM),
21106 lr);
21108 if (!info->lr_save_p)
21109 emit_move_insn (lr, gen_rtx_REG (Pmode, 0));
21111 #endif
21114 /* Write function prologue. */
21116 static void
21117 rs6000_output_function_prologue (FILE *file,
21118 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
21120 rs6000_stack_t *info = rs6000_stack_info ();
21122 if (TARGET_DEBUG_STACK)
21123 debug_stack_info (info);
21125 /* Write .extern for any function we will call to save and restore
21126 fp values. */
21127 if (info->first_fp_reg_save < 64)
21129 char *name;
21130 int regno = info->first_fp_reg_save - 32;
21132 if ((info->savres_strategy & SAVE_INLINE_FPRS) == 0)
21134 name = rs6000_savres_routine_name (info, regno, /*savep=*/true,
21135 /*gpr=*/false, /*lr=*/false);
21136 fprintf (file, "\t.extern %s\n", name);
21138 if ((info->savres_strategy & REST_INLINE_FPRS) == 0)
21140 name = rs6000_savres_routine_name (info, regno, /*savep=*/false,
21141 /*gpr=*/false, /*lr=*/true);
21142 fprintf (file, "\t.extern %s\n", name);
21146 /* Write .extern for AIX common mode routines, if needed. */
21147 if (! TARGET_POWER && ! TARGET_POWERPC && ! common_mode_defined)
21149 fputs ("\t.extern __mulh\n", file);
21150 fputs ("\t.extern __mull\n", file);
21151 fputs ("\t.extern __divss\n", file);
21152 fputs ("\t.extern __divus\n", file);
21153 fputs ("\t.extern __quoss\n", file);
21154 fputs ("\t.extern __quous\n", file);
21155 common_mode_defined = 1;
21158 if (! HAVE_prologue)
21160 rtx prologue;
21162 start_sequence ();
21164 /* A NOTE_INSN_DELETED is supposed to be at the start and end of
21165 the "toplevel" insn chain. */
21166 emit_note (NOTE_INSN_DELETED);
21167 rs6000_emit_prologue ();
21168 emit_note (NOTE_INSN_DELETED);
21170 /* Expand INSN_ADDRESSES so final() doesn't crash. */
21172 rtx insn;
21173 unsigned addr = 0;
21174 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
21176 INSN_ADDRESSES_NEW (insn, addr);
21177 addr += 4;
21181 prologue = get_insns ();
21182 end_sequence ();
21184 if (TARGET_DEBUG_STACK)
21185 debug_rtx_list (prologue, 100);
21187 emit_insn_before_noloc (prologue, BB_HEAD (ENTRY_BLOCK_PTR->next_bb),
21188 ENTRY_BLOCK_PTR);
21191 rs6000_pic_labelno++;
21194 /* Non-zero if vmx regs are restored before the frame pop, zero if
21195 we restore after the pop when possible. */
21196 #define ALWAYS_RESTORE_ALTIVEC_BEFORE_POP 0
21198 /* Reload CR from REG. */
21200 static void
21201 rs6000_restore_saved_cr (rtx reg, int using_mfcr_multiple)
21203 int count = 0;
21204 int i;
21206 if (using_mfcr_multiple)
21208 for (i = 0; i < 8; i++)
21209 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
21210 count++;
21211 gcc_assert (count);
21214 if (using_mfcr_multiple && count > 1)
21216 rtvec p;
21217 int ndx;
21219 p = rtvec_alloc (count);
21221 ndx = 0;
21222 for (i = 0; i < 8; i++)
21223 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
21225 rtvec r = rtvec_alloc (2);
21226 RTVEC_ELT (r, 0) = reg;
21227 RTVEC_ELT (r, 1) = GEN_INT (1 << (7-i));
21228 RTVEC_ELT (p, ndx) =
21229 gen_rtx_SET (VOIDmode, gen_rtx_REG (CCmode, CR0_REGNO+i),
21230 gen_rtx_UNSPEC (CCmode, r, UNSPEC_MOVESI_TO_CR));
21231 ndx++;
21233 emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
21234 gcc_assert (ndx == count);
21236 else
21237 for (i = 0; i < 8; i++)
21238 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
21240 emit_insn (gen_movsi_to_cr_one (gen_rtx_REG (CCmode,
21241 CR0_REGNO+i),
21242 reg));
21246 /* Return true if OFFSET from stack pointer can be clobbered by signals.
21247 V.4 doesn't have any stack cushion, AIX ABIs have 220 or 288 bytes
21248 below stack pointer not cloberred by signals. */
21250 static inline bool
21251 offset_below_red_zone_p (HOST_WIDE_INT offset)
21253 return offset < (DEFAULT_ABI == ABI_V4
21255 : TARGET_32BIT ? -220 : -288);
21258 /* Emit function epilogue as insns. */
21260 void
21261 rs6000_emit_epilogue (int sibcall)
21263 rs6000_stack_t *info;
21264 int restoring_GPRs_inline;
21265 int restoring_FPRs_inline;
21266 int using_load_multiple;
21267 int using_mtcr_multiple;
21268 int use_backchain_to_restore_sp;
21269 int restore_lr;
21270 int strategy;
21271 int sp_offset = 0;
21272 rtx sp_reg_rtx = gen_rtx_REG (Pmode, 1);
21273 rtx frame_reg_rtx = sp_reg_rtx;
21274 rtx cfa_restores = NULL_RTX;
21275 rtx insn;
21276 rtx cr_save_reg = NULL_RTX;
21277 enum machine_mode reg_mode = Pmode;
21278 int reg_size = TARGET_32BIT ? 4 : 8;
21279 int i;
21281 info = rs6000_stack_info ();
21283 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
21285 reg_mode = V2SImode;
21286 reg_size = 8;
21289 strategy = info->savres_strategy;
21290 using_load_multiple = strategy & SAVRES_MULTIPLE;
21291 restoring_FPRs_inline = sibcall || (strategy & REST_INLINE_FPRS);
21292 restoring_GPRs_inline = sibcall || (strategy & REST_INLINE_GPRS);
21293 using_mtcr_multiple = (rs6000_cpu == PROCESSOR_PPC601
21294 || rs6000_cpu == PROCESSOR_PPC603
21295 || rs6000_cpu == PROCESSOR_PPC750
21296 || optimize_size);
21297 /* Restore via the backchain when we have a large frame, since this
21298 is more efficient than an addis, addi pair. The second condition
21299 here will not trigger at the moment; We don't actually need a
21300 frame pointer for alloca, but the generic parts of the compiler
21301 give us one anyway. */
21302 use_backchain_to_restore_sp = (info->total_size > 32767
21303 || info->total_size
21304 + (info->lr_save_p ? info->lr_save_offset : 0)
21305 > 32767
21306 || (cfun->calls_alloca
21307 && !frame_pointer_needed));
21308 restore_lr = (info->lr_save_p
21309 && (restoring_FPRs_inline
21310 || (strategy & REST_NOINLINE_FPRS_DOESNT_RESTORE_LR))
21311 && (restoring_GPRs_inline
21312 || info->first_fp_reg_save < 64));
21314 if (WORLD_SAVE_P (info))
21316 int i, j;
21317 char rname[30];
21318 const char *alloc_rname;
21319 rtvec p;
21321 /* eh_rest_world_r10 will return to the location saved in the LR
21322 stack slot (which is not likely to be our caller.)
21323 Input: R10 -- stack adjustment. Clobbers R0, R11, R12, R7, R8.
21324 rest_world is similar, except any R10 parameter is ignored.
21325 The exception-handling stuff that was here in 2.95 is no
21326 longer necessary. */
21328 p = rtvec_alloc (9
21330 + 32 - info->first_gp_reg_save
21331 + LAST_ALTIVEC_REGNO + 1 - info->first_altivec_reg_save
21332 + 63 + 1 - info->first_fp_reg_save);
21334 strcpy (rname, ((crtl->calls_eh_return) ?
21335 "*eh_rest_world_r10" : "*rest_world"));
21336 alloc_rname = ggc_strdup (rname);
21338 j = 0;
21339 RTVEC_ELT (p, j++) = gen_rtx_RETURN (VOIDmode);
21340 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
21341 gen_rtx_REG (Pmode,
21342 LR_REGNO));
21343 RTVEC_ELT (p, j++)
21344 = gen_rtx_USE (VOIDmode, gen_rtx_SYMBOL_REF (Pmode, alloc_rname));
21345 /* The instruction pattern requires a clobber here;
21346 it is shared with the restVEC helper. */
21347 RTVEC_ELT (p, j++)
21348 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 11));
21351 /* CR register traditionally saved as CR2. */
21352 rtx reg = gen_rtx_REG (reg_mode, CR2_REGNO);
21353 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21354 GEN_INT (info->cr_save_offset));
21355 rtx mem = gen_frame_mem (reg_mode, addr);
21357 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
21360 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
21362 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
21363 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21364 GEN_INT (info->gp_save_offset
21365 + reg_size * i));
21366 rtx mem = gen_frame_mem (reg_mode, addr);
21368 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
21370 for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++)
21372 rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i);
21373 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21374 GEN_INT (info->altivec_save_offset
21375 + 16 * i));
21376 rtx mem = gen_frame_mem (V4SImode, addr);
21378 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
21380 for (i = 0; info->first_fp_reg_save + i <= 63; i++)
21382 rtx reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
21383 ? DFmode : SFmode),
21384 info->first_fp_reg_save + i);
21385 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21386 GEN_INT (info->fp_save_offset
21387 + 8 * i));
21388 rtx mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
21389 ? DFmode : SFmode), addr);
21391 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
21393 RTVEC_ELT (p, j++)
21394 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 0));
21395 RTVEC_ELT (p, j++)
21396 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 12));
21397 RTVEC_ELT (p, j++)
21398 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 7));
21399 RTVEC_ELT (p, j++)
21400 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 8));
21401 RTVEC_ELT (p, j++)
21402 = gen_rtx_USE (VOIDmode, gen_rtx_REG (SImode, 10));
21403 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
21405 return;
21408 /* frame_reg_rtx + sp_offset points to the top of this stack frame. */
21409 if (info->push_p)
21410 sp_offset = info->total_size;
21412 /* Restore AltiVec registers if we must do so before adjusting the
21413 stack. */
21414 if (TARGET_ALTIVEC_ABI
21415 && info->altivec_size != 0
21416 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
21417 || (DEFAULT_ABI != ABI_V4
21418 && offset_below_red_zone_p (info->altivec_save_offset))))
21420 int i;
21422 if (use_backchain_to_restore_sp)
21424 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
21425 emit_move_insn (frame_reg_rtx,
21426 gen_rtx_MEM (Pmode, sp_reg_rtx));
21427 sp_offset = 0;
21429 else if (frame_pointer_needed)
21430 frame_reg_rtx = hard_frame_pointer_rtx;
21432 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
21433 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
21435 rtx addr, areg, mem, reg;
21437 areg = gen_rtx_REG (Pmode, 0);
21438 emit_move_insn
21439 (areg, GEN_INT (info->altivec_save_offset
21440 + sp_offset
21441 + 16 * (i - info->first_altivec_reg_save)));
21443 /* AltiVec addressing mode is [reg+reg]. */
21444 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
21445 mem = gen_frame_mem (V4SImode, addr);
21447 reg = gen_rtx_REG (V4SImode, i);
21448 emit_move_insn (reg, mem);
21449 if (offset_below_red_zone_p (info->altivec_save_offset
21450 + (i - info->first_altivec_reg_save)
21451 * 16))
21452 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21453 cfa_restores);
21457 /* Restore VRSAVE if we must do so before adjusting the stack. */
21458 if (TARGET_ALTIVEC
21459 && TARGET_ALTIVEC_VRSAVE
21460 && info->vrsave_mask != 0
21461 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
21462 || (DEFAULT_ABI != ABI_V4
21463 && offset_below_red_zone_p (info->vrsave_save_offset))))
21465 rtx addr, mem, reg;
21467 if (frame_reg_rtx == sp_reg_rtx)
21469 if (use_backchain_to_restore_sp)
21471 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
21472 emit_move_insn (frame_reg_rtx,
21473 gen_rtx_MEM (Pmode, sp_reg_rtx));
21474 sp_offset = 0;
21476 else if (frame_pointer_needed)
21477 frame_reg_rtx = hard_frame_pointer_rtx;
21480 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21481 GEN_INT (info->vrsave_save_offset + sp_offset));
21482 mem = gen_frame_mem (SImode, addr);
21483 reg = gen_rtx_REG (SImode, 12);
21484 emit_move_insn (reg, mem);
21486 emit_insn (generate_set_vrsave (reg, info, 1));
21489 insn = NULL_RTX;
21490 /* If we have a large stack frame, restore the old stack pointer
21491 using the backchain. */
21492 if (use_backchain_to_restore_sp)
21494 if (frame_reg_rtx == sp_reg_rtx)
21496 /* Under V.4, don't reset the stack pointer until after we're done
21497 loading the saved registers. */
21498 if (DEFAULT_ABI == ABI_V4)
21499 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
21501 insn = emit_move_insn (frame_reg_rtx,
21502 gen_rtx_MEM (Pmode, sp_reg_rtx));
21503 sp_offset = 0;
21505 else if (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
21506 && DEFAULT_ABI == ABI_V4)
21507 /* frame_reg_rtx has been set up by the altivec restore. */
21509 else
21511 insn = emit_move_insn (sp_reg_rtx, frame_reg_rtx);
21512 frame_reg_rtx = sp_reg_rtx;
21515 /* If we have a frame pointer, we can restore the old stack pointer
21516 from it. */
21517 else if (frame_pointer_needed)
21519 frame_reg_rtx = sp_reg_rtx;
21520 if (DEFAULT_ABI == ABI_V4)
21521 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
21522 /* Prevent reordering memory accesses against stack pointer restore. */
21523 else if (cfun->calls_alloca
21524 || offset_below_red_zone_p (-info->total_size))
21526 rtx mem1 = gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx);
21527 rtx mem2 = gen_rtx_MEM (BLKmode, sp_reg_rtx);
21528 MEM_NOTRAP_P (mem1) = 1;
21529 MEM_NOTRAP_P (mem2) = 1;
21530 emit_insn (gen_frame_tie (mem1, mem2));
21533 insn = emit_insn (gen_add3_insn (frame_reg_rtx, hard_frame_pointer_rtx,
21534 GEN_INT (info->total_size)));
21535 sp_offset = 0;
21537 else if (info->push_p
21538 && DEFAULT_ABI != ABI_V4
21539 && !crtl->calls_eh_return)
21541 /* Prevent reordering memory accesses against stack pointer restore. */
21542 if (cfun->calls_alloca
21543 || offset_below_red_zone_p (-info->total_size))
21545 rtx mem = gen_rtx_MEM (BLKmode, sp_reg_rtx);
21546 MEM_NOTRAP_P (mem) = 1;
21547 emit_insn (gen_stack_tie (mem));
21549 insn = emit_insn (gen_add3_insn (sp_reg_rtx, sp_reg_rtx,
21550 GEN_INT (info->total_size)));
21551 sp_offset = 0;
21553 if (insn && frame_reg_rtx == sp_reg_rtx)
21555 if (cfa_restores)
21557 REG_NOTES (insn) = cfa_restores;
21558 cfa_restores = NULL_RTX;
21560 add_reg_note (insn, REG_CFA_DEF_CFA, sp_reg_rtx);
21561 RTX_FRAME_RELATED_P (insn) = 1;
21564 /* Restore AltiVec registers if we have not done so already. */
21565 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
21566 && TARGET_ALTIVEC_ABI
21567 && info->altivec_size != 0
21568 && (DEFAULT_ABI == ABI_V4
21569 || !offset_below_red_zone_p (info->altivec_save_offset)))
21571 int i;
21573 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
21574 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
21576 rtx addr, areg, mem, reg;
21578 areg = gen_rtx_REG (Pmode, 0);
21579 emit_move_insn
21580 (areg, GEN_INT (info->altivec_save_offset
21581 + sp_offset
21582 + 16 * (i - info->first_altivec_reg_save)));
21584 /* AltiVec addressing mode is [reg+reg]. */
21585 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
21586 mem = gen_frame_mem (V4SImode, addr);
21588 reg = gen_rtx_REG (V4SImode, i);
21589 emit_move_insn (reg, mem);
21590 if (DEFAULT_ABI == ABI_V4)
21591 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21592 cfa_restores);
21596 /* Restore VRSAVE if we have not done so already. */
21597 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
21598 && TARGET_ALTIVEC
21599 && TARGET_ALTIVEC_VRSAVE
21600 && info->vrsave_mask != 0
21601 && (DEFAULT_ABI == ABI_V4
21602 || !offset_below_red_zone_p (info->vrsave_save_offset)))
21604 rtx addr, mem, reg;
21606 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21607 GEN_INT (info->vrsave_save_offset + sp_offset));
21608 mem = gen_frame_mem (SImode, addr);
21609 reg = gen_rtx_REG (SImode, 12);
21610 emit_move_insn (reg, mem);
21612 emit_insn (generate_set_vrsave (reg, info, 1));
21615 /* Get the old lr if we saved it. If we are restoring registers
21616 out-of-line, then the out-of-line routines can do this for us. */
21617 if (restore_lr && restoring_GPRs_inline)
21619 rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
21620 info->lr_save_offset + sp_offset);
21622 emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
21625 /* Get the old cr if we saved it. */
21626 if (info->cr_save_p)
21628 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21629 GEN_INT (info->cr_save_offset + sp_offset));
21630 rtx mem = gen_frame_mem (SImode, addr);
21632 cr_save_reg = gen_rtx_REG (SImode,
21633 DEFAULT_ABI == ABI_AIX
21634 && !restoring_GPRs_inline
21635 && info->first_fp_reg_save < 64
21636 ? 11 : 12);
21637 emit_move_insn (cr_save_reg, mem);
21640 /* Set LR here to try to overlap restores below. LR is always saved
21641 above incoming stack, so it never needs REG_CFA_RESTORE. */
21642 if (restore_lr && restoring_GPRs_inline)
21643 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO),
21644 gen_rtx_REG (Pmode, 0));
21646 /* Load exception handler data registers, if needed. */
21647 if (crtl->calls_eh_return)
21649 unsigned int i, regno;
21651 if (TARGET_AIX)
21653 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21654 GEN_INT (sp_offset + 5 * reg_size));
21655 rtx mem = gen_frame_mem (reg_mode, addr);
21657 emit_move_insn (gen_rtx_REG (reg_mode, 2), mem);
21660 for (i = 0; ; ++i)
21662 rtx mem;
21664 regno = EH_RETURN_DATA_REGNO (i);
21665 if (regno == INVALID_REGNUM)
21666 break;
21668 mem = gen_frame_mem_offset (reg_mode, frame_reg_rtx,
21669 info->ehrd_offset + sp_offset
21670 + reg_size * (int) i);
21672 emit_move_insn (gen_rtx_REG (reg_mode, regno), mem);
21676 /* Restore GPRs. This is done as a PARALLEL if we are using
21677 the load-multiple instructions. */
21678 if (TARGET_SPE_ABI
21679 && info->spe_64bit_regs_used != 0
21680 && info->first_gp_reg_save != 32)
21682 /* Determine whether we can address all of the registers that need
21683 to be saved with an offset from the stack pointer that fits in
21684 the small const field for SPE memory instructions. */
21685 int spe_regs_addressable_via_sp
21686 = (SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset
21687 + (32 - info->first_gp_reg_save - 1) * reg_size)
21688 && restoring_GPRs_inline);
21689 int spe_offset;
21691 if (spe_regs_addressable_via_sp)
21692 spe_offset = info->spe_gp_save_offset + sp_offset;
21693 else
21695 rtx old_frame_reg_rtx = frame_reg_rtx;
21696 /* Make r11 point to the start of the SPE save area. We worried about
21697 not clobbering it when we were saving registers in the prologue.
21698 There's no need to worry here because the static chain is passed
21699 anew to every function. */
21700 int ool_adjust = (restoring_GPRs_inline
21702 : (info->first_gp_reg_save
21703 - (FIRST_SAVRES_REGISTER+1))*8);
21705 if (frame_reg_rtx == sp_reg_rtx)
21706 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
21707 emit_insn (gen_addsi3 (frame_reg_rtx, old_frame_reg_rtx,
21708 GEN_INT (info->spe_gp_save_offset
21709 + sp_offset
21710 - ool_adjust)));
21711 /* Keep the invariant that frame_reg_rtx + sp_offset points
21712 at the top of the stack frame. */
21713 sp_offset = -info->spe_gp_save_offset;
21715 spe_offset = 0;
21718 if (restoring_GPRs_inline)
21720 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
21721 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
21723 rtx offset, addr, mem, reg;
21725 /* We're doing all this to ensure that the immediate offset
21726 fits into the immediate field of 'evldd'. */
21727 gcc_assert (SPE_CONST_OFFSET_OK (spe_offset + reg_size * i));
21729 offset = GEN_INT (spe_offset + reg_size * i);
21730 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, offset);
21731 mem = gen_rtx_MEM (V2SImode, addr);
21732 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
21734 insn = emit_move_insn (reg, mem);
21735 if (DEFAULT_ABI == ABI_V4)
21737 if (frame_pointer_needed
21738 && info->first_gp_reg_save + i
21739 == HARD_FRAME_POINTER_REGNUM)
21741 add_reg_note (insn, REG_CFA_DEF_CFA,
21742 plus_constant (frame_reg_rtx,
21743 sp_offset));
21744 RTX_FRAME_RELATED_P (insn) = 1;
21747 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21748 cfa_restores);
21752 else
21754 rtx par;
21756 par = rs6000_make_savres_rtx (info, gen_rtx_REG (Pmode, 11),
21757 0, reg_mode,
21758 /*savep=*/false, /*gpr=*/true,
21759 /*lr=*/true);
21760 emit_jump_insn (par);
21761 /* We don't want anybody else emitting things after we jumped
21762 back. */
21763 return;
21766 else if (!restoring_GPRs_inline)
21768 /* We are jumping to an out-of-line function. */
21769 bool can_use_exit = info->first_fp_reg_save == 64;
21770 rtx par;
21772 /* Emit stack reset code if we need it. */
21773 if (can_use_exit)
21774 rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx,
21775 sp_offset, can_use_exit);
21776 else
21778 emit_insn (gen_add3_insn (gen_rtx_REG (Pmode, DEFAULT_ABI == ABI_AIX
21779 ? 12 : 11),
21780 frame_reg_rtx,
21781 GEN_INT (sp_offset - info->fp_size)));
21782 if (REGNO (frame_reg_rtx) == 11)
21783 sp_offset += info->fp_size;
21786 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
21787 info->gp_save_offset, reg_mode,
21788 /*savep=*/false, /*gpr=*/true,
21789 /*lr=*/can_use_exit);
21791 if (can_use_exit)
21793 if (info->cr_save_p)
21795 rs6000_restore_saved_cr (cr_save_reg, using_mtcr_multiple);
21796 if (DEFAULT_ABI == ABI_V4)
21797 cfa_restores
21798 = alloc_reg_note (REG_CFA_RESTORE,
21799 gen_rtx_REG (SImode, CR2_REGNO),
21800 cfa_restores);
21803 emit_jump_insn (par);
21805 /* We don't want anybody else emitting things after we jumped
21806 back. */
21807 return;
21810 insn = emit_insn (par);
21811 if (DEFAULT_ABI == ABI_V4)
21813 if (frame_pointer_needed)
21815 add_reg_note (insn, REG_CFA_DEF_CFA,
21816 plus_constant (frame_reg_rtx, sp_offset));
21817 RTX_FRAME_RELATED_P (insn) = 1;
21820 for (i = info->first_gp_reg_save; i < 32; i++)
21821 cfa_restores
21822 = alloc_reg_note (REG_CFA_RESTORE,
21823 gen_rtx_REG (reg_mode, i), cfa_restores);
21826 else if (using_load_multiple)
21828 rtvec p;
21829 p = rtvec_alloc (32 - info->first_gp_reg_save);
21830 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
21832 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21833 GEN_INT (info->gp_save_offset
21834 + sp_offset
21835 + reg_size * i));
21836 rtx mem = gen_frame_mem (reg_mode, addr);
21837 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
21839 RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, reg, mem);
21840 if (DEFAULT_ABI == ABI_V4)
21841 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21842 cfa_restores);
21844 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
21845 if (DEFAULT_ABI == ABI_V4 && frame_pointer_needed)
21847 add_reg_note (insn, REG_CFA_DEF_CFA,
21848 plus_constant (frame_reg_rtx, sp_offset));
21849 RTX_FRAME_RELATED_P (insn) = 1;
21852 else
21854 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
21855 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
21857 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21858 GEN_INT (info->gp_save_offset
21859 + sp_offset
21860 + reg_size * i));
21861 rtx mem = gen_frame_mem (reg_mode, addr);
21862 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
21864 insn = emit_move_insn (reg, mem);
21865 if (DEFAULT_ABI == ABI_V4)
21867 if (frame_pointer_needed
21868 && info->first_gp_reg_save + i
21869 == HARD_FRAME_POINTER_REGNUM)
21871 add_reg_note (insn, REG_CFA_DEF_CFA,
21872 plus_constant (frame_reg_rtx, sp_offset));
21873 RTX_FRAME_RELATED_P (insn) = 1;
21876 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21877 cfa_restores);
21882 if (restore_lr && !restoring_GPRs_inline)
21884 rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
21885 info->lr_save_offset + sp_offset);
21887 emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
21888 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO),
21889 gen_rtx_REG (Pmode, 0));
21892 /* Restore fpr's if we need to do it without calling a function. */
21893 if (restoring_FPRs_inline)
21894 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
21895 if ((df_regs_ever_live_p (info->first_fp_reg_save+i)
21896 && ! call_used_regs[info->first_fp_reg_save+i]))
21898 rtx addr, mem, reg;
21899 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21900 GEN_INT (info->fp_save_offset
21901 + sp_offset
21902 + 8 * i));
21903 mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
21904 ? DFmode : SFmode), addr);
21905 reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
21906 ? DFmode : SFmode),
21907 info->first_fp_reg_save + i);
21909 emit_move_insn (reg, mem);
21910 if (DEFAULT_ABI == ABI_V4)
21911 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21912 cfa_restores);
21915 /* If we saved cr, restore it here. Just those that were used. */
21916 if (info->cr_save_p)
21918 rs6000_restore_saved_cr (cr_save_reg, using_mtcr_multiple);
21919 if (DEFAULT_ABI == ABI_V4)
21920 cfa_restores
21921 = alloc_reg_note (REG_CFA_RESTORE, gen_rtx_REG (SImode, CR2_REGNO),
21922 cfa_restores);
21925 /* If this is V.4, unwind the stack pointer after all of the loads
21926 have been done. */
21927 insn = rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx,
21928 sp_offset, !restoring_FPRs_inline);
21929 if (insn)
21931 if (cfa_restores)
21933 REG_NOTES (insn) = cfa_restores;
21934 cfa_restores = NULL_RTX;
21936 add_reg_note (insn, REG_CFA_DEF_CFA, sp_reg_rtx);
21937 RTX_FRAME_RELATED_P (insn) = 1;
21940 if (crtl->calls_eh_return)
21942 rtx sa = EH_RETURN_STACKADJ_RTX;
21943 emit_insn (gen_add3_insn (sp_reg_rtx, sp_reg_rtx, sa));
21946 if (!sibcall)
21948 rtvec p;
21949 bool lr = (strategy & REST_NOINLINE_FPRS_DOESNT_RESTORE_LR) == 0;
21950 if (! restoring_FPRs_inline)
21951 p = rtvec_alloc (4 + 64 - info->first_fp_reg_save);
21952 else
21953 p = rtvec_alloc (2);
21955 RTVEC_ELT (p, 0) = gen_rtx_RETURN (VOIDmode);
21956 RTVEC_ELT (p, 1) = ((restoring_FPRs_inline || !lr)
21957 ? gen_rtx_USE (VOIDmode, gen_rtx_REG (Pmode, 65))
21958 : gen_rtx_CLOBBER (VOIDmode,
21959 gen_rtx_REG (Pmode, 65)));
21961 /* If we have to restore more than two FP registers, branch to the
21962 restore function. It will return to our caller. */
21963 if (! restoring_FPRs_inline)
21965 int i;
21966 rtx sym;
21968 sym = rs6000_savres_routine_sym (info,
21969 /*savep=*/false,
21970 /*gpr=*/false,
21971 /*lr=*/lr);
21972 RTVEC_ELT (p, 2) = gen_rtx_USE (VOIDmode, sym);
21973 RTVEC_ELT (p, 3) = gen_rtx_USE (VOIDmode,
21974 gen_rtx_REG (Pmode,
21975 DEFAULT_ABI == ABI_AIX
21976 ? 1 : 11));
21977 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
21979 rtx addr, mem;
21980 addr = gen_rtx_PLUS (Pmode, sp_reg_rtx,
21981 GEN_INT (info->fp_save_offset + 8*i));
21982 mem = gen_frame_mem (DFmode, addr);
21984 RTVEC_ELT (p, i+4) =
21985 gen_rtx_SET (VOIDmode,
21986 gen_rtx_REG (DFmode, info->first_fp_reg_save + i),
21987 mem);
21991 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
21995 /* Write function epilogue. */
21997 static void
21998 rs6000_output_function_epilogue (FILE *file,
21999 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
22001 if (! HAVE_epilogue)
22003 rtx insn = get_last_insn ();
22004 /* If the last insn was a BARRIER, we don't have to write anything except
22005 the trace table. */
22006 if (GET_CODE (insn) == NOTE)
22007 insn = prev_nonnote_insn (insn);
22008 if (insn == 0 || GET_CODE (insn) != BARRIER)
22010 /* This is slightly ugly, but at least we don't have two
22011 copies of the epilogue-emitting code. */
22012 start_sequence ();
22014 /* A NOTE_INSN_DELETED is supposed to be at the start
22015 and end of the "toplevel" insn chain. */
22016 emit_note (NOTE_INSN_DELETED);
22017 rs6000_emit_epilogue (FALSE);
22018 emit_note (NOTE_INSN_DELETED);
22020 /* Expand INSN_ADDRESSES so final() doesn't crash. */
22022 rtx insn;
22023 unsigned addr = 0;
22024 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
22026 INSN_ADDRESSES_NEW (insn, addr);
22027 addr += 4;
22031 if (TARGET_DEBUG_STACK)
22032 debug_rtx_list (get_insns (), 100);
22033 final (get_insns (), file, FALSE);
22034 end_sequence ();
22038 #if TARGET_MACHO
22039 macho_branch_islands ();
22040 /* Mach-O doesn't support labels at the end of objects, so if
22041 it looks like we might want one, insert a NOP. */
22043 rtx insn = get_last_insn ();
22044 while (insn
22045 && NOTE_P (insn)
22046 && NOTE_KIND (insn) != NOTE_INSN_DELETED_LABEL)
22047 insn = PREV_INSN (insn);
22048 if (insn
22049 && (LABEL_P (insn)
22050 || (NOTE_P (insn)
22051 && NOTE_KIND (insn) == NOTE_INSN_DELETED_LABEL)))
22052 fputs ("\tnop\n", file);
22054 #endif
22056 /* Output a traceback table here. See /usr/include/sys/debug.h for info
22057 on its format.
22059 We don't output a traceback table if -finhibit-size-directive was
22060 used. The documentation for -finhibit-size-directive reads
22061 ``don't output a @code{.size} assembler directive, or anything
22062 else that would cause trouble if the function is split in the
22063 middle, and the two halves are placed at locations far apart in
22064 memory.'' The traceback table has this property, since it
22065 includes the offset from the start of the function to the
22066 traceback table itself.
22068 System V.4 Powerpc's (and the embedded ABI derived from it) use a
22069 different traceback table. */
22070 if (DEFAULT_ABI == ABI_AIX && ! flag_inhibit_size_directive
22071 && rs6000_traceback != traceback_none && !cfun->is_thunk)
22073 const char *fname = NULL;
22074 const char *language_string = lang_hooks.name;
22075 int fixed_parms = 0, float_parms = 0, parm_info = 0;
22076 int i;
22077 int optional_tbtab;
22078 rs6000_stack_t *info = rs6000_stack_info ();
22080 if (rs6000_traceback == traceback_full)
22081 optional_tbtab = 1;
22082 else if (rs6000_traceback == traceback_part)
22083 optional_tbtab = 0;
22084 else
22085 optional_tbtab = !optimize_size && !TARGET_ELF;
22087 if (optional_tbtab)
22089 fname = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0);
22090 while (*fname == '.') /* V.4 encodes . in the name */
22091 fname++;
22093 /* Need label immediately before tbtab, so we can compute
22094 its offset from the function start. */
22095 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
22096 ASM_OUTPUT_LABEL (file, fname);
22099 /* The .tbtab pseudo-op can only be used for the first eight
22100 expressions, since it can't handle the possibly variable
22101 length fields that follow. However, if you omit the optional
22102 fields, the assembler outputs zeros for all optional fields
22103 anyways, giving each variable length field is minimum length
22104 (as defined in sys/debug.h). Thus we can not use the .tbtab
22105 pseudo-op at all. */
22107 /* An all-zero word flags the start of the tbtab, for debuggers
22108 that have to find it by searching forward from the entry
22109 point or from the current pc. */
22110 fputs ("\t.long 0\n", file);
22112 /* Tbtab format type. Use format type 0. */
22113 fputs ("\t.byte 0,", file);
22115 /* Language type. Unfortunately, there does not seem to be any
22116 official way to discover the language being compiled, so we
22117 use language_string.
22118 C is 0. Fortran is 1. Pascal is 2. Ada is 3. C++ is 9.
22119 Java is 13. Objective-C is 14. Objective-C++ isn't assigned
22120 a number, so for now use 9. LTO and Go aren't assigned numbers
22121 either, so for now use 0. */
22122 if (! strcmp (language_string, "GNU C")
22123 || ! strcmp (language_string, "GNU GIMPLE")
22124 || ! strcmp (language_string, "GNU Go"))
22125 i = 0;
22126 else if (! strcmp (language_string, "GNU F77")
22127 || ! strcmp (language_string, "GNU Fortran"))
22128 i = 1;
22129 else if (! strcmp (language_string, "GNU Pascal"))
22130 i = 2;
22131 else if (! strcmp (language_string, "GNU Ada"))
22132 i = 3;
22133 else if (! strcmp (language_string, "GNU C++")
22134 || ! strcmp (language_string, "GNU Objective-C++"))
22135 i = 9;
22136 else if (! strcmp (language_string, "GNU Java"))
22137 i = 13;
22138 else if (! strcmp (language_string, "GNU Objective-C"))
22139 i = 14;
22140 else
22141 gcc_unreachable ();
22142 fprintf (file, "%d,", i);
22144 /* 8 single bit fields: global linkage (not set for C extern linkage,
22145 apparently a PL/I convention?), out-of-line epilogue/prologue, offset
22146 from start of procedure stored in tbtab, internal function, function
22147 has controlled storage, function has no toc, function uses fp,
22148 function logs/aborts fp operations. */
22149 /* Assume that fp operations are used if any fp reg must be saved. */
22150 fprintf (file, "%d,",
22151 (optional_tbtab << 5) | ((info->first_fp_reg_save != 64) << 1));
22153 /* 6 bitfields: function is interrupt handler, name present in
22154 proc table, function calls alloca, on condition directives
22155 (controls stack walks, 3 bits), saves condition reg, saves
22156 link reg. */
22157 /* The `function calls alloca' bit seems to be set whenever reg 31 is
22158 set up as a frame pointer, even when there is no alloca call. */
22159 fprintf (file, "%d,",
22160 ((optional_tbtab << 6)
22161 | ((optional_tbtab & frame_pointer_needed) << 5)
22162 | (info->cr_save_p << 1)
22163 | (info->lr_save_p)));
22165 /* 3 bitfields: saves backchain, fixup code, number of fpr saved
22166 (6 bits). */
22167 fprintf (file, "%d,",
22168 (info->push_p << 7) | (64 - info->first_fp_reg_save));
22170 /* 2 bitfields: spare bits (2 bits), number of gpr saved (6 bits). */
22171 fprintf (file, "%d,", (32 - first_reg_to_save ()));
22173 if (optional_tbtab)
22175 /* Compute the parameter info from the function decl argument
22176 list. */
22177 tree decl;
22178 int next_parm_info_bit = 31;
22180 for (decl = DECL_ARGUMENTS (current_function_decl);
22181 decl; decl = DECL_CHAIN (decl))
22183 rtx parameter = DECL_INCOMING_RTL (decl);
22184 enum machine_mode mode = GET_MODE (parameter);
22186 if (GET_CODE (parameter) == REG)
22188 if (SCALAR_FLOAT_MODE_P (mode))
22190 int bits;
22192 float_parms++;
22194 switch (mode)
22196 case SFmode:
22197 case SDmode:
22198 bits = 0x2;
22199 break;
22201 case DFmode:
22202 case DDmode:
22203 case TFmode:
22204 case TDmode:
22205 bits = 0x3;
22206 break;
22208 default:
22209 gcc_unreachable ();
22212 /* If only one bit will fit, don't or in this entry. */
22213 if (next_parm_info_bit > 0)
22214 parm_info |= (bits << (next_parm_info_bit - 1));
22215 next_parm_info_bit -= 2;
22217 else
22219 fixed_parms += ((GET_MODE_SIZE (mode)
22220 + (UNITS_PER_WORD - 1))
22221 / UNITS_PER_WORD);
22222 next_parm_info_bit -= 1;
22228 /* Number of fixed point parameters. */
22229 /* This is actually the number of words of fixed point parameters; thus
22230 an 8 byte struct counts as 2; and thus the maximum value is 8. */
22231 fprintf (file, "%d,", fixed_parms);
22233 /* 2 bitfields: number of floating point parameters (7 bits), parameters
22234 all on stack. */
22235 /* This is actually the number of fp registers that hold parameters;
22236 and thus the maximum value is 13. */
22237 /* Set parameters on stack bit if parameters are not in their original
22238 registers, regardless of whether they are on the stack? Xlc
22239 seems to set the bit when not optimizing. */
22240 fprintf (file, "%d\n", ((float_parms << 1) | (! optimize)));
22242 if (! optional_tbtab)
22243 return;
22245 /* Optional fields follow. Some are variable length. */
22247 /* Parameter types, left adjusted bit fields: 0 fixed, 10 single float,
22248 11 double float. */
22249 /* There is an entry for each parameter in a register, in the order that
22250 they occur in the parameter list. Any intervening arguments on the
22251 stack are ignored. If the list overflows a long (max possible length
22252 34 bits) then completely leave off all elements that don't fit. */
22253 /* Only emit this long if there was at least one parameter. */
22254 if (fixed_parms || float_parms)
22255 fprintf (file, "\t.long %d\n", parm_info);
22257 /* Offset from start of code to tb table. */
22258 fputs ("\t.long ", file);
22259 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
22260 RS6000_OUTPUT_BASENAME (file, fname);
22261 putc ('-', file);
22262 rs6000_output_function_entry (file, fname);
22263 putc ('\n', file);
22265 /* Interrupt handler mask. */
22266 /* Omit this long, since we never set the interrupt handler bit
22267 above. */
22269 /* Number of CTL (controlled storage) anchors. */
22270 /* Omit this long, since the has_ctl bit is never set above. */
22272 /* Displacement into stack of each CTL anchor. */
22273 /* Omit this list of longs, because there are no CTL anchors. */
22275 /* Length of function name. */
22276 if (*fname == '*')
22277 ++fname;
22278 fprintf (file, "\t.short %d\n", (int) strlen (fname));
22280 /* Function name. */
22281 assemble_string (fname, strlen (fname));
22283 /* Register for alloca automatic storage; this is always reg 31.
22284 Only emit this if the alloca bit was set above. */
22285 if (frame_pointer_needed)
22286 fputs ("\t.byte 31\n", file);
22288 fputs ("\t.align 2\n", file);
22292 /* A C compound statement that outputs the assembler code for a thunk
22293 function, used to implement C++ virtual function calls with
22294 multiple inheritance. The thunk acts as a wrapper around a virtual
22295 function, adjusting the implicit object parameter before handing
22296 control off to the real function.
22298 First, emit code to add the integer DELTA to the location that
22299 contains the incoming first argument. Assume that this argument
22300 contains a pointer, and is the one used to pass the `this' pointer
22301 in C++. This is the incoming argument *before* the function
22302 prologue, e.g. `%o0' on a sparc. The addition must preserve the
22303 values of all other incoming arguments.
22305 After the addition, emit code to jump to FUNCTION, which is a
22306 `FUNCTION_DECL'. This is a direct pure jump, not a call, and does
22307 not touch the return address. Hence returning from FUNCTION will
22308 return to whoever called the current `thunk'.
22310 The effect must be as if FUNCTION had been called directly with the
22311 adjusted first argument. This macro is responsible for emitting
22312 all of the code for a thunk function; output_function_prologue()
22313 and output_function_epilogue() are not invoked.
22315 The THUNK_FNDECL is redundant. (DELTA and FUNCTION have already
22316 been extracted from it.) It might possibly be useful on some
22317 targets, but probably not.
22319 If you do not define this macro, the target-independent code in the
22320 C++ frontend will generate a less efficient heavyweight thunk that
22321 calls FUNCTION instead of jumping to it. The generic approach does
22322 not support varargs. */
22324 static void
22325 rs6000_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
22326 HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
22327 tree function)
22329 rtx this_rtx, insn, funexp;
22331 reload_completed = 1;
22332 epilogue_completed = 1;
22334 /* Mark the end of the (empty) prologue. */
22335 emit_note (NOTE_INSN_PROLOGUE_END);
22337 /* Find the "this" pointer. If the function returns a structure,
22338 the structure return pointer is in r3. */
22339 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function))
22340 this_rtx = gen_rtx_REG (Pmode, 4);
22341 else
22342 this_rtx = gen_rtx_REG (Pmode, 3);
22344 /* Apply the constant offset, if required. */
22345 if (delta)
22346 emit_insn (gen_add3_insn (this_rtx, this_rtx, GEN_INT (delta)));
22348 /* Apply the offset from the vtable, if required. */
22349 if (vcall_offset)
22351 rtx vcall_offset_rtx = GEN_INT (vcall_offset);
22352 rtx tmp = gen_rtx_REG (Pmode, 12);
22354 emit_move_insn (tmp, gen_rtx_MEM (Pmode, this_rtx));
22355 if (((unsigned HOST_WIDE_INT) vcall_offset) + 0x8000 >= 0x10000)
22357 emit_insn (gen_add3_insn (tmp, tmp, vcall_offset_rtx));
22358 emit_move_insn (tmp, gen_rtx_MEM (Pmode, tmp));
22360 else
22362 rtx loc = gen_rtx_PLUS (Pmode, tmp, vcall_offset_rtx);
22364 emit_move_insn (tmp, gen_rtx_MEM (Pmode, loc));
22366 emit_insn (gen_add3_insn (this_rtx, this_rtx, tmp));
22369 /* Generate a tail call to the target function. */
22370 if (!TREE_USED (function))
22372 assemble_external (function);
22373 TREE_USED (function) = 1;
22375 funexp = XEXP (DECL_RTL (function), 0);
22376 funexp = gen_rtx_MEM (FUNCTION_MODE, funexp);
22378 #if TARGET_MACHO
22379 if (MACHOPIC_INDIRECT)
22380 funexp = machopic_indirect_call_target (funexp);
22381 #endif
22383 /* gen_sibcall expects reload to convert scratch pseudo to LR so we must
22384 generate sibcall RTL explicitly. */
22385 insn = emit_call_insn (
22386 gen_rtx_PARALLEL (VOIDmode,
22387 gen_rtvec (4,
22388 gen_rtx_CALL (VOIDmode,
22389 funexp, const0_rtx),
22390 gen_rtx_USE (VOIDmode, const0_rtx),
22391 gen_rtx_USE (VOIDmode,
22392 gen_rtx_REG (SImode,
22393 LR_REGNO)),
22394 gen_rtx_RETURN (VOIDmode))));
22395 SIBLING_CALL_P (insn) = 1;
22396 emit_barrier ();
22398 /* Run just enough of rest_of_compilation to get the insns emitted.
22399 There's not really enough bulk here to make other passes such as
22400 instruction scheduling worth while. Note that use_thunk calls
22401 assemble_start_function and assemble_end_function. */
22402 insn = get_insns ();
22403 insn_locators_alloc ();
22404 shorten_branches (insn);
22405 final_start_function (insn, file, 1);
22406 final (insn, file, 1);
22407 final_end_function ();
22409 reload_completed = 0;
22410 epilogue_completed = 0;
22413 /* A quick summary of the various types of 'constant-pool tables'
22414 under PowerPC:
22416 Target Flags Name One table per
22417 AIX (none) AIX TOC object file
22418 AIX -mfull-toc AIX TOC object file
22419 AIX -mminimal-toc AIX minimal TOC translation unit
22420 SVR4/EABI (none) SVR4 SDATA object file
22421 SVR4/EABI -fpic SVR4 pic object file
22422 SVR4/EABI -fPIC SVR4 PIC translation unit
22423 SVR4/EABI -mrelocatable EABI TOC function
22424 SVR4/EABI -maix AIX TOC object file
22425 SVR4/EABI -maix -mminimal-toc
22426 AIX minimal TOC translation unit
22428 Name Reg. Set by entries contains:
22429 made by addrs? fp? sum?
22431 AIX TOC 2 crt0 as Y option option
22432 AIX minimal TOC 30 prolog gcc Y Y option
22433 SVR4 SDATA 13 crt0 gcc N Y N
22434 SVR4 pic 30 prolog ld Y not yet N
22435 SVR4 PIC 30 prolog gcc Y option option
22436 EABI TOC 30 prolog gcc Y option option
22440 /* Hash functions for the hash table. */
22442 static unsigned
22443 rs6000_hash_constant (rtx k)
22445 enum rtx_code code = GET_CODE (k);
22446 enum machine_mode mode = GET_MODE (k);
22447 unsigned result = (code << 3) ^ mode;
22448 const char *format;
22449 int flen, fidx;
22451 format = GET_RTX_FORMAT (code);
22452 flen = strlen (format);
22453 fidx = 0;
22455 switch (code)
22457 case LABEL_REF:
22458 return result * 1231 + (unsigned) INSN_UID (XEXP (k, 0));
22460 case CONST_DOUBLE:
22461 if (mode != VOIDmode)
22462 return real_hash (CONST_DOUBLE_REAL_VALUE (k)) * result;
22463 flen = 2;
22464 break;
22466 case CODE_LABEL:
22467 fidx = 3;
22468 break;
22470 default:
22471 break;
22474 for (; fidx < flen; fidx++)
22475 switch (format[fidx])
22477 case 's':
22479 unsigned i, len;
22480 const char *str = XSTR (k, fidx);
22481 len = strlen (str);
22482 result = result * 613 + len;
22483 for (i = 0; i < len; i++)
22484 result = result * 613 + (unsigned) str[i];
22485 break;
22487 case 'u':
22488 case 'e':
22489 result = result * 1231 + rs6000_hash_constant (XEXP (k, fidx));
22490 break;
22491 case 'i':
22492 case 'n':
22493 result = result * 613 + (unsigned) XINT (k, fidx);
22494 break;
22495 case 'w':
22496 if (sizeof (unsigned) >= sizeof (HOST_WIDE_INT))
22497 result = result * 613 + (unsigned) XWINT (k, fidx);
22498 else
22500 size_t i;
22501 for (i = 0; i < sizeof (HOST_WIDE_INT) / sizeof (unsigned); i++)
22502 result = result * 613 + (unsigned) (XWINT (k, fidx)
22503 >> CHAR_BIT * i);
22505 break;
22506 case '0':
22507 break;
22508 default:
22509 gcc_unreachable ();
22512 return result;
22515 static unsigned
22516 toc_hash_function (const void *hash_entry)
22518 const struct toc_hash_struct *thc =
22519 (const struct toc_hash_struct *) hash_entry;
22520 return rs6000_hash_constant (thc->key) ^ thc->key_mode;
22523 /* Compare H1 and H2 for equivalence. */
22525 static int
22526 toc_hash_eq (const void *h1, const void *h2)
22528 rtx r1 = ((const struct toc_hash_struct *) h1)->key;
22529 rtx r2 = ((const struct toc_hash_struct *) h2)->key;
22531 if (((const struct toc_hash_struct *) h1)->key_mode
22532 != ((const struct toc_hash_struct *) h2)->key_mode)
22533 return 0;
22535 return rtx_equal_p (r1, r2);
22538 /* These are the names given by the C++ front-end to vtables, and
22539 vtable-like objects. Ideally, this logic should not be here;
22540 instead, there should be some programmatic way of inquiring as
22541 to whether or not an object is a vtable. */
22543 #define VTABLE_NAME_P(NAME) \
22544 (strncmp ("_vt.", name, strlen ("_vt.")) == 0 \
22545 || strncmp ("_ZTV", name, strlen ("_ZTV")) == 0 \
22546 || strncmp ("_ZTT", name, strlen ("_ZTT")) == 0 \
22547 || strncmp ("_ZTI", name, strlen ("_ZTI")) == 0 \
22548 || strncmp ("_ZTC", name, strlen ("_ZTC")) == 0)
22550 #ifdef NO_DOLLAR_IN_LABEL
22551 /* Return a GGC-allocated character string translating dollar signs in
22552 input NAME to underscores. Used by XCOFF ASM_OUTPUT_LABELREF. */
22554 const char *
22555 rs6000_xcoff_strip_dollar (const char *name)
22557 char *strip, *p;
22558 int len;
22560 p = strchr (name, '$');
22562 if (p == 0 || p == name)
22563 return name;
22565 len = strlen (name);
22566 strip = (char *) alloca (len + 1);
22567 strcpy (strip, name);
22568 p = strchr (strip, '$');
22569 while (p)
22571 *p = '_';
22572 p = strchr (p + 1, '$');
22575 return ggc_alloc_string (strip, len);
22577 #endif
22579 void
22580 rs6000_output_symbol_ref (FILE *file, rtx x)
22582 /* Currently C++ toc references to vtables can be emitted before it
22583 is decided whether the vtable is public or private. If this is
22584 the case, then the linker will eventually complain that there is
22585 a reference to an unknown section. Thus, for vtables only,
22586 we emit the TOC reference to reference the symbol and not the
22587 section. */
22588 const char *name = XSTR (x, 0);
22590 if (VTABLE_NAME_P (name))
22592 RS6000_OUTPUT_BASENAME (file, name);
22594 else
22595 assemble_name (file, name);
22598 /* Output a TOC entry. We derive the entry name from what is being
22599 written. */
22601 void
22602 output_toc (FILE *file, rtx x, int labelno, enum machine_mode mode)
22604 char buf[256];
22605 const char *name = buf;
22606 rtx base = x;
22607 HOST_WIDE_INT offset = 0;
22609 gcc_assert (!TARGET_NO_TOC);
22611 /* When the linker won't eliminate them, don't output duplicate
22612 TOC entries (this happens on AIX if there is any kind of TOC,
22613 and on SVR4 under -fPIC or -mrelocatable). Don't do this for
22614 CODE_LABELs. */
22615 if (TARGET_TOC && GET_CODE (x) != LABEL_REF)
22617 struct toc_hash_struct *h;
22618 void * * found;
22620 /* Create toc_hash_table. This can't be done at TARGET_OPTION_OVERRIDE
22621 time because GGC is not initialized at that point. */
22622 if (toc_hash_table == NULL)
22623 toc_hash_table = htab_create_ggc (1021, toc_hash_function,
22624 toc_hash_eq, NULL);
22626 h = ggc_alloc_toc_hash_struct ();
22627 h->key = x;
22628 h->key_mode = mode;
22629 h->labelno = labelno;
22631 found = htab_find_slot (toc_hash_table, h, INSERT);
22632 if (*found == NULL)
22633 *found = h;
22634 else /* This is indeed a duplicate.
22635 Set this label equal to that label. */
22637 fputs ("\t.set ", file);
22638 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
22639 fprintf (file, "%d,", labelno);
22640 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
22641 fprintf (file, "%d\n", ((*(const struct toc_hash_struct **)
22642 found)->labelno));
22643 return;
22647 /* If we're going to put a double constant in the TOC, make sure it's
22648 aligned properly when strict alignment is on. */
22649 if (GET_CODE (x) == CONST_DOUBLE
22650 && STRICT_ALIGNMENT
22651 && GET_MODE_BITSIZE (mode) >= 64
22652 && ! (TARGET_NO_FP_IN_TOC && ! TARGET_MINIMAL_TOC)) {
22653 ASM_OUTPUT_ALIGN (file, 3);
22656 (*targetm.asm_out.internal_label) (file, "LC", labelno);
22658 /* Handle FP constants specially. Note that if we have a minimal
22659 TOC, things we put here aren't actually in the TOC, so we can allow
22660 FP constants. */
22661 if (GET_CODE (x) == CONST_DOUBLE &&
22662 (GET_MODE (x) == TFmode || GET_MODE (x) == TDmode))
22664 REAL_VALUE_TYPE rv;
22665 long k[4];
22667 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
22668 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
22669 REAL_VALUE_TO_TARGET_DECIMAL128 (rv, k);
22670 else
22671 REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv, k);
22673 if (TARGET_64BIT)
22675 if (TARGET_MINIMAL_TOC)
22676 fputs (DOUBLE_INT_ASM_OP, file);
22677 else
22678 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
22679 k[0] & 0xffffffff, k[1] & 0xffffffff,
22680 k[2] & 0xffffffff, k[3] & 0xffffffff);
22681 fprintf (file, "0x%lx%08lx,0x%lx%08lx\n",
22682 k[0] & 0xffffffff, k[1] & 0xffffffff,
22683 k[2] & 0xffffffff, k[3] & 0xffffffff);
22684 return;
22686 else
22688 if (TARGET_MINIMAL_TOC)
22689 fputs ("\t.long ", file);
22690 else
22691 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
22692 k[0] & 0xffffffff, k[1] & 0xffffffff,
22693 k[2] & 0xffffffff, k[3] & 0xffffffff);
22694 fprintf (file, "0x%lx,0x%lx,0x%lx,0x%lx\n",
22695 k[0] & 0xffffffff, k[1] & 0xffffffff,
22696 k[2] & 0xffffffff, k[3] & 0xffffffff);
22697 return;
22700 else if (GET_CODE (x) == CONST_DOUBLE &&
22701 (GET_MODE (x) == DFmode || GET_MODE (x) == DDmode))
22703 REAL_VALUE_TYPE rv;
22704 long k[2];
22706 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
22708 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
22709 REAL_VALUE_TO_TARGET_DECIMAL64 (rv, k);
22710 else
22711 REAL_VALUE_TO_TARGET_DOUBLE (rv, k);
22713 if (TARGET_64BIT)
22715 if (TARGET_MINIMAL_TOC)
22716 fputs (DOUBLE_INT_ASM_OP, file);
22717 else
22718 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
22719 k[0] & 0xffffffff, k[1] & 0xffffffff);
22720 fprintf (file, "0x%lx%08lx\n",
22721 k[0] & 0xffffffff, k[1] & 0xffffffff);
22722 return;
22724 else
22726 if (TARGET_MINIMAL_TOC)
22727 fputs ("\t.long ", file);
22728 else
22729 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
22730 k[0] & 0xffffffff, k[1] & 0xffffffff);
22731 fprintf (file, "0x%lx,0x%lx\n",
22732 k[0] & 0xffffffff, k[1] & 0xffffffff);
22733 return;
22736 else if (GET_CODE (x) == CONST_DOUBLE &&
22737 (GET_MODE (x) == SFmode || GET_MODE (x) == SDmode))
22739 REAL_VALUE_TYPE rv;
22740 long l;
22742 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
22743 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
22744 REAL_VALUE_TO_TARGET_DECIMAL32 (rv, l);
22745 else
22746 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
22748 if (TARGET_64BIT)
22750 if (TARGET_MINIMAL_TOC)
22751 fputs (DOUBLE_INT_ASM_OP, file);
22752 else
22753 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
22754 fprintf (file, "0x%lx00000000\n", l & 0xffffffff);
22755 return;
22757 else
22759 if (TARGET_MINIMAL_TOC)
22760 fputs ("\t.long ", file);
22761 else
22762 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
22763 fprintf (file, "0x%lx\n", l & 0xffffffff);
22764 return;
22767 else if (GET_MODE (x) == VOIDmode
22768 && (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE))
22770 unsigned HOST_WIDE_INT low;
22771 HOST_WIDE_INT high;
22773 if (GET_CODE (x) == CONST_DOUBLE)
22775 low = CONST_DOUBLE_LOW (x);
22776 high = CONST_DOUBLE_HIGH (x);
22778 else
22779 #if HOST_BITS_PER_WIDE_INT == 32
22781 low = INTVAL (x);
22782 high = (low & 0x80000000) ? ~0 : 0;
22784 #else
22786 low = INTVAL (x) & 0xffffffff;
22787 high = (HOST_WIDE_INT) INTVAL (x) >> 32;
22789 #endif
22791 /* TOC entries are always Pmode-sized, but since this
22792 is a bigendian machine then if we're putting smaller
22793 integer constants in the TOC we have to pad them.
22794 (This is still a win over putting the constants in
22795 a separate constant pool, because then we'd have
22796 to have both a TOC entry _and_ the actual constant.)
22798 For a 32-bit target, CONST_INT values are loaded and shifted
22799 entirely within `low' and can be stored in one TOC entry. */
22801 /* It would be easy to make this work, but it doesn't now. */
22802 gcc_assert (!TARGET_64BIT || POINTER_SIZE >= GET_MODE_BITSIZE (mode));
22804 if (POINTER_SIZE > GET_MODE_BITSIZE (mode))
22806 #if HOST_BITS_PER_WIDE_INT == 32
22807 lshift_double (low, high, POINTER_SIZE - GET_MODE_BITSIZE (mode),
22808 POINTER_SIZE, &low, &high, 0);
22809 #else
22810 low |= high << 32;
22811 low <<= POINTER_SIZE - GET_MODE_BITSIZE (mode);
22812 high = (HOST_WIDE_INT) low >> 32;
22813 low &= 0xffffffff;
22814 #endif
22817 if (TARGET_64BIT)
22819 if (TARGET_MINIMAL_TOC)
22820 fputs (DOUBLE_INT_ASM_OP, file);
22821 else
22822 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
22823 (long) high & 0xffffffff, (long) low & 0xffffffff);
22824 fprintf (file, "0x%lx%08lx\n",
22825 (long) high & 0xffffffff, (long) low & 0xffffffff);
22826 return;
22828 else
22830 if (POINTER_SIZE < GET_MODE_BITSIZE (mode))
22832 if (TARGET_MINIMAL_TOC)
22833 fputs ("\t.long ", file);
22834 else
22835 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
22836 (long) high & 0xffffffff, (long) low & 0xffffffff);
22837 fprintf (file, "0x%lx,0x%lx\n",
22838 (long) high & 0xffffffff, (long) low & 0xffffffff);
22840 else
22842 if (TARGET_MINIMAL_TOC)
22843 fputs ("\t.long ", file);
22844 else
22845 fprintf (file, "\t.tc IS_%lx[TC],", (long) low & 0xffffffff);
22846 fprintf (file, "0x%lx\n", (long) low & 0xffffffff);
22848 return;
22852 if (GET_CODE (x) == CONST)
22854 gcc_assert (GET_CODE (XEXP (x, 0)) == PLUS
22855 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT);
22857 base = XEXP (XEXP (x, 0), 0);
22858 offset = INTVAL (XEXP (XEXP (x, 0), 1));
22861 switch (GET_CODE (base))
22863 case SYMBOL_REF:
22864 name = XSTR (base, 0);
22865 break;
22867 case LABEL_REF:
22868 ASM_GENERATE_INTERNAL_LABEL (buf, "L",
22869 CODE_LABEL_NUMBER (XEXP (base, 0)));
22870 break;
22872 case CODE_LABEL:
22873 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (base));
22874 break;
22876 default:
22877 gcc_unreachable ();
22880 if (TARGET_MINIMAL_TOC)
22881 fputs (TARGET_32BIT ? "\t.long " : DOUBLE_INT_ASM_OP, file);
22882 else
22884 fputs ("\t.tc ", file);
22885 RS6000_OUTPUT_BASENAME (file, name);
22887 if (offset < 0)
22888 fprintf (file, ".N" HOST_WIDE_INT_PRINT_UNSIGNED, - offset);
22889 else if (offset)
22890 fprintf (file, ".P" HOST_WIDE_INT_PRINT_UNSIGNED, offset);
22892 fputs ("[TC],", file);
22895 /* Currently C++ toc references to vtables can be emitted before it
22896 is decided whether the vtable is public or private. If this is
22897 the case, then the linker will eventually complain that there is
22898 a TOC reference to an unknown section. Thus, for vtables only,
22899 we emit the TOC reference to reference the symbol and not the
22900 section. */
22901 if (VTABLE_NAME_P (name))
22903 RS6000_OUTPUT_BASENAME (file, name);
22904 if (offset < 0)
22905 fprintf (file, HOST_WIDE_INT_PRINT_DEC, offset);
22906 else if (offset > 0)
22907 fprintf (file, "+" HOST_WIDE_INT_PRINT_DEC, offset);
22909 else
22910 output_addr_const (file, x);
22911 putc ('\n', file);
22914 /* Output an assembler pseudo-op to write an ASCII string of N characters
22915 starting at P to FILE.
22917 On the RS/6000, we have to do this using the .byte operation and
22918 write out special characters outside the quoted string.
22919 Also, the assembler is broken; very long strings are truncated,
22920 so we must artificially break them up early. */
22922 void
22923 output_ascii (FILE *file, const char *p, int n)
22925 char c;
22926 int i, count_string;
22927 const char *for_string = "\t.byte \"";
22928 const char *for_decimal = "\t.byte ";
22929 const char *to_close = NULL;
22931 count_string = 0;
22932 for (i = 0; i < n; i++)
22934 c = *p++;
22935 if (c >= ' ' && c < 0177)
22937 if (for_string)
22938 fputs (for_string, file);
22939 putc (c, file);
22941 /* Write two quotes to get one. */
22942 if (c == '"')
22944 putc (c, file);
22945 ++count_string;
22948 for_string = NULL;
22949 for_decimal = "\"\n\t.byte ";
22950 to_close = "\"\n";
22951 ++count_string;
22953 if (count_string >= 512)
22955 fputs (to_close, file);
22957 for_string = "\t.byte \"";
22958 for_decimal = "\t.byte ";
22959 to_close = NULL;
22960 count_string = 0;
22963 else
22965 if (for_decimal)
22966 fputs (for_decimal, file);
22967 fprintf (file, "%d", c);
22969 for_string = "\n\t.byte \"";
22970 for_decimal = ", ";
22971 to_close = "\n";
22972 count_string = 0;
22976 /* Now close the string if we have written one. Then end the line. */
22977 if (to_close)
22978 fputs (to_close, file);
22981 /* Generate a unique section name for FILENAME for a section type
22982 represented by SECTION_DESC. Output goes into BUF.
22984 SECTION_DESC can be any string, as long as it is different for each
22985 possible section type.
22987 We name the section in the same manner as xlc. The name begins with an
22988 underscore followed by the filename (after stripping any leading directory
22989 names) with the last period replaced by the string SECTION_DESC. If
22990 FILENAME does not contain a period, SECTION_DESC is appended to the end of
22991 the name. */
22993 void
22994 rs6000_gen_section_name (char **buf, const char *filename,
22995 const char *section_desc)
22997 const char *q, *after_last_slash, *last_period = 0;
22998 char *p;
22999 int len;
23001 after_last_slash = filename;
23002 for (q = filename; *q; q++)
23004 if (*q == '/')
23005 after_last_slash = q + 1;
23006 else if (*q == '.')
23007 last_period = q;
23010 len = strlen (after_last_slash) + strlen (section_desc) + 2;
23011 *buf = (char *) xmalloc (len);
23013 p = *buf;
23014 *p++ = '_';
23016 for (q = after_last_slash; *q; q++)
23018 if (q == last_period)
23020 strcpy (p, section_desc);
23021 p += strlen (section_desc);
23022 break;
23025 else if (ISALNUM (*q))
23026 *p++ = *q;
23029 if (last_period == 0)
23030 strcpy (p, section_desc);
23031 else
23032 *p = '\0';
23035 /* Emit profile function. */
23037 void
23038 output_profile_hook (int labelno ATTRIBUTE_UNUSED)
23040 /* Non-standard profiling for kernels, which just saves LR then calls
23041 _mcount without worrying about arg saves. The idea is to change
23042 the function prologue as little as possible as it isn't easy to
23043 account for arg save/restore code added just for _mcount. */
23044 if (TARGET_PROFILE_KERNEL)
23045 return;
23047 if (DEFAULT_ABI == ABI_AIX)
23049 #ifndef NO_PROFILE_COUNTERS
23050 # define NO_PROFILE_COUNTERS 0
23051 #endif
23052 if (NO_PROFILE_COUNTERS)
23053 emit_library_call (init_one_libfunc (RS6000_MCOUNT),
23054 LCT_NORMAL, VOIDmode, 0);
23055 else
23057 char buf[30];
23058 const char *label_name;
23059 rtx fun;
23061 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
23062 label_name = (*targetm.strip_name_encoding) (ggc_strdup (buf));
23063 fun = gen_rtx_SYMBOL_REF (Pmode, label_name);
23065 emit_library_call (init_one_libfunc (RS6000_MCOUNT),
23066 LCT_NORMAL, VOIDmode, 1, fun, Pmode);
23069 else if (DEFAULT_ABI == ABI_DARWIN)
23071 const char *mcount_name = RS6000_MCOUNT;
23072 int caller_addr_regno = LR_REGNO;
23074 /* Be conservative and always set this, at least for now. */
23075 crtl->uses_pic_offset_table = 1;
23077 #if TARGET_MACHO
23078 /* For PIC code, set up a stub and collect the caller's address
23079 from r0, which is where the prologue puts it. */
23080 if (MACHOPIC_INDIRECT
23081 && crtl->uses_pic_offset_table)
23082 caller_addr_regno = 0;
23083 #endif
23084 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, mcount_name),
23085 LCT_NORMAL, VOIDmode, 1,
23086 gen_rtx_REG (Pmode, caller_addr_regno), Pmode);
23090 /* Write function profiler code. */
23092 void
23093 output_function_profiler (FILE *file, int labelno)
23095 char buf[100];
23097 switch (DEFAULT_ABI)
23099 default:
23100 gcc_unreachable ();
23102 case ABI_V4:
23103 if (!TARGET_32BIT)
23105 warning (0, "no profiling of 64-bit code for this ABI");
23106 return;
23108 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
23109 fprintf (file, "\tmflr %s\n", reg_names[0]);
23110 if (NO_PROFILE_COUNTERS)
23112 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
23113 reg_names[0], reg_names[1]);
23115 else if (TARGET_SECURE_PLT && flag_pic)
23117 asm_fprintf (file, "\tbcl 20,31,1f\n1:\n\t{st|stw} %s,4(%s)\n",
23118 reg_names[0], reg_names[1]);
23119 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
23120 asm_fprintf (file, "\t{cau|addis} %s,%s,",
23121 reg_names[12], reg_names[12]);
23122 assemble_name (file, buf);
23123 asm_fprintf (file, "-1b@ha\n\t{cal|la} %s,", reg_names[0]);
23124 assemble_name (file, buf);
23125 asm_fprintf (file, "-1b@l(%s)\n", reg_names[12]);
23127 else if (flag_pic == 1)
23129 fputs ("\tbl _GLOBAL_OFFSET_TABLE_@local-4\n", file);
23130 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
23131 reg_names[0], reg_names[1]);
23132 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
23133 asm_fprintf (file, "\t{l|lwz} %s,", reg_names[0]);
23134 assemble_name (file, buf);
23135 asm_fprintf (file, "@got(%s)\n", reg_names[12]);
23137 else if (flag_pic > 1)
23139 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
23140 reg_names[0], reg_names[1]);
23141 /* Now, we need to get the address of the label. */
23142 fputs ("\tbcl 20,31,1f\n\t.long ", file);
23143 assemble_name (file, buf);
23144 fputs ("-.\n1:", file);
23145 asm_fprintf (file, "\tmflr %s\n", reg_names[11]);
23146 asm_fprintf (file, "\t{l|lwz} %s,0(%s)\n",
23147 reg_names[0], reg_names[11]);
23148 asm_fprintf (file, "\t{cax|add} %s,%s,%s\n",
23149 reg_names[0], reg_names[0], reg_names[11]);
23151 else
23153 asm_fprintf (file, "\t{liu|lis} %s,", reg_names[12]);
23154 assemble_name (file, buf);
23155 fputs ("@ha\n", file);
23156 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
23157 reg_names[0], reg_names[1]);
23158 asm_fprintf (file, "\t{cal|la} %s,", reg_names[0]);
23159 assemble_name (file, buf);
23160 asm_fprintf (file, "@l(%s)\n", reg_names[12]);
23163 /* ABI_V4 saves the static chain reg with ASM_OUTPUT_REG_PUSH. */
23164 fprintf (file, "\tbl %s%s\n",
23165 RS6000_MCOUNT, flag_pic ? "@plt" : "");
23166 break;
23168 case ABI_AIX:
23169 case ABI_DARWIN:
23170 if (!TARGET_PROFILE_KERNEL)
23172 /* Don't do anything, done in output_profile_hook (). */
23174 else
23176 gcc_assert (!TARGET_32BIT);
23178 asm_fprintf (file, "\tmflr %s\n", reg_names[0]);
23179 asm_fprintf (file, "\tstd %s,16(%s)\n", reg_names[0], reg_names[1]);
23181 if (cfun->static_chain_decl != NULL)
23183 asm_fprintf (file, "\tstd %s,24(%s)\n",
23184 reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
23185 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
23186 asm_fprintf (file, "\tld %s,24(%s)\n",
23187 reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
23189 else
23190 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
23192 break;
23198 /* The following variable value is the last issued insn. */
23200 static rtx last_scheduled_insn;
23202 /* The following variable helps to balance issuing of load and
23203 store instructions */
23205 static int load_store_pendulum;
23207 /* Power4 load update and store update instructions are cracked into a
23208 load or store and an integer insn which are executed in the same cycle.
23209 Branches have their own dispatch slot which does not count against the
23210 GCC issue rate, but it changes the program flow so there are no other
23211 instructions to issue in this cycle. */
23213 static int
23214 rs6000_variable_issue_1 (rtx insn, int more)
23216 last_scheduled_insn = insn;
23217 if (GET_CODE (PATTERN (insn)) == USE
23218 || GET_CODE (PATTERN (insn)) == CLOBBER)
23220 cached_can_issue_more = more;
23221 return cached_can_issue_more;
23224 if (insn_terminates_group_p (insn, current_group))
23226 cached_can_issue_more = 0;
23227 return cached_can_issue_more;
23230 /* If no reservation, but reach here */
23231 if (recog_memoized (insn) < 0)
23232 return more;
23234 if (rs6000_sched_groups)
23236 if (is_microcoded_insn (insn))
23237 cached_can_issue_more = 0;
23238 else if (is_cracked_insn (insn))
23239 cached_can_issue_more = more > 2 ? more - 2 : 0;
23240 else
23241 cached_can_issue_more = more - 1;
23243 return cached_can_issue_more;
23246 if (rs6000_cpu_attr == CPU_CELL && is_nonpipeline_insn (insn))
23247 return 0;
23249 cached_can_issue_more = more - 1;
23250 return cached_can_issue_more;
23253 static int
23254 rs6000_variable_issue (FILE *stream, int verbose, rtx insn, int more)
23256 int r = rs6000_variable_issue_1 (insn, more);
23257 if (verbose)
23258 fprintf (stream, "// rs6000_variable_issue (more = %d) = %d\n", more, r);
23259 return r;
23262 /* Adjust the cost of a scheduling dependency. Return the new cost of
23263 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
23265 static int
23266 rs6000_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
23268 enum attr_type attr_type;
23270 if (! recog_memoized (insn))
23271 return 0;
23273 switch (REG_NOTE_KIND (link))
23275 case REG_DEP_TRUE:
23277 /* Data dependency; DEP_INSN writes a register that INSN reads
23278 some cycles later. */
23280 /* Separate a load from a narrower, dependent store. */
23281 if (rs6000_sched_groups
23282 && GET_CODE (PATTERN (insn)) == SET
23283 && GET_CODE (PATTERN (dep_insn)) == SET
23284 && GET_CODE (XEXP (PATTERN (insn), 1)) == MEM
23285 && GET_CODE (XEXP (PATTERN (dep_insn), 0)) == MEM
23286 && (GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (insn), 1)))
23287 > GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (dep_insn), 0)))))
23288 return cost + 14;
23290 attr_type = get_attr_type (insn);
23292 switch (attr_type)
23294 case TYPE_JMPREG:
23295 /* Tell the first scheduling pass about the latency between
23296 a mtctr and bctr (and mtlr and br/blr). The first
23297 scheduling pass will not know about this latency since
23298 the mtctr instruction, which has the latency associated
23299 to it, will be generated by reload. */
23300 return TARGET_POWER ? 5 : 4;
23301 case TYPE_BRANCH:
23302 /* Leave some extra cycles between a compare and its
23303 dependent branch, to inhibit expensive mispredicts. */
23304 if ((rs6000_cpu_attr == CPU_PPC603
23305 || rs6000_cpu_attr == CPU_PPC604
23306 || rs6000_cpu_attr == CPU_PPC604E
23307 || rs6000_cpu_attr == CPU_PPC620
23308 || rs6000_cpu_attr == CPU_PPC630
23309 || rs6000_cpu_attr == CPU_PPC750
23310 || rs6000_cpu_attr == CPU_PPC7400
23311 || rs6000_cpu_attr == CPU_PPC7450
23312 || rs6000_cpu_attr == CPU_POWER4
23313 || rs6000_cpu_attr == CPU_POWER5
23314 || rs6000_cpu_attr == CPU_POWER7
23315 || rs6000_cpu_attr == CPU_CELL)
23316 && recog_memoized (dep_insn)
23317 && (INSN_CODE (dep_insn) >= 0))
23319 switch (get_attr_type (dep_insn))
23321 case TYPE_CMP:
23322 case TYPE_COMPARE:
23323 case TYPE_DELAYED_COMPARE:
23324 case TYPE_IMUL_COMPARE:
23325 case TYPE_LMUL_COMPARE:
23326 case TYPE_FPCOMPARE:
23327 case TYPE_CR_LOGICAL:
23328 case TYPE_DELAYED_CR:
23329 return cost + 2;
23330 default:
23331 break;
23333 break;
23335 case TYPE_STORE:
23336 case TYPE_STORE_U:
23337 case TYPE_STORE_UX:
23338 case TYPE_FPSTORE:
23339 case TYPE_FPSTORE_U:
23340 case TYPE_FPSTORE_UX:
23341 if ((rs6000_cpu == PROCESSOR_POWER6)
23342 && recog_memoized (dep_insn)
23343 && (INSN_CODE (dep_insn) >= 0))
23346 if (GET_CODE (PATTERN (insn)) != SET)
23347 /* If this happens, we have to extend this to schedule
23348 optimally. Return default for now. */
23349 return cost;
23351 /* Adjust the cost for the case where the value written
23352 by a fixed point operation is used as the address
23353 gen value on a store. */
23354 switch (get_attr_type (dep_insn))
23356 case TYPE_LOAD:
23357 case TYPE_LOAD_U:
23358 case TYPE_LOAD_UX:
23359 case TYPE_CNTLZ:
23361 if (! store_data_bypass_p (dep_insn, insn))
23362 return 4;
23363 break;
23365 case TYPE_LOAD_EXT:
23366 case TYPE_LOAD_EXT_U:
23367 case TYPE_LOAD_EXT_UX:
23368 case TYPE_VAR_SHIFT_ROTATE:
23369 case TYPE_VAR_DELAYED_COMPARE:
23371 if (! store_data_bypass_p (dep_insn, insn))
23372 return 6;
23373 break;
23375 case TYPE_INTEGER:
23376 case TYPE_COMPARE:
23377 case TYPE_FAST_COMPARE:
23378 case TYPE_EXTS:
23379 case TYPE_SHIFT:
23380 case TYPE_INSERT_WORD:
23381 case TYPE_INSERT_DWORD:
23382 case TYPE_FPLOAD_U:
23383 case TYPE_FPLOAD_UX:
23384 case TYPE_STORE_U:
23385 case TYPE_STORE_UX:
23386 case TYPE_FPSTORE_U:
23387 case TYPE_FPSTORE_UX:
23389 if (! store_data_bypass_p (dep_insn, insn))
23390 return 3;
23391 break;
23393 case TYPE_IMUL:
23394 case TYPE_IMUL2:
23395 case TYPE_IMUL3:
23396 case TYPE_LMUL:
23397 case TYPE_IMUL_COMPARE:
23398 case TYPE_LMUL_COMPARE:
23400 if (! store_data_bypass_p (dep_insn, insn))
23401 return 17;
23402 break;
23404 case TYPE_IDIV:
23406 if (! store_data_bypass_p (dep_insn, insn))
23407 return 45;
23408 break;
23410 case TYPE_LDIV:
23412 if (! store_data_bypass_p (dep_insn, insn))
23413 return 57;
23414 break;
23416 default:
23417 break;
23420 break;
23422 case TYPE_LOAD:
23423 case TYPE_LOAD_U:
23424 case TYPE_LOAD_UX:
23425 case TYPE_LOAD_EXT:
23426 case TYPE_LOAD_EXT_U:
23427 case TYPE_LOAD_EXT_UX:
23428 if ((rs6000_cpu == PROCESSOR_POWER6)
23429 && recog_memoized (dep_insn)
23430 && (INSN_CODE (dep_insn) >= 0))
23433 /* Adjust the cost for the case where the value written
23434 by a fixed point instruction is used within the address
23435 gen portion of a subsequent load(u)(x) */
23436 switch (get_attr_type (dep_insn))
23438 case TYPE_LOAD:
23439 case TYPE_LOAD_U:
23440 case TYPE_LOAD_UX:
23441 case TYPE_CNTLZ:
23443 if (set_to_load_agen (dep_insn, insn))
23444 return 4;
23445 break;
23447 case TYPE_LOAD_EXT:
23448 case TYPE_LOAD_EXT_U:
23449 case TYPE_LOAD_EXT_UX:
23450 case TYPE_VAR_SHIFT_ROTATE:
23451 case TYPE_VAR_DELAYED_COMPARE:
23453 if (set_to_load_agen (dep_insn, insn))
23454 return 6;
23455 break;
23457 case TYPE_INTEGER:
23458 case TYPE_COMPARE:
23459 case TYPE_FAST_COMPARE:
23460 case TYPE_EXTS:
23461 case TYPE_SHIFT:
23462 case TYPE_INSERT_WORD:
23463 case TYPE_INSERT_DWORD:
23464 case TYPE_FPLOAD_U:
23465 case TYPE_FPLOAD_UX:
23466 case TYPE_STORE_U:
23467 case TYPE_STORE_UX:
23468 case TYPE_FPSTORE_U:
23469 case TYPE_FPSTORE_UX:
23471 if (set_to_load_agen (dep_insn, insn))
23472 return 3;
23473 break;
23475 case TYPE_IMUL:
23476 case TYPE_IMUL2:
23477 case TYPE_IMUL3:
23478 case TYPE_LMUL:
23479 case TYPE_IMUL_COMPARE:
23480 case TYPE_LMUL_COMPARE:
23482 if (set_to_load_agen (dep_insn, insn))
23483 return 17;
23484 break;
23486 case TYPE_IDIV:
23488 if (set_to_load_agen (dep_insn, insn))
23489 return 45;
23490 break;
23492 case TYPE_LDIV:
23494 if (set_to_load_agen (dep_insn, insn))
23495 return 57;
23496 break;
23498 default:
23499 break;
23502 break;
23504 case TYPE_FPLOAD:
23505 if ((rs6000_cpu == PROCESSOR_POWER6)
23506 && recog_memoized (dep_insn)
23507 && (INSN_CODE (dep_insn) >= 0)
23508 && (get_attr_type (dep_insn) == TYPE_MFFGPR))
23509 return 2;
23511 default:
23512 break;
23515 /* Fall out to return default cost. */
23517 break;
23519 case REG_DEP_OUTPUT:
23520 /* Output dependency; DEP_INSN writes a register that INSN writes some
23521 cycles later. */
23522 if ((rs6000_cpu == PROCESSOR_POWER6)
23523 && recog_memoized (dep_insn)
23524 && (INSN_CODE (dep_insn) >= 0))
23526 attr_type = get_attr_type (insn);
23528 switch (attr_type)
23530 case TYPE_FP:
23531 if (get_attr_type (dep_insn) == TYPE_FP)
23532 return 1;
23533 break;
23534 case TYPE_FPLOAD:
23535 if (get_attr_type (dep_insn) == TYPE_MFFGPR)
23536 return 2;
23537 break;
23538 default:
23539 break;
23542 case REG_DEP_ANTI:
23543 /* Anti dependency; DEP_INSN reads a register that INSN writes some
23544 cycles later. */
23545 return 0;
23547 default:
23548 gcc_unreachable ();
23551 return cost;
23554 /* Debug version of rs6000_adjust_cost. */
23556 static int
23557 rs6000_debug_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
23559 int ret = rs6000_adjust_cost (insn, link, dep_insn, cost);
23561 if (ret != cost)
23563 const char *dep;
23565 switch (REG_NOTE_KIND (link))
23567 default: dep = "unknown depencency"; break;
23568 case REG_DEP_TRUE: dep = "data dependency"; break;
23569 case REG_DEP_OUTPUT: dep = "output dependency"; break;
23570 case REG_DEP_ANTI: dep = "anti depencency"; break;
23573 fprintf (stderr,
23574 "\nrs6000_adjust_cost, final cost = %d, orig cost = %d, "
23575 "%s, insn:\n", ret, cost, dep);
23577 debug_rtx (insn);
23580 return ret;
23583 /* The function returns a true if INSN is microcoded.
23584 Return false otherwise. */
23586 static bool
23587 is_microcoded_insn (rtx insn)
23589 if (!insn || !NONDEBUG_INSN_P (insn)
23590 || GET_CODE (PATTERN (insn)) == USE
23591 || GET_CODE (PATTERN (insn)) == CLOBBER)
23592 return false;
23594 if (rs6000_cpu_attr == CPU_CELL)
23595 return get_attr_cell_micro (insn) == CELL_MICRO_ALWAYS;
23597 if (rs6000_sched_groups)
23599 enum attr_type type = get_attr_type (insn);
23600 if (type == TYPE_LOAD_EXT_U
23601 || type == TYPE_LOAD_EXT_UX
23602 || type == TYPE_LOAD_UX
23603 || type == TYPE_STORE_UX
23604 || type == TYPE_MFCR)
23605 return true;
23608 return false;
23611 /* The function returns true if INSN is cracked into 2 instructions
23612 by the processor (and therefore occupies 2 issue slots). */
23614 static bool
23615 is_cracked_insn (rtx insn)
23617 if (!insn || !NONDEBUG_INSN_P (insn)
23618 || GET_CODE (PATTERN (insn)) == USE
23619 || GET_CODE (PATTERN (insn)) == CLOBBER)
23620 return false;
23622 if (rs6000_sched_groups)
23624 enum attr_type type = get_attr_type (insn);
23625 if (type == TYPE_LOAD_U || type == TYPE_STORE_U
23626 || type == TYPE_FPLOAD_U || type == TYPE_FPSTORE_U
23627 || type == TYPE_FPLOAD_UX || type == TYPE_FPSTORE_UX
23628 || type == TYPE_LOAD_EXT || type == TYPE_DELAYED_CR
23629 || type == TYPE_COMPARE || type == TYPE_DELAYED_COMPARE
23630 || type == TYPE_IMUL_COMPARE || type == TYPE_LMUL_COMPARE
23631 || type == TYPE_IDIV || type == TYPE_LDIV
23632 || type == TYPE_INSERT_WORD)
23633 return true;
23636 return false;
23639 /* The function returns true if INSN can be issued only from
23640 the branch slot. */
23642 static bool
23643 is_branch_slot_insn (rtx insn)
23645 if (!insn || !NONDEBUG_INSN_P (insn)
23646 || GET_CODE (PATTERN (insn)) == USE
23647 || GET_CODE (PATTERN (insn)) == CLOBBER)
23648 return false;
23650 if (rs6000_sched_groups)
23652 enum attr_type type = get_attr_type (insn);
23653 if (type == TYPE_BRANCH || type == TYPE_JMPREG)
23654 return true;
23655 return false;
23658 return false;
23661 /* The function returns true if out_inst sets a value that is
23662 used in the address generation computation of in_insn */
23663 static bool
23664 set_to_load_agen (rtx out_insn, rtx in_insn)
23666 rtx out_set, in_set;
23668 /* For performance reasons, only handle the simple case where
23669 both loads are a single_set. */
23670 out_set = single_set (out_insn);
23671 if (out_set)
23673 in_set = single_set (in_insn);
23674 if (in_set)
23675 return reg_mentioned_p (SET_DEST (out_set), SET_SRC (in_set));
23678 return false;
23681 /* The function returns true if the target storage location of
23682 out_insn is adjacent to the target storage location of in_insn */
23683 /* Return 1 if memory locations are adjacent. */
23685 static bool
23686 adjacent_mem_locations (rtx insn1, rtx insn2)
23689 rtx a = get_store_dest (PATTERN (insn1));
23690 rtx b = get_store_dest (PATTERN (insn2));
23692 if ((GET_CODE (XEXP (a, 0)) == REG
23693 || (GET_CODE (XEXP (a, 0)) == PLUS
23694 && GET_CODE (XEXP (XEXP (a, 0), 1)) == CONST_INT))
23695 && (GET_CODE (XEXP (b, 0)) == REG
23696 || (GET_CODE (XEXP (b, 0)) == PLUS
23697 && GET_CODE (XEXP (XEXP (b, 0), 1)) == CONST_INT)))
23699 HOST_WIDE_INT val0 = 0, val1 = 0, val_diff;
23700 rtx reg0, reg1;
23702 if (GET_CODE (XEXP (a, 0)) == PLUS)
23704 reg0 = XEXP (XEXP (a, 0), 0);
23705 val0 = INTVAL (XEXP (XEXP (a, 0), 1));
23707 else
23708 reg0 = XEXP (a, 0);
23710 if (GET_CODE (XEXP (b, 0)) == PLUS)
23712 reg1 = XEXP (XEXP (b, 0), 0);
23713 val1 = INTVAL (XEXP (XEXP (b, 0), 1));
23715 else
23716 reg1 = XEXP (b, 0);
23718 val_diff = val1 - val0;
23720 return ((REGNO (reg0) == REGNO (reg1))
23721 && ((MEM_SIZE (a) && val_diff == INTVAL (MEM_SIZE (a)))
23722 || (MEM_SIZE (b) && val_diff == -INTVAL (MEM_SIZE (b)))));
23725 return false;
23728 /* A C statement (sans semicolon) to update the integer scheduling
23729 priority INSN_PRIORITY (INSN). Increase the priority to execute the
23730 INSN earlier, reduce the priority to execute INSN later. Do not
23731 define this macro if you do not need to adjust the scheduling
23732 priorities of insns. */
23734 static int
23735 rs6000_adjust_priority (rtx insn ATTRIBUTE_UNUSED, int priority)
23737 /* On machines (like the 750) which have asymmetric integer units,
23738 where one integer unit can do multiply and divides and the other
23739 can't, reduce the priority of multiply/divide so it is scheduled
23740 before other integer operations. */
23742 #if 0
23743 if (! INSN_P (insn))
23744 return priority;
23746 if (GET_CODE (PATTERN (insn)) == USE)
23747 return priority;
23749 switch (rs6000_cpu_attr) {
23750 case CPU_PPC750:
23751 switch (get_attr_type (insn))
23753 default:
23754 break;
23756 case TYPE_IMUL:
23757 case TYPE_IDIV:
23758 fprintf (stderr, "priority was %#x (%d) before adjustment\n",
23759 priority, priority);
23760 if (priority >= 0 && priority < 0x01000000)
23761 priority >>= 3;
23762 break;
23765 #endif
23767 if (insn_must_be_first_in_group (insn)
23768 && reload_completed
23769 && current_sched_info->sched_max_insns_priority
23770 && rs6000_sched_restricted_insns_priority)
23773 /* Prioritize insns that can be dispatched only in the first
23774 dispatch slot. */
23775 if (rs6000_sched_restricted_insns_priority == 1)
23776 /* Attach highest priority to insn. This means that in
23777 haifa-sched.c:ready_sort(), dispatch-slot restriction considerations
23778 precede 'priority' (critical path) considerations. */
23779 return current_sched_info->sched_max_insns_priority;
23780 else if (rs6000_sched_restricted_insns_priority == 2)
23781 /* Increase priority of insn by a minimal amount. This means that in
23782 haifa-sched.c:ready_sort(), only 'priority' (critical path)
23783 considerations precede dispatch-slot restriction considerations. */
23784 return (priority + 1);
23787 if (rs6000_cpu == PROCESSOR_POWER6
23788 && ((load_store_pendulum == -2 && is_load_insn (insn))
23789 || (load_store_pendulum == 2 && is_store_insn (insn))))
23790 /* Attach highest priority to insn if the scheduler has just issued two
23791 stores and this instruction is a load, or two loads and this instruction
23792 is a store. Power6 wants loads and stores scheduled alternately
23793 when possible */
23794 return current_sched_info->sched_max_insns_priority;
23796 return priority;
23799 /* Return true if the instruction is nonpipelined on the Cell. */
23800 static bool
23801 is_nonpipeline_insn (rtx insn)
23803 enum attr_type type;
23804 if (!insn || !NONDEBUG_INSN_P (insn)
23805 || GET_CODE (PATTERN (insn)) == USE
23806 || GET_CODE (PATTERN (insn)) == CLOBBER)
23807 return false;
23809 type = get_attr_type (insn);
23810 if (type == TYPE_IMUL
23811 || type == TYPE_IMUL2
23812 || type == TYPE_IMUL3
23813 || type == TYPE_LMUL
23814 || type == TYPE_IDIV
23815 || type == TYPE_LDIV
23816 || type == TYPE_SDIV
23817 || type == TYPE_DDIV
23818 || type == TYPE_SSQRT
23819 || type == TYPE_DSQRT
23820 || type == TYPE_MFCR
23821 || type == TYPE_MFCRF
23822 || type == TYPE_MFJMPR)
23824 return true;
23826 return false;
23830 /* Return how many instructions the machine can issue per cycle. */
23832 static int
23833 rs6000_issue_rate (void)
23835 /* Unless scheduling for register pressure, use issue rate of 1 for
23836 first scheduling pass to decrease degradation. */
23837 if (!reload_completed && !flag_sched_pressure)
23838 return 1;
23840 switch (rs6000_cpu_attr) {
23841 case CPU_RIOS1: /* ? */
23842 case CPU_RS64A:
23843 case CPU_PPC601: /* ? */
23844 case CPU_PPC7450:
23845 return 3;
23846 case CPU_PPC440:
23847 case CPU_PPC603:
23848 case CPU_PPC750:
23849 case CPU_PPC7400:
23850 case CPU_PPC8540:
23851 case CPU_CELL:
23852 case CPU_PPCE300C2:
23853 case CPU_PPCE300C3:
23854 case CPU_PPCE500MC:
23855 case CPU_PPCE500MC64:
23856 case CPU_TITAN:
23857 return 2;
23858 case CPU_RIOS2:
23859 case CPU_PPC476:
23860 case CPU_PPC604:
23861 case CPU_PPC604E:
23862 case CPU_PPC620:
23863 case CPU_PPC630:
23864 return 4;
23865 case CPU_POWER4:
23866 case CPU_POWER5:
23867 case CPU_POWER6:
23868 case CPU_POWER7:
23869 return 5;
23870 default:
23871 return 1;
23875 /* Return how many instructions to look ahead for better insn
23876 scheduling. */
23878 static int
23879 rs6000_use_sched_lookahead (void)
23881 if (rs6000_cpu_attr == CPU_PPC8540)
23882 return 4;
23883 if (rs6000_cpu_attr == CPU_CELL)
23884 return (reload_completed ? 8 : 0);
23885 return 0;
23888 /* We are choosing insn from the ready queue. Return nonzero if INSN can be chosen. */
23889 static int
23890 rs6000_use_sched_lookahead_guard (rtx insn)
23892 if (rs6000_cpu_attr != CPU_CELL)
23893 return 1;
23895 if (insn == NULL_RTX || !INSN_P (insn))
23896 abort ();
23898 if (!reload_completed
23899 || is_nonpipeline_insn (insn)
23900 || is_microcoded_insn (insn))
23901 return 0;
23903 return 1;
23906 /* Determine is PAT refers to memory. */
23908 static bool
23909 is_mem_ref (rtx pat)
23911 const char * fmt;
23912 int i, j;
23913 bool ret = false;
23915 /* stack_tie does not produce any real memory traffic. */
23916 if (GET_CODE (pat) == UNSPEC
23917 && XINT (pat, 1) == UNSPEC_TIE)
23918 return false;
23920 if (GET_CODE (pat) == MEM)
23921 return true;
23923 /* Recursively process the pattern. */
23924 fmt = GET_RTX_FORMAT (GET_CODE (pat));
23926 for (i = GET_RTX_LENGTH (GET_CODE (pat)) - 1; i >= 0 && !ret; i--)
23928 if (fmt[i] == 'e')
23929 ret |= is_mem_ref (XEXP (pat, i));
23930 else if (fmt[i] == 'E')
23931 for (j = XVECLEN (pat, i) - 1; j >= 0; j--)
23932 ret |= is_mem_ref (XVECEXP (pat, i, j));
23935 return ret;
23938 /* Determine if PAT is a PATTERN of a load insn. */
23940 static bool
23941 is_load_insn1 (rtx pat)
23943 if (!pat || pat == NULL_RTX)
23944 return false;
23946 if (GET_CODE (pat) == SET)
23947 return is_mem_ref (SET_SRC (pat));
23949 if (GET_CODE (pat) == PARALLEL)
23951 int i;
23953 for (i = 0; i < XVECLEN (pat, 0); i++)
23954 if (is_load_insn1 (XVECEXP (pat, 0, i)))
23955 return true;
23958 return false;
23961 /* Determine if INSN loads from memory. */
23963 static bool
23964 is_load_insn (rtx insn)
23966 if (!insn || !INSN_P (insn))
23967 return false;
23969 if (GET_CODE (insn) == CALL_INSN)
23970 return false;
23972 return is_load_insn1 (PATTERN (insn));
23975 /* Determine if PAT is a PATTERN of a store insn. */
23977 static bool
23978 is_store_insn1 (rtx pat)
23980 if (!pat || pat == NULL_RTX)
23981 return false;
23983 if (GET_CODE (pat) == SET)
23984 return is_mem_ref (SET_DEST (pat));
23986 if (GET_CODE (pat) == PARALLEL)
23988 int i;
23990 for (i = 0; i < XVECLEN (pat, 0); i++)
23991 if (is_store_insn1 (XVECEXP (pat, 0, i)))
23992 return true;
23995 return false;
23998 /* Determine if INSN stores to memory. */
24000 static bool
24001 is_store_insn (rtx insn)
24003 if (!insn || !INSN_P (insn))
24004 return false;
24006 return is_store_insn1 (PATTERN (insn));
24009 /* Return the dest of a store insn. */
24011 static rtx
24012 get_store_dest (rtx pat)
24014 gcc_assert (is_store_insn1 (pat));
24016 if (GET_CODE (pat) == SET)
24017 return SET_DEST (pat);
24018 else if (GET_CODE (pat) == PARALLEL)
24020 int i;
24022 for (i = 0; i < XVECLEN (pat, 0); i++)
24024 rtx inner_pat = XVECEXP (pat, 0, i);
24025 if (GET_CODE (inner_pat) == SET
24026 && is_mem_ref (SET_DEST (inner_pat)))
24027 return inner_pat;
24030 /* We shouldn't get here, because we should have either a simple
24031 store insn or a store with update which are covered above. */
24032 gcc_unreachable();
24035 /* Returns whether the dependence between INSN and NEXT is considered
24036 costly by the given target. */
24038 static bool
24039 rs6000_is_costly_dependence (dep_t dep, int cost, int distance)
24041 rtx insn;
24042 rtx next;
24044 /* If the flag is not enabled - no dependence is considered costly;
24045 allow all dependent insns in the same group.
24046 This is the most aggressive option. */
24047 if (rs6000_sched_costly_dep == no_dep_costly)
24048 return false;
24050 /* If the flag is set to 1 - a dependence is always considered costly;
24051 do not allow dependent instructions in the same group.
24052 This is the most conservative option. */
24053 if (rs6000_sched_costly_dep == all_deps_costly)
24054 return true;
24056 insn = DEP_PRO (dep);
24057 next = DEP_CON (dep);
24059 if (rs6000_sched_costly_dep == store_to_load_dep_costly
24060 && is_load_insn (next)
24061 && is_store_insn (insn))
24062 /* Prevent load after store in the same group. */
24063 return true;
24065 if (rs6000_sched_costly_dep == true_store_to_load_dep_costly
24066 && is_load_insn (next)
24067 && is_store_insn (insn)
24068 && DEP_TYPE (dep) == REG_DEP_TRUE)
24069 /* Prevent load after store in the same group if it is a true
24070 dependence. */
24071 return true;
24073 /* The flag is set to X; dependences with latency >= X are considered costly,
24074 and will not be scheduled in the same group. */
24075 if (rs6000_sched_costly_dep <= max_dep_latency
24076 && ((cost - distance) >= (int)rs6000_sched_costly_dep))
24077 return true;
24079 return false;
24082 /* Return the next insn after INSN that is found before TAIL is reached,
24083 skipping any "non-active" insns - insns that will not actually occupy
24084 an issue slot. Return NULL_RTX if such an insn is not found. */
24086 static rtx
24087 get_next_active_insn (rtx insn, rtx tail)
24089 if (insn == NULL_RTX || insn == tail)
24090 return NULL_RTX;
24092 while (1)
24094 insn = NEXT_INSN (insn);
24095 if (insn == NULL_RTX || insn == tail)
24096 return NULL_RTX;
24098 if (CALL_P (insn)
24099 || JUMP_P (insn)
24100 || (NONJUMP_INSN_P (insn)
24101 && GET_CODE (PATTERN (insn)) != USE
24102 && GET_CODE (PATTERN (insn)) != CLOBBER
24103 && INSN_CODE (insn) != CODE_FOR_stack_tie))
24104 break;
24106 return insn;
24109 /* We are about to begin issuing insns for this clock cycle. */
24111 static int
24112 rs6000_sched_reorder (FILE *dump ATTRIBUTE_UNUSED, int sched_verbose,
24113 rtx *ready ATTRIBUTE_UNUSED,
24114 int *pn_ready ATTRIBUTE_UNUSED,
24115 int clock_var ATTRIBUTE_UNUSED)
24117 int n_ready = *pn_ready;
24119 if (sched_verbose)
24120 fprintf (dump, "// rs6000_sched_reorder :\n");
24122 /* Reorder the ready list, if the second to last ready insn
24123 is a nonepipeline insn. */
24124 if (rs6000_cpu_attr == CPU_CELL && n_ready > 1)
24126 if (is_nonpipeline_insn (ready[n_ready - 1])
24127 && (recog_memoized (ready[n_ready - 2]) > 0))
24128 /* Simply swap first two insns. */
24130 rtx tmp = ready[n_ready - 1];
24131 ready[n_ready - 1] = ready[n_ready - 2];
24132 ready[n_ready - 2] = tmp;
24136 if (rs6000_cpu == PROCESSOR_POWER6)
24137 load_store_pendulum = 0;
24139 return rs6000_issue_rate ();
24142 /* Like rs6000_sched_reorder, but called after issuing each insn. */
24144 static int
24145 rs6000_sched_reorder2 (FILE *dump, int sched_verbose, rtx *ready,
24146 int *pn_ready, int clock_var ATTRIBUTE_UNUSED)
24148 if (sched_verbose)
24149 fprintf (dump, "// rs6000_sched_reorder2 :\n");
24151 /* For Power6, we need to handle some special cases to try and keep the
24152 store queue from overflowing and triggering expensive flushes.
24154 This code monitors how load and store instructions are being issued
24155 and skews the ready list one way or the other to increase the likelihood
24156 that a desired instruction is issued at the proper time.
24158 A couple of things are done. First, we maintain a "load_store_pendulum"
24159 to track the current state of load/store issue.
24161 - If the pendulum is at zero, then no loads or stores have been
24162 issued in the current cycle so we do nothing.
24164 - If the pendulum is 1, then a single load has been issued in this
24165 cycle and we attempt to locate another load in the ready list to
24166 issue with it.
24168 - If the pendulum is -2, then two stores have already been
24169 issued in this cycle, so we increase the priority of the first load
24170 in the ready list to increase it's likelihood of being chosen first
24171 in the next cycle.
24173 - If the pendulum is -1, then a single store has been issued in this
24174 cycle and we attempt to locate another store in the ready list to
24175 issue with it, preferring a store to an adjacent memory location to
24176 facilitate store pairing in the store queue.
24178 - If the pendulum is 2, then two loads have already been
24179 issued in this cycle, so we increase the priority of the first store
24180 in the ready list to increase it's likelihood of being chosen first
24181 in the next cycle.
24183 - If the pendulum < -2 or > 2, then do nothing.
24185 Note: This code covers the most common scenarios. There exist non
24186 load/store instructions which make use of the LSU and which
24187 would need to be accounted for to strictly model the behavior
24188 of the machine. Those instructions are currently unaccounted
24189 for to help minimize compile time overhead of this code.
24191 if (rs6000_cpu == PROCESSOR_POWER6 && last_scheduled_insn)
24193 int pos;
24194 int i;
24195 rtx tmp;
24197 if (is_store_insn (last_scheduled_insn))
24198 /* Issuing a store, swing the load_store_pendulum to the left */
24199 load_store_pendulum--;
24200 else if (is_load_insn (last_scheduled_insn))
24201 /* Issuing a load, swing the load_store_pendulum to the right */
24202 load_store_pendulum++;
24203 else
24204 return cached_can_issue_more;
24206 /* If the pendulum is balanced, or there is only one instruction on
24207 the ready list, then all is well, so return. */
24208 if ((load_store_pendulum == 0) || (*pn_ready <= 1))
24209 return cached_can_issue_more;
24211 if (load_store_pendulum == 1)
24213 /* A load has been issued in this cycle. Scan the ready list
24214 for another load to issue with it */
24215 pos = *pn_ready-1;
24217 while (pos >= 0)
24219 if (is_load_insn (ready[pos]))
24221 /* Found a load. Move it to the head of the ready list,
24222 and adjust it's priority so that it is more likely to
24223 stay there */
24224 tmp = ready[pos];
24225 for (i=pos; i<*pn_ready-1; i++)
24226 ready[i] = ready[i + 1];
24227 ready[*pn_ready-1] = tmp;
24229 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
24230 INSN_PRIORITY (tmp)++;
24231 break;
24233 pos--;
24236 else if (load_store_pendulum == -2)
24238 /* Two stores have been issued in this cycle. Increase the
24239 priority of the first load in the ready list to favor it for
24240 issuing in the next cycle. */
24241 pos = *pn_ready-1;
24243 while (pos >= 0)
24245 if (is_load_insn (ready[pos])
24246 && !sel_sched_p ()
24247 && INSN_PRIORITY_KNOWN (ready[pos]))
24249 INSN_PRIORITY (ready[pos])++;
24251 /* Adjust the pendulum to account for the fact that a load
24252 was found and increased in priority. This is to prevent
24253 increasing the priority of multiple loads */
24254 load_store_pendulum--;
24256 break;
24258 pos--;
24261 else if (load_store_pendulum == -1)
24263 /* A store has been issued in this cycle. Scan the ready list for
24264 another store to issue with it, preferring a store to an adjacent
24265 memory location */
24266 int first_store_pos = -1;
24268 pos = *pn_ready-1;
24270 while (pos >= 0)
24272 if (is_store_insn (ready[pos]))
24274 /* Maintain the index of the first store found on the
24275 list */
24276 if (first_store_pos == -1)
24277 first_store_pos = pos;
24279 if (is_store_insn (last_scheduled_insn)
24280 && adjacent_mem_locations (last_scheduled_insn,ready[pos]))
24282 /* Found an adjacent store. Move it to the head of the
24283 ready list, and adjust it's priority so that it is
24284 more likely to stay there */
24285 tmp = ready[pos];
24286 for (i=pos; i<*pn_ready-1; i++)
24287 ready[i] = ready[i + 1];
24288 ready[*pn_ready-1] = tmp;
24290 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
24291 INSN_PRIORITY (tmp)++;
24293 first_store_pos = -1;
24295 break;
24298 pos--;
24301 if (first_store_pos >= 0)
24303 /* An adjacent store wasn't found, but a non-adjacent store was,
24304 so move the non-adjacent store to the front of the ready
24305 list, and adjust its priority so that it is more likely to
24306 stay there. */
24307 tmp = ready[first_store_pos];
24308 for (i=first_store_pos; i<*pn_ready-1; i++)
24309 ready[i] = ready[i + 1];
24310 ready[*pn_ready-1] = tmp;
24311 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
24312 INSN_PRIORITY (tmp)++;
24315 else if (load_store_pendulum == 2)
24317 /* Two loads have been issued in this cycle. Increase the priority
24318 of the first store in the ready list to favor it for issuing in
24319 the next cycle. */
24320 pos = *pn_ready-1;
24322 while (pos >= 0)
24324 if (is_store_insn (ready[pos])
24325 && !sel_sched_p ()
24326 && INSN_PRIORITY_KNOWN (ready[pos]))
24328 INSN_PRIORITY (ready[pos])++;
24330 /* Adjust the pendulum to account for the fact that a store
24331 was found and increased in priority. This is to prevent
24332 increasing the priority of multiple stores */
24333 load_store_pendulum++;
24335 break;
24337 pos--;
24342 return cached_can_issue_more;
24345 /* Return whether the presence of INSN causes a dispatch group termination
24346 of group WHICH_GROUP.
24348 If WHICH_GROUP == current_group, this function will return true if INSN
24349 causes the termination of the current group (i.e, the dispatch group to
24350 which INSN belongs). This means that INSN will be the last insn in the
24351 group it belongs to.
24353 If WHICH_GROUP == previous_group, this function will return true if INSN
24354 causes the termination of the previous group (i.e, the dispatch group that
24355 precedes the group to which INSN belongs). This means that INSN will be
24356 the first insn in the group it belongs to). */
24358 static bool
24359 insn_terminates_group_p (rtx insn, enum group_termination which_group)
24361 bool first, last;
24363 if (! insn)
24364 return false;
24366 first = insn_must_be_first_in_group (insn);
24367 last = insn_must_be_last_in_group (insn);
24369 if (first && last)
24370 return true;
24372 if (which_group == current_group)
24373 return last;
24374 else if (which_group == previous_group)
24375 return first;
24377 return false;
24381 static bool
24382 insn_must_be_first_in_group (rtx insn)
24384 enum attr_type type;
24386 if (!insn
24387 || GET_CODE (insn) == NOTE
24388 || DEBUG_INSN_P (insn)
24389 || GET_CODE (PATTERN (insn)) == USE
24390 || GET_CODE (PATTERN (insn)) == CLOBBER)
24391 return false;
24393 switch (rs6000_cpu)
24395 case PROCESSOR_POWER5:
24396 if (is_cracked_insn (insn))
24397 return true;
24398 case PROCESSOR_POWER4:
24399 if (is_microcoded_insn (insn))
24400 return true;
24402 if (!rs6000_sched_groups)
24403 return false;
24405 type = get_attr_type (insn);
24407 switch (type)
24409 case TYPE_MFCR:
24410 case TYPE_MFCRF:
24411 case TYPE_MTCR:
24412 case TYPE_DELAYED_CR:
24413 case TYPE_CR_LOGICAL:
24414 case TYPE_MTJMPR:
24415 case TYPE_MFJMPR:
24416 case TYPE_IDIV:
24417 case TYPE_LDIV:
24418 case TYPE_LOAD_L:
24419 case TYPE_STORE_C:
24420 case TYPE_ISYNC:
24421 case TYPE_SYNC:
24422 return true;
24423 default:
24424 break;
24426 break;
24427 case PROCESSOR_POWER6:
24428 type = get_attr_type (insn);
24430 switch (type)
24432 case TYPE_INSERT_DWORD:
24433 case TYPE_EXTS:
24434 case TYPE_CNTLZ:
24435 case TYPE_SHIFT:
24436 case TYPE_VAR_SHIFT_ROTATE:
24437 case TYPE_TRAP:
24438 case TYPE_IMUL:
24439 case TYPE_IMUL2:
24440 case TYPE_IMUL3:
24441 case TYPE_LMUL:
24442 case TYPE_IDIV:
24443 case TYPE_INSERT_WORD:
24444 case TYPE_DELAYED_COMPARE:
24445 case TYPE_IMUL_COMPARE:
24446 case TYPE_LMUL_COMPARE:
24447 case TYPE_FPCOMPARE:
24448 case TYPE_MFCR:
24449 case TYPE_MTCR:
24450 case TYPE_MFJMPR:
24451 case TYPE_MTJMPR:
24452 case TYPE_ISYNC:
24453 case TYPE_SYNC:
24454 case TYPE_LOAD_L:
24455 case TYPE_STORE_C:
24456 case TYPE_LOAD_U:
24457 case TYPE_LOAD_UX:
24458 case TYPE_LOAD_EXT_UX:
24459 case TYPE_STORE_U:
24460 case TYPE_STORE_UX:
24461 case TYPE_FPLOAD_U:
24462 case TYPE_FPLOAD_UX:
24463 case TYPE_FPSTORE_U:
24464 case TYPE_FPSTORE_UX:
24465 return true;
24466 default:
24467 break;
24469 break;
24470 case PROCESSOR_POWER7:
24471 type = get_attr_type (insn);
24473 switch (type)
24475 case TYPE_CR_LOGICAL:
24476 case TYPE_MFCR:
24477 case TYPE_MFCRF:
24478 case TYPE_MTCR:
24479 case TYPE_IDIV:
24480 case TYPE_LDIV:
24481 case TYPE_COMPARE:
24482 case TYPE_DELAYED_COMPARE:
24483 case TYPE_VAR_DELAYED_COMPARE:
24484 case TYPE_ISYNC:
24485 case TYPE_LOAD_L:
24486 case TYPE_STORE_C:
24487 case TYPE_LOAD_U:
24488 case TYPE_LOAD_UX:
24489 case TYPE_LOAD_EXT:
24490 case TYPE_LOAD_EXT_U:
24491 case TYPE_LOAD_EXT_UX:
24492 case TYPE_STORE_U:
24493 case TYPE_STORE_UX:
24494 case TYPE_FPLOAD_U:
24495 case TYPE_FPLOAD_UX:
24496 case TYPE_FPSTORE_U:
24497 case TYPE_FPSTORE_UX:
24498 case TYPE_MFJMPR:
24499 case TYPE_MTJMPR:
24500 return true;
24501 default:
24502 break;
24504 break;
24505 default:
24506 break;
24509 return false;
24512 static bool
24513 insn_must_be_last_in_group (rtx insn)
24515 enum attr_type type;
24517 if (!insn
24518 || GET_CODE (insn) == NOTE
24519 || DEBUG_INSN_P (insn)
24520 || GET_CODE (PATTERN (insn)) == USE
24521 || GET_CODE (PATTERN (insn)) == CLOBBER)
24522 return false;
24524 switch (rs6000_cpu) {
24525 case PROCESSOR_POWER4:
24526 case PROCESSOR_POWER5:
24527 if (is_microcoded_insn (insn))
24528 return true;
24530 if (is_branch_slot_insn (insn))
24531 return true;
24533 break;
24534 case PROCESSOR_POWER6:
24535 type = get_attr_type (insn);
24537 switch (type)
24539 case TYPE_EXTS:
24540 case TYPE_CNTLZ:
24541 case TYPE_SHIFT:
24542 case TYPE_VAR_SHIFT_ROTATE:
24543 case TYPE_TRAP:
24544 case TYPE_IMUL:
24545 case TYPE_IMUL2:
24546 case TYPE_IMUL3:
24547 case TYPE_LMUL:
24548 case TYPE_IDIV:
24549 case TYPE_DELAYED_COMPARE:
24550 case TYPE_IMUL_COMPARE:
24551 case TYPE_LMUL_COMPARE:
24552 case TYPE_FPCOMPARE:
24553 case TYPE_MFCR:
24554 case TYPE_MTCR:
24555 case TYPE_MFJMPR:
24556 case TYPE_MTJMPR:
24557 case TYPE_ISYNC:
24558 case TYPE_SYNC:
24559 case TYPE_LOAD_L:
24560 case TYPE_STORE_C:
24561 return true;
24562 default:
24563 break;
24565 break;
24566 case PROCESSOR_POWER7:
24567 type = get_attr_type (insn);
24569 switch (type)
24571 case TYPE_ISYNC:
24572 case TYPE_SYNC:
24573 case TYPE_LOAD_L:
24574 case TYPE_STORE_C:
24575 case TYPE_LOAD_EXT_U:
24576 case TYPE_LOAD_EXT_UX:
24577 case TYPE_STORE_UX:
24578 return true;
24579 default:
24580 break;
24582 break;
24583 default:
24584 break;
24587 return false;
24590 /* Return true if it is recommended to keep NEXT_INSN "far" (in a separate
24591 dispatch group) from the insns in GROUP_INSNS. Return false otherwise. */
24593 static bool
24594 is_costly_group (rtx *group_insns, rtx next_insn)
24596 int i;
24597 int issue_rate = rs6000_issue_rate ();
24599 for (i = 0; i < issue_rate; i++)
24601 sd_iterator_def sd_it;
24602 dep_t dep;
24603 rtx insn = group_insns[i];
24605 if (!insn)
24606 continue;
24608 FOR_EACH_DEP (insn, SD_LIST_FORW, sd_it, dep)
24610 rtx next = DEP_CON (dep);
24612 if (next == next_insn
24613 && rs6000_is_costly_dependence (dep, dep_cost (dep), 0))
24614 return true;
24618 return false;
24621 /* Utility of the function redefine_groups.
24622 Check if it is too costly to schedule NEXT_INSN together with GROUP_INSNS
24623 in the same dispatch group. If so, insert nops before NEXT_INSN, in order
24624 to keep it "far" (in a separate group) from GROUP_INSNS, following
24625 one of the following schemes, depending on the value of the flag
24626 -minsert_sched_nops = X:
24627 (1) X == sched_finish_regroup_exact: insert exactly as many nops as needed
24628 in order to force NEXT_INSN into a separate group.
24629 (2) X < sched_finish_regroup_exact: insert exactly X nops.
24630 GROUP_END, CAN_ISSUE_MORE and GROUP_COUNT record the state after nop
24631 insertion (has a group just ended, how many vacant issue slots remain in the
24632 last group, and how many dispatch groups were encountered so far). */
24634 static int
24635 force_new_group (int sched_verbose, FILE *dump, rtx *group_insns,
24636 rtx next_insn, bool *group_end, int can_issue_more,
24637 int *group_count)
24639 rtx nop;
24640 bool force;
24641 int issue_rate = rs6000_issue_rate ();
24642 bool end = *group_end;
24643 int i;
24645 if (next_insn == NULL_RTX || DEBUG_INSN_P (next_insn))
24646 return can_issue_more;
24648 if (rs6000_sched_insert_nops > sched_finish_regroup_exact)
24649 return can_issue_more;
24651 force = is_costly_group (group_insns, next_insn);
24652 if (!force)
24653 return can_issue_more;
24655 if (sched_verbose > 6)
24656 fprintf (dump,"force: group count = %d, can_issue_more = %d\n",
24657 *group_count ,can_issue_more);
24659 if (rs6000_sched_insert_nops == sched_finish_regroup_exact)
24661 if (*group_end)
24662 can_issue_more = 0;
24664 /* Since only a branch can be issued in the last issue_slot, it is
24665 sufficient to insert 'can_issue_more - 1' nops if next_insn is not
24666 a branch. If next_insn is a branch, we insert 'can_issue_more' nops;
24667 in this case the last nop will start a new group and the branch
24668 will be forced to the new group. */
24669 if (can_issue_more && !is_branch_slot_insn (next_insn))
24670 can_issue_more--;
24672 while (can_issue_more > 0)
24674 nop = gen_nop ();
24675 emit_insn_before (nop, next_insn);
24676 can_issue_more--;
24679 *group_end = true;
24680 return 0;
24683 if (rs6000_sched_insert_nops < sched_finish_regroup_exact)
24685 int n_nops = rs6000_sched_insert_nops;
24687 /* Nops can't be issued from the branch slot, so the effective
24688 issue_rate for nops is 'issue_rate - 1'. */
24689 if (can_issue_more == 0)
24690 can_issue_more = issue_rate;
24691 can_issue_more--;
24692 if (can_issue_more == 0)
24694 can_issue_more = issue_rate - 1;
24695 (*group_count)++;
24696 end = true;
24697 for (i = 0; i < issue_rate; i++)
24699 group_insns[i] = 0;
24703 while (n_nops > 0)
24705 nop = gen_nop ();
24706 emit_insn_before (nop, next_insn);
24707 if (can_issue_more == issue_rate - 1) /* new group begins */
24708 end = false;
24709 can_issue_more--;
24710 if (can_issue_more == 0)
24712 can_issue_more = issue_rate - 1;
24713 (*group_count)++;
24714 end = true;
24715 for (i = 0; i < issue_rate; i++)
24717 group_insns[i] = 0;
24720 n_nops--;
24723 /* Scale back relative to 'issue_rate' (instead of 'issue_rate - 1'). */
24724 can_issue_more++;
24726 /* Is next_insn going to start a new group? */
24727 *group_end
24728 = (end
24729 || (can_issue_more == 1 && !is_branch_slot_insn (next_insn))
24730 || (can_issue_more <= 2 && is_cracked_insn (next_insn))
24731 || (can_issue_more < issue_rate &&
24732 insn_terminates_group_p (next_insn, previous_group)));
24733 if (*group_end && end)
24734 (*group_count)--;
24736 if (sched_verbose > 6)
24737 fprintf (dump, "done force: group count = %d, can_issue_more = %d\n",
24738 *group_count, can_issue_more);
24739 return can_issue_more;
24742 return can_issue_more;
24745 /* This function tries to synch the dispatch groups that the compiler "sees"
24746 with the dispatch groups that the processor dispatcher is expected to
24747 form in practice. It tries to achieve this synchronization by forcing the
24748 estimated processor grouping on the compiler (as opposed to the function
24749 'pad_goups' which tries to force the scheduler's grouping on the processor).
24751 The function scans the insn sequence between PREV_HEAD_INSN and TAIL and
24752 examines the (estimated) dispatch groups that will be formed by the processor
24753 dispatcher. It marks these group boundaries to reflect the estimated
24754 processor grouping, overriding the grouping that the scheduler had marked.
24755 Depending on the value of the flag '-minsert-sched-nops' this function can
24756 force certain insns into separate groups or force a certain distance between
24757 them by inserting nops, for example, if there exists a "costly dependence"
24758 between the insns.
24760 The function estimates the group boundaries that the processor will form as
24761 follows: It keeps track of how many vacant issue slots are available after
24762 each insn. A subsequent insn will start a new group if one of the following
24763 4 cases applies:
24764 - no more vacant issue slots remain in the current dispatch group.
24765 - only the last issue slot, which is the branch slot, is vacant, but the next
24766 insn is not a branch.
24767 - only the last 2 or less issue slots, including the branch slot, are vacant,
24768 which means that a cracked insn (which occupies two issue slots) can't be
24769 issued in this group.
24770 - less than 'issue_rate' slots are vacant, and the next insn always needs to
24771 start a new group. */
24773 static int
24774 redefine_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail)
24776 rtx insn, next_insn;
24777 int issue_rate;
24778 int can_issue_more;
24779 int slot, i;
24780 bool group_end;
24781 int group_count = 0;
24782 rtx *group_insns;
24784 /* Initialize. */
24785 issue_rate = rs6000_issue_rate ();
24786 group_insns = XALLOCAVEC (rtx, issue_rate);
24787 for (i = 0; i < issue_rate; i++)
24789 group_insns[i] = 0;
24791 can_issue_more = issue_rate;
24792 slot = 0;
24793 insn = get_next_active_insn (prev_head_insn, tail);
24794 group_end = false;
24796 while (insn != NULL_RTX)
24798 slot = (issue_rate - can_issue_more);
24799 group_insns[slot] = insn;
24800 can_issue_more =
24801 rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more);
24802 if (insn_terminates_group_p (insn, current_group))
24803 can_issue_more = 0;
24805 next_insn = get_next_active_insn (insn, tail);
24806 if (next_insn == NULL_RTX)
24807 return group_count + 1;
24809 /* Is next_insn going to start a new group? */
24810 group_end
24811 = (can_issue_more == 0
24812 || (can_issue_more == 1 && !is_branch_slot_insn (next_insn))
24813 || (can_issue_more <= 2 && is_cracked_insn (next_insn))
24814 || (can_issue_more < issue_rate &&
24815 insn_terminates_group_p (next_insn, previous_group)));
24817 can_issue_more = force_new_group (sched_verbose, dump, group_insns,
24818 next_insn, &group_end, can_issue_more,
24819 &group_count);
24821 if (group_end)
24823 group_count++;
24824 can_issue_more = 0;
24825 for (i = 0; i < issue_rate; i++)
24827 group_insns[i] = 0;
24831 if (GET_MODE (next_insn) == TImode && can_issue_more)
24832 PUT_MODE (next_insn, VOIDmode);
24833 else if (!can_issue_more && GET_MODE (next_insn) != TImode)
24834 PUT_MODE (next_insn, TImode);
24836 insn = next_insn;
24837 if (can_issue_more == 0)
24838 can_issue_more = issue_rate;
24839 } /* while */
24841 return group_count;
24844 /* Scan the insn sequence between PREV_HEAD_INSN and TAIL and examine the
24845 dispatch group boundaries that the scheduler had marked. Pad with nops
24846 any dispatch groups which have vacant issue slots, in order to force the
24847 scheduler's grouping on the processor dispatcher. The function
24848 returns the number of dispatch groups found. */
24850 static int
24851 pad_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail)
24853 rtx insn, next_insn;
24854 rtx nop;
24855 int issue_rate;
24856 int can_issue_more;
24857 int group_end;
24858 int group_count = 0;
24860 /* Initialize issue_rate. */
24861 issue_rate = rs6000_issue_rate ();
24862 can_issue_more = issue_rate;
24864 insn = get_next_active_insn (prev_head_insn, tail);
24865 next_insn = get_next_active_insn (insn, tail);
24867 while (insn != NULL_RTX)
24869 can_issue_more =
24870 rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more);
24872 group_end = (next_insn == NULL_RTX || GET_MODE (next_insn) == TImode);
24874 if (next_insn == NULL_RTX)
24875 break;
24877 if (group_end)
24879 /* If the scheduler had marked group termination at this location
24880 (between insn and next_insn), and neither insn nor next_insn will
24881 force group termination, pad the group with nops to force group
24882 termination. */
24883 if (can_issue_more
24884 && (rs6000_sched_insert_nops == sched_finish_pad_groups)
24885 && !insn_terminates_group_p (insn, current_group)
24886 && !insn_terminates_group_p (next_insn, previous_group))
24888 if (!is_branch_slot_insn (next_insn))
24889 can_issue_more--;
24891 while (can_issue_more)
24893 nop = gen_nop ();
24894 emit_insn_before (nop, next_insn);
24895 can_issue_more--;
24899 can_issue_more = issue_rate;
24900 group_count++;
24903 insn = next_insn;
24904 next_insn = get_next_active_insn (insn, tail);
24907 return group_count;
24910 /* We're beginning a new block. Initialize data structures as necessary. */
24912 static void
24913 rs6000_sched_init (FILE *dump ATTRIBUTE_UNUSED,
24914 int sched_verbose ATTRIBUTE_UNUSED,
24915 int max_ready ATTRIBUTE_UNUSED)
24917 last_scheduled_insn = NULL_RTX;
24918 load_store_pendulum = 0;
24921 /* The following function is called at the end of scheduling BB.
24922 After reload, it inserts nops at insn group bundling. */
24924 static void
24925 rs6000_sched_finish (FILE *dump, int sched_verbose)
24927 int n_groups;
24929 if (sched_verbose)
24930 fprintf (dump, "=== Finishing schedule.\n");
24932 if (reload_completed && rs6000_sched_groups)
24934 /* Do not run sched_finish hook when selective scheduling enabled. */
24935 if (sel_sched_p ())
24936 return;
24938 if (rs6000_sched_insert_nops == sched_finish_none)
24939 return;
24941 if (rs6000_sched_insert_nops == sched_finish_pad_groups)
24942 n_groups = pad_groups (dump, sched_verbose,
24943 current_sched_info->prev_head,
24944 current_sched_info->next_tail);
24945 else
24946 n_groups = redefine_groups (dump, sched_verbose,
24947 current_sched_info->prev_head,
24948 current_sched_info->next_tail);
24950 if (sched_verbose >= 6)
24952 fprintf (dump, "ngroups = %d\n", n_groups);
24953 print_rtl (dump, current_sched_info->prev_head);
24954 fprintf (dump, "Done finish_sched\n");
24959 struct _rs6000_sched_context
24961 short cached_can_issue_more;
24962 rtx last_scheduled_insn;
24963 int load_store_pendulum;
24966 typedef struct _rs6000_sched_context rs6000_sched_context_def;
24967 typedef rs6000_sched_context_def *rs6000_sched_context_t;
24969 /* Allocate store for new scheduling context. */
24970 static void *
24971 rs6000_alloc_sched_context (void)
24973 return xmalloc (sizeof (rs6000_sched_context_def));
24976 /* If CLEAN_P is true then initializes _SC with clean data,
24977 and from the global context otherwise. */
24978 static void
24979 rs6000_init_sched_context (void *_sc, bool clean_p)
24981 rs6000_sched_context_t sc = (rs6000_sched_context_t) _sc;
24983 if (clean_p)
24985 sc->cached_can_issue_more = 0;
24986 sc->last_scheduled_insn = NULL_RTX;
24987 sc->load_store_pendulum = 0;
24989 else
24991 sc->cached_can_issue_more = cached_can_issue_more;
24992 sc->last_scheduled_insn = last_scheduled_insn;
24993 sc->load_store_pendulum = load_store_pendulum;
24997 /* Sets the global scheduling context to the one pointed to by _SC. */
24998 static void
24999 rs6000_set_sched_context (void *_sc)
25001 rs6000_sched_context_t sc = (rs6000_sched_context_t) _sc;
25003 gcc_assert (sc != NULL);
25005 cached_can_issue_more = sc->cached_can_issue_more;
25006 last_scheduled_insn = sc->last_scheduled_insn;
25007 load_store_pendulum = sc->load_store_pendulum;
25010 /* Free _SC. */
25011 static void
25012 rs6000_free_sched_context (void *_sc)
25014 gcc_assert (_sc != NULL);
25016 free (_sc);
25020 /* Length in units of the trampoline for entering a nested function. */
25023 rs6000_trampoline_size (void)
25025 int ret = 0;
25027 switch (DEFAULT_ABI)
25029 default:
25030 gcc_unreachable ();
25032 case ABI_AIX:
25033 ret = (TARGET_32BIT) ? 12 : 24;
25034 break;
25036 case ABI_DARWIN:
25037 case ABI_V4:
25038 ret = (TARGET_32BIT) ? 40 : 48;
25039 break;
25042 return ret;
25045 /* Emit RTL insns to initialize the variable parts of a trampoline.
25046 FNADDR is an RTX for the address of the function's pure code.
25047 CXT is an RTX for the static chain value for the function. */
25049 static void
25050 rs6000_trampoline_init (rtx m_tramp, tree fndecl, rtx cxt)
25052 int regsize = (TARGET_32BIT) ? 4 : 8;
25053 rtx fnaddr = XEXP (DECL_RTL (fndecl), 0);
25054 rtx ctx_reg = force_reg (Pmode, cxt);
25055 rtx addr = force_reg (Pmode, XEXP (m_tramp, 0));
25057 switch (DEFAULT_ABI)
25059 default:
25060 gcc_unreachable ();
25062 /* Under AIX, just build the 3 word function descriptor */
25063 case ABI_AIX:
25065 rtx fnmem = gen_const_mem (Pmode, force_reg (Pmode, fnaddr));
25066 rtx fn_reg = gen_reg_rtx (Pmode);
25067 rtx toc_reg = gen_reg_rtx (Pmode);
25069 /* Macro to shorten the code expansions below. */
25070 # define MEM_PLUS(MEM, OFFSET) adjust_address (MEM, Pmode, OFFSET)
25072 m_tramp = replace_equiv_address (m_tramp, addr);
25074 emit_move_insn (fn_reg, MEM_PLUS (fnmem, 0));
25075 emit_move_insn (toc_reg, MEM_PLUS (fnmem, regsize));
25076 emit_move_insn (MEM_PLUS (m_tramp, 0), fn_reg);
25077 emit_move_insn (MEM_PLUS (m_tramp, regsize), toc_reg);
25078 emit_move_insn (MEM_PLUS (m_tramp, 2*regsize), ctx_reg);
25080 # undef MEM_PLUS
25082 break;
25084 /* Under V.4/eabi/darwin, __trampoline_setup does the real work. */
25085 case ABI_DARWIN:
25086 case ABI_V4:
25087 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__trampoline_setup"),
25088 LCT_NORMAL, VOIDmode, 4,
25089 addr, Pmode,
25090 GEN_INT (rs6000_trampoline_size ()), SImode,
25091 fnaddr, Pmode,
25092 ctx_reg, Pmode);
25093 break;
25098 /* Returns TRUE iff the target attribute indicated by ATTR_ID takes a plain
25099 identifier as an argument, so the front end shouldn't look it up. */
25101 static bool
25102 rs6000_attribute_takes_identifier_p (const_tree attr_id)
25104 return is_attribute_p ("altivec", attr_id);
25107 /* Handle the "altivec" attribute. The attribute may have
25108 arguments as follows:
25110 __attribute__((altivec(vector__)))
25111 __attribute__((altivec(pixel__))) (always followed by 'unsigned short')
25112 __attribute__((altivec(bool__))) (always followed by 'unsigned')
25114 and may appear more than once (e.g., 'vector bool char') in a
25115 given declaration. */
25117 static tree
25118 rs6000_handle_altivec_attribute (tree *node,
25119 tree name ATTRIBUTE_UNUSED,
25120 tree args,
25121 int flags ATTRIBUTE_UNUSED,
25122 bool *no_add_attrs)
25124 tree type = *node, result = NULL_TREE;
25125 enum machine_mode mode;
25126 int unsigned_p;
25127 char altivec_type
25128 = ((args && TREE_CODE (args) == TREE_LIST && TREE_VALUE (args)
25129 && TREE_CODE (TREE_VALUE (args)) == IDENTIFIER_NODE)
25130 ? *IDENTIFIER_POINTER (TREE_VALUE (args))
25131 : '?');
25133 while (POINTER_TYPE_P (type)
25134 || TREE_CODE (type) == FUNCTION_TYPE
25135 || TREE_CODE (type) == METHOD_TYPE
25136 || TREE_CODE (type) == ARRAY_TYPE)
25137 type = TREE_TYPE (type);
25139 mode = TYPE_MODE (type);
25141 /* Check for invalid AltiVec type qualifiers. */
25142 if (type == long_double_type_node)
25143 error ("use of %<long double%> in AltiVec types is invalid");
25144 else if (type == boolean_type_node)
25145 error ("use of boolean types in AltiVec types is invalid");
25146 else if (TREE_CODE (type) == COMPLEX_TYPE)
25147 error ("use of %<complex%> in AltiVec types is invalid");
25148 else if (DECIMAL_FLOAT_MODE_P (mode))
25149 error ("use of decimal floating point types in AltiVec types is invalid");
25150 else if (!TARGET_VSX)
25152 if (type == long_unsigned_type_node || type == long_integer_type_node)
25154 if (TARGET_64BIT)
25155 error ("use of %<long%> in AltiVec types is invalid for "
25156 "64-bit code without -mvsx");
25157 else if (rs6000_warn_altivec_long)
25158 warning (0, "use of %<long%> in AltiVec types is deprecated; "
25159 "use %<int%>");
25161 else if (type == long_long_unsigned_type_node
25162 || type == long_long_integer_type_node)
25163 error ("use of %<long long%> in AltiVec types is invalid without "
25164 "-mvsx");
25165 else if (type == double_type_node)
25166 error ("use of %<double%> in AltiVec types is invalid without -mvsx");
25169 switch (altivec_type)
25171 case 'v':
25172 unsigned_p = TYPE_UNSIGNED (type);
25173 switch (mode)
25175 case DImode:
25176 result = (unsigned_p ? unsigned_V2DI_type_node : V2DI_type_node);
25177 break;
25178 case SImode:
25179 result = (unsigned_p ? unsigned_V4SI_type_node : V4SI_type_node);
25180 break;
25181 case HImode:
25182 result = (unsigned_p ? unsigned_V8HI_type_node : V8HI_type_node);
25183 break;
25184 case QImode:
25185 result = (unsigned_p ? unsigned_V16QI_type_node : V16QI_type_node);
25186 break;
25187 case SFmode: result = V4SF_type_node; break;
25188 case DFmode: result = V2DF_type_node; break;
25189 /* If the user says 'vector int bool', we may be handed the 'bool'
25190 attribute _before_ the 'vector' attribute, and so select the
25191 proper type in the 'b' case below. */
25192 case V4SImode: case V8HImode: case V16QImode: case V4SFmode:
25193 case V2DImode: case V2DFmode:
25194 result = type;
25195 default: break;
25197 break;
25198 case 'b':
25199 switch (mode)
25201 case DImode: case V2DImode: result = bool_V2DI_type_node; break;
25202 case SImode: case V4SImode: result = bool_V4SI_type_node; break;
25203 case HImode: case V8HImode: result = bool_V8HI_type_node; break;
25204 case QImode: case V16QImode: result = bool_V16QI_type_node;
25205 default: break;
25207 break;
25208 case 'p':
25209 switch (mode)
25211 case V8HImode: result = pixel_V8HI_type_node;
25212 default: break;
25214 default: break;
25217 /* Propagate qualifiers attached to the element type
25218 onto the vector type. */
25219 if (result && result != type && TYPE_QUALS (type))
25220 result = build_qualified_type (result, TYPE_QUALS (type));
25222 *no_add_attrs = true; /* No need to hang on to the attribute. */
25224 if (result)
25225 *node = lang_hooks.types.reconstruct_complex_type (*node, result);
25227 return NULL_TREE;
25230 /* AltiVec defines four built-in scalar types that serve as vector
25231 elements; we must teach the compiler how to mangle them. */
25233 static const char *
25234 rs6000_mangle_type (const_tree type)
25236 type = TYPE_MAIN_VARIANT (type);
25238 if (TREE_CODE (type) != VOID_TYPE && TREE_CODE (type) != BOOLEAN_TYPE
25239 && TREE_CODE (type) != INTEGER_TYPE && TREE_CODE (type) != REAL_TYPE)
25240 return NULL;
25242 if (type == bool_char_type_node) return "U6__boolc";
25243 if (type == bool_short_type_node) return "U6__bools";
25244 if (type == pixel_type_node) return "u7__pixel";
25245 if (type == bool_int_type_node) return "U6__booli";
25246 if (type == bool_long_type_node) return "U6__booll";
25248 /* Mangle IBM extended float long double as `g' (__float128) on
25249 powerpc*-linux where long-double-64 previously was the default. */
25250 if (TYPE_MAIN_VARIANT (type) == long_double_type_node
25251 && TARGET_ELF
25252 && TARGET_LONG_DOUBLE_128
25253 && !TARGET_IEEEQUAD)
25254 return "g";
25256 /* For all other types, use normal C++ mangling. */
25257 return NULL;
25260 /* Handle a "longcall" or "shortcall" attribute; arguments as in
25261 struct attribute_spec.handler. */
25263 static tree
25264 rs6000_handle_longcall_attribute (tree *node, tree name,
25265 tree args ATTRIBUTE_UNUSED,
25266 int flags ATTRIBUTE_UNUSED,
25267 bool *no_add_attrs)
25269 if (TREE_CODE (*node) != FUNCTION_TYPE
25270 && TREE_CODE (*node) != FIELD_DECL
25271 && TREE_CODE (*node) != TYPE_DECL)
25273 warning (OPT_Wattributes, "%qE attribute only applies to functions",
25274 name);
25275 *no_add_attrs = true;
25278 return NULL_TREE;
25281 /* Set longcall attributes on all functions declared when
25282 rs6000_default_long_calls is true. */
25283 static void
25284 rs6000_set_default_type_attributes (tree type)
25286 if (rs6000_default_long_calls
25287 && (TREE_CODE (type) == FUNCTION_TYPE
25288 || TREE_CODE (type) == METHOD_TYPE))
25289 TYPE_ATTRIBUTES (type) = tree_cons (get_identifier ("longcall"),
25290 NULL_TREE,
25291 TYPE_ATTRIBUTES (type));
25293 #if TARGET_MACHO
25294 darwin_set_default_type_attributes (type);
25295 #endif
25298 /* Return a reference suitable for calling a function with the
25299 longcall attribute. */
25302 rs6000_longcall_ref (rtx call_ref)
25304 const char *call_name;
25305 tree node;
25307 if (GET_CODE (call_ref) != SYMBOL_REF)
25308 return call_ref;
25310 /* System V adds '.' to the internal name, so skip them. */
25311 call_name = XSTR (call_ref, 0);
25312 if (*call_name == '.')
25314 while (*call_name == '.')
25315 call_name++;
25317 node = get_identifier (call_name);
25318 call_ref = gen_rtx_SYMBOL_REF (VOIDmode, IDENTIFIER_POINTER (node));
25321 return force_reg (Pmode, call_ref);
25324 #ifndef TARGET_USE_MS_BITFIELD_LAYOUT
25325 #define TARGET_USE_MS_BITFIELD_LAYOUT 0
25326 #endif
25328 /* Handle a "ms_struct" or "gcc_struct" attribute; arguments as in
25329 struct attribute_spec.handler. */
25330 static tree
25331 rs6000_handle_struct_attribute (tree *node, tree name,
25332 tree args ATTRIBUTE_UNUSED,
25333 int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
25335 tree *type = NULL;
25336 if (DECL_P (*node))
25338 if (TREE_CODE (*node) == TYPE_DECL)
25339 type = &TREE_TYPE (*node);
25341 else
25342 type = node;
25344 if (!(type && (TREE_CODE (*type) == RECORD_TYPE
25345 || TREE_CODE (*type) == UNION_TYPE)))
25347 warning (OPT_Wattributes, "%qE attribute ignored", name);
25348 *no_add_attrs = true;
25351 else if ((is_attribute_p ("ms_struct", name)
25352 && lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (*type)))
25353 || ((is_attribute_p ("gcc_struct", name)
25354 && lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (*type)))))
25356 warning (OPT_Wattributes, "%qE incompatible attribute ignored",
25357 name);
25358 *no_add_attrs = true;
25361 return NULL_TREE;
25364 static bool
25365 rs6000_ms_bitfield_layout_p (const_tree record_type)
25367 return (TARGET_USE_MS_BITFIELD_LAYOUT &&
25368 !lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (record_type)))
25369 || lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (record_type));
25372 #ifdef USING_ELFOS_H
25374 /* A get_unnamed_section callback, used for switching to toc_section. */
25376 static void
25377 rs6000_elf_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
25379 if (DEFAULT_ABI == ABI_AIX
25380 && TARGET_MINIMAL_TOC
25381 && !TARGET_RELOCATABLE)
25383 if (!toc_initialized)
25385 toc_initialized = 1;
25386 fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);
25387 (*targetm.asm_out.internal_label) (asm_out_file, "LCTOC", 0);
25388 fprintf (asm_out_file, "\t.tc ");
25389 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1[TC],");
25390 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
25391 fprintf (asm_out_file, "\n");
25393 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
25394 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
25395 fprintf (asm_out_file, " = .+32768\n");
25397 else
25398 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
25400 else if (DEFAULT_ABI == ABI_AIX && !TARGET_RELOCATABLE)
25401 fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);
25402 else
25404 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
25405 if (!toc_initialized)
25407 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
25408 fprintf (asm_out_file, " = .+32768\n");
25409 toc_initialized = 1;
25414 /* Implement TARGET_ASM_INIT_SECTIONS. */
25416 static void
25417 rs6000_elf_asm_init_sections (void)
25419 toc_section
25420 = get_unnamed_section (0, rs6000_elf_output_toc_section_asm_op, NULL);
25422 sdata2_section
25423 = get_unnamed_section (SECTION_WRITE, output_section_asm_op,
25424 SDATA2_SECTION_ASM_OP);
25427 /* Implement TARGET_SELECT_RTX_SECTION. */
25429 static section *
25430 rs6000_elf_select_rtx_section (enum machine_mode mode, rtx x,
25431 unsigned HOST_WIDE_INT align)
25433 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
25434 return toc_section;
25435 else
25436 return default_elf_select_rtx_section (mode, x, align);
25439 /* For a SYMBOL_REF, set generic flags and then perform some
25440 target-specific processing.
25442 When the AIX ABI is requested on a non-AIX system, replace the
25443 function name with the real name (with a leading .) rather than the
25444 function descriptor name. This saves a lot of overriding code to
25445 read the prefixes. */
25447 static void
25448 rs6000_elf_encode_section_info (tree decl, rtx rtl, int first)
25450 default_encode_section_info (decl, rtl, first);
25452 if (first
25453 && TREE_CODE (decl) == FUNCTION_DECL
25454 && !TARGET_AIX
25455 && DEFAULT_ABI == ABI_AIX)
25457 rtx sym_ref = XEXP (rtl, 0);
25458 size_t len = strlen (XSTR (sym_ref, 0));
25459 char *str = XALLOCAVEC (char, len + 2);
25460 str[0] = '.';
25461 memcpy (str + 1, XSTR (sym_ref, 0), len + 1);
25462 XSTR (sym_ref, 0) = ggc_alloc_string (str, len + 1);
25466 static inline bool
25467 compare_section_name (const char *section, const char *templ)
25469 int len;
25471 len = strlen (templ);
25472 return (strncmp (section, templ, len) == 0
25473 && (section[len] == 0 || section[len] == '.'));
25476 bool
25477 rs6000_elf_in_small_data_p (const_tree decl)
25479 if (rs6000_sdata == SDATA_NONE)
25480 return false;
25482 /* We want to merge strings, so we never consider them small data. */
25483 if (TREE_CODE (decl) == STRING_CST)
25484 return false;
25486 /* Functions are never in the small data area. */
25487 if (TREE_CODE (decl) == FUNCTION_DECL)
25488 return false;
25490 if (TREE_CODE (decl) == VAR_DECL && DECL_SECTION_NAME (decl))
25492 const char *section = TREE_STRING_POINTER (DECL_SECTION_NAME (decl));
25493 if (compare_section_name (section, ".sdata")
25494 || compare_section_name (section, ".sdata2")
25495 || compare_section_name (section, ".gnu.linkonce.s")
25496 || compare_section_name (section, ".sbss")
25497 || compare_section_name (section, ".sbss2")
25498 || compare_section_name (section, ".gnu.linkonce.sb")
25499 || strcmp (section, ".PPC.EMB.sdata0") == 0
25500 || strcmp (section, ".PPC.EMB.sbss0") == 0)
25501 return true;
25503 else
25505 HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (decl));
25507 if (size > 0
25508 && size <= g_switch_value
25509 /* If it's not public, and we're not going to reference it there,
25510 there's no need to put it in the small data section. */
25511 && (rs6000_sdata != SDATA_DATA || TREE_PUBLIC (decl)))
25512 return true;
25515 return false;
25518 #endif /* USING_ELFOS_H */
25520 /* Implement TARGET_USE_BLOCKS_FOR_CONSTANT_P. */
25522 static bool
25523 rs6000_use_blocks_for_constant_p (enum machine_mode mode, const_rtx x)
25525 return !ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode);
25528 /* Return a REG that occurs in ADDR with coefficient 1.
25529 ADDR can be effectively incremented by incrementing REG.
25531 r0 is special and we must not select it as an address
25532 register by this routine since our caller will try to
25533 increment the returned register via an "la" instruction. */
25536 find_addr_reg (rtx addr)
25538 while (GET_CODE (addr) == PLUS)
25540 if (GET_CODE (XEXP (addr, 0)) == REG
25541 && REGNO (XEXP (addr, 0)) != 0)
25542 addr = XEXP (addr, 0);
25543 else if (GET_CODE (XEXP (addr, 1)) == REG
25544 && REGNO (XEXP (addr, 1)) != 0)
25545 addr = XEXP (addr, 1);
25546 else if (CONSTANT_P (XEXP (addr, 0)))
25547 addr = XEXP (addr, 1);
25548 else if (CONSTANT_P (XEXP (addr, 1)))
25549 addr = XEXP (addr, 0);
25550 else
25551 gcc_unreachable ();
25553 gcc_assert (GET_CODE (addr) == REG && REGNO (addr) != 0);
25554 return addr;
25557 void
25558 rs6000_fatal_bad_address (rtx op)
25560 fatal_insn ("bad address", op);
25563 #if TARGET_MACHO
25565 typedef struct branch_island_d {
25566 tree function_name;
25567 tree label_name;
25568 int line_number;
25569 } branch_island;
25571 DEF_VEC_O(branch_island);
25572 DEF_VEC_ALLOC_O(branch_island,gc);
25574 static VEC(branch_island,gc) *branch_islands;
25576 /* Remember to generate a branch island for far calls to the given
25577 function. */
25579 static void
25580 add_compiler_branch_island (tree label_name, tree function_name,
25581 int line_number)
25583 branch_island *bi = VEC_safe_push (branch_island, gc, branch_islands, NULL);
25585 bi->function_name = function_name;
25586 bi->label_name = label_name;
25587 bi->line_number = line_number;
25590 /* Generate far-jump branch islands for everything recorded in
25591 branch_islands. Invoked immediately after the last instruction of
25592 the epilogue has been emitted; the branch islands must be appended
25593 to, and contiguous with, the function body. Mach-O stubs are
25594 generated in machopic_output_stub(). */
25596 static void
25597 macho_branch_islands (void)
25599 char tmp_buf[512];
25601 while (!VEC_empty (branch_island, branch_islands))
25603 branch_island *bi = VEC_last (branch_island, branch_islands);
25604 const char *label = IDENTIFIER_POINTER (bi->label_name);
25605 const char *name = IDENTIFIER_POINTER (bi->function_name);
25606 char name_buf[512];
25607 /* Cheap copy of the details from the Darwin ASM_OUTPUT_LABELREF(). */
25608 if (name[0] == '*' || name[0] == '&')
25609 strcpy (name_buf, name+1);
25610 else
25612 name_buf[0] = '_';
25613 strcpy (name_buf+1, name);
25615 strcpy (tmp_buf, "\n");
25616 strcat (tmp_buf, label);
25617 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
25618 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
25619 dbxout_stabd (N_SLINE, bi->line_number);
25620 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
25621 if (flag_pic)
25623 strcat (tmp_buf, ":\n\tmflr r0\n\tbcl 20,31,");
25624 strcat (tmp_buf, label);
25625 strcat (tmp_buf, "_pic\n");
25626 strcat (tmp_buf, label);
25627 strcat (tmp_buf, "_pic:\n\tmflr r11\n");
25629 strcat (tmp_buf, "\taddis r11,r11,ha16(");
25630 strcat (tmp_buf, name_buf);
25631 strcat (tmp_buf, " - ");
25632 strcat (tmp_buf, label);
25633 strcat (tmp_buf, "_pic)\n");
25635 strcat (tmp_buf, "\tmtlr r0\n");
25637 strcat (tmp_buf, "\taddi r12,r11,lo16(");
25638 strcat (tmp_buf, name_buf);
25639 strcat (tmp_buf, " - ");
25640 strcat (tmp_buf, label);
25641 strcat (tmp_buf, "_pic)\n");
25643 strcat (tmp_buf, "\tmtctr r12\n\tbctr\n");
25645 else
25647 strcat (tmp_buf, ":\nlis r12,hi16(");
25648 strcat (tmp_buf, name_buf);
25649 strcat (tmp_buf, ")\n\tori r12,r12,lo16(");
25650 strcat (tmp_buf, name_buf);
25651 strcat (tmp_buf, ")\n\tmtctr r12\n\tbctr");
25653 output_asm_insn (tmp_buf, 0);
25654 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
25655 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
25656 dbxout_stabd (N_SLINE, bi->line_number);
25657 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
25658 VEC_pop (branch_island, branch_islands);
25662 /* NO_PREVIOUS_DEF checks in the link list whether the function name is
25663 already there or not. */
25665 static int
25666 no_previous_def (tree function_name)
25668 branch_island *bi;
25669 unsigned ix;
25671 FOR_EACH_VEC_ELT (branch_island, branch_islands, ix, bi)
25672 if (function_name == bi->function_name)
25673 return 0;
25674 return 1;
25677 /* GET_PREV_LABEL gets the label name from the previous definition of
25678 the function. */
25680 static tree
25681 get_prev_label (tree function_name)
25683 branch_island *bi;
25684 unsigned ix;
25686 FOR_EACH_VEC_ELT (branch_island, branch_islands, ix, bi)
25687 if (function_name == bi->function_name)
25688 return bi->label_name;
25689 return NULL_TREE;
25692 /* INSN is either a function call or a millicode call. It may have an
25693 unconditional jump in its delay slot.
25695 CALL_DEST is the routine we are calling. */
25697 char *
25698 output_call (rtx insn, rtx *operands, int dest_operand_number,
25699 int cookie_operand_number)
25701 static char buf[256];
25702 if (darwin_emit_branch_islands
25703 && GET_CODE (operands[dest_operand_number]) == SYMBOL_REF
25704 && (INTVAL (operands[cookie_operand_number]) & CALL_LONG))
25706 tree labelname;
25707 tree funname = get_identifier (XSTR (operands[dest_operand_number], 0));
25709 if (no_previous_def (funname))
25711 rtx label_rtx = gen_label_rtx ();
25712 char *label_buf, temp_buf[256];
25713 ASM_GENERATE_INTERNAL_LABEL (temp_buf, "L",
25714 CODE_LABEL_NUMBER (label_rtx));
25715 label_buf = temp_buf[0] == '*' ? temp_buf + 1 : temp_buf;
25716 labelname = get_identifier (label_buf);
25717 add_compiler_branch_island (labelname, funname, insn_line (insn));
25719 else
25720 labelname = get_prev_label (funname);
25722 /* "jbsr foo, L42" is Mach-O for "Link as 'bl foo' if a 'bl'
25723 instruction will reach 'foo', otherwise link as 'bl L42'".
25724 "L42" should be a 'branch island', that will do a far jump to
25725 'foo'. Branch islands are generated in
25726 macho_branch_islands(). */
25727 sprintf (buf, "jbsr %%z%d,%.246s",
25728 dest_operand_number, IDENTIFIER_POINTER (labelname));
25730 else
25731 sprintf (buf, "bl %%z%d", dest_operand_number);
25732 return buf;
25735 /* Generate PIC and indirect symbol stubs. */
25737 void
25738 machopic_output_stub (FILE *file, const char *symb, const char *stub)
25740 unsigned int length;
25741 char *symbol_name, *lazy_ptr_name;
25742 char *local_label_0;
25743 static int label = 0;
25745 /* Lose our funky encoding stuff so it doesn't contaminate the stub. */
25746 symb = (*targetm.strip_name_encoding) (symb);
25749 length = strlen (symb);
25750 symbol_name = XALLOCAVEC (char, length + 32);
25751 GEN_SYMBOL_NAME_FOR_SYMBOL (symbol_name, symb, length);
25753 lazy_ptr_name = XALLOCAVEC (char, length + 32);
25754 GEN_LAZY_PTR_NAME_FOR_SYMBOL (lazy_ptr_name, symb, length);
25756 if (flag_pic == 2)
25757 switch_to_section (darwin_sections[machopic_picsymbol_stub1_section]);
25758 else
25759 switch_to_section (darwin_sections[machopic_symbol_stub1_section]);
25761 if (flag_pic == 2)
25763 fprintf (file, "\t.align 5\n");
25765 fprintf (file, "%s:\n", stub);
25766 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
25768 label++;
25769 local_label_0 = XALLOCAVEC (char, sizeof ("\"L00000000000$spb\""));
25770 sprintf (local_label_0, "\"L%011d$spb\"", label);
25772 fprintf (file, "\tmflr r0\n");
25773 fprintf (file, "\tbcl 20,31,%s\n", local_label_0);
25774 fprintf (file, "%s:\n\tmflr r11\n", local_label_0);
25775 fprintf (file, "\taddis r11,r11,ha16(%s-%s)\n",
25776 lazy_ptr_name, local_label_0);
25777 fprintf (file, "\tmtlr r0\n");
25778 fprintf (file, "\t%s r12,lo16(%s-%s)(r11)\n",
25779 (TARGET_64BIT ? "ldu" : "lwzu"),
25780 lazy_ptr_name, local_label_0);
25781 fprintf (file, "\tmtctr r12\n");
25782 fprintf (file, "\tbctr\n");
25784 else
25786 fprintf (file, "\t.align 4\n");
25788 fprintf (file, "%s:\n", stub);
25789 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
25791 fprintf (file, "\tlis r11,ha16(%s)\n", lazy_ptr_name);
25792 fprintf (file, "\t%s r12,lo16(%s)(r11)\n",
25793 (TARGET_64BIT ? "ldu" : "lwzu"),
25794 lazy_ptr_name);
25795 fprintf (file, "\tmtctr r12\n");
25796 fprintf (file, "\tbctr\n");
25799 switch_to_section (darwin_sections[machopic_lazy_symbol_ptr_section]);
25800 fprintf (file, "%s:\n", lazy_ptr_name);
25801 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
25802 fprintf (file, "%sdyld_stub_binding_helper\n",
25803 (TARGET_64BIT ? DOUBLE_INT_ASM_OP : "\t.long\t"));
25806 /* Legitimize PIC addresses. If the address is already
25807 position-independent, we return ORIG. Newly generated
25808 position-independent addresses go into a reg. This is REG if non
25809 zero, otherwise we allocate register(s) as necessary. */
25811 #define SMALL_INT(X) ((UINTVAL (X) + 0x8000) < 0x10000)
25814 rs6000_machopic_legitimize_pic_address (rtx orig, enum machine_mode mode,
25815 rtx reg)
25817 rtx base, offset;
25819 if (reg == NULL && ! reload_in_progress && ! reload_completed)
25820 reg = gen_reg_rtx (Pmode);
25822 if (GET_CODE (orig) == CONST)
25824 rtx reg_temp;
25826 if (GET_CODE (XEXP (orig, 0)) == PLUS
25827 && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx)
25828 return orig;
25830 gcc_assert (GET_CODE (XEXP (orig, 0)) == PLUS);
25832 /* Use a different reg for the intermediate value, as
25833 it will be marked UNCHANGING. */
25834 reg_temp = !can_create_pseudo_p () ? reg : gen_reg_rtx (Pmode);
25835 base = rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 0),
25836 Pmode, reg_temp);
25837 offset =
25838 rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 1),
25839 Pmode, reg);
25841 if (GET_CODE (offset) == CONST_INT)
25843 if (SMALL_INT (offset))
25844 return plus_constant (base, INTVAL (offset));
25845 else if (! reload_in_progress && ! reload_completed)
25846 offset = force_reg (Pmode, offset);
25847 else
25849 rtx mem = force_const_mem (Pmode, orig);
25850 return machopic_legitimize_pic_address (mem, Pmode, reg);
25853 return gen_rtx_PLUS (Pmode, base, offset);
25856 /* Fall back on generic machopic code. */
25857 return machopic_legitimize_pic_address (orig, mode, reg);
25860 /* Output a .machine directive for the Darwin assembler, and call
25861 the generic start_file routine. */
25863 static void
25864 rs6000_darwin_file_start (void)
25866 static const struct
25868 const char *arg;
25869 const char *name;
25870 int if_set;
25871 } mapping[] = {
25872 { "ppc64", "ppc64", MASK_64BIT },
25873 { "970", "ppc970", MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64 },
25874 { "power4", "ppc970", 0 },
25875 { "G5", "ppc970", 0 },
25876 { "7450", "ppc7450", 0 },
25877 { "7400", "ppc7400", MASK_ALTIVEC },
25878 { "G4", "ppc7400", 0 },
25879 { "750", "ppc750", 0 },
25880 { "740", "ppc750", 0 },
25881 { "G3", "ppc750", 0 },
25882 { "604e", "ppc604e", 0 },
25883 { "604", "ppc604", 0 },
25884 { "603e", "ppc603", 0 },
25885 { "603", "ppc603", 0 },
25886 { "601", "ppc601", 0 },
25887 { NULL, "ppc", 0 } };
25888 const char *cpu_id = "";
25889 size_t i;
25891 rs6000_file_start ();
25892 darwin_file_start ();
25894 /* Determine the argument to -mcpu=. Default to G3 if not specified. */
25895 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
25896 if (rs6000_select[i].set_arch_p && rs6000_select[i].string
25897 && rs6000_select[i].string[0] != '\0')
25898 cpu_id = rs6000_select[i].string;
25900 /* Look through the mapping array. Pick the first name that either
25901 matches the argument, has a bit set in IF_SET that is also set
25902 in the target flags, or has a NULL name. */
25904 i = 0;
25905 while (mapping[i].arg != NULL
25906 && strcmp (mapping[i].arg, cpu_id) != 0
25907 && (mapping[i].if_set & target_flags) == 0)
25908 i++;
25910 fprintf (asm_out_file, "\t.machine %s\n", mapping[i].name);
25913 #endif /* TARGET_MACHO */
25915 #if TARGET_ELF
25916 static int
25917 rs6000_elf_reloc_rw_mask (void)
25919 if (flag_pic)
25920 return 3;
25921 else if (DEFAULT_ABI == ABI_AIX)
25922 return 2;
25923 else
25924 return 0;
25927 /* Record an element in the table of global constructors. SYMBOL is
25928 a SYMBOL_REF of the function to be called; PRIORITY is a number
25929 between 0 and MAX_INIT_PRIORITY.
25931 This differs from default_named_section_asm_out_constructor in
25932 that we have special handling for -mrelocatable. */
25934 static void
25935 rs6000_elf_asm_out_constructor (rtx symbol, int priority)
25937 const char *section = ".ctors";
25938 char buf[16];
25940 if (priority != DEFAULT_INIT_PRIORITY)
25942 sprintf (buf, ".ctors.%.5u",
25943 /* Invert the numbering so the linker puts us in the proper
25944 order; constructors are run from right to left, and the
25945 linker sorts in increasing order. */
25946 MAX_INIT_PRIORITY - priority);
25947 section = buf;
25950 switch_to_section (get_section (section, SECTION_WRITE, NULL));
25951 assemble_align (POINTER_SIZE);
25953 if (TARGET_RELOCATABLE)
25955 fputs ("\t.long (", asm_out_file);
25956 output_addr_const (asm_out_file, symbol);
25957 fputs (")@fixup\n", asm_out_file);
25959 else
25960 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
25963 static void
25964 rs6000_elf_asm_out_destructor (rtx symbol, int priority)
25966 const char *section = ".dtors";
25967 char buf[16];
25969 if (priority != DEFAULT_INIT_PRIORITY)
25971 sprintf (buf, ".dtors.%.5u",
25972 /* Invert the numbering so the linker puts us in the proper
25973 order; constructors are run from right to left, and the
25974 linker sorts in increasing order. */
25975 MAX_INIT_PRIORITY - priority);
25976 section = buf;
25979 switch_to_section (get_section (section, SECTION_WRITE, NULL));
25980 assemble_align (POINTER_SIZE);
25982 if (TARGET_RELOCATABLE)
25984 fputs ("\t.long (", asm_out_file);
25985 output_addr_const (asm_out_file, symbol);
25986 fputs (")@fixup\n", asm_out_file);
25988 else
25989 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
25992 void
25993 rs6000_elf_declare_function_name (FILE *file, const char *name, tree decl)
25995 if (TARGET_64BIT)
25997 fputs ("\t.section\t\".opd\",\"aw\"\n\t.align 3\n", file);
25998 ASM_OUTPUT_LABEL (file, name);
25999 fputs (DOUBLE_INT_ASM_OP, file);
26000 rs6000_output_function_entry (file, name);
26001 fputs (",.TOC.@tocbase,0\n\t.previous\n", file);
26002 if (DOT_SYMBOLS)
26004 fputs ("\t.size\t", file);
26005 assemble_name (file, name);
26006 fputs (",24\n\t.type\t.", file);
26007 assemble_name (file, name);
26008 fputs (",@function\n", file);
26009 if (TREE_PUBLIC (decl) && ! DECL_WEAK (decl))
26011 fputs ("\t.globl\t.", file);
26012 assemble_name (file, name);
26013 putc ('\n', file);
26016 else
26017 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
26018 ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
26019 rs6000_output_function_entry (file, name);
26020 fputs (":\n", file);
26021 return;
26024 if (TARGET_RELOCATABLE
26025 && !TARGET_SECURE_PLT
26026 && (get_pool_size () != 0 || crtl->profile)
26027 && uses_TOC ())
26029 char buf[256];
26031 (*targetm.asm_out.internal_label) (file, "LCL", rs6000_pic_labelno);
26033 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
26034 fprintf (file, "\t.long ");
26035 assemble_name (file, buf);
26036 putc ('-', file);
26037 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
26038 assemble_name (file, buf);
26039 putc ('\n', file);
26042 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
26043 ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
26045 if (DEFAULT_ABI == ABI_AIX)
26047 const char *desc_name, *orig_name;
26049 orig_name = (*targetm.strip_name_encoding) (name);
26050 desc_name = orig_name;
26051 while (*desc_name == '.')
26052 desc_name++;
26054 if (TREE_PUBLIC (decl))
26055 fprintf (file, "\t.globl %s\n", desc_name);
26057 fprintf (file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
26058 fprintf (file, "%s:\n", desc_name);
26059 fprintf (file, "\t.long %s\n", orig_name);
26060 fputs ("\t.long _GLOBAL_OFFSET_TABLE_\n", file);
26061 if (DEFAULT_ABI == ABI_AIX)
26062 fputs ("\t.long 0\n", file);
26063 fprintf (file, "\t.previous\n");
26065 ASM_OUTPUT_LABEL (file, name);
26068 static void
26069 rs6000_elf_file_end (void)
26071 #ifdef HAVE_AS_GNU_ATTRIBUTE
26072 if (TARGET_32BIT && DEFAULT_ABI == ABI_V4)
26074 if (rs6000_passes_float)
26075 fprintf (asm_out_file, "\t.gnu_attribute 4, %d\n",
26076 ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT) ? 1
26077 : (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT) ? 3
26078 : 2));
26079 if (rs6000_passes_vector)
26080 fprintf (asm_out_file, "\t.gnu_attribute 8, %d\n",
26081 (TARGET_ALTIVEC_ABI ? 2
26082 : TARGET_SPE_ABI ? 3
26083 : 1));
26084 if (rs6000_returns_struct)
26085 fprintf (asm_out_file, "\t.gnu_attribute 12, %d\n",
26086 aix_struct_return ? 2 : 1);
26088 #endif
26089 #ifdef POWERPC_LINUX
26090 if (TARGET_32BIT)
26091 file_end_indicate_exec_stack ();
26092 #endif
26094 #endif
26096 #if TARGET_XCOFF
26097 static void
26098 rs6000_xcoff_asm_output_anchor (rtx symbol)
26100 char buffer[100];
26102 sprintf (buffer, "$ + " HOST_WIDE_INT_PRINT_DEC,
26103 SYMBOL_REF_BLOCK_OFFSET (symbol));
26104 ASM_OUTPUT_DEF (asm_out_file, XSTR (symbol, 0), buffer);
26107 static void
26108 rs6000_xcoff_asm_globalize_label (FILE *stream, const char *name)
26110 fputs (GLOBAL_ASM_OP, stream);
26111 RS6000_OUTPUT_BASENAME (stream, name);
26112 putc ('\n', stream);
26115 /* A get_unnamed_decl callback, used for read-only sections. PTR
26116 points to the section string variable. */
26118 static void
26119 rs6000_xcoff_output_readonly_section_asm_op (const void *directive)
26121 fprintf (asm_out_file, "\t.csect %s[RO],%s\n",
26122 *(const char *const *) directive,
26123 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR);
26126 /* Likewise for read-write sections. */
26128 static void
26129 rs6000_xcoff_output_readwrite_section_asm_op (const void *directive)
26131 fprintf (asm_out_file, "\t.csect %s[RW],%s\n",
26132 *(const char *const *) directive,
26133 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR);
26136 /* A get_unnamed_section callback, used for switching to toc_section. */
26138 static void
26139 rs6000_xcoff_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
26141 if (TARGET_MINIMAL_TOC)
26143 /* toc_section is always selected at least once from
26144 rs6000_xcoff_file_start, so this is guaranteed to
26145 always be defined once and only once in each file. */
26146 if (!toc_initialized)
26148 fputs ("\t.toc\nLCTOC..1:\n", asm_out_file);
26149 fputs ("\t.tc toc_table[TC],toc_table[RW]\n", asm_out_file);
26150 toc_initialized = 1;
26152 fprintf (asm_out_file, "\t.csect toc_table[RW]%s\n",
26153 (TARGET_32BIT ? "" : ",3"));
26155 else
26156 fputs ("\t.toc\n", asm_out_file);
26159 /* Implement TARGET_ASM_INIT_SECTIONS. */
26161 static void
26162 rs6000_xcoff_asm_init_sections (void)
26164 read_only_data_section
26165 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
26166 &xcoff_read_only_section_name);
26168 private_data_section
26169 = get_unnamed_section (SECTION_WRITE,
26170 rs6000_xcoff_output_readwrite_section_asm_op,
26171 &xcoff_private_data_section_name);
26173 read_only_private_data_section
26174 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
26175 &xcoff_private_data_section_name);
26177 toc_section
26178 = get_unnamed_section (0, rs6000_xcoff_output_toc_section_asm_op, NULL);
26180 readonly_data_section = read_only_data_section;
26181 exception_section = data_section;
26184 static int
26185 rs6000_xcoff_reloc_rw_mask (void)
26187 return 3;
26190 static void
26191 rs6000_xcoff_asm_named_section (const char *name, unsigned int flags,
26192 tree decl ATTRIBUTE_UNUSED)
26194 int smclass;
26195 static const char * const suffix[3] = { "PR", "RO", "RW" };
26197 if (flags & SECTION_CODE)
26198 smclass = 0;
26199 else if (flags & SECTION_WRITE)
26200 smclass = 2;
26201 else
26202 smclass = 1;
26204 fprintf (asm_out_file, "\t.csect %s%s[%s],%u\n",
26205 (flags & SECTION_CODE) ? "." : "",
26206 name, suffix[smclass], flags & SECTION_ENTSIZE);
26209 static section *
26210 rs6000_xcoff_select_section (tree decl, int reloc,
26211 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
26213 if (decl_readonly_section (decl, reloc))
26215 if (TREE_PUBLIC (decl))
26216 return read_only_data_section;
26217 else
26218 return read_only_private_data_section;
26220 else
26222 if (TREE_PUBLIC (decl))
26223 return data_section;
26224 else
26225 return private_data_section;
26229 static void
26230 rs6000_xcoff_unique_section (tree decl, int reloc ATTRIBUTE_UNUSED)
26232 const char *name;
26234 /* Use select_section for private and uninitialized data. */
26235 if (!TREE_PUBLIC (decl)
26236 || DECL_COMMON (decl)
26237 || DECL_INITIAL (decl) == NULL_TREE
26238 || DECL_INITIAL (decl) == error_mark_node
26239 || (flag_zero_initialized_in_bss
26240 && initializer_zerop (DECL_INITIAL (decl))))
26241 return;
26243 name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
26244 name = (*targetm.strip_name_encoding) (name);
26245 DECL_SECTION_NAME (decl) = build_string (strlen (name), name);
26248 /* Select section for constant in constant pool.
26250 On RS/6000, all constants are in the private read-only data area.
26251 However, if this is being placed in the TOC it must be output as a
26252 toc entry. */
26254 static section *
26255 rs6000_xcoff_select_rtx_section (enum machine_mode mode, rtx x,
26256 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
26258 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
26259 return toc_section;
26260 else
26261 return read_only_private_data_section;
26264 /* Remove any trailing [DS] or the like from the symbol name. */
26266 static const char *
26267 rs6000_xcoff_strip_name_encoding (const char *name)
26269 size_t len;
26270 if (*name == '*')
26271 name++;
26272 len = strlen (name);
26273 if (name[len - 1] == ']')
26274 return ggc_alloc_string (name, len - 4);
26275 else
26276 return name;
26279 /* Section attributes. AIX is always PIC. */
26281 static unsigned int
26282 rs6000_xcoff_section_type_flags (tree decl, const char *name, int reloc)
26284 unsigned int align;
26285 unsigned int flags = default_section_type_flags (decl, name, reloc);
26287 /* Align to at least UNIT size. */
26288 if (flags & SECTION_CODE)
26289 align = MIN_UNITS_PER_WORD;
26290 else
26291 /* Increase alignment of large objects if not already stricter. */
26292 align = MAX ((DECL_ALIGN (decl) / BITS_PER_UNIT),
26293 int_size_in_bytes (TREE_TYPE (decl)) > MIN_UNITS_PER_WORD
26294 ? UNITS_PER_FP_WORD : MIN_UNITS_PER_WORD);
26296 return flags | (exact_log2 (align) & SECTION_ENTSIZE);
26299 /* Output at beginning of assembler file.
26301 Initialize the section names for the RS/6000 at this point.
26303 Specify filename, including full path, to assembler.
26305 We want to go into the TOC section so at least one .toc will be emitted.
26306 Also, in order to output proper .bs/.es pairs, we need at least one static
26307 [RW] section emitted.
26309 Finally, declare mcount when profiling to make the assembler happy. */
26311 static void
26312 rs6000_xcoff_file_start (void)
26314 rs6000_gen_section_name (&xcoff_bss_section_name,
26315 main_input_filename, ".bss_");
26316 rs6000_gen_section_name (&xcoff_private_data_section_name,
26317 main_input_filename, ".rw_");
26318 rs6000_gen_section_name (&xcoff_read_only_section_name,
26319 main_input_filename, ".ro_");
26321 fputs ("\t.file\t", asm_out_file);
26322 output_quoted_string (asm_out_file, main_input_filename);
26323 fputc ('\n', asm_out_file);
26324 if (write_symbols != NO_DEBUG)
26325 switch_to_section (private_data_section);
26326 switch_to_section (text_section);
26327 if (profile_flag)
26328 fprintf (asm_out_file, "\t.extern %s\n", RS6000_MCOUNT);
26329 rs6000_file_start ();
26332 /* Output at end of assembler file.
26333 On the RS/6000, referencing data should automatically pull in text. */
26335 static void
26336 rs6000_xcoff_file_end (void)
26338 switch_to_section (text_section);
26339 fputs ("_section_.text:\n", asm_out_file);
26340 switch_to_section (data_section);
26341 fputs (TARGET_32BIT
26342 ? "\t.long _section_.text\n" : "\t.llong _section_.text\n",
26343 asm_out_file);
26345 #endif /* TARGET_XCOFF */
26347 /* Compute a (partial) cost for rtx X. Return true if the complete
26348 cost has been computed, and false if subexpressions should be
26349 scanned. In either case, *TOTAL contains the cost result. */
26351 static bool
26352 rs6000_rtx_costs (rtx x, int code, int outer_code, int *total,
26353 bool speed)
26355 enum machine_mode mode = GET_MODE (x);
26357 switch (code)
26359 /* On the RS/6000, if it is valid in the insn, it is free. */
26360 case CONST_INT:
26361 if (((outer_code == SET
26362 || outer_code == PLUS
26363 || outer_code == MINUS)
26364 && (satisfies_constraint_I (x)
26365 || satisfies_constraint_L (x)))
26366 || (outer_code == AND
26367 && (satisfies_constraint_K (x)
26368 || (mode == SImode
26369 ? satisfies_constraint_L (x)
26370 : satisfies_constraint_J (x))
26371 || mask_operand (x, mode)
26372 || (mode == DImode
26373 && mask64_operand (x, DImode))))
26374 || ((outer_code == IOR || outer_code == XOR)
26375 && (satisfies_constraint_K (x)
26376 || (mode == SImode
26377 ? satisfies_constraint_L (x)
26378 : satisfies_constraint_J (x))))
26379 || outer_code == ASHIFT
26380 || outer_code == ASHIFTRT
26381 || outer_code == LSHIFTRT
26382 || outer_code == ROTATE
26383 || outer_code == ROTATERT
26384 || outer_code == ZERO_EXTRACT
26385 || (outer_code == MULT
26386 && satisfies_constraint_I (x))
26387 || ((outer_code == DIV || outer_code == UDIV
26388 || outer_code == MOD || outer_code == UMOD)
26389 && exact_log2 (INTVAL (x)) >= 0)
26390 || (outer_code == COMPARE
26391 && (satisfies_constraint_I (x)
26392 || satisfies_constraint_K (x)))
26393 || ((outer_code == EQ || outer_code == NE)
26394 && (satisfies_constraint_I (x)
26395 || satisfies_constraint_K (x)
26396 || (mode == SImode
26397 ? satisfies_constraint_L (x)
26398 : satisfies_constraint_J (x))))
26399 || (outer_code == GTU
26400 && satisfies_constraint_I (x))
26401 || (outer_code == LTU
26402 && satisfies_constraint_P (x)))
26404 *total = 0;
26405 return true;
26407 else if ((outer_code == PLUS
26408 && reg_or_add_cint_operand (x, VOIDmode))
26409 || (outer_code == MINUS
26410 && reg_or_sub_cint_operand (x, VOIDmode))
26411 || ((outer_code == SET
26412 || outer_code == IOR
26413 || outer_code == XOR)
26414 && (INTVAL (x)
26415 & ~ (unsigned HOST_WIDE_INT) 0xffffffff) == 0))
26417 *total = COSTS_N_INSNS (1);
26418 return true;
26420 /* FALLTHRU */
26422 case CONST_DOUBLE:
26423 if (mode == DImode && code == CONST_DOUBLE)
26425 if ((outer_code == IOR || outer_code == XOR)
26426 && CONST_DOUBLE_HIGH (x) == 0
26427 && (CONST_DOUBLE_LOW (x)
26428 & ~ (unsigned HOST_WIDE_INT) 0xffff) == 0)
26430 *total = 0;
26431 return true;
26433 else if ((outer_code == AND && and64_2_operand (x, DImode))
26434 || ((outer_code == SET
26435 || outer_code == IOR
26436 || outer_code == XOR)
26437 && CONST_DOUBLE_HIGH (x) == 0))
26439 *total = COSTS_N_INSNS (1);
26440 return true;
26443 /* FALLTHRU */
26445 case CONST:
26446 case HIGH:
26447 case SYMBOL_REF:
26448 case MEM:
26449 /* When optimizing for size, MEM should be slightly more expensive
26450 than generating address, e.g., (plus (reg) (const)).
26451 L1 cache latency is about two instructions. */
26452 *total = !speed ? COSTS_N_INSNS (1) + 1 : COSTS_N_INSNS (2);
26453 return true;
26455 case LABEL_REF:
26456 *total = 0;
26457 return true;
26459 case PLUS:
26460 case MINUS:
26461 if (FLOAT_MODE_P (mode))
26462 *total = rs6000_cost->fp;
26463 else
26464 *total = COSTS_N_INSNS (1);
26465 return false;
26467 case MULT:
26468 if (GET_CODE (XEXP (x, 1)) == CONST_INT
26469 && satisfies_constraint_I (XEXP (x, 1)))
26471 if (INTVAL (XEXP (x, 1)) >= -256
26472 && INTVAL (XEXP (x, 1)) <= 255)
26473 *total = rs6000_cost->mulsi_const9;
26474 else
26475 *total = rs6000_cost->mulsi_const;
26477 else if (mode == SFmode)
26478 *total = rs6000_cost->fp;
26479 else if (FLOAT_MODE_P (mode))
26480 *total = rs6000_cost->dmul;
26481 else if (mode == DImode)
26482 *total = rs6000_cost->muldi;
26483 else
26484 *total = rs6000_cost->mulsi;
26485 return false;
26487 case FMA:
26488 if (mode == SFmode)
26489 *total = rs6000_cost->fp;
26490 else
26491 *total = rs6000_cost->dmul;
26492 break;
26494 case DIV:
26495 case MOD:
26496 if (FLOAT_MODE_P (mode))
26498 *total = mode == DFmode ? rs6000_cost->ddiv
26499 : rs6000_cost->sdiv;
26500 return false;
26502 /* FALLTHRU */
26504 case UDIV:
26505 case UMOD:
26506 if (GET_CODE (XEXP (x, 1)) == CONST_INT
26507 && exact_log2 (INTVAL (XEXP (x, 1))) >= 0)
26509 if (code == DIV || code == MOD)
26510 /* Shift, addze */
26511 *total = COSTS_N_INSNS (2);
26512 else
26513 /* Shift */
26514 *total = COSTS_N_INSNS (1);
26516 else
26518 if (GET_MODE (XEXP (x, 1)) == DImode)
26519 *total = rs6000_cost->divdi;
26520 else
26521 *total = rs6000_cost->divsi;
26523 /* Add in shift and subtract for MOD. */
26524 if (code == MOD || code == UMOD)
26525 *total += COSTS_N_INSNS (2);
26526 return false;
26528 case CTZ:
26529 case FFS:
26530 *total = COSTS_N_INSNS (4);
26531 return false;
26533 case POPCOUNT:
26534 *total = COSTS_N_INSNS (TARGET_POPCNTD ? 1 : 6);
26535 return false;
26537 case PARITY:
26538 *total = COSTS_N_INSNS (TARGET_CMPB ? 2 : 6);
26539 return false;
26541 case NOT:
26542 if (outer_code == AND || outer_code == IOR || outer_code == XOR)
26544 *total = 0;
26545 return false;
26547 /* FALLTHRU */
26549 case AND:
26550 case CLZ:
26551 case IOR:
26552 case XOR:
26553 case ZERO_EXTRACT:
26554 *total = COSTS_N_INSNS (1);
26555 return false;
26557 case ASHIFT:
26558 case ASHIFTRT:
26559 case LSHIFTRT:
26560 case ROTATE:
26561 case ROTATERT:
26562 /* Handle mul_highpart. */
26563 if (outer_code == TRUNCATE
26564 && GET_CODE (XEXP (x, 0)) == MULT)
26566 if (mode == DImode)
26567 *total = rs6000_cost->muldi;
26568 else
26569 *total = rs6000_cost->mulsi;
26570 return true;
26572 else if (outer_code == AND)
26573 *total = 0;
26574 else
26575 *total = COSTS_N_INSNS (1);
26576 return false;
26578 case SIGN_EXTEND:
26579 case ZERO_EXTEND:
26580 if (GET_CODE (XEXP (x, 0)) == MEM)
26581 *total = 0;
26582 else
26583 *total = COSTS_N_INSNS (1);
26584 return false;
26586 case COMPARE:
26587 case NEG:
26588 case ABS:
26589 if (!FLOAT_MODE_P (mode))
26591 *total = COSTS_N_INSNS (1);
26592 return false;
26594 /* FALLTHRU */
26596 case FLOAT:
26597 case UNSIGNED_FLOAT:
26598 case FIX:
26599 case UNSIGNED_FIX:
26600 case FLOAT_TRUNCATE:
26601 *total = rs6000_cost->fp;
26602 return false;
26604 case FLOAT_EXTEND:
26605 if (mode == DFmode)
26606 *total = 0;
26607 else
26608 *total = rs6000_cost->fp;
26609 return false;
26611 case UNSPEC:
26612 switch (XINT (x, 1))
26614 case UNSPEC_FRSP:
26615 *total = rs6000_cost->fp;
26616 return true;
26618 default:
26619 break;
26621 break;
26623 case CALL:
26624 case IF_THEN_ELSE:
26625 if (!speed)
26627 *total = COSTS_N_INSNS (1);
26628 return true;
26630 else if (FLOAT_MODE_P (mode)
26631 && TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS)
26633 *total = rs6000_cost->fp;
26634 return false;
26636 break;
26638 case EQ:
26639 case GTU:
26640 case LTU:
26641 /* Carry bit requires mode == Pmode.
26642 NEG or PLUS already counted so only add one. */
26643 if (mode == Pmode
26644 && (outer_code == NEG || outer_code == PLUS))
26646 *total = COSTS_N_INSNS (1);
26647 return true;
26649 if (outer_code == SET)
26651 if (XEXP (x, 1) == const0_rtx)
26653 if (TARGET_ISEL && !TARGET_MFCRF)
26654 *total = COSTS_N_INSNS (8);
26655 else
26656 *total = COSTS_N_INSNS (2);
26657 return true;
26659 else if (mode == Pmode)
26661 *total = COSTS_N_INSNS (3);
26662 return false;
26665 /* FALLTHRU */
26667 case GT:
26668 case LT:
26669 case UNORDERED:
26670 if (outer_code == SET && (XEXP (x, 1) == const0_rtx))
26672 if (TARGET_ISEL && !TARGET_MFCRF)
26673 *total = COSTS_N_INSNS (8);
26674 else
26675 *total = COSTS_N_INSNS (2);
26676 return true;
26678 /* CC COMPARE. */
26679 if (outer_code == COMPARE)
26681 *total = 0;
26682 return true;
26684 break;
26686 default:
26687 break;
26690 return false;
26693 /* Debug form of r6000_rtx_costs that is selected if -mdebug=cost. */
26695 static bool
26696 rs6000_debug_rtx_costs (rtx x, int code, int outer_code, int *total,
26697 bool speed)
26699 bool ret = rs6000_rtx_costs (x, code, outer_code, total, speed);
26701 fprintf (stderr,
26702 "\nrs6000_rtx_costs, return = %s, code = %s, outer_code = %s, "
26703 "total = %d, speed = %s, x:\n",
26704 ret ? "complete" : "scan inner",
26705 GET_RTX_NAME (code),
26706 GET_RTX_NAME (outer_code),
26707 *total,
26708 speed ? "true" : "false");
26710 debug_rtx (x);
26712 return ret;
26715 /* Debug form of ADDRESS_COST that is selected if -mdebug=cost. */
26717 static int
26718 rs6000_debug_address_cost (rtx x, bool speed)
26720 int ret = TARGET_ADDRESS_COST (x, speed);
26722 fprintf (stderr, "\nrs6000_address_cost, return = %d, speed = %s, x:\n",
26723 ret, speed ? "true" : "false");
26724 debug_rtx (x);
26726 return ret;
26730 /* A C expression returning the cost of moving data from a register of class
26731 CLASS1 to one of CLASS2. */
26733 static int
26734 rs6000_register_move_cost (enum machine_mode mode,
26735 reg_class_t from, reg_class_t to)
26737 int ret;
26739 /* Moves from/to GENERAL_REGS. */
26740 if (reg_classes_intersect_p (to, GENERAL_REGS)
26741 || reg_classes_intersect_p (from, GENERAL_REGS))
26743 if (! reg_classes_intersect_p (to, GENERAL_REGS))
26744 from = to;
26746 if (from == FLOAT_REGS || from == ALTIVEC_REGS || from == VSX_REGS)
26747 ret = (rs6000_memory_move_cost (mode, from, false)
26748 + rs6000_memory_move_cost (mode, GENERAL_REGS, false));
26750 /* It's more expensive to move CR_REGS than CR0_REGS because of the
26751 shift. */
26752 else if (from == CR_REGS)
26753 ret = 4;
26755 /* Power6 has slower LR/CTR moves so make them more expensive than
26756 memory in order to bias spills to memory .*/
26757 else if (rs6000_cpu == PROCESSOR_POWER6
26758 && reg_classes_intersect_p (from, LINK_OR_CTR_REGS))
26759 ret = 6 * hard_regno_nregs[0][mode];
26761 else
26762 /* A move will cost one instruction per GPR moved. */
26763 ret = 2 * hard_regno_nregs[0][mode];
26766 /* If we have VSX, we can easily move between FPR or Altivec registers. */
26767 else if (VECTOR_UNIT_VSX_P (mode)
26768 && reg_classes_intersect_p (to, VSX_REGS)
26769 && reg_classes_intersect_p (from, VSX_REGS))
26770 ret = 2 * hard_regno_nregs[32][mode];
26772 /* Moving between two similar registers is just one instruction. */
26773 else if (reg_classes_intersect_p (to, from))
26774 ret = (mode == TFmode || mode == TDmode) ? 4 : 2;
26776 /* Everything else has to go through GENERAL_REGS. */
26777 else
26778 ret = (rs6000_register_move_cost (mode, GENERAL_REGS, to)
26779 + rs6000_register_move_cost (mode, from, GENERAL_REGS));
26781 if (TARGET_DEBUG_COST)
26782 fprintf (stderr,
26783 "rs6000_register_move_cost:, ret=%d, mode=%s, from=%s, to=%s\n",
26784 ret, GET_MODE_NAME (mode), reg_class_names[from],
26785 reg_class_names[to]);
26787 return ret;
26790 /* A C expressions returning the cost of moving data of MODE from a register to
26791 or from memory. */
26793 static int
26794 rs6000_memory_move_cost (enum machine_mode mode, reg_class_t rclass,
26795 bool in ATTRIBUTE_UNUSED)
26797 int ret;
26799 if (reg_classes_intersect_p (rclass, GENERAL_REGS))
26800 ret = 4 * hard_regno_nregs[0][mode];
26801 else if (reg_classes_intersect_p (rclass, FLOAT_REGS))
26802 ret = 4 * hard_regno_nregs[32][mode];
26803 else if (reg_classes_intersect_p (rclass, ALTIVEC_REGS))
26804 ret = 4 * hard_regno_nregs[FIRST_ALTIVEC_REGNO][mode];
26805 else
26806 ret = 4 + rs6000_register_move_cost (mode, rclass, GENERAL_REGS);
26808 if (TARGET_DEBUG_COST)
26809 fprintf (stderr,
26810 "rs6000_memory_move_cost: ret=%d, mode=%s, rclass=%s, in=%d\n",
26811 ret, GET_MODE_NAME (mode), reg_class_names[rclass], in);
26813 return ret;
26816 /* Returns a code for a target-specific builtin that implements
26817 reciprocal of the function, or NULL_TREE if not available. */
26819 static tree
26820 rs6000_builtin_reciprocal (unsigned int fn, bool md_fn,
26821 bool sqrt ATTRIBUTE_UNUSED)
26823 if (optimize_insn_for_size_p ())
26824 return NULL_TREE;
26826 if (md_fn)
26827 switch (fn)
26829 case VSX_BUILTIN_XVSQRTDP:
26830 if (!RS6000_RECIP_AUTO_RSQRTE_P (V2DFmode))
26831 return NULL_TREE;
26833 return rs6000_builtin_decls[VSX_BUILTIN_VEC_RSQRT_V2DF];
26835 case VSX_BUILTIN_XVSQRTSP:
26836 if (!RS6000_RECIP_AUTO_RSQRTE_P (V4SFmode))
26837 return NULL_TREE;
26839 return rs6000_builtin_decls[VSX_BUILTIN_VEC_RSQRT_V4SF];
26841 default:
26842 return NULL_TREE;
26845 else
26846 switch (fn)
26848 case BUILT_IN_SQRT:
26849 if (!RS6000_RECIP_AUTO_RSQRTE_P (DFmode))
26850 return NULL_TREE;
26852 return rs6000_builtin_decls[RS6000_BUILTIN_RSQRT];
26854 case BUILT_IN_SQRTF:
26855 if (!RS6000_RECIP_AUTO_RSQRTE_P (SFmode))
26856 return NULL_TREE;
26858 return rs6000_builtin_decls[RS6000_BUILTIN_RSQRTF];
26860 default:
26861 return NULL_TREE;
26865 /* Load up a constant. If the mode is a vector mode, splat the value across
26866 all of the vector elements. */
26868 static rtx
26869 rs6000_load_constant_and_splat (enum machine_mode mode, REAL_VALUE_TYPE dconst)
26871 rtx reg;
26873 if (mode == SFmode || mode == DFmode)
26875 rtx d = CONST_DOUBLE_FROM_REAL_VALUE (dconst, mode);
26876 reg = force_reg (mode, d);
26878 else if (mode == V4SFmode)
26880 rtx d = CONST_DOUBLE_FROM_REAL_VALUE (dconst, SFmode);
26881 rtvec v = gen_rtvec (4, d, d, d, d);
26882 reg = gen_reg_rtx (mode);
26883 rs6000_expand_vector_init (reg, gen_rtx_PARALLEL (mode, v));
26885 else if (mode == V2DFmode)
26887 rtx d = CONST_DOUBLE_FROM_REAL_VALUE (dconst, DFmode);
26888 rtvec v = gen_rtvec (2, d, d);
26889 reg = gen_reg_rtx (mode);
26890 rs6000_expand_vector_init (reg, gen_rtx_PARALLEL (mode, v));
26892 else
26893 gcc_unreachable ();
26895 return reg;
26898 /* Generate an FMA instruction. */
26900 static void
26901 rs6000_emit_madd (rtx target, rtx m1, rtx m2, rtx a)
26903 enum machine_mode mode = GET_MODE (target);
26904 rtx dst;
26906 dst = expand_ternary_op (mode, fma_optab, m1, m2, a, target, 0);
26907 gcc_assert (dst != NULL);
26909 if (dst != target)
26910 emit_move_insn (target, dst);
26913 /* Generate a FMSUB instruction: dst = fma(m1, m2, -a). */
26915 static void
26916 rs6000_emit_msub (rtx target, rtx m1, rtx m2, rtx a)
26918 enum machine_mode mode = GET_MODE (target);
26919 rtx dst;
26921 /* Altivec does not support fms directly;
26922 generate in terms of fma in that case. */
26923 if (optab_handler (fms_optab, mode) != CODE_FOR_nothing)
26924 dst = expand_ternary_op (mode, fms_optab, m1, m2, a, target, 0);
26925 else
26927 a = expand_unop (mode, neg_optab, a, NULL_RTX, 0);
26928 dst = expand_ternary_op (mode, fma_optab, m1, m2, a, target, 0);
26930 gcc_assert (dst != NULL);
26932 if (dst != target)
26933 emit_move_insn (target, dst);
26936 /* Generate a FNMSUB instruction: dst = -fma(m1, m2, -a). */
26938 static void
26939 rs6000_emit_nmsub (rtx dst, rtx m1, rtx m2, rtx a)
26941 enum machine_mode mode = GET_MODE (dst);
26942 rtx r;
26944 /* This is a tad more complicated, since the fnma_optab is for
26945 a different expression: fma(-m1, m2, a), which is the same
26946 thing except in the case of signed zeros.
26948 Fortunately we know that if FMA is supported that FNMSUB is
26949 also supported in the ISA. Just expand it directly. */
26951 gcc_assert (optab_handler (fma_optab, mode) != CODE_FOR_nothing);
26953 r = gen_rtx_NEG (mode, a);
26954 r = gen_rtx_FMA (mode, m1, m2, r);
26955 r = gen_rtx_NEG (mode, r);
26956 emit_insn (gen_rtx_SET (VOIDmode, dst, r));
26959 /* Newton-Raphson approximation of floating point divide with just 2 passes
26960 (either single precision floating point, or newer machines with higher
26961 accuracy estimates). Support both scalar and vector divide. Assumes no
26962 trapping math and finite arguments. */
26964 static void
26965 rs6000_emit_swdiv_high_precision (rtx dst, rtx n, rtx d)
26967 enum machine_mode mode = GET_MODE (dst);
26968 rtx x0, e0, e1, y1, u0, v0;
26969 enum insn_code code = optab_handler (smul_optab, mode);
26970 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (code);
26971 rtx one = rs6000_load_constant_and_splat (mode, dconst1);
26973 gcc_assert (code != CODE_FOR_nothing);
26975 /* x0 = 1./d estimate */
26976 x0 = gen_reg_rtx (mode);
26977 emit_insn (gen_rtx_SET (VOIDmode, x0,
26978 gen_rtx_UNSPEC (mode, gen_rtvec (1, d),
26979 UNSPEC_FRES)));
26981 e0 = gen_reg_rtx (mode);
26982 rs6000_emit_nmsub (e0, d, x0, one); /* e0 = 1. - (d * x0) */
26984 e1 = gen_reg_rtx (mode);
26985 rs6000_emit_madd (e1, e0, e0, e0); /* e1 = (e0 * e0) + e0 */
26987 y1 = gen_reg_rtx (mode);
26988 rs6000_emit_madd (y1, e1, x0, x0); /* y1 = (e1 * x0) + x0 */
26990 u0 = gen_reg_rtx (mode);
26991 emit_insn (gen_mul (u0, n, y1)); /* u0 = n * y1 */
26993 v0 = gen_reg_rtx (mode);
26994 rs6000_emit_nmsub (v0, d, u0, n); /* v0 = n - (d * u0) */
26996 rs6000_emit_madd (dst, v0, y1, u0); /* dst = (v0 * y1) + u0 */
26999 /* Newton-Raphson approximation of floating point divide that has a low
27000 precision estimate. Assumes no trapping math and finite arguments. */
27002 static void
27003 rs6000_emit_swdiv_low_precision (rtx dst, rtx n, rtx d)
27005 enum machine_mode mode = GET_MODE (dst);
27006 rtx x0, e0, e1, e2, y1, y2, y3, u0, v0, one;
27007 enum insn_code code = optab_handler (smul_optab, mode);
27008 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (code);
27010 gcc_assert (code != CODE_FOR_nothing);
27012 one = rs6000_load_constant_and_splat (mode, dconst1);
27014 /* x0 = 1./d estimate */
27015 x0 = gen_reg_rtx (mode);
27016 emit_insn (gen_rtx_SET (VOIDmode, x0,
27017 gen_rtx_UNSPEC (mode, gen_rtvec (1, d),
27018 UNSPEC_FRES)));
27020 e0 = gen_reg_rtx (mode);
27021 rs6000_emit_nmsub (e0, d, x0, one); /* e0 = 1. - d * x0 */
27023 y1 = gen_reg_rtx (mode);
27024 rs6000_emit_madd (y1, e0, x0, x0); /* y1 = x0 + e0 * x0 */
27026 e1 = gen_reg_rtx (mode);
27027 emit_insn (gen_mul (e1, e0, e0)); /* e1 = e0 * e0 */
27029 y2 = gen_reg_rtx (mode);
27030 rs6000_emit_madd (y2, e1, y1, y1); /* y2 = y1 + e1 * y1 */
27032 e2 = gen_reg_rtx (mode);
27033 emit_insn (gen_mul (e2, e1, e1)); /* e2 = e1 * e1 */
27035 y3 = gen_reg_rtx (mode);
27036 rs6000_emit_madd (y3, e2, y2, y2); /* y3 = y2 + e2 * y2 */
27038 u0 = gen_reg_rtx (mode);
27039 emit_insn (gen_mul (u0, n, y3)); /* u0 = n * y3 */
27041 v0 = gen_reg_rtx (mode);
27042 rs6000_emit_nmsub (v0, d, u0, n); /* v0 = n - d * u0 */
27044 rs6000_emit_madd (dst, v0, y3, u0); /* dst = u0 + v0 * y3 */
27047 /* Newton-Raphson approximation of floating point divide DST = N/D. If NOTE_P,
27048 add a reg_note saying that this was a division. Support both scalar and
27049 vector divide. Assumes no trapping math and finite arguments. */
27051 void
27052 rs6000_emit_swdiv (rtx dst, rtx n, rtx d, bool note_p)
27054 enum machine_mode mode = GET_MODE (dst);
27056 if (RS6000_RECIP_HIGH_PRECISION_P (mode))
27057 rs6000_emit_swdiv_high_precision (dst, n, d);
27058 else
27059 rs6000_emit_swdiv_low_precision (dst, n, d);
27061 if (note_p)
27062 add_reg_note (get_last_insn (), REG_EQUAL, gen_rtx_DIV (mode, n, d));
27065 /* Newton-Raphson approximation of single/double-precision floating point
27066 rsqrt. Assumes no trapping math and finite arguments. */
27068 void
27069 rs6000_emit_swrsqrt (rtx dst, rtx src)
27071 enum machine_mode mode = GET_MODE (src);
27072 rtx x0 = gen_reg_rtx (mode);
27073 rtx y = gen_reg_rtx (mode);
27074 int passes = (TARGET_RECIP_PRECISION) ? 2 : 3;
27075 REAL_VALUE_TYPE dconst3_2;
27076 int i;
27077 rtx halfthree;
27078 enum insn_code code = optab_handler (smul_optab, mode);
27079 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (code);
27081 gcc_assert (code != CODE_FOR_nothing);
27083 /* Load up the constant 1.5 either as a scalar, or as a vector. */
27084 real_from_integer (&dconst3_2, VOIDmode, 3, 0, 0);
27085 SET_REAL_EXP (&dconst3_2, REAL_EXP (&dconst3_2) - 1);
27087 halfthree = rs6000_load_constant_and_splat (mode, dconst3_2);
27089 /* x0 = rsqrt estimate */
27090 emit_insn (gen_rtx_SET (VOIDmode, x0,
27091 gen_rtx_UNSPEC (mode, gen_rtvec (1, src),
27092 UNSPEC_RSQRT)));
27094 /* y = 0.5 * src = 1.5 * src - src -> fewer constants */
27095 rs6000_emit_msub (y, src, halfthree, src);
27097 for (i = 0; i < passes; i++)
27099 rtx x1 = gen_reg_rtx (mode);
27100 rtx u = gen_reg_rtx (mode);
27101 rtx v = gen_reg_rtx (mode);
27103 /* x1 = x0 * (1.5 - y * (x0 * x0)) */
27104 emit_insn (gen_mul (u, x0, x0));
27105 rs6000_emit_nmsub (v, y, u, halfthree);
27106 emit_insn (gen_mul (x1, x0, v));
27107 x0 = x1;
27110 emit_move_insn (dst, x0);
27111 return;
27114 /* Emit popcount intrinsic on TARGET_POPCNTB (Power5) and TARGET_POPCNTD
27115 (Power7) targets. DST is the target, and SRC is the argument operand. */
27117 void
27118 rs6000_emit_popcount (rtx dst, rtx src)
27120 enum machine_mode mode = GET_MODE (dst);
27121 rtx tmp1, tmp2;
27123 /* Use the PPC ISA 2.06 popcnt{w,d} instruction if we can. */
27124 if (TARGET_POPCNTD)
27126 if (mode == SImode)
27127 emit_insn (gen_popcntdsi2 (dst, src));
27128 else
27129 emit_insn (gen_popcntddi2 (dst, src));
27130 return;
27133 tmp1 = gen_reg_rtx (mode);
27135 if (mode == SImode)
27137 emit_insn (gen_popcntbsi2 (tmp1, src));
27138 tmp2 = expand_mult (SImode, tmp1, GEN_INT (0x01010101),
27139 NULL_RTX, 0);
27140 tmp2 = force_reg (SImode, tmp2);
27141 emit_insn (gen_lshrsi3 (dst, tmp2, GEN_INT (24)));
27143 else
27145 emit_insn (gen_popcntbdi2 (tmp1, src));
27146 tmp2 = expand_mult (DImode, tmp1,
27147 GEN_INT ((HOST_WIDE_INT)
27148 0x01010101 << 32 | 0x01010101),
27149 NULL_RTX, 0);
27150 tmp2 = force_reg (DImode, tmp2);
27151 emit_insn (gen_lshrdi3 (dst, tmp2, GEN_INT (56)));
27156 /* Emit parity intrinsic on TARGET_POPCNTB targets. DST is the
27157 target, and SRC is the argument operand. */
27159 void
27160 rs6000_emit_parity (rtx dst, rtx src)
27162 enum machine_mode mode = GET_MODE (dst);
27163 rtx tmp;
27165 tmp = gen_reg_rtx (mode);
27167 /* Use the PPC ISA 2.05 prtyw/prtyd instruction if we can. */
27168 if (TARGET_CMPB)
27170 if (mode == SImode)
27172 emit_insn (gen_popcntbsi2 (tmp, src));
27173 emit_insn (gen_paritysi2_cmpb (dst, tmp));
27175 else
27177 emit_insn (gen_popcntbdi2 (tmp, src));
27178 emit_insn (gen_paritydi2_cmpb (dst, tmp));
27180 return;
27183 if (mode == SImode)
27185 /* Is mult+shift >= shift+xor+shift+xor? */
27186 if (rs6000_cost->mulsi_const >= COSTS_N_INSNS (3))
27188 rtx tmp1, tmp2, tmp3, tmp4;
27190 tmp1 = gen_reg_rtx (SImode);
27191 emit_insn (gen_popcntbsi2 (tmp1, src));
27193 tmp2 = gen_reg_rtx (SImode);
27194 emit_insn (gen_lshrsi3 (tmp2, tmp1, GEN_INT (16)));
27195 tmp3 = gen_reg_rtx (SImode);
27196 emit_insn (gen_xorsi3 (tmp3, tmp1, tmp2));
27198 tmp4 = gen_reg_rtx (SImode);
27199 emit_insn (gen_lshrsi3 (tmp4, tmp3, GEN_INT (8)));
27200 emit_insn (gen_xorsi3 (tmp, tmp3, tmp4));
27202 else
27203 rs6000_emit_popcount (tmp, src);
27204 emit_insn (gen_andsi3 (dst, tmp, const1_rtx));
27206 else
27208 /* Is mult+shift >= shift+xor+shift+xor+shift+xor? */
27209 if (rs6000_cost->muldi >= COSTS_N_INSNS (5))
27211 rtx tmp1, tmp2, tmp3, tmp4, tmp5, tmp6;
27213 tmp1 = gen_reg_rtx (DImode);
27214 emit_insn (gen_popcntbdi2 (tmp1, src));
27216 tmp2 = gen_reg_rtx (DImode);
27217 emit_insn (gen_lshrdi3 (tmp2, tmp1, GEN_INT (32)));
27218 tmp3 = gen_reg_rtx (DImode);
27219 emit_insn (gen_xordi3 (tmp3, tmp1, tmp2));
27221 tmp4 = gen_reg_rtx (DImode);
27222 emit_insn (gen_lshrdi3 (tmp4, tmp3, GEN_INT (16)));
27223 tmp5 = gen_reg_rtx (DImode);
27224 emit_insn (gen_xordi3 (tmp5, tmp3, tmp4));
27226 tmp6 = gen_reg_rtx (DImode);
27227 emit_insn (gen_lshrdi3 (tmp6, tmp5, GEN_INT (8)));
27228 emit_insn (gen_xordi3 (tmp, tmp5, tmp6));
27230 else
27231 rs6000_emit_popcount (tmp, src);
27232 emit_insn (gen_anddi3 (dst, tmp, const1_rtx));
27236 /* Return an RTX representing where to find the function value of a
27237 function returning MODE. */
27238 static rtx
27239 rs6000_complex_function_value (enum machine_mode mode)
27241 unsigned int regno;
27242 rtx r1, r2;
27243 enum machine_mode inner = GET_MODE_INNER (mode);
27244 unsigned int inner_bytes = GET_MODE_SIZE (inner);
27246 if (FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
27247 regno = FP_ARG_RETURN;
27248 else
27250 regno = GP_ARG_RETURN;
27252 /* 32-bit is OK since it'll go in r3/r4. */
27253 if (TARGET_32BIT && inner_bytes >= 4)
27254 return gen_rtx_REG (mode, regno);
27257 if (inner_bytes >= 8)
27258 return gen_rtx_REG (mode, regno);
27260 r1 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno),
27261 const0_rtx);
27262 r2 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno + 1),
27263 GEN_INT (inner_bytes));
27264 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
27267 /* Target hook for TARGET_FUNCTION_VALUE.
27269 On the SPE, both FPs and vectors are returned in r3.
27271 On RS/6000 an integer value is in r3 and a floating-point value is in
27272 fp1, unless -msoft-float. */
27275 rs6000_function_value (const_tree valtype,
27276 const_tree fn_decl_or_type ATTRIBUTE_UNUSED,
27277 bool outgoing ATTRIBUTE_UNUSED)
27279 enum machine_mode mode;
27280 unsigned int regno;
27282 /* Special handling for structs in darwin64. */
27283 if (TARGET_MACHO
27284 && rs6000_darwin64_struct_check_p (TYPE_MODE (valtype), valtype))
27286 CUMULATIVE_ARGS valcum;
27287 rtx valret;
27289 valcum.words = 0;
27290 valcum.fregno = FP_ARG_MIN_REG;
27291 valcum.vregno = ALTIVEC_ARG_MIN_REG;
27292 /* Do a trial code generation as if this were going to be passed as
27293 an argument; if any part goes in memory, we return NULL. */
27294 valret = rs6000_darwin64_record_arg (&valcum, valtype, true, /* retval= */ true);
27295 if (valret)
27296 return valret;
27297 /* Otherwise fall through to standard ABI rules. */
27300 if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DImode)
27302 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
27303 return gen_rtx_PARALLEL (DImode,
27304 gen_rtvec (2,
27305 gen_rtx_EXPR_LIST (VOIDmode,
27306 gen_rtx_REG (SImode, GP_ARG_RETURN),
27307 const0_rtx),
27308 gen_rtx_EXPR_LIST (VOIDmode,
27309 gen_rtx_REG (SImode,
27310 GP_ARG_RETURN + 1),
27311 GEN_INT (4))));
27313 if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DCmode)
27315 return gen_rtx_PARALLEL (DCmode,
27316 gen_rtvec (4,
27317 gen_rtx_EXPR_LIST (VOIDmode,
27318 gen_rtx_REG (SImode, GP_ARG_RETURN),
27319 const0_rtx),
27320 gen_rtx_EXPR_LIST (VOIDmode,
27321 gen_rtx_REG (SImode,
27322 GP_ARG_RETURN + 1),
27323 GEN_INT (4)),
27324 gen_rtx_EXPR_LIST (VOIDmode,
27325 gen_rtx_REG (SImode,
27326 GP_ARG_RETURN + 2),
27327 GEN_INT (8)),
27328 gen_rtx_EXPR_LIST (VOIDmode,
27329 gen_rtx_REG (SImode,
27330 GP_ARG_RETURN + 3),
27331 GEN_INT (12))));
27334 mode = TYPE_MODE (valtype);
27335 if ((INTEGRAL_TYPE_P (valtype) && GET_MODE_BITSIZE (mode) < BITS_PER_WORD)
27336 || POINTER_TYPE_P (valtype))
27337 mode = TARGET_32BIT ? SImode : DImode;
27339 if (DECIMAL_FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
27340 /* _Decimal128 must use an even/odd register pair. */
27341 regno = (mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN;
27342 else if (SCALAR_FLOAT_TYPE_P (valtype) && TARGET_HARD_FLOAT && TARGET_FPRS
27343 && ((TARGET_SINGLE_FLOAT && (mode == SFmode)) || TARGET_DOUBLE_FLOAT))
27344 regno = FP_ARG_RETURN;
27345 else if (TREE_CODE (valtype) == COMPLEX_TYPE
27346 && targetm.calls.split_complex_arg)
27347 return rs6000_complex_function_value (mode);
27348 else if (TREE_CODE (valtype) == VECTOR_TYPE
27349 && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI
27350 && ALTIVEC_VECTOR_MODE (mode))
27351 regno = ALTIVEC_ARG_RETURN;
27352 else if (TREE_CODE (valtype) == VECTOR_TYPE
27353 && TARGET_VSX && TARGET_ALTIVEC_ABI
27354 && VSX_VECTOR_MODE (mode))
27355 regno = ALTIVEC_ARG_RETURN;
27356 else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
27357 && (mode == DFmode || mode == DCmode
27358 || mode == TFmode || mode == TCmode))
27359 return spe_build_register_parallel (mode, GP_ARG_RETURN);
27360 else
27361 regno = GP_ARG_RETURN;
27363 return gen_rtx_REG (mode, regno);
27366 /* Define how to find the value returned by a library function
27367 assuming the value has mode MODE. */
27369 rs6000_libcall_value (enum machine_mode mode)
27371 unsigned int regno;
27373 if (TARGET_32BIT && TARGET_POWERPC64 && mode == DImode)
27375 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
27376 return gen_rtx_PARALLEL (DImode,
27377 gen_rtvec (2,
27378 gen_rtx_EXPR_LIST (VOIDmode,
27379 gen_rtx_REG (SImode, GP_ARG_RETURN),
27380 const0_rtx),
27381 gen_rtx_EXPR_LIST (VOIDmode,
27382 gen_rtx_REG (SImode,
27383 GP_ARG_RETURN + 1),
27384 GEN_INT (4))));
27387 if (DECIMAL_FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
27388 /* _Decimal128 must use an even/odd register pair. */
27389 regno = (mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN;
27390 else if (SCALAR_FLOAT_MODE_P (mode)
27391 && TARGET_HARD_FLOAT && TARGET_FPRS
27392 && ((TARGET_SINGLE_FLOAT && mode == SFmode) || TARGET_DOUBLE_FLOAT))
27393 regno = FP_ARG_RETURN;
27394 else if (ALTIVEC_VECTOR_MODE (mode)
27395 && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI)
27396 regno = ALTIVEC_ARG_RETURN;
27397 else if (VSX_VECTOR_MODE (mode)
27398 && TARGET_VSX && TARGET_ALTIVEC_ABI)
27399 regno = ALTIVEC_ARG_RETURN;
27400 else if (COMPLEX_MODE_P (mode) && targetm.calls.split_complex_arg)
27401 return rs6000_complex_function_value (mode);
27402 else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
27403 && (mode == DFmode || mode == DCmode
27404 || mode == TFmode || mode == TCmode))
27405 return spe_build_register_parallel (mode, GP_ARG_RETURN);
27406 else
27407 regno = GP_ARG_RETURN;
27409 return gen_rtx_REG (mode, regno);
27413 /* Given FROM and TO register numbers, say whether this elimination is allowed.
27414 Frame pointer elimination is automatically handled.
27416 For the RS/6000, if frame pointer elimination is being done, we would like
27417 to convert ap into fp, not sp.
27419 We need r30 if -mminimal-toc was specified, and there are constant pool
27420 references. */
27422 bool
27423 rs6000_can_eliminate (const int from, const int to)
27425 return (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM
27426 ? ! frame_pointer_needed
27427 : from == RS6000_PIC_OFFSET_TABLE_REGNUM
27428 ? ! TARGET_MINIMAL_TOC || TARGET_NO_TOC || get_pool_size () == 0
27429 : true);
27432 /* Define the offset between two registers, FROM to be eliminated and its
27433 replacement TO, at the start of a routine. */
27434 HOST_WIDE_INT
27435 rs6000_initial_elimination_offset (int from, int to)
27437 rs6000_stack_t *info = rs6000_stack_info ();
27438 HOST_WIDE_INT offset;
27440 if (from == HARD_FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
27441 offset = info->push_p ? 0 : -info->total_size;
27442 else if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
27444 offset = info->push_p ? 0 : -info->total_size;
27445 if (FRAME_GROWS_DOWNWARD)
27446 offset += info->fixed_size + info->vars_size + info->parm_size;
27448 else if (from == FRAME_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
27449 offset = FRAME_GROWS_DOWNWARD
27450 ? info->fixed_size + info->vars_size + info->parm_size
27451 : 0;
27452 else if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
27453 offset = info->total_size;
27454 else if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
27455 offset = info->push_p ? info->total_size : 0;
27456 else if (from == RS6000_PIC_OFFSET_TABLE_REGNUM)
27457 offset = 0;
27458 else
27459 gcc_unreachable ();
27461 return offset;
27464 static rtx
27465 rs6000_dwarf_register_span (rtx reg)
27467 rtx parts[8];
27468 int i, words;
27469 unsigned regno = REGNO (reg);
27470 enum machine_mode mode = GET_MODE (reg);
27472 if (TARGET_SPE
27473 && regno < 32
27474 && (SPE_VECTOR_MODE (GET_MODE (reg))
27475 || (TARGET_E500_DOUBLE && FLOAT_MODE_P (mode)
27476 && mode != SFmode && mode != SDmode && mode != SCmode)))
27478 else
27479 return NULL_RTX;
27481 regno = REGNO (reg);
27483 /* The duality of the SPE register size wreaks all kinds of havoc.
27484 This is a way of distinguishing r0 in 32-bits from r0 in
27485 64-bits. */
27486 words = (GET_MODE_SIZE (mode) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD;
27487 gcc_assert (words <= 4);
27488 for (i = 0; i < words; i++, regno++)
27490 if (BYTES_BIG_ENDIAN)
27492 parts[2 * i] = gen_rtx_REG (SImode, regno + 1200);
27493 parts[2 * i + 1] = gen_rtx_REG (SImode, regno);
27495 else
27497 parts[2 * i] = gen_rtx_REG (SImode, regno);
27498 parts[2 * i + 1] = gen_rtx_REG (SImode, regno + 1200);
27502 return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (words * 2, parts));
27505 /* Fill in sizes for SPE register high parts in table used by unwinder. */
27507 static void
27508 rs6000_init_dwarf_reg_sizes_extra (tree address)
27510 if (TARGET_SPE)
27512 int i;
27513 enum machine_mode mode = TYPE_MODE (char_type_node);
27514 rtx addr = expand_expr (address, NULL_RTX, VOIDmode, EXPAND_NORMAL);
27515 rtx mem = gen_rtx_MEM (BLKmode, addr);
27516 rtx value = gen_int_mode (4, mode);
27518 for (i = 1201; i < 1232; i++)
27520 int column = DWARF_REG_TO_UNWIND_COLUMN (i);
27521 HOST_WIDE_INT offset
27522 = DWARF_FRAME_REGNUM (column) * GET_MODE_SIZE (mode);
27524 emit_move_insn (adjust_address (mem, mode, offset), value);
27529 /* Map internal gcc register numbers to DWARF2 register numbers. */
27531 unsigned int
27532 rs6000_dbx_register_number (unsigned int regno)
27534 if (regno <= 63 || write_symbols != DWARF2_DEBUG)
27535 return regno;
27536 if (regno == MQ_REGNO)
27537 return 100;
27538 if (regno == LR_REGNO)
27539 return 108;
27540 if (regno == CTR_REGNO)
27541 return 109;
27542 if (CR_REGNO_P (regno))
27543 return regno - CR0_REGNO + 86;
27544 if (regno == CA_REGNO)
27545 return 101; /* XER */
27546 if (ALTIVEC_REGNO_P (regno))
27547 return regno - FIRST_ALTIVEC_REGNO + 1124;
27548 if (regno == VRSAVE_REGNO)
27549 return 356;
27550 if (regno == VSCR_REGNO)
27551 return 67;
27552 if (regno == SPE_ACC_REGNO)
27553 return 99;
27554 if (regno == SPEFSCR_REGNO)
27555 return 612;
27556 /* SPE high reg number. We get these values of regno from
27557 rs6000_dwarf_register_span. */
27558 gcc_assert (regno >= 1200 && regno < 1232);
27559 return regno;
27562 /* target hook eh_return_filter_mode */
27563 static enum machine_mode
27564 rs6000_eh_return_filter_mode (void)
27566 return TARGET_32BIT ? SImode : word_mode;
27569 /* Target hook for scalar_mode_supported_p. */
27570 static bool
27571 rs6000_scalar_mode_supported_p (enum machine_mode mode)
27573 if (DECIMAL_FLOAT_MODE_P (mode))
27574 return default_decimal_float_supported_p ();
27575 else
27576 return default_scalar_mode_supported_p (mode);
27579 /* Target hook for vector_mode_supported_p. */
27580 static bool
27581 rs6000_vector_mode_supported_p (enum machine_mode mode)
27584 if (TARGET_PAIRED_FLOAT && PAIRED_VECTOR_MODE (mode))
27585 return true;
27587 if (TARGET_SPE && SPE_VECTOR_MODE (mode))
27588 return true;
27590 else if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode))
27591 return true;
27593 else
27594 return false;
27597 /* Target hook for invalid_arg_for_unprototyped_fn. */
27598 static const char *
27599 invalid_arg_for_unprototyped_fn (const_tree typelist, const_tree funcdecl, const_tree val)
27601 return (!rs6000_darwin64_abi
27602 && typelist == 0
27603 && TREE_CODE (TREE_TYPE (val)) == VECTOR_TYPE
27604 && (funcdecl == NULL_TREE
27605 || (TREE_CODE (funcdecl) == FUNCTION_DECL
27606 && DECL_BUILT_IN_CLASS (funcdecl) != BUILT_IN_MD)))
27607 ? N_("AltiVec argument passed to unprototyped function")
27608 : NULL;
27611 /* For TARGET_SECURE_PLT 32-bit PIC code we can save PIC register
27612 setup by using __stack_chk_fail_local hidden function instead of
27613 calling __stack_chk_fail directly. Otherwise it is better to call
27614 __stack_chk_fail directly. */
27616 static tree
27617 rs6000_stack_protect_fail (void)
27619 return (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
27620 ? default_hidden_stack_protect_fail ()
27621 : default_external_stack_protect_fail ();
27624 void
27625 rs6000_final_prescan_insn (rtx insn, rtx *operand ATTRIBUTE_UNUSED,
27626 int num_operands ATTRIBUTE_UNUSED)
27628 if (rs6000_warn_cell_microcode)
27630 const char *temp;
27631 int insn_code_number = recog_memoized (insn);
27632 location_t location = locator_location (INSN_LOCATOR (insn));
27634 /* Punt on insns we cannot recognize. */
27635 if (insn_code_number < 0)
27636 return;
27638 temp = get_insn_template (insn_code_number, insn);
27640 if (get_attr_cell_micro (insn) == CELL_MICRO_ALWAYS)
27641 warning_at (location, OPT_mwarn_cell_microcode,
27642 "emitting microcode insn %s\t[%s] #%d",
27643 temp, insn_data[INSN_CODE (insn)].name, INSN_UID (insn));
27644 else if (get_attr_cell_micro (insn) == CELL_MICRO_CONDITIONAL)
27645 warning_at (location, OPT_mwarn_cell_microcode,
27646 "emitting conditional microcode insn %s\t[%s] #%d",
27647 temp, insn_data[INSN_CODE (insn)].name, INSN_UID (insn));
27652 /* Mask options that we want to support inside of attribute((target)) and
27653 #pragma GCC target operations. Note, we do not include things like
27654 64/32-bit, endianess, hard/soft floating point, etc. that would have
27655 different calling sequences. */
27657 struct rs6000_opt_mask {
27658 const char *name; /* option name */
27659 int mask; /* mask to set */
27660 bool invert; /* invert sense of mask */
27661 bool valid_target; /* option is a target option */
27664 static struct rs6000_opt_mask const rs6000_opt_masks[] =
27666 { "altivec", MASK_ALTIVEC, false, true },
27667 { "cmpb", MASK_CMPB, false, true },
27668 { "dlmzb", MASK_DLMZB, false, true },
27669 { "fprnd", MASK_FPRND, false, true },
27670 { "hard-dfp", MASK_DFP, false, true },
27671 { "isel", MASK_ISEL, false, true },
27672 { "mfcrf", MASK_MFCRF, false, true },
27673 { "mfpgpr", MASK_MFPGPR, false, true },
27674 { "mulhw", MASK_MULHW, false, true },
27675 { "multiple", MASK_MULTIPLE, false, true },
27676 { "update", MASK_NO_UPDATE, true , true },
27677 { "popcntb", MASK_POPCNTB, false, true },
27678 { "popcntd", MASK_POPCNTD, false, true },
27679 { "powerpc-gfxopt", MASK_PPC_GFXOPT, false, true },
27680 { "powerpc-gpopt", MASK_PPC_GPOPT, false, true },
27681 { "recip-precision", MASK_RECIP_PRECISION, false, true },
27682 { "string", MASK_STRING, false, true },
27683 { "vsx", MASK_VSX, false, true },
27684 #ifdef MASK_64BIT
27685 #if TARGET_AIX_OS
27686 { "aix64", MASK_64BIT, false, false },
27687 { "aix32", MASK_64BIT, true, false },
27688 #else
27689 { "64", MASK_64BIT, false, false },
27690 { "32", MASK_64BIT, true, false },
27691 #endif
27692 #endif
27693 #ifdef MASK_EABI
27694 { "eabi", MASK_EABI, false, false },
27695 #endif
27696 #ifdef MASK_LITTLE_ENDIAN
27697 { "little", MASK_LITTLE_ENDIAN, false, false },
27698 { "big", MASK_LITTLE_ENDIAN, true, false },
27699 #endif
27700 #ifdef MASK_RELOCATABLE
27701 { "relocatable", MASK_RELOCATABLE, false, false },
27702 #endif
27703 #ifdef MASK_STRICT_ALIGN
27704 { "strict-align", MASK_STRICT_ALIGN, false, false },
27705 #endif
27706 { "power", MASK_POWER, false, false },
27707 { "power2", MASK_POWER2, false, false },
27708 { "powerpc", MASK_POWERPC, false, false },
27709 { "soft-float", MASK_SOFT_FLOAT, false, false },
27710 { "string", MASK_STRING, false, false },
27713 /* Option variables that we want to support inside attribute((target)) and
27714 #pragma GCC target operations. */
27716 struct rs6000_opt_var {
27717 const char *name; /* option name */
27718 size_t global_offset; /* offset of the option in global_options. */
27719 size_t target_offset; /* offset of the option in target optiosn. */
27722 static struct rs6000_opt_var const rs6000_opt_vars[] =
27724 { "friz",
27725 offsetof (struct gcc_options, x_TARGET_FRIZ),
27726 offsetof (struct cl_target_option, x_TARGET_FRIZ), },
27727 { "avoid-indexed-addresses",
27728 offsetof (struct gcc_options, x_TARGET_AVOID_XFORM),
27729 offsetof (struct cl_target_option, x_TARGET_AVOID_XFORM) },
27730 { "paired",
27731 offsetof (struct gcc_options, x_rs6000_paired_float),
27732 offsetof (struct cl_target_option, x_rs6000_paired_float), },
27733 { "longcall",
27734 offsetof (struct gcc_options, x_rs6000_default_long_calls),
27735 offsetof (struct cl_target_option, x_rs6000_default_long_calls), },
27738 /* Inner function to handle attribute((target("..."))) and #pragma GCC target
27739 parsing. Return true if there were no errors. */
27741 static bool
27742 rs6000_inner_target_options (tree args, bool attr_p)
27744 bool ret = true;
27746 if (args == NULL_TREE)
27749 else if (TREE_CODE (args) == STRING_CST)
27751 char *p = ASTRDUP (TREE_STRING_POINTER (args));
27752 char *q;
27754 while ((q = strtok (p, ",")) != NULL)
27756 bool error_p = false;
27757 bool not_valid_p = false;
27758 const char *cpu_opt = NULL;
27760 p = NULL;
27761 if (strncmp (q, "cpu=", 4) == 0)
27763 int cpu_index = rs6000_cpu_name_lookup (q+4);
27764 if (cpu_index >= 0)
27765 rs6000_cpu_index = cpu_index;
27766 else
27768 error_p = true;
27769 cpu_opt = q+4;
27772 else if (strncmp (q, "tune=", 5) == 0)
27774 int tune_index = rs6000_cpu_name_lookup (q+5);
27775 if (tune_index >= 0)
27776 rs6000_tune_index = tune_index;
27777 else
27779 error_p = true;
27780 cpu_opt = q+5;
27783 else
27785 size_t i;
27786 bool invert = false;
27787 char *r = q;
27789 error_p = true;
27790 if (strncmp (r, "no-", 3) == 0)
27792 invert = true;
27793 r += 3;
27796 for (i = 0; i < ARRAY_SIZE (rs6000_opt_masks); i++)
27797 if (strcmp (r, rs6000_opt_masks[i].name) == 0)
27799 int mask = rs6000_opt_masks[i].mask;
27801 if (!rs6000_opt_masks[i].valid_target)
27802 not_valid_p = true;
27803 else
27805 error_p = false;
27806 target_flags_explicit |= mask;
27808 if (rs6000_opt_masks[i].invert)
27809 invert = !invert;
27811 if (invert)
27812 target_flags &= ~mask;
27813 else
27814 target_flags |= mask;
27816 break;
27819 if (error_p && !not_valid_p)
27821 for (i = 0; i < ARRAY_SIZE (rs6000_opt_vars); i++)
27822 if (strcmp (r, rs6000_opt_vars[i].name) == 0)
27824 size_t j = rs6000_opt_vars[i].global_offset;
27825 ((int *) &global_options)[j] = !invert;
27826 error_p = false;
27827 break;
27832 if (error_p)
27834 const char *eprefix, *esuffix;
27836 ret = false;
27837 if (attr_p)
27839 eprefix = "__attribute__((__target__(";
27840 esuffix = ")))";
27842 else
27844 eprefix = "#pragma GCC target ";
27845 esuffix = "";
27848 if (cpu_opt)
27849 error ("invalid cpu \"%s\" for %s\"%s\"%s", cpu_opt, eprefix,
27850 q, esuffix);
27851 else if (not_valid_p)
27852 error ("%s\"%s\"%s is not allowed", eprefix, q, esuffix);
27853 else
27854 error ("%s\"%s\"%s is invalid", eprefix, q, esuffix);
27859 else if (TREE_CODE (args) == TREE_LIST)
27863 tree value = TREE_VALUE (args);
27864 if (value)
27866 bool ret2 = rs6000_inner_target_options (value, attr_p);
27867 if (!ret2)
27868 ret = false;
27870 args = TREE_CHAIN (args);
27872 while (args != NULL_TREE);
27875 else
27876 gcc_unreachable ();
27878 return ret;
27881 /* Print out the target options as a list for -mdebug=target. */
27883 static void
27884 rs6000_debug_target_options (tree args, const char *prefix)
27886 if (args == NULL_TREE)
27887 fprintf (stderr, "%s<NULL>", prefix);
27889 else if (TREE_CODE (args) == STRING_CST)
27891 char *p = ASTRDUP (TREE_STRING_POINTER (args));
27892 char *q;
27894 while ((q = strtok (p, ",")) != NULL)
27896 p = NULL;
27897 fprintf (stderr, "%s\"%s\"", prefix, q);
27898 prefix = ", ";
27902 else if (TREE_CODE (args) == TREE_LIST)
27906 tree value = TREE_VALUE (args);
27907 if (value)
27909 rs6000_debug_target_options (value, prefix);
27910 prefix = ", ";
27912 args = TREE_CHAIN (args);
27914 while (args != NULL_TREE);
27917 else
27918 gcc_unreachable ();
27920 return;
27924 /* Hook to validate attribute((target("..."))). */
27926 static bool
27927 rs6000_valid_attribute_p (tree fndecl,
27928 tree ARG_UNUSED (name),
27929 tree args,
27930 int flags)
27932 struct cl_target_option cur_target;
27933 bool ret;
27934 tree old_optimize = build_optimization_node ();
27935 tree new_target, new_optimize;
27936 tree func_optimize = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl);
27938 gcc_assert ((fndecl != NULL_TREE) && (args != NULL_TREE));
27940 if (TARGET_DEBUG_TARGET)
27942 tree tname = DECL_NAME (fndecl);
27943 fprintf (stderr, "\n==================== rs6000_valid_attribute_p:\n");
27944 if (tname)
27945 fprintf (stderr, "function: %.*s\n",
27946 (int) IDENTIFIER_LENGTH (tname),
27947 IDENTIFIER_POINTER (tname));
27948 else
27949 fprintf (stderr, "function: unknown\n");
27951 fprintf (stderr, "args:");
27952 rs6000_debug_target_options (args, " ");
27953 fprintf (stderr, "\n");
27955 if (flags)
27956 fprintf (stderr, "flags: 0x%x\n", flags);
27958 fprintf (stderr, "--------------------\n");
27961 old_optimize = build_optimization_node ();
27962 func_optimize = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl);
27964 /* If the function changed the optimization levels as well as setting target
27965 options, start with the optimizations specified. */
27966 if (func_optimize && func_optimize != old_optimize)
27967 cl_optimization_restore (&global_options,
27968 TREE_OPTIMIZATION (func_optimize));
27970 /* The target attributes may also change some optimization flags, so update
27971 the optimization options if necessary. */
27972 cl_target_option_save (&cur_target, &global_options);
27973 rs6000_cpu_index = rs6000_tune_index = -1;
27974 ret = rs6000_inner_target_options (args, true);
27976 /* Set up any additional state. */
27977 if (ret)
27979 ret = rs6000_option_override_internal (false);
27980 new_target = build_target_option_node ();
27982 else
27983 new_target = NULL;
27985 new_optimize = build_optimization_node ();
27987 if (!new_target)
27988 ret = false;
27990 else if (fndecl)
27992 DECL_FUNCTION_SPECIFIC_TARGET (fndecl) = new_target;
27994 if (old_optimize != new_optimize)
27995 DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl) = new_optimize;
27998 cl_target_option_restore (&global_options, &cur_target);
28000 if (old_optimize != new_optimize)
28001 cl_optimization_restore (&global_options,
28002 TREE_OPTIMIZATION (old_optimize));
28004 return ret;
28008 /* Hook to validate the current #pragma GCC target and set the state, and
28009 update the macros based on what was changed. If ARGS is NULL, then
28010 POP_TARGET is used to reset the options. */
28012 bool
28013 rs6000_pragma_target_parse (tree args, tree pop_target)
28015 tree cur_tree;
28016 bool ret;
28018 if (TARGET_DEBUG_TARGET)
28020 fprintf (stderr, "\n==================== rs6000_pragma_target_parse\n");
28021 fprintf (stderr, "args:");
28022 rs6000_debug_target_options (args, " ");
28023 fprintf (stderr, "\n");
28025 if (pop_target)
28027 fprintf (stderr, "pop_target:\n");
28028 debug_tree (pop_target);
28030 else
28031 fprintf (stderr, "pop_target: <NULL>\n");
28033 fprintf (stderr, "--------------------\n");
28036 if (! args)
28038 ret = true;
28039 cur_tree = ((pop_target)
28040 ? pop_target
28041 : target_option_default_node);
28042 cl_target_option_restore (&global_options,
28043 TREE_TARGET_OPTION (cur_tree));
28045 else
28047 rs6000_cpu_index = rs6000_tune_index = -1;
28048 ret = rs6000_inner_target_options (args, false);
28049 cur_tree = build_target_option_node ();
28051 if (!cur_tree)
28052 ret = false;
28055 if (cur_tree)
28056 target_option_current_node = cur_tree;
28058 return ret;
28062 /* Remember the last target of rs6000_set_current_function. */
28063 static GTY(()) tree rs6000_previous_fndecl;
28065 /* Establish appropriate back-end context for processing the function
28066 FNDECL. The argument might be NULL to indicate processing at top
28067 level, outside of any function scope. */
28068 static void
28069 rs6000_set_current_function (tree fndecl)
28071 tree old_tree = (rs6000_previous_fndecl
28072 ? DECL_FUNCTION_SPECIFIC_TARGET (rs6000_previous_fndecl)
28073 : NULL_TREE);
28075 tree new_tree = (fndecl
28076 ? DECL_FUNCTION_SPECIFIC_TARGET (fndecl)
28077 : NULL_TREE);
28079 if (TARGET_DEBUG_TARGET)
28081 bool print_final = false;
28082 fprintf (stderr, "\n==================== rs6000_set_current_function");
28084 if (fndecl)
28085 fprintf (stderr, ", fndecl %s (%p)",
28086 (DECL_NAME (fndecl)
28087 ? IDENTIFIER_POINTER (DECL_NAME (fndecl))
28088 : "<unknown>"), (void *)fndecl);
28090 if (rs6000_previous_fndecl)
28091 fprintf (stderr, ", prev_fndecl (%p)", (void *)rs6000_previous_fndecl);
28093 fprintf (stderr, "\n");
28094 if (new_tree)
28096 fprintf (stderr, "\nnew fndecl target specific options:\n");
28097 debug_tree (new_tree);
28098 print_final = true;
28101 if (old_tree)
28103 fprintf (stderr, "\nold fndecl target specific options:\n");
28104 debug_tree (old_tree);
28105 print_final = true;
28108 if (print_final)
28109 fprintf (stderr, "--------------------\n");
28112 /* Only change the context if the function changes. This hook is called
28113 several times in the course of compiling a function, and we don't want to
28114 slow things down too much or call target_reinit when it isn't safe. */
28115 if (fndecl && fndecl != rs6000_previous_fndecl)
28117 rs6000_previous_fndecl = fndecl;
28118 if (old_tree == new_tree)
28121 else if (new_tree)
28123 cl_target_option_restore (&global_options,
28124 TREE_TARGET_OPTION (new_tree));
28125 target_reinit ();
28128 else if (old_tree)
28130 struct cl_target_option *def
28131 = TREE_TARGET_OPTION (target_option_current_node);
28133 cl_target_option_restore (&global_options, def);
28134 target_reinit ();
28140 /* Save the current options */
28142 static void
28143 rs6000_function_specific_save (struct cl_target_option *ptr)
28145 ptr->rs6000_target_flags_explicit = target_flags_explicit;
28148 /* Restore the current options */
28150 static void
28151 rs6000_function_specific_restore (struct cl_target_option *ptr)
28153 target_flags_explicit = ptr->rs6000_target_flags_explicit;
28154 (void) rs6000_option_override_internal (false);
28157 /* Print the current options */
28159 static void
28160 rs6000_function_specific_print (FILE *file, int indent,
28161 struct cl_target_option *ptr)
28163 size_t i;
28164 int flags = ptr->x_target_flags;
28166 /* Print the various mask options. */
28167 for (i = 0; i < ARRAY_SIZE (rs6000_opt_masks); i++)
28168 if ((flags & rs6000_opt_masks[i].mask) != 0)
28170 flags &= ~ rs6000_opt_masks[i].mask;
28171 fprintf (file, "%*s-m%s%s\n", indent, "",
28172 rs6000_opt_masks[i].invert ? "no-" : "",
28173 rs6000_opt_masks[i].name);
28176 /* Print the various options that are variables. */
28177 for (i = 0; i < ARRAY_SIZE (rs6000_opt_vars); i++)
28179 size_t j = rs6000_opt_vars[i].target_offset;
28180 if (((signed char *) ptr)[j])
28181 fprintf (file, "%*s-m%s\n", indent, "",
28182 rs6000_opt_vars[i].name);
28187 /* Hook to determine if one function can safely inline another. */
28189 static bool
28190 rs6000_can_inline_p (tree caller, tree callee)
28192 bool ret = false;
28193 tree caller_tree = DECL_FUNCTION_SPECIFIC_TARGET (caller);
28194 tree callee_tree = DECL_FUNCTION_SPECIFIC_TARGET (callee);
28196 /* If callee has no option attributes, then it is ok to inline. */
28197 if (!callee_tree)
28198 ret = true;
28200 /* If caller has no option attributes, but callee does then it is not ok to
28201 inline. */
28202 else if (!caller_tree)
28203 ret = false;
28205 else
28207 struct cl_target_option *caller_opts = TREE_TARGET_OPTION (caller_tree);
28208 struct cl_target_option *callee_opts = TREE_TARGET_OPTION (callee_tree);
28210 /* Callee's options should a subset of the caller's, i.e. a vsx function
28211 can inline an altivec function but a non-vsx function can't inline a
28212 vsx function. */
28213 if ((caller_opts->x_target_flags & callee_opts->x_target_flags)
28214 == callee_opts->x_target_flags)
28215 ret = true;
28218 if (TARGET_DEBUG_TARGET)
28219 fprintf (stderr, "rs6000_can_inline_p:, caller %s, callee %s, %s inline\n",
28220 (DECL_NAME (caller)
28221 ? IDENTIFIER_POINTER (DECL_NAME (caller))
28222 : "<unknown>"),
28223 (DECL_NAME (callee)
28224 ? IDENTIFIER_POINTER (DECL_NAME (callee))
28225 : "<unknown>"),
28226 (ret ? "can" : "cannot"));
28228 return ret;
28231 /* Allocate a stack temp and fixup the address so it meets the particular
28232 memory requirements (either offetable or REG+REG addressing). */
28235 rs6000_allocate_stack_temp (enum machine_mode mode,
28236 bool offsettable_p,
28237 bool reg_reg_p)
28239 rtx stack = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
28240 rtx addr = XEXP (stack, 0);
28241 int strict_p = (reload_in_progress || reload_completed);
28243 if (!legitimate_indirect_address_p (addr, strict_p))
28245 if (offsettable_p
28246 && !rs6000_legitimate_offset_address_p (mode, addr, strict_p))
28247 stack = replace_equiv_address (stack, copy_addr_to_reg (addr));
28249 else if (reg_reg_p && !legitimate_indexed_address_p (addr, strict_p))
28250 stack = replace_equiv_address (stack, copy_addr_to_reg (addr));
28253 return stack;
28256 /* Given a memory reference, if it is not a reg or reg+reg addressing, convert
28257 to such a form to deal with memory reference instructions like STFIWX that
28258 only take reg+reg addressing. */
28261 rs6000_address_for_fpconvert (rtx x)
28263 int strict_p = (reload_in_progress || reload_completed);
28264 rtx addr;
28266 gcc_assert (MEM_P (x));
28267 addr = XEXP (x, 0);
28268 if (! legitimate_indirect_address_p (addr, strict_p)
28269 && ! legitimate_indexed_address_p (addr, strict_p))
28271 if (GET_CODE (addr) == PRE_INC || GET_CODE (addr) == PRE_DEC)
28273 rtx reg = XEXP (addr, 0);
28274 HOST_WIDE_INT size = GET_MODE_SIZE (GET_MODE (x));
28275 rtx size_rtx = GEN_INT ((GET_CODE (addr) == PRE_DEC) ? -size : size);
28276 gcc_assert (REG_P (reg));
28277 emit_insn (gen_add3_insn (reg, reg, size_rtx));
28278 addr = reg;
28280 else if (GET_CODE (addr) == PRE_MODIFY)
28282 rtx reg = XEXP (addr, 0);
28283 rtx expr = XEXP (addr, 1);
28284 gcc_assert (REG_P (reg));
28285 gcc_assert (GET_CODE (expr) == PLUS);
28286 emit_insn (gen_add3_insn (reg, XEXP (expr, 0), XEXP (expr, 1)));
28287 addr = reg;
28290 x = replace_equiv_address (x, copy_addr_to_reg (addr));
28293 return x;
28296 /* Given a memory reference, if it is not in the form for altivec memory
28297 reference instructions (i.e. reg or reg+reg addressing with AND of -16),
28298 convert to the altivec format. */
28301 rs6000_address_for_altivec (rtx x)
28303 gcc_assert (MEM_P (x));
28304 if (!altivec_indexed_or_indirect_operand (x, GET_MODE (x)))
28306 rtx addr = XEXP (x, 0);
28307 int strict_p = (reload_in_progress || reload_completed);
28309 if (!legitimate_indexed_address_p (addr, strict_p)
28310 && !legitimate_indirect_address_p (addr, strict_p))
28311 addr = copy_to_mode_reg (Pmode, addr);
28313 addr = gen_rtx_AND (Pmode, addr, GEN_INT (-16));
28314 x = change_address (x, GET_MODE (x), addr);
28317 return x;
28321 #include "gt-rs6000.h"