gcc/
[official-gcc.git] / gcc / config / rs6000 / rs6000.c
blob231651e0d46e2edd8408af7924ac85383f08068e
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 #if TARGET_XCOFF
62 #include "xcoffout.h" /* get declarations of xcoff_*_section_name */
63 #endif
64 #if TARGET_MACHO
65 #include "gstab.h" /* for N_SLINE */
66 #endif
68 #ifndef TARGET_NO_PROTOTYPE
69 #define TARGET_NO_PROTOTYPE 0
70 #endif
72 #define min(A,B) ((A) < (B) ? (A) : (B))
73 #define max(A,B) ((A) > (B) ? (A) : (B))
75 /* Structure used to define the rs6000 stack */
76 typedef struct rs6000_stack {
77 int reload_completed; /* stack info won't change from here on */
78 int first_gp_reg_save; /* first callee saved GP register used */
79 int first_fp_reg_save; /* first callee saved FP register used */
80 int first_altivec_reg_save; /* first callee saved AltiVec register used */
81 int lr_save_p; /* true if the link reg needs to be saved */
82 int cr_save_p; /* true if the CR reg needs to be saved */
83 unsigned int vrsave_mask; /* mask of vec registers to save */
84 int push_p; /* true if we need to allocate stack space */
85 int calls_p; /* true if the function makes any calls */
86 int world_save_p; /* true if we're saving *everything*:
87 r13-r31, cr, f14-f31, vrsave, v20-v31 */
88 enum rs6000_abi abi; /* which ABI to use */
89 int gp_save_offset; /* offset to save GP regs from initial SP */
90 int fp_save_offset; /* offset to save FP regs from initial SP */
91 int altivec_save_offset; /* offset to save AltiVec regs from initial SP */
92 int lr_save_offset; /* offset to save LR from initial SP */
93 int cr_save_offset; /* offset to save CR from initial SP */
94 int vrsave_save_offset; /* offset to save VRSAVE from initial SP */
95 int spe_gp_save_offset; /* offset to save spe 64-bit gprs */
96 int varargs_save_offset; /* offset to save the varargs registers */
97 int ehrd_offset; /* offset to EH return data */
98 int reg_size; /* register size (4 or 8) */
99 HOST_WIDE_INT vars_size; /* variable save area size */
100 int parm_size; /* outgoing parameter size */
101 int save_size; /* save area size */
102 int fixed_size; /* fixed size of stack frame */
103 int gp_size; /* size of saved GP registers */
104 int fp_size; /* size of saved FP registers */
105 int altivec_size; /* size of saved AltiVec registers */
106 int cr_size; /* size to hold CR if not in save_size */
107 int vrsave_size; /* size to hold VRSAVE if not in save_size */
108 int altivec_padding_size; /* size of altivec alignment padding if
109 not in save_size */
110 int spe_gp_size; /* size of 64-bit GPR save size for SPE */
111 int spe_padding_size;
112 HOST_WIDE_INT total_size; /* total bytes allocated for stack */
113 int spe_64bit_regs_used;
114 int savres_strategy;
115 } rs6000_stack_t;
117 /* A C structure for machine-specific, per-function data.
118 This is added to the cfun structure. */
119 typedef struct GTY(()) machine_function
121 /* Some local-dynamic symbol. */
122 const char *some_ld_name;
123 /* Whether the instruction chain has been scanned already. */
124 int insn_chain_scanned_p;
125 /* Flags if __builtin_return_address (n) with n >= 1 was used. */
126 int ra_needs_full_frame;
127 /* Flags if __builtin_return_address (0) was used. */
128 int ra_need_lr;
129 /* Cache lr_save_p after expansion of builtin_eh_return. */
130 int lr_save_state;
131 /* Offset from virtual_stack_vars_rtx to the start of the ABI_V4
132 varargs save area. */
133 HOST_WIDE_INT varargs_save_offset;
134 /* Temporary stack slot to use for SDmode copies. This slot is
135 64-bits wide and is allocated early enough so that the offset
136 does not overflow the 16-bit load/store offset field. */
137 rtx sdmode_stack_slot;
138 } machine_function;
140 /* Target cpu type */
142 struct rs6000_cpu_select rs6000_select[3] =
144 /* switch name, tune arch */
145 { (const char *)0, "--with-cpu=", 1, 1 },
146 { (const char *)0, "-mcpu=", 1, 1 },
147 { (const char *)0, "-mtune=", 1, 0 },
150 /* String variables to hold the various options. */
151 static const char *rs6000_sched_insert_nops_str;
152 static const char *rs6000_sched_costly_dep_str;
153 static const char *rs6000_recip_name;
155 #ifdef USING_ELFOS_H
156 static const char *rs6000_abi_name;
157 static const char *rs6000_sdata_name;
158 #endif
160 /* Support targetm.vectorize.builtin_mask_for_load. */
161 static GTY(()) tree altivec_builtin_mask_for_load;
163 /* Set to nonzero once AIX common-mode calls have been defined. */
164 static GTY(()) int common_mode_defined;
166 /* Label number of label created for -mrelocatable, to call to so we can
167 get the address of the GOT section */
168 static int rs6000_pic_labelno;
170 #ifdef USING_ELFOS_H
171 /* Counter for labels which are to be placed in .fixup. */
172 int fixuplabelno = 0;
173 #endif
175 /* Whether to use variant of AIX ABI for PowerPC64 Linux. */
176 int dot_symbols;
178 /* Specify the machine mode that pointers have. After generation of rtl, the
179 compiler makes no further distinction between pointers and any other objects
180 of this machine mode. The type is unsigned since not all things that
181 include rs6000.h also include machmode.h. */
182 unsigned rs6000_pmode;
184 /* Width in bits of a pointer. */
185 unsigned rs6000_pointer_size;
187 #ifdef HAVE_AS_GNU_ATTRIBUTE
188 /* Flag whether floating point values have been passed/returned. */
189 static bool rs6000_passes_float;
190 /* Flag whether vector values have been passed/returned. */
191 static bool rs6000_passes_vector;
192 /* Flag whether small (<= 8 byte) structures have been returned. */
193 static bool rs6000_returns_struct;
194 #endif
196 /* Value is TRUE if register/mode pair is acceptable. */
197 bool rs6000_hard_regno_mode_ok_p[NUM_MACHINE_MODES][FIRST_PSEUDO_REGISTER];
199 /* Maximum number of registers needed for a given register class and mode. */
200 unsigned char rs6000_class_max_nregs[NUM_MACHINE_MODES][LIM_REG_CLASSES];
202 /* How many registers are needed for a given register and mode. */
203 unsigned char rs6000_hard_regno_nregs[NUM_MACHINE_MODES][FIRST_PSEUDO_REGISTER];
205 /* Map register number to register class. */
206 enum reg_class rs6000_regno_regclass[FIRST_PSEUDO_REGISTER];
208 /* Reload functions based on the type and the vector unit. */
209 static enum insn_code rs6000_vector_reload[NUM_MACHINE_MODES][2];
211 /* Built in types. */
212 tree rs6000_builtin_types[RS6000_BTI_MAX];
213 tree rs6000_builtin_decls[RS6000_BUILTIN_COUNT];
215 /* Flag to say the TOC is initialized */
216 int toc_initialized;
217 char toc_label_name[10];
219 /* Cached value of rs6000_variable_issue. This is cached in
220 rs6000_variable_issue hook and returned from rs6000_sched_reorder2. */
221 static short cached_can_issue_more;
223 static GTY(()) section *read_only_data_section;
224 static GTY(()) section *private_data_section;
225 static GTY(()) section *read_only_private_data_section;
226 static GTY(()) section *sdata2_section;
227 static GTY(()) section *toc_section;
229 /* True for any options that were explicitly set. */
230 static struct {
231 bool aix_struct_ret; /* True if -maix-struct-ret was used. */
232 bool alignment; /* True if -malign- was used. */
233 bool spe_abi; /* True if -mabi=spe/no-spe was used. */
234 bool altivec_abi; /* True if -mabi=altivec/no-altivec used. */
235 bool spe; /* True if -mspe= was used. */
236 bool float_gprs; /* True if -mfloat-gprs= was used. */
237 bool long_double; /* True if -mlong-double- was used. */
238 bool ieee; /* True if -mabi=ieee/ibmlongdouble used. */
239 bool vrsave; /* True if -mvrsave was used. */
240 bool cmodel; /* True if -mcmodel was used. */
241 } rs6000_explicit_options;
243 struct builtin_description
245 /* mask is not const because we're going to alter it below. This
246 nonsense will go away when we rewrite the -march infrastructure
247 to give us more target flag bits. */
248 unsigned int mask;
249 const enum insn_code icode;
250 const char *const name;
251 const enum rs6000_builtins code;
254 /* Describe the vector unit used for modes. */
255 enum rs6000_vector rs6000_vector_unit[NUM_MACHINE_MODES];
256 enum rs6000_vector rs6000_vector_mem[NUM_MACHINE_MODES];
258 /* Register classes for various constraints that are based on the target
259 switches. */
260 enum reg_class rs6000_constraints[RS6000_CONSTRAINT_MAX];
262 /* Describe the alignment of a vector. */
263 int rs6000_vector_align[NUM_MACHINE_MODES];
265 /* Map selected modes to types for builtins. */
266 static GTY(()) tree builtin_mode_to_type[MAX_MACHINE_MODE][2];
268 /* What modes to automatically generate reciprocal divide estimate (fre) and
269 reciprocal sqrt (frsqrte) for. */
270 unsigned char rs6000_recip_bits[MAX_MACHINE_MODE];
272 /* Masks to determine which reciprocal esitmate instructions to generate
273 automatically. */
274 enum rs6000_recip_mask {
275 RECIP_SF_DIV = 0x001, /* Use divide estimate */
276 RECIP_DF_DIV = 0x002,
277 RECIP_V4SF_DIV = 0x004,
278 RECIP_V2DF_DIV = 0x008,
280 RECIP_SF_RSQRT = 0x010, /* Use reciprocal sqrt estimate. */
281 RECIP_DF_RSQRT = 0x020,
282 RECIP_V4SF_RSQRT = 0x040,
283 RECIP_V2DF_RSQRT = 0x080,
285 /* Various combination of flags for -mrecip=xxx. */
286 RECIP_NONE = 0,
287 RECIP_ALL = (RECIP_SF_DIV | RECIP_DF_DIV | RECIP_V4SF_DIV
288 | RECIP_V2DF_DIV | RECIP_SF_RSQRT | RECIP_DF_RSQRT
289 | RECIP_V4SF_RSQRT | RECIP_V2DF_RSQRT),
291 RECIP_HIGH_PRECISION = RECIP_ALL,
293 /* On low precision machines like the power5, don't enable double precision
294 reciprocal square root estimate, since it isn't accurate enough. */
295 RECIP_LOW_PRECISION = (RECIP_ALL & ~(RECIP_DF_RSQRT | RECIP_V2DF_RSQRT))
298 /* -mrecip options. */
299 static struct
301 const char *string; /* option name */
302 unsigned int mask; /* mask bits to set */
303 } recip_options[] = {
304 { "all", RECIP_ALL },
305 { "none", RECIP_NONE },
306 { "div", (RECIP_SF_DIV | RECIP_DF_DIV | RECIP_V4SF_DIV
307 | RECIP_V2DF_DIV) },
308 { "divf", (RECIP_SF_DIV | RECIP_V4SF_DIV) },
309 { "divd", (RECIP_DF_DIV | RECIP_V2DF_DIV) },
310 { "rsqrt", (RECIP_SF_RSQRT | RECIP_DF_RSQRT | RECIP_V4SF_RSQRT
311 | RECIP_V2DF_RSQRT) },
312 { "rsqrtf", (RECIP_SF_RSQRT | RECIP_V4SF_RSQRT) },
313 { "rsqrtd", (RECIP_DF_RSQRT | RECIP_V2DF_RSQRT) },
316 /* 2 argument gen function typedef. */
317 typedef rtx (*gen_2arg_fn_t) (rtx, rtx, rtx);
320 /* Target cpu costs. */
322 struct processor_costs {
323 const int mulsi; /* cost of SImode multiplication. */
324 const int mulsi_const; /* cost of SImode multiplication by constant. */
325 const int mulsi_const9; /* cost of SImode mult by short constant. */
326 const int muldi; /* cost of DImode multiplication. */
327 const int divsi; /* cost of SImode division. */
328 const int divdi; /* cost of DImode division. */
329 const int fp; /* cost of simple SFmode and DFmode insns. */
330 const int dmul; /* cost of DFmode multiplication (and fmadd). */
331 const int sdiv; /* cost of SFmode division (fdivs). */
332 const int ddiv; /* cost of DFmode division (fdiv). */
333 const int cache_line_size; /* cache line size in bytes. */
334 const int l1_cache_size; /* size of l1 cache, in kilobytes. */
335 const int l2_cache_size; /* size of l2 cache, in kilobytes. */
336 const int simultaneous_prefetches; /* number of parallel prefetch
337 operations. */
340 const struct processor_costs *rs6000_cost;
342 /* Processor costs (relative to an add) */
344 /* Instruction size costs on 32bit processors. */
345 static const
346 struct processor_costs size32_cost = {
347 COSTS_N_INSNS (1), /* mulsi */
348 COSTS_N_INSNS (1), /* mulsi_const */
349 COSTS_N_INSNS (1), /* mulsi_const9 */
350 COSTS_N_INSNS (1), /* muldi */
351 COSTS_N_INSNS (1), /* divsi */
352 COSTS_N_INSNS (1), /* divdi */
353 COSTS_N_INSNS (1), /* fp */
354 COSTS_N_INSNS (1), /* dmul */
355 COSTS_N_INSNS (1), /* sdiv */
356 COSTS_N_INSNS (1), /* ddiv */
363 /* Instruction size costs on 64bit processors. */
364 static const
365 struct processor_costs size64_cost = {
366 COSTS_N_INSNS (1), /* mulsi */
367 COSTS_N_INSNS (1), /* mulsi_const */
368 COSTS_N_INSNS (1), /* mulsi_const9 */
369 COSTS_N_INSNS (1), /* muldi */
370 COSTS_N_INSNS (1), /* divsi */
371 COSTS_N_INSNS (1), /* divdi */
372 COSTS_N_INSNS (1), /* fp */
373 COSTS_N_INSNS (1), /* dmul */
374 COSTS_N_INSNS (1), /* sdiv */
375 COSTS_N_INSNS (1), /* ddiv */
376 128,
382 /* Instruction costs on RIOS1 processors. */
383 static const
384 struct processor_costs rios1_cost = {
385 COSTS_N_INSNS (5), /* mulsi */
386 COSTS_N_INSNS (4), /* mulsi_const */
387 COSTS_N_INSNS (3), /* mulsi_const9 */
388 COSTS_N_INSNS (5), /* muldi */
389 COSTS_N_INSNS (19), /* divsi */
390 COSTS_N_INSNS (19), /* divdi */
391 COSTS_N_INSNS (2), /* fp */
392 COSTS_N_INSNS (2), /* dmul */
393 COSTS_N_INSNS (19), /* sdiv */
394 COSTS_N_INSNS (19), /* ddiv */
395 128, /* cache line size */
396 64, /* l1 cache */
397 512, /* l2 cache */
398 0, /* streams */
401 /* Instruction costs on RIOS2 processors. */
402 static const
403 struct processor_costs rios2_cost = {
404 COSTS_N_INSNS (2), /* mulsi */
405 COSTS_N_INSNS (2), /* mulsi_const */
406 COSTS_N_INSNS (2), /* mulsi_const9 */
407 COSTS_N_INSNS (2), /* muldi */
408 COSTS_N_INSNS (13), /* divsi */
409 COSTS_N_INSNS (13), /* divdi */
410 COSTS_N_INSNS (2), /* fp */
411 COSTS_N_INSNS (2), /* dmul */
412 COSTS_N_INSNS (17), /* sdiv */
413 COSTS_N_INSNS (17), /* ddiv */
414 256, /* cache line size */
415 256, /* l1 cache */
416 1024, /* l2 cache */
417 0, /* streams */
420 /* Instruction costs on RS64A processors. */
421 static const
422 struct processor_costs rs64a_cost = {
423 COSTS_N_INSNS (20), /* mulsi */
424 COSTS_N_INSNS (12), /* mulsi_const */
425 COSTS_N_INSNS (8), /* mulsi_const9 */
426 COSTS_N_INSNS (34), /* muldi */
427 COSTS_N_INSNS (65), /* divsi */
428 COSTS_N_INSNS (67), /* divdi */
429 COSTS_N_INSNS (4), /* fp */
430 COSTS_N_INSNS (4), /* dmul */
431 COSTS_N_INSNS (31), /* sdiv */
432 COSTS_N_INSNS (31), /* ddiv */
433 128, /* cache line size */
434 128, /* l1 cache */
435 2048, /* l2 cache */
436 1, /* streams */
439 /* Instruction costs on MPCCORE processors. */
440 static const
441 struct processor_costs mpccore_cost = {
442 COSTS_N_INSNS (2), /* mulsi */
443 COSTS_N_INSNS (2), /* mulsi_const */
444 COSTS_N_INSNS (2), /* mulsi_const9 */
445 COSTS_N_INSNS (2), /* muldi */
446 COSTS_N_INSNS (6), /* divsi */
447 COSTS_N_INSNS (6), /* divdi */
448 COSTS_N_INSNS (4), /* fp */
449 COSTS_N_INSNS (5), /* dmul */
450 COSTS_N_INSNS (10), /* sdiv */
451 COSTS_N_INSNS (17), /* ddiv */
452 32, /* cache line size */
453 4, /* l1 cache */
454 16, /* l2 cache */
455 1, /* streams */
458 /* Instruction costs on PPC403 processors. */
459 static const
460 struct processor_costs ppc403_cost = {
461 COSTS_N_INSNS (4), /* mulsi */
462 COSTS_N_INSNS (4), /* mulsi_const */
463 COSTS_N_INSNS (4), /* mulsi_const9 */
464 COSTS_N_INSNS (4), /* muldi */
465 COSTS_N_INSNS (33), /* divsi */
466 COSTS_N_INSNS (33), /* divdi */
467 COSTS_N_INSNS (11), /* fp */
468 COSTS_N_INSNS (11), /* dmul */
469 COSTS_N_INSNS (11), /* sdiv */
470 COSTS_N_INSNS (11), /* ddiv */
471 32, /* cache line size */
472 4, /* l1 cache */
473 16, /* l2 cache */
474 1, /* streams */
477 /* Instruction costs on PPC405 processors. */
478 static const
479 struct processor_costs ppc405_cost = {
480 COSTS_N_INSNS (5), /* mulsi */
481 COSTS_N_INSNS (4), /* mulsi_const */
482 COSTS_N_INSNS (3), /* mulsi_const9 */
483 COSTS_N_INSNS (5), /* muldi */
484 COSTS_N_INSNS (35), /* divsi */
485 COSTS_N_INSNS (35), /* divdi */
486 COSTS_N_INSNS (11), /* fp */
487 COSTS_N_INSNS (11), /* dmul */
488 COSTS_N_INSNS (11), /* sdiv */
489 COSTS_N_INSNS (11), /* ddiv */
490 32, /* cache line size */
491 16, /* l1 cache */
492 128, /* l2 cache */
493 1, /* streams */
496 /* Instruction costs on PPC440 processors. */
497 static const
498 struct processor_costs ppc440_cost = {
499 COSTS_N_INSNS (3), /* mulsi */
500 COSTS_N_INSNS (2), /* mulsi_const */
501 COSTS_N_INSNS (2), /* mulsi_const9 */
502 COSTS_N_INSNS (3), /* muldi */
503 COSTS_N_INSNS (34), /* divsi */
504 COSTS_N_INSNS (34), /* divdi */
505 COSTS_N_INSNS (5), /* fp */
506 COSTS_N_INSNS (5), /* dmul */
507 COSTS_N_INSNS (19), /* sdiv */
508 COSTS_N_INSNS (33), /* ddiv */
509 32, /* cache line size */
510 32, /* l1 cache */
511 256, /* l2 cache */
512 1, /* streams */
515 /* Instruction costs on PPC476 processors. */
516 static const
517 struct processor_costs ppc476_cost = {
518 COSTS_N_INSNS (4), /* mulsi */
519 COSTS_N_INSNS (4), /* mulsi_const */
520 COSTS_N_INSNS (4), /* mulsi_const9 */
521 COSTS_N_INSNS (4), /* muldi */
522 COSTS_N_INSNS (11), /* divsi */
523 COSTS_N_INSNS (11), /* divdi */
524 COSTS_N_INSNS (6), /* fp */
525 COSTS_N_INSNS (6), /* dmul */
526 COSTS_N_INSNS (19), /* sdiv */
527 COSTS_N_INSNS (33), /* ddiv */
528 32, /* l1 cache line size */
529 32, /* l1 cache */
530 512, /* l2 cache */
531 1, /* streams */
534 /* Instruction costs on PPC601 processors. */
535 static const
536 struct processor_costs ppc601_cost = {
537 COSTS_N_INSNS (5), /* mulsi */
538 COSTS_N_INSNS (5), /* mulsi_const */
539 COSTS_N_INSNS (5), /* mulsi_const9 */
540 COSTS_N_INSNS (5), /* muldi */
541 COSTS_N_INSNS (36), /* divsi */
542 COSTS_N_INSNS (36), /* divdi */
543 COSTS_N_INSNS (4), /* fp */
544 COSTS_N_INSNS (5), /* dmul */
545 COSTS_N_INSNS (17), /* sdiv */
546 COSTS_N_INSNS (31), /* ddiv */
547 32, /* cache line size */
548 32, /* l1 cache */
549 256, /* l2 cache */
550 1, /* streams */
553 /* Instruction costs on PPC603 processors. */
554 static const
555 struct processor_costs ppc603_cost = {
556 COSTS_N_INSNS (5), /* mulsi */
557 COSTS_N_INSNS (3), /* mulsi_const */
558 COSTS_N_INSNS (2), /* mulsi_const9 */
559 COSTS_N_INSNS (5), /* muldi */
560 COSTS_N_INSNS (37), /* divsi */
561 COSTS_N_INSNS (37), /* divdi */
562 COSTS_N_INSNS (3), /* fp */
563 COSTS_N_INSNS (4), /* dmul */
564 COSTS_N_INSNS (18), /* sdiv */
565 COSTS_N_INSNS (33), /* ddiv */
566 32, /* cache line size */
567 8, /* l1 cache */
568 64, /* l2 cache */
569 1, /* streams */
572 /* Instruction costs on PPC604 processors. */
573 static const
574 struct processor_costs ppc604_cost = {
575 COSTS_N_INSNS (4), /* mulsi */
576 COSTS_N_INSNS (4), /* mulsi_const */
577 COSTS_N_INSNS (4), /* mulsi_const9 */
578 COSTS_N_INSNS (4), /* muldi */
579 COSTS_N_INSNS (20), /* divsi */
580 COSTS_N_INSNS (20), /* divdi */
581 COSTS_N_INSNS (3), /* fp */
582 COSTS_N_INSNS (3), /* dmul */
583 COSTS_N_INSNS (18), /* sdiv */
584 COSTS_N_INSNS (32), /* ddiv */
585 32, /* cache line size */
586 16, /* l1 cache */
587 512, /* l2 cache */
588 1, /* streams */
591 /* Instruction costs on PPC604e processors. */
592 static const
593 struct processor_costs ppc604e_cost = {
594 COSTS_N_INSNS (2), /* mulsi */
595 COSTS_N_INSNS (2), /* mulsi_const */
596 COSTS_N_INSNS (2), /* mulsi_const9 */
597 COSTS_N_INSNS (2), /* muldi */
598 COSTS_N_INSNS (20), /* divsi */
599 COSTS_N_INSNS (20), /* divdi */
600 COSTS_N_INSNS (3), /* fp */
601 COSTS_N_INSNS (3), /* dmul */
602 COSTS_N_INSNS (18), /* sdiv */
603 COSTS_N_INSNS (32), /* ddiv */
604 32, /* cache line size */
605 32, /* l1 cache */
606 1024, /* l2 cache */
607 1, /* streams */
610 /* Instruction costs on PPC620 processors. */
611 static const
612 struct processor_costs ppc620_cost = {
613 COSTS_N_INSNS (5), /* mulsi */
614 COSTS_N_INSNS (4), /* mulsi_const */
615 COSTS_N_INSNS (3), /* mulsi_const9 */
616 COSTS_N_INSNS (7), /* muldi */
617 COSTS_N_INSNS (21), /* divsi */
618 COSTS_N_INSNS (37), /* divdi */
619 COSTS_N_INSNS (3), /* fp */
620 COSTS_N_INSNS (3), /* dmul */
621 COSTS_N_INSNS (18), /* sdiv */
622 COSTS_N_INSNS (32), /* ddiv */
623 128, /* cache line size */
624 32, /* l1 cache */
625 1024, /* l2 cache */
626 1, /* streams */
629 /* Instruction costs on PPC630 processors. */
630 static const
631 struct processor_costs ppc630_cost = {
632 COSTS_N_INSNS (5), /* mulsi */
633 COSTS_N_INSNS (4), /* mulsi_const */
634 COSTS_N_INSNS (3), /* mulsi_const9 */
635 COSTS_N_INSNS (7), /* muldi */
636 COSTS_N_INSNS (21), /* divsi */
637 COSTS_N_INSNS (37), /* divdi */
638 COSTS_N_INSNS (3), /* fp */
639 COSTS_N_INSNS (3), /* dmul */
640 COSTS_N_INSNS (17), /* sdiv */
641 COSTS_N_INSNS (21), /* ddiv */
642 128, /* cache line size */
643 64, /* l1 cache */
644 1024, /* l2 cache */
645 1, /* streams */
648 /* Instruction costs on Cell processor. */
649 /* COSTS_N_INSNS (1) ~ one add. */
650 static const
651 struct processor_costs ppccell_cost = {
652 COSTS_N_INSNS (9/2)+2, /* mulsi */
653 COSTS_N_INSNS (6/2), /* mulsi_const */
654 COSTS_N_INSNS (6/2), /* mulsi_const9 */
655 COSTS_N_INSNS (15/2)+2, /* muldi */
656 COSTS_N_INSNS (38/2), /* divsi */
657 COSTS_N_INSNS (70/2), /* divdi */
658 COSTS_N_INSNS (10/2), /* fp */
659 COSTS_N_INSNS (10/2), /* dmul */
660 COSTS_N_INSNS (74/2), /* sdiv */
661 COSTS_N_INSNS (74/2), /* ddiv */
662 128, /* cache line size */
663 32, /* l1 cache */
664 512, /* l2 cache */
665 6, /* streams */
668 /* Instruction costs on PPC750 and PPC7400 processors. */
669 static const
670 struct processor_costs ppc750_cost = {
671 COSTS_N_INSNS (5), /* mulsi */
672 COSTS_N_INSNS (3), /* mulsi_const */
673 COSTS_N_INSNS (2), /* mulsi_const9 */
674 COSTS_N_INSNS (5), /* muldi */
675 COSTS_N_INSNS (17), /* divsi */
676 COSTS_N_INSNS (17), /* divdi */
677 COSTS_N_INSNS (3), /* fp */
678 COSTS_N_INSNS (3), /* dmul */
679 COSTS_N_INSNS (17), /* sdiv */
680 COSTS_N_INSNS (31), /* ddiv */
681 32, /* cache line size */
682 32, /* l1 cache */
683 512, /* l2 cache */
684 1, /* streams */
687 /* Instruction costs on PPC7450 processors. */
688 static const
689 struct processor_costs ppc7450_cost = {
690 COSTS_N_INSNS (4), /* mulsi */
691 COSTS_N_INSNS (3), /* mulsi_const */
692 COSTS_N_INSNS (3), /* mulsi_const9 */
693 COSTS_N_INSNS (4), /* muldi */
694 COSTS_N_INSNS (23), /* divsi */
695 COSTS_N_INSNS (23), /* divdi */
696 COSTS_N_INSNS (5), /* fp */
697 COSTS_N_INSNS (5), /* dmul */
698 COSTS_N_INSNS (21), /* sdiv */
699 COSTS_N_INSNS (35), /* ddiv */
700 32, /* cache line size */
701 32, /* l1 cache */
702 1024, /* l2 cache */
703 1, /* streams */
706 /* Instruction costs on PPC8540 processors. */
707 static const
708 struct processor_costs ppc8540_cost = {
709 COSTS_N_INSNS (4), /* mulsi */
710 COSTS_N_INSNS (4), /* mulsi_const */
711 COSTS_N_INSNS (4), /* mulsi_const9 */
712 COSTS_N_INSNS (4), /* muldi */
713 COSTS_N_INSNS (19), /* divsi */
714 COSTS_N_INSNS (19), /* divdi */
715 COSTS_N_INSNS (4), /* fp */
716 COSTS_N_INSNS (4), /* dmul */
717 COSTS_N_INSNS (29), /* sdiv */
718 COSTS_N_INSNS (29), /* ddiv */
719 32, /* cache line size */
720 32, /* l1 cache */
721 256, /* l2 cache */
722 1, /* prefetch streams /*/
725 /* Instruction costs on E300C2 and E300C3 cores. */
726 static const
727 struct processor_costs ppce300c2c3_cost = {
728 COSTS_N_INSNS (4), /* mulsi */
729 COSTS_N_INSNS (4), /* mulsi_const */
730 COSTS_N_INSNS (4), /* mulsi_const9 */
731 COSTS_N_INSNS (4), /* muldi */
732 COSTS_N_INSNS (19), /* divsi */
733 COSTS_N_INSNS (19), /* divdi */
734 COSTS_N_INSNS (3), /* fp */
735 COSTS_N_INSNS (4), /* dmul */
736 COSTS_N_INSNS (18), /* sdiv */
737 COSTS_N_INSNS (33), /* ddiv */
739 16, /* l1 cache */
740 16, /* l2 cache */
741 1, /* prefetch streams /*/
744 /* Instruction costs on PPCE500MC processors. */
745 static const
746 struct processor_costs ppce500mc_cost = {
747 COSTS_N_INSNS (4), /* mulsi */
748 COSTS_N_INSNS (4), /* mulsi_const */
749 COSTS_N_INSNS (4), /* mulsi_const9 */
750 COSTS_N_INSNS (4), /* muldi */
751 COSTS_N_INSNS (14), /* divsi */
752 COSTS_N_INSNS (14), /* divdi */
753 COSTS_N_INSNS (8), /* fp */
754 COSTS_N_INSNS (10), /* dmul */
755 COSTS_N_INSNS (36), /* sdiv */
756 COSTS_N_INSNS (66), /* ddiv */
757 64, /* cache line size */
758 32, /* l1 cache */
759 128, /* l2 cache */
760 1, /* prefetch streams /*/
763 /* Instruction costs on PPCE500MC64 processors. */
764 static const
765 struct processor_costs ppce500mc64_cost = {
766 COSTS_N_INSNS (4), /* mulsi */
767 COSTS_N_INSNS (4), /* mulsi_const */
768 COSTS_N_INSNS (4), /* mulsi_const9 */
769 COSTS_N_INSNS (4), /* muldi */
770 COSTS_N_INSNS (14), /* divsi */
771 COSTS_N_INSNS (14), /* divdi */
772 COSTS_N_INSNS (4), /* fp */
773 COSTS_N_INSNS (10), /* dmul */
774 COSTS_N_INSNS (36), /* sdiv */
775 COSTS_N_INSNS (66), /* ddiv */
776 64, /* cache line size */
777 32, /* l1 cache */
778 128, /* l2 cache */
779 1, /* prefetch streams /*/
782 /* Instruction costs on AppliedMicro Titan processors. */
783 static const
784 struct processor_costs titan_cost = {
785 COSTS_N_INSNS (5), /* mulsi */
786 COSTS_N_INSNS (5), /* mulsi_const */
787 COSTS_N_INSNS (5), /* mulsi_const9 */
788 COSTS_N_INSNS (5), /* muldi */
789 COSTS_N_INSNS (18), /* divsi */
790 COSTS_N_INSNS (18), /* divdi */
791 COSTS_N_INSNS (10), /* fp */
792 COSTS_N_INSNS (10), /* dmul */
793 COSTS_N_INSNS (46), /* sdiv */
794 COSTS_N_INSNS (72), /* ddiv */
795 32, /* cache line size */
796 32, /* l1 cache */
797 512, /* l2 cache */
798 1, /* prefetch streams /*/
801 /* Instruction costs on POWER4 and POWER5 processors. */
802 static const
803 struct processor_costs power4_cost = {
804 COSTS_N_INSNS (3), /* mulsi */
805 COSTS_N_INSNS (2), /* mulsi_const */
806 COSTS_N_INSNS (2), /* mulsi_const9 */
807 COSTS_N_INSNS (4), /* muldi */
808 COSTS_N_INSNS (18), /* divsi */
809 COSTS_N_INSNS (34), /* divdi */
810 COSTS_N_INSNS (3), /* fp */
811 COSTS_N_INSNS (3), /* dmul */
812 COSTS_N_INSNS (17), /* sdiv */
813 COSTS_N_INSNS (17), /* ddiv */
814 128, /* cache line size */
815 32, /* l1 cache */
816 1024, /* l2 cache */
817 8, /* prefetch streams /*/
820 /* Instruction costs on POWER6 processors. */
821 static const
822 struct processor_costs power6_cost = {
823 COSTS_N_INSNS (8), /* mulsi */
824 COSTS_N_INSNS (8), /* mulsi_const */
825 COSTS_N_INSNS (8), /* mulsi_const9 */
826 COSTS_N_INSNS (8), /* muldi */
827 COSTS_N_INSNS (22), /* divsi */
828 COSTS_N_INSNS (28), /* divdi */
829 COSTS_N_INSNS (3), /* fp */
830 COSTS_N_INSNS (3), /* dmul */
831 COSTS_N_INSNS (13), /* sdiv */
832 COSTS_N_INSNS (16), /* ddiv */
833 128, /* cache line size */
834 64, /* l1 cache */
835 2048, /* l2 cache */
836 16, /* prefetch streams */
839 /* Instruction costs on POWER7 processors. */
840 static const
841 struct processor_costs power7_cost = {
842 COSTS_N_INSNS (2), /* mulsi */
843 COSTS_N_INSNS (2), /* mulsi_const */
844 COSTS_N_INSNS (2), /* mulsi_const9 */
845 COSTS_N_INSNS (2), /* muldi */
846 COSTS_N_INSNS (18), /* divsi */
847 COSTS_N_INSNS (34), /* divdi */
848 COSTS_N_INSNS (3), /* fp */
849 COSTS_N_INSNS (3), /* dmul */
850 COSTS_N_INSNS (13), /* sdiv */
851 COSTS_N_INSNS (16), /* ddiv */
852 128, /* cache line size */
853 32, /* l1 cache */
854 256, /* l2 cache */
855 12, /* prefetch streams */
858 /* Instruction costs on POWER A2 processors. */
859 static const
860 struct processor_costs ppca2_cost = {
861 COSTS_N_INSNS (16), /* mulsi */
862 COSTS_N_INSNS (16), /* mulsi_const */
863 COSTS_N_INSNS (16), /* mulsi_const9 */
864 COSTS_N_INSNS (16), /* muldi */
865 COSTS_N_INSNS (22), /* divsi */
866 COSTS_N_INSNS (28), /* divdi */
867 COSTS_N_INSNS (3), /* fp */
868 COSTS_N_INSNS (3), /* dmul */
869 COSTS_N_INSNS (59), /* sdiv */
870 COSTS_N_INSNS (72), /* ddiv */
872 16, /* l1 cache */
873 2048, /* l2 cache */
874 16, /* prefetch streams */
878 /* Table that classifies rs6000 builtin functions (pure, const, etc.). */
879 #undef RS6000_BUILTIN
880 #undef RS6000_BUILTIN_EQUATE
881 #define RS6000_BUILTIN(NAME, TYPE) TYPE,
882 #define RS6000_BUILTIN_EQUATE(NAME, VALUE)
884 static const enum rs6000_btc builtin_classify[(int)RS6000_BUILTIN_COUNT] =
886 #include "rs6000-builtin.def"
889 #undef RS6000_BUILTIN
890 #undef RS6000_BUILTIN_EQUATE
892 /* Support for -mveclibabi=<xxx> to control which vector library to use. */
893 static tree (*rs6000_veclib_handler) (tree, tree, tree);
896 static bool rs6000_function_ok_for_sibcall (tree, tree);
897 static const char *rs6000_invalid_within_doloop (const_rtx);
898 static bool rs6000_legitimate_address_p (enum machine_mode, rtx, bool);
899 static bool rs6000_debug_legitimate_address_p (enum machine_mode, rtx, bool);
900 static rtx rs6000_generate_compare (rtx, enum machine_mode);
901 static void rs6000_emit_stack_tie (void);
902 static void rs6000_frame_related (rtx, rtx, HOST_WIDE_INT, rtx, rtx);
903 static bool spe_func_has_64bit_regs_p (void);
904 static void emit_frame_save (rtx, rtx, enum machine_mode, unsigned int,
905 int, HOST_WIDE_INT);
906 static rtx gen_frame_mem_offset (enum machine_mode, rtx, int);
907 static unsigned rs6000_hash_constant (rtx);
908 static unsigned toc_hash_function (const void *);
909 static int toc_hash_eq (const void *, const void *);
910 static bool reg_offset_addressing_ok_p (enum machine_mode);
911 static bool virtual_stack_registers_memory_p (rtx);
912 static bool constant_pool_expr_p (rtx);
913 static bool legitimate_small_data_p (enum machine_mode, rtx);
914 static bool legitimate_lo_sum_address_p (enum machine_mode, rtx, int);
915 static struct machine_function * rs6000_init_machine_status (void);
916 static bool rs6000_assemble_integer (rtx, unsigned int, int);
917 static bool no_global_regs_above (int, bool);
918 #ifdef HAVE_GAS_HIDDEN
919 static void rs6000_assemble_visibility (tree, int);
920 #endif
921 static int rs6000_ra_ever_killed (void);
922 static bool rs6000_attribute_takes_identifier_p (const_tree);
923 static tree rs6000_handle_longcall_attribute (tree *, tree, tree, int, bool *);
924 static tree rs6000_handle_altivec_attribute (tree *, tree, tree, int, bool *);
925 static bool rs6000_ms_bitfield_layout_p (const_tree);
926 static tree rs6000_handle_struct_attribute (tree *, tree, tree, int, bool *);
927 static void rs6000_eliminate_indexed_memrefs (rtx operands[2]);
928 static const char *rs6000_mangle_type (const_tree);
929 static void rs6000_set_default_type_attributes (tree);
930 static rtx rs6000_savres_routine_sym (rs6000_stack_t *, bool, bool, bool);
931 static rtx rs6000_emit_stack_reset (rs6000_stack_t *, rtx, rtx, int, bool);
932 static rtx rs6000_make_savres_rtx (rs6000_stack_t *, rtx, int,
933 enum machine_mode, bool, bool, bool);
934 static bool rs6000_reg_live_or_pic_offset_p (int);
935 static tree rs6000_builtin_vectorized_libmass (tree, tree, tree);
936 static tree rs6000_builtin_vectorized_function (tree, tree, tree);
937 static void rs6000_restore_saved_cr (rtx, int);
938 static bool rs6000_output_addr_const_extra (FILE *, rtx);
939 static void rs6000_output_function_prologue (FILE *, HOST_WIDE_INT);
940 static void rs6000_output_function_epilogue (FILE *, HOST_WIDE_INT);
941 static void rs6000_output_mi_thunk (FILE *, tree, HOST_WIDE_INT, HOST_WIDE_INT,
942 tree);
943 static rtx rs6000_emit_set_long_const (rtx, HOST_WIDE_INT, HOST_WIDE_INT);
944 static bool rs6000_return_in_memory (const_tree, const_tree);
945 static rtx rs6000_function_value (const_tree, const_tree, bool);
946 static void rs6000_file_start (void);
947 #if TARGET_ELF
948 static int rs6000_elf_reloc_rw_mask (void);
949 static void rs6000_elf_asm_out_constructor (rtx, int) ATTRIBUTE_UNUSED;
950 static void rs6000_elf_asm_out_destructor (rtx, int) ATTRIBUTE_UNUSED;
951 static void rs6000_elf_file_end (void) ATTRIBUTE_UNUSED;
952 static void rs6000_elf_asm_init_sections (void);
953 static section *rs6000_elf_select_rtx_section (enum machine_mode, rtx,
954 unsigned HOST_WIDE_INT);
955 static void rs6000_elf_encode_section_info (tree, rtx, int)
956 ATTRIBUTE_UNUSED;
957 #endif
958 static bool rs6000_use_blocks_for_constant_p (enum machine_mode, const_rtx);
959 static void rs6000_alloc_sdmode_stack_slot (void);
960 static void rs6000_instantiate_decls (void);
961 #if TARGET_XCOFF
962 static void rs6000_xcoff_asm_output_anchor (rtx);
963 static void rs6000_xcoff_asm_globalize_label (FILE *, const char *);
964 static void rs6000_xcoff_asm_init_sections (void);
965 static int rs6000_xcoff_reloc_rw_mask (void);
966 static void rs6000_xcoff_asm_named_section (const char *, unsigned int, tree);
967 static section *rs6000_xcoff_select_section (tree, int,
968 unsigned HOST_WIDE_INT);
969 static void rs6000_xcoff_unique_section (tree, int);
970 static section *rs6000_xcoff_select_rtx_section
971 (enum machine_mode, rtx, unsigned HOST_WIDE_INT);
972 static const char * rs6000_xcoff_strip_name_encoding (const char *);
973 static unsigned int rs6000_xcoff_section_type_flags (tree, const char *, int);
974 static void rs6000_xcoff_file_start (void);
975 static void rs6000_xcoff_file_end (void);
976 #endif
977 static int rs6000_variable_issue (FILE *, int, rtx, int);
978 static int rs6000_register_move_cost (enum machine_mode,
979 reg_class_t, reg_class_t);
980 static int rs6000_memory_move_cost (enum machine_mode, reg_class_t, bool);
981 static bool rs6000_rtx_costs (rtx, int, int, int *, bool);
982 static bool rs6000_debug_rtx_costs (rtx, int, int, int *, bool);
983 static int rs6000_debug_address_cost (rtx, bool);
984 static int rs6000_adjust_cost (rtx, rtx, rtx, int);
985 static int rs6000_debug_adjust_cost (rtx, rtx, rtx, int);
986 static void rs6000_sched_init (FILE *, int, int);
987 static bool is_microcoded_insn (rtx);
988 static bool is_nonpipeline_insn (rtx);
989 static bool is_cracked_insn (rtx);
990 static bool is_branch_slot_insn (rtx);
991 static bool is_load_insn (rtx);
992 static rtx get_store_dest (rtx pat);
993 static bool is_store_insn (rtx);
994 static bool set_to_load_agen (rtx,rtx);
995 static bool adjacent_mem_locations (rtx,rtx);
996 static int rs6000_adjust_priority (rtx, int);
997 static int rs6000_issue_rate (void);
998 static bool rs6000_is_costly_dependence (dep_t, int, int);
999 static rtx get_next_active_insn (rtx, rtx);
1000 static bool insn_terminates_group_p (rtx , enum group_termination);
1001 static bool insn_must_be_first_in_group (rtx);
1002 static bool insn_must_be_last_in_group (rtx);
1003 static bool is_costly_group (rtx *, rtx);
1004 static int force_new_group (int, FILE *, rtx *, rtx, bool *, int, int *);
1005 static int redefine_groups (FILE *, int, rtx, rtx);
1006 static int pad_groups (FILE *, int, rtx, rtx);
1007 static void rs6000_sched_finish (FILE *, int);
1008 static int rs6000_sched_reorder (FILE *, int, rtx *, int *, int);
1009 static int rs6000_sched_reorder2 (FILE *, int, rtx *, int *, int);
1010 static int rs6000_use_sched_lookahead (void);
1011 static int rs6000_use_sched_lookahead_guard (rtx);
1012 static void * rs6000_alloc_sched_context (void);
1013 static void rs6000_init_sched_context (void *, bool);
1014 static void rs6000_set_sched_context (void *);
1015 static void rs6000_free_sched_context (void *);
1016 static tree rs6000_builtin_reciprocal (unsigned int, bool, bool);
1017 static tree rs6000_builtin_mask_for_load (void);
1018 static tree rs6000_builtin_mul_widen_even (tree);
1019 static tree rs6000_builtin_mul_widen_odd (tree);
1020 static tree rs6000_builtin_conversion (unsigned int, tree, tree);
1021 static tree rs6000_builtin_vec_perm (tree, tree *);
1022 static bool rs6000_builtin_support_vector_misalignment (enum
1023 machine_mode,
1024 const_tree,
1025 int, bool);
1026 static int rs6000_builtin_vectorization_cost (enum vect_cost_for_stmt,
1027 tree, int);
1028 static enum machine_mode rs6000_preferred_simd_mode (enum machine_mode);
1030 static void def_builtin (int, const char *, tree, int);
1031 static bool rs6000_vector_alignment_reachable (const_tree, bool);
1032 static void rs6000_init_builtins (void);
1033 static tree rs6000_builtin_decl (unsigned, bool);
1035 static rtx rs6000_expand_unop_builtin (enum insn_code, tree, rtx);
1036 static rtx rs6000_expand_binop_builtin (enum insn_code, tree, rtx);
1037 static rtx rs6000_expand_ternop_builtin (enum insn_code, tree, rtx);
1038 static rtx rs6000_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
1039 static void altivec_init_builtins (void);
1040 static unsigned builtin_hash_function (const void *);
1041 static int builtin_hash_eq (const void *, const void *);
1042 static tree builtin_function_type (enum machine_mode, enum machine_mode,
1043 enum machine_mode, enum machine_mode,
1044 enum rs6000_builtins, const char *name);
1045 static void rs6000_common_init_builtins (void);
1046 static void rs6000_init_libfuncs (void);
1048 static void paired_init_builtins (void);
1049 static rtx paired_expand_builtin (tree, rtx, bool *);
1050 static rtx paired_expand_lv_builtin (enum insn_code, tree, rtx);
1051 static rtx paired_expand_stv_builtin (enum insn_code, tree);
1052 static rtx paired_expand_predicate_builtin (enum insn_code, tree, rtx);
1054 static void enable_mask_for_builtins (struct builtin_description *, int,
1055 enum rs6000_builtins,
1056 enum rs6000_builtins);
1057 static void spe_init_builtins (void);
1058 static rtx spe_expand_builtin (tree, rtx, bool *);
1059 static rtx spe_expand_stv_builtin (enum insn_code, tree);
1060 static rtx spe_expand_predicate_builtin (enum insn_code, tree, rtx);
1061 static rtx spe_expand_evsel_builtin (enum insn_code, tree, rtx);
1062 static int rs6000_emit_int_cmove (rtx, rtx, rtx, rtx);
1063 static rs6000_stack_t *rs6000_stack_info (void);
1064 static void debug_stack_info (rs6000_stack_t *);
1066 static rtx altivec_expand_builtin (tree, rtx, bool *);
1067 static rtx altivec_expand_ld_builtin (tree, rtx, bool *);
1068 static rtx altivec_expand_st_builtin (tree, rtx, bool *);
1069 static rtx altivec_expand_dst_builtin (tree, rtx, bool *);
1070 static rtx altivec_expand_abs_builtin (enum insn_code, tree, rtx);
1071 static rtx altivec_expand_predicate_builtin (enum insn_code, tree, rtx);
1072 static rtx altivec_expand_stv_builtin (enum insn_code, tree);
1073 static rtx altivec_expand_vec_init_builtin (tree, tree, rtx);
1074 static rtx altivec_expand_vec_set_builtin (tree);
1075 static rtx altivec_expand_vec_ext_builtin (tree, rtx);
1076 static int get_element_number (tree, tree);
1077 static void rs6000_option_override (void);
1078 static void rs6000_option_init_struct (struct gcc_options *);
1079 static void rs6000_option_default_params (void);
1080 static bool rs6000_handle_option (size_t, const char *, int);
1081 static int rs6000_loop_align_max_skip (rtx);
1082 static void rs6000_parse_yes_no_option (const char *, const char *, int *);
1083 static int first_altivec_reg_to_save (void);
1084 static unsigned int compute_vrsave_mask (void);
1085 static void compute_save_world_info (rs6000_stack_t *info_ptr);
1086 static void is_altivec_return_reg (rtx, void *);
1087 static rtx generate_set_vrsave (rtx, rs6000_stack_t *, int);
1088 int easy_vector_constant (rtx, enum machine_mode);
1089 static rtx rs6000_dwarf_register_span (rtx);
1090 static void rs6000_init_dwarf_reg_sizes_extra (tree);
1091 static rtx rs6000_legitimize_address (rtx, rtx, enum machine_mode);
1092 static rtx rs6000_debug_legitimize_address (rtx, rtx, enum machine_mode);
1093 static rtx rs6000_legitimize_tls_address (rtx, enum tls_model);
1094 static void rs6000_output_dwarf_dtprel (FILE *, int, rtx) ATTRIBUTE_UNUSED;
1095 static rtx rs6000_delegitimize_address (rtx);
1096 static rtx rs6000_tls_get_addr (void);
1097 static rtx rs6000_got_sym (void);
1098 static int rs6000_tls_symbol_ref_1 (rtx *, void *);
1099 static const char *rs6000_get_some_local_dynamic_name (void);
1100 static int rs6000_get_some_local_dynamic_name_1 (rtx *, void *);
1101 static rtx rs6000_complex_function_value (enum machine_mode);
1102 static rtx rs6000_spe_function_arg (const CUMULATIVE_ARGS *,
1103 enum machine_mode, const_tree);
1104 static void rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS *,
1105 HOST_WIDE_INT, int);
1106 static void rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS *,
1107 const_tree,
1108 HOST_WIDE_INT);
1109 static void rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS *,
1110 HOST_WIDE_INT,
1111 rtx[], int *);
1112 static void rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *,
1113 const_tree, HOST_WIDE_INT,
1114 rtx[], int *);
1115 static rtx rs6000_darwin64_record_arg (CUMULATIVE_ARGS *, const_tree, bool, bool);
1116 static rtx rs6000_mixed_function_arg (enum machine_mode, const_tree, int);
1117 static void rs6000_function_arg_advance (CUMULATIVE_ARGS *, enum machine_mode,
1118 const_tree, bool);
1119 static rtx rs6000_function_arg (CUMULATIVE_ARGS *, enum machine_mode,
1120 const_tree, bool);
1121 static unsigned int rs6000_function_arg_boundary (enum machine_mode,
1122 const_tree);
1123 static void rs6000_move_block_from_reg (int regno, rtx x, int nregs);
1124 static void setup_incoming_varargs (CUMULATIVE_ARGS *,
1125 enum machine_mode, tree,
1126 int *, int);
1127 static bool rs6000_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode,
1128 const_tree, bool);
1129 static int rs6000_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode,
1130 tree, bool);
1131 static const char *invalid_arg_for_unprototyped_fn (const_tree, const_tree, const_tree);
1132 #if TARGET_MACHO
1133 static void macho_branch_islands (void);
1134 static int no_previous_def (tree function_name);
1135 static tree get_prev_label (tree function_name);
1136 static void rs6000_darwin_file_start (void);
1137 #endif
1139 static tree rs6000_build_builtin_va_list (void);
1140 static void rs6000_va_start (tree, rtx);
1141 static tree rs6000_gimplify_va_arg (tree, tree, gimple_seq *, gimple_seq *);
1142 static bool rs6000_must_pass_in_stack (enum machine_mode, const_tree);
1143 static bool rs6000_scalar_mode_supported_p (enum machine_mode);
1144 static bool rs6000_vector_mode_supported_p (enum machine_mode);
1145 static rtx rs6000_emit_vector_compare_inner (enum rtx_code, rtx, rtx);
1146 static rtx rs6000_emit_vector_compare (enum rtx_code, rtx, rtx,
1147 enum machine_mode);
1148 static tree rs6000_stack_protect_fail (void);
1150 static rtx rs6000_legitimize_reload_address (rtx, enum machine_mode, int, int,
1151 int, int *);
1153 static rtx rs6000_debug_legitimize_reload_address (rtx, enum machine_mode, int,
1154 int, int, int *);
1156 rtx (*rs6000_legitimize_reload_address_ptr) (rtx, enum machine_mode, int, int,
1157 int, int *)
1158 = rs6000_legitimize_reload_address;
1160 static bool rs6000_mode_dependent_address_p (const_rtx);
1161 static bool rs6000_mode_dependent_address (const_rtx);
1162 static bool rs6000_debug_mode_dependent_address (const_rtx);
1163 static bool (*rs6000_mode_dependent_address_ptr) (const_rtx)
1164 = rs6000_mode_dependent_address;
1166 static enum reg_class rs6000_secondary_reload_class (enum reg_class,
1167 enum machine_mode, rtx);
1168 static enum reg_class rs6000_debug_secondary_reload_class (enum reg_class,
1169 enum machine_mode,
1170 rtx);
1171 enum reg_class (*rs6000_secondary_reload_class_ptr) (enum reg_class,
1172 enum machine_mode, rtx)
1173 = rs6000_secondary_reload_class;
1175 static enum reg_class rs6000_preferred_reload_class (rtx, enum reg_class);
1176 static enum reg_class rs6000_debug_preferred_reload_class (rtx,
1177 enum reg_class);
1178 enum reg_class (*rs6000_preferred_reload_class_ptr) (rtx, enum reg_class)
1179 = rs6000_preferred_reload_class;
1181 static bool rs6000_secondary_memory_needed (enum reg_class, enum reg_class,
1182 enum machine_mode);
1184 static bool rs6000_debug_secondary_memory_needed (enum reg_class,
1185 enum reg_class,
1186 enum machine_mode);
1188 bool (*rs6000_secondary_memory_needed_ptr) (enum reg_class, enum reg_class,
1189 enum machine_mode)
1190 = rs6000_secondary_memory_needed;
1192 static bool rs6000_cannot_change_mode_class (enum machine_mode,
1193 enum machine_mode,
1194 enum reg_class);
1195 static bool rs6000_debug_cannot_change_mode_class (enum machine_mode,
1196 enum machine_mode,
1197 enum reg_class);
1199 bool (*rs6000_cannot_change_mode_class_ptr) (enum machine_mode,
1200 enum machine_mode,
1201 enum reg_class)
1202 = rs6000_cannot_change_mode_class;
1204 static reg_class_t rs6000_secondary_reload (bool, rtx, reg_class_t,
1205 enum machine_mode,
1206 struct secondary_reload_info *);
1208 static const reg_class_t *rs6000_ira_cover_classes (void);
1210 const int INSN_NOT_AVAILABLE = -1;
1211 static enum machine_mode rs6000_eh_return_filter_mode (void);
1212 static bool rs6000_can_eliminate (const int, const int);
1213 static void rs6000_conditional_register_usage (void);
1214 static void rs6000_trampoline_init (rtx, tree, rtx);
1216 /* Hash table stuff for keeping track of TOC entries. */
1218 struct GTY(()) toc_hash_struct
1220 /* `key' will satisfy CONSTANT_P; in fact, it will satisfy
1221 ASM_OUTPUT_SPECIAL_POOL_ENTRY_P. */
1222 rtx key;
1223 enum machine_mode key_mode;
1224 int labelno;
1227 static GTY ((param_is (struct toc_hash_struct))) htab_t toc_hash_table;
1229 /* Hash table to keep track of the argument types for builtin functions. */
1231 struct GTY(()) builtin_hash_struct
1233 tree type;
1234 enum machine_mode mode[4]; /* return value + 3 arguments. */
1235 unsigned char uns_p[4]; /* and whether the types are unsigned. */
1238 static GTY ((param_is (struct builtin_hash_struct))) htab_t builtin_hash_table;
1240 static bool rs6000_valid_attribute_p (tree, tree, tree, int);
1241 static void rs6000_function_specific_save (struct cl_target_option *);
1242 static void rs6000_function_specific_restore (struct cl_target_option *);
1243 static void rs6000_function_specific_print (FILE *, int,
1244 struct cl_target_option *);
1245 static bool rs6000_can_inline_p (tree, tree);
1246 static void rs6000_set_current_function (tree);
1249 /* Default register names. */
1250 char rs6000_reg_names[][8] =
1252 "0", "1", "2", "3", "4", "5", "6", "7",
1253 "8", "9", "10", "11", "12", "13", "14", "15",
1254 "16", "17", "18", "19", "20", "21", "22", "23",
1255 "24", "25", "26", "27", "28", "29", "30", "31",
1256 "0", "1", "2", "3", "4", "5", "6", "7",
1257 "8", "9", "10", "11", "12", "13", "14", "15",
1258 "16", "17", "18", "19", "20", "21", "22", "23",
1259 "24", "25", "26", "27", "28", "29", "30", "31",
1260 "mq", "lr", "ctr","ap",
1261 "0", "1", "2", "3", "4", "5", "6", "7",
1262 "ca",
1263 /* AltiVec registers. */
1264 "0", "1", "2", "3", "4", "5", "6", "7",
1265 "8", "9", "10", "11", "12", "13", "14", "15",
1266 "16", "17", "18", "19", "20", "21", "22", "23",
1267 "24", "25", "26", "27", "28", "29", "30", "31",
1268 "vrsave", "vscr",
1269 /* SPE registers. */
1270 "spe_acc", "spefscr",
1271 /* Soft frame pointer. */
1272 "sfp"
1275 #ifdef TARGET_REGNAMES
1276 static const char alt_reg_names[][8] =
1278 "%r0", "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7",
1279 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15",
1280 "%r16", "%r17", "%r18", "%r19", "%r20", "%r21", "%r22", "%r23",
1281 "%r24", "%r25", "%r26", "%r27", "%r28", "%r29", "%r30", "%r31",
1282 "%f0", "%f1", "%f2", "%f3", "%f4", "%f5", "%f6", "%f7",
1283 "%f8", "%f9", "%f10", "%f11", "%f12", "%f13", "%f14", "%f15",
1284 "%f16", "%f17", "%f18", "%f19", "%f20", "%f21", "%f22", "%f23",
1285 "%f24", "%f25", "%f26", "%f27", "%f28", "%f29", "%f30", "%f31",
1286 "mq", "lr", "ctr", "ap",
1287 "%cr0", "%cr1", "%cr2", "%cr3", "%cr4", "%cr5", "%cr6", "%cr7",
1288 "ca",
1289 /* AltiVec registers. */
1290 "%v0", "%v1", "%v2", "%v3", "%v4", "%v5", "%v6", "%v7",
1291 "%v8", "%v9", "%v10", "%v11", "%v12", "%v13", "%v14", "%v15",
1292 "%v16", "%v17", "%v18", "%v19", "%v20", "%v21", "%v22", "%v23",
1293 "%v24", "%v25", "%v26", "%v27", "%v28", "%v29", "%v30", "%v31",
1294 "vrsave", "vscr",
1295 /* SPE registers. */
1296 "spe_acc", "spefscr",
1297 /* Soft frame pointer. */
1298 "sfp"
1300 #endif
1302 /* Table of valid machine attributes. */
1304 static const struct attribute_spec rs6000_attribute_table[] =
1306 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
1307 { "altivec", 1, 1, false, true, false, rs6000_handle_altivec_attribute },
1308 { "longcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute },
1309 { "shortcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute },
1310 { "ms_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute },
1311 { "gcc_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute },
1312 #ifdef SUBTARGET_ATTRIBUTE_TABLE
1313 SUBTARGET_ATTRIBUTE_TABLE,
1314 #endif
1315 { NULL, 0, 0, false, false, false, NULL }
1318 /* Implement TARGET_OPTION_OPTIMIZATION_TABLE. */
1319 static const struct default_options rs6000_option_optimization_table[] =
1321 { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 },
1322 { OPT_LEVELS_NONE, 0, NULL, 0 }
1325 #ifndef MASK_STRICT_ALIGN
1326 #define MASK_STRICT_ALIGN 0
1327 #endif
1328 #ifndef TARGET_PROFILE_KERNEL
1329 #define TARGET_PROFILE_KERNEL 0
1330 #endif
1332 /* The VRSAVE bitmask puts bit %v0 as the most significant bit. */
1333 #define ALTIVEC_REG_BIT(REGNO) (0x80000000 >> ((REGNO) - FIRST_ALTIVEC_REGNO))
1335 /* Initialize the GCC target structure. */
1336 #undef TARGET_ATTRIBUTE_TABLE
1337 #define TARGET_ATTRIBUTE_TABLE rs6000_attribute_table
1338 #undef TARGET_SET_DEFAULT_TYPE_ATTRIBUTES
1339 #define TARGET_SET_DEFAULT_TYPE_ATTRIBUTES rs6000_set_default_type_attributes
1340 #undef TARGET_ATTRIBUTE_TAKES_IDENTIFIER_P
1341 #define TARGET_ATTRIBUTE_TAKES_IDENTIFIER_P rs6000_attribute_takes_identifier_p
1343 #undef TARGET_ASM_ALIGNED_DI_OP
1344 #define TARGET_ASM_ALIGNED_DI_OP DOUBLE_INT_ASM_OP
1346 /* Default unaligned ops are only provided for ELF. Find the ops needed
1347 for non-ELF systems. */
1348 #ifndef OBJECT_FORMAT_ELF
1349 #if TARGET_XCOFF
1350 /* For XCOFF. rs6000_assemble_integer will handle unaligned DIs on
1351 64-bit targets. */
1352 #undef TARGET_ASM_UNALIGNED_HI_OP
1353 #define TARGET_ASM_UNALIGNED_HI_OP "\t.vbyte\t2,"
1354 #undef TARGET_ASM_UNALIGNED_SI_OP
1355 #define TARGET_ASM_UNALIGNED_SI_OP "\t.vbyte\t4,"
1356 #undef TARGET_ASM_UNALIGNED_DI_OP
1357 #define TARGET_ASM_UNALIGNED_DI_OP "\t.vbyte\t8,"
1358 #else
1359 /* For Darwin. */
1360 #undef TARGET_ASM_UNALIGNED_HI_OP
1361 #define TARGET_ASM_UNALIGNED_HI_OP "\t.short\t"
1362 #undef TARGET_ASM_UNALIGNED_SI_OP
1363 #define TARGET_ASM_UNALIGNED_SI_OP "\t.long\t"
1364 #undef TARGET_ASM_UNALIGNED_DI_OP
1365 #define TARGET_ASM_UNALIGNED_DI_OP "\t.quad\t"
1366 #undef TARGET_ASM_ALIGNED_DI_OP
1367 #define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t"
1368 #endif
1369 #endif
1371 /* This hook deals with fixups for relocatable code and DI-mode objects
1372 in 64-bit code. */
1373 #undef TARGET_ASM_INTEGER
1374 #define TARGET_ASM_INTEGER rs6000_assemble_integer
1376 #ifdef HAVE_GAS_HIDDEN
1377 #undef TARGET_ASM_ASSEMBLE_VISIBILITY
1378 #define TARGET_ASM_ASSEMBLE_VISIBILITY rs6000_assemble_visibility
1379 #endif
1381 #undef TARGET_HAVE_TLS
1382 #define TARGET_HAVE_TLS HAVE_AS_TLS
1384 #undef TARGET_CANNOT_FORCE_CONST_MEM
1385 #define TARGET_CANNOT_FORCE_CONST_MEM rs6000_tls_referenced_p
1387 #undef TARGET_DELEGITIMIZE_ADDRESS
1388 #define TARGET_DELEGITIMIZE_ADDRESS rs6000_delegitimize_address
1390 #undef TARGET_ASM_FUNCTION_PROLOGUE
1391 #define TARGET_ASM_FUNCTION_PROLOGUE rs6000_output_function_prologue
1392 #undef TARGET_ASM_FUNCTION_EPILOGUE
1393 #define TARGET_ASM_FUNCTION_EPILOGUE rs6000_output_function_epilogue
1395 #undef TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA
1396 #define TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA rs6000_output_addr_const_extra
1398 #undef TARGET_LEGITIMIZE_ADDRESS
1399 #define TARGET_LEGITIMIZE_ADDRESS rs6000_legitimize_address
1401 #undef TARGET_SCHED_VARIABLE_ISSUE
1402 #define TARGET_SCHED_VARIABLE_ISSUE rs6000_variable_issue
1404 #undef TARGET_SCHED_ISSUE_RATE
1405 #define TARGET_SCHED_ISSUE_RATE rs6000_issue_rate
1406 #undef TARGET_SCHED_ADJUST_COST
1407 #define TARGET_SCHED_ADJUST_COST rs6000_adjust_cost
1408 #undef TARGET_SCHED_ADJUST_PRIORITY
1409 #define TARGET_SCHED_ADJUST_PRIORITY rs6000_adjust_priority
1410 #undef TARGET_SCHED_IS_COSTLY_DEPENDENCE
1411 #define TARGET_SCHED_IS_COSTLY_DEPENDENCE rs6000_is_costly_dependence
1412 #undef TARGET_SCHED_INIT
1413 #define TARGET_SCHED_INIT rs6000_sched_init
1414 #undef TARGET_SCHED_FINISH
1415 #define TARGET_SCHED_FINISH rs6000_sched_finish
1416 #undef TARGET_SCHED_REORDER
1417 #define TARGET_SCHED_REORDER rs6000_sched_reorder
1418 #undef TARGET_SCHED_REORDER2
1419 #define TARGET_SCHED_REORDER2 rs6000_sched_reorder2
1421 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
1422 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD rs6000_use_sched_lookahead
1424 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD
1425 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD rs6000_use_sched_lookahead_guard
1427 #undef TARGET_SCHED_ALLOC_SCHED_CONTEXT
1428 #define TARGET_SCHED_ALLOC_SCHED_CONTEXT rs6000_alloc_sched_context
1429 #undef TARGET_SCHED_INIT_SCHED_CONTEXT
1430 #define TARGET_SCHED_INIT_SCHED_CONTEXT rs6000_init_sched_context
1431 #undef TARGET_SCHED_SET_SCHED_CONTEXT
1432 #define TARGET_SCHED_SET_SCHED_CONTEXT rs6000_set_sched_context
1433 #undef TARGET_SCHED_FREE_SCHED_CONTEXT
1434 #define TARGET_SCHED_FREE_SCHED_CONTEXT rs6000_free_sched_context
1436 #undef TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD
1437 #define TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD rs6000_builtin_mask_for_load
1438 #undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN
1439 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN rs6000_builtin_mul_widen_even
1440 #undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD
1441 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD rs6000_builtin_mul_widen_odd
1442 #undef TARGET_VECTORIZE_BUILTIN_CONVERSION
1443 #define TARGET_VECTORIZE_BUILTIN_CONVERSION rs6000_builtin_conversion
1444 #undef TARGET_VECTORIZE_BUILTIN_VEC_PERM
1445 #define TARGET_VECTORIZE_BUILTIN_VEC_PERM rs6000_builtin_vec_perm
1446 #undef TARGET_VECTORIZE_SUPPORT_VECTOR_MISALIGNMENT
1447 #define TARGET_VECTORIZE_SUPPORT_VECTOR_MISALIGNMENT \
1448 rs6000_builtin_support_vector_misalignment
1449 #undef TARGET_VECTORIZE_VECTOR_ALIGNMENT_REACHABLE
1450 #define TARGET_VECTORIZE_VECTOR_ALIGNMENT_REACHABLE rs6000_vector_alignment_reachable
1451 #undef TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST
1452 #define TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST \
1453 rs6000_builtin_vectorization_cost
1454 #undef TARGET_VECTORIZE_PREFERRED_SIMD_MODE
1455 #define TARGET_VECTORIZE_PREFERRED_SIMD_MODE \
1456 rs6000_preferred_simd_mode
1458 #undef TARGET_INIT_BUILTINS
1459 #define TARGET_INIT_BUILTINS rs6000_init_builtins
1460 #undef TARGET_BUILTIN_DECL
1461 #define TARGET_BUILTIN_DECL rs6000_builtin_decl
1463 #undef TARGET_EXPAND_BUILTIN
1464 #define TARGET_EXPAND_BUILTIN rs6000_expand_builtin
1466 #undef TARGET_MANGLE_TYPE
1467 #define TARGET_MANGLE_TYPE rs6000_mangle_type
1469 #undef TARGET_INIT_LIBFUNCS
1470 #define TARGET_INIT_LIBFUNCS rs6000_init_libfuncs
1472 #if TARGET_MACHO
1473 #undef TARGET_BINDS_LOCAL_P
1474 #define TARGET_BINDS_LOCAL_P darwin_binds_local_p
1475 #endif
1477 #undef TARGET_MS_BITFIELD_LAYOUT_P
1478 #define TARGET_MS_BITFIELD_LAYOUT_P rs6000_ms_bitfield_layout_p
1480 #undef TARGET_ASM_OUTPUT_MI_THUNK
1481 #define TARGET_ASM_OUTPUT_MI_THUNK rs6000_output_mi_thunk
1483 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
1484 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true
1486 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
1487 #define TARGET_FUNCTION_OK_FOR_SIBCALL rs6000_function_ok_for_sibcall
1489 #undef TARGET_INVALID_WITHIN_DOLOOP
1490 #define TARGET_INVALID_WITHIN_DOLOOP rs6000_invalid_within_doloop
1492 #undef TARGET_REGISTER_MOVE_COST
1493 #define TARGET_REGISTER_MOVE_COST rs6000_register_move_cost
1494 #undef TARGET_MEMORY_MOVE_COST
1495 #define TARGET_MEMORY_MOVE_COST rs6000_memory_move_cost
1496 #undef TARGET_RTX_COSTS
1497 #define TARGET_RTX_COSTS rs6000_rtx_costs
1498 #undef TARGET_ADDRESS_COST
1499 #define TARGET_ADDRESS_COST hook_int_rtx_bool_0
1501 #undef TARGET_DWARF_REGISTER_SPAN
1502 #define TARGET_DWARF_REGISTER_SPAN rs6000_dwarf_register_span
1504 #undef TARGET_INIT_DWARF_REG_SIZES_EXTRA
1505 #define TARGET_INIT_DWARF_REG_SIZES_EXTRA rs6000_init_dwarf_reg_sizes_extra
1507 /* On rs6000, function arguments are promoted, as are function return
1508 values. */
1509 #undef TARGET_PROMOTE_FUNCTION_MODE
1510 #define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote
1512 #undef TARGET_RETURN_IN_MEMORY
1513 #define TARGET_RETURN_IN_MEMORY rs6000_return_in_memory
1515 #undef TARGET_SETUP_INCOMING_VARARGS
1516 #define TARGET_SETUP_INCOMING_VARARGS setup_incoming_varargs
1518 /* Always strict argument naming on rs6000. */
1519 #undef TARGET_STRICT_ARGUMENT_NAMING
1520 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
1521 #undef TARGET_PRETEND_OUTGOING_VARARGS_NAMED
1522 #define TARGET_PRETEND_OUTGOING_VARARGS_NAMED hook_bool_CUMULATIVE_ARGS_true
1523 #undef TARGET_SPLIT_COMPLEX_ARG
1524 #define TARGET_SPLIT_COMPLEX_ARG hook_bool_const_tree_true
1525 #undef TARGET_MUST_PASS_IN_STACK
1526 #define TARGET_MUST_PASS_IN_STACK rs6000_must_pass_in_stack
1527 #undef TARGET_PASS_BY_REFERENCE
1528 #define TARGET_PASS_BY_REFERENCE rs6000_pass_by_reference
1529 #undef TARGET_ARG_PARTIAL_BYTES
1530 #define TARGET_ARG_PARTIAL_BYTES rs6000_arg_partial_bytes
1531 #undef TARGET_FUNCTION_ARG_ADVANCE
1532 #define TARGET_FUNCTION_ARG_ADVANCE rs6000_function_arg_advance
1533 #undef TARGET_FUNCTION_ARG
1534 #define TARGET_FUNCTION_ARG rs6000_function_arg
1535 #undef TARGET_FUNCTION_ARG_BOUNDARY
1536 #define TARGET_FUNCTION_ARG_BOUNDARY rs6000_function_arg_boundary
1538 #undef TARGET_BUILD_BUILTIN_VA_LIST
1539 #define TARGET_BUILD_BUILTIN_VA_LIST rs6000_build_builtin_va_list
1541 #undef TARGET_EXPAND_BUILTIN_VA_START
1542 #define TARGET_EXPAND_BUILTIN_VA_START rs6000_va_start
1544 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
1545 #define TARGET_GIMPLIFY_VA_ARG_EXPR rs6000_gimplify_va_arg
1547 #undef TARGET_EH_RETURN_FILTER_MODE
1548 #define TARGET_EH_RETURN_FILTER_MODE rs6000_eh_return_filter_mode
1550 #undef TARGET_SCALAR_MODE_SUPPORTED_P
1551 #define TARGET_SCALAR_MODE_SUPPORTED_P rs6000_scalar_mode_supported_p
1553 #undef TARGET_VECTOR_MODE_SUPPORTED_P
1554 #define TARGET_VECTOR_MODE_SUPPORTED_P rs6000_vector_mode_supported_p
1556 #undef TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN
1557 #define TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN invalid_arg_for_unprototyped_fn
1559 #undef TARGET_HANDLE_OPTION
1560 #define TARGET_HANDLE_OPTION rs6000_handle_option
1562 #undef TARGET_ASM_LOOP_ALIGN_MAX_SKIP
1563 #define TARGET_ASM_LOOP_ALIGN_MAX_SKIP rs6000_loop_align_max_skip
1565 #undef TARGET_OPTION_OVERRIDE
1566 #define TARGET_OPTION_OVERRIDE rs6000_option_override
1568 #undef TARGET_OPTION_INIT_STRUCT
1569 #define TARGET_OPTION_INIT_STRUCT rs6000_option_init_struct
1571 #undef TARGET_OPTION_DEFAULT_PARAMS
1572 #define TARGET_OPTION_DEFAULT_PARAMS rs6000_option_default_params
1574 #undef TARGET_OPTION_OPTIMIZATION_TABLE
1575 #define TARGET_OPTION_OPTIMIZATION_TABLE rs6000_option_optimization_table
1577 #undef TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION
1578 #define TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION \
1579 rs6000_builtin_vectorized_function
1581 #undef TARGET_DEFAULT_TARGET_FLAGS
1582 #define TARGET_DEFAULT_TARGET_FLAGS \
1583 (TARGET_DEFAULT)
1585 #undef TARGET_STACK_PROTECT_FAIL
1586 #define TARGET_STACK_PROTECT_FAIL rs6000_stack_protect_fail
1588 /* MPC604EUM 3.5.2 Weak Consistency between Multiple Processors
1589 The PowerPC architecture requires only weak consistency among
1590 processors--that is, memory accesses between processors need not be
1591 sequentially consistent and memory accesses among processors can occur
1592 in any order. The ability to order memory accesses weakly provides
1593 opportunities for more efficient use of the system bus. Unless a
1594 dependency exists, the 604e allows read operations to precede store
1595 operations. */
1596 #undef TARGET_RELAXED_ORDERING
1597 #define TARGET_RELAXED_ORDERING true
1599 #ifdef HAVE_AS_TLS
1600 #undef TARGET_ASM_OUTPUT_DWARF_DTPREL
1601 #define TARGET_ASM_OUTPUT_DWARF_DTPREL rs6000_output_dwarf_dtprel
1602 #endif
1604 /* Use a 32-bit anchor range. This leads to sequences like:
1606 addis tmp,anchor,high
1607 add dest,tmp,low
1609 where tmp itself acts as an anchor, and can be shared between
1610 accesses to the same 64k page. */
1611 #undef TARGET_MIN_ANCHOR_OFFSET
1612 #define TARGET_MIN_ANCHOR_OFFSET -0x7fffffff - 1
1613 #undef TARGET_MAX_ANCHOR_OFFSET
1614 #define TARGET_MAX_ANCHOR_OFFSET 0x7fffffff
1615 #undef TARGET_USE_BLOCKS_FOR_CONSTANT_P
1616 #define TARGET_USE_BLOCKS_FOR_CONSTANT_P rs6000_use_blocks_for_constant_p
1618 #undef TARGET_BUILTIN_RECIPROCAL
1619 #define TARGET_BUILTIN_RECIPROCAL rs6000_builtin_reciprocal
1621 #undef TARGET_EXPAND_TO_RTL_HOOK
1622 #define TARGET_EXPAND_TO_RTL_HOOK rs6000_alloc_sdmode_stack_slot
1624 #undef TARGET_INSTANTIATE_DECLS
1625 #define TARGET_INSTANTIATE_DECLS rs6000_instantiate_decls
1627 #undef TARGET_SECONDARY_RELOAD
1628 #define TARGET_SECONDARY_RELOAD rs6000_secondary_reload
1630 #undef TARGET_IRA_COVER_CLASSES
1631 #define TARGET_IRA_COVER_CLASSES rs6000_ira_cover_classes
1633 #undef TARGET_LEGITIMATE_ADDRESS_P
1634 #define TARGET_LEGITIMATE_ADDRESS_P rs6000_legitimate_address_p
1636 #undef TARGET_MODE_DEPENDENT_ADDRESS_P
1637 #define TARGET_MODE_DEPENDENT_ADDRESS_P rs6000_mode_dependent_address_p
1639 #undef TARGET_CAN_ELIMINATE
1640 #define TARGET_CAN_ELIMINATE rs6000_can_eliminate
1642 #undef TARGET_CONDITIONAL_REGISTER_USAGE
1643 #define TARGET_CONDITIONAL_REGISTER_USAGE rs6000_conditional_register_usage
1645 #undef TARGET_TRAMPOLINE_INIT
1646 #define TARGET_TRAMPOLINE_INIT rs6000_trampoline_init
1648 #undef TARGET_FUNCTION_VALUE
1649 #define TARGET_FUNCTION_VALUE rs6000_function_value
1651 #undef TARGET_OPTION_VALID_ATTRIBUTE_P
1652 #define TARGET_OPTION_VALID_ATTRIBUTE_P rs6000_valid_attribute_p
1654 #undef TARGET_OPTION_SAVE
1655 #define TARGET_OPTION_SAVE rs6000_function_specific_save
1657 #undef TARGET_OPTION_RESTORE
1658 #define TARGET_OPTION_RESTORE rs6000_function_specific_restore
1660 #undef TARGET_OPTION_PRINT
1661 #define TARGET_OPTION_PRINT rs6000_function_specific_print
1663 #undef TARGET_CAN_INLINE_P
1664 #define TARGET_CAN_INLINE_P rs6000_can_inline_p
1666 #undef TARGET_SET_CURRENT_FUNCTION
1667 #define TARGET_SET_CURRENT_FUNCTION rs6000_set_current_function
1669 struct gcc_target targetm = TARGET_INITIALIZER;
1672 /* Simplifications for entries below. */
1674 enum {
1675 POWERPC_BASE_MASK = MASK_POWERPC | MASK_NEW_MNEMONICS,
1676 POWERPC_7400_MASK = POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_ALTIVEC
1679 /* Some OSs don't support saving the high part of 64-bit registers on context
1680 switch. Other OSs don't support saving Altivec registers. On those OSs, we
1681 don't touch the MASK_POWERPC64 or MASK_ALTIVEC settings; if the user wants
1682 either, the user must explicitly specify them and we won't interfere with
1683 the user's specification. */
1685 enum {
1686 POWER_MASKS = MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING,
1687 POWERPC_MASKS = (POWERPC_BASE_MASK | MASK_PPC_GPOPT | MASK_STRICT_ALIGN
1688 | MASK_PPC_GFXOPT | MASK_POWERPC64 | MASK_ALTIVEC
1689 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_MULHW
1690 | MASK_DLMZB | MASK_CMPB | MASK_MFPGPR | MASK_DFP
1691 | MASK_POPCNTD | MASK_VSX | MASK_ISEL | MASK_NO_UPDATE
1692 | MASK_RECIP_PRECISION)
1695 /* Masks for instructions set at various powerpc ISAs. */
1696 enum {
1697 ISA_2_1_MASKS = MASK_MFCRF,
1698 ISA_2_2_MASKS = (ISA_2_1_MASKS | MASK_POPCNTB),
1699 ISA_2_4_MASKS = (ISA_2_2_MASKS | MASK_FPRND),
1701 /* For ISA 2.05, do not add MFPGPR, since it isn't in ISA 2.06, and don't add
1702 ALTIVEC, since in general it isn't a win on power6. In ISA 2.04, fsel,
1703 fre, fsqrt, etc. were no longer documented as optional. Group masks by
1704 server and embedded. */
1705 ISA_2_5_MASKS_EMBEDDED = (ISA_2_2_MASKS | MASK_CMPB | MASK_RECIP_PRECISION
1706 | MASK_PPC_GFXOPT | MASK_PPC_GPOPT),
1707 ISA_2_5_MASKS_SERVER = (ISA_2_5_MASKS_EMBEDDED | MASK_DFP),
1709 /* For ISA 2.06, don't add ISEL, since in general it isn't a win, but
1710 altivec is a win so enable it. */
1711 ISA_2_6_MASKS_EMBEDDED = (ISA_2_5_MASKS_EMBEDDED | MASK_POPCNTD),
1712 ISA_2_6_MASKS_SERVER = (ISA_2_5_MASKS_SERVER | MASK_POPCNTD | MASK_ALTIVEC
1713 | MASK_VSX)
1716 /* This table occasionally claims that a processor does not support a
1717 particular feature even though it does, but the feature is slower than the
1718 alternative. Thus, it shouldn't be relied on as a complete description of
1719 the processor's support.
1721 Please keep this list in order, and don't forget to update the documentation
1722 in invoke.texi when adding a new processor or flag. */
1724 struct rs6000_ptt
1726 const char *const name; /* Canonical processor name. */
1727 const enum processor_type processor; /* Processor type enum value. */
1728 const int target_enable; /* Target flags to enable. */
1731 static struct rs6000_ptt const processor_target_table[] =
1733 {"401", PROCESSOR_PPC403, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
1734 {"403", PROCESSOR_PPC403,
1735 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_STRICT_ALIGN},
1736 {"405", PROCESSOR_PPC405,
1737 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
1738 {"405fp", PROCESSOR_PPC405,
1739 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
1740 {"440", PROCESSOR_PPC440,
1741 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
1742 {"440fp", PROCESSOR_PPC440,
1743 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
1744 {"464", PROCESSOR_PPC440,
1745 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
1746 {"464fp", PROCESSOR_PPC440,
1747 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
1748 {"476", PROCESSOR_PPC476,
1749 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_PPC_GFXOPT | MASK_MFCRF
1750 | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_MULHW | MASK_DLMZB},
1751 {"476fp", PROCESSOR_PPC476,
1752 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_MFCRF | MASK_POPCNTB
1753 | MASK_FPRND | MASK_CMPB | MASK_MULHW | MASK_DLMZB},
1754 {"505", PROCESSOR_MPCCORE, POWERPC_BASE_MASK},
1755 {"601", PROCESSOR_PPC601,
1756 MASK_POWER | POWERPC_BASE_MASK | MASK_MULTIPLE | MASK_STRING},
1757 {"602", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1758 {"603", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1759 {"603e", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1760 {"604", PROCESSOR_PPC604, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1761 {"604e", PROCESSOR_PPC604e, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1762 {"620", PROCESSOR_PPC620,
1763 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
1764 {"630", PROCESSOR_PPC630,
1765 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
1766 {"740", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1767 {"7400", PROCESSOR_PPC7400, POWERPC_7400_MASK},
1768 {"7450", PROCESSOR_PPC7450, POWERPC_7400_MASK},
1769 {"750", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1770 {"801", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
1771 {"821", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
1772 {"823", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
1773 {"8540", PROCESSOR_PPC8540, POWERPC_BASE_MASK | MASK_STRICT_ALIGN
1774 | MASK_ISEL},
1775 /* 8548 has a dummy entry for now. */
1776 {"8548", PROCESSOR_PPC8540, POWERPC_BASE_MASK | MASK_STRICT_ALIGN
1777 | MASK_ISEL},
1778 {"a2", PROCESSOR_PPCA2,
1779 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64 | MASK_POPCNTB
1780 | MASK_CMPB | MASK_NO_UPDATE },
1781 {"e300c2", PROCESSOR_PPCE300C2, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
1782 {"e300c3", PROCESSOR_PPCE300C3, POWERPC_BASE_MASK},
1783 {"e500mc", PROCESSOR_PPCE500MC, POWERPC_BASE_MASK | MASK_PPC_GFXOPT
1784 | MASK_ISEL},
1785 {"e500mc64", PROCESSOR_PPCE500MC64, POWERPC_BASE_MASK | MASK_POWERPC64
1786 | MASK_PPC_GFXOPT | MASK_ISEL},
1787 {"860", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
1788 {"970", PROCESSOR_POWER4,
1789 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
1790 {"cell", PROCESSOR_CELL,
1791 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
1792 {"common", PROCESSOR_COMMON, MASK_NEW_MNEMONICS},
1793 {"ec603e", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
1794 {"G3", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1795 {"G4", PROCESSOR_PPC7450, POWERPC_7400_MASK},
1796 {"G5", PROCESSOR_POWER4,
1797 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
1798 {"titan", PROCESSOR_TITAN,
1799 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
1800 {"power", PROCESSOR_POWER, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
1801 {"power2", PROCESSOR_POWER,
1802 MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING},
1803 {"power3", PROCESSOR_PPC630,
1804 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
1805 {"power4", PROCESSOR_POWER4,
1806 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
1807 | MASK_MFCRF},
1808 {"power5", PROCESSOR_POWER5,
1809 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
1810 | MASK_MFCRF | MASK_POPCNTB},
1811 {"power5+", PROCESSOR_POWER5,
1812 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
1813 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND},
1814 {"power6", PROCESSOR_POWER6,
1815 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
1816 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP
1817 | MASK_RECIP_PRECISION},
1818 {"power6x", 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_MFPGPR | MASK_RECIP_PRECISION},
1822 {"power7", PROCESSOR_POWER7, /* Don't add MASK_ISEL by default */
1823 POWERPC_7400_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_MFCRF
1824 | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP | MASK_POPCNTD
1825 | MASK_VSX | MASK_RECIP_PRECISION},
1826 {"powerpc", PROCESSOR_POWERPC, POWERPC_BASE_MASK},
1827 {"powerpc64", PROCESSOR_POWERPC64,
1828 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
1829 {"rios", PROCESSOR_RIOS1, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
1830 {"rios1", PROCESSOR_RIOS1, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
1831 {"rios2", PROCESSOR_RIOS2,
1832 MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING},
1833 {"rsc", PROCESSOR_PPC601, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
1834 {"rsc1", PROCESSOR_PPC601, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
1835 {"rs64", PROCESSOR_RS64A,
1836 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64}
1839 /* Look up a processor name for -mcpu=xxx and -mtune=xxx. Return -1 if the
1840 name is invalid. */
1842 static int
1843 rs6000_cpu_name_lookup (const char *name)
1845 size_t i;
1847 if (name != NULL)
1849 for (i = 0; i < ARRAY_SIZE (processor_target_table); i++)
1850 if (! strcmp (name, processor_target_table[i].name))
1851 return (int)i;
1854 return -1;
1858 /* Return number of consecutive hard regs needed starting at reg REGNO
1859 to hold something of mode MODE.
1860 This is ordinarily the length in words of a value of mode MODE
1861 but can be less for certain modes in special long registers.
1863 For the SPE, GPRs are 64 bits but only 32 bits are visible in
1864 scalar instructions. The upper 32 bits are only available to the
1865 SIMD instructions.
1867 POWER and PowerPC GPRs hold 32 bits worth;
1868 PowerPC64 GPRs and FPRs point register holds 64 bits worth. */
1870 static int
1871 rs6000_hard_regno_nregs_internal (int regno, enum machine_mode mode)
1873 unsigned HOST_WIDE_INT reg_size;
1875 if (FP_REGNO_P (regno))
1876 reg_size = (VECTOR_MEM_VSX_P (mode)
1877 ? UNITS_PER_VSX_WORD
1878 : UNITS_PER_FP_WORD);
1880 else if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode))
1881 reg_size = UNITS_PER_SPE_WORD;
1883 else if (ALTIVEC_REGNO_P (regno))
1884 reg_size = UNITS_PER_ALTIVEC_WORD;
1886 /* The value returned for SCmode in the E500 double case is 2 for
1887 ABI compatibility; storing an SCmode value in a single register
1888 would require function_arg and rs6000_spe_function_arg to handle
1889 SCmode so as to pass the value correctly in a pair of
1890 registers. */
1891 else if (TARGET_E500_DOUBLE && FLOAT_MODE_P (mode) && mode != SCmode
1892 && !DECIMAL_FLOAT_MODE_P (mode))
1893 reg_size = UNITS_PER_FP_WORD;
1895 else
1896 reg_size = UNITS_PER_WORD;
1898 return (GET_MODE_SIZE (mode) + reg_size - 1) / reg_size;
1901 /* Value is 1 if hard register REGNO can hold a value of machine-mode
1902 MODE. */
1903 static int
1904 rs6000_hard_regno_mode_ok (int regno, enum machine_mode mode)
1906 int last_regno = regno + rs6000_hard_regno_nregs[mode][regno] - 1;
1908 /* VSX registers that overlap the FPR registers are larger than for non-VSX
1909 implementations. Don't allow an item to be split between a FP register
1910 and an Altivec register. */
1911 if (VECTOR_MEM_VSX_P (mode))
1913 if (FP_REGNO_P (regno))
1914 return FP_REGNO_P (last_regno);
1916 if (ALTIVEC_REGNO_P (regno))
1917 return ALTIVEC_REGNO_P (last_regno);
1920 /* The GPRs can hold any mode, but values bigger than one register
1921 cannot go past R31. */
1922 if (INT_REGNO_P (regno))
1923 return INT_REGNO_P (last_regno);
1925 /* The float registers (except for VSX vector modes) can only hold floating
1926 modes and DImode. This excludes the 32-bit decimal float mode for
1927 now. */
1928 if (FP_REGNO_P (regno))
1930 if (SCALAR_FLOAT_MODE_P (mode)
1931 && (mode != TDmode || (regno % 2) == 0)
1932 && FP_REGNO_P (last_regno))
1933 return 1;
1935 if (GET_MODE_CLASS (mode) == MODE_INT
1936 && GET_MODE_SIZE (mode) == UNITS_PER_FP_WORD)
1937 return 1;
1939 if (PAIRED_SIMD_REGNO_P (regno) && TARGET_PAIRED_FLOAT
1940 && PAIRED_VECTOR_MODE (mode))
1941 return 1;
1943 return 0;
1946 /* The CR register can only hold CC modes. */
1947 if (CR_REGNO_P (regno))
1948 return GET_MODE_CLASS (mode) == MODE_CC;
1950 if (CA_REGNO_P (regno))
1951 return mode == BImode;
1953 /* AltiVec only in AldyVec registers. */
1954 if (ALTIVEC_REGNO_P (regno))
1955 return VECTOR_MEM_ALTIVEC_OR_VSX_P (mode);
1957 /* ...but GPRs can hold SIMD data on the SPE in one register. */
1958 if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode))
1959 return 1;
1961 /* We cannot put TImode anywhere except general register and it must be able
1962 to fit within the register set. In the future, allow TImode in the
1963 Altivec or VSX registers. */
1965 return GET_MODE_SIZE (mode) <= UNITS_PER_WORD;
1968 /* Print interesting facts about registers. */
1969 static void
1970 rs6000_debug_reg_print (int first_regno, int last_regno, const char *reg_name)
1972 int r, m;
1974 for (r = first_regno; r <= last_regno; ++r)
1976 const char *comma = "";
1977 int len;
1979 if (first_regno == last_regno)
1980 fprintf (stderr, "%s:\t", reg_name);
1981 else
1982 fprintf (stderr, "%s%d:\t", reg_name, r - first_regno);
1984 len = 8;
1985 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1986 if (rs6000_hard_regno_mode_ok_p[m][r] && rs6000_hard_regno_nregs[m][r])
1988 if (len > 70)
1990 fprintf (stderr, ",\n\t");
1991 len = 8;
1992 comma = "";
1995 if (rs6000_hard_regno_nregs[m][r] > 1)
1996 len += fprintf (stderr, "%s%s/%d", comma, GET_MODE_NAME (m),
1997 rs6000_hard_regno_nregs[m][r]);
1998 else
1999 len += fprintf (stderr, "%s%s", comma, GET_MODE_NAME (m));
2001 comma = ", ";
2004 if (call_used_regs[r])
2006 if (len > 70)
2008 fprintf (stderr, ",\n\t");
2009 len = 8;
2010 comma = "";
2013 len += fprintf (stderr, "%s%s", comma, "call-used");
2014 comma = ", ";
2017 if (fixed_regs[r])
2019 if (len > 70)
2021 fprintf (stderr, ",\n\t");
2022 len = 8;
2023 comma = "";
2026 len += fprintf (stderr, "%s%s", comma, "fixed");
2027 comma = ", ";
2030 if (len > 70)
2032 fprintf (stderr, ",\n\t");
2033 comma = "";
2036 fprintf (stderr, "%sregno = %d\n", comma, r);
2040 #define DEBUG_FMT_D "%-32s= %d\n"
2041 #define DEBUG_FMT_S "%-32s= %s\n"
2043 /* Print various interesting information with -mdebug=reg. */
2044 static void
2045 rs6000_debug_reg_global (void)
2047 static const char *const tf[2] = { "false", "true" };
2048 const char *nl = (const char *)0;
2049 int m;
2050 char costly_num[20];
2051 char nop_num[20];
2052 const char *costly_str;
2053 const char *nop_str;
2054 const char *trace_str;
2055 const char *abi_str;
2056 const char *cmodel_str;
2058 /* Map enum rs6000_vector to string. */
2059 static const char *rs6000_debug_vector_unit[] = {
2060 "none",
2061 "altivec",
2062 "vsx",
2063 "paired",
2064 "spe",
2065 "other"
2068 fprintf (stderr, "Register information: (last virtual reg = %d)\n",
2069 LAST_VIRTUAL_REGISTER);
2070 rs6000_debug_reg_print (0, 31, "gr");
2071 rs6000_debug_reg_print (32, 63, "fp");
2072 rs6000_debug_reg_print (FIRST_ALTIVEC_REGNO,
2073 LAST_ALTIVEC_REGNO,
2074 "vs");
2075 rs6000_debug_reg_print (LR_REGNO, LR_REGNO, "lr");
2076 rs6000_debug_reg_print (CTR_REGNO, CTR_REGNO, "ctr");
2077 rs6000_debug_reg_print (CR0_REGNO, CR7_REGNO, "cr");
2078 rs6000_debug_reg_print (MQ_REGNO, MQ_REGNO, "mq");
2079 rs6000_debug_reg_print (CA_REGNO, CA_REGNO, "ca");
2080 rs6000_debug_reg_print (VRSAVE_REGNO, VRSAVE_REGNO, "vrsave");
2081 rs6000_debug_reg_print (VSCR_REGNO, VSCR_REGNO, "vscr");
2082 rs6000_debug_reg_print (SPE_ACC_REGNO, SPE_ACC_REGNO, "spe_a");
2083 rs6000_debug_reg_print (SPEFSCR_REGNO, SPEFSCR_REGNO, "spe_f");
2085 fprintf (stderr,
2086 "\n"
2087 "d reg_class = %s\n"
2088 "f reg_class = %s\n"
2089 "v reg_class = %s\n"
2090 "wa reg_class = %s\n"
2091 "wd reg_class = %s\n"
2092 "wf reg_class = %s\n"
2093 "ws reg_class = %s\n\n",
2094 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_d]],
2095 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_f]],
2096 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_v]],
2097 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wa]],
2098 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wd]],
2099 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wf]],
2100 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_ws]]);
2102 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2103 if (rs6000_vector_unit[m] || rs6000_vector_mem[m])
2105 nl = "\n";
2106 fprintf (stderr, "Vector mode: %-5s arithmetic: %-8s move: %-8s\n",
2107 GET_MODE_NAME (m),
2108 rs6000_debug_vector_unit[ rs6000_vector_unit[m] ],
2109 rs6000_debug_vector_unit[ rs6000_vector_mem[m] ]);
2112 if (nl)
2113 fputs (nl, stderr);
2115 if (rs6000_recip_control)
2117 fprintf (stderr, "\nReciprocal mask = 0x%x\n", rs6000_recip_control);
2119 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2120 if (rs6000_recip_bits[m])
2122 fprintf (stderr,
2123 "Reciprocal estimate mode: %-5s divide: %s rsqrt: %s\n",
2124 GET_MODE_NAME (m),
2125 (RS6000_RECIP_AUTO_RE_P (m)
2126 ? "auto"
2127 : (RS6000_RECIP_HAVE_RE_P (m) ? "have" : "none")),
2128 (RS6000_RECIP_AUTO_RSQRTE_P (m)
2129 ? "auto"
2130 : (RS6000_RECIP_HAVE_RSQRTE_P (m) ? "have" : "none")));
2133 fputs ("\n", stderr);
2136 if (rs6000_cpu_index >= 0)
2137 fprintf (stderr, DEBUG_FMT_S, "cpu",
2138 processor_target_table[rs6000_cpu_index].name);
2140 if (rs6000_tune_index >= 0)
2141 fprintf (stderr, DEBUG_FMT_S, "tune",
2142 processor_target_table[rs6000_tune_index].name);
2144 switch (rs6000_sched_costly_dep)
2146 case max_dep_latency:
2147 costly_str = "max_dep_latency";
2148 break;
2150 case no_dep_costly:
2151 costly_str = "no_dep_costly";
2152 break;
2154 case all_deps_costly:
2155 costly_str = "all_deps_costly";
2156 break;
2158 case true_store_to_load_dep_costly:
2159 costly_str = "true_store_to_load_dep_costly";
2160 break;
2162 case store_to_load_dep_costly:
2163 costly_str = "store_to_load_dep_costly";
2164 break;
2166 default:
2167 costly_str = costly_num;
2168 sprintf (costly_num, "%d", (int)rs6000_sched_costly_dep);
2169 break;
2172 fprintf (stderr, DEBUG_FMT_S, "sched_costly_dep", costly_str);
2174 switch (rs6000_sched_insert_nops)
2176 case sched_finish_regroup_exact:
2177 nop_str = "sched_finish_regroup_exact";
2178 break;
2180 case sched_finish_pad_groups:
2181 nop_str = "sched_finish_pad_groups";
2182 break;
2184 case sched_finish_none:
2185 nop_str = "sched_finish_none";
2186 break;
2188 default:
2189 nop_str = nop_num;
2190 sprintf (nop_num, "%d", (int)rs6000_sched_insert_nops);
2191 break;
2194 fprintf (stderr, DEBUG_FMT_S, "sched_insert_nops", nop_str);
2196 switch (rs6000_sdata)
2198 default:
2199 case SDATA_NONE:
2200 break;
2202 case SDATA_DATA:
2203 fprintf (stderr, DEBUG_FMT_S, "sdata", "data");
2204 break;
2206 case SDATA_SYSV:
2207 fprintf (stderr, DEBUG_FMT_S, "sdata", "sysv");
2208 break;
2210 case SDATA_EABI:
2211 fprintf (stderr, DEBUG_FMT_S, "sdata", "eabi");
2212 break;
2216 switch (rs6000_traceback)
2218 case traceback_default: trace_str = "default"; break;
2219 case traceback_none: trace_str = "none"; break;
2220 case traceback_part: trace_str = "part"; break;
2221 case traceback_full: trace_str = "full"; break;
2222 default: trace_str = "unknown"; break;
2225 fprintf (stderr, DEBUG_FMT_S, "traceback", trace_str);
2227 switch (rs6000_current_cmodel)
2229 case CMODEL_SMALL: cmodel_str = "small"; break;
2230 case CMODEL_MEDIUM: cmodel_str = "medium"; break;
2231 case CMODEL_LARGE: cmodel_str = "large"; break;
2232 default: cmodel_str = "unknown"; break;
2235 fprintf (stderr, DEBUG_FMT_S, "cmodel", cmodel_str);
2237 switch (rs6000_current_abi)
2239 case ABI_NONE: abi_str = "none"; break;
2240 case ABI_AIX: abi_str = "aix"; break;
2241 case ABI_V4: abi_str = "V4"; break;
2242 case ABI_DARWIN: abi_str = "darwin"; break;
2243 default: abi_str = "unknown"; break;
2246 fprintf (stderr, DEBUG_FMT_S, "abi", abi_str);
2248 if (rs6000_altivec_abi)
2249 fprintf (stderr, DEBUG_FMT_S, "altivec_abi", "true");
2251 if (rs6000_spe_abi)
2252 fprintf (stderr, DEBUG_FMT_S, "spe_abi", "true");
2254 if (rs6000_darwin64_abi)
2255 fprintf (stderr, DEBUG_FMT_S, "darwin64_abi", "true");
2257 if (rs6000_float_gprs)
2258 fprintf (stderr, DEBUG_FMT_S, "float_gprs", "true");
2260 fprintf (stderr, DEBUG_FMT_S, "always_hint", tf[!!rs6000_always_hint]);
2261 fprintf (stderr, DEBUG_FMT_S, "align_branch",
2262 tf[!!rs6000_align_branch_targets]);
2263 fprintf (stderr, DEBUG_FMT_D, "tls_size", rs6000_tls_size);
2264 fprintf (stderr, DEBUG_FMT_D, "long_double_size",
2265 rs6000_long_double_type_size);
2266 fprintf (stderr, DEBUG_FMT_D, "sched_restricted_insns_priority",
2267 (int)rs6000_sched_restricted_insns_priority);
2270 /* Initialize the various global tables that are based on register size. */
2271 static void
2272 rs6000_init_hard_regno_mode_ok (bool global_init_p)
2274 int r, m, c;
2275 int align64;
2276 int align32;
2278 /* Precalculate REGNO_REG_CLASS. */
2279 rs6000_regno_regclass[0] = GENERAL_REGS;
2280 for (r = 1; r < 32; ++r)
2281 rs6000_regno_regclass[r] = BASE_REGS;
2283 for (r = 32; r < 64; ++r)
2284 rs6000_regno_regclass[r] = FLOAT_REGS;
2286 for (r = 64; r < FIRST_PSEUDO_REGISTER; ++r)
2287 rs6000_regno_regclass[r] = NO_REGS;
2289 for (r = FIRST_ALTIVEC_REGNO; r <= LAST_ALTIVEC_REGNO; ++r)
2290 rs6000_regno_regclass[r] = ALTIVEC_REGS;
2292 rs6000_regno_regclass[CR0_REGNO] = CR0_REGS;
2293 for (r = CR1_REGNO; r <= CR7_REGNO; ++r)
2294 rs6000_regno_regclass[r] = CR_REGS;
2296 rs6000_regno_regclass[MQ_REGNO] = MQ_REGS;
2297 rs6000_regno_regclass[LR_REGNO] = LINK_REGS;
2298 rs6000_regno_regclass[CTR_REGNO] = CTR_REGS;
2299 rs6000_regno_regclass[CA_REGNO] = CA_REGS;
2300 rs6000_regno_regclass[VRSAVE_REGNO] = VRSAVE_REGS;
2301 rs6000_regno_regclass[VSCR_REGNO] = VRSAVE_REGS;
2302 rs6000_regno_regclass[SPE_ACC_REGNO] = SPE_ACC_REGS;
2303 rs6000_regno_regclass[SPEFSCR_REGNO] = SPEFSCR_REGS;
2304 rs6000_regno_regclass[ARG_POINTER_REGNUM] = BASE_REGS;
2305 rs6000_regno_regclass[FRAME_POINTER_REGNUM] = BASE_REGS;
2307 /* Precalculate vector information, this must be set up before the
2308 rs6000_hard_regno_nregs_internal below. */
2309 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2311 rs6000_vector_unit[m] = rs6000_vector_mem[m] = VECTOR_NONE;
2312 rs6000_vector_reload[m][0] = CODE_FOR_nothing;
2313 rs6000_vector_reload[m][1] = CODE_FOR_nothing;
2316 for (c = 0; c < (int)(int)RS6000_CONSTRAINT_MAX; c++)
2317 rs6000_constraints[c] = NO_REGS;
2319 /* The VSX hardware allows native alignment for vectors, but control whether the compiler
2320 believes it can use native alignment or still uses 128-bit alignment. */
2321 if (TARGET_VSX && !TARGET_VSX_ALIGN_128)
2323 align64 = 64;
2324 align32 = 32;
2326 else
2328 align64 = 128;
2329 align32 = 128;
2332 /* V2DF mode, VSX only. */
2333 if (TARGET_VSX)
2335 rs6000_vector_unit[V2DFmode] = VECTOR_VSX;
2336 rs6000_vector_mem[V2DFmode] = VECTOR_VSX;
2337 rs6000_vector_align[V2DFmode] = align64;
2340 /* V4SF mode, either VSX or Altivec. */
2341 if (TARGET_VSX)
2343 rs6000_vector_unit[V4SFmode] = VECTOR_VSX;
2344 rs6000_vector_mem[V4SFmode] = VECTOR_VSX;
2345 rs6000_vector_align[V4SFmode] = align32;
2347 else if (TARGET_ALTIVEC)
2349 rs6000_vector_unit[V4SFmode] = VECTOR_ALTIVEC;
2350 rs6000_vector_mem[V4SFmode] = VECTOR_ALTIVEC;
2351 rs6000_vector_align[V4SFmode] = align32;
2354 /* V16QImode, V8HImode, V4SImode are Altivec only, but possibly do VSX loads
2355 and stores. */
2356 if (TARGET_ALTIVEC)
2358 rs6000_vector_unit[V4SImode] = VECTOR_ALTIVEC;
2359 rs6000_vector_unit[V8HImode] = VECTOR_ALTIVEC;
2360 rs6000_vector_unit[V16QImode] = VECTOR_ALTIVEC;
2361 rs6000_vector_align[V4SImode] = align32;
2362 rs6000_vector_align[V8HImode] = align32;
2363 rs6000_vector_align[V16QImode] = align32;
2365 if (TARGET_VSX)
2367 rs6000_vector_mem[V4SImode] = VECTOR_VSX;
2368 rs6000_vector_mem[V8HImode] = VECTOR_VSX;
2369 rs6000_vector_mem[V16QImode] = VECTOR_VSX;
2371 else
2373 rs6000_vector_mem[V4SImode] = VECTOR_ALTIVEC;
2374 rs6000_vector_mem[V8HImode] = VECTOR_ALTIVEC;
2375 rs6000_vector_mem[V16QImode] = VECTOR_ALTIVEC;
2379 /* V2DImode, only allow under VSX, which can do V2DI insert/splat/extract.
2380 Altivec doesn't have 64-bit support. */
2381 if (TARGET_VSX)
2383 rs6000_vector_mem[V2DImode] = VECTOR_VSX;
2384 rs6000_vector_unit[V2DImode] = VECTOR_NONE;
2385 rs6000_vector_align[V2DImode] = align64;
2388 /* DFmode, see if we want to use the VSX unit. */
2389 if (TARGET_VSX && TARGET_VSX_SCALAR_DOUBLE)
2391 rs6000_vector_unit[DFmode] = VECTOR_VSX;
2392 rs6000_vector_mem[DFmode]
2393 = (TARGET_VSX_SCALAR_MEMORY ? VECTOR_VSX : VECTOR_NONE);
2394 rs6000_vector_align[DFmode] = align64;
2397 /* TODO add SPE and paired floating point vector support. */
2399 /* Register class constaints for the constraints that depend on compile
2400 switches. */
2401 if (TARGET_HARD_FLOAT && TARGET_FPRS)
2402 rs6000_constraints[RS6000_CONSTRAINT_f] = FLOAT_REGS;
2404 if (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
2405 rs6000_constraints[RS6000_CONSTRAINT_d] = FLOAT_REGS;
2407 if (TARGET_VSX)
2409 /* At present, we just use VSX_REGS, but we have different constraints
2410 based on the use, in case we want to fine tune the default register
2411 class used. wa = any VSX register, wf = register class to use for
2412 V4SF, wd = register class to use for V2DF, and ws = register classs to
2413 use for DF scalars. */
2414 rs6000_constraints[RS6000_CONSTRAINT_wa] = VSX_REGS;
2415 rs6000_constraints[RS6000_CONSTRAINT_wf] = VSX_REGS;
2416 rs6000_constraints[RS6000_CONSTRAINT_wd] = VSX_REGS;
2417 rs6000_constraints[RS6000_CONSTRAINT_ws] = (TARGET_VSX_SCALAR_MEMORY
2418 ? VSX_REGS
2419 : FLOAT_REGS);
2422 if (TARGET_ALTIVEC)
2423 rs6000_constraints[RS6000_CONSTRAINT_v] = ALTIVEC_REGS;
2425 /* Set up the reload helper functions. */
2426 if (TARGET_VSX || TARGET_ALTIVEC)
2428 if (TARGET_64BIT)
2430 rs6000_vector_reload[V16QImode][0] = CODE_FOR_reload_v16qi_di_store;
2431 rs6000_vector_reload[V16QImode][1] = CODE_FOR_reload_v16qi_di_load;
2432 rs6000_vector_reload[V8HImode][0] = CODE_FOR_reload_v8hi_di_store;
2433 rs6000_vector_reload[V8HImode][1] = CODE_FOR_reload_v8hi_di_load;
2434 rs6000_vector_reload[V4SImode][0] = CODE_FOR_reload_v4si_di_store;
2435 rs6000_vector_reload[V4SImode][1] = CODE_FOR_reload_v4si_di_load;
2436 rs6000_vector_reload[V2DImode][0] = CODE_FOR_reload_v2di_di_store;
2437 rs6000_vector_reload[V2DImode][1] = CODE_FOR_reload_v2di_di_load;
2438 rs6000_vector_reload[V4SFmode][0] = CODE_FOR_reload_v4sf_di_store;
2439 rs6000_vector_reload[V4SFmode][1] = CODE_FOR_reload_v4sf_di_load;
2440 rs6000_vector_reload[V2DFmode][0] = CODE_FOR_reload_v2df_di_store;
2441 rs6000_vector_reload[V2DFmode][1] = CODE_FOR_reload_v2df_di_load;
2443 else
2445 rs6000_vector_reload[V16QImode][0] = CODE_FOR_reload_v16qi_si_store;
2446 rs6000_vector_reload[V16QImode][1] = CODE_FOR_reload_v16qi_si_load;
2447 rs6000_vector_reload[V8HImode][0] = CODE_FOR_reload_v8hi_si_store;
2448 rs6000_vector_reload[V8HImode][1] = CODE_FOR_reload_v8hi_si_load;
2449 rs6000_vector_reload[V4SImode][0] = CODE_FOR_reload_v4si_si_store;
2450 rs6000_vector_reload[V4SImode][1] = CODE_FOR_reload_v4si_si_load;
2451 rs6000_vector_reload[V2DImode][0] = CODE_FOR_reload_v2di_si_store;
2452 rs6000_vector_reload[V2DImode][1] = CODE_FOR_reload_v2di_si_load;
2453 rs6000_vector_reload[V4SFmode][0] = CODE_FOR_reload_v4sf_si_store;
2454 rs6000_vector_reload[V4SFmode][1] = CODE_FOR_reload_v4sf_si_load;
2455 rs6000_vector_reload[V2DFmode][0] = CODE_FOR_reload_v2df_si_store;
2456 rs6000_vector_reload[V2DFmode][1] = CODE_FOR_reload_v2df_si_load;
2460 /* Precalculate HARD_REGNO_NREGS. */
2461 for (r = 0; r < FIRST_PSEUDO_REGISTER; ++r)
2462 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2463 rs6000_hard_regno_nregs[m][r]
2464 = rs6000_hard_regno_nregs_internal (r, (enum machine_mode)m);
2466 /* Precalculate HARD_REGNO_MODE_OK. */
2467 for (r = 0; r < FIRST_PSEUDO_REGISTER; ++r)
2468 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2469 if (rs6000_hard_regno_mode_ok (r, (enum machine_mode)m))
2470 rs6000_hard_regno_mode_ok_p[m][r] = true;
2472 /* Precalculate CLASS_MAX_NREGS sizes. */
2473 for (c = 0; c < LIM_REG_CLASSES; ++c)
2475 int reg_size;
2477 if (TARGET_VSX && VSX_REG_CLASS_P (c))
2478 reg_size = UNITS_PER_VSX_WORD;
2480 else if (c == ALTIVEC_REGS)
2481 reg_size = UNITS_PER_ALTIVEC_WORD;
2483 else if (c == FLOAT_REGS)
2484 reg_size = UNITS_PER_FP_WORD;
2486 else
2487 reg_size = UNITS_PER_WORD;
2489 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2490 rs6000_class_max_nregs[m][c]
2491 = (GET_MODE_SIZE (m) + reg_size - 1) / reg_size;
2494 if (TARGET_E500_DOUBLE)
2495 rs6000_class_max_nregs[DFmode][GENERAL_REGS] = 1;
2497 /* Calculate which modes to automatically generate code to use a the
2498 reciprocal divide and square root instructions. In the future, possibly
2499 automatically generate the instructions even if the user did not specify
2500 -mrecip. The older machines double precision reciprocal sqrt estimate is
2501 not accurate enough. */
2502 memset (rs6000_recip_bits, 0, sizeof (rs6000_recip_bits));
2503 if (TARGET_FRES)
2504 rs6000_recip_bits[SFmode] = RS6000_RECIP_MASK_HAVE_RE;
2505 if (TARGET_FRE)
2506 rs6000_recip_bits[DFmode] = RS6000_RECIP_MASK_HAVE_RE;
2507 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode))
2508 rs6000_recip_bits[V4SFmode] = RS6000_RECIP_MASK_HAVE_RE;
2509 if (VECTOR_UNIT_VSX_P (V2DFmode))
2510 rs6000_recip_bits[V2DFmode] = RS6000_RECIP_MASK_HAVE_RE;
2512 if (TARGET_FRSQRTES)
2513 rs6000_recip_bits[SFmode] |= RS6000_RECIP_MASK_HAVE_RSQRTE;
2514 if (TARGET_FRSQRTE)
2515 rs6000_recip_bits[DFmode] |= RS6000_RECIP_MASK_HAVE_RSQRTE;
2516 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode))
2517 rs6000_recip_bits[V4SFmode] |= RS6000_RECIP_MASK_HAVE_RSQRTE;
2518 if (VECTOR_UNIT_VSX_P (V2DFmode))
2519 rs6000_recip_bits[V2DFmode] |= RS6000_RECIP_MASK_HAVE_RSQRTE;
2521 if (rs6000_recip_control)
2523 if (!flag_finite_math_only)
2524 warning (0, "-mrecip requires -ffinite-math or -ffast-math");
2525 if (flag_trapping_math)
2526 warning (0, "-mrecip requires -fno-trapping-math or -ffast-math");
2527 if (!flag_reciprocal_math)
2528 warning (0, "-mrecip requires -freciprocal-math or -ffast-math");
2529 if (flag_finite_math_only && !flag_trapping_math && flag_reciprocal_math)
2531 if (RS6000_RECIP_HAVE_RE_P (SFmode)
2532 && (rs6000_recip_control & RECIP_SF_DIV) != 0)
2533 rs6000_recip_bits[SFmode] |= RS6000_RECIP_MASK_AUTO_RE;
2535 if (RS6000_RECIP_HAVE_RE_P (DFmode)
2536 && (rs6000_recip_control & RECIP_DF_DIV) != 0)
2537 rs6000_recip_bits[DFmode] |= RS6000_RECIP_MASK_AUTO_RE;
2539 if (RS6000_RECIP_HAVE_RE_P (V4SFmode)
2540 && (rs6000_recip_control & RECIP_V4SF_DIV) != 0)
2541 rs6000_recip_bits[V4SFmode] |= RS6000_RECIP_MASK_AUTO_RE;
2543 if (RS6000_RECIP_HAVE_RE_P (V2DFmode)
2544 && (rs6000_recip_control & RECIP_V2DF_DIV) != 0)
2545 rs6000_recip_bits[V2DFmode] |= RS6000_RECIP_MASK_AUTO_RE;
2547 if (RS6000_RECIP_HAVE_RSQRTE_P (SFmode)
2548 && (rs6000_recip_control & RECIP_SF_RSQRT) != 0)
2549 rs6000_recip_bits[SFmode] |= RS6000_RECIP_MASK_AUTO_RSQRTE;
2551 if (RS6000_RECIP_HAVE_RSQRTE_P (DFmode)
2552 && (rs6000_recip_control & RECIP_DF_RSQRT) != 0)
2553 rs6000_recip_bits[DFmode] |= RS6000_RECIP_MASK_AUTO_RSQRTE;
2555 if (RS6000_RECIP_HAVE_RSQRTE_P (V4SFmode)
2556 && (rs6000_recip_control & RECIP_V4SF_RSQRT) != 0)
2557 rs6000_recip_bits[V4SFmode] |= RS6000_RECIP_MASK_AUTO_RSQRTE;
2559 if (RS6000_RECIP_HAVE_RSQRTE_P (V2DFmode)
2560 && (rs6000_recip_control & RECIP_V2DF_RSQRT) != 0)
2561 rs6000_recip_bits[V2DFmode] |= RS6000_RECIP_MASK_AUTO_RSQRTE;
2565 if (global_init_p || TARGET_DEBUG_TARGET)
2567 if (TARGET_DEBUG_REG)
2568 rs6000_debug_reg_global ();
2570 if (TARGET_DEBUG_COST || TARGET_DEBUG_REG)
2571 fprintf (stderr,
2572 "SImode variable mult cost = %d\n"
2573 "SImode constant mult cost = %d\n"
2574 "SImode short constant mult cost = %d\n"
2575 "DImode multipliciation cost = %d\n"
2576 "SImode division cost = %d\n"
2577 "DImode division cost = %d\n"
2578 "Simple fp operation cost = %d\n"
2579 "DFmode multiplication cost = %d\n"
2580 "SFmode division cost = %d\n"
2581 "DFmode division cost = %d\n"
2582 "cache line size = %d\n"
2583 "l1 cache size = %d\n"
2584 "l2 cache size = %d\n"
2585 "simultaneous prefetches = %d\n"
2586 "\n",
2587 rs6000_cost->mulsi,
2588 rs6000_cost->mulsi_const,
2589 rs6000_cost->mulsi_const9,
2590 rs6000_cost->muldi,
2591 rs6000_cost->divsi,
2592 rs6000_cost->divdi,
2593 rs6000_cost->fp,
2594 rs6000_cost->dmul,
2595 rs6000_cost->sdiv,
2596 rs6000_cost->ddiv,
2597 rs6000_cost->cache_line_size,
2598 rs6000_cost->l1_cache_size,
2599 rs6000_cost->l2_cache_size,
2600 rs6000_cost->simultaneous_prefetches);
2604 #if TARGET_MACHO
2605 /* The Darwin version of SUBTARGET_OVERRIDE_OPTIONS. */
2607 static void
2608 darwin_rs6000_override_options (void)
2610 /* The Darwin ABI always includes AltiVec, can't be (validly) turned
2611 off. */
2612 rs6000_altivec_abi = 1;
2613 TARGET_ALTIVEC_VRSAVE = 1;
2615 if (DEFAULT_ABI == ABI_DARWIN
2616 && TARGET_64BIT)
2617 darwin_one_byte_bool = 1;
2619 if (TARGET_64BIT && ! TARGET_POWERPC64)
2621 target_flags |= MASK_POWERPC64;
2622 warning (0, "-m64 requires PowerPC64 architecture, enabling");
2624 if (flag_mkernel)
2626 rs6000_default_long_calls = 1;
2627 target_flags |= MASK_SOFT_FLOAT;
2630 /* Make -m64 imply -maltivec. Darwin's 64-bit ABI includes
2631 Altivec. */
2632 if (!flag_mkernel && !flag_apple_kext
2633 && TARGET_64BIT
2634 && ! (target_flags_explicit & MASK_ALTIVEC))
2635 target_flags |= MASK_ALTIVEC;
2637 /* Unless the user (not the configurer) has explicitly overridden
2638 it with -mcpu=G3 or -mno-altivec, then 10.5+ targets default to
2639 G4 unless targetting the kernel. */
2640 if (!flag_mkernel
2641 && !flag_apple_kext
2642 && strverscmp (darwin_macosx_version_min, "10.5") >= 0
2643 && ! (target_flags_explicit & MASK_ALTIVEC)
2644 && ! rs6000_select[1].string)
2646 target_flags |= MASK_ALTIVEC;
2649 #endif
2651 /* If not otherwise specified by a target, make 'long double' equivalent to
2652 'double'. */
2654 #ifndef RS6000_DEFAULT_LONG_DOUBLE_SIZE
2655 #define RS6000_DEFAULT_LONG_DOUBLE_SIZE 64
2656 #endif
2658 /* Override command line options. Mostly we process the processor type and
2659 sometimes adjust other TARGET_ options. */
2661 static bool
2662 rs6000_option_override_internal (bool global_init_p)
2664 bool ret = true;
2665 const char *default_cpu = OPTION_TARGET_CPU_DEFAULT;
2666 int set_masks;
2667 int cpu_index;
2668 int tune_index;
2669 struct cl_target_option *main_target_opt
2670 = ((global_init_p || target_option_default_node == NULL)
2671 ? NULL : TREE_TARGET_OPTION (target_option_default_node));
2673 /* Numerous experiment shows that IRA based loop pressure
2674 calculation works better for RTL loop invariant motion on targets
2675 with enough (>= 32) registers. It is an expensive optimization.
2676 So it is on only for peak performance. */
2677 if (optimize >= 3 && global_init_p)
2678 flag_ira_loop_pressure = 1;
2680 /* Set the pointer size. */
2681 if (TARGET_64BIT)
2683 rs6000_pmode = (int)DImode;
2684 rs6000_pointer_size = 64;
2686 else
2688 rs6000_pmode = (int)SImode;
2689 rs6000_pointer_size = 32;
2692 set_masks = POWER_MASKS | POWERPC_MASKS | MASK_SOFT_FLOAT;
2693 #ifdef OS_MISSING_POWERPC64
2694 if (OS_MISSING_POWERPC64)
2695 set_masks &= ~MASK_POWERPC64;
2696 #endif
2697 #ifdef OS_MISSING_ALTIVEC
2698 if (OS_MISSING_ALTIVEC)
2699 set_masks &= ~MASK_ALTIVEC;
2700 #endif
2702 /* Don't override by the processor default if given explicitly. */
2703 set_masks &= ~target_flags_explicit;
2705 /* Identify the processor type. */
2706 if (!default_cpu)
2708 if (TARGET_POWERPC64)
2709 default_cpu = "powerpc64";
2710 else if (TARGET_POWERPC)
2711 default_cpu = "powerpc";
2714 /* Process the -mcpu=<xxx> and -mtune=<xxx> argument. If the user changed
2715 the cpu in a target attribute or pragma, but did not specify a tuning
2716 option, use the cpu for the tuning option rather than the option specified
2717 with -mtune on the command line. */
2718 if (rs6000_cpu_index > 0)
2719 cpu_index = rs6000_cpu_index;
2720 else if (main_target_opt != NULL && main_target_opt->x_rs6000_cpu_index > 0)
2721 rs6000_cpu_index = cpu_index = main_target_opt->x_rs6000_cpu_index;
2722 else
2723 rs6000_cpu_index = cpu_index = rs6000_cpu_name_lookup (default_cpu);
2725 if (rs6000_tune_index > 0)
2726 tune_index = rs6000_tune_index;
2727 else
2728 rs6000_tune_index = tune_index = cpu_index;
2730 if (cpu_index >= 0)
2732 target_flags &= ~set_masks;
2733 target_flags |= (processor_target_table[cpu_index].target_enable
2734 & set_masks);
2737 rs6000_cpu = ((tune_index >= 0)
2738 ? processor_target_table[tune_index].processor
2739 : (TARGET_POWERPC64
2740 ? PROCESSOR_DEFAULT64
2741 : PROCESSOR_DEFAULT));
2743 if (rs6000_cpu == PROCESSOR_PPCE300C2 || rs6000_cpu == PROCESSOR_PPCE300C3
2744 || rs6000_cpu == PROCESSOR_PPCE500MC || rs6000_cpu == PROCESSOR_PPCE500MC64)
2746 if (TARGET_ALTIVEC)
2747 error ("AltiVec not supported in this target");
2748 if (TARGET_SPE)
2749 error ("SPE not supported in this target");
2752 /* Disable Cell microcode if we are optimizing for the Cell
2753 and not optimizing for size. */
2754 if (rs6000_gen_cell_microcode == -1)
2755 rs6000_gen_cell_microcode = !(rs6000_cpu == PROCESSOR_CELL
2756 && !optimize_size);
2758 /* If we are optimizing big endian systems for space and it's OK to
2759 use instructions that would be microcoded on the Cell, use the
2760 load/store multiple and string instructions. */
2761 if (BYTES_BIG_ENDIAN && optimize_size && rs6000_gen_cell_microcode)
2762 target_flags |= ~target_flags_explicit & (MASK_MULTIPLE | MASK_STRING);
2764 /* Don't allow -mmultiple or -mstring on little endian systems
2765 unless the cpu is a 750, because the hardware doesn't support the
2766 instructions used in little endian mode, and causes an alignment
2767 trap. The 750 does not cause an alignment trap (except when the
2768 target is unaligned). */
2770 if (!BYTES_BIG_ENDIAN && rs6000_cpu != PROCESSOR_PPC750)
2772 if (TARGET_MULTIPLE)
2774 target_flags &= ~MASK_MULTIPLE;
2775 if ((target_flags_explicit & MASK_MULTIPLE) != 0)
2776 warning (0, "-mmultiple is not supported on little endian systems");
2779 if (TARGET_STRING)
2781 target_flags &= ~MASK_STRING;
2782 if ((target_flags_explicit & MASK_STRING) != 0)
2783 warning (0, "-mstring is not supported on little endian systems");
2787 /* Add some warnings for VSX. */
2788 if (TARGET_VSX)
2790 const char *msg = NULL;
2791 if (!TARGET_HARD_FLOAT || !TARGET_FPRS
2792 || !TARGET_SINGLE_FLOAT || !TARGET_DOUBLE_FLOAT)
2794 if (target_flags_explicit & MASK_VSX)
2795 msg = N_("-mvsx requires hardware floating point");
2796 else
2797 target_flags &= ~ MASK_VSX;
2799 else if (TARGET_PAIRED_FLOAT)
2800 msg = N_("-mvsx and -mpaired are incompatible");
2801 /* The hardware will allow VSX and little endian, but until we make sure
2802 things like vector select, etc. work don't allow VSX on little endian
2803 systems at this point. */
2804 else if (!BYTES_BIG_ENDIAN)
2805 msg = N_("-mvsx used with little endian code");
2806 else if (TARGET_AVOID_XFORM > 0)
2807 msg = N_("-mvsx needs indexed addressing");
2808 else if (!TARGET_ALTIVEC && (target_flags_explicit & MASK_ALTIVEC))
2810 if (target_flags_explicit & MASK_VSX)
2811 msg = N_("-mvsx and -mno-altivec are incompatible");
2812 else
2813 msg = N_("-mno-altivec disables vsx");
2816 if (msg)
2818 warning (0, msg);
2819 target_flags &= ~ MASK_VSX;
2820 target_flags_explicit |= MASK_VSX;
2824 /* For the newer switches (vsx, dfp, etc.) set some of the older options,
2825 unless the user explicitly used the -mno-<option> to disable the code. */
2826 if (TARGET_VSX)
2827 target_flags |= (ISA_2_6_MASKS_SERVER & ~target_flags_explicit);
2828 else if (TARGET_POPCNTD)
2829 target_flags |= (ISA_2_6_MASKS_EMBEDDED & ~target_flags_explicit);
2830 else if (TARGET_DFP)
2831 target_flags |= (ISA_2_5_MASKS_SERVER & ~target_flags_explicit);
2832 else if (TARGET_CMPB)
2833 target_flags |= (ISA_2_5_MASKS_EMBEDDED & ~target_flags_explicit);
2834 else if (TARGET_FPRND)
2835 target_flags |= (ISA_2_4_MASKS & ~target_flags_explicit);
2836 else if (TARGET_POPCNTB)
2837 target_flags |= (ISA_2_2_MASKS & ~target_flags_explicit);
2838 else if (TARGET_ALTIVEC)
2839 target_flags |= (MASK_PPC_GFXOPT & ~target_flags_explicit);
2841 /* E500mc does "better" if we inline more aggressively. Respect the
2842 user's opinion, though. */
2843 if (rs6000_block_move_inline_limit == 0
2844 && (rs6000_cpu == PROCESSOR_PPCE500MC
2845 || rs6000_cpu == PROCESSOR_PPCE500MC64))
2846 rs6000_block_move_inline_limit = 128;
2848 /* store_one_arg depends on expand_block_move to handle at least the
2849 size of reg_parm_stack_space. */
2850 if (rs6000_block_move_inline_limit < (TARGET_POWERPC64 ? 64 : 32))
2851 rs6000_block_move_inline_limit = (TARGET_POWERPC64 ? 64 : 32);
2853 if (global_init_p)
2855 /* If the appropriate debug option is enabled, replace the target hooks
2856 with debug versions that call the real version and then prints
2857 debugging information. */
2858 if (TARGET_DEBUG_COST)
2860 targetm.rtx_costs = rs6000_debug_rtx_costs;
2861 targetm.address_cost = rs6000_debug_address_cost;
2862 targetm.sched.adjust_cost = rs6000_debug_adjust_cost;
2865 if (TARGET_DEBUG_ADDR)
2867 targetm.legitimate_address_p = rs6000_debug_legitimate_address_p;
2868 targetm.legitimize_address = rs6000_debug_legitimize_address;
2869 rs6000_secondary_reload_class_ptr
2870 = rs6000_debug_secondary_reload_class;
2871 rs6000_secondary_memory_needed_ptr
2872 = rs6000_debug_secondary_memory_needed;
2873 rs6000_cannot_change_mode_class_ptr
2874 = rs6000_debug_cannot_change_mode_class;
2875 rs6000_preferred_reload_class_ptr
2876 = rs6000_debug_preferred_reload_class;
2877 rs6000_legitimize_reload_address_ptr
2878 = rs6000_debug_legitimize_reload_address;
2879 rs6000_mode_dependent_address_ptr
2880 = rs6000_debug_mode_dependent_address;
2883 if (rs6000_veclibabi_name)
2885 if (strcmp (rs6000_veclibabi_name, "mass") == 0)
2886 rs6000_veclib_handler = rs6000_builtin_vectorized_libmass;
2887 else
2889 error ("unknown vectorization library ABI type (%s) for "
2890 "-mveclibabi= switch", rs6000_veclibabi_name);
2891 ret = false;
2896 if (!rs6000_explicit_options.long_double)
2898 if (main_target_opt != NULL
2899 && (main_target_opt->x_rs6000_long_double_type_size
2900 != RS6000_DEFAULT_LONG_DOUBLE_SIZE))
2901 error ("target attribute or pragma changes long double size");
2902 else
2903 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
2906 #ifndef POWERPC_LINUX
2907 if (!rs6000_explicit_options.ieee)
2908 rs6000_ieeequad = 1;
2909 #endif
2911 /* Disable VSX and Altivec silently if the user switched cpus to power7 in a
2912 target attribute or pragma which automatically enables both options,
2913 unless the altivec ABI was set. This is set by default for 64-bit, but
2914 not for 32-bit. */
2915 if (main_target_opt != NULL && !main_target_opt->x_rs6000_altivec_abi)
2916 target_flags &= ~((MASK_VSX | MASK_ALTIVEC) & ~target_flags_explicit);
2918 /* Enable Altivec ABI for AIX -maltivec. */
2919 if (TARGET_XCOFF && (TARGET_ALTIVEC || TARGET_VSX))
2921 if (main_target_opt != NULL && !main_target_opt->x_rs6000_altivec_abi)
2922 error ("target attribute or pragma changes AltiVec ABI");
2923 else
2924 rs6000_altivec_abi = 1;
2927 /* The AltiVec ABI is the default for PowerPC-64 GNU/Linux. For
2928 PowerPC-32 GNU/Linux, -maltivec implies the AltiVec ABI. It can
2929 be explicitly overridden in either case. */
2930 if (TARGET_ELF)
2932 if (!rs6000_explicit_options.altivec_abi
2933 && (TARGET_64BIT || TARGET_ALTIVEC || TARGET_VSX))
2935 if (main_target_opt != NULL &&
2936 !main_target_opt->x_rs6000_altivec_abi)
2937 error ("target attribute or pragma changes AltiVec ABI");
2938 else
2939 rs6000_altivec_abi = 1;
2942 /* Enable VRSAVE for AltiVec ABI, unless explicitly overridden. */
2943 if (!rs6000_explicit_options.vrsave)
2944 TARGET_ALTIVEC_VRSAVE = rs6000_altivec_abi;
2947 /* Set the Darwin64 ABI as default for 64-bit Darwin.
2948 So far, the only darwin64 targets are also MACH-O. */
2949 if (TARGET_MACHO
2950 && DEFAULT_ABI == ABI_DARWIN
2951 && TARGET_64BIT)
2953 if (main_target_opt != NULL && !main_target_opt->x_rs6000_darwin64_abi)
2954 error ("target attribute or pragma changes darwin64 ABI");
2955 else
2957 rs6000_darwin64_abi = 1;
2958 /* Default to natural alignment, for better performance. */
2959 rs6000_alignment_flags = MASK_ALIGN_NATURAL;
2963 /* Place FP constants in the constant pool instead of TOC
2964 if section anchors enabled. */
2965 if (flag_section_anchors)
2966 TARGET_NO_FP_IN_TOC = 1;
2968 #ifdef SUBTARGET_OVERRIDE_OPTIONS
2969 SUBTARGET_OVERRIDE_OPTIONS;
2970 #endif
2971 #ifdef SUBSUBTARGET_OVERRIDE_OPTIONS
2972 SUBSUBTARGET_OVERRIDE_OPTIONS;
2973 #endif
2974 #ifdef SUB3TARGET_OVERRIDE_OPTIONS
2975 SUB3TARGET_OVERRIDE_OPTIONS;
2976 #endif
2978 if (TARGET_E500 || rs6000_cpu == PROCESSOR_PPCE500MC
2979 || rs6000_cpu == PROCESSOR_PPCE500MC64)
2981 /* The e500 and e500mc do not have string instructions, and we set
2982 MASK_STRING above when optimizing for size. */
2983 if ((target_flags & MASK_STRING) != 0)
2984 target_flags = target_flags & ~MASK_STRING;
2986 else if (rs6000_select[1].string != NULL)
2988 /* For the powerpc-eabispe configuration, we set all these by
2989 default, so let's unset them if we manually set another
2990 CPU that is not the E500. */
2991 if (main_target_opt != NULL
2992 && ((main_target_opt->x_rs6000_spe_abi != rs6000_spe_abi)
2993 || (main_target_opt->x_rs6000_spe != rs6000_spe)
2994 || (main_target_opt->x_rs6000_float_gprs != rs6000_float_gprs)))
2995 error ("target attribute or pragma changes SPE ABI");
2996 else
2998 if (!rs6000_explicit_options.spe_abi)
2999 rs6000_spe_abi = 0;
3000 if (!rs6000_explicit_options.spe)
3001 rs6000_spe = 0;
3002 if (!rs6000_explicit_options.float_gprs)
3003 rs6000_float_gprs = 0;
3005 if (!(target_flags_explicit & MASK_ISEL))
3006 target_flags &= ~MASK_ISEL;
3009 /* Detect invalid option combinations with E500. */
3010 CHECK_E500_OPTIONS;
3012 rs6000_always_hint = (rs6000_cpu != PROCESSOR_POWER4
3013 && rs6000_cpu != PROCESSOR_POWER5
3014 && rs6000_cpu != PROCESSOR_POWER6
3015 && rs6000_cpu != PROCESSOR_POWER7
3016 && rs6000_cpu != PROCESSOR_PPCA2
3017 && rs6000_cpu != PROCESSOR_CELL);
3018 rs6000_sched_groups = (rs6000_cpu == PROCESSOR_POWER4
3019 || rs6000_cpu == PROCESSOR_POWER5
3020 || rs6000_cpu == PROCESSOR_POWER7);
3021 rs6000_align_branch_targets = (rs6000_cpu == PROCESSOR_POWER4
3022 || rs6000_cpu == PROCESSOR_POWER5
3023 || rs6000_cpu == PROCESSOR_POWER6
3024 || rs6000_cpu == PROCESSOR_POWER7
3025 || rs6000_cpu == PROCESSOR_PPCE500MC
3026 || rs6000_cpu == PROCESSOR_PPCE500MC64);
3028 /* Allow debug switches to override the above settings. These are set to -1
3029 in rs6000.opt to indicate the user hasn't directly set the switch. */
3030 if (TARGET_ALWAYS_HINT >= 0)
3031 rs6000_always_hint = TARGET_ALWAYS_HINT;
3033 if (TARGET_SCHED_GROUPS >= 0)
3034 rs6000_sched_groups = TARGET_SCHED_GROUPS;
3036 if (TARGET_ALIGN_BRANCH_TARGETS >= 0)
3037 rs6000_align_branch_targets = TARGET_ALIGN_BRANCH_TARGETS;
3039 rs6000_sched_restricted_insns_priority
3040 = (rs6000_sched_groups ? 1 : 0);
3042 /* Handle -msched-costly-dep option. */
3043 rs6000_sched_costly_dep
3044 = (rs6000_sched_groups ? store_to_load_dep_costly : no_dep_costly);
3046 if (rs6000_sched_costly_dep_str)
3048 if (! strcmp (rs6000_sched_costly_dep_str, "no"))
3049 rs6000_sched_costly_dep = no_dep_costly;
3050 else if (! strcmp (rs6000_sched_costly_dep_str, "all"))
3051 rs6000_sched_costly_dep = all_deps_costly;
3052 else if (! strcmp (rs6000_sched_costly_dep_str, "true_store_to_load"))
3053 rs6000_sched_costly_dep = true_store_to_load_dep_costly;
3054 else if (! strcmp (rs6000_sched_costly_dep_str, "store_to_load"))
3055 rs6000_sched_costly_dep = store_to_load_dep_costly;
3056 else
3057 rs6000_sched_costly_dep = ((enum rs6000_dependence_cost)
3058 atoi (rs6000_sched_costly_dep_str));
3061 /* Handle -minsert-sched-nops option. */
3062 rs6000_sched_insert_nops
3063 = (rs6000_sched_groups ? sched_finish_regroup_exact : sched_finish_none);
3065 if (rs6000_sched_insert_nops_str)
3067 if (! strcmp (rs6000_sched_insert_nops_str, "no"))
3068 rs6000_sched_insert_nops = sched_finish_none;
3069 else if (! strcmp (rs6000_sched_insert_nops_str, "pad"))
3070 rs6000_sched_insert_nops = sched_finish_pad_groups;
3071 else if (! strcmp (rs6000_sched_insert_nops_str, "regroup_exact"))
3072 rs6000_sched_insert_nops = sched_finish_regroup_exact;
3073 else
3074 rs6000_sched_insert_nops = ((enum rs6000_nop_insertion)
3075 atoi (rs6000_sched_insert_nops_str));
3078 if (global_init_p)
3080 #ifdef TARGET_REGNAMES
3081 /* If the user desires alternate register names, copy in the
3082 alternate names now. */
3083 if (TARGET_REGNAMES)
3084 memcpy (rs6000_reg_names, alt_reg_names, sizeof (rs6000_reg_names));
3085 #endif
3087 /* Set aix_struct_return last, after the ABI is determined.
3088 If -maix-struct-return or -msvr4-struct-return was explicitly
3089 used, don't override with the ABI default. */
3090 if (!rs6000_explicit_options.aix_struct_ret)
3091 aix_struct_return = (DEFAULT_ABI != ABI_V4 || DRAFT_V4_STRUCT_RET);
3093 #if 0
3094 /* IBM XL compiler defaults to unsigned bitfields. */
3095 if (TARGET_XL_COMPAT)
3096 flag_signed_bitfields = 0;
3097 #endif
3099 if (TARGET_LONG_DOUBLE_128 && !TARGET_IEEEQUAD)
3100 REAL_MODE_FORMAT (TFmode) = &ibm_extended_format;
3102 if (TARGET_TOC)
3103 ASM_GENERATE_INTERNAL_LABEL (toc_label_name, "LCTOC", 1);
3105 /* We can only guarantee the availability of DI pseudo-ops when
3106 assembling for 64-bit targets. */
3107 if (!TARGET_64BIT)
3109 targetm.asm_out.aligned_op.di = NULL;
3110 targetm.asm_out.unaligned_op.di = NULL;
3114 /* Set branch target alignment, if not optimizing for size. */
3115 if (!optimize_size)
3117 /* Cell wants to be aligned 8byte for dual issue. Titan wants to be
3118 aligned 8byte to avoid misprediction by the branch predictor. */
3119 if (rs6000_cpu == PROCESSOR_TITAN
3120 || rs6000_cpu == PROCESSOR_CELL)
3122 if (align_functions <= 0)
3123 align_functions = 8;
3124 if (align_jumps <= 0)
3125 align_jumps = 8;
3126 if (align_loops <= 0)
3127 align_loops = 8;
3129 if (rs6000_align_branch_targets)
3131 if (align_functions <= 0)
3132 align_functions = 16;
3133 if (align_jumps <= 0)
3134 align_jumps = 16;
3135 if (align_loops <= 0)
3137 can_override_loop_align = 1;
3138 align_loops = 16;
3141 if (align_jumps_max_skip <= 0)
3142 align_jumps_max_skip = 15;
3143 if (align_loops_max_skip <= 0)
3144 align_loops_max_skip = 15;
3147 /* Arrange to save and restore machine status around nested functions. */
3148 init_machine_status = rs6000_init_machine_status;
3150 /* We should always be splitting complex arguments, but we can't break
3151 Linux and Darwin ABIs at the moment. For now, only AIX is fixed. */
3152 if (DEFAULT_ABI != ABI_AIX)
3153 targetm.calls.split_complex_arg = NULL;
3156 /* Initialize rs6000_cost with the appropriate target costs. */
3157 if (optimize_size)
3158 rs6000_cost = TARGET_POWERPC64 ? &size64_cost : &size32_cost;
3159 else
3160 switch (rs6000_cpu)
3162 case PROCESSOR_RIOS1:
3163 rs6000_cost = &rios1_cost;
3164 break;
3166 case PROCESSOR_RIOS2:
3167 rs6000_cost = &rios2_cost;
3168 break;
3170 case PROCESSOR_RS64A:
3171 rs6000_cost = &rs64a_cost;
3172 break;
3174 case PROCESSOR_MPCCORE:
3175 rs6000_cost = &mpccore_cost;
3176 break;
3178 case PROCESSOR_PPC403:
3179 rs6000_cost = &ppc403_cost;
3180 break;
3182 case PROCESSOR_PPC405:
3183 rs6000_cost = &ppc405_cost;
3184 break;
3186 case PROCESSOR_PPC440:
3187 rs6000_cost = &ppc440_cost;
3188 break;
3190 case PROCESSOR_PPC476:
3191 rs6000_cost = &ppc476_cost;
3192 break;
3194 case PROCESSOR_PPC601:
3195 rs6000_cost = &ppc601_cost;
3196 break;
3198 case PROCESSOR_PPC603:
3199 rs6000_cost = &ppc603_cost;
3200 break;
3202 case PROCESSOR_PPC604:
3203 rs6000_cost = &ppc604_cost;
3204 break;
3206 case PROCESSOR_PPC604e:
3207 rs6000_cost = &ppc604e_cost;
3208 break;
3210 case PROCESSOR_PPC620:
3211 rs6000_cost = &ppc620_cost;
3212 break;
3214 case PROCESSOR_PPC630:
3215 rs6000_cost = &ppc630_cost;
3216 break;
3218 case PROCESSOR_CELL:
3219 rs6000_cost = &ppccell_cost;
3220 break;
3222 case PROCESSOR_PPC750:
3223 case PROCESSOR_PPC7400:
3224 rs6000_cost = &ppc750_cost;
3225 break;
3227 case PROCESSOR_PPC7450:
3228 rs6000_cost = &ppc7450_cost;
3229 break;
3231 case PROCESSOR_PPC8540:
3232 rs6000_cost = &ppc8540_cost;
3233 break;
3235 case PROCESSOR_PPCE300C2:
3236 case PROCESSOR_PPCE300C3:
3237 rs6000_cost = &ppce300c2c3_cost;
3238 break;
3240 case PROCESSOR_PPCE500MC:
3241 rs6000_cost = &ppce500mc_cost;
3242 break;
3244 case PROCESSOR_PPCE500MC64:
3245 rs6000_cost = &ppce500mc64_cost;
3246 break;
3248 case PROCESSOR_TITAN:
3249 rs6000_cost = &titan_cost;
3250 break;
3252 case PROCESSOR_POWER4:
3253 case PROCESSOR_POWER5:
3254 rs6000_cost = &power4_cost;
3255 break;
3257 case PROCESSOR_POWER6:
3258 rs6000_cost = &power6_cost;
3259 break;
3261 case PROCESSOR_POWER7:
3262 rs6000_cost = &power7_cost;
3263 break;
3265 case PROCESSOR_PPCA2:
3266 rs6000_cost = &ppca2_cost;
3267 break;
3269 default:
3270 gcc_unreachable ();
3273 if (global_init_p)
3275 maybe_set_param_value (PARAM_SIMULTANEOUS_PREFETCHES,
3276 rs6000_cost->simultaneous_prefetches,
3277 global_options.x_param_values,
3278 global_options_set.x_param_values);
3279 maybe_set_param_value (PARAM_L1_CACHE_SIZE, rs6000_cost->l1_cache_size,
3280 global_options.x_param_values,
3281 global_options_set.x_param_values);
3282 maybe_set_param_value (PARAM_L1_CACHE_LINE_SIZE,
3283 rs6000_cost->cache_line_size,
3284 global_options.x_param_values,
3285 global_options_set.x_param_values);
3286 maybe_set_param_value (PARAM_L2_CACHE_SIZE, rs6000_cost->l2_cache_size,
3287 global_options.x_param_values,
3288 global_options_set.x_param_values);
3290 /* If using typedef char *va_list, signal that
3291 __builtin_va_start (&ap, 0) can be optimized to
3292 ap = __builtin_next_arg (0). */
3293 if (DEFAULT_ABI != ABI_V4)
3294 targetm.expand_builtin_va_start = NULL;
3297 /* Set up single/double float flags.
3298 If TARGET_HARD_FLOAT is set, but neither single or double is set,
3299 then set both flags. */
3300 if (TARGET_HARD_FLOAT && TARGET_FPRS
3301 && rs6000_single_float == 0 && rs6000_double_float == 0)
3302 rs6000_single_float = rs6000_double_float = 1;
3304 /* Reset single and double FP flags if target is E500. */
3305 if (TARGET_E500)
3307 rs6000_single_float = rs6000_double_float = 0;
3308 if (TARGET_E500_SINGLE)
3309 rs6000_single_float = 1;
3310 if (TARGET_E500_DOUBLE)
3311 rs6000_single_float = rs6000_double_float = 1;
3314 if (main_target_opt)
3316 if (main_target_opt->x_rs6000_single_float != rs6000_single_float)
3317 error ("target attribute or pragma changes single precision floating "
3318 "point");
3319 if (main_target_opt->x_rs6000_double_float != rs6000_double_float)
3320 error ("target attribute or pragma changes double precision floating "
3321 "point");
3324 /* If not explicitly specified via option, decide whether to generate indexed
3325 load/store instructions. */
3326 if (TARGET_AVOID_XFORM == -1)
3327 /* Avoid indexed addressing when targeting Power6 in order to avoid the
3328 DERAT mispredict penalty. However the LVE and STVE altivec instructions
3329 need indexed accesses and the type used is the scalar type of the element
3330 being loaded or stored. */
3331 TARGET_AVOID_XFORM = (rs6000_cpu == PROCESSOR_POWER6 && TARGET_CMPB
3332 && !TARGET_ALTIVEC);
3334 /* Set the -mrecip options. */
3335 if (rs6000_recip_name)
3337 char *p = ASTRDUP (rs6000_recip_name);
3338 char *q;
3339 unsigned int mask, i;
3340 bool invert;
3342 while ((q = strtok (p, ",")) != NULL)
3344 p = NULL;
3345 if (*q == '!')
3347 invert = true;
3348 q++;
3350 else
3351 invert = false;
3353 if (!strcmp (q, "default"))
3354 mask = ((TARGET_RECIP_PRECISION)
3355 ? RECIP_HIGH_PRECISION : RECIP_LOW_PRECISION);
3356 else
3358 for (i = 0; i < ARRAY_SIZE (recip_options); i++)
3359 if (!strcmp (q, recip_options[i].string))
3361 mask = recip_options[i].mask;
3362 break;
3365 if (i == ARRAY_SIZE (recip_options))
3367 error ("unknown option for -mrecip=%s", q);
3368 invert = false;
3369 mask = 0;
3370 ret = false;
3374 if (invert)
3375 rs6000_recip_control &= ~mask;
3376 else
3377 rs6000_recip_control |= mask;
3381 rs6000_init_hard_regno_mode_ok (global_init_p);
3383 /* Save the initial options in case the user does function specific options */
3384 if (global_init_p)
3385 target_option_default_node = target_option_current_node
3386 = build_target_option_node ();
3388 return ret;
3391 /* Implement TARGET_OPTION_OVERRIDE. On the RS/6000 this is used to
3392 define the target cpu type. */
3394 static void
3395 rs6000_option_override (void)
3397 (void) rs6000_option_override_internal (true);
3401 /* Implement targetm.vectorize.builtin_mask_for_load. */
3402 static tree
3403 rs6000_builtin_mask_for_load (void)
3405 if (TARGET_ALTIVEC || TARGET_VSX)
3406 return altivec_builtin_mask_for_load;
3407 else
3408 return 0;
3411 /* Implement LOOP_ALIGN. */
3413 rs6000_loop_align (rtx label)
3415 basic_block bb;
3416 int ninsns;
3418 /* Don't override loop alignment if -falign-loops was specified. */
3419 if (!can_override_loop_align)
3420 return align_loops_log;
3422 bb = BLOCK_FOR_INSN (label);
3423 ninsns = num_loop_insns(bb->loop_father);
3425 /* Align small loops to 32 bytes to fit in an icache sector, otherwise return default. */
3426 if (ninsns > 4 && ninsns <= 8
3427 && (rs6000_cpu == PROCESSOR_POWER4
3428 || rs6000_cpu == PROCESSOR_POWER5
3429 || rs6000_cpu == PROCESSOR_POWER6
3430 || rs6000_cpu == PROCESSOR_POWER7))
3431 return 5;
3432 else
3433 return align_loops_log;
3436 /* Implement TARGET_LOOP_ALIGN_MAX_SKIP. */
3437 static int
3438 rs6000_loop_align_max_skip (rtx label)
3440 return (1 << rs6000_loop_align (label)) - 1;
3443 /* Implement targetm.vectorize.builtin_conversion.
3444 Returns a decl of a function that implements conversion of an integer vector
3445 into a floating-point vector, or vice-versa. DEST_TYPE is the
3446 destination type and SRC_TYPE the source type of the conversion.
3447 Return NULL_TREE if it is not available. */
3448 static tree
3449 rs6000_builtin_conversion (unsigned int tcode, tree dest_type, tree src_type)
3451 enum tree_code code = (enum tree_code) tcode;
3453 switch (code)
3455 case FIX_TRUNC_EXPR:
3456 switch (TYPE_MODE (dest_type))
3458 case V2DImode:
3459 if (!VECTOR_UNIT_VSX_P (V2DFmode))
3460 return NULL_TREE;
3462 return TYPE_UNSIGNED (dest_type)
3463 ? rs6000_builtin_decls[VSX_BUILTIN_XVCVDPUXDS_UNS]
3464 : rs6000_builtin_decls[VSX_BUILTIN_XVCVDPSXDS];
3466 case V4SImode:
3467 if (VECTOR_UNIT_NONE_P (V4SImode) || VECTOR_UNIT_NONE_P (V4SFmode))
3468 return NULL_TREE;
3470 return TYPE_UNSIGNED (dest_type)
3471 ? rs6000_builtin_decls[VECTOR_BUILTIN_FIXUNS_V4SF_V4SI]
3472 : rs6000_builtin_decls[VECTOR_BUILTIN_FIX_V4SF_V4SI];
3474 default:
3475 return NULL_TREE;
3478 case FLOAT_EXPR:
3479 switch (TYPE_MODE (src_type))
3481 case V2DImode:
3482 if (!VECTOR_UNIT_VSX_P (V2DFmode))
3483 return NULL_TREE;
3485 return TYPE_UNSIGNED (src_type)
3486 ? rs6000_builtin_decls[VSX_BUILTIN_XVCVUXDDP]
3487 : rs6000_builtin_decls[VSX_BUILTIN_XVCVSXDDP];
3489 case V4SImode:
3490 if (VECTOR_UNIT_NONE_P (V4SImode) || VECTOR_UNIT_NONE_P (V4SFmode))
3491 return NULL_TREE;
3493 return TYPE_UNSIGNED (src_type)
3494 ? rs6000_builtin_decls[VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF]
3495 : rs6000_builtin_decls[VECTOR_BUILTIN_FLOAT_V4SI_V4SF];
3497 default:
3498 return NULL_TREE;
3501 default:
3502 return NULL_TREE;
3506 /* Implement targetm.vectorize.builtin_mul_widen_even. */
3507 static tree
3508 rs6000_builtin_mul_widen_even (tree type)
3510 if (!TARGET_ALTIVEC)
3511 return NULL_TREE;
3513 switch (TYPE_MODE (type))
3515 case V8HImode:
3516 return TYPE_UNSIGNED (type)
3517 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULEUH_UNS]
3518 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULESH];
3520 case V16QImode:
3521 return TYPE_UNSIGNED (type)
3522 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULEUB_UNS]
3523 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULESB];
3524 default:
3525 return NULL_TREE;
3529 /* Implement targetm.vectorize.builtin_mul_widen_odd. */
3530 static tree
3531 rs6000_builtin_mul_widen_odd (tree type)
3533 if (!TARGET_ALTIVEC)
3534 return NULL_TREE;
3536 switch (TYPE_MODE (type))
3538 case V8HImode:
3539 return TYPE_UNSIGNED (type)
3540 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOUH_UNS]
3541 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOSH];
3543 case V16QImode:
3544 return TYPE_UNSIGNED (type)
3545 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOUB_UNS]
3546 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOSB];
3547 default:
3548 return NULL_TREE;
3553 /* Return true iff, data reference of TYPE can reach vector alignment (16)
3554 after applying N number of iterations. This routine does not determine
3555 how may iterations are required to reach desired alignment. */
3557 static bool
3558 rs6000_vector_alignment_reachable (const_tree type ATTRIBUTE_UNUSED, bool is_packed)
3560 if (is_packed)
3561 return false;
3563 if (TARGET_32BIT)
3565 if (rs6000_alignment_flags == MASK_ALIGN_NATURAL)
3566 return true;
3568 if (rs6000_alignment_flags == MASK_ALIGN_POWER)
3569 return true;
3571 return false;
3573 else
3575 if (TARGET_MACHO)
3576 return false;
3578 /* Assuming that all other types are naturally aligned. CHECKME! */
3579 return true;
3583 /* Return true if the vector misalignment factor is supported by the
3584 target. */
3585 bool
3586 rs6000_builtin_support_vector_misalignment (enum machine_mode mode,
3587 const_tree type,
3588 int misalignment,
3589 bool is_packed)
3591 if (TARGET_VSX)
3593 /* Return if movmisalign pattern is not supported for this mode. */
3594 if (optab_handler (movmisalign_optab, mode) == CODE_FOR_nothing)
3595 return false;
3597 if (misalignment == -1)
3599 /* Misalignment factor is unknown at compile time but we know
3600 it's word aligned. */
3601 if (rs6000_vector_alignment_reachable (type, is_packed))
3603 int element_size = TREE_INT_CST_LOW (TYPE_SIZE (type));
3605 if (element_size == 64 || element_size == 32)
3606 return true;
3609 return false;
3612 /* VSX supports word-aligned vector. */
3613 if (misalignment % 4 == 0)
3614 return true;
3616 return false;
3619 /* Implement targetm.vectorize.builtin_vec_perm. */
3620 tree
3621 rs6000_builtin_vec_perm (tree type, tree *mask_element_type)
3623 tree inner_type = TREE_TYPE (type);
3624 bool uns_p = TYPE_UNSIGNED (inner_type);
3625 tree d;
3627 *mask_element_type = unsigned_char_type_node;
3629 switch (TYPE_MODE (type))
3631 case V16QImode:
3632 d = (uns_p
3633 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_16QI_UNS]
3634 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_16QI]);
3635 break;
3637 case V8HImode:
3638 d = (uns_p
3639 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_8HI_UNS]
3640 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_8HI]);
3641 break;
3643 case V4SImode:
3644 d = (uns_p
3645 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SI_UNS]
3646 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SI]);
3647 break;
3649 case V4SFmode:
3650 d = rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SF];
3651 break;
3653 case V2DFmode:
3654 if (!TARGET_ALLOW_DF_PERMUTE)
3655 return NULL_TREE;
3657 d = rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DF];
3658 break;
3660 case V2DImode:
3661 if (!TARGET_ALLOW_DF_PERMUTE)
3662 return NULL_TREE;
3664 d = (uns_p
3665 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DI_UNS]
3666 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DI]);
3667 break;
3669 default:
3670 return NULL_TREE;
3673 gcc_assert (d);
3674 return d;
3678 /* Implement targetm.vectorize.builtin_vectorization_cost. */
3679 static int
3680 rs6000_builtin_vectorization_cost (enum vect_cost_for_stmt type_of_cost,
3681 tree vectype, int misalign)
3683 unsigned elements;
3685 switch (type_of_cost)
3687 case scalar_stmt:
3688 case scalar_load:
3689 case scalar_store:
3690 case vector_stmt:
3691 case vector_load:
3692 case vector_store:
3693 case vec_to_scalar:
3694 case scalar_to_vec:
3695 case cond_branch_not_taken:
3696 case vec_perm:
3697 return 1;
3699 case cond_branch_taken:
3700 return 3;
3702 case unaligned_load:
3703 if (TARGET_VSX && TARGET_ALLOW_MOVMISALIGN)
3705 elements = TYPE_VECTOR_SUBPARTS (vectype);
3706 if (elements == 2)
3707 /* Double word aligned. */
3708 return 2;
3710 if (elements == 4)
3712 switch (misalign)
3714 case 8:
3715 /* Double word aligned. */
3716 return 2;
3718 case -1:
3719 /* Unknown misalignment. */
3720 case 4:
3721 case 12:
3722 /* Word aligned. */
3723 return 22;
3725 default:
3726 gcc_unreachable ();
3731 if (TARGET_ALTIVEC)
3732 /* Misaligned loads are not supported. */
3733 gcc_unreachable ();
3735 return 2;
3737 case unaligned_store:
3738 if (TARGET_VSX && TARGET_ALLOW_MOVMISALIGN)
3740 elements = TYPE_VECTOR_SUBPARTS (vectype);
3741 if (elements == 2)
3742 /* Double word aligned. */
3743 return 2;
3745 if (elements == 4)
3747 switch (misalign)
3749 case 8:
3750 /* Double word aligned. */
3751 return 2;
3753 case -1:
3754 /* Unknown misalignment. */
3755 case 4:
3756 case 12:
3757 /* Word aligned. */
3758 return 23;
3760 default:
3761 gcc_unreachable ();
3766 if (TARGET_ALTIVEC)
3767 /* Misaligned stores are not supported. */
3768 gcc_unreachable ();
3770 return 2;
3772 default:
3773 gcc_unreachable ();
3777 /* Implement targetm.vectorize.preferred_simd_mode. */
3779 static enum machine_mode
3780 rs6000_preferred_simd_mode (enum machine_mode mode)
3782 if (TARGET_VSX)
3783 switch (mode)
3785 case DFmode:
3786 return V2DFmode;
3787 default:;
3789 if (TARGET_ALTIVEC || TARGET_VSX)
3790 switch (mode)
3792 case SFmode:
3793 return V4SFmode;
3794 case DImode:
3795 return V2DImode;
3796 case SImode:
3797 return V4SImode;
3798 case HImode:
3799 return V8HImode;
3800 case QImode:
3801 return V16QImode;
3802 default:;
3804 if (TARGET_SPE)
3805 switch (mode)
3807 case SFmode:
3808 return V2SFmode;
3809 case SImode:
3810 return V2SImode;
3811 default:;
3813 if (TARGET_PAIRED_FLOAT
3814 && mode == SFmode)
3815 return V2SFmode;
3816 return word_mode;
3819 /* Handle generic options of the form -mfoo=yes/no.
3820 NAME is the option name.
3821 VALUE is the option value.
3822 FLAG is the pointer to the flag where to store a 1 or 0, depending on
3823 whether the option value is 'yes' or 'no' respectively. */
3824 static void
3825 rs6000_parse_yes_no_option (const char *name, const char *value, int *flag)
3827 if (value == 0)
3828 return;
3829 else if (!strcmp (value, "yes"))
3830 *flag = 1;
3831 else if (!strcmp (value, "no"))
3832 *flag = 0;
3833 else
3834 error ("unknown -m%s= option specified: '%s'", name, value);
3837 /* Implement TARGET_OPTION_INIT_STRUCT. */
3839 static void
3840 rs6000_option_init_struct (struct gcc_options *opts)
3842 if (DEFAULT_ABI == ABI_DARWIN)
3843 /* The Darwin libraries never set errno, so we might as well
3844 avoid calling them when that's the only reason we would. */
3845 opts->x_flag_errno_math = 0;
3847 /* Enable section anchors by default. */
3848 if (!TARGET_MACHO)
3849 opts->x_flag_section_anchors = 1;
3852 /* Implement TARGET_OPTION_DEFAULT_PARAMS. */
3854 static void
3855 rs6000_option_default_params (void)
3857 /* Double growth factor to counter reduced min jump length. */
3858 set_default_param_value (PARAM_MAX_GROW_COPY_BB_INSNS, 16);
3861 static enum fpu_type_t
3862 rs6000_parse_fpu_option (const char *option)
3864 if (!strcmp("none", option)) return FPU_NONE;
3865 if (!strcmp("sp_lite", option)) return FPU_SF_LITE;
3866 if (!strcmp("dp_lite", option)) return FPU_DF_LITE;
3867 if (!strcmp("sp_full", option)) return FPU_SF_FULL;
3868 if (!strcmp("dp_full", option)) return FPU_DF_FULL;
3869 error("unknown value %s for -mfpu", option);
3870 return FPU_NONE;
3874 /* Handler for the Mathematical Acceleration Subsystem (mass) interface to a
3875 library with vectorized intrinsics. */
3877 static tree
3878 rs6000_builtin_vectorized_libmass (tree fndecl, tree type_out, tree type_in)
3880 char name[32];
3881 const char *suffix = NULL;
3882 tree fntype, new_fndecl, bdecl = NULL_TREE;
3883 int n_args = 1;
3884 const char *bname;
3885 enum machine_mode el_mode, in_mode;
3886 int n, in_n;
3888 /* Libmass is suitable for unsafe math only as it does not correctly support
3889 parts of IEEE with the required precision such as denormals. Only support
3890 it if we have VSX to use the simd d2 or f4 functions.
3891 XXX: Add variable length support. */
3892 if (!flag_unsafe_math_optimizations || !TARGET_VSX)
3893 return NULL_TREE;
3895 el_mode = TYPE_MODE (TREE_TYPE (type_out));
3896 n = TYPE_VECTOR_SUBPARTS (type_out);
3897 in_mode = TYPE_MODE (TREE_TYPE (type_in));
3898 in_n = TYPE_VECTOR_SUBPARTS (type_in);
3899 if (el_mode != in_mode
3900 || n != in_n)
3901 return NULL_TREE;
3903 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
3905 enum built_in_function fn = DECL_FUNCTION_CODE (fndecl);
3906 switch (fn)
3908 case BUILT_IN_ATAN2:
3909 case BUILT_IN_HYPOT:
3910 case BUILT_IN_POW:
3911 n_args = 2;
3912 /* fall through */
3914 case BUILT_IN_ACOS:
3915 case BUILT_IN_ACOSH:
3916 case BUILT_IN_ASIN:
3917 case BUILT_IN_ASINH:
3918 case BUILT_IN_ATAN:
3919 case BUILT_IN_ATANH:
3920 case BUILT_IN_CBRT:
3921 case BUILT_IN_COS:
3922 case BUILT_IN_COSH:
3923 case BUILT_IN_ERF:
3924 case BUILT_IN_ERFC:
3925 case BUILT_IN_EXP2:
3926 case BUILT_IN_EXP:
3927 case BUILT_IN_EXPM1:
3928 case BUILT_IN_LGAMMA:
3929 case BUILT_IN_LOG10:
3930 case BUILT_IN_LOG1P:
3931 case BUILT_IN_LOG2:
3932 case BUILT_IN_LOG:
3933 case BUILT_IN_SIN:
3934 case BUILT_IN_SINH:
3935 case BUILT_IN_SQRT:
3936 case BUILT_IN_TAN:
3937 case BUILT_IN_TANH:
3938 bdecl = implicit_built_in_decls[fn];
3939 suffix = "d2"; /* pow -> powd2 */
3940 if (el_mode != DFmode
3941 || n != 2)
3942 return NULL_TREE;
3943 break;
3945 case BUILT_IN_ATAN2F:
3946 case BUILT_IN_HYPOTF:
3947 case BUILT_IN_POWF:
3948 n_args = 2;
3949 /* fall through */
3951 case BUILT_IN_ACOSF:
3952 case BUILT_IN_ACOSHF:
3953 case BUILT_IN_ASINF:
3954 case BUILT_IN_ASINHF:
3955 case BUILT_IN_ATANF:
3956 case BUILT_IN_ATANHF:
3957 case BUILT_IN_CBRTF:
3958 case BUILT_IN_COSF:
3959 case BUILT_IN_COSHF:
3960 case BUILT_IN_ERFF:
3961 case BUILT_IN_ERFCF:
3962 case BUILT_IN_EXP2F:
3963 case BUILT_IN_EXPF:
3964 case BUILT_IN_EXPM1F:
3965 case BUILT_IN_LGAMMAF:
3966 case BUILT_IN_LOG10F:
3967 case BUILT_IN_LOG1PF:
3968 case BUILT_IN_LOG2F:
3969 case BUILT_IN_LOGF:
3970 case BUILT_IN_SINF:
3971 case BUILT_IN_SINHF:
3972 case BUILT_IN_SQRTF:
3973 case BUILT_IN_TANF:
3974 case BUILT_IN_TANHF:
3975 bdecl = implicit_built_in_decls[fn];
3976 suffix = "4"; /* powf -> powf4 */
3977 if (el_mode != SFmode
3978 || n != 4)
3979 return NULL_TREE;
3980 break;
3982 default:
3983 return NULL_TREE;
3986 else
3987 return NULL_TREE;
3989 gcc_assert (suffix != NULL);
3990 bname = IDENTIFIER_POINTER (DECL_NAME (bdecl));
3991 strcpy (name, bname + sizeof ("__builtin_") - 1);
3992 strcat (name, suffix);
3994 if (n_args == 1)
3995 fntype = build_function_type_list (type_out, type_in, NULL);
3996 else if (n_args == 2)
3997 fntype = build_function_type_list (type_out, type_in, type_in, NULL);
3998 else
3999 gcc_unreachable ();
4001 /* Build a function declaration for the vectorized function. */
4002 new_fndecl = build_decl (BUILTINS_LOCATION,
4003 FUNCTION_DECL, get_identifier (name), fntype);
4004 TREE_PUBLIC (new_fndecl) = 1;
4005 DECL_EXTERNAL (new_fndecl) = 1;
4006 DECL_IS_NOVOPS (new_fndecl) = 1;
4007 TREE_READONLY (new_fndecl) = 1;
4009 return new_fndecl;
4012 /* Returns a function decl for a vectorized version of the builtin function
4013 with builtin function code FN and the result vector type TYPE, or NULL_TREE
4014 if it is not available. */
4016 static tree
4017 rs6000_builtin_vectorized_function (tree fndecl, tree type_out,
4018 tree type_in)
4020 enum machine_mode in_mode, out_mode;
4021 int in_n, out_n;
4023 if (TREE_CODE (type_out) != VECTOR_TYPE
4024 || TREE_CODE (type_in) != VECTOR_TYPE
4025 || !TARGET_VECTORIZE_BUILTINS)
4026 return NULL_TREE;
4028 out_mode = TYPE_MODE (TREE_TYPE (type_out));
4029 out_n = TYPE_VECTOR_SUBPARTS (type_out);
4030 in_mode = TYPE_MODE (TREE_TYPE (type_in));
4031 in_n = TYPE_VECTOR_SUBPARTS (type_in);
4033 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
4035 enum built_in_function fn = DECL_FUNCTION_CODE (fndecl);
4036 switch (fn)
4038 case BUILT_IN_COPYSIGN:
4039 if (VECTOR_UNIT_VSX_P (V2DFmode)
4040 && out_mode == DFmode && out_n == 2
4041 && in_mode == DFmode && in_n == 2)
4042 return rs6000_builtin_decls[VSX_BUILTIN_CPSGNDP];
4043 break;
4044 case BUILT_IN_COPYSIGNF:
4045 if (out_mode != SFmode || out_n != 4
4046 || in_mode != SFmode || in_n != 4)
4047 break;
4048 if (VECTOR_UNIT_VSX_P (V4SFmode))
4049 return rs6000_builtin_decls[VSX_BUILTIN_CPSGNSP];
4050 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
4051 return rs6000_builtin_decls[ALTIVEC_BUILTIN_COPYSIGN_V4SF];
4052 break;
4053 case BUILT_IN_SQRT:
4054 if (VECTOR_UNIT_VSX_P (V2DFmode)
4055 && out_mode == DFmode && out_n == 2
4056 && in_mode == DFmode && in_n == 2)
4057 return rs6000_builtin_decls[VSX_BUILTIN_XVSQRTDP];
4058 break;
4059 case BUILT_IN_SQRTF:
4060 if (VECTOR_UNIT_VSX_P (V4SFmode)
4061 && out_mode == SFmode && out_n == 4
4062 && in_mode == SFmode && in_n == 4)
4063 return rs6000_builtin_decls[VSX_BUILTIN_XVSQRTSP];
4064 break;
4065 case BUILT_IN_CEIL:
4066 if (VECTOR_UNIT_VSX_P (V2DFmode)
4067 && out_mode == DFmode && out_n == 2
4068 && in_mode == DFmode && in_n == 2)
4069 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIP];
4070 break;
4071 case BUILT_IN_CEILF:
4072 if (out_mode != SFmode || out_n != 4
4073 || in_mode != SFmode || in_n != 4)
4074 break;
4075 if (VECTOR_UNIT_VSX_P (V4SFmode))
4076 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIP];
4077 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
4078 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIP];
4079 break;
4080 case BUILT_IN_FLOOR:
4081 if (VECTOR_UNIT_VSX_P (V2DFmode)
4082 && out_mode == DFmode && out_n == 2
4083 && in_mode == DFmode && in_n == 2)
4084 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIM];
4085 break;
4086 case BUILT_IN_FLOORF:
4087 if (out_mode != SFmode || out_n != 4
4088 || in_mode != SFmode || in_n != 4)
4089 break;
4090 if (VECTOR_UNIT_VSX_P (V4SFmode))
4091 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIM];
4092 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
4093 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIM];
4094 break;
4095 case BUILT_IN_FMA:
4096 if (VECTOR_UNIT_VSX_P (V2DFmode)
4097 && out_mode == DFmode && out_n == 2
4098 && in_mode == DFmode && in_n == 2)
4099 return rs6000_builtin_decls[VSX_BUILTIN_XVMADDDP];
4100 break;
4101 case BUILT_IN_FMAF:
4102 if (VECTOR_UNIT_VSX_P (V4SFmode)
4103 && out_mode == SFmode && out_n == 4
4104 && in_mode == SFmode && in_n == 4)
4105 return rs6000_builtin_decls[VSX_BUILTIN_XVMADDSP];
4106 else if (VECTOR_UNIT_ALTIVEC_P (V4SFmode)
4107 && out_mode == SFmode && out_n == 4
4108 && in_mode == SFmode && in_n == 4)
4109 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VMADDFP];
4110 break;
4111 case BUILT_IN_TRUNC:
4112 if (VECTOR_UNIT_VSX_P (V2DFmode)
4113 && out_mode == DFmode && out_n == 2
4114 && in_mode == DFmode && in_n == 2)
4115 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIZ];
4116 break;
4117 case BUILT_IN_TRUNCF:
4118 if (out_mode != SFmode || out_n != 4
4119 || in_mode != SFmode || in_n != 4)
4120 break;
4121 if (VECTOR_UNIT_VSX_P (V4SFmode))
4122 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIZ];
4123 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
4124 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIZ];
4125 break;
4126 case BUILT_IN_NEARBYINT:
4127 if (VECTOR_UNIT_VSX_P (V2DFmode)
4128 && flag_unsafe_math_optimizations
4129 && out_mode == DFmode && out_n == 2
4130 && in_mode == DFmode && in_n == 2)
4131 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPI];
4132 break;
4133 case BUILT_IN_NEARBYINTF:
4134 if (VECTOR_UNIT_VSX_P (V4SFmode)
4135 && flag_unsafe_math_optimizations
4136 && out_mode == SFmode && out_n == 4
4137 && in_mode == SFmode && in_n == 4)
4138 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPI];
4139 break;
4140 case BUILT_IN_RINT:
4141 if (VECTOR_UNIT_VSX_P (V2DFmode)
4142 && !flag_trapping_math
4143 && out_mode == DFmode && out_n == 2
4144 && in_mode == DFmode && in_n == 2)
4145 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIC];
4146 break;
4147 case BUILT_IN_RINTF:
4148 if (VECTOR_UNIT_VSX_P (V4SFmode)
4149 && !flag_trapping_math
4150 && out_mode == SFmode && out_n == 4
4151 && in_mode == SFmode && in_n == 4)
4152 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIC];
4153 break;
4154 default:
4155 break;
4159 else if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
4161 enum rs6000_builtins fn
4162 = (enum rs6000_builtins)DECL_FUNCTION_CODE (fndecl);
4163 switch (fn)
4165 case RS6000_BUILTIN_RSQRTF:
4166 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)
4167 && out_mode == SFmode && out_n == 4
4168 && in_mode == SFmode && in_n == 4)
4169 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRSQRTFP];
4170 break;
4171 case RS6000_BUILTIN_RSQRT:
4172 if (VECTOR_UNIT_VSX_P (V2DFmode)
4173 && out_mode == DFmode && out_n == 2
4174 && in_mode == DFmode && in_n == 2)
4175 return rs6000_builtin_decls[VSX_BUILTIN_VEC_RSQRT_V2DF];
4176 break;
4177 case RS6000_BUILTIN_RECIPF:
4178 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)
4179 && out_mode == SFmode && out_n == 4
4180 && in_mode == SFmode && in_n == 4)
4181 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRECIPFP];
4182 break;
4183 case RS6000_BUILTIN_RECIP:
4184 if (VECTOR_UNIT_VSX_P (V2DFmode)
4185 && out_mode == DFmode && out_n == 2
4186 && in_mode == DFmode && in_n == 2)
4187 return rs6000_builtin_decls[VSX_BUILTIN_RECIP_V2DF];
4188 break;
4189 default:
4190 break;
4194 /* Generate calls to libmass if appropriate. */
4195 if (rs6000_veclib_handler)
4196 return rs6000_veclib_handler (fndecl, type_out, type_in);
4198 return NULL_TREE;
4202 /* Implement TARGET_HANDLE_OPTION. */
4204 static bool
4205 rs6000_handle_option (size_t code, const char *arg, int value)
4207 enum fpu_type_t fpu_type = FPU_NONE;
4208 int isel;
4209 char *p, *q;
4211 switch (code)
4213 case OPT_mno_power:
4214 target_flags &= ~(MASK_POWER | MASK_POWER2
4215 | MASK_MULTIPLE | MASK_STRING);
4216 target_flags_explicit |= (MASK_POWER | MASK_POWER2
4217 | MASK_MULTIPLE | MASK_STRING);
4218 break;
4219 case OPT_mno_powerpc:
4220 target_flags &= ~(MASK_POWERPC | MASK_PPC_GPOPT
4221 | MASK_PPC_GFXOPT | MASK_POWERPC64);
4222 target_flags_explicit |= (MASK_POWERPC | MASK_PPC_GPOPT
4223 | MASK_PPC_GFXOPT | MASK_POWERPC64);
4224 break;
4225 case OPT_mfull_toc:
4226 target_flags &= ~MASK_MINIMAL_TOC;
4227 TARGET_NO_FP_IN_TOC = 0;
4228 TARGET_NO_SUM_IN_TOC = 0;
4229 target_flags_explicit |= MASK_MINIMAL_TOC;
4230 #ifdef TARGET_USES_SYSV4_OPT
4231 /* Note, V.4 no longer uses a normal TOC, so make -mfull-toc, be
4232 just the same as -mminimal-toc. */
4233 target_flags |= MASK_MINIMAL_TOC;
4234 target_flags_explicit |= MASK_MINIMAL_TOC;
4235 #endif
4236 break;
4238 #ifdef TARGET_USES_SYSV4_OPT
4239 case OPT_mtoc:
4240 /* Make -mtoc behave like -mminimal-toc. */
4241 target_flags |= MASK_MINIMAL_TOC;
4242 target_flags_explicit |= MASK_MINIMAL_TOC;
4243 break;
4244 #endif
4246 #if defined (HAVE_LD_LARGE_TOC) && defined (TARGET_USES_LINUX64_OPT)
4247 case OPT_mcmodel_:
4248 if (strcmp (arg, "small") == 0)
4249 rs6000_current_cmodel = CMODEL_SMALL;
4250 else if (strcmp (arg, "medium") == 0)
4251 rs6000_current_cmodel = CMODEL_MEDIUM;
4252 else if (strcmp (arg, "large") == 0)
4253 rs6000_current_cmodel = CMODEL_LARGE;
4254 else
4256 error ("invalid option for -mcmodel: '%s'", arg);
4257 return false;
4259 rs6000_explicit_options.cmodel = true;
4260 #endif
4262 #ifdef TARGET_USES_AIX64_OPT
4263 case OPT_maix64:
4264 #else
4265 case OPT_m64:
4266 #endif
4267 target_flags |= MASK_POWERPC64 | MASK_POWERPC;
4268 target_flags |= ~target_flags_explicit & MASK_PPC_GFXOPT;
4269 target_flags_explicit |= MASK_POWERPC64 | MASK_POWERPC;
4270 break;
4272 #ifdef TARGET_USES_AIX64_OPT
4273 case OPT_maix32:
4274 #else
4275 case OPT_m32:
4276 #endif
4277 target_flags &= ~MASK_POWERPC64;
4278 target_flags_explicit |= MASK_POWERPC64;
4279 break;
4281 case OPT_minsert_sched_nops_:
4282 rs6000_sched_insert_nops_str = arg;
4283 break;
4285 case OPT_mminimal_toc:
4286 if (value == 1)
4288 TARGET_NO_FP_IN_TOC = 0;
4289 TARGET_NO_SUM_IN_TOC = 0;
4291 break;
4293 case OPT_mpower:
4294 if (value == 1)
4296 target_flags |= (MASK_MULTIPLE | MASK_STRING);
4297 target_flags_explicit |= (MASK_MULTIPLE | MASK_STRING);
4299 break;
4301 case OPT_mpower2:
4302 if (value == 1)
4304 target_flags |= (MASK_POWER | MASK_MULTIPLE | MASK_STRING);
4305 target_flags_explicit |= (MASK_POWER | MASK_MULTIPLE | MASK_STRING);
4307 break;
4309 case OPT_mpowerpc_gpopt:
4310 case OPT_mpowerpc_gfxopt:
4311 if (value == 1)
4313 target_flags |= MASK_POWERPC;
4314 target_flags_explicit |= MASK_POWERPC;
4316 break;
4318 case OPT_maix_struct_return:
4319 case OPT_msvr4_struct_return:
4320 rs6000_explicit_options.aix_struct_ret = true;
4321 break;
4323 case OPT_mvrsave:
4324 rs6000_explicit_options.vrsave = true;
4325 TARGET_ALTIVEC_VRSAVE = value;
4326 break;
4328 case OPT_mvrsave_:
4329 rs6000_explicit_options.vrsave = true;
4330 rs6000_parse_yes_no_option ("vrsave", arg, &(TARGET_ALTIVEC_VRSAVE));
4331 break;
4333 case OPT_misel_:
4334 target_flags_explicit |= MASK_ISEL;
4335 isel = 0;
4336 rs6000_parse_yes_no_option ("isel", arg, &isel);
4337 if (isel)
4338 target_flags |= MASK_ISEL;
4339 else
4340 target_flags &= ~MASK_ISEL;
4341 break;
4343 case OPT_mspe:
4344 rs6000_explicit_options.spe = true;
4345 rs6000_spe = value;
4346 break;
4348 case OPT_mspe_:
4349 rs6000_explicit_options.spe = true;
4350 rs6000_parse_yes_no_option ("spe", arg, &(rs6000_spe));
4351 break;
4353 case OPT_mdebug_:
4354 p = ASTRDUP (arg);
4355 rs6000_debug = 0;
4357 while ((q = strtok (p, ",")) != NULL)
4359 unsigned mask = 0;
4360 bool invert;
4362 p = NULL;
4363 if (*q == '!')
4365 invert = true;
4366 q++;
4368 else
4369 invert = false;
4371 if (! strcmp (q, "all"))
4372 mask = MASK_DEBUG_ALL;
4373 else if (! strcmp (q, "stack"))
4374 mask = MASK_DEBUG_STACK;
4375 else if (! strcmp (q, "arg"))
4376 mask = MASK_DEBUG_ARG;
4377 else if (! strcmp (q, "reg"))
4378 mask = MASK_DEBUG_REG;
4379 else if (! strcmp (q, "addr"))
4380 mask = MASK_DEBUG_ADDR;
4381 else if (! strcmp (q, "cost"))
4382 mask = MASK_DEBUG_COST;
4383 else if (! strcmp (q, "target"))
4384 mask = MASK_DEBUG_TARGET;
4385 else
4386 error ("unknown -mdebug-%s switch", q);
4388 if (invert)
4389 rs6000_debug &= ~mask;
4390 else
4391 rs6000_debug |= mask;
4393 break;
4395 #ifdef TARGET_USES_SYSV4_OPT
4396 case OPT_mcall_:
4397 rs6000_abi_name = arg;
4398 break;
4400 case OPT_msdata_:
4401 rs6000_sdata_name = arg;
4402 break;
4404 case OPT_mtls_size_:
4405 if (strcmp (arg, "16") == 0)
4406 rs6000_tls_size = 16;
4407 else if (strcmp (arg, "32") == 0)
4408 rs6000_tls_size = 32;
4409 else if (strcmp (arg, "64") == 0)
4410 rs6000_tls_size = 64;
4411 else
4412 error ("bad value %qs for -mtls-size switch", arg);
4413 break;
4415 case OPT_mrelocatable:
4416 if (value == 1)
4418 target_flags |= MASK_MINIMAL_TOC;
4419 target_flags_explicit |= MASK_MINIMAL_TOC;
4420 TARGET_NO_FP_IN_TOC = 1;
4422 break;
4424 case OPT_mrelocatable_lib:
4425 if (value == 1)
4427 target_flags |= MASK_RELOCATABLE | MASK_MINIMAL_TOC;
4428 target_flags_explicit |= MASK_RELOCATABLE | MASK_MINIMAL_TOC;
4429 TARGET_NO_FP_IN_TOC = 1;
4431 else
4433 target_flags &= ~MASK_RELOCATABLE;
4434 target_flags_explicit |= MASK_RELOCATABLE;
4436 break;
4437 #endif
4439 case OPT_mabi_:
4440 if (!strcmp (arg, "altivec"))
4442 rs6000_explicit_options.altivec_abi = true;
4443 rs6000_altivec_abi = 1;
4445 /* Enabling the AltiVec ABI turns off the SPE ABI. */
4446 rs6000_spe_abi = 0;
4448 else if (! strcmp (arg, "no-altivec"))
4450 rs6000_explicit_options.altivec_abi = true;
4451 rs6000_altivec_abi = 0;
4453 else if (! strcmp (arg, "spe"))
4455 rs6000_explicit_options.spe_abi = true;
4456 rs6000_spe_abi = 1;
4457 rs6000_altivec_abi = 0;
4458 if (!TARGET_SPE_ABI)
4459 error ("not configured for ABI: '%s'", arg);
4461 else if (! strcmp (arg, "no-spe"))
4463 rs6000_explicit_options.spe_abi = true;
4464 rs6000_spe_abi = 0;
4467 /* These are here for testing during development only, do not
4468 document in the manual please. */
4469 else if (! strcmp (arg, "d64"))
4471 rs6000_darwin64_abi = 1;
4472 warning (0, "using darwin64 ABI");
4474 else if (! strcmp (arg, "d32"))
4476 rs6000_darwin64_abi = 0;
4477 warning (0, "using old darwin ABI");
4480 else if (! strcmp (arg, "ibmlongdouble"))
4482 rs6000_explicit_options.ieee = true;
4483 rs6000_ieeequad = 0;
4484 warning (0, "using IBM extended precision long double");
4486 else if (! strcmp (arg, "ieeelongdouble"))
4488 rs6000_explicit_options.ieee = true;
4489 rs6000_ieeequad = 1;
4490 warning (0, "using IEEE extended precision long double");
4493 else
4495 error ("unknown ABI specified: '%s'", arg);
4496 return false;
4498 break;
4500 case OPT_mcpu_:
4501 rs6000_select[1].string = arg;
4502 rs6000_cpu_index = rs6000_cpu_name_lookup (arg);
4503 if (rs6000_cpu_index < 0)
4504 error ("bad value (%s) for -mcpu", arg);
4505 break;
4507 case OPT_mtune_:
4508 rs6000_select[2].string = arg;
4509 rs6000_tune_index = rs6000_cpu_name_lookup (arg);
4510 if (rs6000_tune_index < 0)
4511 error ("bad value (%s) for -mtune", arg);
4512 break;
4514 case OPT_mtraceback_:
4515 if (! strncmp (arg, "full", 4))
4516 rs6000_traceback = traceback_full;
4517 else if (! strncmp (arg, "part", 4))
4518 rs6000_traceback = traceback_part;
4519 else if (! strncmp (arg, "no", 2))
4520 rs6000_traceback = traceback_none;
4521 else
4522 error ("unknown -mtraceback arg %qs; expecting %<full%>, "
4523 "%<partial%> or %<none%>", arg);
4524 break;
4526 case OPT_mfloat_gprs_:
4527 rs6000_explicit_options.float_gprs = true;
4528 if (! strcmp (arg, "yes") || ! strcmp (arg, "single"))
4529 rs6000_float_gprs = 1;
4530 else if (! strcmp (arg, "double"))
4531 rs6000_float_gprs = 2;
4532 else if (! strcmp (arg, "no"))
4533 rs6000_float_gprs = 0;
4534 else
4536 error ("invalid option for -mfloat-gprs: '%s'", arg);
4537 return false;
4539 break;
4541 case OPT_mlong_double_:
4542 rs6000_explicit_options.long_double = true;
4543 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
4544 if (value != 64 && value != 128)
4546 error ("unknown switch -mlong-double-%s", arg);
4547 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
4548 return false;
4550 else
4551 rs6000_long_double_type_size = value;
4552 break;
4554 case OPT_msched_costly_dep_:
4555 rs6000_sched_costly_dep_str = arg;
4556 break;
4558 case OPT_malign_:
4559 rs6000_explicit_options.alignment = true;
4560 if (! strcmp (arg, "power"))
4562 /* On 64-bit Darwin, power alignment is ABI-incompatible with
4563 some C library functions, so warn about it. The flag may be
4564 useful for performance studies from time to time though, so
4565 don't disable it entirely. */
4566 if (DEFAULT_ABI == ABI_DARWIN && TARGET_64BIT)
4567 warning (0, "-malign-power is not supported for 64-bit Darwin;"
4568 " it is incompatible with the installed C and C++ libraries");
4569 rs6000_alignment_flags = MASK_ALIGN_POWER;
4571 else if (! strcmp (arg, "natural"))
4572 rs6000_alignment_flags = MASK_ALIGN_NATURAL;
4573 else
4575 error ("unknown -malign-XXXXX option specified: '%s'", arg);
4576 return false;
4578 break;
4580 case OPT_msingle_float:
4581 if (!TARGET_SINGLE_FPU)
4582 warning (0, "-msingle-float option equivalent to -mhard-float");
4583 /* -msingle-float implies -mno-double-float and TARGET_HARD_FLOAT. */
4584 rs6000_double_float = 0;
4585 target_flags &= ~MASK_SOFT_FLOAT;
4586 target_flags_explicit |= MASK_SOFT_FLOAT;
4587 break;
4589 case OPT_mdouble_float:
4590 /* -mdouble-float implies -msingle-float and TARGET_HARD_FLOAT. */
4591 rs6000_single_float = 1;
4592 target_flags &= ~MASK_SOFT_FLOAT;
4593 target_flags_explicit |= MASK_SOFT_FLOAT;
4594 break;
4596 case OPT_msimple_fpu:
4597 if (!TARGET_SINGLE_FPU)
4598 warning (0, "-msimple-fpu option ignored");
4599 break;
4601 case OPT_mhard_float:
4602 /* -mhard_float implies -msingle-float and -mdouble-float. */
4603 rs6000_single_float = rs6000_double_float = 1;
4604 break;
4606 case OPT_msoft_float:
4607 /* -msoft_float implies -mnosingle-float and -mnodouble-float. */
4608 rs6000_single_float = rs6000_double_float = 0;
4609 break;
4611 case OPT_mfpu_:
4612 fpu_type = rs6000_parse_fpu_option(arg);
4613 if (fpu_type != FPU_NONE)
4614 /* If -mfpu is not none, then turn off SOFT_FLOAT, turn on HARD_FLOAT. */
4616 target_flags &= ~MASK_SOFT_FLOAT;
4617 target_flags_explicit |= MASK_SOFT_FLOAT;
4618 rs6000_xilinx_fpu = 1;
4619 if (fpu_type == FPU_SF_LITE || fpu_type == FPU_SF_FULL)
4620 rs6000_single_float = 1;
4621 if (fpu_type == FPU_DF_LITE || fpu_type == FPU_DF_FULL)
4622 rs6000_single_float = rs6000_double_float = 1;
4623 if (fpu_type == FPU_SF_LITE || fpu_type == FPU_DF_LITE)
4624 rs6000_simple_fpu = 1;
4626 else
4628 /* -mfpu=none is equivalent to -msoft-float */
4629 target_flags |= MASK_SOFT_FLOAT;
4630 target_flags_explicit |= MASK_SOFT_FLOAT;
4631 rs6000_single_float = rs6000_double_float = 0;
4634 case OPT_mrecip:
4635 rs6000_recip_name = (value) ? "default" : "none";
4636 break;
4638 case OPT_mrecip_:
4639 rs6000_recip_name = arg;
4640 break;
4642 return true;
4645 /* Do anything needed at the start of the asm file. */
4647 static void
4648 rs6000_file_start (void)
4650 size_t i;
4651 char buffer[80];
4652 const char *start = buffer;
4653 struct rs6000_cpu_select *ptr;
4654 const char *default_cpu = TARGET_CPU_DEFAULT;
4655 FILE *file = asm_out_file;
4657 default_file_start ();
4659 #ifdef TARGET_BI_ARCH
4660 if ((TARGET_DEFAULT ^ target_flags) & MASK_64BIT)
4661 default_cpu = 0;
4662 #endif
4664 if (flag_verbose_asm)
4666 sprintf (buffer, "\n%s rs6000/powerpc options:", ASM_COMMENT_START);
4667 rs6000_select[0].string = default_cpu;
4669 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
4671 ptr = &rs6000_select[i];
4672 if (ptr->string != (char *)0 && ptr->string[0] != '\0')
4674 fprintf (file, "%s %s%s", start, ptr->name, ptr->string);
4675 start = "";
4679 if (PPC405_ERRATUM77)
4681 fprintf (file, "%s PPC405CR_ERRATUM77", start);
4682 start = "";
4685 #ifdef USING_ELFOS_H
4686 switch (rs6000_sdata)
4688 case SDATA_NONE: fprintf (file, "%s -msdata=none", start); start = ""; break;
4689 case SDATA_DATA: fprintf (file, "%s -msdata=data", start); start = ""; break;
4690 case SDATA_SYSV: fprintf (file, "%s -msdata=sysv", start); start = ""; break;
4691 case SDATA_EABI: fprintf (file, "%s -msdata=eabi", start); start = ""; break;
4694 if (rs6000_sdata && g_switch_value)
4696 fprintf (file, "%s -G %d", start,
4697 g_switch_value);
4698 start = "";
4700 #endif
4702 if (*start == '\0')
4703 putc ('\n', file);
4706 if (DEFAULT_ABI == ABI_AIX || (TARGET_ELF && flag_pic == 2))
4708 switch_to_section (toc_section);
4709 switch_to_section (text_section);
4714 /* Return nonzero if this function is known to have a null epilogue. */
4717 direct_return (void)
4719 if (reload_completed)
4721 rs6000_stack_t *info = rs6000_stack_info ();
4723 if (info->first_gp_reg_save == 32
4724 && info->first_fp_reg_save == 64
4725 && info->first_altivec_reg_save == LAST_ALTIVEC_REGNO + 1
4726 && ! info->lr_save_p
4727 && ! info->cr_save_p
4728 && info->vrsave_mask == 0
4729 && ! info->push_p)
4730 return 1;
4733 return 0;
4736 /* Return the number of instructions it takes to form a constant in an
4737 integer register. */
4740 num_insns_constant_wide (HOST_WIDE_INT value)
4742 /* signed constant loadable with {cal|addi} */
4743 if ((unsigned HOST_WIDE_INT) (value + 0x8000) < 0x10000)
4744 return 1;
4746 /* constant loadable with {cau|addis} */
4747 else if ((value & 0xffff) == 0
4748 && (value >> 31 == -1 || value >> 31 == 0))
4749 return 1;
4751 #if HOST_BITS_PER_WIDE_INT == 64
4752 else if (TARGET_POWERPC64)
4754 HOST_WIDE_INT low = ((value & 0xffffffff) ^ 0x80000000) - 0x80000000;
4755 HOST_WIDE_INT high = value >> 31;
4757 if (high == 0 || high == -1)
4758 return 2;
4760 high >>= 1;
4762 if (low == 0)
4763 return num_insns_constant_wide (high) + 1;
4764 else if (high == 0)
4765 return num_insns_constant_wide (low) + 1;
4766 else
4767 return (num_insns_constant_wide (high)
4768 + num_insns_constant_wide (low) + 1);
4770 #endif
4772 else
4773 return 2;
4777 num_insns_constant (rtx op, enum machine_mode mode)
4779 HOST_WIDE_INT low, high;
4781 switch (GET_CODE (op))
4783 case CONST_INT:
4784 #if HOST_BITS_PER_WIDE_INT == 64
4785 if ((INTVAL (op) >> 31) != 0 && (INTVAL (op) >> 31) != -1
4786 && mask64_operand (op, mode))
4787 return 2;
4788 else
4789 #endif
4790 return num_insns_constant_wide (INTVAL (op));
4792 case CONST_DOUBLE:
4793 if (mode == SFmode || mode == SDmode)
4795 long l;
4796 REAL_VALUE_TYPE rv;
4798 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
4799 if (DECIMAL_FLOAT_MODE_P (mode))
4800 REAL_VALUE_TO_TARGET_DECIMAL32 (rv, l);
4801 else
4802 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
4803 return num_insns_constant_wide ((HOST_WIDE_INT) l);
4806 if (mode == VOIDmode || mode == DImode)
4808 high = CONST_DOUBLE_HIGH (op);
4809 low = CONST_DOUBLE_LOW (op);
4811 else
4813 long l[2];
4814 REAL_VALUE_TYPE rv;
4816 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
4817 if (DECIMAL_FLOAT_MODE_P (mode))
4818 REAL_VALUE_TO_TARGET_DECIMAL64 (rv, l);
4819 else
4820 REAL_VALUE_TO_TARGET_DOUBLE (rv, l);
4821 high = l[WORDS_BIG_ENDIAN == 0];
4822 low = l[WORDS_BIG_ENDIAN != 0];
4825 if (TARGET_32BIT)
4826 return (num_insns_constant_wide (low)
4827 + num_insns_constant_wide (high));
4828 else
4830 if ((high == 0 && low >= 0)
4831 || (high == -1 && low < 0))
4832 return num_insns_constant_wide (low);
4834 else if (mask64_operand (op, mode))
4835 return 2;
4837 else if (low == 0)
4838 return num_insns_constant_wide (high) + 1;
4840 else
4841 return (num_insns_constant_wide (high)
4842 + num_insns_constant_wide (low) + 1);
4845 default:
4846 gcc_unreachable ();
4850 /* Interpret element ELT of the CONST_VECTOR OP as an integer value.
4851 If the mode of OP is MODE_VECTOR_INT, this simply returns the
4852 corresponding element of the vector, but for V4SFmode and V2SFmode,
4853 the corresponding "float" is interpreted as an SImode integer. */
4855 HOST_WIDE_INT
4856 const_vector_elt_as_int (rtx op, unsigned int elt)
4858 rtx tmp;
4860 /* We can't handle V2DImode and V2DFmode vector constants here yet. */
4861 gcc_assert (GET_MODE (op) != V2DImode
4862 && GET_MODE (op) != V2DFmode);
4864 tmp = CONST_VECTOR_ELT (op, elt);
4865 if (GET_MODE (op) == V4SFmode
4866 || GET_MODE (op) == V2SFmode)
4867 tmp = gen_lowpart (SImode, tmp);
4868 return INTVAL (tmp);
4871 /* Return true if OP can be synthesized with a particular vspltisb, vspltish
4872 or vspltisw instruction. OP is a CONST_VECTOR. Which instruction is used
4873 depends on STEP and COPIES, one of which will be 1. If COPIES > 1,
4874 all items are set to the same value and contain COPIES replicas of the
4875 vsplt's operand; if STEP > 1, one in STEP elements is set to the vsplt's
4876 operand and the others are set to the value of the operand's msb. */
4878 static bool
4879 vspltis_constant (rtx op, unsigned step, unsigned copies)
4881 enum machine_mode mode = GET_MODE (op);
4882 enum machine_mode inner = GET_MODE_INNER (mode);
4884 unsigned i;
4885 unsigned nunits;
4886 unsigned bitsize;
4887 unsigned mask;
4889 HOST_WIDE_INT val;
4890 HOST_WIDE_INT splat_val;
4891 HOST_WIDE_INT msb_val;
4893 if (mode == V2DImode || mode == V2DFmode)
4894 return false;
4896 nunits = GET_MODE_NUNITS (mode);
4897 bitsize = GET_MODE_BITSIZE (inner);
4898 mask = GET_MODE_MASK (inner);
4900 val = const_vector_elt_as_int (op, nunits - 1);
4901 splat_val = val;
4902 msb_val = val > 0 ? 0 : -1;
4904 /* Construct the value to be splatted, if possible. If not, return 0. */
4905 for (i = 2; i <= copies; i *= 2)
4907 HOST_WIDE_INT small_val;
4908 bitsize /= 2;
4909 small_val = splat_val >> bitsize;
4910 mask >>= bitsize;
4911 if (splat_val != ((small_val << bitsize) | (small_val & mask)))
4912 return false;
4913 splat_val = small_val;
4916 /* Check if SPLAT_VAL can really be the operand of a vspltis[bhw]. */
4917 if (EASY_VECTOR_15 (splat_val))
4920 /* Also check if we can splat, and then add the result to itself. Do so if
4921 the value is positive, of if the splat instruction is using OP's mode;
4922 for splat_val < 0, the splat and the add should use the same mode. */
4923 else if (EASY_VECTOR_15_ADD_SELF (splat_val)
4924 && (splat_val >= 0 || (step == 1 && copies == 1)))
4927 /* Also check if are loading up the most significant bit which can be done by
4928 loading up -1 and shifting the value left by -1. */
4929 else if (EASY_VECTOR_MSB (splat_val, inner))
4932 else
4933 return false;
4935 /* Check if VAL is present in every STEP-th element, and the
4936 other elements are filled with its most significant bit. */
4937 for (i = 0; i < nunits - 1; ++i)
4939 HOST_WIDE_INT desired_val;
4940 if (((i + 1) & (step - 1)) == 0)
4941 desired_val = val;
4942 else
4943 desired_val = msb_val;
4945 if (desired_val != const_vector_elt_as_int (op, i))
4946 return false;
4949 return true;
4953 /* Return true if OP is of the given MODE and can be synthesized
4954 with a vspltisb, vspltish or vspltisw. */
4956 bool
4957 easy_altivec_constant (rtx op, enum machine_mode mode)
4959 unsigned step, copies;
4961 if (mode == VOIDmode)
4962 mode = GET_MODE (op);
4963 else if (mode != GET_MODE (op))
4964 return false;
4966 /* V2DI/V2DF was added with VSX. Only allow 0 and all 1's as easy
4967 constants. */
4968 if (mode == V2DFmode)
4969 return zero_constant (op, mode);
4971 if (mode == V2DImode)
4973 /* In case the compiler is built 32-bit, CONST_DOUBLE constants are not
4974 easy. */
4975 if (GET_CODE (CONST_VECTOR_ELT (op, 0)) != CONST_INT
4976 || GET_CODE (CONST_VECTOR_ELT (op, 1)) != CONST_INT)
4977 return false;
4979 if (zero_constant (op, mode))
4980 return true;
4982 if (INTVAL (CONST_VECTOR_ELT (op, 0)) == -1
4983 && INTVAL (CONST_VECTOR_ELT (op, 1)) == -1)
4984 return true;
4986 return false;
4989 /* Start with a vspltisw. */
4990 step = GET_MODE_NUNITS (mode) / 4;
4991 copies = 1;
4993 if (vspltis_constant (op, step, copies))
4994 return true;
4996 /* Then try with a vspltish. */
4997 if (step == 1)
4998 copies <<= 1;
4999 else
5000 step >>= 1;
5002 if (vspltis_constant (op, step, copies))
5003 return true;
5005 /* And finally a vspltisb. */
5006 if (step == 1)
5007 copies <<= 1;
5008 else
5009 step >>= 1;
5011 if (vspltis_constant (op, step, copies))
5012 return true;
5014 return false;
5017 /* Generate a VEC_DUPLICATE representing a vspltis[bhw] instruction whose
5018 result is OP. Abort if it is not possible. */
5021 gen_easy_altivec_constant (rtx op)
5023 enum machine_mode mode = GET_MODE (op);
5024 int nunits = GET_MODE_NUNITS (mode);
5025 rtx last = CONST_VECTOR_ELT (op, nunits - 1);
5026 unsigned step = nunits / 4;
5027 unsigned copies = 1;
5029 /* Start with a vspltisw. */
5030 if (vspltis_constant (op, step, copies))
5031 return gen_rtx_VEC_DUPLICATE (V4SImode, gen_lowpart (SImode, last));
5033 /* Then try with a vspltish. */
5034 if (step == 1)
5035 copies <<= 1;
5036 else
5037 step >>= 1;
5039 if (vspltis_constant (op, step, copies))
5040 return gen_rtx_VEC_DUPLICATE (V8HImode, gen_lowpart (HImode, last));
5042 /* And finally a vspltisb. */
5043 if (step == 1)
5044 copies <<= 1;
5045 else
5046 step >>= 1;
5048 if (vspltis_constant (op, step, copies))
5049 return gen_rtx_VEC_DUPLICATE (V16QImode, gen_lowpart (QImode, last));
5051 gcc_unreachable ();
5054 const char *
5055 output_vec_const_move (rtx *operands)
5057 int cst, cst2;
5058 enum machine_mode mode;
5059 rtx dest, vec;
5061 dest = operands[0];
5062 vec = operands[1];
5063 mode = GET_MODE (dest);
5065 if (TARGET_VSX)
5067 if (zero_constant (vec, mode))
5068 return "xxlxor %x0,%x0,%x0";
5070 if (mode == V2DImode
5071 && INTVAL (CONST_VECTOR_ELT (vec, 0)) == -1
5072 && INTVAL (CONST_VECTOR_ELT (vec, 1)) == -1)
5073 return "vspltisw %0,-1";
5076 if (TARGET_ALTIVEC)
5078 rtx splat_vec;
5079 if (zero_constant (vec, mode))
5080 return "vxor %0,%0,%0";
5082 splat_vec = gen_easy_altivec_constant (vec);
5083 gcc_assert (GET_CODE (splat_vec) == VEC_DUPLICATE);
5084 operands[1] = XEXP (splat_vec, 0);
5085 if (!EASY_VECTOR_15 (INTVAL (operands[1])))
5086 return "#";
5088 switch (GET_MODE (splat_vec))
5090 case V4SImode:
5091 return "vspltisw %0,%1";
5093 case V8HImode:
5094 return "vspltish %0,%1";
5096 case V16QImode:
5097 return "vspltisb %0,%1";
5099 default:
5100 gcc_unreachable ();
5104 gcc_assert (TARGET_SPE);
5106 /* Vector constant 0 is handled as a splitter of V2SI, and in the
5107 pattern of V1DI, V4HI, and V2SF.
5109 FIXME: We should probably return # and add post reload
5110 splitters for these, but this way is so easy ;-). */
5111 cst = INTVAL (CONST_VECTOR_ELT (vec, 0));
5112 cst2 = INTVAL (CONST_VECTOR_ELT (vec, 1));
5113 operands[1] = CONST_VECTOR_ELT (vec, 0);
5114 operands[2] = CONST_VECTOR_ELT (vec, 1);
5115 if (cst == cst2)
5116 return "li %0,%1\n\tevmergelo %0,%0,%0";
5117 else
5118 return "li %0,%1\n\tevmergelo %0,%0,%0\n\tli %0,%2";
5121 /* Initialize TARGET of vector PAIRED to VALS. */
5123 void
5124 paired_expand_vector_init (rtx target, rtx vals)
5126 enum machine_mode mode = GET_MODE (target);
5127 int n_elts = GET_MODE_NUNITS (mode);
5128 int n_var = 0;
5129 rtx x, new_rtx, tmp, constant_op, op1, op2;
5130 int i;
5132 for (i = 0; i < n_elts; ++i)
5134 x = XVECEXP (vals, 0, i);
5135 if (!CONSTANT_P (x))
5136 ++n_var;
5138 if (n_var == 0)
5140 /* Load from constant pool. */
5141 emit_move_insn (target, gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0)));
5142 return;
5145 if (n_var == 2)
5147 /* The vector is initialized only with non-constants. */
5148 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, XVECEXP (vals, 0, 0),
5149 XVECEXP (vals, 0, 1));
5151 emit_move_insn (target, new_rtx);
5152 return;
5155 /* One field is non-constant and the other one is a constant. Load the
5156 constant from the constant pool and use ps_merge instruction to
5157 construct the whole vector. */
5158 op1 = XVECEXP (vals, 0, 0);
5159 op2 = XVECEXP (vals, 0, 1);
5161 constant_op = (CONSTANT_P (op1)) ? op1 : op2;
5163 tmp = gen_reg_rtx (GET_MODE (constant_op));
5164 emit_move_insn (tmp, constant_op);
5166 if (CONSTANT_P (op1))
5167 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, tmp, op2);
5168 else
5169 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, op1, tmp);
5171 emit_move_insn (target, new_rtx);
5174 void
5175 paired_expand_vector_move (rtx operands[])
5177 rtx op0 = operands[0], op1 = operands[1];
5179 emit_move_insn (op0, op1);
5182 /* Emit vector compare for code RCODE. DEST is destination, OP1 and
5183 OP2 are two VEC_COND_EXPR operands, CC_OP0 and CC_OP1 are the two
5184 operands for the relation operation COND. This is a recursive
5185 function. */
5187 static void
5188 paired_emit_vector_compare (enum rtx_code rcode,
5189 rtx dest, rtx op0, rtx op1,
5190 rtx cc_op0, rtx cc_op1)
5192 rtx tmp = gen_reg_rtx (V2SFmode);
5193 rtx tmp1, max, min;
5195 gcc_assert (TARGET_PAIRED_FLOAT);
5196 gcc_assert (GET_MODE (op0) == GET_MODE (op1));
5198 switch (rcode)
5200 case LT:
5201 case LTU:
5202 paired_emit_vector_compare (GE, dest, op1, op0, cc_op0, cc_op1);
5203 return;
5204 case GE:
5205 case GEU:
5206 emit_insn (gen_subv2sf3 (tmp, cc_op0, cc_op1));
5207 emit_insn (gen_selv2sf4 (dest, tmp, op0, op1, CONST0_RTX (SFmode)));
5208 return;
5209 case LE:
5210 case LEU:
5211 paired_emit_vector_compare (GE, dest, op0, op1, cc_op1, cc_op0);
5212 return;
5213 case GT:
5214 paired_emit_vector_compare (LE, dest, op1, op0, cc_op0, cc_op1);
5215 return;
5216 case EQ:
5217 tmp1 = gen_reg_rtx (V2SFmode);
5218 max = gen_reg_rtx (V2SFmode);
5219 min = gen_reg_rtx (V2SFmode);
5220 gen_reg_rtx (V2SFmode);
5222 emit_insn (gen_subv2sf3 (tmp, cc_op0, cc_op1));
5223 emit_insn (gen_selv2sf4
5224 (max, tmp, cc_op0, cc_op1, CONST0_RTX (SFmode)));
5225 emit_insn (gen_subv2sf3 (tmp, cc_op1, cc_op0));
5226 emit_insn (gen_selv2sf4
5227 (min, tmp, cc_op0, cc_op1, CONST0_RTX (SFmode)));
5228 emit_insn (gen_subv2sf3 (tmp1, min, max));
5229 emit_insn (gen_selv2sf4 (dest, tmp1, op0, op1, CONST0_RTX (SFmode)));
5230 return;
5231 case NE:
5232 paired_emit_vector_compare (EQ, dest, op1, op0, cc_op0, cc_op1);
5233 return;
5234 case UNLE:
5235 paired_emit_vector_compare (LE, dest, op1, op0, cc_op0, cc_op1);
5236 return;
5237 case UNLT:
5238 paired_emit_vector_compare (LT, dest, op1, op0, cc_op0, cc_op1);
5239 return;
5240 case UNGE:
5241 paired_emit_vector_compare (GE, dest, op1, op0, cc_op0, cc_op1);
5242 return;
5243 case UNGT:
5244 paired_emit_vector_compare (GT, dest, op1, op0, cc_op0, cc_op1);
5245 return;
5246 default:
5247 gcc_unreachable ();
5250 return;
5253 /* Emit vector conditional expression.
5254 DEST is destination. OP1 and OP2 are two VEC_COND_EXPR operands.
5255 CC_OP0 and CC_OP1 are the two operands for the relation operation COND. */
5258 paired_emit_vector_cond_expr (rtx dest, rtx op1, rtx op2,
5259 rtx cond, rtx cc_op0, rtx cc_op1)
5261 enum rtx_code rcode = GET_CODE (cond);
5263 if (!TARGET_PAIRED_FLOAT)
5264 return 0;
5266 paired_emit_vector_compare (rcode, dest, op1, op2, cc_op0, cc_op1);
5268 return 1;
5271 /* Initialize vector TARGET to VALS. */
5273 void
5274 rs6000_expand_vector_init (rtx target, rtx vals)
5276 enum machine_mode mode = GET_MODE (target);
5277 enum machine_mode inner_mode = GET_MODE_INNER (mode);
5278 int n_elts = GET_MODE_NUNITS (mode);
5279 int n_var = 0, one_var = -1;
5280 bool all_same = true, all_const_zero = true;
5281 rtx x, mem;
5282 int i;
5284 for (i = 0; i < n_elts; ++i)
5286 x = XVECEXP (vals, 0, i);
5287 if (!CONSTANT_P (x))
5288 ++n_var, one_var = i;
5289 else if (x != CONST0_RTX (inner_mode))
5290 all_const_zero = false;
5292 if (i > 0 && !rtx_equal_p (x, XVECEXP (vals, 0, 0)))
5293 all_same = false;
5296 if (n_var == 0)
5298 rtx const_vec = gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0));
5299 bool int_vector_p = (GET_MODE_CLASS (mode) == MODE_VECTOR_INT);
5300 if ((int_vector_p || TARGET_VSX) && all_const_zero)
5302 /* Zero register. */
5303 emit_insn (gen_rtx_SET (VOIDmode, target,
5304 gen_rtx_XOR (mode, target, target)));
5305 return;
5307 else if (int_vector_p && easy_vector_constant (const_vec, mode))
5309 /* Splat immediate. */
5310 emit_insn (gen_rtx_SET (VOIDmode, target, const_vec));
5311 return;
5313 else
5315 /* Load from constant pool. */
5316 emit_move_insn (target, const_vec);
5317 return;
5321 /* Double word values on VSX can use xxpermdi or lxvdsx. */
5322 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
5324 if (all_same)
5326 rtx element = XVECEXP (vals, 0, 0);
5327 if (mode == V2DFmode)
5328 emit_insn (gen_vsx_splat_v2df (target, element));
5329 else
5330 emit_insn (gen_vsx_splat_v2di (target, element));
5332 else
5334 if (mode == V2DFmode)
5336 rtx op0 = copy_to_mode_reg (DFmode, XVECEXP (vals, 0, 0));
5337 rtx op1 = copy_to_mode_reg (DFmode, XVECEXP (vals, 0, 1));
5338 emit_insn (gen_vsx_concat_v2df (target, op0, op1));
5340 else
5342 rtx op0 = copy_to_mode_reg (DImode, XVECEXP (vals, 0, 0));
5343 rtx op1 = copy_to_mode_reg (DImode, XVECEXP (vals, 0, 1));
5344 emit_insn (gen_vsx_concat_v2di (target, op0, op1));
5347 return;
5350 /* With single precision floating point on VSX, know that internally single
5351 precision is actually represented as a double, and either make 2 V2DF
5352 vectors, and convert these vectors to single precision, or do one
5353 conversion, and splat the result to the other elements. */
5354 if (mode == V4SFmode && VECTOR_MEM_VSX_P (mode))
5356 if (all_same)
5358 rtx freg = gen_reg_rtx (V4SFmode);
5359 rtx sreg = copy_to_reg (XVECEXP (vals, 0, 0));
5361 emit_insn (gen_vsx_xscvdpsp_scalar (freg, sreg));
5362 emit_insn (gen_vsx_xxspltw_v4sf (target, freg, const0_rtx));
5364 else
5366 rtx dbl_even = gen_reg_rtx (V2DFmode);
5367 rtx dbl_odd = gen_reg_rtx (V2DFmode);
5368 rtx flt_even = gen_reg_rtx (V4SFmode);
5369 rtx flt_odd = gen_reg_rtx (V4SFmode);
5371 emit_insn (gen_vsx_concat_v2sf (dbl_even,
5372 copy_to_reg (XVECEXP (vals, 0, 0)),
5373 copy_to_reg (XVECEXP (vals, 0, 1))));
5374 emit_insn (gen_vsx_concat_v2sf (dbl_odd,
5375 copy_to_reg (XVECEXP (vals, 0, 2)),
5376 copy_to_reg (XVECEXP (vals, 0, 3))));
5377 emit_insn (gen_vsx_xvcvdpsp (flt_even, dbl_even));
5378 emit_insn (gen_vsx_xvcvdpsp (flt_odd, dbl_odd));
5379 emit_insn (gen_vec_extract_evenv4sf (target, flt_even, flt_odd));
5381 return;
5384 /* Store value to stack temp. Load vector element. Splat. However, splat
5385 of 64-bit items is not supported on Altivec. */
5386 if (all_same && GET_MODE_SIZE (mode) <= 4)
5388 mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0);
5389 emit_move_insn (adjust_address_nv (mem, inner_mode, 0),
5390 XVECEXP (vals, 0, 0));
5391 x = gen_rtx_UNSPEC (VOIDmode,
5392 gen_rtvec (1, const0_rtx), UNSPEC_LVE);
5393 emit_insn (gen_rtx_PARALLEL (VOIDmode,
5394 gen_rtvec (2,
5395 gen_rtx_SET (VOIDmode,
5396 target, mem),
5397 x)));
5398 x = gen_rtx_VEC_SELECT (inner_mode, target,
5399 gen_rtx_PARALLEL (VOIDmode,
5400 gen_rtvec (1, const0_rtx)));
5401 emit_insn (gen_rtx_SET (VOIDmode, target,
5402 gen_rtx_VEC_DUPLICATE (mode, x)));
5403 return;
5406 /* One field is non-constant. Load constant then overwrite
5407 varying field. */
5408 if (n_var == 1)
5410 rtx copy = copy_rtx (vals);
5412 /* Load constant part of vector, substitute neighboring value for
5413 varying element. */
5414 XVECEXP (copy, 0, one_var) = XVECEXP (vals, 0, (one_var + 1) % n_elts);
5415 rs6000_expand_vector_init (target, copy);
5417 /* Insert variable. */
5418 rs6000_expand_vector_set (target, XVECEXP (vals, 0, one_var), one_var);
5419 return;
5422 /* Construct the vector in memory one field at a time
5423 and load the whole vector. */
5424 mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
5425 for (i = 0; i < n_elts; i++)
5426 emit_move_insn (adjust_address_nv (mem, inner_mode,
5427 i * GET_MODE_SIZE (inner_mode)),
5428 XVECEXP (vals, 0, i));
5429 emit_move_insn (target, mem);
5432 /* Set field ELT of TARGET to VAL. */
5434 void
5435 rs6000_expand_vector_set (rtx target, rtx val, int elt)
5437 enum machine_mode mode = GET_MODE (target);
5438 enum machine_mode inner_mode = GET_MODE_INNER (mode);
5439 rtx reg = gen_reg_rtx (mode);
5440 rtx mask, mem, x;
5441 int width = GET_MODE_SIZE (inner_mode);
5442 int i;
5444 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
5446 rtx (*set_func) (rtx, rtx, rtx, rtx)
5447 = ((mode == V2DFmode) ? gen_vsx_set_v2df : gen_vsx_set_v2di);
5448 emit_insn (set_func (target, target, val, GEN_INT (elt)));
5449 return;
5452 /* Load single variable value. */
5453 mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0);
5454 emit_move_insn (adjust_address_nv (mem, inner_mode, 0), val);
5455 x = gen_rtx_UNSPEC (VOIDmode,
5456 gen_rtvec (1, const0_rtx), UNSPEC_LVE);
5457 emit_insn (gen_rtx_PARALLEL (VOIDmode,
5458 gen_rtvec (2,
5459 gen_rtx_SET (VOIDmode,
5460 reg, mem),
5461 x)));
5463 /* Linear sequence. */
5464 mask = gen_rtx_PARALLEL (V16QImode, rtvec_alloc (16));
5465 for (i = 0; i < 16; ++i)
5466 XVECEXP (mask, 0, i) = GEN_INT (i);
5468 /* Set permute mask to insert element into target. */
5469 for (i = 0; i < width; ++i)
5470 XVECEXP (mask, 0, elt*width + i)
5471 = GEN_INT (i + 0x10);
5472 x = gen_rtx_CONST_VECTOR (V16QImode, XVEC (mask, 0));
5473 x = gen_rtx_UNSPEC (mode,
5474 gen_rtvec (3, target, reg,
5475 force_reg (V16QImode, x)),
5476 UNSPEC_VPERM);
5477 emit_insn (gen_rtx_SET (VOIDmode, target, x));
5480 /* Extract field ELT from VEC into TARGET. */
5482 void
5483 rs6000_expand_vector_extract (rtx target, rtx vec, int elt)
5485 enum machine_mode mode = GET_MODE (vec);
5486 enum machine_mode inner_mode = GET_MODE_INNER (mode);
5487 rtx mem;
5489 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
5491 rtx (*extract_func) (rtx, rtx, rtx)
5492 = ((mode == V2DFmode) ? gen_vsx_extract_v2df : gen_vsx_extract_v2di);
5493 emit_insn (extract_func (target, vec, GEN_INT (elt)));
5494 return;
5497 /* Allocate mode-sized buffer. */
5498 mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
5500 emit_move_insn (mem, vec);
5502 /* Add offset to field within buffer matching vector element. */
5503 mem = adjust_address_nv (mem, inner_mode, elt * GET_MODE_SIZE (inner_mode));
5505 emit_move_insn (target, adjust_address_nv (mem, inner_mode, 0));
5508 /* Generates shifts and masks for a pair of rldicl or rldicr insns to
5509 implement ANDing by the mask IN. */
5510 void
5511 build_mask64_2_operands (rtx in, rtx *out)
5513 #if HOST_BITS_PER_WIDE_INT >= 64
5514 unsigned HOST_WIDE_INT c, lsb, m1, m2;
5515 int shift;
5517 gcc_assert (GET_CODE (in) == CONST_INT);
5519 c = INTVAL (in);
5520 if (c & 1)
5522 /* Assume c initially something like 0x00fff000000fffff. The idea
5523 is to rotate the word so that the middle ^^^^^^ group of zeros
5524 is at the MS end and can be cleared with an rldicl mask. We then
5525 rotate back and clear off the MS ^^ group of zeros with a
5526 second rldicl. */
5527 c = ~c; /* c == 0xff000ffffff00000 */
5528 lsb = c & -c; /* lsb == 0x0000000000100000 */
5529 m1 = -lsb; /* m1 == 0xfffffffffff00000 */
5530 c = ~c; /* c == 0x00fff000000fffff */
5531 c &= -lsb; /* c == 0x00fff00000000000 */
5532 lsb = c & -c; /* lsb == 0x0000100000000000 */
5533 c = ~c; /* c == 0xff000fffffffffff */
5534 c &= -lsb; /* c == 0xff00000000000000 */
5535 shift = 0;
5536 while ((lsb >>= 1) != 0)
5537 shift++; /* shift == 44 on exit from loop */
5538 m1 <<= 64 - shift; /* m1 == 0xffffff0000000000 */
5539 m1 = ~m1; /* m1 == 0x000000ffffffffff */
5540 m2 = ~c; /* m2 == 0x00ffffffffffffff */
5542 else
5544 /* Assume c initially something like 0xff000f0000000000. The idea
5545 is to rotate the word so that the ^^^ middle group of zeros
5546 is at the LS end and can be cleared with an rldicr mask. We then
5547 rotate back and clear off the LS group of ^^^^^^^^^^ zeros with
5548 a second rldicr. */
5549 lsb = c & -c; /* lsb == 0x0000010000000000 */
5550 m2 = -lsb; /* m2 == 0xffffff0000000000 */
5551 c = ~c; /* c == 0x00fff0ffffffffff */
5552 c &= -lsb; /* c == 0x00fff00000000000 */
5553 lsb = c & -c; /* lsb == 0x0000100000000000 */
5554 c = ~c; /* c == 0xff000fffffffffff */
5555 c &= -lsb; /* c == 0xff00000000000000 */
5556 shift = 0;
5557 while ((lsb >>= 1) != 0)
5558 shift++; /* shift == 44 on exit from loop */
5559 m1 = ~c; /* m1 == 0x00ffffffffffffff */
5560 m1 >>= shift; /* m1 == 0x0000000000000fff */
5561 m1 = ~m1; /* m1 == 0xfffffffffffff000 */
5564 /* Note that when we only have two 0->1 and 1->0 transitions, one of the
5565 masks will be all 1's. We are guaranteed more than one transition. */
5566 out[0] = GEN_INT (64 - shift);
5567 out[1] = GEN_INT (m1);
5568 out[2] = GEN_INT (shift);
5569 out[3] = GEN_INT (m2);
5570 #else
5571 (void)in;
5572 (void)out;
5573 gcc_unreachable ();
5574 #endif
5577 /* Return TRUE if OP is an invalid SUBREG operation on the e500. */
5579 bool
5580 invalid_e500_subreg (rtx op, enum machine_mode mode)
5582 if (TARGET_E500_DOUBLE)
5584 /* Reject (subreg:SI (reg:DF)); likewise with subreg:DI or
5585 subreg:TI and reg:TF. Decimal float modes are like integer
5586 modes (only low part of each register used) for this
5587 purpose. */
5588 if (GET_CODE (op) == SUBREG
5589 && (mode == SImode || mode == DImode || mode == TImode
5590 || mode == DDmode || mode == TDmode)
5591 && REG_P (SUBREG_REG (op))
5592 && (GET_MODE (SUBREG_REG (op)) == DFmode
5593 || GET_MODE (SUBREG_REG (op)) == TFmode))
5594 return true;
5596 /* Reject (subreg:DF (reg:DI)); likewise with subreg:TF and
5597 reg:TI. */
5598 if (GET_CODE (op) == SUBREG
5599 && (mode == DFmode || mode == TFmode)
5600 && REG_P (SUBREG_REG (op))
5601 && (GET_MODE (SUBREG_REG (op)) == DImode
5602 || GET_MODE (SUBREG_REG (op)) == TImode
5603 || GET_MODE (SUBREG_REG (op)) == DDmode
5604 || GET_MODE (SUBREG_REG (op)) == TDmode))
5605 return true;
5608 if (TARGET_SPE
5609 && GET_CODE (op) == SUBREG
5610 && mode == SImode
5611 && REG_P (SUBREG_REG (op))
5612 && SPE_VECTOR_MODE (GET_MODE (SUBREG_REG (op))))
5613 return true;
5615 return false;
5618 /* AIX increases natural record alignment to doubleword if the first
5619 field is an FP double while the FP fields remain word aligned. */
5621 unsigned int
5622 rs6000_special_round_type_align (tree type, unsigned int computed,
5623 unsigned int specified)
5625 unsigned int align = MAX (computed, specified);
5626 tree field = TYPE_FIELDS (type);
5628 /* Skip all non field decls */
5629 while (field != NULL && TREE_CODE (field) != FIELD_DECL)
5630 field = DECL_CHAIN (field);
5632 if (field != NULL && field != type)
5634 type = TREE_TYPE (field);
5635 while (TREE_CODE (type) == ARRAY_TYPE)
5636 type = TREE_TYPE (type);
5638 if (type != error_mark_node && TYPE_MODE (type) == DFmode)
5639 align = MAX (align, 64);
5642 return align;
5645 /* Darwin increases record alignment to the natural alignment of
5646 the first field. */
5648 unsigned int
5649 darwin_rs6000_special_round_type_align (tree type, unsigned int computed,
5650 unsigned int specified)
5652 unsigned int align = MAX (computed, specified);
5654 if (TYPE_PACKED (type))
5655 return align;
5657 /* Find the first field, looking down into aggregates. */
5658 do {
5659 tree field = TYPE_FIELDS (type);
5660 /* Skip all non field decls */
5661 while (field != NULL && TREE_CODE (field) != FIELD_DECL)
5662 field = DECL_CHAIN (field);
5663 if (! field)
5664 break;
5665 /* A packed field does not contribute any extra alignment. */
5666 if (DECL_PACKED (field))
5667 return align;
5668 type = TREE_TYPE (field);
5669 while (TREE_CODE (type) == ARRAY_TYPE)
5670 type = TREE_TYPE (type);
5671 } while (AGGREGATE_TYPE_P (type));
5673 if (! AGGREGATE_TYPE_P (type) && type != error_mark_node)
5674 align = MAX (align, TYPE_ALIGN (type));
5676 return align;
5679 /* Return 1 for an operand in small memory on V.4/eabi. */
5682 small_data_operand (rtx op ATTRIBUTE_UNUSED,
5683 enum machine_mode mode ATTRIBUTE_UNUSED)
5685 #if TARGET_ELF
5686 rtx sym_ref;
5688 if (rs6000_sdata == SDATA_NONE || rs6000_sdata == SDATA_DATA)
5689 return 0;
5691 if (DEFAULT_ABI != ABI_V4)
5692 return 0;
5694 /* Vector and float memory instructions have a limited offset on the
5695 SPE, so using a vector or float variable directly as an operand is
5696 not useful. */
5697 if (TARGET_SPE
5698 && (SPE_VECTOR_MODE (mode) || FLOAT_MODE_P (mode)))
5699 return 0;
5701 if (GET_CODE (op) == SYMBOL_REF)
5702 sym_ref = op;
5704 else if (GET_CODE (op) != CONST
5705 || GET_CODE (XEXP (op, 0)) != PLUS
5706 || GET_CODE (XEXP (XEXP (op, 0), 0)) != SYMBOL_REF
5707 || GET_CODE (XEXP (XEXP (op, 0), 1)) != CONST_INT)
5708 return 0;
5710 else
5712 rtx sum = XEXP (op, 0);
5713 HOST_WIDE_INT summand;
5715 /* We have to be careful here, because it is the referenced address
5716 that must be 32k from _SDA_BASE_, not just the symbol. */
5717 summand = INTVAL (XEXP (sum, 1));
5718 if (summand < 0 || summand > g_switch_value)
5719 return 0;
5721 sym_ref = XEXP (sum, 0);
5724 return SYMBOL_REF_SMALL_P (sym_ref);
5725 #else
5726 return 0;
5727 #endif
5730 /* Return true if either operand is a general purpose register. */
5732 bool
5733 gpr_or_gpr_p (rtx op0, rtx op1)
5735 return ((REG_P (op0) && INT_REGNO_P (REGNO (op0)))
5736 || (REG_P (op1) && INT_REGNO_P (REGNO (op1))));
5740 /* Subroutines of rs6000_legitimize_address and rs6000_legitimate_address_p. */
5742 static bool
5743 reg_offset_addressing_ok_p (enum machine_mode mode)
5745 switch (mode)
5747 case V16QImode:
5748 case V8HImode:
5749 case V4SFmode:
5750 case V4SImode:
5751 case V2DFmode:
5752 case V2DImode:
5753 /* AltiVec/VSX vector modes. Only reg+reg addressing is valid. */
5754 if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode))
5755 return false;
5756 break;
5758 case V4HImode:
5759 case V2SImode:
5760 case V1DImode:
5761 case V2SFmode:
5762 /* Paired vector modes. Only reg+reg addressing is valid. */
5763 if (TARGET_PAIRED_FLOAT)
5764 return false;
5765 break;
5767 default:
5768 break;
5771 return true;
5774 static bool
5775 virtual_stack_registers_memory_p (rtx op)
5777 int regnum;
5779 if (GET_CODE (op) == REG)
5780 regnum = REGNO (op);
5782 else if (GET_CODE (op) == PLUS
5783 && GET_CODE (XEXP (op, 0)) == REG
5784 && GET_CODE (XEXP (op, 1)) == CONST_INT)
5785 regnum = REGNO (XEXP (op, 0));
5787 else
5788 return false;
5790 return (regnum >= FIRST_VIRTUAL_REGISTER
5791 && regnum <= LAST_VIRTUAL_POINTER_REGISTER);
5794 static bool
5795 constant_pool_expr_p (rtx op)
5797 rtx base, offset;
5799 split_const (op, &base, &offset);
5800 return (GET_CODE (base) == SYMBOL_REF
5801 && CONSTANT_POOL_ADDRESS_P (base)
5802 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (base), Pmode));
5805 static rtx tocrel_base, tocrel_offset;
5807 bool
5808 toc_relative_expr_p (rtx op)
5810 if (GET_CODE (op) != CONST)
5811 return false;
5813 split_const (op, &tocrel_base, &tocrel_offset);
5814 return (GET_CODE (tocrel_base) == UNSPEC
5815 && XINT (tocrel_base, 1) == UNSPEC_TOCREL);
5818 bool
5819 legitimate_constant_pool_address_p (const_rtx x, bool strict)
5821 return (TARGET_TOC
5822 && (GET_CODE (x) == PLUS || GET_CODE (x) == LO_SUM)
5823 && GET_CODE (XEXP (x, 0)) == REG
5824 && (REGNO (XEXP (x, 0)) == TOC_REGISTER
5825 || ((TARGET_MINIMAL_TOC
5826 || TARGET_CMODEL != CMODEL_SMALL)
5827 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict)))
5828 && toc_relative_expr_p (XEXP (x, 1)));
5831 static bool
5832 legitimate_small_data_p (enum machine_mode mode, rtx x)
5834 return (DEFAULT_ABI == ABI_V4
5835 && !flag_pic && !TARGET_TOC
5836 && (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST)
5837 && small_data_operand (x, mode));
5840 /* SPE offset addressing is limited to 5-bits worth of double words. */
5841 #define SPE_CONST_OFFSET_OK(x) (((x) & ~0xf8) == 0)
5843 bool
5844 rs6000_legitimate_offset_address_p (enum machine_mode mode, rtx x, int strict)
5846 unsigned HOST_WIDE_INT offset, extra;
5848 if (GET_CODE (x) != PLUS)
5849 return false;
5850 if (GET_CODE (XEXP (x, 0)) != REG)
5851 return false;
5852 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
5853 return false;
5854 if (!reg_offset_addressing_ok_p (mode))
5855 return virtual_stack_registers_memory_p (x);
5856 if (legitimate_constant_pool_address_p (x, strict))
5857 return true;
5858 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5859 return false;
5861 offset = INTVAL (XEXP (x, 1));
5862 extra = 0;
5863 switch (mode)
5865 case V4HImode:
5866 case V2SImode:
5867 case V1DImode:
5868 case V2SFmode:
5869 /* SPE vector modes. */
5870 return SPE_CONST_OFFSET_OK (offset);
5872 case DFmode:
5873 if (TARGET_E500_DOUBLE)
5874 return SPE_CONST_OFFSET_OK (offset);
5876 /* If we are using VSX scalar loads, restrict ourselves to reg+reg
5877 addressing. */
5878 if (VECTOR_MEM_VSX_P (DFmode))
5879 return false;
5881 case DDmode:
5882 case DImode:
5883 /* On e500v2, we may have:
5885 (subreg:DF (mem:DI (plus (reg) (const_int))) 0).
5887 Which gets addressed with evldd instructions. */
5888 if (TARGET_E500_DOUBLE)
5889 return SPE_CONST_OFFSET_OK (offset);
5891 if (mode == DFmode || mode == DDmode || !TARGET_POWERPC64)
5892 extra = 4;
5893 else if (offset & 3)
5894 return false;
5895 break;
5897 case TFmode:
5898 if (TARGET_E500_DOUBLE)
5899 return (SPE_CONST_OFFSET_OK (offset)
5900 && SPE_CONST_OFFSET_OK (offset + 8));
5902 case TDmode:
5903 case TImode:
5904 if (mode == TFmode || mode == TDmode || !TARGET_POWERPC64)
5905 extra = 12;
5906 else if (offset & 3)
5907 return false;
5908 else
5909 extra = 8;
5910 break;
5912 default:
5913 break;
5916 offset += 0x8000;
5917 return (offset < 0x10000) && (offset + extra < 0x10000);
5920 bool
5921 legitimate_indexed_address_p (rtx x, int strict)
5923 rtx op0, op1;
5925 if (GET_CODE (x) != PLUS)
5926 return false;
5928 op0 = XEXP (x, 0);
5929 op1 = XEXP (x, 1);
5931 /* Recognize the rtl generated by reload which we know will later be
5932 replaced with proper base and index regs. */
5933 if (!strict
5934 && reload_in_progress
5935 && (REG_P (op0) || GET_CODE (op0) == PLUS)
5936 && REG_P (op1))
5937 return true;
5939 return (REG_P (op0) && REG_P (op1)
5940 && ((INT_REG_OK_FOR_BASE_P (op0, strict)
5941 && INT_REG_OK_FOR_INDEX_P (op1, strict))
5942 || (INT_REG_OK_FOR_BASE_P (op1, strict)
5943 && INT_REG_OK_FOR_INDEX_P (op0, strict))));
5946 bool
5947 avoiding_indexed_address_p (enum machine_mode mode)
5949 /* Avoid indexed addressing for modes that have non-indexed
5950 load/store instruction forms. */
5951 return (TARGET_AVOID_XFORM && VECTOR_MEM_NONE_P (mode));
5954 inline bool
5955 legitimate_indirect_address_p (rtx x, int strict)
5957 return GET_CODE (x) == REG && INT_REG_OK_FOR_BASE_P (x, strict);
5960 bool
5961 macho_lo_sum_memory_operand (rtx x, enum machine_mode mode)
5963 if (!TARGET_MACHO || !flag_pic
5964 || mode != SImode || GET_CODE (x) != MEM)
5965 return false;
5966 x = XEXP (x, 0);
5968 if (GET_CODE (x) != LO_SUM)
5969 return false;
5970 if (GET_CODE (XEXP (x, 0)) != REG)
5971 return false;
5972 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 0))
5973 return false;
5974 x = XEXP (x, 1);
5976 return CONSTANT_P (x);
5979 static bool
5980 legitimate_lo_sum_address_p (enum machine_mode mode, rtx x, int strict)
5982 if (GET_CODE (x) != LO_SUM)
5983 return false;
5984 if (GET_CODE (XEXP (x, 0)) != REG)
5985 return false;
5986 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
5987 return false;
5988 /* Restrict addressing for DI because of our SUBREG hackery. */
5989 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
5990 || mode == DDmode || mode == TDmode
5991 || mode == DImode))
5992 return false;
5993 x = XEXP (x, 1);
5995 if (TARGET_ELF || TARGET_MACHO)
5997 if (DEFAULT_ABI != ABI_AIX && DEFAULT_ABI != ABI_DARWIN && flag_pic)
5998 return false;
5999 if (TARGET_TOC)
6000 return false;
6001 if (GET_MODE_NUNITS (mode) != 1)
6002 return false;
6003 if (GET_MODE_BITSIZE (mode) > 64
6004 || (GET_MODE_BITSIZE (mode) > 32 && !TARGET_POWERPC64
6005 && !(TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
6006 && (mode == DFmode || mode == DDmode))))
6007 return false;
6009 return CONSTANT_P (x);
6012 return false;
6016 /* Try machine-dependent ways of modifying an illegitimate address
6017 to be legitimate. If we find one, return the new, valid address.
6018 This is used from only one place: `memory_address' in explow.c.
6020 OLDX is the address as it was before break_out_memory_refs was
6021 called. In some cases it is useful to look at this to decide what
6022 needs to be done.
6024 It is always safe for this function to do nothing. It exists to
6025 recognize opportunities to optimize the output.
6027 On RS/6000, first check for the sum of a register with a constant
6028 integer that is out of range. If so, generate code to add the
6029 constant with the low-order 16 bits masked to the register and force
6030 this result into another register (this can be done with `cau').
6031 Then generate an address of REG+(CONST&0xffff), allowing for the
6032 possibility of bit 16 being a one.
6034 Then check for the sum of a register and something not constant, try to
6035 load the other things into a register and return the sum. */
6037 static rtx
6038 rs6000_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
6039 enum machine_mode mode)
6041 unsigned int extra = 0;
6043 if (!reg_offset_addressing_ok_p (mode))
6045 if (virtual_stack_registers_memory_p (x))
6046 return x;
6048 /* In theory we should not be seeing addresses of the form reg+0,
6049 but just in case it is generated, optimize it away. */
6050 if (GET_CODE (x) == PLUS && XEXP (x, 1) == const0_rtx)
6051 return force_reg (Pmode, XEXP (x, 0));
6053 /* Make sure both operands are registers. */
6054 else if (GET_CODE (x) == PLUS)
6055 return gen_rtx_PLUS (Pmode,
6056 force_reg (Pmode, XEXP (x, 0)),
6057 force_reg (Pmode, XEXP (x, 1)));
6058 else
6059 return force_reg (Pmode, x);
6061 if (GET_CODE (x) == SYMBOL_REF)
6063 enum tls_model model = SYMBOL_REF_TLS_MODEL (x);
6064 if (model != 0)
6065 return rs6000_legitimize_tls_address (x, model);
6068 switch (mode)
6070 case DFmode:
6071 case DDmode:
6072 extra = 4;
6073 break;
6074 case DImode:
6075 if (!TARGET_POWERPC64)
6076 extra = 4;
6077 break;
6078 case TFmode:
6079 case TDmode:
6080 extra = 12;
6081 break;
6082 case TImode:
6083 extra = TARGET_POWERPC64 ? 8 : 12;
6084 break;
6085 default:
6086 break;
6089 if (GET_CODE (x) == PLUS
6090 && GET_CODE (XEXP (x, 0)) == REG
6091 && GET_CODE (XEXP (x, 1)) == CONST_INT
6092 && ((unsigned HOST_WIDE_INT) (INTVAL (XEXP (x, 1)) + 0x8000)
6093 >= 0x10000 - extra)
6094 && !((TARGET_POWERPC64
6095 && (mode == DImode || mode == TImode)
6096 && (INTVAL (XEXP (x, 1)) & 3) != 0)
6097 || SPE_VECTOR_MODE (mode)
6098 || (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
6099 || mode == DImode || mode == DDmode
6100 || mode == TDmode))))
6102 HOST_WIDE_INT high_int, low_int;
6103 rtx sum;
6104 low_int = ((INTVAL (XEXP (x, 1)) & 0xffff) ^ 0x8000) - 0x8000;
6105 if (low_int >= 0x8000 - extra)
6106 low_int = 0;
6107 high_int = INTVAL (XEXP (x, 1)) - low_int;
6108 sum = force_operand (gen_rtx_PLUS (Pmode, XEXP (x, 0),
6109 GEN_INT (high_int)), 0);
6110 return plus_constant (sum, low_int);
6112 else if (GET_CODE (x) == PLUS
6113 && GET_CODE (XEXP (x, 0)) == REG
6114 && GET_CODE (XEXP (x, 1)) != CONST_INT
6115 && GET_MODE_NUNITS (mode) == 1
6116 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
6117 || TARGET_POWERPC64
6118 || ((mode != DImode && mode != DFmode && mode != DDmode)
6119 || (TARGET_E500_DOUBLE && mode != DDmode)))
6120 && (TARGET_POWERPC64 || mode != DImode)
6121 && !avoiding_indexed_address_p (mode)
6122 && mode != TImode
6123 && mode != TFmode
6124 && mode != TDmode)
6126 return gen_rtx_PLUS (Pmode, XEXP (x, 0),
6127 force_reg (Pmode, force_operand (XEXP (x, 1), 0)));
6129 else if (SPE_VECTOR_MODE (mode)
6130 || (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
6131 || mode == DDmode || mode == TDmode
6132 || mode == DImode)))
6134 if (mode == DImode)
6135 return x;
6136 /* We accept [reg + reg] and [reg + OFFSET]. */
6138 if (GET_CODE (x) == PLUS)
6140 rtx op1 = XEXP (x, 0);
6141 rtx op2 = XEXP (x, 1);
6142 rtx y;
6144 op1 = force_reg (Pmode, op1);
6146 if (GET_CODE (op2) != REG
6147 && (GET_CODE (op2) != CONST_INT
6148 || !SPE_CONST_OFFSET_OK (INTVAL (op2))
6149 || (GET_MODE_SIZE (mode) > 8
6150 && !SPE_CONST_OFFSET_OK (INTVAL (op2) + 8))))
6151 op2 = force_reg (Pmode, op2);
6153 /* We can't always do [reg + reg] for these, because [reg +
6154 reg + offset] is not a legitimate addressing mode. */
6155 y = gen_rtx_PLUS (Pmode, op1, op2);
6157 if ((GET_MODE_SIZE (mode) > 8 || mode == DDmode) && REG_P (op2))
6158 return force_reg (Pmode, y);
6159 else
6160 return y;
6163 return force_reg (Pmode, x);
6165 else if (TARGET_ELF
6166 && TARGET_32BIT
6167 && TARGET_NO_TOC
6168 && ! flag_pic
6169 && GET_CODE (x) != CONST_INT
6170 && GET_CODE (x) != CONST_DOUBLE
6171 && CONSTANT_P (x)
6172 && GET_MODE_NUNITS (mode) == 1
6173 && (GET_MODE_BITSIZE (mode) <= 32
6174 || ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
6175 && (mode == DFmode || mode == DDmode))))
6177 rtx reg = gen_reg_rtx (Pmode);
6178 emit_insn (gen_elf_high (reg, x));
6179 return gen_rtx_LO_SUM (Pmode, reg, x);
6181 else if (TARGET_MACHO && TARGET_32BIT && TARGET_NO_TOC
6182 && ! flag_pic
6183 #if TARGET_MACHO
6184 && ! MACHO_DYNAMIC_NO_PIC_P
6185 #endif
6186 && GET_CODE (x) != CONST_INT
6187 && GET_CODE (x) != CONST_DOUBLE
6188 && CONSTANT_P (x)
6189 && GET_MODE_NUNITS (mode) == 1
6190 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
6191 || (mode != DFmode && mode != DDmode))
6192 && mode != DImode
6193 && mode != TImode)
6195 rtx reg = gen_reg_rtx (Pmode);
6196 emit_insn (gen_macho_high (reg, x));
6197 return gen_rtx_LO_SUM (Pmode, reg, x);
6199 else if (TARGET_TOC
6200 && GET_CODE (x) == SYMBOL_REF
6201 && constant_pool_expr_p (x)
6202 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), Pmode))
6204 rtx reg = TARGET_CMODEL != CMODEL_SMALL ? gen_reg_rtx (Pmode) : NULL_RTX;
6205 return create_TOC_reference (x, reg);
6207 else
6208 return x;
6211 /* Debug version of rs6000_legitimize_address. */
6212 static rtx
6213 rs6000_debug_legitimize_address (rtx x, rtx oldx, enum machine_mode mode)
6215 rtx ret;
6216 rtx insns;
6218 start_sequence ();
6219 ret = rs6000_legitimize_address (x, oldx, mode);
6220 insns = get_insns ();
6221 end_sequence ();
6223 if (ret != x)
6225 fprintf (stderr,
6226 "\nrs6000_legitimize_address: mode %s, old code %s, "
6227 "new code %s, modified\n",
6228 GET_MODE_NAME (mode), GET_RTX_NAME (GET_CODE (x)),
6229 GET_RTX_NAME (GET_CODE (ret)));
6231 fprintf (stderr, "Original address:\n");
6232 debug_rtx (x);
6234 fprintf (stderr, "oldx:\n");
6235 debug_rtx (oldx);
6237 fprintf (stderr, "New address:\n");
6238 debug_rtx (ret);
6240 if (insns)
6242 fprintf (stderr, "Insns added:\n");
6243 debug_rtx_list (insns, 20);
6246 else
6248 fprintf (stderr,
6249 "\nrs6000_legitimize_address: mode %s, code %s, no change:\n",
6250 GET_MODE_NAME (mode), GET_RTX_NAME (GET_CODE (x)));
6252 debug_rtx (x);
6255 if (insns)
6256 emit_insn (insns);
6258 return ret;
6261 /* This is called from dwarf2out.c via TARGET_ASM_OUTPUT_DWARF_DTPREL.
6262 We need to emit DTP-relative relocations. */
6264 static void
6265 rs6000_output_dwarf_dtprel (FILE *file, int size, rtx x)
6267 switch (size)
6269 case 4:
6270 fputs ("\t.long\t", file);
6271 break;
6272 case 8:
6273 fputs (DOUBLE_INT_ASM_OP, file);
6274 break;
6275 default:
6276 gcc_unreachable ();
6278 output_addr_const (file, x);
6279 fputs ("@dtprel+0x8000", file);
6282 /* In the name of slightly smaller debug output, and to cater to
6283 general assembler lossage, recognize various UNSPEC sequences
6284 and turn them back into a direct symbol reference. */
6286 static rtx
6287 rs6000_delegitimize_address (rtx orig_x)
6289 rtx x, y;
6291 orig_x = delegitimize_mem_from_attrs (orig_x);
6292 x = orig_x;
6293 if (MEM_P (x))
6294 x = XEXP (x, 0);
6296 if (GET_CODE (x) == (TARGET_CMODEL != CMODEL_SMALL ? LO_SUM : PLUS)
6297 && GET_CODE (XEXP (x, 1)) == CONST)
6299 y = XEXP (XEXP (x, 1), 0);
6300 if (GET_CODE (y) == UNSPEC
6301 && XINT (y, 1) == UNSPEC_TOCREL
6302 && ((GET_CODE (XEXP (x, 0)) == REG
6303 && (REGNO (XEXP (x, 0)) == TOC_REGISTER
6304 || TARGET_MINIMAL_TOC
6305 || TARGET_CMODEL != CMODEL_SMALL))
6306 || (TARGET_CMODEL != CMODEL_SMALL
6307 && GET_CODE (XEXP (x, 0)) == PLUS
6308 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
6309 && REGNO (XEXP (XEXP (x, 0), 0)) == TOC_REGISTER
6310 && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH
6311 && rtx_equal_p (XEXP (x, 1),
6312 XEXP (XEXP (XEXP (x, 0), 1), 0)))))
6314 y = XVECEXP (y, 0, 0);
6315 if (!MEM_P (orig_x))
6316 return y;
6317 else
6318 return replace_equiv_address_nv (orig_x, y);
6322 if (TARGET_MACHO
6323 && GET_CODE (orig_x) == LO_SUM
6324 && GET_CODE (XEXP (x, 1)) == CONST)
6326 y = XEXP (XEXP (x, 1), 0);
6327 if (GET_CODE (y) == UNSPEC
6328 && XINT (y, 1) == UNSPEC_MACHOPIC_OFFSET)
6329 return XVECEXP (y, 0, 0);
6332 return orig_x;
6335 /* Construct the SYMBOL_REF for the tls_get_addr function. */
6337 static GTY(()) rtx rs6000_tls_symbol;
6338 static rtx
6339 rs6000_tls_get_addr (void)
6341 if (!rs6000_tls_symbol)
6342 rs6000_tls_symbol = init_one_libfunc ("__tls_get_addr");
6344 return rs6000_tls_symbol;
6347 /* Construct the SYMBOL_REF for TLS GOT references. */
6349 static GTY(()) rtx rs6000_got_symbol;
6350 static rtx
6351 rs6000_got_sym (void)
6353 if (!rs6000_got_symbol)
6355 rs6000_got_symbol = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
6356 SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_LOCAL;
6357 SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_EXTERNAL;
6360 return rs6000_got_symbol;
6363 /* ADDR contains a thread-local SYMBOL_REF. Generate code to compute
6364 this (thread-local) address. */
6366 static rtx
6367 rs6000_legitimize_tls_address (rtx addr, enum tls_model model)
6369 rtx dest, insn;
6371 dest = gen_reg_rtx (Pmode);
6372 if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 16)
6374 rtx tlsreg;
6376 if (TARGET_64BIT)
6378 tlsreg = gen_rtx_REG (Pmode, 13);
6379 insn = gen_tls_tprel_64 (dest, tlsreg, addr);
6381 else
6383 tlsreg = gen_rtx_REG (Pmode, 2);
6384 insn = gen_tls_tprel_32 (dest, tlsreg, addr);
6386 emit_insn (insn);
6388 else if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 32)
6390 rtx tlsreg, tmp;
6392 tmp = gen_reg_rtx (Pmode);
6393 if (TARGET_64BIT)
6395 tlsreg = gen_rtx_REG (Pmode, 13);
6396 insn = gen_tls_tprel_ha_64 (tmp, tlsreg, addr);
6398 else
6400 tlsreg = gen_rtx_REG (Pmode, 2);
6401 insn = gen_tls_tprel_ha_32 (tmp, tlsreg, addr);
6403 emit_insn (insn);
6404 if (TARGET_64BIT)
6405 insn = gen_tls_tprel_lo_64 (dest, tmp, addr);
6406 else
6407 insn = gen_tls_tprel_lo_32 (dest, tmp, addr);
6408 emit_insn (insn);
6410 else
6412 rtx r3, got, tga, tmp1, tmp2, call_insn;
6414 /* We currently use relocations like @got@tlsgd for tls, which
6415 means the linker will handle allocation of tls entries, placing
6416 them in the .got section. So use a pointer to the .got section,
6417 not one to secondary TOC sections used by 64-bit -mminimal-toc,
6418 or to secondary GOT sections used by 32-bit -fPIC. */
6419 if (TARGET_64BIT)
6420 got = gen_rtx_REG (Pmode, 2);
6421 else
6423 if (flag_pic == 1)
6424 got = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
6425 else
6427 rtx gsym = rs6000_got_sym ();
6428 got = gen_reg_rtx (Pmode);
6429 if (flag_pic == 0)
6430 rs6000_emit_move (got, gsym, Pmode);
6431 else
6433 rtx mem, lab, last;
6435 tmp1 = gen_reg_rtx (Pmode);
6436 tmp2 = gen_reg_rtx (Pmode);
6437 mem = gen_const_mem (Pmode, tmp1);
6438 lab = gen_label_rtx ();
6439 emit_insn (gen_load_toc_v4_PIC_1b (gsym, lab));
6440 emit_move_insn (tmp1, gen_rtx_REG (Pmode, LR_REGNO));
6441 emit_move_insn (tmp2, mem);
6442 last = emit_insn (gen_addsi3 (got, tmp1, tmp2));
6443 set_unique_reg_note (last, REG_EQUAL, gsym);
6448 if (model == TLS_MODEL_GLOBAL_DYNAMIC)
6450 r3 = gen_rtx_REG (Pmode, 3);
6451 tga = rs6000_tls_get_addr ();
6452 emit_library_call_value (tga, dest, LCT_CONST, Pmode, 1, r3, Pmode);
6454 if (DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
6455 insn = gen_tls_gd_aix64 (r3, got, addr, tga, const0_rtx);
6456 else if (DEFAULT_ABI == ABI_AIX && !TARGET_64BIT)
6457 insn = gen_tls_gd_aix32 (r3, got, addr, tga, const0_rtx);
6458 else if (DEFAULT_ABI == ABI_V4)
6459 insn = gen_tls_gd_sysvsi (r3, got, addr, tga, const0_rtx);
6460 else
6461 gcc_unreachable ();
6462 call_insn = last_call_insn ();
6463 PATTERN (call_insn) = insn;
6464 if (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
6465 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn),
6466 pic_offset_table_rtx);
6468 else if (model == TLS_MODEL_LOCAL_DYNAMIC)
6470 r3 = gen_rtx_REG (Pmode, 3);
6471 tga = rs6000_tls_get_addr ();
6472 tmp1 = gen_reg_rtx (Pmode);
6473 emit_library_call_value (tga, tmp1, LCT_CONST, Pmode, 1, r3, Pmode);
6475 if (DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
6476 insn = gen_tls_ld_aix64 (r3, got, tga, const0_rtx);
6477 else if (DEFAULT_ABI == ABI_AIX && !TARGET_64BIT)
6478 insn = gen_tls_ld_aix32 (r3, got, tga, const0_rtx);
6479 else if (DEFAULT_ABI == ABI_V4)
6480 insn = gen_tls_ld_sysvsi (r3, got, tga, const0_rtx);
6481 else
6482 gcc_unreachable ();
6483 call_insn = last_call_insn ();
6484 PATTERN (call_insn) = insn;
6485 if (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
6486 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn),
6487 pic_offset_table_rtx);
6489 if (rs6000_tls_size == 16)
6491 if (TARGET_64BIT)
6492 insn = gen_tls_dtprel_64 (dest, tmp1, addr);
6493 else
6494 insn = gen_tls_dtprel_32 (dest, tmp1, addr);
6496 else if (rs6000_tls_size == 32)
6498 tmp2 = gen_reg_rtx (Pmode);
6499 if (TARGET_64BIT)
6500 insn = gen_tls_dtprel_ha_64 (tmp2, tmp1, addr);
6501 else
6502 insn = gen_tls_dtprel_ha_32 (tmp2, tmp1, addr);
6503 emit_insn (insn);
6504 if (TARGET_64BIT)
6505 insn = gen_tls_dtprel_lo_64 (dest, tmp2, addr);
6506 else
6507 insn = gen_tls_dtprel_lo_32 (dest, tmp2, addr);
6509 else
6511 tmp2 = gen_reg_rtx (Pmode);
6512 if (TARGET_64BIT)
6513 insn = gen_tls_got_dtprel_64 (tmp2, got, addr);
6514 else
6515 insn = gen_tls_got_dtprel_32 (tmp2, got, addr);
6516 emit_insn (insn);
6517 insn = gen_rtx_SET (Pmode, dest,
6518 gen_rtx_PLUS (Pmode, tmp2, tmp1));
6520 emit_insn (insn);
6522 else
6524 /* IE, or 64-bit offset LE. */
6525 tmp2 = gen_reg_rtx (Pmode);
6526 if (TARGET_64BIT)
6527 insn = gen_tls_got_tprel_64 (tmp2, got, addr);
6528 else
6529 insn = gen_tls_got_tprel_32 (tmp2, got, addr);
6530 emit_insn (insn);
6531 if (TARGET_64BIT)
6532 insn = gen_tls_tls_64 (dest, tmp2, addr);
6533 else
6534 insn = gen_tls_tls_32 (dest, tmp2, addr);
6535 emit_insn (insn);
6539 return dest;
6542 /* Return 1 if X contains a thread-local symbol. */
6544 bool
6545 rs6000_tls_referenced_p (rtx x)
6547 if (! TARGET_HAVE_TLS)
6548 return false;
6550 return for_each_rtx (&x, &rs6000_tls_symbol_ref_1, 0);
6553 /* Return 1 if *X is a thread-local symbol. This is the same as
6554 rs6000_tls_symbol_ref except for the type of the unused argument. */
6556 static int
6557 rs6000_tls_symbol_ref_1 (rtx *x, void *data ATTRIBUTE_UNUSED)
6559 return RS6000_SYMBOL_REF_TLS_P (*x);
6562 /* Our implementation of LEGITIMIZE_RELOAD_ADDRESS. Returns a value to
6563 replace the input X, or the original X if no replacement is called for.
6564 The output parameter *WIN is 1 if the calling macro should goto WIN,
6565 0 if it should not.
6567 For RS/6000, we wish to handle large displacements off a base
6568 register by splitting the addend across an addiu/addis and the mem insn.
6569 This cuts number of extra insns needed from 3 to 1.
6571 On Darwin, we use this to generate code for floating point constants.
6572 A movsf_low is generated so we wind up with 2 instructions rather than 3.
6573 The Darwin code is inside #if TARGET_MACHO because only then are the
6574 machopic_* functions defined. */
6575 static rtx
6576 rs6000_legitimize_reload_address (rtx x, enum machine_mode mode,
6577 int opnum, int type,
6578 int ind_levels ATTRIBUTE_UNUSED, int *win)
6580 bool reg_offset_p = reg_offset_addressing_ok_p (mode);
6582 /* We must recognize output that we have already generated ourselves. */
6583 if (GET_CODE (x) == PLUS
6584 && GET_CODE (XEXP (x, 0)) == PLUS
6585 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
6586 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
6587 && GET_CODE (XEXP (x, 1)) == CONST_INT)
6589 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6590 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
6591 opnum, (enum reload_type)type);
6592 *win = 1;
6593 return x;
6596 /* Likewise for (lo_sum (high ...) ...) output we have generated. */
6597 if (GET_CODE (x) == LO_SUM
6598 && GET_CODE (XEXP (x, 0)) == HIGH)
6600 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6601 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6602 opnum, (enum reload_type)type);
6603 *win = 1;
6604 return x;
6607 #if TARGET_MACHO
6608 if (DEFAULT_ABI == ABI_DARWIN && flag_pic
6609 && GET_CODE (x) == LO_SUM
6610 && GET_CODE (XEXP (x, 0)) == PLUS
6611 && XEXP (XEXP (x, 0), 0) == pic_offset_table_rtx
6612 && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH
6613 && XEXP (XEXP (XEXP (x, 0), 1), 0) == XEXP (x, 1)
6614 && machopic_operand_p (XEXP (x, 1)))
6616 /* Result of previous invocation of this function on Darwin
6617 floating point constant. */
6618 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6619 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6620 opnum, (enum reload_type)type);
6621 *win = 1;
6622 return x;
6624 #endif
6626 if (TARGET_CMODEL != CMODEL_SMALL
6627 && GET_CODE (x) == LO_SUM
6628 && GET_CODE (XEXP (x, 0)) == PLUS
6629 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
6630 && REGNO (XEXP (XEXP (x, 0), 0)) == TOC_REGISTER
6631 && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH
6632 && GET_CODE (XEXP (x, 1)) == CONST
6633 && GET_CODE (XEXP (XEXP (x, 1), 0)) == UNSPEC
6634 && XINT (XEXP (XEXP (x, 1), 0), 1) == UNSPEC_TOCREL
6635 && rtx_equal_p (XEXP (XEXP (XEXP (x, 0), 1), 0), XEXP (x, 1)))
6637 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6638 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6639 opnum, (enum reload_type) type);
6640 *win = 1;
6641 return x;
6644 /* Force ld/std non-word aligned offset into base register by wrapping
6645 in offset 0. */
6646 if (GET_CODE (x) == PLUS
6647 && GET_CODE (XEXP (x, 0)) == REG
6648 && REGNO (XEXP (x, 0)) < 32
6649 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 1)
6650 && GET_CODE (XEXP (x, 1)) == CONST_INT
6651 && reg_offset_p
6652 && (INTVAL (XEXP (x, 1)) & 3) != 0
6653 && VECTOR_MEM_NONE_P (mode)
6654 && GET_MODE_SIZE (mode) >= UNITS_PER_WORD
6655 && TARGET_POWERPC64)
6657 x = gen_rtx_PLUS (GET_MODE (x), x, GEN_INT (0));
6658 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6659 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
6660 opnum, (enum reload_type) type);
6661 *win = 1;
6662 return x;
6665 if (GET_CODE (x) == PLUS
6666 && GET_CODE (XEXP (x, 0)) == REG
6667 && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER
6668 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 1)
6669 && GET_CODE (XEXP (x, 1)) == CONST_INT
6670 && reg_offset_p
6671 && !SPE_VECTOR_MODE (mode)
6672 && !(TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
6673 || mode == DDmode || mode == TDmode
6674 || mode == DImode))
6675 && VECTOR_MEM_NONE_P (mode))
6677 HOST_WIDE_INT val = INTVAL (XEXP (x, 1));
6678 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
6679 HOST_WIDE_INT high
6680 = (((val - low) & 0xffffffff) ^ 0x80000000) - 0x80000000;
6682 /* Check for 32-bit overflow. */
6683 if (high + low != val)
6685 *win = 0;
6686 return x;
6689 /* Reload the high part into a base reg; leave the low part
6690 in the mem directly. */
6692 x = gen_rtx_PLUS (GET_MODE (x),
6693 gen_rtx_PLUS (GET_MODE (x), XEXP (x, 0),
6694 GEN_INT (high)),
6695 GEN_INT (low));
6697 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6698 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
6699 opnum, (enum reload_type)type);
6700 *win = 1;
6701 return x;
6704 if (GET_CODE (x) == SYMBOL_REF
6705 && reg_offset_p
6706 && VECTOR_MEM_NONE_P (mode)
6707 && !SPE_VECTOR_MODE (mode)
6708 #if TARGET_MACHO
6709 && DEFAULT_ABI == ABI_DARWIN
6710 && (flag_pic || MACHO_DYNAMIC_NO_PIC_P)
6711 #else
6712 && DEFAULT_ABI == ABI_V4
6713 && !flag_pic
6714 #endif
6715 /* Don't do this for TFmode or TDmode, since the result isn't offsettable.
6716 The same goes for DImode without 64-bit gprs and DFmode and DDmode
6717 without fprs. */
6718 && mode != TFmode
6719 && mode != TDmode
6720 && (mode != DImode || TARGET_POWERPC64)
6721 && ((mode != DFmode && mode != DDmode) || TARGET_POWERPC64
6722 || (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)))
6724 #if TARGET_MACHO
6725 if (flag_pic)
6727 rtx offset = machopic_gen_offset (x);
6728 x = gen_rtx_LO_SUM (GET_MODE (x),
6729 gen_rtx_PLUS (Pmode, pic_offset_table_rtx,
6730 gen_rtx_HIGH (Pmode, offset)), offset);
6732 else
6733 #endif
6734 x = gen_rtx_LO_SUM (GET_MODE (x),
6735 gen_rtx_HIGH (Pmode, x), x);
6737 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6738 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6739 opnum, (enum reload_type)type);
6740 *win = 1;
6741 return x;
6744 /* Reload an offset address wrapped by an AND that represents the
6745 masking of the lower bits. Strip the outer AND and let reload
6746 convert the offset address into an indirect address. For VSX,
6747 force reload to create the address with an AND in a separate
6748 register, because we can't guarantee an altivec register will
6749 be used. */
6750 if (VECTOR_MEM_ALTIVEC_P (mode)
6751 && GET_CODE (x) == AND
6752 && GET_CODE (XEXP (x, 0)) == PLUS
6753 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
6754 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
6755 && GET_CODE (XEXP (x, 1)) == CONST_INT
6756 && INTVAL (XEXP (x, 1)) == -16)
6758 x = XEXP (x, 0);
6759 *win = 1;
6760 return x;
6763 if (TARGET_TOC
6764 && reg_offset_p
6765 && GET_CODE (x) == SYMBOL_REF
6766 && constant_pool_expr_p (x)
6767 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), mode))
6769 x = create_TOC_reference (x, NULL_RTX);
6770 if (TARGET_CMODEL != CMODEL_SMALL)
6771 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6772 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6773 opnum, (enum reload_type) type);
6774 *win = 1;
6775 return x;
6777 *win = 0;
6778 return x;
6781 /* Debug version of rs6000_legitimize_reload_address. */
6782 static rtx
6783 rs6000_debug_legitimize_reload_address (rtx x, enum machine_mode mode,
6784 int opnum, int type,
6785 int ind_levels, int *win)
6787 rtx ret = rs6000_legitimize_reload_address (x, mode, opnum, type,
6788 ind_levels, win);
6789 fprintf (stderr,
6790 "\nrs6000_legitimize_reload_address: mode = %s, opnum = %d, "
6791 "type = %d, ind_levels = %d, win = %d, original addr:\n",
6792 GET_MODE_NAME (mode), opnum, type, ind_levels, *win);
6793 debug_rtx (x);
6795 if (x == ret)
6796 fprintf (stderr, "Same address returned\n");
6797 else if (!ret)
6798 fprintf (stderr, "NULL returned\n");
6799 else
6801 fprintf (stderr, "New address:\n");
6802 debug_rtx (ret);
6805 return ret;
6808 /* TARGET_LEGITIMATE_ADDRESS_P recognizes an RTL expression
6809 that is a valid memory address for an instruction.
6810 The MODE argument is the machine mode for the MEM expression
6811 that wants to use this address.
6813 On the RS/6000, there are four valid address: a SYMBOL_REF that
6814 refers to a constant pool entry of an address (or the sum of it
6815 plus a constant), a short (16-bit signed) constant plus a register,
6816 the sum of two registers, or a register indirect, possibly with an
6817 auto-increment. For DFmode, DDmode and DImode with a constant plus
6818 register, we must ensure that both words are addressable or PowerPC64
6819 with offset word aligned.
6821 For modes spanning multiple registers (DFmode and DDmode in 32-bit GPRs,
6822 32-bit DImode, TImode, TFmode, TDmode), indexed addressing cannot be used
6823 because adjacent memory cells are accessed by adding word-sized offsets
6824 during assembly output. */
6825 bool
6826 rs6000_legitimate_address_p (enum machine_mode mode, rtx x, bool reg_ok_strict)
6828 bool reg_offset_p = reg_offset_addressing_ok_p (mode);
6830 /* If this is an unaligned stvx/ldvx type address, discard the outer AND. */
6831 if (VECTOR_MEM_ALTIVEC_P (mode)
6832 && GET_CODE (x) == AND
6833 && GET_CODE (XEXP (x, 1)) == CONST_INT
6834 && INTVAL (XEXP (x, 1)) == -16)
6835 x = XEXP (x, 0);
6837 if (RS6000_SYMBOL_REF_TLS_P (x))
6838 return 0;
6839 if (legitimate_indirect_address_p (x, reg_ok_strict))
6840 return 1;
6841 if ((GET_CODE (x) == PRE_INC || GET_CODE (x) == PRE_DEC)
6842 && !VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)
6843 && !SPE_VECTOR_MODE (mode)
6844 && mode != TFmode
6845 && mode != TDmode
6846 /* Restrict addressing for DI because of our SUBREG hackery. */
6847 && !(TARGET_E500_DOUBLE
6848 && (mode == DFmode || mode == DDmode || mode == DImode))
6849 && TARGET_UPDATE
6850 && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict))
6851 return 1;
6852 if (virtual_stack_registers_memory_p (x))
6853 return 1;
6854 if (reg_offset_p && legitimate_small_data_p (mode, x))
6855 return 1;
6856 if (reg_offset_p && legitimate_constant_pool_address_p (x, reg_ok_strict))
6857 return 1;
6858 /* If not REG_OK_STRICT (before reload) let pass any stack offset. */
6859 if (! reg_ok_strict
6860 && reg_offset_p
6861 && GET_CODE (x) == PLUS
6862 && GET_CODE (XEXP (x, 0)) == REG
6863 && (XEXP (x, 0) == virtual_stack_vars_rtx
6864 || XEXP (x, 0) == arg_pointer_rtx)
6865 && GET_CODE (XEXP (x, 1)) == CONST_INT)
6866 return 1;
6867 if (rs6000_legitimate_offset_address_p (mode, x, reg_ok_strict))
6868 return 1;
6869 if (mode != TImode
6870 && mode != TFmode
6871 && mode != TDmode
6872 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
6873 || TARGET_POWERPC64
6874 || (mode != DFmode && mode != DDmode)
6875 || (TARGET_E500_DOUBLE && mode != DDmode))
6876 && (TARGET_POWERPC64 || mode != DImode)
6877 && !avoiding_indexed_address_p (mode)
6878 && legitimate_indexed_address_p (x, reg_ok_strict))
6879 return 1;
6880 if (GET_CODE (x) == PRE_MODIFY
6881 && mode != TImode
6882 && mode != TFmode
6883 && mode != TDmode
6884 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
6885 || TARGET_POWERPC64
6886 || ((mode != DFmode && mode != DDmode) || TARGET_E500_DOUBLE))
6887 && (TARGET_POWERPC64 || mode != DImode)
6888 && !VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)
6889 && !SPE_VECTOR_MODE (mode)
6890 /* Restrict addressing for DI because of our SUBREG hackery. */
6891 && !(TARGET_E500_DOUBLE
6892 && (mode == DFmode || mode == DDmode || mode == DImode))
6893 && TARGET_UPDATE
6894 && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict)
6895 && (rs6000_legitimate_offset_address_p (mode, XEXP (x, 1), reg_ok_strict)
6896 || (!avoiding_indexed_address_p (mode)
6897 && legitimate_indexed_address_p (XEXP (x, 1), reg_ok_strict)))
6898 && rtx_equal_p (XEXP (XEXP (x, 1), 0), XEXP (x, 0)))
6899 return 1;
6900 if (reg_offset_p && legitimate_lo_sum_address_p (mode, x, reg_ok_strict))
6901 return 1;
6902 return 0;
6905 /* Debug version of rs6000_legitimate_address_p. */
6906 static bool
6907 rs6000_debug_legitimate_address_p (enum machine_mode mode, rtx x,
6908 bool reg_ok_strict)
6910 bool ret = rs6000_legitimate_address_p (mode, x, reg_ok_strict);
6911 fprintf (stderr,
6912 "\nrs6000_legitimate_address_p: return = %s, mode = %s, "
6913 "strict = %d, code = %s\n",
6914 ret ? "true" : "false",
6915 GET_MODE_NAME (mode),
6916 reg_ok_strict,
6917 GET_RTX_NAME (GET_CODE (x)));
6918 debug_rtx (x);
6920 return ret;
6923 /* Implement TARGET_MODE_DEPENDENT_ADDRESS_P. */
6925 static bool
6926 rs6000_mode_dependent_address_p (const_rtx addr)
6928 return rs6000_mode_dependent_address_ptr (addr);
6931 /* Go to LABEL if ADDR (a legitimate address expression)
6932 has an effect that depends on the machine mode it is used for.
6934 On the RS/6000 this is true of all integral offsets (since AltiVec
6935 and VSX modes don't allow them) or is a pre-increment or decrement.
6937 ??? Except that due to conceptual problems in offsettable_address_p
6938 we can't really report the problems of integral offsets. So leave
6939 this assuming that the adjustable offset must be valid for the
6940 sub-words of a TFmode operand, which is what we had before. */
6942 static bool
6943 rs6000_mode_dependent_address (const_rtx addr)
6945 switch (GET_CODE (addr))
6947 case PLUS:
6948 /* Any offset from virtual_stack_vars_rtx and arg_pointer_rtx
6949 is considered a legitimate address before reload, so there
6950 are no offset restrictions in that case. Note that this
6951 condition is safe in strict mode because any address involving
6952 virtual_stack_vars_rtx or arg_pointer_rtx would already have
6953 been rejected as illegitimate. */
6954 if (XEXP (addr, 0) != virtual_stack_vars_rtx
6955 && XEXP (addr, 0) != arg_pointer_rtx
6956 && GET_CODE (XEXP (addr, 1)) == CONST_INT)
6958 unsigned HOST_WIDE_INT val = INTVAL (XEXP (addr, 1));
6959 return val + 12 + 0x8000 >= 0x10000;
6961 break;
6963 case LO_SUM:
6964 /* Anything in the constant pool is sufficiently aligned that
6965 all bytes have the same high part address. */
6966 return !legitimate_constant_pool_address_p (addr, false);
6968 /* Auto-increment cases are now treated generically in recog.c. */
6969 case PRE_MODIFY:
6970 return TARGET_UPDATE;
6972 /* AND is only allowed in Altivec loads. */
6973 case AND:
6974 return true;
6976 default:
6977 break;
6980 return false;
6983 /* Debug version of rs6000_mode_dependent_address. */
6984 static bool
6985 rs6000_debug_mode_dependent_address (const_rtx addr)
6987 bool ret = rs6000_mode_dependent_address (addr);
6989 fprintf (stderr, "\nrs6000_mode_dependent_address: ret = %s\n",
6990 ret ? "true" : "false");
6991 debug_rtx (addr);
6993 return ret;
6996 /* Implement FIND_BASE_TERM. */
6999 rs6000_find_base_term (rtx op)
7001 rtx base, offset;
7003 split_const (op, &base, &offset);
7004 if (GET_CODE (base) == UNSPEC)
7005 switch (XINT (base, 1))
7007 case UNSPEC_TOCREL:
7008 case UNSPEC_MACHOPIC_OFFSET:
7009 /* OP represents SYM [+ OFFSET] - ANCHOR. SYM is the base term
7010 for aliasing purposes. */
7011 return XVECEXP (base, 0, 0);
7014 return op;
7017 /* More elaborate version of recog's offsettable_memref_p predicate
7018 that works around the ??? note of rs6000_mode_dependent_address.
7019 In particular it accepts
7021 (mem:DI (plus:SI (reg/f:SI 31 31) (const_int 32760 [0x7ff8])))
7023 in 32-bit mode, that the recog predicate rejects. */
7025 bool
7026 rs6000_offsettable_memref_p (rtx op)
7028 if (!MEM_P (op))
7029 return false;
7031 /* First mimic offsettable_memref_p. */
7032 if (offsettable_address_p (1, GET_MODE (op), XEXP (op, 0)))
7033 return true;
7035 /* offsettable_address_p invokes rs6000_mode_dependent_address, but
7036 the latter predicate knows nothing about the mode of the memory
7037 reference and, therefore, assumes that it is the largest supported
7038 mode (TFmode). As a consequence, legitimate offsettable memory
7039 references are rejected. rs6000_legitimate_offset_address_p contains
7040 the correct logic for the PLUS case of rs6000_mode_dependent_address. */
7041 return rs6000_legitimate_offset_address_p (GET_MODE (op), XEXP (op, 0), 1);
7044 /* Change register usage conditional on target flags. */
7045 static void
7046 rs6000_conditional_register_usage (void)
7048 int i;
7050 if (TARGET_DEBUG_TARGET)
7051 fprintf (stderr, "rs6000_conditional_register_usage called\n");
7053 /* Set MQ register fixed (already call_used) if not POWER
7054 architecture (RIOS1, RIOS2, RSC, and PPC601) so that it will not
7055 be allocated. */
7056 if (! TARGET_POWER)
7057 fixed_regs[64] = 1;
7059 /* 64-bit AIX and Linux reserve GPR13 for thread-private data. */
7060 if (TARGET_64BIT)
7061 fixed_regs[13] = call_used_regs[13]
7062 = call_really_used_regs[13] = 1;
7064 /* Conditionally disable FPRs. */
7065 if (TARGET_SOFT_FLOAT || !TARGET_FPRS)
7066 for (i = 32; i < 64; i++)
7067 fixed_regs[i] = call_used_regs[i]
7068 = call_really_used_regs[i] = 1;
7070 /* The TOC register is not killed across calls in a way that is
7071 visible to the compiler. */
7072 if (DEFAULT_ABI == ABI_AIX)
7073 call_really_used_regs[2] = 0;
7075 if (DEFAULT_ABI == ABI_V4
7076 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
7077 && flag_pic == 2)
7078 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
7080 if (DEFAULT_ABI == ABI_V4
7081 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
7082 && flag_pic == 1)
7083 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
7084 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
7085 = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
7087 if (DEFAULT_ABI == ABI_DARWIN
7088 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM)
7089 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
7090 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
7091 = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
7093 if (TARGET_TOC && TARGET_MINIMAL_TOC)
7094 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
7095 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
7097 if (TARGET_SPE)
7099 global_regs[SPEFSCR_REGNO] = 1;
7100 /* We used to use r14 as FIXED_SCRATCH to address SPE 64-bit
7101 registers in prologues and epilogues. We no longer use r14
7102 for FIXED_SCRATCH, but we're keeping r14 out of the allocation
7103 pool for link-compatibility with older versions of GCC. Once
7104 "old" code has died out, we can return r14 to the allocation
7105 pool. */
7106 fixed_regs[14]
7107 = call_used_regs[14]
7108 = call_really_used_regs[14] = 1;
7111 if (!TARGET_ALTIVEC && !TARGET_VSX)
7113 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
7114 fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1;
7115 call_really_used_regs[VRSAVE_REGNO] = 1;
7118 if (TARGET_ALTIVEC || TARGET_VSX)
7119 global_regs[VSCR_REGNO] = 1;
7121 if (TARGET_ALTIVEC_ABI)
7123 for (i = FIRST_ALTIVEC_REGNO; i < FIRST_ALTIVEC_REGNO + 20; ++i)
7124 call_used_regs[i] = call_really_used_regs[i] = 1;
7126 /* AIX reserves VR20:31 in non-extended ABI mode. */
7127 if (TARGET_XCOFF)
7128 for (i = FIRST_ALTIVEC_REGNO + 20; i < FIRST_ALTIVEC_REGNO + 32; ++i)
7129 fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1;
7133 /* Try to output insns to set TARGET equal to the constant C if it can
7134 be done in less than N insns. Do all computations in MODE.
7135 Returns the place where the output has been placed if it can be
7136 done and the insns have been emitted. If it would take more than N
7137 insns, zero is returned and no insns and emitted. */
7140 rs6000_emit_set_const (rtx dest, enum machine_mode mode,
7141 rtx source, int n ATTRIBUTE_UNUSED)
7143 rtx result, insn, set;
7144 HOST_WIDE_INT c0, c1;
7146 switch (mode)
7148 case QImode:
7149 case HImode:
7150 if (dest == NULL)
7151 dest = gen_reg_rtx (mode);
7152 emit_insn (gen_rtx_SET (VOIDmode, dest, source));
7153 return dest;
7155 case SImode:
7156 result = !can_create_pseudo_p () ? dest : gen_reg_rtx (SImode);
7158 emit_insn (gen_rtx_SET (VOIDmode, copy_rtx (result),
7159 GEN_INT (INTVAL (source)
7160 & (~ (HOST_WIDE_INT) 0xffff))));
7161 emit_insn (gen_rtx_SET (VOIDmode, dest,
7162 gen_rtx_IOR (SImode, copy_rtx (result),
7163 GEN_INT (INTVAL (source) & 0xffff))));
7164 result = dest;
7165 break;
7167 case DImode:
7168 switch (GET_CODE (source))
7170 case CONST_INT:
7171 c0 = INTVAL (source);
7172 c1 = -(c0 < 0);
7173 break;
7175 case CONST_DOUBLE:
7176 #if HOST_BITS_PER_WIDE_INT >= 64
7177 c0 = CONST_DOUBLE_LOW (source);
7178 c1 = -(c0 < 0);
7179 #else
7180 c0 = CONST_DOUBLE_LOW (source);
7181 c1 = CONST_DOUBLE_HIGH (source);
7182 #endif
7183 break;
7185 default:
7186 gcc_unreachable ();
7189 result = rs6000_emit_set_long_const (dest, c0, c1);
7190 break;
7192 default:
7193 gcc_unreachable ();
7196 insn = get_last_insn ();
7197 set = single_set (insn);
7198 if (! CONSTANT_P (SET_SRC (set)))
7199 set_unique_reg_note (insn, REG_EQUAL, source);
7201 return result;
7204 /* Having failed to find a 3 insn sequence in rs6000_emit_set_const,
7205 fall back to a straight forward decomposition. We do this to avoid
7206 exponential run times encountered when looking for longer sequences
7207 with rs6000_emit_set_const. */
7208 static rtx
7209 rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c1, HOST_WIDE_INT c2)
7211 if (!TARGET_POWERPC64)
7213 rtx operand1, operand2;
7215 operand1 = operand_subword_force (dest, WORDS_BIG_ENDIAN == 0,
7216 DImode);
7217 operand2 = operand_subword_force (copy_rtx (dest), WORDS_BIG_ENDIAN != 0,
7218 DImode);
7219 emit_move_insn (operand1, GEN_INT (c1));
7220 emit_move_insn (operand2, GEN_INT (c2));
7222 else
7224 HOST_WIDE_INT ud1, ud2, ud3, ud4;
7226 ud1 = c1 & 0xffff;
7227 ud2 = (c1 & 0xffff0000) >> 16;
7228 #if HOST_BITS_PER_WIDE_INT >= 64
7229 c2 = c1 >> 32;
7230 #endif
7231 ud3 = c2 & 0xffff;
7232 ud4 = (c2 & 0xffff0000) >> 16;
7234 if ((ud4 == 0xffff && ud3 == 0xffff && ud2 == 0xffff && (ud1 & 0x8000))
7235 || (ud4 == 0 && ud3 == 0 && ud2 == 0 && ! (ud1 & 0x8000)))
7237 if (ud1 & 0x8000)
7238 emit_move_insn (dest, GEN_INT (((ud1 ^ 0x8000) - 0x8000)));
7239 else
7240 emit_move_insn (dest, GEN_INT (ud1));
7243 else if ((ud4 == 0xffff && ud3 == 0xffff && (ud2 & 0x8000))
7244 || (ud4 == 0 && ud3 == 0 && ! (ud2 & 0x8000)))
7246 if (ud2 & 0x8000)
7247 emit_move_insn (dest, GEN_INT (((ud2 << 16) ^ 0x80000000)
7248 - 0x80000000));
7249 else
7250 emit_move_insn (dest, GEN_INT (ud2 << 16));
7251 if (ud1 != 0)
7252 emit_move_insn (copy_rtx (dest),
7253 gen_rtx_IOR (DImode, copy_rtx (dest),
7254 GEN_INT (ud1)));
7256 else if (ud3 == 0 && ud4 == 0)
7258 gcc_assert (ud2 & 0x8000);
7259 emit_move_insn (dest, GEN_INT (((ud2 << 16) ^ 0x80000000)
7260 - 0x80000000));
7261 if (ud1 != 0)
7262 emit_move_insn (copy_rtx (dest),
7263 gen_rtx_IOR (DImode, copy_rtx (dest),
7264 GEN_INT (ud1)));
7265 emit_move_insn (copy_rtx (dest),
7266 gen_rtx_ZERO_EXTEND (DImode,
7267 gen_lowpart (SImode,
7268 copy_rtx (dest))));
7270 else if ((ud4 == 0xffff && (ud3 & 0x8000))
7271 || (ud4 == 0 && ! (ud3 & 0x8000)))
7273 if (ud3 & 0x8000)
7274 emit_move_insn (dest, GEN_INT (((ud3 << 16) ^ 0x80000000)
7275 - 0x80000000));
7276 else
7277 emit_move_insn (dest, GEN_INT (ud3 << 16));
7279 if (ud2 != 0)
7280 emit_move_insn (copy_rtx (dest),
7281 gen_rtx_IOR (DImode, copy_rtx (dest),
7282 GEN_INT (ud2)));
7283 emit_move_insn (copy_rtx (dest),
7284 gen_rtx_ASHIFT (DImode, copy_rtx (dest),
7285 GEN_INT (16)));
7286 if (ud1 != 0)
7287 emit_move_insn (copy_rtx (dest),
7288 gen_rtx_IOR (DImode, copy_rtx (dest),
7289 GEN_INT (ud1)));
7291 else
7293 if (ud4 & 0x8000)
7294 emit_move_insn (dest, GEN_INT (((ud4 << 16) ^ 0x80000000)
7295 - 0x80000000));
7296 else
7297 emit_move_insn (dest, GEN_INT (ud4 << 16));
7299 if (ud3 != 0)
7300 emit_move_insn (copy_rtx (dest),
7301 gen_rtx_IOR (DImode, copy_rtx (dest),
7302 GEN_INT (ud3)));
7304 emit_move_insn (copy_rtx (dest),
7305 gen_rtx_ASHIFT (DImode, copy_rtx (dest),
7306 GEN_INT (32)));
7307 if (ud2 != 0)
7308 emit_move_insn (copy_rtx (dest),
7309 gen_rtx_IOR (DImode, copy_rtx (dest),
7310 GEN_INT (ud2 << 16)));
7311 if (ud1 != 0)
7312 emit_move_insn (copy_rtx (dest),
7313 gen_rtx_IOR (DImode, copy_rtx (dest), GEN_INT (ud1)));
7316 return dest;
7319 /* Helper for the following. Get rid of [r+r] memory refs
7320 in cases where it won't work (TImode, TFmode, TDmode). */
7322 static void
7323 rs6000_eliminate_indexed_memrefs (rtx operands[2])
7325 if (reload_in_progress)
7326 return;
7328 if (GET_CODE (operands[0]) == MEM
7329 && GET_CODE (XEXP (operands[0], 0)) != REG
7330 && ! legitimate_constant_pool_address_p (XEXP (operands[0], 0), false))
7331 operands[0]
7332 = replace_equiv_address (operands[0],
7333 copy_addr_to_reg (XEXP (operands[0], 0)));
7335 if (GET_CODE (operands[1]) == MEM
7336 && GET_CODE (XEXP (operands[1], 0)) != REG
7337 && ! legitimate_constant_pool_address_p (XEXP (operands[1], 0), false))
7338 operands[1]
7339 = replace_equiv_address (operands[1],
7340 copy_addr_to_reg (XEXP (operands[1], 0)));
7343 /* Return true if memory accesses to DECL are known to never straddle
7344 a 32k boundary. */
7346 static bool
7347 offsettable_ok_by_alignment (tree decl)
7349 unsigned HOST_WIDE_INT dsize, dalign;
7351 /* Presume any compiler generated symbol_ref is suitably aligned. */
7352 if (!decl)
7353 return true;
7355 if (TREE_CODE (decl) != VAR_DECL
7356 && TREE_CODE (decl) != PARM_DECL
7357 && TREE_CODE (decl) != RESULT_DECL
7358 && TREE_CODE (decl) != FIELD_DECL)
7359 return true;
7361 if (!DECL_SIZE_UNIT (decl))
7362 return false;
7364 if (!host_integerp (DECL_SIZE_UNIT (decl), 1))
7365 return false;
7367 dsize = tree_low_cst (DECL_SIZE_UNIT (decl), 1);
7368 if (dsize <= 1)
7369 return true;
7370 if (dsize > 32768)
7371 return false;
7373 dalign = DECL_ALIGN_UNIT (decl);
7374 return dalign >= dsize;
7377 /* Emit a move from SOURCE to DEST in mode MODE. */
7378 void
7379 rs6000_emit_move (rtx dest, rtx source, enum machine_mode mode)
7381 rtx operands[2];
7382 operands[0] = dest;
7383 operands[1] = source;
7385 if (TARGET_DEBUG_ADDR)
7387 fprintf (stderr,
7388 "\nrs6000_emit_move: mode = %s, reload_in_progress = %d, "
7389 "reload_completed = %d, can_create_pseudos = %d.\ndest:\n",
7390 GET_MODE_NAME (mode),
7391 reload_in_progress,
7392 reload_completed,
7393 can_create_pseudo_p ());
7394 debug_rtx (dest);
7395 fprintf (stderr, "source:\n");
7396 debug_rtx (source);
7399 /* Sanity checks. Check that we get CONST_DOUBLE only when we should. */
7400 if (GET_CODE (operands[1]) == CONST_DOUBLE
7401 && ! FLOAT_MODE_P (mode)
7402 && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
7404 /* FIXME. This should never happen. */
7405 /* Since it seems that it does, do the safe thing and convert
7406 to a CONST_INT. */
7407 operands[1] = gen_int_mode (CONST_DOUBLE_LOW (operands[1]), mode);
7409 gcc_assert (GET_CODE (operands[1]) != CONST_DOUBLE
7410 || FLOAT_MODE_P (mode)
7411 || ((CONST_DOUBLE_HIGH (operands[1]) != 0
7412 || CONST_DOUBLE_LOW (operands[1]) < 0)
7413 && (CONST_DOUBLE_HIGH (operands[1]) != -1
7414 || CONST_DOUBLE_LOW (operands[1]) >= 0)));
7416 /* Check if GCC is setting up a block move that will end up using FP
7417 registers as temporaries. We must make sure this is acceptable. */
7418 if (GET_CODE (operands[0]) == MEM
7419 && GET_CODE (operands[1]) == MEM
7420 && mode == DImode
7421 && (SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[0]))
7422 || SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[1])))
7423 && ! (SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[0]) > 32
7424 ? 32 : MEM_ALIGN (operands[0])))
7425 || SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[1]) > 32
7426 ? 32
7427 : MEM_ALIGN (operands[1]))))
7428 && ! MEM_VOLATILE_P (operands [0])
7429 && ! MEM_VOLATILE_P (operands [1]))
7431 emit_move_insn (adjust_address (operands[0], SImode, 0),
7432 adjust_address (operands[1], SImode, 0));
7433 emit_move_insn (adjust_address (copy_rtx (operands[0]), SImode, 4),
7434 adjust_address (copy_rtx (operands[1]), SImode, 4));
7435 return;
7438 if (can_create_pseudo_p () && GET_CODE (operands[0]) == MEM
7439 && !gpc_reg_operand (operands[1], mode))
7440 operands[1] = force_reg (mode, operands[1]);
7442 if (mode == SFmode && ! TARGET_POWERPC
7443 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
7444 && GET_CODE (operands[0]) == MEM)
7446 int regnum;
7448 if (reload_in_progress || reload_completed)
7449 regnum = true_regnum (operands[1]);
7450 else if (GET_CODE (operands[1]) == REG)
7451 regnum = REGNO (operands[1]);
7452 else
7453 regnum = -1;
7455 /* If operands[1] is a register, on POWER it may have
7456 double-precision data in it, so truncate it to single
7457 precision. */
7458 if (FP_REGNO_P (regnum) || regnum >= FIRST_PSEUDO_REGISTER)
7460 rtx newreg;
7461 newreg = (!can_create_pseudo_p () ? copy_rtx (operands[1])
7462 : gen_reg_rtx (mode));
7463 emit_insn (gen_aux_truncdfsf2 (newreg, operands[1]));
7464 operands[1] = newreg;
7468 /* Recognize the case where operand[1] is a reference to thread-local
7469 data and load its address to a register. */
7470 if (rs6000_tls_referenced_p (operands[1]))
7472 enum tls_model model;
7473 rtx tmp = operands[1];
7474 rtx addend = NULL;
7476 if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
7478 addend = XEXP (XEXP (tmp, 0), 1);
7479 tmp = XEXP (XEXP (tmp, 0), 0);
7482 gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
7483 model = SYMBOL_REF_TLS_MODEL (tmp);
7484 gcc_assert (model != 0);
7486 tmp = rs6000_legitimize_tls_address (tmp, model);
7487 if (addend)
7489 tmp = gen_rtx_PLUS (mode, tmp, addend);
7490 tmp = force_operand (tmp, operands[0]);
7492 operands[1] = tmp;
7495 /* Handle the case where reload calls us with an invalid address. */
7496 if (reload_in_progress && mode == Pmode
7497 && (! general_operand (operands[1], mode)
7498 || ! nonimmediate_operand (operands[0], mode)))
7499 goto emit_set;
7501 /* 128-bit constant floating-point values on Darwin should really be
7502 loaded as two parts. */
7503 if (!TARGET_IEEEQUAD && TARGET_LONG_DOUBLE_128
7504 && mode == TFmode && GET_CODE (operands[1]) == CONST_DOUBLE)
7506 /* DImode is used, not DFmode, because simplify_gen_subreg doesn't
7507 know how to get a DFmode SUBREG of a TFmode. */
7508 enum machine_mode imode = (TARGET_E500_DOUBLE ? DFmode : DImode);
7509 rs6000_emit_move (simplify_gen_subreg (imode, operands[0], mode, 0),
7510 simplify_gen_subreg (imode, operands[1], mode, 0),
7511 imode);
7512 rs6000_emit_move (simplify_gen_subreg (imode, operands[0], mode,
7513 GET_MODE_SIZE (imode)),
7514 simplify_gen_subreg (imode, operands[1], mode,
7515 GET_MODE_SIZE (imode)),
7516 imode);
7517 return;
7520 if (reload_in_progress && cfun->machine->sdmode_stack_slot != NULL_RTX)
7521 cfun->machine->sdmode_stack_slot =
7522 eliminate_regs (cfun->machine->sdmode_stack_slot, VOIDmode, NULL_RTX);
7524 if (reload_in_progress
7525 && mode == SDmode
7526 && MEM_P (operands[0])
7527 && rtx_equal_p (operands[0], cfun->machine->sdmode_stack_slot)
7528 && REG_P (operands[1]))
7530 if (FP_REGNO_P (REGNO (operands[1])))
7532 rtx mem = adjust_address_nv (operands[0], DDmode, 0);
7533 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
7534 emit_insn (gen_movsd_store (mem, operands[1]));
7536 else if (INT_REGNO_P (REGNO (operands[1])))
7538 rtx mem = adjust_address_nv (operands[0], mode, 4);
7539 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
7540 emit_insn (gen_movsd_hardfloat (mem, operands[1]));
7542 else
7543 gcc_unreachable();
7544 return;
7546 if (reload_in_progress
7547 && mode == SDmode
7548 && REG_P (operands[0])
7549 && MEM_P (operands[1])
7550 && rtx_equal_p (operands[1], cfun->machine->sdmode_stack_slot))
7552 if (FP_REGNO_P (REGNO (operands[0])))
7554 rtx mem = adjust_address_nv (operands[1], DDmode, 0);
7555 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
7556 emit_insn (gen_movsd_load (operands[0], mem));
7558 else if (INT_REGNO_P (REGNO (operands[0])))
7560 rtx mem = adjust_address_nv (operands[1], mode, 4);
7561 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
7562 emit_insn (gen_movsd_hardfloat (operands[0], mem));
7564 else
7565 gcc_unreachable();
7566 return;
7569 /* FIXME: In the long term, this switch statement should go away
7570 and be replaced by a sequence of tests based on things like
7571 mode == Pmode. */
7572 switch (mode)
7574 case HImode:
7575 case QImode:
7576 if (CONSTANT_P (operands[1])
7577 && GET_CODE (operands[1]) != CONST_INT)
7578 operands[1] = force_const_mem (mode, operands[1]);
7579 break;
7581 case TFmode:
7582 case TDmode:
7583 rs6000_eliminate_indexed_memrefs (operands);
7584 /* fall through */
7586 case DFmode:
7587 case DDmode:
7588 case SFmode:
7589 case SDmode:
7590 if (CONSTANT_P (operands[1])
7591 && ! easy_fp_constant (operands[1], mode))
7592 operands[1] = force_const_mem (mode, operands[1]);
7593 break;
7595 case V16QImode:
7596 case V8HImode:
7597 case V4SFmode:
7598 case V4SImode:
7599 case V4HImode:
7600 case V2SFmode:
7601 case V2SImode:
7602 case V1DImode:
7603 case V2DFmode:
7604 case V2DImode:
7605 if (CONSTANT_P (operands[1])
7606 && !easy_vector_constant (operands[1], mode))
7607 operands[1] = force_const_mem (mode, operands[1]);
7608 break;
7610 case SImode:
7611 case DImode:
7612 /* Use default pattern for address of ELF small data */
7613 if (TARGET_ELF
7614 && mode == Pmode
7615 && DEFAULT_ABI == ABI_V4
7616 && (GET_CODE (operands[1]) == SYMBOL_REF
7617 || GET_CODE (operands[1]) == CONST)
7618 && small_data_operand (operands[1], mode))
7620 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
7621 return;
7624 if (DEFAULT_ABI == ABI_V4
7625 && mode == Pmode && mode == SImode
7626 && flag_pic == 1 && got_operand (operands[1], mode))
7628 emit_insn (gen_movsi_got (operands[0], operands[1]));
7629 return;
7632 if ((TARGET_ELF || DEFAULT_ABI == ABI_DARWIN)
7633 && TARGET_NO_TOC
7634 && ! flag_pic
7635 && mode == Pmode
7636 && CONSTANT_P (operands[1])
7637 && GET_CODE (operands[1]) != HIGH
7638 && GET_CODE (operands[1]) != CONST_INT)
7640 rtx target = (!can_create_pseudo_p ()
7641 ? operands[0]
7642 : gen_reg_rtx (mode));
7644 /* If this is a function address on -mcall-aixdesc,
7645 convert it to the address of the descriptor. */
7646 if (DEFAULT_ABI == ABI_AIX
7647 && GET_CODE (operands[1]) == SYMBOL_REF
7648 && XSTR (operands[1], 0)[0] == '.')
7650 const char *name = XSTR (operands[1], 0);
7651 rtx new_ref;
7652 while (*name == '.')
7653 name++;
7654 new_ref = gen_rtx_SYMBOL_REF (Pmode, name);
7655 CONSTANT_POOL_ADDRESS_P (new_ref)
7656 = CONSTANT_POOL_ADDRESS_P (operands[1]);
7657 SYMBOL_REF_FLAGS (new_ref) = SYMBOL_REF_FLAGS (operands[1]);
7658 SYMBOL_REF_USED (new_ref) = SYMBOL_REF_USED (operands[1]);
7659 SYMBOL_REF_DATA (new_ref) = SYMBOL_REF_DATA (operands[1]);
7660 operands[1] = new_ref;
7663 if (DEFAULT_ABI == ABI_DARWIN)
7665 #if TARGET_MACHO
7666 if (MACHO_DYNAMIC_NO_PIC_P)
7668 /* Take care of any required data indirection. */
7669 operands[1] = rs6000_machopic_legitimize_pic_address (
7670 operands[1], mode, operands[0]);
7671 if (operands[0] != operands[1])
7672 emit_insn (gen_rtx_SET (VOIDmode,
7673 operands[0], operands[1]));
7674 return;
7676 #endif
7677 emit_insn (gen_macho_high (target, operands[1]));
7678 emit_insn (gen_macho_low (operands[0], target, operands[1]));
7679 return;
7682 emit_insn (gen_elf_high (target, operands[1]));
7683 emit_insn (gen_elf_low (operands[0], target, operands[1]));
7684 return;
7687 /* If this is a SYMBOL_REF that refers to a constant pool entry,
7688 and we have put it in the TOC, we just need to make a TOC-relative
7689 reference to it. */
7690 if ((TARGET_TOC
7691 && GET_CODE (operands[1]) == SYMBOL_REF
7692 && constant_pool_expr_p (operands[1])
7693 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (operands[1]),
7694 get_pool_mode (operands[1])))
7695 || (TARGET_CMODEL == CMODEL_MEDIUM
7696 && GET_CODE (operands[1]) == SYMBOL_REF
7697 && !CONSTANT_POOL_ADDRESS_P (operands[1])
7698 && SYMBOL_REF_LOCAL_P (operands[1])
7699 && offsettable_ok_by_alignment (SYMBOL_REF_DECL (operands[1]))))
7701 rtx reg = NULL_RTX;
7702 if (TARGET_CMODEL != CMODEL_SMALL)
7704 if (can_create_pseudo_p ())
7705 reg = gen_reg_rtx (Pmode);
7706 else
7707 reg = operands[0];
7709 operands[1] = create_TOC_reference (operands[1], reg);
7711 else if (mode == Pmode
7712 && CONSTANT_P (operands[1])
7713 && ((GET_CODE (operands[1]) != CONST_INT
7714 && ! easy_fp_constant (operands[1], mode))
7715 || (GET_CODE (operands[1]) == CONST_INT
7716 && (num_insns_constant (operands[1], mode)
7717 > (TARGET_CMODEL != CMODEL_SMALL ? 3 : 2)))
7718 || (GET_CODE (operands[0]) == REG
7719 && FP_REGNO_P (REGNO (operands[0]))))
7720 && GET_CODE (operands[1]) != HIGH
7721 && ! legitimate_constant_pool_address_p (operands[1], false)
7722 && ! toc_relative_expr_p (operands[1])
7723 && (TARGET_CMODEL == CMODEL_SMALL
7724 || can_create_pseudo_p ()
7725 || (REG_P (operands[0])
7726 && INT_REG_OK_FOR_BASE_P (operands[0], true))))
7729 #if TARGET_MACHO
7730 /* Darwin uses a special PIC legitimizer. */
7731 if (DEFAULT_ABI == ABI_DARWIN && MACHOPIC_INDIRECT)
7733 operands[1] =
7734 rs6000_machopic_legitimize_pic_address (operands[1], mode,
7735 operands[0]);
7736 if (operands[0] != operands[1])
7737 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
7738 return;
7740 #endif
7742 /* If we are to limit the number of things we put in the TOC and
7743 this is a symbol plus a constant we can add in one insn,
7744 just put the symbol in the TOC and add the constant. Don't do
7745 this if reload is in progress. */
7746 if (GET_CODE (operands[1]) == CONST
7747 && TARGET_NO_SUM_IN_TOC && ! reload_in_progress
7748 && GET_CODE (XEXP (operands[1], 0)) == PLUS
7749 && add_operand (XEXP (XEXP (operands[1], 0), 1), mode)
7750 && (GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == LABEL_REF
7751 || GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == SYMBOL_REF)
7752 && ! side_effects_p (operands[0]))
7754 rtx sym =
7755 force_const_mem (mode, XEXP (XEXP (operands[1], 0), 0));
7756 rtx other = XEXP (XEXP (operands[1], 0), 1);
7758 sym = force_reg (mode, sym);
7759 emit_insn (gen_add3_insn (operands[0], sym, other));
7760 return;
7763 operands[1] = force_const_mem (mode, operands[1]);
7765 if (TARGET_TOC
7766 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
7767 && constant_pool_expr_p (XEXP (operands[1], 0))
7768 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (
7769 get_pool_constant (XEXP (operands[1], 0)),
7770 get_pool_mode (XEXP (operands[1], 0))))
7772 rtx tocref;
7773 rtx reg = NULL_RTX;
7774 if (TARGET_CMODEL != CMODEL_SMALL)
7776 if (can_create_pseudo_p ())
7777 reg = gen_reg_rtx (Pmode);
7778 else
7779 reg = operands[0];
7781 tocref = create_TOC_reference (XEXP (operands[1], 0), reg);
7782 operands[1] = gen_const_mem (mode, tocref);
7783 set_mem_alias_set (operands[1], get_TOC_alias_set ());
7786 break;
7788 case TImode:
7789 rs6000_eliminate_indexed_memrefs (operands);
7791 if (TARGET_POWER)
7793 emit_insn (gen_rtx_PARALLEL (VOIDmode,
7794 gen_rtvec (2,
7795 gen_rtx_SET (VOIDmode,
7796 operands[0], operands[1]),
7797 gen_rtx_CLOBBER (VOIDmode,
7798 gen_rtx_SCRATCH (SImode)))));
7799 return;
7801 break;
7803 default:
7804 fatal_insn ("bad move", gen_rtx_SET (VOIDmode, dest, source));
7807 /* Above, we may have called force_const_mem which may have returned
7808 an invalid address. If we can, fix this up; otherwise, reload will
7809 have to deal with it. */
7810 if (GET_CODE (operands[1]) == MEM && ! reload_in_progress)
7811 operands[1] = validize_mem (operands[1]);
7813 emit_set:
7814 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
7817 /* Nonzero if we can use a floating-point register to pass this arg. */
7818 #define USE_FP_FOR_ARG_P(CUM,MODE,TYPE) \
7819 (SCALAR_FLOAT_MODE_P (MODE) \
7820 && (CUM)->fregno <= FP_ARG_MAX_REG \
7821 && TARGET_HARD_FLOAT && TARGET_FPRS)
7823 /* Nonzero if we can use an AltiVec register to pass this arg. */
7824 #define USE_ALTIVEC_FOR_ARG_P(CUM,MODE,TYPE,NAMED) \
7825 ((ALTIVEC_VECTOR_MODE (MODE) || VSX_VECTOR_MODE (MODE)) \
7826 && (CUM)->vregno <= ALTIVEC_ARG_MAX_REG \
7827 && TARGET_ALTIVEC_ABI \
7828 && (NAMED))
7830 /* Return a nonzero value to say to return the function value in
7831 memory, just as large structures are always returned. TYPE will be
7832 the data type of the value, and FNTYPE will be the type of the
7833 function doing the returning, or @code{NULL} for libcalls.
7835 The AIX ABI for the RS/6000 specifies that all structures are
7836 returned in memory. The Darwin ABI does the same.
7838 For the Darwin 64 Bit ABI, a function result can be returned in
7839 registers or in memory, depending on the size of the return data
7840 type. If it is returned in registers, the value occupies the same
7841 registers as it would if it were the first and only function
7842 argument. Otherwise, the function places its result in memory at
7843 the location pointed to by GPR3.
7845 The SVR4 ABI specifies that structures <= 8 bytes are returned in r3/r4,
7846 but a draft put them in memory, and GCC used to implement the draft
7847 instead of the final standard. Therefore, aix_struct_return
7848 controls this instead of DEFAULT_ABI; V.4 targets needing backward
7849 compatibility can change DRAFT_V4_STRUCT_RET to override the
7850 default, and -m switches get the final word. See
7851 rs6000_option_override_internal for more details.
7853 The PPC32 SVR4 ABI uses IEEE double extended for long double, if 128-bit
7854 long double support is enabled. These values are returned in memory.
7856 int_size_in_bytes returns -1 for variable size objects, which go in
7857 memory always. The cast to unsigned makes -1 > 8. */
7859 static bool
7860 rs6000_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
7862 /* For the Darwin64 ABI, test if we can fit the return value in regs. */
7863 if (TARGET_MACHO
7864 && rs6000_darwin64_abi
7865 && TREE_CODE (type) == RECORD_TYPE
7866 && int_size_in_bytes (type) > 0)
7868 CUMULATIVE_ARGS valcum;
7869 rtx valret;
7871 valcum.words = 0;
7872 valcum.fregno = FP_ARG_MIN_REG;
7873 valcum.vregno = ALTIVEC_ARG_MIN_REG;
7874 /* Do a trial code generation as if this were going to be passed
7875 as an argument; if any part goes in memory, we return NULL. */
7876 valret = rs6000_darwin64_record_arg (&valcum, type, true, true);
7877 if (valret)
7878 return false;
7879 /* Otherwise fall through to more conventional ABI rules. */
7882 if (AGGREGATE_TYPE_P (type)
7883 && (aix_struct_return
7884 || (unsigned HOST_WIDE_INT) int_size_in_bytes (type) > 8))
7885 return true;
7887 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
7888 modes only exist for GCC vector types if -maltivec. */
7889 if (TARGET_32BIT && !TARGET_ALTIVEC_ABI
7890 && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
7891 return false;
7893 /* Return synthetic vectors in memory. */
7894 if (TREE_CODE (type) == VECTOR_TYPE
7895 && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
7897 static bool warned_for_return_big_vectors = false;
7898 if (!warned_for_return_big_vectors)
7900 warning (0, "GCC vector returned by reference: "
7901 "non-standard ABI extension with no compatibility guarantee");
7902 warned_for_return_big_vectors = true;
7904 return true;
7907 if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && TYPE_MODE (type) == TFmode)
7908 return true;
7910 return false;
7913 #ifdef HAVE_AS_GNU_ATTRIBUTE
7914 /* Return TRUE if a call to function FNDECL may be one that
7915 potentially affects the function calling ABI of the object file. */
7917 static bool
7918 call_ABI_of_interest (tree fndecl)
7920 if (cgraph_state == CGRAPH_STATE_EXPANSION)
7922 struct cgraph_node *c_node;
7924 /* Libcalls are always interesting. */
7925 if (fndecl == NULL_TREE)
7926 return true;
7928 /* Any call to an external function is interesting. */
7929 if (DECL_EXTERNAL (fndecl))
7930 return true;
7932 /* Interesting functions that we are emitting in this object file. */
7933 c_node = cgraph_node (fndecl);
7934 return !cgraph_only_called_directly_p (c_node);
7936 return false;
7938 #endif
7940 /* Initialize a variable CUM of type CUMULATIVE_ARGS
7941 for a call to a function whose data type is FNTYPE.
7942 For a library call, FNTYPE is 0 and RETURN_MODE the return value mode.
7944 For incoming args we set the number of arguments in the prototype large
7945 so we never return a PARALLEL. */
7947 void
7948 init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype,
7949 rtx libname ATTRIBUTE_UNUSED, int incoming,
7950 int libcall, int n_named_args,
7951 tree fndecl ATTRIBUTE_UNUSED,
7952 enum machine_mode return_mode ATTRIBUTE_UNUSED)
7954 static CUMULATIVE_ARGS zero_cumulative;
7956 *cum = zero_cumulative;
7957 cum->words = 0;
7958 cum->fregno = FP_ARG_MIN_REG;
7959 cum->vregno = ALTIVEC_ARG_MIN_REG;
7960 cum->prototype = (fntype && prototype_p (fntype));
7961 cum->call_cookie = ((DEFAULT_ABI == ABI_V4 && libcall)
7962 ? CALL_LIBCALL : CALL_NORMAL);
7963 cum->sysv_gregno = GP_ARG_MIN_REG;
7964 cum->stdarg = stdarg_p (fntype);
7966 cum->nargs_prototype = 0;
7967 if (incoming || cum->prototype)
7968 cum->nargs_prototype = n_named_args;
7970 /* Check for a longcall attribute. */
7971 if ((!fntype && rs6000_default_long_calls)
7972 || (fntype
7973 && lookup_attribute ("longcall", TYPE_ATTRIBUTES (fntype))
7974 && !lookup_attribute ("shortcall", TYPE_ATTRIBUTES (fntype))))
7975 cum->call_cookie |= CALL_LONG;
7977 if (TARGET_DEBUG_ARG)
7979 fprintf (stderr, "\ninit_cumulative_args:");
7980 if (fntype)
7982 tree ret_type = TREE_TYPE (fntype);
7983 fprintf (stderr, " ret code = %s,",
7984 tree_code_name[ (int)TREE_CODE (ret_type) ]);
7987 if (cum->call_cookie & CALL_LONG)
7988 fprintf (stderr, " longcall,");
7990 fprintf (stderr, " proto = %d, nargs = %d\n",
7991 cum->prototype, cum->nargs_prototype);
7994 #ifdef HAVE_AS_GNU_ATTRIBUTE
7995 if (DEFAULT_ABI == ABI_V4)
7997 cum->escapes = call_ABI_of_interest (fndecl);
7998 if (cum->escapes)
8000 tree return_type;
8002 if (fntype)
8004 return_type = TREE_TYPE (fntype);
8005 return_mode = TYPE_MODE (return_type);
8007 else
8008 return_type = lang_hooks.types.type_for_mode (return_mode, 0);
8010 if (return_type != NULL)
8012 if (TREE_CODE (return_type) == RECORD_TYPE
8013 && TYPE_TRANSPARENT_AGGR (return_type))
8015 return_type = TREE_TYPE (first_field (return_type));
8016 return_mode = TYPE_MODE (return_type);
8018 if (AGGREGATE_TYPE_P (return_type)
8019 && ((unsigned HOST_WIDE_INT) int_size_in_bytes (return_type)
8020 <= 8))
8021 rs6000_returns_struct = true;
8023 if (SCALAR_FLOAT_MODE_P (return_mode))
8024 rs6000_passes_float = true;
8025 else if (ALTIVEC_VECTOR_MODE (return_mode)
8026 || VSX_VECTOR_MODE (return_mode)
8027 || SPE_VECTOR_MODE (return_mode))
8028 rs6000_passes_vector = true;
8031 #endif
8033 if (fntype
8034 && !TARGET_ALTIVEC
8035 && TARGET_ALTIVEC_ABI
8036 && ALTIVEC_VECTOR_MODE (TYPE_MODE (TREE_TYPE (fntype))))
8038 error ("cannot return value in vector register because"
8039 " altivec instructions are disabled, use -maltivec"
8040 " to enable them");
8044 /* Return true if TYPE must be passed on the stack and not in registers. */
8046 static bool
8047 rs6000_must_pass_in_stack (enum machine_mode mode, const_tree type)
8049 if (DEFAULT_ABI == ABI_AIX || TARGET_64BIT)
8050 return must_pass_in_stack_var_size (mode, type);
8051 else
8052 return must_pass_in_stack_var_size_or_pad (mode, type);
8055 /* If defined, a C expression which determines whether, and in which
8056 direction, to pad out an argument with extra space. The value
8057 should be of type `enum direction': either `upward' to pad above
8058 the argument, `downward' to pad below, or `none' to inhibit
8059 padding.
8061 For the AIX ABI structs are always stored left shifted in their
8062 argument slot. */
8064 enum direction
8065 function_arg_padding (enum machine_mode mode, const_tree type)
8067 #ifndef AGGREGATE_PADDING_FIXED
8068 #define AGGREGATE_PADDING_FIXED 0
8069 #endif
8070 #ifndef AGGREGATES_PAD_UPWARD_ALWAYS
8071 #define AGGREGATES_PAD_UPWARD_ALWAYS 0
8072 #endif
8074 if (!AGGREGATE_PADDING_FIXED)
8076 /* GCC used to pass structures of the same size as integer types as
8077 if they were in fact integers, ignoring FUNCTION_ARG_PADDING.
8078 i.e. Structures of size 1 or 2 (or 4 when TARGET_64BIT) were
8079 passed padded downward, except that -mstrict-align further
8080 muddied the water in that multi-component structures of 2 and 4
8081 bytes in size were passed padded upward.
8083 The following arranges for best compatibility with previous
8084 versions of gcc, but removes the -mstrict-align dependency. */
8085 if (BYTES_BIG_ENDIAN)
8087 HOST_WIDE_INT size = 0;
8089 if (mode == BLKmode)
8091 if (type && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST)
8092 size = int_size_in_bytes (type);
8094 else
8095 size = GET_MODE_SIZE (mode);
8097 if (size == 1 || size == 2 || size == 4)
8098 return downward;
8100 return upward;
8103 if (AGGREGATES_PAD_UPWARD_ALWAYS)
8105 if (type != 0 && AGGREGATE_TYPE_P (type))
8106 return upward;
8109 /* Fall back to the default. */
8110 return DEFAULT_FUNCTION_ARG_PADDING (mode, type);
8113 /* If defined, a C expression that gives the alignment boundary, in bits,
8114 of an argument with the specified mode and type. If it is not defined,
8115 PARM_BOUNDARY is used for all arguments.
8117 V.4 wants long longs and doubles to be double word aligned. Just
8118 testing the mode size is a boneheaded way to do this as it means
8119 that other types such as complex int are also double word aligned.
8120 However, we're stuck with this because changing the ABI might break
8121 existing library interfaces.
8123 Doubleword align SPE vectors.
8124 Quadword align Altivec vectors.
8125 Quadword align large synthetic vector types. */
8127 static unsigned int
8128 rs6000_function_arg_boundary (enum machine_mode mode, const_tree type)
8130 if (DEFAULT_ABI == ABI_V4
8131 && (GET_MODE_SIZE (mode) == 8
8132 || (TARGET_HARD_FLOAT
8133 && TARGET_FPRS
8134 && (mode == TFmode || mode == TDmode))))
8135 return 64;
8136 else if (SPE_VECTOR_MODE (mode)
8137 || (type && TREE_CODE (type) == VECTOR_TYPE
8138 && int_size_in_bytes (type) >= 8
8139 && int_size_in_bytes (type) < 16))
8140 return 64;
8141 else if ((ALTIVEC_VECTOR_MODE (mode) || VSX_VECTOR_MODE (mode))
8142 || (type && TREE_CODE (type) == VECTOR_TYPE
8143 && int_size_in_bytes (type) >= 16))
8144 return 128;
8145 else if (TARGET_MACHO
8146 && rs6000_darwin64_abi
8147 && mode == BLKmode
8148 && type && TYPE_ALIGN (type) > 64)
8149 return 128;
8150 else
8151 return PARM_BOUNDARY;
8154 /* For a function parm of MODE and TYPE, return the starting word in
8155 the parameter area. NWORDS of the parameter area are already used. */
8157 static unsigned int
8158 rs6000_parm_start (enum machine_mode mode, const_tree type,
8159 unsigned int nwords)
8161 unsigned int align;
8162 unsigned int parm_offset;
8164 align = rs6000_function_arg_boundary (mode, type) / PARM_BOUNDARY - 1;
8165 parm_offset = DEFAULT_ABI == ABI_V4 ? 2 : 6;
8166 return nwords + (-(parm_offset + nwords) & align);
8169 /* Compute the size (in words) of a function argument. */
8171 static unsigned long
8172 rs6000_arg_size (enum machine_mode mode, const_tree type)
8174 unsigned long size;
8176 if (mode != BLKmode)
8177 size = GET_MODE_SIZE (mode);
8178 else
8179 size = int_size_in_bytes (type);
8181 if (TARGET_32BIT)
8182 return (size + 3) >> 2;
8183 else
8184 return (size + 7) >> 3;
8187 /* Use this to flush pending int fields. */
8189 static void
8190 rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS *cum,
8191 HOST_WIDE_INT bitpos, int final)
8193 unsigned int startbit, endbit;
8194 int intregs, intoffset;
8195 enum machine_mode mode;
8197 /* Handle the situations where a float is taking up the first half
8198 of the GPR, and the other half is empty (typically due to
8199 alignment restrictions). We can detect this by a 8-byte-aligned
8200 int field, or by seeing that this is the final flush for this
8201 argument. Count the word and continue on. */
8202 if (cum->floats_in_gpr == 1
8203 && (cum->intoffset % 64 == 0
8204 || (cum->intoffset == -1 && final)))
8206 cum->words++;
8207 cum->floats_in_gpr = 0;
8210 if (cum->intoffset == -1)
8211 return;
8213 intoffset = cum->intoffset;
8214 cum->intoffset = -1;
8215 cum->floats_in_gpr = 0;
8217 if (intoffset % BITS_PER_WORD != 0)
8219 mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD,
8220 MODE_INT, 0);
8221 if (mode == BLKmode)
8223 /* We couldn't find an appropriate mode, which happens,
8224 e.g., in packed structs when there are 3 bytes to load.
8225 Back intoffset back to the beginning of the word in this
8226 case. */
8227 intoffset = intoffset & -BITS_PER_WORD;
8231 startbit = intoffset & -BITS_PER_WORD;
8232 endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD;
8233 intregs = (endbit - startbit) / BITS_PER_WORD;
8234 cum->words += intregs;
8235 /* words should be unsigned. */
8236 if ((unsigned)cum->words < (endbit/BITS_PER_WORD))
8238 int pad = (endbit/BITS_PER_WORD) - cum->words;
8239 cum->words += pad;
8243 /* The darwin64 ABI calls for us to recurse down through structs,
8244 looking for elements passed in registers. Unfortunately, we have
8245 to track int register count here also because of misalignments
8246 in powerpc alignment mode. */
8248 static void
8249 rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS *cum,
8250 const_tree type,
8251 HOST_WIDE_INT startbitpos)
8253 tree f;
8255 for (f = TYPE_FIELDS (type); f ; f = DECL_CHAIN (f))
8256 if (TREE_CODE (f) == FIELD_DECL)
8258 HOST_WIDE_INT bitpos = startbitpos;
8259 tree ftype = TREE_TYPE (f);
8260 enum machine_mode mode;
8261 if (ftype == error_mark_node)
8262 continue;
8263 mode = TYPE_MODE (ftype);
8265 if (DECL_SIZE (f) != 0
8266 && host_integerp (bit_position (f), 1))
8267 bitpos += int_bit_position (f);
8269 /* ??? FIXME: else assume zero offset. */
8271 if (TREE_CODE (ftype) == RECORD_TYPE)
8272 rs6000_darwin64_record_arg_advance_recurse (cum, ftype, bitpos);
8273 else if (USE_FP_FOR_ARG_P (cum, mode, ftype))
8275 unsigned n_fpregs = (GET_MODE_SIZE (mode) + 7) >> 3;
8276 rs6000_darwin64_record_arg_advance_flush (cum, bitpos, 0);
8277 cum->fregno += n_fpregs;
8278 /* Single-precision floats present a special problem for
8279 us, because they are smaller than an 8-byte GPR, and so
8280 the structure-packing rules combined with the standard
8281 varargs behavior mean that we want to pack float/float
8282 and float/int combinations into a single register's
8283 space. This is complicated by the arg advance flushing,
8284 which works on arbitrarily large groups of int-type
8285 fields. */
8286 if (mode == SFmode)
8288 if (cum->floats_in_gpr == 1)
8290 /* Two floats in a word; count the word and reset
8291 the float count. */
8292 cum->words++;
8293 cum->floats_in_gpr = 0;
8295 else if (bitpos % 64 == 0)
8297 /* A float at the beginning of an 8-byte word;
8298 count it and put off adjusting cum->words until
8299 we see if a arg advance flush is going to do it
8300 for us. */
8301 cum->floats_in_gpr++;
8303 else
8305 /* The float is at the end of a word, preceded
8306 by integer fields, so the arg advance flush
8307 just above has already set cum->words and
8308 everything is taken care of. */
8311 else
8312 cum->words += n_fpregs;
8314 else if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, 1))
8316 rs6000_darwin64_record_arg_advance_flush (cum, bitpos, 0);
8317 cum->vregno++;
8318 cum->words += 2;
8320 else if (cum->intoffset == -1)
8321 cum->intoffset = bitpos;
8325 /* Check for an item that needs to be considered specially under the darwin 64
8326 bit ABI. These are record types where the mode is BLK or the structure is
8327 8 bytes in size. */
8328 static int
8329 rs6000_darwin64_struct_check_p (enum machine_mode mode, const_tree type)
8331 return rs6000_darwin64_abi
8332 && ((mode == BLKmode
8333 && TREE_CODE (type) == RECORD_TYPE
8334 && int_size_in_bytes (type) > 0)
8335 || (type && TREE_CODE (type) == RECORD_TYPE
8336 && int_size_in_bytes (type) == 8)) ? 1 : 0;
8339 /* Update the data in CUM to advance over an argument
8340 of mode MODE and data type TYPE.
8341 (TYPE is null for libcalls where that information may not be available.)
8343 Note that for args passed by reference, function_arg will be called
8344 with MODE and TYPE set to that of the pointer to the arg, not the arg
8345 itself. */
8347 static void
8348 rs6000_function_arg_advance_1 (CUMULATIVE_ARGS *cum, enum machine_mode mode,
8349 const_tree type, bool named, int depth)
8351 /* Only tick off an argument if we're not recursing. */
8352 if (depth == 0)
8353 cum->nargs_prototype--;
8355 #ifdef HAVE_AS_GNU_ATTRIBUTE
8356 if (DEFAULT_ABI == ABI_V4
8357 && cum->escapes)
8359 if (SCALAR_FLOAT_MODE_P (mode))
8360 rs6000_passes_float = true;
8361 else if (named && (ALTIVEC_VECTOR_MODE (mode) || VSX_VECTOR_MODE (mode)))
8362 rs6000_passes_vector = true;
8363 else if (SPE_VECTOR_MODE (mode)
8364 && !cum->stdarg
8365 && cum->sysv_gregno <= GP_ARG_MAX_REG)
8366 rs6000_passes_vector = true;
8368 #endif
8370 if (TARGET_ALTIVEC_ABI
8371 && (ALTIVEC_VECTOR_MODE (mode)
8372 || VSX_VECTOR_MODE (mode)
8373 || (type && TREE_CODE (type) == VECTOR_TYPE
8374 && int_size_in_bytes (type) == 16)))
8376 bool stack = false;
8378 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
8380 cum->vregno++;
8381 if (!TARGET_ALTIVEC)
8382 error ("cannot pass argument in vector register because"
8383 " altivec instructions are disabled, use -maltivec"
8384 " to enable them");
8386 /* PowerPC64 Linux and AIX allocate GPRs for a vector argument
8387 even if it is going to be passed in a vector register.
8388 Darwin does the same for variable-argument functions. */
8389 if ((DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
8390 || (cum->stdarg && DEFAULT_ABI != ABI_V4))
8391 stack = true;
8393 else
8394 stack = true;
8396 if (stack)
8398 int align;
8400 /* Vector parameters must be 16-byte aligned. This places
8401 them at 2 mod 4 in terms of words in 32-bit mode, since
8402 the parameter save area starts at offset 24 from the
8403 stack. In 64-bit mode, they just have to start on an
8404 even word, since the parameter save area is 16-byte
8405 aligned. Space for GPRs is reserved even if the argument
8406 will be passed in memory. */
8407 if (TARGET_32BIT)
8408 align = (2 - cum->words) & 3;
8409 else
8410 align = cum->words & 1;
8411 cum->words += align + rs6000_arg_size (mode, type);
8413 if (TARGET_DEBUG_ARG)
8415 fprintf (stderr, "function_adv: words = %2d, align=%d, ",
8416 cum->words, align);
8417 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s\n",
8418 cum->nargs_prototype, cum->prototype,
8419 GET_MODE_NAME (mode));
8423 else if (TARGET_SPE_ABI && TARGET_SPE && SPE_VECTOR_MODE (mode)
8424 && !cum->stdarg
8425 && cum->sysv_gregno <= GP_ARG_MAX_REG)
8426 cum->sysv_gregno++;
8428 else if (TARGET_MACHO && rs6000_darwin64_struct_check_p (mode, type))
8430 int size = int_size_in_bytes (type);
8431 /* Variable sized types have size == -1 and are
8432 treated as if consisting entirely of ints.
8433 Pad to 16 byte boundary if needed. */
8434 if (TYPE_ALIGN (type) >= 2 * BITS_PER_WORD
8435 && (cum->words % 2) != 0)
8436 cum->words++;
8437 /* For varargs, we can just go up by the size of the struct. */
8438 if (!named)
8439 cum->words += (size + 7) / 8;
8440 else
8442 /* It is tempting to say int register count just goes up by
8443 sizeof(type)/8, but this is wrong in a case such as
8444 { int; double; int; } [powerpc alignment]. We have to
8445 grovel through the fields for these too. */
8446 cum->intoffset = 0;
8447 cum->floats_in_gpr = 0;
8448 rs6000_darwin64_record_arg_advance_recurse (cum, type, 0);
8449 rs6000_darwin64_record_arg_advance_flush (cum,
8450 size * BITS_PER_UNIT, 1);
8452 if (TARGET_DEBUG_ARG)
8454 fprintf (stderr, "function_adv: words = %2d, align=%d, size=%d",
8455 cum->words, TYPE_ALIGN (type), size);
8456 fprintf (stderr,
8457 "nargs = %4d, proto = %d, mode = %4s (darwin64 abi)\n",
8458 cum->nargs_prototype, cum->prototype,
8459 GET_MODE_NAME (mode));
8462 else if (DEFAULT_ABI == ABI_V4)
8464 if (TARGET_HARD_FLOAT && TARGET_FPRS
8465 && ((TARGET_SINGLE_FLOAT && mode == SFmode)
8466 || (TARGET_DOUBLE_FLOAT && mode == DFmode)
8467 || (mode == TFmode && !TARGET_IEEEQUAD)
8468 || mode == SDmode || mode == DDmode || mode == TDmode))
8470 /* _Decimal128 must use an even/odd register pair. This assumes
8471 that the register number is odd when fregno is odd. */
8472 if (mode == TDmode && (cum->fregno % 2) == 1)
8473 cum->fregno++;
8475 if (cum->fregno + (mode == TFmode || mode == TDmode ? 1 : 0)
8476 <= FP_ARG_V4_MAX_REG)
8477 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
8478 else
8480 cum->fregno = FP_ARG_V4_MAX_REG + 1;
8481 if (mode == DFmode || mode == TFmode
8482 || mode == DDmode || mode == TDmode)
8483 cum->words += cum->words & 1;
8484 cum->words += rs6000_arg_size (mode, type);
8487 else
8489 int n_words = rs6000_arg_size (mode, type);
8490 int gregno = cum->sysv_gregno;
8492 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
8493 (r7,r8) or (r9,r10). As does any other 2 word item such
8494 as complex int due to a historical mistake. */
8495 if (n_words == 2)
8496 gregno += (1 - gregno) & 1;
8498 /* Multi-reg args are not split between registers and stack. */
8499 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
8501 /* Long long and SPE vectors are aligned on the stack.
8502 So are other 2 word items such as complex int due to
8503 a historical mistake. */
8504 if (n_words == 2)
8505 cum->words += cum->words & 1;
8506 cum->words += n_words;
8509 /* Note: continuing to accumulate gregno past when we've started
8510 spilling to the stack indicates the fact that we've started
8511 spilling to the stack to expand_builtin_saveregs. */
8512 cum->sysv_gregno = gregno + n_words;
8515 if (TARGET_DEBUG_ARG)
8517 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
8518 cum->words, cum->fregno);
8519 fprintf (stderr, "gregno = %2d, nargs = %4d, proto = %d, ",
8520 cum->sysv_gregno, cum->nargs_prototype, cum->prototype);
8521 fprintf (stderr, "mode = %4s, named = %d\n",
8522 GET_MODE_NAME (mode), named);
8525 else
8527 int n_words = rs6000_arg_size (mode, type);
8528 int start_words = cum->words;
8529 int align_words = rs6000_parm_start (mode, type, start_words);
8531 cum->words = align_words + n_words;
8533 if (SCALAR_FLOAT_MODE_P (mode)
8534 && TARGET_HARD_FLOAT && TARGET_FPRS)
8536 /* _Decimal128 must be passed in an even/odd float register pair.
8537 This assumes that the register number is odd when fregno is
8538 odd. */
8539 if (mode == TDmode && (cum->fregno % 2) == 1)
8540 cum->fregno++;
8541 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
8544 if (TARGET_DEBUG_ARG)
8546 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
8547 cum->words, cum->fregno);
8548 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s, ",
8549 cum->nargs_prototype, cum->prototype, GET_MODE_NAME (mode));
8550 fprintf (stderr, "named = %d, align = %d, depth = %d\n",
8551 named, align_words - start_words, depth);
8556 static void
8557 rs6000_function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
8558 const_tree type, bool named)
8560 rs6000_function_arg_advance_1 (cum, mode, type, named, 0);
8563 static rtx
8564 spe_build_register_parallel (enum machine_mode mode, int gregno)
8566 rtx r1, r3, r5, r7;
8568 switch (mode)
8570 case DFmode:
8571 r1 = gen_rtx_REG (DImode, gregno);
8572 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
8573 return gen_rtx_PARALLEL (mode, gen_rtvec (1, r1));
8575 case DCmode:
8576 case TFmode:
8577 r1 = gen_rtx_REG (DImode, gregno);
8578 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
8579 r3 = gen_rtx_REG (DImode, gregno + 2);
8580 r3 = gen_rtx_EXPR_LIST (VOIDmode, r3, GEN_INT (8));
8581 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r3));
8583 case TCmode:
8584 r1 = gen_rtx_REG (DImode, gregno);
8585 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
8586 r3 = gen_rtx_REG (DImode, gregno + 2);
8587 r3 = gen_rtx_EXPR_LIST (VOIDmode, r3, GEN_INT (8));
8588 r5 = gen_rtx_REG (DImode, gregno + 4);
8589 r5 = gen_rtx_EXPR_LIST (VOIDmode, r5, GEN_INT (16));
8590 r7 = gen_rtx_REG (DImode, gregno + 6);
8591 r7 = gen_rtx_EXPR_LIST (VOIDmode, r7, GEN_INT (24));
8592 return gen_rtx_PARALLEL (mode, gen_rtvec (4, r1, r3, r5, r7));
8594 default:
8595 gcc_unreachable ();
8599 /* Determine where to put a SIMD argument on the SPE. */
8600 static rtx
8601 rs6000_spe_function_arg (const CUMULATIVE_ARGS *cum, enum machine_mode mode,
8602 const_tree type)
8604 int gregno = cum->sysv_gregno;
8606 /* On E500 v2, double arithmetic is done on the full 64-bit GPR, but
8607 are passed and returned in a pair of GPRs for ABI compatibility. */
8608 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
8609 || mode == DCmode || mode == TCmode))
8611 int n_words = rs6000_arg_size (mode, type);
8613 /* Doubles go in an odd/even register pair (r5/r6, etc). */
8614 if (mode == DFmode)
8615 gregno += (1 - gregno) & 1;
8617 /* Multi-reg args are not split between registers and stack. */
8618 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
8619 return NULL_RTX;
8621 return spe_build_register_parallel (mode, gregno);
8623 if (cum->stdarg)
8625 int n_words = rs6000_arg_size (mode, type);
8627 /* SPE vectors are put in odd registers. */
8628 if (n_words == 2 && (gregno & 1) == 0)
8629 gregno += 1;
8631 if (gregno + n_words - 1 <= GP_ARG_MAX_REG)
8633 rtx r1, r2;
8634 enum machine_mode m = SImode;
8636 r1 = gen_rtx_REG (m, gregno);
8637 r1 = gen_rtx_EXPR_LIST (m, r1, const0_rtx);
8638 r2 = gen_rtx_REG (m, gregno + 1);
8639 r2 = gen_rtx_EXPR_LIST (m, r2, GEN_INT (4));
8640 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
8642 else
8643 return NULL_RTX;
8645 else
8647 if (gregno <= GP_ARG_MAX_REG)
8648 return gen_rtx_REG (mode, gregno);
8649 else
8650 return NULL_RTX;
8654 /* A subroutine of rs6000_darwin64_record_arg. Assign the bits of the
8655 structure between cum->intoffset and bitpos to integer registers. */
8657 static void
8658 rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS *cum,
8659 HOST_WIDE_INT bitpos, rtx rvec[], int *k)
8661 enum machine_mode mode;
8662 unsigned int regno;
8663 unsigned int startbit, endbit;
8664 int this_regno, intregs, intoffset;
8665 rtx reg;
8667 if (cum->intoffset == -1)
8668 return;
8670 intoffset = cum->intoffset;
8671 cum->intoffset = -1;
8673 /* If this is the trailing part of a word, try to only load that
8674 much into the register. Otherwise load the whole register. Note
8675 that in the latter case we may pick up unwanted bits. It's not a
8676 problem at the moment but may wish to revisit. */
8678 if (intoffset % BITS_PER_WORD != 0)
8680 mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD,
8681 MODE_INT, 0);
8682 if (mode == BLKmode)
8684 /* We couldn't find an appropriate mode, which happens,
8685 e.g., in packed structs when there are 3 bytes to load.
8686 Back intoffset back to the beginning of the word in this
8687 case. */
8688 intoffset = intoffset & -BITS_PER_WORD;
8689 mode = word_mode;
8692 else
8693 mode = word_mode;
8695 startbit = intoffset & -BITS_PER_WORD;
8696 endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD;
8697 intregs = (endbit - startbit) / BITS_PER_WORD;
8698 this_regno = cum->words + intoffset / BITS_PER_WORD;
8700 if (intregs > 0 && intregs > GP_ARG_NUM_REG - this_regno)
8701 cum->use_stack = 1;
8703 intregs = MIN (intregs, GP_ARG_NUM_REG - this_regno);
8704 if (intregs <= 0)
8705 return;
8707 intoffset /= BITS_PER_UNIT;
8710 regno = GP_ARG_MIN_REG + this_regno;
8711 reg = gen_rtx_REG (mode, regno);
8712 rvec[(*k)++] =
8713 gen_rtx_EXPR_LIST (VOIDmode, reg, GEN_INT (intoffset));
8715 this_regno += 1;
8716 intoffset = (intoffset | (UNITS_PER_WORD-1)) + 1;
8717 mode = word_mode;
8718 intregs -= 1;
8720 while (intregs > 0);
8723 /* Recursive workhorse for the following. */
8725 static void
8726 rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *cum, const_tree type,
8727 HOST_WIDE_INT startbitpos, rtx rvec[],
8728 int *k)
8730 tree f;
8732 for (f = TYPE_FIELDS (type); f ; f = DECL_CHAIN (f))
8733 if (TREE_CODE (f) == FIELD_DECL)
8735 HOST_WIDE_INT bitpos = startbitpos;
8736 tree ftype = TREE_TYPE (f);
8737 enum machine_mode mode;
8738 if (ftype == error_mark_node)
8739 continue;
8740 mode = TYPE_MODE (ftype);
8742 if (DECL_SIZE (f) != 0
8743 && host_integerp (bit_position (f), 1))
8744 bitpos += int_bit_position (f);
8746 /* ??? FIXME: else assume zero offset. */
8748 if (TREE_CODE (ftype) == RECORD_TYPE)
8749 rs6000_darwin64_record_arg_recurse (cum, ftype, bitpos, rvec, k);
8750 else if (cum->named && USE_FP_FOR_ARG_P (cum, mode, ftype))
8752 unsigned n_fpreg = (GET_MODE_SIZE (mode) + 7) >> 3;
8753 #if 0
8754 switch (mode)
8756 case SCmode: mode = SFmode; break;
8757 case DCmode: mode = DFmode; break;
8758 case TCmode: mode = TFmode; break;
8759 default: break;
8761 #endif
8762 rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
8763 if (cum->fregno + n_fpreg > FP_ARG_MAX_REG + 1)
8765 gcc_assert (cum->fregno == FP_ARG_MAX_REG
8766 && (mode == TFmode || mode == TDmode));
8767 /* Long double or _Decimal128 split over regs and memory. */
8768 mode = DECIMAL_FLOAT_MODE_P (mode) ? DDmode : DFmode;
8769 cum->use_stack=1;
8771 rvec[(*k)++]
8772 = gen_rtx_EXPR_LIST (VOIDmode,
8773 gen_rtx_REG (mode, cum->fregno++),
8774 GEN_INT (bitpos / BITS_PER_UNIT));
8775 if (mode == TFmode || mode == TDmode)
8776 cum->fregno++;
8778 else if (cum->named && USE_ALTIVEC_FOR_ARG_P (cum, mode, ftype, 1))
8780 rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
8781 rvec[(*k)++]
8782 = gen_rtx_EXPR_LIST (VOIDmode,
8783 gen_rtx_REG (mode, cum->vregno++),
8784 GEN_INT (bitpos / BITS_PER_UNIT));
8786 else if (cum->intoffset == -1)
8787 cum->intoffset = bitpos;
8791 /* For the darwin64 ABI, we want to construct a PARALLEL consisting of
8792 the register(s) to be used for each field and subfield of a struct
8793 being passed by value, along with the offset of where the
8794 register's value may be found in the block. FP fields go in FP
8795 register, vector fields go in vector registers, and everything
8796 else goes in int registers, packed as in memory.
8798 This code is also used for function return values. RETVAL indicates
8799 whether this is the case.
8801 Much of this is taken from the SPARC V9 port, which has a similar
8802 calling convention. */
8804 static rtx
8805 rs6000_darwin64_record_arg (CUMULATIVE_ARGS *orig_cum, const_tree type,
8806 bool named, bool retval)
8808 rtx rvec[FIRST_PSEUDO_REGISTER];
8809 int k = 1, kbase = 1;
8810 HOST_WIDE_INT typesize = int_size_in_bytes (type);
8811 /* This is a copy; modifications are not visible to our caller. */
8812 CUMULATIVE_ARGS copy_cum = *orig_cum;
8813 CUMULATIVE_ARGS *cum = &copy_cum;
8815 /* Pad to 16 byte boundary if needed. */
8816 if (!retval && TYPE_ALIGN (type) >= 2 * BITS_PER_WORD
8817 && (cum->words % 2) != 0)
8818 cum->words++;
8820 cum->intoffset = 0;
8821 cum->use_stack = 0;
8822 cum->named = named;
8824 /* Put entries into rvec[] for individual FP and vector fields, and
8825 for the chunks of memory that go in int regs. Note we start at
8826 element 1; 0 is reserved for an indication of using memory, and
8827 may or may not be filled in below. */
8828 rs6000_darwin64_record_arg_recurse (cum, type, /* startbit pos= */ 0, rvec, &k);
8829 rs6000_darwin64_record_arg_flush (cum, typesize * BITS_PER_UNIT, rvec, &k);
8831 /* If any part of the struct went on the stack put all of it there.
8832 This hack is because the generic code for
8833 FUNCTION_ARG_PARTIAL_NREGS cannot handle cases where the register
8834 parts of the struct are not at the beginning. */
8835 if (cum->use_stack)
8837 if (retval)
8838 return NULL_RTX; /* doesn't go in registers at all */
8839 kbase = 0;
8840 rvec[0] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
8842 if (k > 1 || cum->use_stack)
8843 return gen_rtx_PARALLEL (BLKmode, gen_rtvec_v (k - kbase, &rvec[kbase]));
8844 else
8845 return NULL_RTX;
8848 /* Determine where to place an argument in 64-bit mode with 32-bit ABI. */
8850 static rtx
8851 rs6000_mixed_function_arg (enum machine_mode mode, const_tree type,
8852 int align_words)
8854 int n_units;
8855 int i, k;
8856 rtx rvec[GP_ARG_NUM_REG + 1];
8858 if (align_words >= GP_ARG_NUM_REG)
8859 return NULL_RTX;
8861 n_units = rs6000_arg_size (mode, type);
8863 /* Optimize the simple case where the arg fits in one gpr, except in
8864 the case of BLKmode due to assign_parms assuming that registers are
8865 BITS_PER_WORD wide. */
8866 if (n_units == 0
8867 || (n_units == 1 && mode != BLKmode))
8868 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
8870 k = 0;
8871 if (align_words + n_units > GP_ARG_NUM_REG)
8872 /* Not all of the arg fits in gprs. Say that it goes in memory too,
8873 using a magic NULL_RTX component.
8874 This is not strictly correct. Only some of the arg belongs in
8875 memory, not all of it. However, the normal scheme using
8876 function_arg_partial_nregs can result in unusual subregs, eg.
8877 (subreg:SI (reg:DF) 4), which are not handled well. The code to
8878 store the whole arg to memory is often more efficient than code
8879 to store pieces, and we know that space is available in the right
8880 place for the whole arg. */
8881 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
8883 i = 0;
8886 rtx r = gen_rtx_REG (SImode, GP_ARG_MIN_REG + align_words);
8887 rtx off = GEN_INT (i++ * 4);
8888 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
8890 while (++align_words < GP_ARG_NUM_REG && --n_units != 0);
8892 return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
8895 /* Determine where to put an argument to a function.
8896 Value is zero to push the argument on the stack,
8897 or a hard register in which to store the argument.
8899 MODE is the argument's machine mode.
8900 TYPE is the data type of the argument (as a tree).
8901 This is null for libcalls where that information may
8902 not be available.
8903 CUM is a variable of type CUMULATIVE_ARGS which gives info about
8904 the preceding args and about the function being called. It is
8905 not modified in this routine.
8906 NAMED is nonzero if this argument is a named parameter
8907 (otherwise it is an extra parameter matching an ellipsis).
8909 On RS/6000 the first eight words of non-FP are normally in registers
8910 and the rest are pushed. Under AIX, the first 13 FP args are in registers.
8911 Under V.4, the first 8 FP args are in registers.
8913 If this is floating-point and no prototype is specified, we use
8914 both an FP and integer register (or possibly FP reg and stack). Library
8915 functions (when CALL_LIBCALL is set) always have the proper types for args,
8916 so we can pass the FP value just in one register. emit_library_function
8917 doesn't support PARALLEL anyway.
8919 Note that for args passed by reference, function_arg will be called
8920 with MODE and TYPE set to that of the pointer to the arg, not the arg
8921 itself. */
8923 static rtx
8924 rs6000_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
8925 const_tree type, bool named)
8927 enum rs6000_abi abi = DEFAULT_ABI;
8929 /* Return a marker to indicate whether CR1 needs to set or clear the
8930 bit that V.4 uses to say fp args were passed in registers.
8931 Assume that we don't need the marker for software floating point,
8932 or compiler generated library calls. */
8933 if (mode == VOIDmode)
8935 if (abi == ABI_V4
8936 && (cum->call_cookie & CALL_LIBCALL) == 0
8937 && (cum->stdarg
8938 || (cum->nargs_prototype < 0
8939 && (cum->prototype || TARGET_NO_PROTOTYPE))))
8941 /* For the SPE, we need to crxor CR6 always. */
8942 if (TARGET_SPE_ABI)
8943 return GEN_INT (cum->call_cookie | CALL_V4_SET_FP_ARGS);
8944 else if (TARGET_HARD_FLOAT && TARGET_FPRS)
8945 return GEN_INT (cum->call_cookie
8946 | ((cum->fregno == FP_ARG_MIN_REG)
8947 ? CALL_V4_SET_FP_ARGS
8948 : CALL_V4_CLEAR_FP_ARGS));
8951 return GEN_INT (cum->call_cookie);
8954 if (TARGET_MACHO && rs6000_darwin64_struct_check_p (mode, type))
8956 rtx rslt = rs6000_darwin64_record_arg (cum, type, named, /*retval= */false);
8957 if (rslt != NULL_RTX)
8958 return rslt;
8959 /* Else fall through to usual handling. */
8962 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
8963 if (TARGET_64BIT && ! cum->prototype)
8965 /* Vector parameters get passed in vector register
8966 and also in GPRs or memory, in absence of prototype. */
8967 int align_words;
8968 rtx slot;
8969 align_words = (cum->words + 1) & ~1;
8971 if (align_words >= GP_ARG_NUM_REG)
8973 slot = NULL_RTX;
8975 else
8977 slot = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
8979 return gen_rtx_PARALLEL (mode,
8980 gen_rtvec (2,
8981 gen_rtx_EXPR_LIST (VOIDmode,
8982 slot, const0_rtx),
8983 gen_rtx_EXPR_LIST (VOIDmode,
8984 gen_rtx_REG (mode, cum->vregno),
8985 const0_rtx)));
8987 else
8988 return gen_rtx_REG (mode, cum->vregno);
8989 else if (TARGET_ALTIVEC_ABI
8990 && (ALTIVEC_VECTOR_MODE (mode)
8991 || VSX_VECTOR_MODE (mode)
8992 || (type && TREE_CODE (type) == VECTOR_TYPE
8993 && int_size_in_bytes (type) == 16)))
8995 if (named || abi == ABI_V4)
8996 return NULL_RTX;
8997 else
8999 /* Vector parameters to varargs functions under AIX or Darwin
9000 get passed in memory and possibly also in GPRs. */
9001 int align, align_words, n_words;
9002 enum machine_mode part_mode;
9004 /* Vector parameters must be 16-byte aligned. This places them at
9005 2 mod 4 in terms of words in 32-bit mode, since the parameter
9006 save area starts at offset 24 from the stack. In 64-bit mode,
9007 they just have to start on an even word, since the parameter
9008 save area is 16-byte aligned. */
9009 if (TARGET_32BIT)
9010 align = (2 - cum->words) & 3;
9011 else
9012 align = cum->words & 1;
9013 align_words = cum->words + align;
9015 /* Out of registers? Memory, then. */
9016 if (align_words >= GP_ARG_NUM_REG)
9017 return NULL_RTX;
9019 if (TARGET_32BIT && TARGET_POWERPC64)
9020 return rs6000_mixed_function_arg (mode, type, align_words);
9022 /* The vector value goes in GPRs. Only the part of the
9023 value in GPRs is reported here. */
9024 part_mode = mode;
9025 n_words = rs6000_arg_size (mode, type);
9026 if (align_words + n_words > GP_ARG_NUM_REG)
9027 /* Fortunately, there are only two possibilities, the value
9028 is either wholly in GPRs or half in GPRs and half not. */
9029 part_mode = DImode;
9031 return gen_rtx_REG (part_mode, GP_ARG_MIN_REG + align_words);
9034 else if (TARGET_SPE_ABI && TARGET_SPE
9035 && (SPE_VECTOR_MODE (mode)
9036 || (TARGET_E500_DOUBLE && (mode == DFmode
9037 || mode == DCmode
9038 || mode == TFmode
9039 || mode == TCmode))))
9040 return rs6000_spe_function_arg (cum, mode, type);
9042 else if (abi == ABI_V4)
9044 if (TARGET_HARD_FLOAT && TARGET_FPRS
9045 && ((TARGET_SINGLE_FLOAT && mode == SFmode)
9046 || (TARGET_DOUBLE_FLOAT && mode == DFmode)
9047 || (mode == TFmode && !TARGET_IEEEQUAD)
9048 || mode == SDmode || mode == DDmode || mode == TDmode))
9050 /* _Decimal128 must use an even/odd register pair. This assumes
9051 that the register number is odd when fregno is odd. */
9052 if (mode == TDmode && (cum->fregno % 2) == 1)
9053 cum->fregno++;
9055 if (cum->fregno + (mode == TFmode || mode == TDmode ? 1 : 0)
9056 <= FP_ARG_V4_MAX_REG)
9057 return gen_rtx_REG (mode, cum->fregno);
9058 else
9059 return NULL_RTX;
9061 else
9063 int n_words = rs6000_arg_size (mode, type);
9064 int gregno = cum->sysv_gregno;
9066 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
9067 (r7,r8) or (r9,r10). As does any other 2 word item such
9068 as complex int due to a historical mistake. */
9069 if (n_words == 2)
9070 gregno += (1 - gregno) & 1;
9072 /* Multi-reg args are not split between registers and stack. */
9073 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
9074 return NULL_RTX;
9076 if (TARGET_32BIT && TARGET_POWERPC64)
9077 return rs6000_mixed_function_arg (mode, type,
9078 gregno - GP_ARG_MIN_REG);
9079 return gen_rtx_REG (mode, gregno);
9082 else
9084 int align_words = rs6000_parm_start (mode, type, cum->words);
9086 /* _Decimal128 must be passed in an even/odd float register pair.
9087 This assumes that the register number is odd when fregno is odd. */
9088 if (mode == TDmode && (cum->fregno % 2) == 1)
9089 cum->fregno++;
9091 if (USE_FP_FOR_ARG_P (cum, mode, type))
9093 rtx rvec[GP_ARG_NUM_REG + 1];
9094 rtx r;
9095 int k;
9096 bool needs_psave;
9097 enum machine_mode fmode = mode;
9098 unsigned long n_fpreg = (GET_MODE_SIZE (mode) + 7) >> 3;
9100 if (cum->fregno + n_fpreg > FP_ARG_MAX_REG + 1)
9102 /* Currently, we only ever need one reg here because complex
9103 doubles are split. */
9104 gcc_assert (cum->fregno == FP_ARG_MAX_REG
9105 && (fmode == TFmode || fmode == TDmode));
9107 /* Long double or _Decimal128 split over regs and memory. */
9108 fmode = DECIMAL_FLOAT_MODE_P (fmode) ? DDmode : DFmode;
9111 /* Do we also need to pass this arg in the parameter save
9112 area? */
9113 needs_psave = (type
9114 && (cum->nargs_prototype <= 0
9115 || (DEFAULT_ABI == ABI_AIX
9116 && TARGET_XL_COMPAT
9117 && align_words >= GP_ARG_NUM_REG)));
9119 if (!needs_psave && mode == fmode)
9120 return gen_rtx_REG (fmode, cum->fregno);
9122 k = 0;
9123 if (needs_psave)
9125 /* Describe the part that goes in gprs or the stack.
9126 This piece must come first, before the fprs. */
9127 if (align_words < GP_ARG_NUM_REG)
9129 unsigned long n_words = rs6000_arg_size (mode, type);
9131 if (align_words + n_words > GP_ARG_NUM_REG
9132 || (TARGET_32BIT && TARGET_POWERPC64))
9134 /* If this is partially on the stack, then we only
9135 include the portion actually in registers here. */
9136 enum machine_mode rmode = TARGET_32BIT ? SImode : DImode;
9137 rtx off;
9138 int i = 0;
9139 if (align_words + n_words > GP_ARG_NUM_REG)
9140 /* Not all of the arg fits in gprs. Say that it
9141 goes in memory too, using a magic NULL_RTX
9142 component. Also see comment in
9143 rs6000_mixed_function_arg for why the normal
9144 function_arg_partial_nregs scheme doesn't work
9145 in this case. */
9146 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX,
9147 const0_rtx);
9150 r = gen_rtx_REG (rmode,
9151 GP_ARG_MIN_REG + align_words);
9152 off = GEN_INT (i++ * GET_MODE_SIZE (rmode));
9153 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
9155 while (++align_words < GP_ARG_NUM_REG && --n_words != 0);
9157 else
9159 /* The whole arg fits in gprs. */
9160 r = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
9161 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
9164 else
9165 /* It's entirely in memory. */
9166 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
9169 /* Describe where this piece goes in the fprs. */
9170 r = gen_rtx_REG (fmode, cum->fregno);
9171 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
9173 return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
9175 else if (align_words < GP_ARG_NUM_REG)
9177 if (TARGET_32BIT && TARGET_POWERPC64)
9178 return rs6000_mixed_function_arg (mode, type, align_words);
9180 if (mode == BLKmode)
9181 mode = Pmode;
9183 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
9185 else
9186 return NULL_RTX;
9190 /* For an arg passed partly in registers and partly in memory, this is
9191 the number of bytes passed in registers. For args passed entirely in
9192 registers or entirely in memory, zero. When an arg is described by a
9193 PARALLEL, perhaps using more than one register type, this function
9194 returns the number of bytes used by the first element of the PARALLEL. */
9196 static int
9197 rs6000_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode,
9198 tree type, bool named)
9200 int ret = 0;
9201 int align_words;
9203 if (DEFAULT_ABI == ABI_V4)
9204 return 0;
9206 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named)
9207 && cum->nargs_prototype >= 0)
9208 return 0;
9210 /* In this complicated case we just disable the partial_nregs code. */
9211 if (TARGET_MACHO && rs6000_darwin64_struct_check_p (mode, type))
9212 return 0;
9214 align_words = rs6000_parm_start (mode, type, cum->words);
9216 if (USE_FP_FOR_ARG_P (cum, mode, type))
9218 /* If we are passing this arg in the fixed parameter save area
9219 (gprs or memory) as well as fprs, then this function should
9220 return the number of partial bytes passed in the parameter
9221 save area rather than partial bytes passed in fprs. */
9222 if (type
9223 && (cum->nargs_prototype <= 0
9224 || (DEFAULT_ABI == ABI_AIX
9225 && TARGET_XL_COMPAT
9226 && align_words >= GP_ARG_NUM_REG)))
9227 return 0;
9228 else if (cum->fregno + ((GET_MODE_SIZE (mode) + 7) >> 3)
9229 > FP_ARG_MAX_REG + 1)
9230 ret = (FP_ARG_MAX_REG + 1 - cum->fregno) * 8;
9231 else if (cum->nargs_prototype >= 0)
9232 return 0;
9235 if (align_words < GP_ARG_NUM_REG
9236 && GP_ARG_NUM_REG < align_words + rs6000_arg_size (mode, type))
9237 ret = (GP_ARG_NUM_REG - align_words) * (TARGET_32BIT ? 4 : 8);
9239 if (ret != 0 && TARGET_DEBUG_ARG)
9240 fprintf (stderr, "rs6000_arg_partial_bytes: %d\n", ret);
9242 return ret;
9245 /* A C expression that indicates when an argument must be passed by
9246 reference. If nonzero for an argument, a copy of that argument is
9247 made in memory and a pointer to the argument is passed instead of
9248 the argument itself. The pointer is passed in whatever way is
9249 appropriate for passing a pointer to that type.
9251 Under V.4, aggregates and long double are passed by reference.
9253 As an extension to all 32-bit ABIs, AltiVec vectors are passed by
9254 reference unless the AltiVec vector extension ABI is in force.
9256 As an extension to all ABIs, variable sized types are passed by
9257 reference. */
9259 static bool
9260 rs6000_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
9261 enum machine_mode mode, const_tree type,
9262 bool named ATTRIBUTE_UNUSED)
9264 if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && mode == TFmode)
9266 if (TARGET_DEBUG_ARG)
9267 fprintf (stderr, "function_arg_pass_by_reference: V4 long double\n");
9268 return 1;
9271 if (!type)
9272 return 0;
9274 if (DEFAULT_ABI == ABI_V4 && AGGREGATE_TYPE_P (type))
9276 if (TARGET_DEBUG_ARG)
9277 fprintf (stderr, "function_arg_pass_by_reference: V4 aggregate\n");
9278 return 1;
9281 if (int_size_in_bytes (type) < 0)
9283 if (TARGET_DEBUG_ARG)
9284 fprintf (stderr, "function_arg_pass_by_reference: variable size\n");
9285 return 1;
9288 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
9289 modes only exist for GCC vector types if -maltivec. */
9290 if (TARGET_32BIT && !TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
9292 if (TARGET_DEBUG_ARG)
9293 fprintf (stderr, "function_arg_pass_by_reference: AltiVec\n");
9294 return 1;
9297 /* Pass synthetic vectors in memory. */
9298 if (TREE_CODE (type) == VECTOR_TYPE
9299 && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
9301 static bool warned_for_pass_big_vectors = false;
9302 if (TARGET_DEBUG_ARG)
9303 fprintf (stderr, "function_arg_pass_by_reference: synthetic vector\n");
9304 if (!warned_for_pass_big_vectors)
9306 warning (0, "GCC vector passed by reference: "
9307 "non-standard ABI extension with no compatibility guarantee");
9308 warned_for_pass_big_vectors = true;
9310 return 1;
9313 return 0;
9316 static void
9317 rs6000_move_block_from_reg (int regno, rtx x, int nregs)
9319 int i;
9320 enum machine_mode reg_mode = TARGET_32BIT ? SImode : DImode;
9322 if (nregs == 0)
9323 return;
9325 for (i = 0; i < nregs; i++)
9327 rtx tem = adjust_address_nv (x, reg_mode, i * GET_MODE_SIZE (reg_mode));
9328 if (reload_completed)
9330 if (! strict_memory_address_p (reg_mode, XEXP (tem, 0)))
9331 tem = NULL_RTX;
9332 else
9333 tem = simplify_gen_subreg (reg_mode, x, BLKmode,
9334 i * GET_MODE_SIZE (reg_mode));
9336 else
9337 tem = replace_equiv_address (tem, XEXP (tem, 0));
9339 gcc_assert (tem);
9341 emit_move_insn (tem, gen_rtx_REG (reg_mode, regno + i));
9345 /* Perform any needed actions needed for a function that is receiving a
9346 variable number of arguments.
9348 CUM is as above.
9350 MODE and TYPE are the mode and type of the current parameter.
9352 PRETEND_SIZE is a variable that should be set to the amount of stack
9353 that must be pushed by the prolog to pretend that our caller pushed
9356 Normally, this macro will push all remaining incoming registers on the
9357 stack and set PRETEND_SIZE to the length of the registers pushed. */
9359 static void
9360 setup_incoming_varargs (CUMULATIVE_ARGS *cum, enum machine_mode mode,
9361 tree type, int *pretend_size ATTRIBUTE_UNUSED,
9362 int no_rtl)
9364 CUMULATIVE_ARGS next_cum;
9365 int reg_size = TARGET_32BIT ? 4 : 8;
9366 rtx save_area = NULL_RTX, mem;
9367 int first_reg_offset;
9368 alias_set_type set;
9370 /* Skip the last named argument. */
9371 next_cum = *cum;
9372 rs6000_function_arg_advance_1 (&next_cum, mode, type, true, 0);
9374 if (DEFAULT_ABI == ABI_V4)
9376 first_reg_offset = next_cum.sysv_gregno - GP_ARG_MIN_REG;
9378 if (! no_rtl)
9380 int gpr_reg_num = 0, gpr_size = 0, fpr_size = 0;
9381 HOST_WIDE_INT offset = 0;
9383 /* Try to optimize the size of the varargs save area.
9384 The ABI requires that ap.reg_save_area is doubleword
9385 aligned, but we don't need to allocate space for all
9386 the bytes, only those to which we actually will save
9387 anything. */
9388 if (cfun->va_list_gpr_size && first_reg_offset < GP_ARG_NUM_REG)
9389 gpr_reg_num = GP_ARG_NUM_REG - first_reg_offset;
9390 if (TARGET_HARD_FLOAT && TARGET_FPRS
9391 && next_cum.fregno <= FP_ARG_V4_MAX_REG
9392 && cfun->va_list_fpr_size)
9394 if (gpr_reg_num)
9395 fpr_size = (next_cum.fregno - FP_ARG_MIN_REG)
9396 * UNITS_PER_FP_WORD;
9397 if (cfun->va_list_fpr_size
9398 < FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
9399 fpr_size += cfun->va_list_fpr_size * UNITS_PER_FP_WORD;
9400 else
9401 fpr_size += (FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
9402 * UNITS_PER_FP_WORD;
9404 if (gpr_reg_num)
9406 offset = -((first_reg_offset * reg_size) & ~7);
9407 if (!fpr_size && gpr_reg_num > cfun->va_list_gpr_size)
9409 gpr_reg_num = cfun->va_list_gpr_size;
9410 if (reg_size == 4 && (first_reg_offset & 1))
9411 gpr_reg_num++;
9413 gpr_size = (gpr_reg_num * reg_size + 7) & ~7;
9415 else if (fpr_size)
9416 offset = - (int) (next_cum.fregno - FP_ARG_MIN_REG)
9417 * UNITS_PER_FP_WORD
9418 - (int) (GP_ARG_NUM_REG * reg_size);
9420 if (gpr_size + fpr_size)
9422 rtx reg_save_area
9423 = assign_stack_local (BLKmode, gpr_size + fpr_size, 64);
9424 gcc_assert (GET_CODE (reg_save_area) == MEM);
9425 reg_save_area = XEXP (reg_save_area, 0);
9426 if (GET_CODE (reg_save_area) == PLUS)
9428 gcc_assert (XEXP (reg_save_area, 0)
9429 == virtual_stack_vars_rtx);
9430 gcc_assert (GET_CODE (XEXP (reg_save_area, 1)) == CONST_INT);
9431 offset += INTVAL (XEXP (reg_save_area, 1));
9433 else
9434 gcc_assert (reg_save_area == virtual_stack_vars_rtx);
9437 cfun->machine->varargs_save_offset = offset;
9438 save_area = plus_constant (virtual_stack_vars_rtx, offset);
9441 else
9443 first_reg_offset = next_cum.words;
9444 save_area = virtual_incoming_args_rtx;
9446 if (targetm.calls.must_pass_in_stack (mode, type))
9447 first_reg_offset += rs6000_arg_size (TYPE_MODE (type), type);
9450 set = get_varargs_alias_set ();
9451 if (! no_rtl && first_reg_offset < GP_ARG_NUM_REG
9452 && cfun->va_list_gpr_size)
9454 int nregs = GP_ARG_NUM_REG - first_reg_offset;
9456 if (va_list_gpr_counter_field)
9458 /* V4 va_list_gpr_size counts number of registers needed. */
9459 if (nregs > cfun->va_list_gpr_size)
9460 nregs = cfun->va_list_gpr_size;
9462 else
9464 /* char * va_list instead counts number of bytes needed. */
9465 if (nregs > cfun->va_list_gpr_size / reg_size)
9466 nregs = cfun->va_list_gpr_size / reg_size;
9469 mem = gen_rtx_MEM (BLKmode,
9470 plus_constant (save_area,
9471 first_reg_offset * reg_size));
9472 MEM_NOTRAP_P (mem) = 1;
9473 set_mem_alias_set (mem, set);
9474 set_mem_align (mem, BITS_PER_WORD);
9476 rs6000_move_block_from_reg (GP_ARG_MIN_REG + first_reg_offset, mem,
9477 nregs);
9480 /* Save FP registers if needed. */
9481 if (DEFAULT_ABI == ABI_V4
9482 && TARGET_HARD_FLOAT && TARGET_FPRS
9483 && ! no_rtl
9484 && next_cum.fregno <= FP_ARG_V4_MAX_REG
9485 && cfun->va_list_fpr_size)
9487 int fregno = next_cum.fregno, nregs;
9488 rtx cr1 = gen_rtx_REG (CCmode, CR1_REGNO);
9489 rtx lab = gen_label_rtx ();
9490 int off = (GP_ARG_NUM_REG * reg_size) + ((fregno - FP_ARG_MIN_REG)
9491 * UNITS_PER_FP_WORD);
9493 emit_jump_insn
9494 (gen_rtx_SET (VOIDmode,
9495 pc_rtx,
9496 gen_rtx_IF_THEN_ELSE (VOIDmode,
9497 gen_rtx_NE (VOIDmode, cr1,
9498 const0_rtx),
9499 gen_rtx_LABEL_REF (VOIDmode, lab),
9500 pc_rtx)));
9502 for (nregs = 0;
9503 fregno <= FP_ARG_V4_MAX_REG && nregs < cfun->va_list_fpr_size;
9504 fregno++, off += UNITS_PER_FP_WORD, nregs++)
9506 mem = gen_rtx_MEM ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
9507 ? DFmode : SFmode,
9508 plus_constant (save_area, off));
9509 MEM_NOTRAP_P (mem) = 1;
9510 set_mem_alias_set (mem, set);
9511 set_mem_align (mem, GET_MODE_ALIGNMENT (
9512 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
9513 ? DFmode : SFmode));
9514 emit_move_insn (mem, gen_rtx_REG (
9515 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
9516 ? DFmode : SFmode, fregno));
9519 emit_label (lab);
9523 /* Create the va_list data type. */
9525 static tree
9526 rs6000_build_builtin_va_list (void)
9528 tree f_gpr, f_fpr, f_res, f_ovf, f_sav, record, type_decl;
9530 /* For AIX, prefer 'char *' because that's what the system
9531 header files like. */
9532 if (DEFAULT_ABI != ABI_V4)
9533 return build_pointer_type (char_type_node);
9535 record = (*lang_hooks.types.make_type) (RECORD_TYPE);
9536 type_decl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
9537 get_identifier ("__va_list_tag"), record);
9539 f_gpr = build_decl (BUILTINS_LOCATION, FIELD_DECL, get_identifier ("gpr"),
9540 unsigned_char_type_node);
9541 f_fpr = build_decl (BUILTINS_LOCATION, FIELD_DECL, get_identifier ("fpr"),
9542 unsigned_char_type_node);
9543 /* Give the two bytes of padding a name, so that -Wpadded won't warn on
9544 every user file. */
9545 f_res = build_decl (BUILTINS_LOCATION, FIELD_DECL,
9546 get_identifier ("reserved"), short_unsigned_type_node);
9547 f_ovf = build_decl (BUILTINS_LOCATION, FIELD_DECL,
9548 get_identifier ("overflow_arg_area"),
9549 ptr_type_node);
9550 f_sav = build_decl (BUILTINS_LOCATION, FIELD_DECL,
9551 get_identifier ("reg_save_area"),
9552 ptr_type_node);
9554 va_list_gpr_counter_field = f_gpr;
9555 va_list_fpr_counter_field = f_fpr;
9557 DECL_FIELD_CONTEXT (f_gpr) = record;
9558 DECL_FIELD_CONTEXT (f_fpr) = record;
9559 DECL_FIELD_CONTEXT (f_res) = record;
9560 DECL_FIELD_CONTEXT (f_ovf) = record;
9561 DECL_FIELD_CONTEXT (f_sav) = record;
9563 TYPE_STUB_DECL (record) = type_decl;
9564 TYPE_NAME (record) = type_decl;
9565 TYPE_FIELDS (record) = f_gpr;
9566 DECL_CHAIN (f_gpr) = f_fpr;
9567 DECL_CHAIN (f_fpr) = f_res;
9568 DECL_CHAIN (f_res) = f_ovf;
9569 DECL_CHAIN (f_ovf) = f_sav;
9571 layout_type (record);
9573 /* The correct type is an array type of one element. */
9574 return build_array_type (record, build_index_type (size_zero_node));
9577 /* Implement va_start. */
9579 static void
9580 rs6000_va_start (tree valist, rtx nextarg)
9582 HOST_WIDE_INT words, n_gpr, n_fpr;
9583 tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
9584 tree gpr, fpr, ovf, sav, t;
9586 /* Only SVR4 needs something special. */
9587 if (DEFAULT_ABI != ABI_V4)
9589 std_expand_builtin_va_start (valist, nextarg);
9590 return;
9593 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
9594 f_fpr = DECL_CHAIN (f_gpr);
9595 f_res = DECL_CHAIN (f_fpr);
9596 f_ovf = DECL_CHAIN (f_res);
9597 f_sav = DECL_CHAIN (f_ovf);
9599 valist = build_simple_mem_ref (valist);
9600 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
9601 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), unshare_expr (valist),
9602 f_fpr, NULL_TREE);
9603 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), unshare_expr (valist),
9604 f_ovf, NULL_TREE);
9605 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), unshare_expr (valist),
9606 f_sav, NULL_TREE);
9608 /* Count number of gp and fp argument registers used. */
9609 words = crtl->args.info.words;
9610 n_gpr = MIN (crtl->args.info.sysv_gregno - GP_ARG_MIN_REG,
9611 GP_ARG_NUM_REG);
9612 n_fpr = MIN (crtl->args.info.fregno - FP_ARG_MIN_REG,
9613 FP_ARG_NUM_REG);
9615 if (TARGET_DEBUG_ARG)
9616 fprintf (stderr, "va_start: words = "HOST_WIDE_INT_PRINT_DEC", n_gpr = "
9617 HOST_WIDE_INT_PRINT_DEC", n_fpr = "HOST_WIDE_INT_PRINT_DEC"\n",
9618 words, n_gpr, n_fpr);
9620 if (cfun->va_list_gpr_size)
9622 t = build2 (MODIFY_EXPR, TREE_TYPE (gpr), gpr,
9623 build_int_cst (NULL_TREE, n_gpr));
9624 TREE_SIDE_EFFECTS (t) = 1;
9625 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
9628 if (cfun->va_list_fpr_size)
9630 t = build2 (MODIFY_EXPR, TREE_TYPE (fpr), fpr,
9631 build_int_cst (NULL_TREE, n_fpr));
9632 TREE_SIDE_EFFECTS (t) = 1;
9633 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
9635 #ifdef HAVE_AS_GNU_ATTRIBUTE
9636 if (call_ABI_of_interest (cfun->decl))
9637 rs6000_passes_float = true;
9638 #endif
9641 /* Find the overflow area. */
9642 t = make_tree (TREE_TYPE (ovf), virtual_incoming_args_rtx);
9643 if (words != 0)
9644 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (ovf), t,
9645 size_int (words * UNITS_PER_WORD));
9646 t = build2 (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
9647 TREE_SIDE_EFFECTS (t) = 1;
9648 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
9650 /* If there were no va_arg invocations, don't set up the register
9651 save area. */
9652 if (!cfun->va_list_gpr_size
9653 && !cfun->va_list_fpr_size
9654 && n_gpr < GP_ARG_NUM_REG
9655 && n_fpr < FP_ARG_V4_MAX_REG)
9656 return;
9658 /* Find the register save area. */
9659 t = make_tree (TREE_TYPE (sav), virtual_stack_vars_rtx);
9660 if (cfun->machine->varargs_save_offset)
9661 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (sav), t,
9662 size_int (cfun->machine->varargs_save_offset));
9663 t = build2 (MODIFY_EXPR, TREE_TYPE (sav), sav, t);
9664 TREE_SIDE_EFFECTS (t) = 1;
9665 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
9668 /* Implement va_arg. */
9670 tree
9671 rs6000_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
9672 gimple_seq *post_p)
9674 tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
9675 tree gpr, fpr, ovf, sav, reg, t, u;
9676 int size, rsize, n_reg, sav_ofs, sav_scale;
9677 tree lab_false, lab_over, addr;
9678 int align;
9679 tree ptrtype = build_pointer_type_for_mode (type, ptr_mode, true);
9680 int regalign = 0;
9681 gimple stmt;
9683 if (pass_by_reference (NULL, TYPE_MODE (type), type, false))
9685 t = rs6000_gimplify_va_arg (valist, ptrtype, pre_p, post_p);
9686 return build_va_arg_indirect_ref (t);
9689 /* We need to deal with the fact that the darwin ppc64 ABI is defined by an
9690 earlier version of gcc, with the property that it always applied alignment
9691 adjustments to the va-args (even for zero-sized types). The cheapest way
9692 to deal with this is to replicate the effect of the part of
9693 std_gimplify_va_arg_expr that carries out the align adjust, for the case
9694 of relevance.
9695 We don't need to check for pass-by-reference because of the test above.
9696 We can return a simplifed answer, since we know there's no offset to add. */
9698 if (TARGET_MACHO
9699 && rs6000_darwin64_abi
9700 && integer_zerop (TYPE_SIZE (type)))
9702 unsigned HOST_WIDE_INT align, boundary;
9703 tree valist_tmp = get_initialized_tmp_var (valist, pre_p, NULL);
9704 align = PARM_BOUNDARY / BITS_PER_UNIT;
9705 boundary = rs6000_function_arg_boundary (TYPE_MODE (type), type);
9706 if (boundary > MAX_SUPPORTED_STACK_ALIGNMENT)
9707 boundary = MAX_SUPPORTED_STACK_ALIGNMENT;
9708 boundary /= BITS_PER_UNIT;
9709 if (boundary > align)
9711 tree t ;
9712 /* This updates arg ptr by the amount that would be necessary
9713 to align the zero-sized (but not zero-alignment) item. */
9714 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
9715 fold_build2 (POINTER_PLUS_EXPR,
9716 TREE_TYPE (valist),
9717 valist_tmp, size_int (boundary - 1)));
9718 gimplify_and_add (t, pre_p);
9720 t = fold_convert (sizetype, valist_tmp);
9721 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
9722 fold_convert (TREE_TYPE (valist),
9723 fold_build2 (BIT_AND_EXPR, sizetype, t,
9724 size_int (-boundary))));
9725 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist, t);
9726 gimplify_and_add (t, pre_p);
9728 /* Since it is zero-sized there's no increment for the item itself. */
9729 valist_tmp = fold_convert (build_pointer_type (type), valist_tmp);
9730 return build_va_arg_indirect_ref (valist_tmp);
9733 if (DEFAULT_ABI != ABI_V4)
9735 if (targetm.calls.split_complex_arg && TREE_CODE (type) == COMPLEX_TYPE)
9737 tree elem_type = TREE_TYPE (type);
9738 enum machine_mode elem_mode = TYPE_MODE (elem_type);
9739 int elem_size = GET_MODE_SIZE (elem_mode);
9741 if (elem_size < UNITS_PER_WORD)
9743 tree real_part, imag_part;
9744 gimple_seq post = NULL;
9746 real_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
9747 &post);
9748 /* Copy the value into a temporary, lest the formal temporary
9749 be reused out from under us. */
9750 real_part = get_initialized_tmp_var (real_part, pre_p, &post);
9751 gimple_seq_add_seq (pre_p, post);
9753 imag_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
9754 post_p);
9756 return build2 (COMPLEX_EXPR, type, real_part, imag_part);
9760 return std_gimplify_va_arg_expr (valist, type, pre_p, post_p);
9763 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
9764 f_fpr = DECL_CHAIN (f_gpr);
9765 f_res = DECL_CHAIN (f_fpr);
9766 f_ovf = DECL_CHAIN (f_res);
9767 f_sav = DECL_CHAIN (f_ovf);
9769 valist = build_va_arg_indirect_ref (valist);
9770 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
9771 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), unshare_expr (valist),
9772 f_fpr, NULL_TREE);
9773 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), unshare_expr (valist),
9774 f_ovf, NULL_TREE);
9775 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), unshare_expr (valist),
9776 f_sav, NULL_TREE);
9778 size = int_size_in_bytes (type);
9779 rsize = (size + 3) / 4;
9780 align = 1;
9782 if (TARGET_HARD_FLOAT && TARGET_FPRS
9783 && ((TARGET_SINGLE_FLOAT && TYPE_MODE (type) == SFmode)
9784 || (TARGET_DOUBLE_FLOAT
9785 && (TYPE_MODE (type) == DFmode
9786 || TYPE_MODE (type) == TFmode
9787 || TYPE_MODE (type) == SDmode
9788 || TYPE_MODE (type) == DDmode
9789 || TYPE_MODE (type) == TDmode))))
9791 /* FP args go in FP registers, if present. */
9792 reg = fpr;
9793 n_reg = (size + 7) / 8;
9794 sav_ofs = ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? 8 : 4) * 4;
9795 sav_scale = ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? 8 : 4);
9796 if (TYPE_MODE (type) != SFmode && TYPE_MODE (type) != SDmode)
9797 align = 8;
9799 else
9801 /* Otherwise into GP registers. */
9802 reg = gpr;
9803 n_reg = rsize;
9804 sav_ofs = 0;
9805 sav_scale = 4;
9806 if (n_reg == 2)
9807 align = 8;
9810 /* Pull the value out of the saved registers.... */
9812 lab_over = NULL;
9813 addr = create_tmp_var (ptr_type_node, "addr");
9815 /* AltiVec vectors never go in registers when -mabi=altivec. */
9816 if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
9817 align = 16;
9818 else
9820 lab_false = create_artificial_label (input_location);
9821 lab_over = create_artificial_label (input_location);
9823 /* Long long and SPE vectors are aligned in the registers.
9824 As are any other 2 gpr item such as complex int due to a
9825 historical mistake. */
9826 u = reg;
9827 if (n_reg == 2 && reg == gpr)
9829 regalign = 1;
9830 u = build2 (BIT_AND_EXPR, TREE_TYPE (reg), unshare_expr (reg),
9831 build_int_cst (TREE_TYPE (reg), n_reg - 1));
9832 u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg),
9833 unshare_expr (reg), u);
9835 /* _Decimal128 is passed in even/odd fpr pairs; the stored
9836 reg number is 0 for f1, so we want to make it odd. */
9837 else if (reg == fpr && TYPE_MODE (type) == TDmode)
9839 t = build2 (BIT_IOR_EXPR, TREE_TYPE (reg), unshare_expr (reg),
9840 build_int_cst (TREE_TYPE (reg), 1));
9841 u = build2 (MODIFY_EXPR, void_type_node, unshare_expr (reg), t);
9844 t = fold_convert (TREE_TYPE (reg), size_int (8 - n_reg + 1));
9845 t = build2 (GE_EXPR, boolean_type_node, u, t);
9846 u = build1 (GOTO_EXPR, void_type_node, lab_false);
9847 t = build3 (COND_EXPR, void_type_node, t, u, NULL_TREE);
9848 gimplify_and_add (t, pre_p);
9850 t = sav;
9851 if (sav_ofs)
9852 t = build2 (POINTER_PLUS_EXPR, ptr_type_node, sav, size_int (sav_ofs));
9854 u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg), unshare_expr (reg),
9855 build_int_cst (TREE_TYPE (reg), n_reg));
9856 u = fold_convert (sizetype, u);
9857 u = build2 (MULT_EXPR, sizetype, u, size_int (sav_scale));
9858 t = build2 (POINTER_PLUS_EXPR, ptr_type_node, t, u);
9860 /* _Decimal32 varargs are located in the second word of the 64-bit
9861 FP register for 32-bit binaries. */
9862 if (!TARGET_POWERPC64
9863 && TARGET_HARD_FLOAT && TARGET_FPRS
9864 && TYPE_MODE (type) == SDmode)
9865 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (size));
9867 gimplify_assign (addr, t, pre_p);
9869 gimple_seq_add_stmt (pre_p, gimple_build_goto (lab_over));
9871 stmt = gimple_build_label (lab_false);
9872 gimple_seq_add_stmt (pre_p, stmt);
9874 if ((n_reg == 2 && !regalign) || n_reg > 2)
9876 /* Ensure that we don't find any more args in regs.
9877 Alignment has taken care of for special cases. */
9878 gimplify_assign (reg, build_int_cst (TREE_TYPE (reg), 8), pre_p);
9882 /* ... otherwise out of the overflow area. */
9884 /* Care for on-stack alignment if needed. */
9885 t = ovf;
9886 if (align != 1)
9888 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (align - 1));
9889 t = fold_convert (sizetype, t);
9890 t = build2 (BIT_AND_EXPR, TREE_TYPE (t), t,
9891 size_int (-align));
9892 t = fold_convert (TREE_TYPE (ovf), t);
9894 gimplify_expr (&t, pre_p, NULL, is_gimple_val, fb_rvalue);
9896 gimplify_assign (unshare_expr (addr), t, pre_p);
9898 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (size));
9899 gimplify_assign (unshare_expr (ovf), t, pre_p);
9901 if (lab_over)
9903 stmt = gimple_build_label (lab_over);
9904 gimple_seq_add_stmt (pre_p, stmt);
9907 if (STRICT_ALIGNMENT
9908 && (TYPE_ALIGN (type)
9909 > (unsigned) BITS_PER_UNIT * (align < 4 ? 4 : align)))
9911 /* The value (of type complex double, for example) may not be
9912 aligned in memory in the saved registers, so copy via a
9913 temporary. (This is the same code as used for SPARC.) */
9914 tree tmp = create_tmp_var (type, "va_arg_tmp");
9915 tree dest_addr = build_fold_addr_expr (tmp);
9917 tree copy = build_call_expr (implicit_built_in_decls[BUILT_IN_MEMCPY],
9918 3, dest_addr, addr, size_int (rsize * 4));
9920 gimplify_and_add (copy, pre_p);
9921 addr = dest_addr;
9924 addr = fold_convert (ptrtype, addr);
9925 return build_va_arg_indirect_ref (addr);
9928 /* Builtins. */
9930 static void
9931 def_builtin (int mask, const char *name, tree type, int code)
9933 if ((mask & target_flags) || TARGET_PAIRED_FLOAT)
9935 tree t;
9936 if (rs6000_builtin_decls[code])
9937 fatal_error ("internal error: builtin function to %s already processed",
9938 name);
9940 rs6000_builtin_decls[code] = t =
9941 add_builtin_function (name, type, code, BUILT_IN_MD,
9942 NULL, NULL_TREE);
9944 gcc_assert (code >= 0 && code < (int)RS6000_BUILTIN_COUNT);
9945 switch (builtin_classify[code])
9947 default:
9948 gcc_unreachable ();
9950 /* assume builtin can do anything. */
9951 case RS6000_BTC_MISC:
9952 break;
9954 /* const function, function only depends on the inputs. */
9955 case RS6000_BTC_CONST:
9956 TREE_READONLY (t) = 1;
9957 TREE_NOTHROW (t) = 1;
9958 break;
9960 /* pure function, function can read global memory. */
9961 case RS6000_BTC_PURE:
9962 DECL_PURE_P (t) = 1;
9963 TREE_NOTHROW (t) = 1;
9964 break;
9966 /* Function is a math function. If rounding mode is on, then treat
9967 the function as not reading global memory, but it can have
9968 arbitrary side effects. If it is off, then assume the function is
9969 a const function. This mimics the ATTR_MATHFN_FPROUNDING
9970 attribute in builtin-attribute.def that is used for the math
9971 functions. */
9972 case RS6000_BTC_FP_PURE:
9973 TREE_NOTHROW (t) = 1;
9974 if (flag_rounding_math)
9976 DECL_PURE_P (t) = 1;
9977 DECL_IS_NOVOPS (t) = 1;
9979 else
9980 TREE_READONLY (t) = 1;
9981 break;
9986 /* Simple ternary operations: VECd = foo (VECa, VECb, VECc). */
9988 static const struct builtin_description bdesc_3arg[] =
9990 { MASK_ALTIVEC, CODE_FOR_fmav4sf4, "__builtin_altivec_vmaddfp", ALTIVEC_BUILTIN_VMADDFP },
9991 { MASK_ALTIVEC, CODE_FOR_altivec_vmhaddshs, "__builtin_altivec_vmhaddshs", ALTIVEC_BUILTIN_VMHADDSHS },
9992 { MASK_ALTIVEC, CODE_FOR_altivec_vmhraddshs, "__builtin_altivec_vmhraddshs", ALTIVEC_BUILTIN_VMHRADDSHS },
9993 { MASK_ALTIVEC, CODE_FOR_altivec_vmladduhm, "__builtin_altivec_vmladduhm", ALTIVEC_BUILTIN_VMLADDUHM},
9994 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumubm, "__builtin_altivec_vmsumubm", ALTIVEC_BUILTIN_VMSUMUBM },
9995 { MASK_ALTIVEC, CODE_FOR_altivec_vmsummbm, "__builtin_altivec_vmsummbm", ALTIVEC_BUILTIN_VMSUMMBM },
9996 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhm, "__builtin_altivec_vmsumuhm", ALTIVEC_BUILTIN_VMSUMUHM },
9997 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshm, "__builtin_altivec_vmsumshm", ALTIVEC_BUILTIN_VMSUMSHM },
9998 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhs, "__builtin_altivec_vmsumuhs", ALTIVEC_BUILTIN_VMSUMUHS },
9999 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshs, "__builtin_altivec_vmsumshs", ALTIVEC_BUILTIN_VMSUMSHS },
10000 { MASK_ALTIVEC, CODE_FOR_nfmsv4sf4, "__builtin_altivec_vnmsubfp", ALTIVEC_BUILTIN_VNMSUBFP },
10001 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2df, "__builtin_altivec_vperm_2df", ALTIVEC_BUILTIN_VPERM_2DF },
10002 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2di, "__builtin_altivec_vperm_2di", ALTIVEC_BUILTIN_VPERM_2DI },
10003 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4sf, "__builtin_altivec_vperm_4sf", ALTIVEC_BUILTIN_VPERM_4SF },
10004 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4si, "__builtin_altivec_vperm_4si", ALTIVEC_BUILTIN_VPERM_4SI },
10005 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v8hi, "__builtin_altivec_vperm_8hi", ALTIVEC_BUILTIN_VPERM_8HI },
10006 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_altivec_vperm_16qi", ALTIVEC_BUILTIN_VPERM_16QI },
10007 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2di_uns, "__builtin_altivec_vperm_2di_uns", ALTIVEC_BUILTIN_VPERM_2DI_UNS },
10008 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4si_uns, "__builtin_altivec_vperm_4si_uns", ALTIVEC_BUILTIN_VPERM_4SI_UNS },
10009 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v8hi_uns, "__builtin_altivec_vperm_8hi_uns", ALTIVEC_BUILTIN_VPERM_8HI_UNS },
10010 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_altivec_vperm_16qi_uns", ALTIVEC_BUILTIN_VPERM_16QI_UNS },
10011 { MASK_ALTIVEC, CODE_FOR_vector_select_v4sf, "__builtin_altivec_vsel_4sf", ALTIVEC_BUILTIN_VSEL_4SF },
10012 { MASK_ALTIVEC, CODE_FOR_vector_select_v4si, "__builtin_altivec_vsel_4si", ALTIVEC_BUILTIN_VSEL_4SI },
10013 { MASK_ALTIVEC, CODE_FOR_vector_select_v8hi, "__builtin_altivec_vsel_8hi", ALTIVEC_BUILTIN_VSEL_8HI },
10014 { MASK_ALTIVEC, CODE_FOR_vector_select_v16qi, "__builtin_altivec_vsel_16qi", ALTIVEC_BUILTIN_VSEL_16QI },
10015 { MASK_ALTIVEC, CODE_FOR_vector_select_v2df, "__builtin_altivec_vsel_2df", ALTIVEC_BUILTIN_VSEL_2DF },
10016 { MASK_ALTIVEC, CODE_FOR_vector_select_v2di, "__builtin_altivec_vsel_2di", ALTIVEC_BUILTIN_VSEL_2DI },
10017 { MASK_ALTIVEC, CODE_FOR_vector_select_v4si_uns, "__builtin_altivec_vsel_4si_uns", ALTIVEC_BUILTIN_VSEL_4SI_UNS },
10018 { MASK_ALTIVEC, CODE_FOR_vector_select_v8hi_uns, "__builtin_altivec_vsel_8hi_uns", ALTIVEC_BUILTIN_VSEL_8HI_UNS },
10019 { MASK_ALTIVEC, CODE_FOR_vector_select_v16qi_uns, "__builtin_altivec_vsel_16qi_uns", ALTIVEC_BUILTIN_VSEL_16QI_UNS },
10020 { MASK_ALTIVEC, CODE_FOR_vector_select_v2di_uns, "__builtin_altivec_vsel_2di_uns", ALTIVEC_BUILTIN_VSEL_2DI_UNS },
10021 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v16qi, "__builtin_altivec_vsldoi_16qi", ALTIVEC_BUILTIN_VSLDOI_16QI },
10022 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v8hi, "__builtin_altivec_vsldoi_8hi", ALTIVEC_BUILTIN_VSLDOI_8HI },
10023 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v4si, "__builtin_altivec_vsldoi_4si", ALTIVEC_BUILTIN_VSLDOI_4SI },
10024 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v4sf, "__builtin_altivec_vsldoi_4sf", ALTIVEC_BUILTIN_VSLDOI_4SF },
10026 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_madd", ALTIVEC_BUILTIN_VEC_MADD },
10027 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_madds", ALTIVEC_BUILTIN_VEC_MADDS },
10028 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mladd", ALTIVEC_BUILTIN_VEC_MLADD },
10029 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mradds", ALTIVEC_BUILTIN_VEC_MRADDS },
10030 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msum", ALTIVEC_BUILTIN_VEC_MSUM },
10031 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumshm", ALTIVEC_BUILTIN_VEC_VMSUMSHM },
10032 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumuhm", ALTIVEC_BUILTIN_VEC_VMSUMUHM },
10033 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsummbm", ALTIVEC_BUILTIN_VEC_VMSUMMBM },
10034 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumubm", ALTIVEC_BUILTIN_VEC_VMSUMUBM },
10035 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msums", ALTIVEC_BUILTIN_VEC_MSUMS },
10036 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumshs", ALTIVEC_BUILTIN_VEC_VMSUMSHS },
10037 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumuhs", ALTIVEC_BUILTIN_VEC_VMSUMUHS },
10038 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nmsub", ALTIVEC_BUILTIN_VEC_NMSUB },
10039 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_perm", ALTIVEC_BUILTIN_VEC_PERM },
10040 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sel", ALTIVEC_BUILTIN_VEC_SEL },
10042 { MASK_VSX, CODE_FOR_fmav2df4, "__builtin_vsx_xvmadddp", VSX_BUILTIN_XVMADDDP },
10043 { MASK_VSX, CODE_FOR_fmsv2df4, "__builtin_vsx_xvmsubdp", VSX_BUILTIN_XVMSUBDP },
10044 { MASK_VSX, CODE_FOR_nfmav2df4, "__builtin_vsx_xvnmadddp", VSX_BUILTIN_XVNMADDDP },
10045 { MASK_VSX, CODE_FOR_nfmsv2df4, "__builtin_vsx_xvnmsubdp", VSX_BUILTIN_XVNMSUBDP },
10047 { MASK_VSX, CODE_FOR_fmav4sf4, "__builtin_vsx_xvmaddsp", VSX_BUILTIN_XVMADDSP },
10048 { MASK_VSX, CODE_FOR_fmsv4sf4, "__builtin_vsx_xvmsubsp", VSX_BUILTIN_XVMSUBSP },
10049 { MASK_VSX, CODE_FOR_nfmav4sf4, "__builtin_vsx_xvnmaddsp", VSX_BUILTIN_XVNMADDSP },
10050 { MASK_VSX, CODE_FOR_nfmsv4sf4, "__builtin_vsx_xvnmsubsp", VSX_BUILTIN_XVNMSUBSP },
10052 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msub", VSX_BUILTIN_VEC_MSUB },
10053 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nmadd", VSX_BUILTIN_VEC_NMADD },
10055 { MASK_VSX, CODE_FOR_vector_select_v2di, "__builtin_vsx_xxsel_2di", VSX_BUILTIN_XXSEL_2DI },
10056 { MASK_VSX, CODE_FOR_vector_select_v2df, "__builtin_vsx_xxsel_2df", VSX_BUILTIN_XXSEL_2DF },
10057 { MASK_VSX, CODE_FOR_vector_select_v4sf, "__builtin_vsx_xxsel_4sf", VSX_BUILTIN_XXSEL_4SF },
10058 { MASK_VSX, CODE_FOR_vector_select_v4si, "__builtin_vsx_xxsel_4si", VSX_BUILTIN_XXSEL_4SI },
10059 { MASK_VSX, CODE_FOR_vector_select_v8hi, "__builtin_vsx_xxsel_8hi", VSX_BUILTIN_XXSEL_8HI },
10060 { MASK_VSX, CODE_FOR_vector_select_v16qi, "__builtin_vsx_xxsel_16qi", VSX_BUILTIN_XXSEL_16QI },
10061 { MASK_VSX, CODE_FOR_vector_select_v2di_uns, "__builtin_vsx_xxsel_2di_uns", VSX_BUILTIN_XXSEL_2DI_UNS },
10062 { MASK_VSX, CODE_FOR_vector_select_v4si_uns, "__builtin_vsx_xxsel_4si_uns", VSX_BUILTIN_XXSEL_4SI_UNS },
10063 { MASK_VSX, CODE_FOR_vector_select_v8hi_uns, "__builtin_vsx_xxsel_8hi_uns", VSX_BUILTIN_XXSEL_8HI_UNS },
10064 { MASK_VSX, CODE_FOR_vector_select_v16qi_uns, "__builtin_vsx_xxsel_16qi_uns", VSX_BUILTIN_XXSEL_16QI_UNS },
10066 { MASK_VSX, CODE_FOR_altivec_vperm_v2di, "__builtin_vsx_vperm_2di", VSX_BUILTIN_VPERM_2DI },
10067 { MASK_VSX, CODE_FOR_altivec_vperm_v2df, "__builtin_vsx_vperm_2df", VSX_BUILTIN_VPERM_2DF },
10068 { MASK_VSX, CODE_FOR_altivec_vperm_v4sf, "__builtin_vsx_vperm_4sf", VSX_BUILTIN_VPERM_4SF },
10069 { MASK_VSX, CODE_FOR_altivec_vperm_v4si, "__builtin_vsx_vperm_4si", VSX_BUILTIN_VPERM_4SI },
10070 { MASK_VSX, CODE_FOR_altivec_vperm_v8hi, "__builtin_vsx_vperm_8hi", VSX_BUILTIN_VPERM_8HI },
10071 { MASK_VSX, CODE_FOR_altivec_vperm_v16qi, "__builtin_vsx_vperm_16qi", VSX_BUILTIN_VPERM_16QI },
10072 { MASK_VSX, CODE_FOR_altivec_vperm_v2di_uns, "__builtin_vsx_vperm_2di_uns", VSX_BUILTIN_VPERM_2DI_UNS },
10073 { MASK_VSX, CODE_FOR_altivec_vperm_v4si_uns, "__builtin_vsx_vperm_4si_uns", VSX_BUILTIN_VPERM_4SI_UNS },
10074 { MASK_VSX, CODE_FOR_altivec_vperm_v8hi_uns, "__builtin_vsx_vperm_8hi_uns", VSX_BUILTIN_VPERM_8HI_UNS },
10075 { MASK_VSX, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_vsx_vperm_16qi_uns", VSX_BUILTIN_VPERM_16QI_UNS },
10077 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v2df, "__builtin_vsx_xxpermdi_2df", VSX_BUILTIN_XXPERMDI_2DF },
10078 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v2di, "__builtin_vsx_xxpermdi_2di", VSX_BUILTIN_XXPERMDI_2DI },
10079 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v4sf, "__builtin_vsx_xxpermdi_4sf", VSX_BUILTIN_XXPERMDI_4SF },
10080 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v4si, "__builtin_vsx_xxpermdi_4si", VSX_BUILTIN_XXPERMDI_4SI },
10081 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v8hi, "__builtin_vsx_xxpermdi_8hi", VSX_BUILTIN_XXPERMDI_8HI },
10082 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v16qi, "__builtin_vsx_xxpermdi_16qi", VSX_BUILTIN_XXPERMDI_16QI },
10083 { MASK_VSX, CODE_FOR_nothing, "__builtin_vsx_xxpermdi", VSX_BUILTIN_VEC_XXPERMDI },
10084 { MASK_VSX, CODE_FOR_vsx_set_v2df, "__builtin_vsx_set_2df", VSX_BUILTIN_SET_2DF },
10085 { MASK_VSX, CODE_FOR_vsx_set_v2di, "__builtin_vsx_set_2di", VSX_BUILTIN_SET_2DI },
10087 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v2di, "__builtin_vsx_xxsldwi_2di", VSX_BUILTIN_XXSLDWI_2DI },
10088 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v2df, "__builtin_vsx_xxsldwi_2df", VSX_BUILTIN_XXSLDWI_2DF },
10089 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v4sf, "__builtin_vsx_xxsldwi_4sf", VSX_BUILTIN_XXSLDWI_4SF },
10090 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v4si, "__builtin_vsx_xxsldwi_4si", VSX_BUILTIN_XXSLDWI_4SI },
10091 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v8hi, "__builtin_vsx_xxsldwi_8hi", VSX_BUILTIN_XXSLDWI_8HI },
10092 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v16qi, "__builtin_vsx_xxsldwi_16qi", VSX_BUILTIN_XXSLDWI_16QI },
10093 { MASK_VSX, CODE_FOR_nothing, "__builtin_vsx_xxsldwi", VSX_BUILTIN_VEC_XXSLDWI },
10095 { 0, CODE_FOR_fmsv2sf4, "__builtin_paired_msub", PAIRED_BUILTIN_MSUB },
10096 { 0, CODE_FOR_fmav2sf4, "__builtin_paired_madd", PAIRED_BUILTIN_MADD },
10097 { 0, CODE_FOR_paired_madds0, "__builtin_paired_madds0", PAIRED_BUILTIN_MADDS0 },
10098 { 0, CODE_FOR_paired_madds1, "__builtin_paired_madds1", PAIRED_BUILTIN_MADDS1 },
10099 { 0, CODE_FOR_nfmsv2sf4, "__builtin_paired_nmsub", PAIRED_BUILTIN_NMSUB },
10100 { 0, CODE_FOR_nfmav2sf4, "__builtin_paired_nmadd", PAIRED_BUILTIN_NMADD },
10101 { 0, CODE_FOR_paired_sum0, "__builtin_paired_sum0", PAIRED_BUILTIN_SUM0 },
10102 { 0, CODE_FOR_paired_sum1, "__builtin_paired_sum1", PAIRED_BUILTIN_SUM1 },
10103 { 0, CODE_FOR_selv2sf4, "__builtin_paired_selv2sf4", PAIRED_BUILTIN_SELV2SF4 },
10106 /* DST operations: void foo (void *, const int, const char). */
10108 static const struct builtin_description bdesc_dst[] =
10110 { MASK_ALTIVEC, CODE_FOR_altivec_dst, "__builtin_altivec_dst", ALTIVEC_BUILTIN_DST },
10111 { MASK_ALTIVEC, CODE_FOR_altivec_dstt, "__builtin_altivec_dstt", ALTIVEC_BUILTIN_DSTT },
10112 { MASK_ALTIVEC, CODE_FOR_altivec_dstst, "__builtin_altivec_dstst", ALTIVEC_BUILTIN_DSTST },
10113 { MASK_ALTIVEC, CODE_FOR_altivec_dststt, "__builtin_altivec_dststt", ALTIVEC_BUILTIN_DSTSTT },
10115 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dst", ALTIVEC_BUILTIN_VEC_DST },
10116 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dstt", ALTIVEC_BUILTIN_VEC_DSTT },
10117 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dstst", ALTIVEC_BUILTIN_VEC_DSTST },
10118 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dststt", ALTIVEC_BUILTIN_VEC_DSTSTT }
10121 /* Simple binary operations: VECc = foo (VECa, VECb). */
10123 static struct builtin_description bdesc_2arg[] =
10125 { MASK_ALTIVEC, CODE_FOR_addv16qi3, "__builtin_altivec_vaddubm", ALTIVEC_BUILTIN_VADDUBM },
10126 { MASK_ALTIVEC, CODE_FOR_addv8hi3, "__builtin_altivec_vadduhm", ALTIVEC_BUILTIN_VADDUHM },
10127 { MASK_ALTIVEC, CODE_FOR_addv4si3, "__builtin_altivec_vadduwm", ALTIVEC_BUILTIN_VADDUWM },
10128 { MASK_ALTIVEC, CODE_FOR_addv4sf3, "__builtin_altivec_vaddfp", ALTIVEC_BUILTIN_VADDFP },
10129 { MASK_ALTIVEC, CODE_FOR_altivec_vaddcuw, "__builtin_altivec_vaddcuw", ALTIVEC_BUILTIN_VADDCUW },
10130 { MASK_ALTIVEC, CODE_FOR_altivec_vaddubs, "__builtin_altivec_vaddubs", ALTIVEC_BUILTIN_VADDUBS },
10131 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsbs, "__builtin_altivec_vaddsbs", ALTIVEC_BUILTIN_VADDSBS },
10132 { MASK_ALTIVEC, CODE_FOR_altivec_vadduhs, "__builtin_altivec_vadduhs", ALTIVEC_BUILTIN_VADDUHS },
10133 { MASK_ALTIVEC, CODE_FOR_altivec_vaddshs, "__builtin_altivec_vaddshs", ALTIVEC_BUILTIN_VADDSHS },
10134 { MASK_ALTIVEC, CODE_FOR_altivec_vadduws, "__builtin_altivec_vadduws", ALTIVEC_BUILTIN_VADDUWS },
10135 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsws, "__builtin_altivec_vaddsws", ALTIVEC_BUILTIN_VADDSWS },
10136 { MASK_ALTIVEC, CODE_FOR_andv4si3, "__builtin_altivec_vand", ALTIVEC_BUILTIN_VAND },
10137 { MASK_ALTIVEC, CODE_FOR_andcv4si3, "__builtin_altivec_vandc", ALTIVEC_BUILTIN_VANDC },
10138 { MASK_ALTIVEC, CODE_FOR_altivec_vavgub, "__builtin_altivec_vavgub", ALTIVEC_BUILTIN_VAVGUB },
10139 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsb, "__builtin_altivec_vavgsb", ALTIVEC_BUILTIN_VAVGSB },
10140 { MASK_ALTIVEC, CODE_FOR_altivec_vavguh, "__builtin_altivec_vavguh", ALTIVEC_BUILTIN_VAVGUH },
10141 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsh, "__builtin_altivec_vavgsh", ALTIVEC_BUILTIN_VAVGSH },
10142 { MASK_ALTIVEC, CODE_FOR_altivec_vavguw, "__builtin_altivec_vavguw", ALTIVEC_BUILTIN_VAVGUW },
10143 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsw, "__builtin_altivec_vavgsw", ALTIVEC_BUILTIN_VAVGSW },
10144 { MASK_ALTIVEC, CODE_FOR_altivec_vcfux, "__builtin_altivec_vcfux", ALTIVEC_BUILTIN_VCFUX },
10145 { MASK_ALTIVEC, CODE_FOR_altivec_vcfsx, "__builtin_altivec_vcfsx", ALTIVEC_BUILTIN_VCFSX },
10146 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpbfp, "__builtin_altivec_vcmpbfp", ALTIVEC_BUILTIN_VCMPBFP },
10147 { MASK_ALTIVEC, CODE_FOR_vector_eqv16qi, "__builtin_altivec_vcmpequb", ALTIVEC_BUILTIN_VCMPEQUB },
10148 { MASK_ALTIVEC, CODE_FOR_vector_eqv8hi, "__builtin_altivec_vcmpequh", ALTIVEC_BUILTIN_VCMPEQUH },
10149 { MASK_ALTIVEC, CODE_FOR_vector_eqv4si, "__builtin_altivec_vcmpequw", ALTIVEC_BUILTIN_VCMPEQUW },
10150 { MASK_ALTIVEC, CODE_FOR_vector_eqv4sf, "__builtin_altivec_vcmpeqfp", ALTIVEC_BUILTIN_VCMPEQFP },
10151 { MASK_ALTIVEC, CODE_FOR_vector_gev4sf, "__builtin_altivec_vcmpgefp", ALTIVEC_BUILTIN_VCMPGEFP },
10152 { MASK_ALTIVEC, CODE_FOR_vector_gtuv16qi, "__builtin_altivec_vcmpgtub", ALTIVEC_BUILTIN_VCMPGTUB },
10153 { MASK_ALTIVEC, CODE_FOR_vector_gtv16qi, "__builtin_altivec_vcmpgtsb", ALTIVEC_BUILTIN_VCMPGTSB },
10154 { MASK_ALTIVEC, CODE_FOR_vector_gtuv8hi, "__builtin_altivec_vcmpgtuh", ALTIVEC_BUILTIN_VCMPGTUH },
10155 { MASK_ALTIVEC, CODE_FOR_vector_gtv8hi, "__builtin_altivec_vcmpgtsh", ALTIVEC_BUILTIN_VCMPGTSH },
10156 { MASK_ALTIVEC, CODE_FOR_vector_gtuv4si, "__builtin_altivec_vcmpgtuw", ALTIVEC_BUILTIN_VCMPGTUW },
10157 { MASK_ALTIVEC, CODE_FOR_vector_gtv4si, "__builtin_altivec_vcmpgtsw", ALTIVEC_BUILTIN_VCMPGTSW },
10158 { MASK_ALTIVEC, CODE_FOR_vector_gtv4sf, "__builtin_altivec_vcmpgtfp", ALTIVEC_BUILTIN_VCMPGTFP },
10159 { MASK_ALTIVEC, CODE_FOR_altivec_vctsxs, "__builtin_altivec_vctsxs", ALTIVEC_BUILTIN_VCTSXS },
10160 { MASK_ALTIVEC, CODE_FOR_altivec_vctuxs, "__builtin_altivec_vctuxs", ALTIVEC_BUILTIN_VCTUXS },
10161 { MASK_ALTIVEC, CODE_FOR_umaxv16qi3, "__builtin_altivec_vmaxub", ALTIVEC_BUILTIN_VMAXUB },
10162 { MASK_ALTIVEC, CODE_FOR_smaxv16qi3, "__builtin_altivec_vmaxsb", ALTIVEC_BUILTIN_VMAXSB },
10163 { MASK_ALTIVEC, CODE_FOR_umaxv8hi3, "__builtin_altivec_vmaxuh", ALTIVEC_BUILTIN_VMAXUH },
10164 { MASK_ALTIVEC, CODE_FOR_smaxv8hi3, "__builtin_altivec_vmaxsh", ALTIVEC_BUILTIN_VMAXSH },
10165 { MASK_ALTIVEC, CODE_FOR_umaxv4si3, "__builtin_altivec_vmaxuw", ALTIVEC_BUILTIN_VMAXUW },
10166 { MASK_ALTIVEC, CODE_FOR_smaxv4si3, "__builtin_altivec_vmaxsw", ALTIVEC_BUILTIN_VMAXSW },
10167 { MASK_ALTIVEC, CODE_FOR_smaxv4sf3, "__builtin_altivec_vmaxfp", ALTIVEC_BUILTIN_VMAXFP },
10168 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghb, "__builtin_altivec_vmrghb", ALTIVEC_BUILTIN_VMRGHB },
10169 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghh, "__builtin_altivec_vmrghh", ALTIVEC_BUILTIN_VMRGHH },
10170 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghw, "__builtin_altivec_vmrghw", ALTIVEC_BUILTIN_VMRGHW },
10171 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglb, "__builtin_altivec_vmrglb", ALTIVEC_BUILTIN_VMRGLB },
10172 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglh, "__builtin_altivec_vmrglh", ALTIVEC_BUILTIN_VMRGLH },
10173 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglw, "__builtin_altivec_vmrglw", ALTIVEC_BUILTIN_VMRGLW },
10174 { MASK_ALTIVEC, CODE_FOR_uminv16qi3, "__builtin_altivec_vminub", ALTIVEC_BUILTIN_VMINUB },
10175 { MASK_ALTIVEC, CODE_FOR_sminv16qi3, "__builtin_altivec_vminsb", ALTIVEC_BUILTIN_VMINSB },
10176 { MASK_ALTIVEC, CODE_FOR_uminv8hi3, "__builtin_altivec_vminuh", ALTIVEC_BUILTIN_VMINUH },
10177 { MASK_ALTIVEC, CODE_FOR_sminv8hi3, "__builtin_altivec_vminsh", ALTIVEC_BUILTIN_VMINSH },
10178 { MASK_ALTIVEC, CODE_FOR_uminv4si3, "__builtin_altivec_vminuw", ALTIVEC_BUILTIN_VMINUW },
10179 { MASK_ALTIVEC, CODE_FOR_sminv4si3, "__builtin_altivec_vminsw", ALTIVEC_BUILTIN_VMINSW },
10180 { MASK_ALTIVEC, CODE_FOR_sminv4sf3, "__builtin_altivec_vminfp", ALTIVEC_BUILTIN_VMINFP },
10181 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleub, "__builtin_altivec_vmuleub", ALTIVEC_BUILTIN_VMULEUB },
10182 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleub, "__builtin_altivec_vmuleub_uns", ALTIVEC_BUILTIN_VMULEUB_UNS },
10183 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesb, "__builtin_altivec_vmulesb", ALTIVEC_BUILTIN_VMULESB },
10184 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleuh, "__builtin_altivec_vmuleuh", ALTIVEC_BUILTIN_VMULEUH },
10185 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleuh, "__builtin_altivec_vmuleuh_uns", ALTIVEC_BUILTIN_VMULEUH_UNS },
10186 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesh, "__builtin_altivec_vmulesh", ALTIVEC_BUILTIN_VMULESH },
10187 { MASK_ALTIVEC, CODE_FOR_altivec_vmuloub, "__builtin_altivec_vmuloub", ALTIVEC_BUILTIN_VMULOUB },
10188 { MASK_ALTIVEC, CODE_FOR_altivec_vmuloub, "__builtin_altivec_vmuloub_uns", ALTIVEC_BUILTIN_VMULOUB_UNS },
10189 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosb, "__builtin_altivec_vmulosb", ALTIVEC_BUILTIN_VMULOSB },
10190 { MASK_ALTIVEC, CODE_FOR_altivec_vmulouh, "__builtin_altivec_vmulouh", ALTIVEC_BUILTIN_VMULOUH },
10191 { MASK_ALTIVEC, CODE_FOR_altivec_vmulouh, "__builtin_altivec_vmulouh_uns", ALTIVEC_BUILTIN_VMULOUH_UNS },
10192 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosh, "__builtin_altivec_vmulosh", ALTIVEC_BUILTIN_VMULOSH },
10193 { MASK_ALTIVEC, CODE_FOR_norv4si3, "__builtin_altivec_vnor", ALTIVEC_BUILTIN_VNOR },
10194 { MASK_ALTIVEC, CODE_FOR_iorv4si3, "__builtin_altivec_vor", ALTIVEC_BUILTIN_VOR },
10195 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhum, "__builtin_altivec_vpkuhum", ALTIVEC_BUILTIN_VPKUHUM },
10196 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwum, "__builtin_altivec_vpkuwum", ALTIVEC_BUILTIN_VPKUWUM },
10197 { MASK_ALTIVEC, CODE_FOR_altivec_vpkpx, "__builtin_altivec_vpkpx", ALTIVEC_BUILTIN_VPKPX },
10198 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshss, "__builtin_altivec_vpkshss", ALTIVEC_BUILTIN_VPKSHSS },
10199 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswss, "__builtin_altivec_vpkswss", ALTIVEC_BUILTIN_VPKSWSS },
10200 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhus, "__builtin_altivec_vpkuhus", ALTIVEC_BUILTIN_VPKUHUS },
10201 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshus, "__builtin_altivec_vpkshus", ALTIVEC_BUILTIN_VPKSHUS },
10202 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwus, "__builtin_altivec_vpkuwus", ALTIVEC_BUILTIN_VPKUWUS },
10203 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswus, "__builtin_altivec_vpkswus", ALTIVEC_BUILTIN_VPKSWUS },
10204 { MASK_ALTIVEC, CODE_FOR_recipv4sf3, "__builtin_altivec_vrecipdivfp", ALTIVEC_BUILTIN_VRECIPFP },
10205 { MASK_ALTIVEC, CODE_FOR_vrotlv16qi3, "__builtin_altivec_vrlb", ALTIVEC_BUILTIN_VRLB },
10206 { MASK_ALTIVEC, CODE_FOR_vrotlv8hi3, "__builtin_altivec_vrlh", ALTIVEC_BUILTIN_VRLH },
10207 { MASK_ALTIVEC, CODE_FOR_vrotlv4si3, "__builtin_altivec_vrlw", ALTIVEC_BUILTIN_VRLW },
10208 { MASK_ALTIVEC, CODE_FOR_vashlv16qi3, "__builtin_altivec_vslb", ALTIVEC_BUILTIN_VSLB },
10209 { MASK_ALTIVEC, CODE_FOR_vashlv8hi3, "__builtin_altivec_vslh", ALTIVEC_BUILTIN_VSLH },
10210 { MASK_ALTIVEC, CODE_FOR_vashlv4si3, "__builtin_altivec_vslw", ALTIVEC_BUILTIN_VSLW },
10211 { MASK_ALTIVEC, CODE_FOR_altivec_vsl, "__builtin_altivec_vsl", ALTIVEC_BUILTIN_VSL },
10212 { MASK_ALTIVEC, CODE_FOR_altivec_vslo, "__builtin_altivec_vslo", ALTIVEC_BUILTIN_VSLO },
10213 { MASK_ALTIVEC, CODE_FOR_altivec_vspltb, "__builtin_altivec_vspltb", ALTIVEC_BUILTIN_VSPLTB },
10214 { MASK_ALTIVEC, CODE_FOR_altivec_vsplth, "__builtin_altivec_vsplth", ALTIVEC_BUILTIN_VSPLTH },
10215 { MASK_ALTIVEC, CODE_FOR_altivec_vspltw, "__builtin_altivec_vspltw", ALTIVEC_BUILTIN_VSPLTW },
10216 { MASK_ALTIVEC, CODE_FOR_vlshrv16qi3, "__builtin_altivec_vsrb", ALTIVEC_BUILTIN_VSRB },
10217 { MASK_ALTIVEC, CODE_FOR_vlshrv8hi3, "__builtin_altivec_vsrh", ALTIVEC_BUILTIN_VSRH },
10218 { MASK_ALTIVEC, CODE_FOR_vlshrv4si3, "__builtin_altivec_vsrw", ALTIVEC_BUILTIN_VSRW },
10219 { MASK_ALTIVEC, CODE_FOR_vashrv16qi3, "__builtin_altivec_vsrab", ALTIVEC_BUILTIN_VSRAB },
10220 { MASK_ALTIVEC, CODE_FOR_vashrv8hi3, "__builtin_altivec_vsrah", ALTIVEC_BUILTIN_VSRAH },
10221 { MASK_ALTIVEC, CODE_FOR_vashrv4si3, "__builtin_altivec_vsraw", ALTIVEC_BUILTIN_VSRAW },
10222 { MASK_ALTIVEC, CODE_FOR_altivec_vsr, "__builtin_altivec_vsr", ALTIVEC_BUILTIN_VSR },
10223 { MASK_ALTIVEC, CODE_FOR_altivec_vsro, "__builtin_altivec_vsro", ALTIVEC_BUILTIN_VSRO },
10224 { MASK_ALTIVEC, CODE_FOR_subv16qi3, "__builtin_altivec_vsububm", ALTIVEC_BUILTIN_VSUBUBM },
10225 { MASK_ALTIVEC, CODE_FOR_subv8hi3, "__builtin_altivec_vsubuhm", ALTIVEC_BUILTIN_VSUBUHM },
10226 { MASK_ALTIVEC, CODE_FOR_subv4si3, "__builtin_altivec_vsubuwm", ALTIVEC_BUILTIN_VSUBUWM },
10227 { MASK_ALTIVEC, CODE_FOR_subv4sf3, "__builtin_altivec_vsubfp", ALTIVEC_BUILTIN_VSUBFP },
10228 { MASK_ALTIVEC, CODE_FOR_altivec_vsubcuw, "__builtin_altivec_vsubcuw", ALTIVEC_BUILTIN_VSUBCUW },
10229 { MASK_ALTIVEC, CODE_FOR_altivec_vsububs, "__builtin_altivec_vsububs", ALTIVEC_BUILTIN_VSUBUBS },
10230 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsbs, "__builtin_altivec_vsubsbs", ALTIVEC_BUILTIN_VSUBSBS },
10231 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuhs, "__builtin_altivec_vsubuhs", ALTIVEC_BUILTIN_VSUBUHS },
10232 { MASK_ALTIVEC, CODE_FOR_altivec_vsubshs, "__builtin_altivec_vsubshs", ALTIVEC_BUILTIN_VSUBSHS },
10233 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuws, "__builtin_altivec_vsubuws", ALTIVEC_BUILTIN_VSUBUWS },
10234 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsws, "__builtin_altivec_vsubsws", ALTIVEC_BUILTIN_VSUBSWS },
10235 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4ubs, "__builtin_altivec_vsum4ubs", ALTIVEC_BUILTIN_VSUM4UBS },
10236 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4sbs, "__builtin_altivec_vsum4sbs", ALTIVEC_BUILTIN_VSUM4SBS },
10237 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4shs, "__builtin_altivec_vsum4shs", ALTIVEC_BUILTIN_VSUM4SHS },
10238 { MASK_ALTIVEC, CODE_FOR_altivec_vsum2sws, "__builtin_altivec_vsum2sws", ALTIVEC_BUILTIN_VSUM2SWS },
10239 { MASK_ALTIVEC, CODE_FOR_altivec_vsumsws, "__builtin_altivec_vsumsws", ALTIVEC_BUILTIN_VSUMSWS },
10240 { MASK_ALTIVEC, CODE_FOR_xorv4si3, "__builtin_altivec_vxor", ALTIVEC_BUILTIN_VXOR },
10241 { MASK_ALTIVEC, CODE_FOR_vector_copysignv4sf3, "__builtin_altivec_copysignfp", ALTIVEC_BUILTIN_COPYSIGN_V4SF },
10243 { MASK_VSX, CODE_FOR_addv2df3, "__builtin_vsx_xvadddp", VSX_BUILTIN_XVADDDP },
10244 { MASK_VSX, CODE_FOR_subv2df3, "__builtin_vsx_xvsubdp", VSX_BUILTIN_XVSUBDP },
10245 { MASK_VSX, CODE_FOR_mulv2df3, "__builtin_vsx_xvmuldp", VSX_BUILTIN_XVMULDP },
10246 { MASK_VSX, CODE_FOR_divv2df3, "__builtin_vsx_xvdivdp", VSX_BUILTIN_XVDIVDP },
10247 { MASK_VSX, CODE_FOR_recipv2df3, "__builtin_vsx_xvrecipdivdp", VSX_BUILTIN_RECIP_V2DF },
10248 { MASK_VSX, CODE_FOR_sminv2df3, "__builtin_vsx_xvmindp", VSX_BUILTIN_XVMINDP },
10249 { MASK_VSX, CODE_FOR_smaxv2df3, "__builtin_vsx_xvmaxdp", VSX_BUILTIN_XVMAXDP },
10250 { MASK_VSX, CODE_FOR_vsx_tdivv2df3_fe, "__builtin_vsx_xvtdivdp_fe", VSX_BUILTIN_XVTDIVDP_FE },
10251 { MASK_VSX, CODE_FOR_vsx_tdivv2df3_fg, "__builtin_vsx_xvtdivdp_fg", VSX_BUILTIN_XVTDIVDP_FG },
10252 { MASK_VSX, CODE_FOR_vector_eqv2df, "__builtin_vsx_xvcmpeqdp", VSX_BUILTIN_XVCMPEQDP },
10253 { MASK_VSX, CODE_FOR_vector_gtv2df, "__builtin_vsx_xvcmpgtdp", VSX_BUILTIN_XVCMPGTDP },
10254 { MASK_VSX, CODE_FOR_vector_gev2df, "__builtin_vsx_xvcmpgedp", VSX_BUILTIN_XVCMPGEDP },
10256 { MASK_VSX, CODE_FOR_addv4sf3, "__builtin_vsx_xvaddsp", VSX_BUILTIN_XVADDSP },
10257 { MASK_VSX, CODE_FOR_subv4sf3, "__builtin_vsx_xvsubsp", VSX_BUILTIN_XVSUBSP },
10258 { MASK_VSX, CODE_FOR_mulv4sf3, "__builtin_vsx_xvmulsp", VSX_BUILTIN_XVMULSP },
10259 { MASK_VSX, CODE_FOR_divv4sf3, "__builtin_vsx_xvdivsp", VSX_BUILTIN_XVDIVSP },
10260 { MASK_VSX, CODE_FOR_recipv4sf3, "__builtin_vsx_xvrecipdivsp", VSX_BUILTIN_RECIP_V4SF },
10261 { MASK_VSX, CODE_FOR_sminv4sf3, "__builtin_vsx_xvminsp", VSX_BUILTIN_XVMINSP },
10262 { MASK_VSX, CODE_FOR_smaxv4sf3, "__builtin_vsx_xvmaxsp", VSX_BUILTIN_XVMAXSP },
10263 { MASK_VSX, CODE_FOR_vsx_tdivv4sf3_fe, "__builtin_vsx_xvtdivsp_fe", VSX_BUILTIN_XVTDIVSP_FE },
10264 { MASK_VSX, CODE_FOR_vsx_tdivv4sf3_fg, "__builtin_vsx_xvtdivsp_fg", VSX_BUILTIN_XVTDIVSP_FG },
10265 { MASK_VSX, CODE_FOR_vector_eqv4sf, "__builtin_vsx_xvcmpeqsp", VSX_BUILTIN_XVCMPEQSP },
10266 { MASK_VSX, CODE_FOR_vector_gtv4sf, "__builtin_vsx_xvcmpgtsp", VSX_BUILTIN_XVCMPGTSP },
10267 { MASK_VSX, CODE_FOR_vector_gev4sf, "__builtin_vsx_xvcmpgesp", VSX_BUILTIN_XVCMPGESP },
10269 { MASK_VSX, CODE_FOR_smindf3, "__builtin_vsx_xsmindp", VSX_BUILTIN_XSMINDP },
10270 { MASK_VSX, CODE_FOR_smaxdf3, "__builtin_vsx_xsmaxdp", VSX_BUILTIN_XSMAXDP },
10271 { MASK_VSX, CODE_FOR_vsx_tdivdf3_fe, "__builtin_vsx_xstdivdp_fe", VSX_BUILTIN_XSTDIVDP_FE },
10272 { MASK_VSX, CODE_FOR_vsx_tdivdf3_fg, "__builtin_vsx_xstdivdp_fg", VSX_BUILTIN_XSTDIVDP_FG },
10273 { MASK_VSX, CODE_FOR_vector_copysignv2df3, "__builtin_vsx_cpsgndp", VSX_BUILTIN_CPSGNDP },
10274 { MASK_VSX, CODE_FOR_vector_copysignv4sf3, "__builtin_vsx_cpsgnsp", VSX_BUILTIN_CPSGNSP },
10276 { MASK_VSX, CODE_FOR_vsx_concat_v2df, "__builtin_vsx_concat_2df", VSX_BUILTIN_CONCAT_2DF },
10277 { MASK_VSX, CODE_FOR_vsx_concat_v2di, "__builtin_vsx_concat_2di", VSX_BUILTIN_CONCAT_2DI },
10278 { MASK_VSX, CODE_FOR_vsx_splat_v2df, "__builtin_vsx_splat_2df", VSX_BUILTIN_SPLAT_2DF },
10279 { MASK_VSX, CODE_FOR_vsx_splat_v2di, "__builtin_vsx_splat_2di", VSX_BUILTIN_SPLAT_2DI },
10280 { MASK_VSX, CODE_FOR_vsx_xxmrghw_v4sf, "__builtin_vsx_xxmrghw", VSX_BUILTIN_XXMRGHW_4SF },
10281 { MASK_VSX, CODE_FOR_vsx_xxmrghw_v4si, "__builtin_vsx_xxmrghw_4si", VSX_BUILTIN_XXMRGHW_4SI },
10282 { MASK_VSX, CODE_FOR_vsx_xxmrglw_v4sf, "__builtin_vsx_xxmrglw", VSX_BUILTIN_XXMRGLW_4SF },
10283 { MASK_VSX, CODE_FOR_vsx_xxmrglw_v4si, "__builtin_vsx_xxmrglw_4si", VSX_BUILTIN_XXMRGLW_4SI },
10284 { MASK_VSX, CODE_FOR_vec_interleave_lowv2df, "__builtin_vsx_mergel_2df", VSX_BUILTIN_VEC_MERGEL_V2DF },
10285 { MASK_VSX, CODE_FOR_vec_interleave_lowv2di, "__builtin_vsx_mergel_2di", VSX_BUILTIN_VEC_MERGEL_V2DI },
10286 { MASK_VSX, CODE_FOR_vec_interleave_highv2df, "__builtin_vsx_mergeh_2df", VSX_BUILTIN_VEC_MERGEH_V2DF },
10287 { MASK_VSX, CODE_FOR_vec_interleave_highv2di, "__builtin_vsx_mergeh_2di", VSX_BUILTIN_VEC_MERGEH_V2DI },
10289 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_add", ALTIVEC_BUILTIN_VEC_ADD },
10290 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vaddfp", ALTIVEC_BUILTIN_VEC_VADDFP },
10291 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduwm", ALTIVEC_BUILTIN_VEC_VADDUWM },
10292 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhm", ALTIVEC_BUILTIN_VEC_VADDUHM },
10293 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubm", ALTIVEC_BUILTIN_VEC_VADDUBM },
10294 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_addc", ALTIVEC_BUILTIN_VEC_ADDC },
10295 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_adds", ALTIVEC_BUILTIN_VEC_ADDS },
10296 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddsws", ALTIVEC_BUILTIN_VEC_VADDSWS },
10297 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduws", ALTIVEC_BUILTIN_VEC_VADDUWS },
10298 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddshs", ALTIVEC_BUILTIN_VEC_VADDSHS },
10299 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhs", ALTIVEC_BUILTIN_VEC_VADDUHS },
10300 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddsbs", ALTIVEC_BUILTIN_VEC_VADDSBS },
10301 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubs", ALTIVEC_BUILTIN_VEC_VADDUBS },
10302 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_and", ALTIVEC_BUILTIN_VEC_AND },
10303 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_andc", ALTIVEC_BUILTIN_VEC_ANDC },
10304 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_avg", ALTIVEC_BUILTIN_VEC_AVG },
10305 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsw", ALTIVEC_BUILTIN_VEC_VAVGSW },
10306 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavguw", ALTIVEC_BUILTIN_VEC_VAVGUW },
10307 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsh", ALTIVEC_BUILTIN_VEC_VAVGSH },
10308 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavguh", ALTIVEC_BUILTIN_VEC_VAVGUH },
10309 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsb", ALTIVEC_BUILTIN_VEC_VAVGSB },
10310 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgub", ALTIVEC_BUILTIN_VEC_VAVGUB },
10311 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpb", ALTIVEC_BUILTIN_VEC_CMPB },
10312 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpeq", ALTIVEC_BUILTIN_VEC_CMPEQ },
10313 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpeqfp", ALTIVEC_BUILTIN_VEC_VCMPEQFP },
10314 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequw", ALTIVEC_BUILTIN_VEC_VCMPEQUW },
10315 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequh", ALTIVEC_BUILTIN_VEC_VCMPEQUH },
10316 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequb", ALTIVEC_BUILTIN_VEC_VCMPEQUB },
10317 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpge", ALTIVEC_BUILTIN_VEC_CMPGE },
10318 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpgt", ALTIVEC_BUILTIN_VEC_CMPGT },
10319 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtfp", ALTIVEC_BUILTIN_VEC_VCMPGTFP },
10320 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsw", ALTIVEC_BUILTIN_VEC_VCMPGTSW },
10321 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtuw", ALTIVEC_BUILTIN_VEC_VCMPGTUW },
10322 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsh", ALTIVEC_BUILTIN_VEC_VCMPGTSH },
10323 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtuh", ALTIVEC_BUILTIN_VEC_VCMPGTUH },
10324 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsb", ALTIVEC_BUILTIN_VEC_VCMPGTSB },
10325 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtub", ALTIVEC_BUILTIN_VEC_VCMPGTUB },
10326 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmple", ALTIVEC_BUILTIN_VEC_CMPLE },
10327 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmplt", ALTIVEC_BUILTIN_VEC_CMPLT },
10328 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_copysign", ALTIVEC_BUILTIN_VEC_COPYSIGN },
10329 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_max", ALTIVEC_BUILTIN_VEC_MAX },
10330 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vmaxfp", ALTIVEC_BUILTIN_VEC_VMAXFP },
10331 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsw", ALTIVEC_BUILTIN_VEC_VMAXSW },
10332 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxuw", ALTIVEC_BUILTIN_VEC_VMAXUW },
10333 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsh", ALTIVEC_BUILTIN_VEC_VMAXSH },
10334 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxuh", ALTIVEC_BUILTIN_VEC_VMAXUH },
10335 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsb", ALTIVEC_BUILTIN_VEC_VMAXSB },
10336 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxub", ALTIVEC_BUILTIN_VEC_VMAXUB },
10337 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mergeh", ALTIVEC_BUILTIN_VEC_MERGEH },
10338 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghw", ALTIVEC_BUILTIN_VEC_VMRGHW },
10339 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghh", ALTIVEC_BUILTIN_VEC_VMRGHH },
10340 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghb", ALTIVEC_BUILTIN_VEC_VMRGHB },
10341 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mergel", ALTIVEC_BUILTIN_VEC_MERGEL },
10342 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglw", ALTIVEC_BUILTIN_VEC_VMRGLW },
10343 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglh", ALTIVEC_BUILTIN_VEC_VMRGLH },
10344 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglb", ALTIVEC_BUILTIN_VEC_VMRGLB },
10345 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_min", ALTIVEC_BUILTIN_VEC_MIN },
10346 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vminfp", ALTIVEC_BUILTIN_VEC_VMINFP },
10347 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsw", ALTIVEC_BUILTIN_VEC_VMINSW },
10348 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminuw", ALTIVEC_BUILTIN_VEC_VMINUW },
10349 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsh", ALTIVEC_BUILTIN_VEC_VMINSH },
10350 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminuh", ALTIVEC_BUILTIN_VEC_VMINUH },
10351 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsb", ALTIVEC_BUILTIN_VEC_VMINSB },
10352 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminub", ALTIVEC_BUILTIN_VEC_VMINUB },
10353 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mule", ALTIVEC_BUILTIN_VEC_MULE },
10354 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuleub", ALTIVEC_BUILTIN_VEC_VMULEUB },
10355 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulesb", ALTIVEC_BUILTIN_VEC_VMULESB },
10356 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuleuh", ALTIVEC_BUILTIN_VEC_VMULEUH },
10357 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulesh", ALTIVEC_BUILTIN_VEC_VMULESH },
10358 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mulo", ALTIVEC_BUILTIN_VEC_MULO },
10359 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulosh", ALTIVEC_BUILTIN_VEC_VMULOSH },
10360 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulouh", ALTIVEC_BUILTIN_VEC_VMULOUH },
10361 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulosb", ALTIVEC_BUILTIN_VEC_VMULOSB },
10362 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuloub", ALTIVEC_BUILTIN_VEC_VMULOUB },
10363 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_nor", ALTIVEC_BUILTIN_VEC_NOR },
10364 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_or", ALTIVEC_BUILTIN_VEC_OR },
10365 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_pack", ALTIVEC_BUILTIN_VEC_PACK },
10366 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuwum", ALTIVEC_BUILTIN_VEC_VPKUWUM },
10367 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuhum", ALTIVEC_BUILTIN_VEC_VPKUHUM },
10368 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packpx", ALTIVEC_BUILTIN_VEC_PACKPX },
10369 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packs", ALTIVEC_BUILTIN_VEC_PACKS },
10370 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkswss", ALTIVEC_BUILTIN_VEC_VPKSWSS },
10371 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuwus", ALTIVEC_BUILTIN_VEC_VPKUWUS },
10372 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkshss", ALTIVEC_BUILTIN_VEC_VPKSHSS },
10373 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuhus", ALTIVEC_BUILTIN_VEC_VPKUHUS },
10374 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packsu", ALTIVEC_BUILTIN_VEC_PACKSU },
10375 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkswus", ALTIVEC_BUILTIN_VEC_VPKSWUS },
10376 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkshus", ALTIVEC_BUILTIN_VEC_VPKSHUS },
10377 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_recipdiv", ALTIVEC_BUILTIN_VEC_RECIP },
10378 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rl", ALTIVEC_BUILTIN_VEC_RL },
10379 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlw", ALTIVEC_BUILTIN_VEC_VRLW },
10380 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlh", ALTIVEC_BUILTIN_VEC_VRLH },
10381 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlb", ALTIVEC_BUILTIN_VEC_VRLB },
10382 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sl", ALTIVEC_BUILTIN_VEC_SL },
10383 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslw", ALTIVEC_BUILTIN_VEC_VSLW },
10384 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslh", ALTIVEC_BUILTIN_VEC_VSLH },
10385 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslb", ALTIVEC_BUILTIN_VEC_VSLB },
10386 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sll", ALTIVEC_BUILTIN_VEC_SLL },
10387 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_slo", ALTIVEC_BUILTIN_VEC_SLO },
10388 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sr", ALTIVEC_BUILTIN_VEC_SR },
10389 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrw", ALTIVEC_BUILTIN_VEC_VSRW },
10390 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrh", ALTIVEC_BUILTIN_VEC_VSRH },
10391 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrb", ALTIVEC_BUILTIN_VEC_VSRB },
10392 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sra", ALTIVEC_BUILTIN_VEC_SRA },
10393 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsraw", ALTIVEC_BUILTIN_VEC_VSRAW },
10394 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrah", ALTIVEC_BUILTIN_VEC_VSRAH },
10395 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrab", ALTIVEC_BUILTIN_VEC_VSRAB },
10396 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_srl", ALTIVEC_BUILTIN_VEC_SRL },
10397 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sro", ALTIVEC_BUILTIN_VEC_SRO },
10398 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_sub", ALTIVEC_BUILTIN_VEC_SUB },
10399 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vsubfp", ALTIVEC_BUILTIN_VEC_VSUBFP },
10400 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuwm", ALTIVEC_BUILTIN_VEC_VSUBUWM },
10401 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuhm", ALTIVEC_BUILTIN_VEC_VSUBUHM },
10402 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsububm", ALTIVEC_BUILTIN_VEC_VSUBUBM },
10403 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_subc", ALTIVEC_BUILTIN_VEC_SUBC },
10404 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_subs", ALTIVEC_BUILTIN_VEC_SUBS },
10405 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubsws", ALTIVEC_BUILTIN_VEC_VSUBSWS },
10406 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuws", ALTIVEC_BUILTIN_VEC_VSUBUWS },
10407 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubshs", ALTIVEC_BUILTIN_VEC_VSUBSHS },
10408 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuhs", ALTIVEC_BUILTIN_VEC_VSUBUHS },
10409 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubsbs", ALTIVEC_BUILTIN_VEC_VSUBSBS },
10410 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsububs", ALTIVEC_BUILTIN_VEC_VSUBUBS },
10411 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sum4s", ALTIVEC_BUILTIN_VEC_SUM4S },
10412 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4shs", ALTIVEC_BUILTIN_VEC_VSUM4SHS },
10413 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4sbs", ALTIVEC_BUILTIN_VEC_VSUM4SBS },
10414 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4ubs", ALTIVEC_BUILTIN_VEC_VSUM4UBS },
10415 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sum2s", ALTIVEC_BUILTIN_VEC_SUM2S },
10416 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sums", ALTIVEC_BUILTIN_VEC_SUMS },
10417 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_xor", ALTIVEC_BUILTIN_VEC_XOR },
10419 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_mul", VSX_BUILTIN_VEC_MUL },
10420 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_div", VSX_BUILTIN_VEC_DIV },
10422 { 0, CODE_FOR_paired_divv2sf3, "__builtin_paired_divv2sf3", PAIRED_BUILTIN_DIVV2SF3 },
10423 { 0, CODE_FOR_paired_addv2sf3, "__builtin_paired_addv2sf3", PAIRED_BUILTIN_ADDV2SF3 },
10424 { 0, CODE_FOR_paired_subv2sf3, "__builtin_paired_subv2sf3", PAIRED_BUILTIN_SUBV2SF3 },
10425 { 0, CODE_FOR_paired_mulv2sf3, "__builtin_paired_mulv2sf3", PAIRED_BUILTIN_MULV2SF3 },
10426 { 0, CODE_FOR_paired_muls0, "__builtin_paired_muls0", PAIRED_BUILTIN_MULS0 },
10427 { 0, CODE_FOR_paired_muls1, "__builtin_paired_muls1", PAIRED_BUILTIN_MULS1 },
10428 { 0, CODE_FOR_paired_merge00, "__builtin_paired_merge00", PAIRED_BUILTIN_MERGE00 },
10429 { 0, CODE_FOR_paired_merge01, "__builtin_paired_merge01", PAIRED_BUILTIN_MERGE01 },
10430 { 0, CODE_FOR_paired_merge10, "__builtin_paired_merge10", PAIRED_BUILTIN_MERGE10 },
10431 { 0, CODE_FOR_paired_merge11, "__builtin_paired_merge11", PAIRED_BUILTIN_MERGE11 },
10433 /* Place holder, leave as first spe builtin. */
10434 { 0, CODE_FOR_addv2si3, "__builtin_spe_evaddw", SPE_BUILTIN_EVADDW },
10435 { 0, CODE_FOR_andv2si3, "__builtin_spe_evand", SPE_BUILTIN_EVAND },
10436 { 0, CODE_FOR_spe_evandc, "__builtin_spe_evandc", SPE_BUILTIN_EVANDC },
10437 { 0, CODE_FOR_divv2si3, "__builtin_spe_evdivws", SPE_BUILTIN_EVDIVWS },
10438 { 0, CODE_FOR_spe_evdivwu, "__builtin_spe_evdivwu", SPE_BUILTIN_EVDIVWU },
10439 { 0, CODE_FOR_spe_eveqv, "__builtin_spe_eveqv", SPE_BUILTIN_EVEQV },
10440 { 0, CODE_FOR_spe_evfsadd, "__builtin_spe_evfsadd", SPE_BUILTIN_EVFSADD },
10441 { 0, CODE_FOR_spe_evfsdiv, "__builtin_spe_evfsdiv", SPE_BUILTIN_EVFSDIV },
10442 { 0, CODE_FOR_spe_evfsmul, "__builtin_spe_evfsmul", SPE_BUILTIN_EVFSMUL },
10443 { 0, CODE_FOR_spe_evfssub, "__builtin_spe_evfssub", SPE_BUILTIN_EVFSSUB },
10444 { 0, CODE_FOR_spe_evmergehi, "__builtin_spe_evmergehi", SPE_BUILTIN_EVMERGEHI },
10445 { 0, CODE_FOR_spe_evmergehilo, "__builtin_spe_evmergehilo", SPE_BUILTIN_EVMERGEHILO },
10446 { 0, CODE_FOR_spe_evmergelo, "__builtin_spe_evmergelo", SPE_BUILTIN_EVMERGELO },
10447 { 0, CODE_FOR_spe_evmergelohi, "__builtin_spe_evmergelohi", SPE_BUILTIN_EVMERGELOHI },
10448 { 0, CODE_FOR_spe_evmhegsmfaa, "__builtin_spe_evmhegsmfaa", SPE_BUILTIN_EVMHEGSMFAA },
10449 { 0, CODE_FOR_spe_evmhegsmfan, "__builtin_spe_evmhegsmfan", SPE_BUILTIN_EVMHEGSMFAN },
10450 { 0, CODE_FOR_spe_evmhegsmiaa, "__builtin_spe_evmhegsmiaa", SPE_BUILTIN_EVMHEGSMIAA },
10451 { 0, CODE_FOR_spe_evmhegsmian, "__builtin_spe_evmhegsmian", SPE_BUILTIN_EVMHEGSMIAN },
10452 { 0, CODE_FOR_spe_evmhegumiaa, "__builtin_spe_evmhegumiaa", SPE_BUILTIN_EVMHEGUMIAA },
10453 { 0, CODE_FOR_spe_evmhegumian, "__builtin_spe_evmhegumian", SPE_BUILTIN_EVMHEGUMIAN },
10454 { 0, CODE_FOR_spe_evmhesmf, "__builtin_spe_evmhesmf", SPE_BUILTIN_EVMHESMF },
10455 { 0, CODE_FOR_spe_evmhesmfa, "__builtin_spe_evmhesmfa", SPE_BUILTIN_EVMHESMFA },
10456 { 0, CODE_FOR_spe_evmhesmfaaw, "__builtin_spe_evmhesmfaaw", SPE_BUILTIN_EVMHESMFAAW },
10457 { 0, CODE_FOR_spe_evmhesmfanw, "__builtin_spe_evmhesmfanw", SPE_BUILTIN_EVMHESMFANW },
10458 { 0, CODE_FOR_spe_evmhesmi, "__builtin_spe_evmhesmi", SPE_BUILTIN_EVMHESMI },
10459 { 0, CODE_FOR_spe_evmhesmia, "__builtin_spe_evmhesmia", SPE_BUILTIN_EVMHESMIA },
10460 { 0, CODE_FOR_spe_evmhesmiaaw, "__builtin_spe_evmhesmiaaw", SPE_BUILTIN_EVMHESMIAAW },
10461 { 0, CODE_FOR_spe_evmhesmianw, "__builtin_spe_evmhesmianw", SPE_BUILTIN_EVMHESMIANW },
10462 { 0, CODE_FOR_spe_evmhessf, "__builtin_spe_evmhessf", SPE_BUILTIN_EVMHESSF },
10463 { 0, CODE_FOR_spe_evmhessfa, "__builtin_spe_evmhessfa", SPE_BUILTIN_EVMHESSFA },
10464 { 0, CODE_FOR_spe_evmhessfaaw, "__builtin_spe_evmhessfaaw", SPE_BUILTIN_EVMHESSFAAW },
10465 { 0, CODE_FOR_spe_evmhessfanw, "__builtin_spe_evmhessfanw", SPE_BUILTIN_EVMHESSFANW },
10466 { 0, CODE_FOR_spe_evmhessiaaw, "__builtin_spe_evmhessiaaw", SPE_BUILTIN_EVMHESSIAAW },
10467 { 0, CODE_FOR_spe_evmhessianw, "__builtin_spe_evmhessianw", SPE_BUILTIN_EVMHESSIANW },
10468 { 0, CODE_FOR_spe_evmheumi, "__builtin_spe_evmheumi", SPE_BUILTIN_EVMHEUMI },
10469 { 0, CODE_FOR_spe_evmheumia, "__builtin_spe_evmheumia", SPE_BUILTIN_EVMHEUMIA },
10470 { 0, CODE_FOR_spe_evmheumiaaw, "__builtin_spe_evmheumiaaw", SPE_BUILTIN_EVMHEUMIAAW },
10471 { 0, CODE_FOR_spe_evmheumianw, "__builtin_spe_evmheumianw", SPE_BUILTIN_EVMHEUMIANW },
10472 { 0, CODE_FOR_spe_evmheusiaaw, "__builtin_spe_evmheusiaaw", SPE_BUILTIN_EVMHEUSIAAW },
10473 { 0, CODE_FOR_spe_evmheusianw, "__builtin_spe_evmheusianw", SPE_BUILTIN_EVMHEUSIANW },
10474 { 0, CODE_FOR_spe_evmhogsmfaa, "__builtin_spe_evmhogsmfaa", SPE_BUILTIN_EVMHOGSMFAA },
10475 { 0, CODE_FOR_spe_evmhogsmfan, "__builtin_spe_evmhogsmfan", SPE_BUILTIN_EVMHOGSMFAN },
10476 { 0, CODE_FOR_spe_evmhogsmiaa, "__builtin_spe_evmhogsmiaa", SPE_BUILTIN_EVMHOGSMIAA },
10477 { 0, CODE_FOR_spe_evmhogsmian, "__builtin_spe_evmhogsmian", SPE_BUILTIN_EVMHOGSMIAN },
10478 { 0, CODE_FOR_spe_evmhogumiaa, "__builtin_spe_evmhogumiaa", SPE_BUILTIN_EVMHOGUMIAA },
10479 { 0, CODE_FOR_spe_evmhogumian, "__builtin_spe_evmhogumian", SPE_BUILTIN_EVMHOGUMIAN },
10480 { 0, CODE_FOR_spe_evmhosmf, "__builtin_spe_evmhosmf", SPE_BUILTIN_EVMHOSMF },
10481 { 0, CODE_FOR_spe_evmhosmfa, "__builtin_spe_evmhosmfa", SPE_BUILTIN_EVMHOSMFA },
10482 { 0, CODE_FOR_spe_evmhosmfaaw, "__builtin_spe_evmhosmfaaw", SPE_BUILTIN_EVMHOSMFAAW },
10483 { 0, CODE_FOR_spe_evmhosmfanw, "__builtin_spe_evmhosmfanw", SPE_BUILTIN_EVMHOSMFANW },
10484 { 0, CODE_FOR_spe_evmhosmi, "__builtin_spe_evmhosmi", SPE_BUILTIN_EVMHOSMI },
10485 { 0, CODE_FOR_spe_evmhosmia, "__builtin_spe_evmhosmia", SPE_BUILTIN_EVMHOSMIA },
10486 { 0, CODE_FOR_spe_evmhosmiaaw, "__builtin_spe_evmhosmiaaw", SPE_BUILTIN_EVMHOSMIAAW },
10487 { 0, CODE_FOR_spe_evmhosmianw, "__builtin_spe_evmhosmianw", SPE_BUILTIN_EVMHOSMIANW },
10488 { 0, CODE_FOR_spe_evmhossf, "__builtin_spe_evmhossf", SPE_BUILTIN_EVMHOSSF },
10489 { 0, CODE_FOR_spe_evmhossfa, "__builtin_spe_evmhossfa", SPE_BUILTIN_EVMHOSSFA },
10490 { 0, CODE_FOR_spe_evmhossfaaw, "__builtin_spe_evmhossfaaw", SPE_BUILTIN_EVMHOSSFAAW },
10491 { 0, CODE_FOR_spe_evmhossfanw, "__builtin_spe_evmhossfanw", SPE_BUILTIN_EVMHOSSFANW },
10492 { 0, CODE_FOR_spe_evmhossiaaw, "__builtin_spe_evmhossiaaw", SPE_BUILTIN_EVMHOSSIAAW },
10493 { 0, CODE_FOR_spe_evmhossianw, "__builtin_spe_evmhossianw", SPE_BUILTIN_EVMHOSSIANW },
10494 { 0, CODE_FOR_spe_evmhoumi, "__builtin_spe_evmhoumi", SPE_BUILTIN_EVMHOUMI },
10495 { 0, CODE_FOR_spe_evmhoumia, "__builtin_spe_evmhoumia", SPE_BUILTIN_EVMHOUMIA },
10496 { 0, CODE_FOR_spe_evmhoumiaaw, "__builtin_spe_evmhoumiaaw", SPE_BUILTIN_EVMHOUMIAAW },
10497 { 0, CODE_FOR_spe_evmhoumianw, "__builtin_spe_evmhoumianw", SPE_BUILTIN_EVMHOUMIANW },
10498 { 0, CODE_FOR_spe_evmhousiaaw, "__builtin_spe_evmhousiaaw", SPE_BUILTIN_EVMHOUSIAAW },
10499 { 0, CODE_FOR_spe_evmhousianw, "__builtin_spe_evmhousianw", SPE_BUILTIN_EVMHOUSIANW },
10500 { 0, CODE_FOR_spe_evmwhsmf, "__builtin_spe_evmwhsmf", SPE_BUILTIN_EVMWHSMF },
10501 { 0, CODE_FOR_spe_evmwhsmfa, "__builtin_spe_evmwhsmfa", SPE_BUILTIN_EVMWHSMFA },
10502 { 0, CODE_FOR_spe_evmwhsmi, "__builtin_spe_evmwhsmi", SPE_BUILTIN_EVMWHSMI },
10503 { 0, CODE_FOR_spe_evmwhsmia, "__builtin_spe_evmwhsmia", SPE_BUILTIN_EVMWHSMIA },
10504 { 0, CODE_FOR_spe_evmwhssf, "__builtin_spe_evmwhssf", SPE_BUILTIN_EVMWHSSF },
10505 { 0, CODE_FOR_spe_evmwhssfa, "__builtin_spe_evmwhssfa", SPE_BUILTIN_EVMWHSSFA },
10506 { 0, CODE_FOR_spe_evmwhumi, "__builtin_spe_evmwhumi", SPE_BUILTIN_EVMWHUMI },
10507 { 0, CODE_FOR_spe_evmwhumia, "__builtin_spe_evmwhumia", SPE_BUILTIN_EVMWHUMIA },
10508 { 0, CODE_FOR_spe_evmwlsmiaaw, "__builtin_spe_evmwlsmiaaw", SPE_BUILTIN_EVMWLSMIAAW },
10509 { 0, CODE_FOR_spe_evmwlsmianw, "__builtin_spe_evmwlsmianw", SPE_BUILTIN_EVMWLSMIANW },
10510 { 0, CODE_FOR_spe_evmwlssiaaw, "__builtin_spe_evmwlssiaaw", SPE_BUILTIN_EVMWLSSIAAW },
10511 { 0, CODE_FOR_spe_evmwlssianw, "__builtin_spe_evmwlssianw", SPE_BUILTIN_EVMWLSSIANW },
10512 { 0, CODE_FOR_spe_evmwlumi, "__builtin_spe_evmwlumi", SPE_BUILTIN_EVMWLUMI },
10513 { 0, CODE_FOR_spe_evmwlumia, "__builtin_spe_evmwlumia", SPE_BUILTIN_EVMWLUMIA },
10514 { 0, CODE_FOR_spe_evmwlumiaaw, "__builtin_spe_evmwlumiaaw", SPE_BUILTIN_EVMWLUMIAAW },
10515 { 0, CODE_FOR_spe_evmwlumianw, "__builtin_spe_evmwlumianw", SPE_BUILTIN_EVMWLUMIANW },
10516 { 0, CODE_FOR_spe_evmwlusiaaw, "__builtin_spe_evmwlusiaaw", SPE_BUILTIN_EVMWLUSIAAW },
10517 { 0, CODE_FOR_spe_evmwlusianw, "__builtin_spe_evmwlusianw", SPE_BUILTIN_EVMWLUSIANW },
10518 { 0, CODE_FOR_spe_evmwsmf, "__builtin_spe_evmwsmf", SPE_BUILTIN_EVMWSMF },
10519 { 0, CODE_FOR_spe_evmwsmfa, "__builtin_spe_evmwsmfa", SPE_BUILTIN_EVMWSMFA },
10520 { 0, CODE_FOR_spe_evmwsmfaa, "__builtin_spe_evmwsmfaa", SPE_BUILTIN_EVMWSMFAA },
10521 { 0, CODE_FOR_spe_evmwsmfan, "__builtin_spe_evmwsmfan", SPE_BUILTIN_EVMWSMFAN },
10522 { 0, CODE_FOR_spe_evmwsmi, "__builtin_spe_evmwsmi", SPE_BUILTIN_EVMWSMI },
10523 { 0, CODE_FOR_spe_evmwsmia, "__builtin_spe_evmwsmia", SPE_BUILTIN_EVMWSMIA },
10524 { 0, CODE_FOR_spe_evmwsmiaa, "__builtin_spe_evmwsmiaa", SPE_BUILTIN_EVMWSMIAA },
10525 { 0, CODE_FOR_spe_evmwsmian, "__builtin_spe_evmwsmian", SPE_BUILTIN_EVMWSMIAN },
10526 { 0, CODE_FOR_spe_evmwssf, "__builtin_spe_evmwssf", SPE_BUILTIN_EVMWSSF },
10527 { 0, CODE_FOR_spe_evmwssfa, "__builtin_spe_evmwssfa", SPE_BUILTIN_EVMWSSFA },
10528 { 0, CODE_FOR_spe_evmwssfaa, "__builtin_spe_evmwssfaa", SPE_BUILTIN_EVMWSSFAA },
10529 { 0, CODE_FOR_spe_evmwssfan, "__builtin_spe_evmwssfan", SPE_BUILTIN_EVMWSSFAN },
10530 { 0, CODE_FOR_spe_evmwumi, "__builtin_spe_evmwumi", SPE_BUILTIN_EVMWUMI },
10531 { 0, CODE_FOR_spe_evmwumia, "__builtin_spe_evmwumia", SPE_BUILTIN_EVMWUMIA },
10532 { 0, CODE_FOR_spe_evmwumiaa, "__builtin_spe_evmwumiaa", SPE_BUILTIN_EVMWUMIAA },
10533 { 0, CODE_FOR_spe_evmwumian, "__builtin_spe_evmwumian", SPE_BUILTIN_EVMWUMIAN },
10534 { 0, CODE_FOR_spe_evnand, "__builtin_spe_evnand", SPE_BUILTIN_EVNAND },
10535 { 0, CODE_FOR_spe_evnor, "__builtin_spe_evnor", SPE_BUILTIN_EVNOR },
10536 { 0, CODE_FOR_spe_evor, "__builtin_spe_evor", SPE_BUILTIN_EVOR },
10537 { 0, CODE_FOR_spe_evorc, "__builtin_spe_evorc", SPE_BUILTIN_EVORC },
10538 { 0, CODE_FOR_spe_evrlw, "__builtin_spe_evrlw", SPE_BUILTIN_EVRLW },
10539 { 0, CODE_FOR_spe_evslw, "__builtin_spe_evslw", SPE_BUILTIN_EVSLW },
10540 { 0, CODE_FOR_spe_evsrws, "__builtin_spe_evsrws", SPE_BUILTIN_EVSRWS },
10541 { 0, CODE_FOR_spe_evsrwu, "__builtin_spe_evsrwu", SPE_BUILTIN_EVSRWU },
10542 { 0, CODE_FOR_subv2si3, "__builtin_spe_evsubfw", SPE_BUILTIN_EVSUBFW },
10544 /* SPE binary operations expecting a 5-bit unsigned literal. */
10545 { 0, CODE_FOR_spe_evaddiw, "__builtin_spe_evaddiw", SPE_BUILTIN_EVADDIW },
10547 { 0, CODE_FOR_spe_evrlwi, "__builtin_spe_evrlwi", SPE_BUILTIN_EVRLWI },
10548 { 0, CODE_FOR_spe_evslwi, "__builtin_spe_evslwi", SPE_BUILTIN_EVSLWI },
10549 { 0, CODE_FOR_spe_evsrwis, "__builtin_spe_evsrwis", SPE_BUILTIN_EVSRWIS },
10550 { 0, CODE_FOR_spe_evsrwiu, "__builtin_spe_evsrwiu", SPE_BUILTIN_EVSRWIU },
10551 { 0, CODE_FOR_spe_evsubifw, "__builtin_spe_evsubifw", SPE_BUILTIN_EVSUBIFW },
10552 { 0, CODE_FOR_spe_evmwhssfaa, "__builtin_spe_evmwhssfaa", SPE_BUILTIN_EVMWHSSFAA },
10553 { 0, CODE_FOR_spe_evmwhssmaa, "__builtin_spe_evmwhssmaa", SPE_BUILTIN_EVMWHSSMAA },
10554 { 0, CODE_FOR_spe_evmwhsmfaa, "__builtin_spe_evmwhsmfaa", SPE_BUILTIN_EVMWHSMFAA },
10555 { 0, CODE_FOR_spe_evmwhsmiaa, "__builtin_spe_evmwhsmiaa", SPE_BUILTIN_EVMWHSMIAA },
10556 { 0, CODE_FOR_spe_evmwhusiaa, "__builtin_spe_evmwhusiaa", SPE_BUILTIN_EVMWHUSIAA },
10557 { 0, CODE_FOR_spe_evmwhumiaa, "__builtin_spe_evmwhumiaa", SPE_BUILTIN_EVMWHUMIAA },
10558 { 0, CODE_FOR_spe_evmwhssfan, "__builtin_spe_evmwhssfan", SPE_BUILTIN_EVMWHSSFAN },
10559 { 0, CODE_FOR_spe_evmwhssian, "__builtin_spe_evmwhssian", SPE_BUILTIN_EVMWHSSIAN },
10560 { 0, CODE_FOR_spe_evmwhsmfan, "__builtin_spe_evmwhsmfan", SPE_BUILTIN_EVMWHSMFAN },
10561 { 0, CODE_FOR_spe_evmwhsmian, "__builtin_spe_evmwhsmian", SPE_BUILTIN_EVMWHSMIAN },
10562 { 0, CODE_FOR_spe_evmwhusian, "__builtin_spe_evmwhusian", SPE_BUILTIN_EVMWHUSIAN },
10563 { 0, CODE_FOR_spe_evmwhumian, "__builtin_spe_evmwhumian", SPE_BUILTIN_EVMWHUMIAN },
10564 { 0, CODE_FOR_spe_evmwhgssfaa, "__builtin_spe_evmwhgssfaa", SPE_BUILTIN_EVMWHGSSFAA },
10565 { 0, CODE_FOR_spe_evmwhgsmfaa, "__builtin_spe_evmwhgsmfaa", SPE_BUILTIN_EVMWHGSMFAA },
10566 { 0, CODE_FOR_spe_evmwhgsmiaa, "__builtin_spe_evmwhgsmiaa", SPE_BUILTIN_EVMWHGSMIAA },
10567 { 0, CODE_FOR_spe_evmwhgumiaa, "__builtin_spe_evmwhgumiaa", SPE_BUILTIN_EVMWHGUMIAA },
10568 { 0, CODE_FOR_spe_evmwhgssfan, "__builtin_spe_evmwhgssfan", SPE_BUILTIN_EVMWHGSSFAN },
10569 { 0, CODE_FOR_spe_evmwhgsmfan, "__builtin_spe_evmwhgsmfan", SPE_BUILTIN_EVMWHGSMFAN },
10570 { 0, CODE_FOR_spe_evmwhgsmian, "__builtin_spe_evmwhgsmian", SPE_BUILTIN_EVMWHGSMIAN },
10571 { 0, CODE_FOR_spe_evmwhgumian, "__builtin_spe_evmwhgumian", SPE_BUILTIN_EVMWHGUMIAN },
10572 { 0, CODE_FOR_spe_brinc, "__builtin_spe_brinc", SPE_BUILTIN_BRINC },
10574 /* Place-holder. Leave as last binary SPE builtin. */
10575 { 0, CODE_FOR_xorv2si3, "__builtin_spe_evxor", SPE_BUILTIN_EVXOR }
10578 /* AltiVec predicates. */
10580 struct builtin_description_predicates
10582 const unsigned int mask;
10583 const enum insn_code icode;
10584 const char *const name;
10585 const enum rs6000_builtins code;
10588 static const struct builtin_description_predicates bdesc_altivec_preds[] =
10590 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpbfp_p, "__builtin_altivec_vcmpbfp_p",
10591 ALTIVEC_BUILTIN_VCMPBFP_P },
10592 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_eq_v4sf_p,
10593 "__builtin_altivec_vcmpeqfp_p", ALTIVEC_BUILTIN_VCMPEQFP_P },
10594 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_ge_v4sf_p,
10595 "__builtin_altivec_vcmpgefp_p", ALTIVEC_BUILTIN_VCMPGEFP_P },
10596 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_gt_v4sf_p,
10597 "__builtin_altivec_vcmpgtfp_p", ALTIVEC_BUILTIN_VCMPGTFP_P },
10598 { MASK_ALTIVEC, CODE_FOR_vector_eq_v4si_p, "__builtin_altivec_vcmpequw_p",
10599 ALTIVEC_BUILTIN_VCMPEQUW_P },
10600 { MASK_ALTIVEC, CODE_FOR_vector_gt_v4si_p, "__builtin_altivec_vcmpgtsw_p",
10601 ALTIVEC_BUILTIN_VCMPGTSW_P },
10602 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v4si_p, "__builtin_altivec_vcmpgtuw_p",
10603 ALTIVEC_BUILTIN_VCMPGTUW_P },
10604 { MASK_ALTIVEC, CODE_FOR_vector_eq_v8hi_p, "__builtin_altivec_vcmpequh_p",
10605 ALTIVEC_BUILTIN_VCMPEQUH_P },
10606 { MASK_ALTIVEC, CODE_FOR_vector_gt_v8hi_p, "__builtin_altivec_vcmpgtsh_p",
10607 ALTIVEC_BUILTIN_VCMPGTSH_P },
10608 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v8hi_p, "__builtin_altivec_vcmpgtuh_p",
10609 ALTIVEC_BUILTIN_VCMPGTUH_P },
10610 { MASK_ALTIVEC, CODE_FOR_vector_eq_v16qi_p, "__builtin_altivec_vcmpequb_p",
10611 ALTIVEC_BUILTIN_VCMPEQUB_P },
10612 { MASK_ALTIVEC, CODE_FOR_vector_gt_v16qi_p, "__builtin_altivec_vcmpgtsb_p",
10613 ALTIVEC_BUILTIN_VCMPGTSB_P },
10614 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v16qi_p, "__builtin_altivec_vcmpgtub_p",
10615 ALTIVEC_BUILTIN_VCMPGTUB_P },
10617 { MASK_VSX, CODE_FOR_vector_eq_v4sf_p, "__builtin_vsx_xvcmpeqsp_p",
10618 VSX_BUILTIN_XVCMPEQSP_P },
10619 { MASK_VSX, CODE_FOR_vector_ge_v4sf_p, "__builtin_vsx_xvcmpgesp_p",
10620 VSX_BUILTIN_XVCMPGESP_P },
10621 { MASK_VSX, CODE_FOR_vector_gt_v4sf_p, "__builtin_vsx_xvcmpgtsp_p",
10622 VSX_BUILTIN_XVCMPGTSP_P },
10623 { MASK_VSX, CODE_FOR_vector_eq_v2df_p, "__builtin_vsx_xvcmpeqdp_p",
10624 VSX_BUILTIN_XVCMPEQDP_P },
10625 { MASK_VSX, CODE_FOR_vector_ge_v2df_p, "__builtin_vsx_xvcmpgedp_p",
10626 VSX_BUILTIN_XVCMPGEDP_P },
10627 { MASK_VSX, CODE_FOR_vector_gt_v2df_p, "__builtin_vsx_xvcmpgtdp_p",
10628 VSX_BUILTIN_XVCMPGTDP_P },
10630 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpeq_p",
10631 ALTIVEC_BUILTIN_VCMPEQ_P },
10632 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpgt_p",
10633 ALTIVEC_BUILTIN_VCMPGT_P },
10634 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpge_p",
10635 ALTIVEC_BUILTIN_VCMPGE_P }
10638 /* SPE predicates. */
10639 static struct builtin_description bdesc_spe_predicates[] =
10641 /* Place-holder. Leave as first. */
10642 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evcmpeq", SPE_BUILTIN_EVCMPEQ },
10643 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evcmpgts", SPE_BUILTIN_EVCMPGTS },
10644 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evcmpgtu", SPE_BUILTIN_EVCMPGTU },
10645 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evcmplts", SPE_BUILTIN_EVCMPLTS },
10646 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evcmpltu", SPE_BUILTIN_EVCMPLTU },
10647 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evfscmpeq", SPE_BUILTIN_EVFSCMPEQ },
10648 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evfscmpgt", SPE_BUILTIN_EVFSCMPGT },
10649 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evfscmplt", SPE_BUILTIN_EVFSCMPLT },
10650 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evfststeq", SPE_BUILTIN_EVFSTSTEQ },
10651 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evfststgt", SPE_BUILTIN_EVFSTSTGT },
10652 /* Place-holder. Leave as last. */
10653 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evfststlt", SPE_BUILTIN_EVFSTSTLT },
10656 /* SPE evsel predicates. */
10657 static struct builtin_description bdesc_spe_evsel[] =
10659 /* Place-holder. Leave as first. */
10660 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evsel_gts", SPE_BUILTIN_EVSEL_CMPGTS },
10661 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evsel_gtu", SPE_BUILTIN_EVSEL_CMPGTU },
10662 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evsel_lts", SPE_BUILTIN_EVSEL_CMPLTS },
10663 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evsel_ltu", SPE_BUILTIN_EVSEL_CMPLTU },
10664 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evsel_eq", SPE_BUILTIN_EVSEL_CMPEQ },
10665 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evsel_fsgt", SPE_BUILTIN_EVSEL_FSCMPGT },
10666 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evsel_fslt", SPE_BUILTIN_EVSEL_FSCMPLT },
10667 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evsel_fseq", SPE_BUILTIN_EVSEL_FSCMPEQ },
10668 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evsel_fststgt", SPE_BUILTIN_EVSEL_FSTSTGT },
10669 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evsel_fststlt", SPE_BUILTIN_EVSEL_FSTSTLT },
10670 /* Place-holder. Leave as last. */
10671 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evsel_fststeq", SPE_BUILTIN_EVSEL_FSTSTEQ },
10674 /* PAIRED predicates. */
10675 static const struct builtin_description bdesc_paired_preds[] =
10677 /* Place-holder. Leave as first. */
10678 { 0, CODE_FOR_paired_cmpu0, "__builtin_paired_cmpu0", PAIRED_BUILTIN_CMPU0 },
10679 /* Place-holder. Leave as last. */
10680 { 0, CODE_FOR_paired_cmpu1, "__builtin_paired_cmpu1", PAIRED_BUILTIN_CMPU1 },
10683 /* ABS* operations. */
10685 static const struct builtin_description bdesc_abs[] =
10687 { MASK_ALTIVEC, CODE_FOR_absv4si2, "__builtin_altivec_abs_v4si", ALTIVEC_BUILTIN_ABS_V4SI },
10688 { MASK_ALTIVEC, CODE_FOR_absv8hi2, "__builtin_altivec_abs_v8hi", ALTIVEC_BUILTIN_ABS_V8HI },
10689 { MASK_ALTIVEC, CODE_FOR_absv4sf2, "__builtin_altivec_abs_v4sf", ALTIVEC_BUILTIN_ABS_V4SF },
10690 { MASK_ALTIVEC, CODE_FOR_absv16qi2, "__builtin_altivec_abs_v16qi", ALTIVEC_BUILTIN_ABS_V16QI },
10691 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v4si, "__builtin_altivec_abss_v4si", ALTIVEC_BUILTIN_ABSS_V4SI },
10692 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v8hi, "__builtin_altivec_abss_v8hi", ALTIVEC_BUILTIN_ABSS_V8HI },
10693 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v16qi, "__builtin_altivec_abss_v16qi", ALTIVEC_BUILTIN_ABSS_V16QI },
10694 { MASK_VSX, CODE_FOR_absv2df2, "__builtin_vsx_xvabsdp", VSX_BUILTIN_XVABSDP },
10695 { MASK_VSX, CODE_FOR_vsx_nabsv2df2, "__builtin_vsx_xvnabsdp", VSX_BUILTIN_XVNABSDP },
10696 { MASK_VSX, CODE_FOR_absv4sf2, "__builtin_vsx_xvabssp", VSX_BUILTIN_XVABSSP },
10697 { MASK_VSX, CODE_FOR_vsx_nabsv4sf2, "__builtin_vsx_xvnabssp", VSX_BUILTIN_XVNABSSP },
10700 /* Simple unary operations: VECb = foo (unsigned literal) or VECb =
10701 foo (VECa). */
10703 static struct builtin_description bdesc_1arg[] =
10705 { MASK_ALTIVEC, CODE_FOR_altivec_vexptefp, "__builtin_altivec_vexptefp", ALTIVEC_BUILTIN_VEXPTEFP },
10706 { MASK_ALTIVEC, CODE_FOR_altivec_vlogefp, "__builtin_altivec_vlogefp", ALTIVEC_BUILTIN_VLOGEFP },
10707 { MASK_ALTIVEC, CODE_FOR_rev4sf2, "__builtin_altivec_vrefp", ALTIVEC_BUILTIN_VREFP },
10708 { MASK_ALTIVEC, CODE_FOR_vector_floorv4sf2, "__builtin_altivec_vrfim", ALTIVEC_BUILTIN_VRFIM },
10709 { MASK_ALTIVEC, CODE_FOR_altivec_vrfin, "__builtin_altivec_vrfin", ALTIVEC_BUILTIN_VRFIN },
10710 { MASK_ALTIVEC, CODE_FOR_vector_ceilv4sf2, "__builtin_altivec_vrfip", ALTIVEC_BUILTIN_VRFIP },
10711 { MASK_ALTIVEC, CODE_FOR_vector_btruncv4sf2, "__builtin_altivec_vrfiz", ALTIVEC_BUILTIN_VRFIZ },
10712 { MASK_ALTIVEC, CODE_FOR_rsqrtv4sf2, "__builtin_altivec_vrsqrtfp", ALTIVEC_BUILTIN_VRSQRTFP },
10713 { MASK_ALTIVEC, CODE_FOR_rsqrtev4sf2, "__builtin_altivec_vrsqrtefp", ALTIVEC_BUILTIN_VRSQRTEFP },
10714 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisb, "__builtin_altivec_vspltisb", ALTIVEC_BUILTIN_VSPLTISB },
10715 { MASK_ALTIVEC, CODE_FOR_altivec_vspltish, "__builtin_altivec_vspltish", ALTIVEC_BUILTIN_VSPLTISH },
10716 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisw, "__builtin_altivec_vspltisw", ALTIVEC_BUILTIN_VSPLTISW },
10717 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsb, "__builtin_altivec_vupkhsb", ALTIVEC_BUILTIN_VUPKHSB },
10718 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhpx, "__builtin_altivec_vupkhpx", ALTIVEC_BUILTIN_VUPKHPX },
10719 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsh, "__builtin_altivec_vupkhsh", ALTIVEC_BUILTIN_VUPKHSH },
10720 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsb, "__builtin_altivec_vupklsb", ALTIVEC_BUILTIN_VUPKLSB },
10721 { MASK_ALTIVEC, CODE_FOR_altivec_vupklpx, "__builtin_altivec_vupklpx", ALTIVEC_BUILTIN_VUPKLPX },
10722 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsh, "__builtin_altivec_vupklsh", ALTIVEC_BUILTIN_VUPKLSH },
10724 { MASK_VSX, CODE_FOR_negv2df2, "__builtin_vsx_xvnegdp", VSX_BUILTIN_XVNEGDP },
10725 { MASK_VSX, CODE_FOR_sqrtv2df2, "__builtin_vsx_xvsqrtdp", VSX_BUILTIN_XVSQRTDP },
10726 { MASK_VSX, CODE_FOR_rsqrtv2df2, "__builtin_vsx_xvrsqrtdp", VSX_BUILTIN_VEC_RSQRT_V2DF },
10727 { MASK_VSX, CODE_FOR_rsqrtev2df2, "__builtin_vsx_xvrsqrtedp", VSX_BUILTIN_XVRSQRTEDP },
10728 { MASK_VSX, CODE_FOR_vsx_tsqrtv2df2_fe, "__builtin_vsx_xvtsqrtdp_fe", VSX_BUILTIN_XVTSQRTDP_FE },
10729 { MASK_VSX, CODE_FOR_vsx_tsqrtv2df2_fg, "__builtin_vsx_xvtsqrtdp_fg", VSX_BUILTIN_XVTSQRTDP_FG },
10730 { MASK_VSX, CODE_FOR_vsx_frev2df2, "__builtin_vsx_xvredp", VSX_BUILTIN_XVREDP },
10732 { MASK_VSX, CODE_FOR_negv4sf2, "__builtin_vsx_xvnegsp", VSX_BUILTIN_XVNEGSP },
10733 { MASK_VSX, CODE_FOR_sqrtv4sf2, "__builtin_vsx_xvsqrtsp", VSX_BUILTIN_XVSQRTSP },
10734 { MASK_VSX, CODE_FOR_rsqrtv4sf2, "__builtin_vsx_xvrsqrtsp", VSX_BUILTIN_VEC_RSQRT_V4SF },
10735 { MASK_VSX, CODE_FOR_rsqrtev4sf2, "__builtin_vsx_xvrsqrtesp", VSX_BUILTIN_XVRSQRTESP },
10736 { MASK_VSX, CODE_FOR_vsx_tsqrtv4sf2_fe, "__builtin_vsx_xvtsqrtsp_fe", VSX_BUILTIN_XVTSQRTSP_FE },
10737 { MASK_VSX, CODE_FOR_vsx_tsqrtv4sf2_fg, "__builtin_vsx_xvtsqrtsp_fg", VSX_BUILTIN_XVTSQRTSP_FG },
10738 { MASK_VSX, CODE_FOR_vsx_frev4sf2, "__builtin_vsx_xvresp", VSX_BUILTIN_XVRESP },
10740 { MASK_VSX, CODE_FOR_vsx_xscvdpsp, "__builtin_vsx_xscvdpsp", VSX_BUILTIN_XSCVDPSP },
10741 { MASK_VSX, CODE_FOR_vsx_xscvdpsp, "__builtin_vsx_xscvspdp", VSX_BUILTIN_XSCVSPDP },
10742 { MASK_VSX, CODE_FOR_vsx_xvcvdpsp, "__builtin_vsx_xvcvdpsp", VSX_BUILTIN_XVCVDPSP },
10743 { MASK_VSX, CODE_FOR_vsx_xvcvspdp, "__builtin_vsx_xvcvspdp", VSX_BUILTIN_XVCVSPDP },
10744 { MASK_VSX, CODE_FOR_vsx_tsqrtdf2_fe, "__builtin_vsx_xstsqrtdp_fe", VSX_BUILTIN_XSTSQRTDP_FE },
10745 { MASK_VSX, CODE_FOR_vsx_tsqrtdf2_fg, "__builtin_vsx_xstsqrtdp_fg", VSX_BUILTIN_XSTSQRTDP_FG },
10747 { MASK_VSX, CODE_FOR_vsx_fix_truncv2dfv2di2, "__builtin_vsx_xvcvdpsxds", VSX_BUILTIN_XVCVDPSXDS },
10748 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv2dfv2di2, "__builtin_vsx_xvcvdpuxds", VSX_BUILTIN_XVCVDPUXDS },
10749 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv2dfv2di2, "__builtin_vsx_xvcvdpuxds_uns", VSX_BUILTIN_XVCVDPUXDS_UNS },
10750 { MASK_VSX, CODE_FOR_vsx_floatv2div2df2, "__builtin_vsx_xvcvsxddp", VSX_BUILTIN_XVCVSXDDP },
10751 { MASK_VSX, CODE_FOR_vsx_floatunsv2div2df2, "__builtin_vsx_xvcvuxddp", VSX_BUILTIN_XVCVUXDDP },
10752 { MASK_VSX, CODE_FOR_vsx_floatunsv2div2df2, "__builtin_vsx_xvcvuxddp_uns", VSX_BUILTIN_XVCVUXDDP_UNS },
10754 { MASK_VSX, CODE_FOR_vsx_fix_truncv4sfv4si2, "__builtin_vsx_xvcvspsxws", VSX_BUILTIN_XVCVSPSXWS },
10755 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv4sfv4si2, "__builtin_vsx_xvcvspuxws", VSX_BUILTIN_XVCVSPUXWS },
10756 { MASK_VSX, CODE_FOR_vsx_floatv4siv4sf2, "__builtin_vsx_xvcvsxwsp", VSX_BUILTIN_XVCVSXWSP },
10757 { MASK_VSX, CODE_FOR_vsx_floatunsv4siv4sf2, "__builtin_vsx_xvcvuxwsp", VSX_BUILTIN_XVCVUXWSP },
10759 { MASK_VSX, CODE_FOR_vsx_xvcvdpsxws, "__builtin_vsx_xvcvdpsxws", VSX_BUILTIN_XVCVDPSXWS },
10760 { MASK_VSX, CODE_FOR_vsx_xvcvdpuxws, "__builtin_vsx_xvcvdpuxws", VSX_BUILTIN_XVCVDPUXWS },
10761 { MASK_VSX, CODE_FOR_vsx_xvcvsxwdp, "__builtin_vsx_xvcvsxwdp", VSX_BUILTIN_XVCVSXWDP },
10762 { MASK_VSX, CODE_FOR_vsx_xvcvuxwdp, "__builtin_vsx_xvcvuxwdp", VSX_BUILTIN_XVCVUXWDP },
10763 { MASK_VSX, CODE_FOR_vsx_xvrdpi, "__builtin_vsx_xvrdpi", VSX_BUILTIN_XVRDPI },
10764 { MASK_VSX, CODE_FOR_vsx_xvrdpic, "__builtin_vsx_xvrdpic", VSX_BUILTIN_XVRDPIC },
10765 { MASK_VSX, CODE_FOR_vsx_floorv2df2, "__builtin_vsx_xvrdpim", VSX_BUILTIN_XVRDPIM },
10766 { MASK_VSX, CODE_FOR_vsx_ceilv2df2, "__builtin_vsx_xvrdpip", VSX_BUILTIN_XVRDPIP },
10767 { MASK_VSX, CODE_FOR_vsx_btruncv2df2, "__builtin_vsx_xvrdpiz", VSX_BUILTIN_XVRDPIZ },
10769 { MASK_VSX, CODE_FOR_vsx_xvcvspsxds, "__builtin_vsx_xvcvspsxds", VSX_BUILTIN_XVCVSPSXDS },
10770 { MASK_VSX, CODE_FOR_vsx_xvcvspuxds, "__builtin_vsx_xvcvspuxds", VSX_BUILTIN_XVCVSPUXDS },
10771 { MASK_VSX, CODE_FOR_vsx_xvcvsxdsp, "__builtin_vsx_xvcvsxdsp", VSX_BUILTIN_XVCVSXDSP },
10772 { MASK_VSX, CODE_FOR_vsx_xvcvuxdsp, "__builtin_vsx_xvcvuxdsp", VSX_BUILTIN_XVCVUXDSP },
10773 { MASK_VSX, CODE_FOR_vsx_xvrspi, "__builtin_vsx_xvrspi", VSX_BUILTIN_XVRSPI },
10774 { MASK_VSX, CODE_FOR_vsx_xvrspic, "__builtin_vsx_xvrspic", VSX_BUILTIN_XVRSPIC },
10775 { MASK_VSX, CODE_FOR_vsx_floorv4sf2, "__builtin_vsx_xvrspim", VSX_BUILTIN_XVRSPIM },
10776 { MASK_VSX, CODE_FOR_vsx_ceilv4sf2, "__builtin_vsx_xvrspip", VSX_BUILTIN_XVRSPIP },
10777 { MASK_VSX, CODE_FOR_vsx_btruncv4sf2, "__builtin_vsx_xvrspiz", VSX_BUILTIN_XVRSPIZ },
10779 { MASK_VSX, CODE_FOR_vsx_xsrdpi, "__builtin_vsx_xsrdpi", VSX_BUILTIN_XSRDPI },
10780 { MASK_VSX, CODE_FOR_vsx_xsrdpic, "__builtin_vsx_xsrdpic", VSX_BUILTIN_XSRDPIC },
10781 { MASK_VSX, CODE_FOR_vsx_floordf2, "__builtin_vsx_xsrdpim", VSX_BUILTIN_XSRDPIM },
10782 { MASK_VSX, CODE_FOR_vsx_ceildf2, "__builtin_vsx_xsrdpip", VSX_BUILTIN_XSRDPIP },
10783 { MASK_VSX, CODE_FOR_vsx_btruncdf2, "__builtin_vsx_xsrdpiz", VSX_BUILTIN_XSRDPIZ },
10785 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abs", ALTIVEC_BUILTIN_VEC_ABS },
10786 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abss", ALTIVEC_BUILTIN_VEC_ABSS },
10787 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_ceil", ALTIVEC_BUILTIN_VEC_CEIL },
10788 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_expte", ALTIVEC_BUILTIN_VEC_EXPTE },
10789 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_floor", ALTIVEC_BUILTIN_VEC_FLOOR },
10790 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_loge", ALTIVEC_BUILTIN_VEC_LOGE },
10791 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mtvscr", ALTIVEC_BUILTIN_VEC_MTVSCR },
10792 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_re", ALTIVEC_BUILTIN_VEC_RE },
10793 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_round", ALTIVEC_BUILTIN_VEC_ROUND },
10794 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rsqrt", ALTIVEC_BUILTIN_VEC_RSQRT },
10795 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rsqrte", ALTIVEC_BUILTIN_VEC_RSQRTE },
10796 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_trunc", ALTIVEC_BUILTIN_VEC_TRUNC },
10797 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_unpackh", ALTIVEC_BUILTIN_VEC_UNPACKH },
10798 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhsh", ALTIVEC_BUILTIN_VEC_VUPKHSH },
10799 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhpx", ALTIVEC_BUILTIN_VEC_VUPKHPX },
10800 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhsb", ALTIVEC_BUILTIN_VEC_VUPKHSB },
10801 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_unpackl", ALTIVEC_BUILTIN_VEC_UNPACKL },
10802 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklpx", ALTIVEC_BUILTIN_VEC_VUPKLPX },
10803 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsh", ALTIVEC_BUILTIN_VEC_VUPKLSH },
10804 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsb", ALTIVEC_BUILTIN_VEC_VUPKLSB },
10806 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_nearbyint", ALTIVEC_BUILTIN_VEC_NEARBYINT },
10807 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_rint", ALTIVEC_BUILTIN_VEC_RINT },
10808 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_sqrt", ALTIVEC_BUILTIN_VEC_SQRT },
10810 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_floatv4siv4sf2, "__builtin_vec_float_sisf", VECTOR_BUILTIN_FLOAT_V4SI_V4SF },
10811 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_unsigned_floatv4siv4sf2, "__builtin_vec_uns_float_sisf", VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF },
10812 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_fix_truncv4sfv4si2, "__builtin_vec_fix_sfsi", VECTOR_BUILTIN_FIX_V4SF_V4SI },
10813 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_fixuns_truncv4sfv4si2, "__builtin_vec_fixuns_sfsi", VECTOR_BUILTIN_FIXUNS_V4SF_V4SI },
10815 /* The SPE unary builtins must start with SPE_BUILTIN_EVABS and
10816 end with SPE_BUILTIN_EVSUBFUSIAAW. */
10817 { 0, CODE_FOR_absv2si2, "__builtin_spe_evabs", SPE_BUILTIN_EVABS },
10818 { 0, CODE_FOR_spe_evaddsmiaaw, "__builtin_spe_evaddsmiaaw", SPE_BUILTIN_EVADDSMIAAW },
10819 { 0, CODE_FOR_spe_evaddssiaaw, "__builtin_spe_evaddssiaaw", SPE_BUILTIN_EVADDSSIAAW },
10820 { 0, CODE_FOR_spe_evaddumiaaw, "__builtin_spe_evaddumiaaw", SPE_BUILTIN_EVADDUMIAAW },
10821 { 0, CODE_FOR_spe_evaddusiaaw, "__builtin_spe_evaddusiaaw", SPE_BUILTIN_EVADDUSIAAW },
10822 { 0, CODE_FOR_spe_evcntlsw, "__builtin_spe_evcntlsw", SPE_BUILTIN_EVCNTLSW },
10823 { 0, CODE_FOR_spe_evcntlzw, "__builtin_spe_evcntlzw", SPE_BUILTIN_EVCNTLZW },
10824 { 0, CODE_FOR_spe_evextsb, "__builtin_spe_evextsb", SPE_BUILTIN_EVEXTSB },
10825 { 0, CODE_FOR_spe_evextsh, "__builtin_spe_evextsh", SPE_BUILTIN_EVEXTSH },
10826 { 0, CODE_FOR_spe_evfsabs, "__builtin_spe_evfsabs", SPE_BUILTIN_EVFSABS },
10827 { 0, CODE_FOR_spe_evfscfsf, "__builtin_spe_evfscfsf", SPE_BUILTIN_EVFSCFSF },
10828 { 0, CODE_FOR_spe_evfscfsi, "__builtin_spe_evfscfsi", SPE_BUILTIN_EVFSCFSI },
10829 { 0, CODE_FOR_spe_evfscfuf, "__builtin_spe_evfscfuf", SPE_BUILTIN_EVFSCFUF },
10830 { 0, CODE_FOR_spe_evfscfui, "__builtin_spe_evfscfui", SPE_BUILTIN_EVFSCFUI },
10831 { 0, CODE_FOR_spe_evfsctsf, "__builtin_spe_evfsctsf", SPE_BUILTIN_EVFSCTSF },
10832 { 0, CODE_FOR_spe_evfsctsi, "__builtin_spe_evfsctsi", SPE_BUILTIN_EVFSCTSI },
10833 { 0, CODE_FOR_spe_evfsctsiz, "__builtin_spe_evfsctsiz", SPE_BUILTIN_EVFSCTSIZ },
10834 { 0, CODE_FOR_spe_evfsctuf, "__builtin_spe_evfsctuf", SPE_BUILTIN_EVFSCTUF },
10835 { 0, CODE_FOR_spe_evfsctui, "__builtin_spe_evfsctui", SPE_BUILTIN_EVFSCTUI },
10836 { 0, CODE_FOR_spe_evfsctuiz, "__builtin_spe_evfsctuiz", SPE_BUILTIN_EVFSCTUIZ },
10837 { 0, CODE_FOR_spe_evfsnabs, "__builtin_spe_evfsnabs", SPE_BUILTIN_EVFSNABS },
10838 { 0, CODE_FOR_spe_evfsneg, "__builtin_spe_evfsneg", SPE_BUILTIN_EVFSNEG },
10839 { 0, CODE_FOR_spe_evmra, "__builtin_spe_evmra", SPE_BUILTIN_EVMRA },
10840 { 0, CODE_FOR_negv2si2, "__builtin_spe_evneg", SPE_BUILTIN_EVNEG },
10841 { 0, CODE_FOR_spe_evrndw, "__builtin_spe_evrndw", SPE_BUILTIN_EVRNDW },
10842 { 0, CODE_FOR_spe_evsubfsmiaaw, "__builtin_spe_evsubfsmiaaw", SPE_BUILTIN_EVSUBFSMIAAW },
10843 { 0, CODE_FOR_spe_evsubfssiaaw, "__builtin_spe_evsubfssiaaw", SPE_BUILTIN_EVSUBFSSIAAW },
10844 { 0, CODE_FOR_spe_evsubfumiaaw, "__builtin_spe_evsubfumiaaw", SPE_BUILTIN_EVSUBFUMIAAW },
10846 /* Place-holder. Leave as last unary SPE builtin. */
10847 { 0, CODE_FOR_spe_evsubfusiaaw, "__builtin_spe_evsubfusiaaw", SPE_BUILTIN_EVSUBFUSIAAW },
10849 { 0, CODE_FOR_paired_absv2sf2, "__builtin_paired_absv2sf2", PAIRED_BUILTIN_ABSV2SF2 },
10850 { 0, CODE_FOR_nabsv2sf2, "__builtin_paired_nabsv2sf2", PAIRED_BUILTIN_NABSV2SF2 },
10851 { 0, CODE_FOR_paired_negv2sf2, "__builtin_paired_negv2sf2", PAIRED_BUILTIN_NEGV2SF2 },
10852 { 0, CODE_FOR_sqrtv2sf2, "__builtin_paired_sqrtv2sf2", PAIRED_BUILTIN_SQRTV2SF2 },
10853 { 0, CODE_FOR_resv2sf2, "__builtin_paired_resv2sf2", PAIRED_BUILTIN_RESV2SF2 }
10856 static rtx
10857 rs6000_expand_unop_builtin (enum insn_code icode, tree exp, rtx target)
10859 rtx pat;
10860 tree arg0 = CALL_EXPR_ARG (exp, 0);
10861 rtx op0 = expand_normal (arg0);
10862 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10863 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10865 if (icode == CODE_FOR_nothing)
10866 /* Builtin not supported on this processor. */
10867 return 0;
10869 /* If we got invalid arguments bail out before generating bad rtl. */
10870 if (arg0 == error_mark_node)
10871 return const0_rtx;
10873 if (icode == CODE_FOR_altivec_vspltisb
10874 || icode == CODE_FOR_altivec_vspltish
10875 || icode == CODE_FOR_altivec_vspltisw
10876 || icode == CODE_FOR_spe_evsplatfi
10877 || icode == CODE_FOR_spe_evsplati)
10879 /* Only allow 5-bit *signed* literals. */
10880 if (GET_CODE (op0) != CONST_INT
10881 || INTVAL (op0) > 15
10882 || INTVAL (op0) < -16)
10884 error ("argument 1 must be a 5-bit signed literal");
10885 return const0_rtx;
10889 if (target == 0
10890 || GET_MODE (target) != tmode
10891 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10892 target = gen_reg_rtx (tmode);
10894 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10895 op0 = copy_to_mode_reg (mode0, op0);
10897 pat = GEN_FCN (icode) (target, op0);
10898 if (! pat)
10899 return 0;
10900 emit_insn (pat);
10902 return target;
10905 static rtx
10906 altivec_expand_abs_builtin (enum insn_code icode, tree exp, rtx target)
10908 rtx pat, scratch1, scratch2;
10909 tree arg0 = CALL_EXPR_ARG (exp, 0);
10910 rtx op0 = expand_normal (arg0);
10911 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10912 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10914 /* If we have invalid arguments, bail out before generating bad rtl. */
10915 if (arg0 == error_mark_node)
10916 return const0_rtx;
10918 if (target == 0
10919 || GET_MODE (target) != tmode
10920 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10921 target = gen_reg_rtx (tmode);
10923 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10924 op0 = copy_to_mode_reg (mode0, op0);
10926 scratch1 = gen_reg_rtx (mode0);
10927 scratch2 = gen_reg_rtx (mode0);
10929 pat = GEN_FCN (icode) (target, op0, scratch1, scratch2);
10930 if (! pat)
10931 return 0;
10932 emit_insn (pat);
10934 return target;
10937 static rtx
10938 rs6000_expand_binop_builtin (enum insn_code icode, tree exp, rtx target)
10940 rtx pat;
10941 tree arg0 = CALL_EXPR_ARG (exp, 0);
10942 tree arg1 = CALL_EXPR_ARG (exp, 1);
10943 rtx op0 = expand_normal (arg0);
10944 rtx op1 = expand_normal (arg1);
10945 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10946 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10947 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
10949 if (icode == CODE_FOR_nothing)
10950 /* Builtin not supported on this processor. */
10951 return 0;
10953 /* If we got invalid arguments bail out before generating bad rtl. */
10954 if (arg0 == error_mark_node || arg1 == error_mark_node)
10955 return const0_rtx;
10957 if (icode == CODE_FOR_altivec_vcfux
10958 || icode == CODE_FOR_altivec_vcfsx
10959 || icode == CODE_FOR_altivec_vctsxs
10960 || icode == CODE_FOR_altivec_vctuxs
10961 || icode == CODE_FOR_altivec_vspltb
10962 || icode == CODE_FOR_altivec_vsplth
10963 || icode == CODE_FOR_altivec_vspltw
10964 || icode == CODE_FOR_spe_evaddiw
10965 || icode == CODE_FOR_spe_evldd
10966 || icode == CODE_FOR_spe_evldh
10967 || icode == CODE_FOR_spe_evldw
10968 || icode == CODE_FOR_spe_evlhhesplat
10969 || icode == CODE_FOR_spe_evlhhossplat
10970 || icode == CODE_FOR_spe_evlhhousplat
10971 || icode == CODE_FOR_spe_evlwhe
10972 || icode == CODE_FOR_spe_evlwhos
10973 || icode == CODE_FOR_spe_evlwhou
10974 || icode == CODE_FOR_spe_evlwhsplat
10975 || icode == CODE_FOR_spe_evlwwsplat
10976 || icode == CODE_FOR_spe_evrlwi
10977 || icode == CODE_FOR_spe_evslwi
10978 || icode == CODE_FOR_spe_evsrwis
10979 || icode == CODE_FOR_spe_evsubifw
10980 || icode == CODE_FOR_spe_evsrwiu)
10982 /* Only allow 5-bit unsigned literals. */
10983 STRIP_NOPS (arg1);
10984 if (TREE_CODE (arg1) != INTEGER_CST
10985 || TREE_INT_CST_LOW (arg1) & ~0x1f)
10987 error ("argument 2 must be a 5-bit unsigned literal");
10988 return const0_rtx;
10992 if (target == 0
10993 || GET_MODE (target) != tmode
10994 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10995 target = gen_reg_rtx (tmode);
10997 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10998 op0 = copy_to_mode_reg (mode0, op0);
10999 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
11000 op1 = copy_to_mode_reg (mode1, op1);
11002 pat = GEN_FCN (icode) (target, op0, op1);
11003 if (! pat)
11004 return 0;
11005 emit_insn (pat);
11007 return target;
11010 static rtx
11011 altivec_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
11013 rtx pat, scratch;
11014 tree cr6_form = CALL_EXPR_ARG (exp, 0);
11015 tree arg0 = CALL_EXPR_ARG (exp, 1);
11016 tree arg1 = CALL_EXPR_ARG (exp, 2);
11017 rtx op0 = expand_normal (arg0);
11018 rtx op1 = expand_normal (arg1);
11019 enum machine_mode tmode = SImode;
11020 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
11021 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
11022 int cr6_form_int;
11024 if (TREE_CODE (cr6_form) != INTEGER_CST)
11026 error ("argument 1 of __builtin_altivec_predicate must be a constant");
11027 return const0_rtx;
11029 else
11030 cr6_form_int = TREE_INT_CST_LOW (cr6_form);
11032 gcc_assert (mode0 == mode1);
11034 /* If we have invalid arguments, bail out before generating bad rtl. */
11035 if (arg0 == error_mark_node || arg1 == error_mark_node)
11036 return const0_rtx;
11038 if (target == 0
11039 || GET_MODE (target) != tmode
11040 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11041 target = gen_reg_rtx (tmode);
11043 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
11044 op0 = copy_to_mode_reg (mode0, op0);
11045 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
11046 op1 = copy_to_mode_reg (mode1, op1);
11048 scratch = gen_reg_rtx (mode0);
11050 pat = GEN_FCN (icode) (scratch, op0, op1);
11051 if (! pat)
11052 return 0;
11053 emit_insn (pat);
11055 /* The vec_any* and vec_all* predicates use the same opcodes for two
11056 different operations, but the bits in CR6 will be different
11057 depending on what information we want. So we have to play tricks
11058 with CR6 to get the right bits out.
11060 If you think this is disgusting, look at the specs for the
11061 AltiVec predicates. */
11063 switch (cr6_form_int)
11065 case 0:
11066 emit_insn (gen_cr6_test_for_zero (target));
11067 break;
11068 case 1:
11069 emit_insn (gen_cr6_test_for_zero_reverse (target));
11070 break;
11071 case 2:
11072 emit_insn (gen_cr6_test_for_lt (target));
11073 break;
11074 case 3:
11075 emit_insn (gen_cr6_test_for_lt_reverse (target));
11076 break;
11077 default:
11078 error ("argument 1 of __builtin_altivec_predicate is out of range");
11079 break;
11082 return target;
11085 static rtx
11086 paired_expand_lv_builtin (enum insn_code icode, tree exp, rtx target)
11088 rtx pat, addr;
11089 tree arg0 = CALL_EXPR_ARG (exp, 0);
11090 tree arg1 = CALL_EXPR_ARG (exp, 1);
11091 enum machine_mode tmode = insn_data[icode].operand[0].mode;
11092 enum machine_mode mode0 = Pmode;
11093 enum machine_mode mode1 = Pmode;
11094 rtx op0 = expand_normal (arg0);
11095 rtx op1 = expand_normal (arg1);
11097 if (icode == CODE_FOR_nothing)
11098 /* Builtin not supported on this processor. */
11099 return 0;
11101 /* If we got invalid arguments bail out before generating bad rtl. */
11102 if (arg0 == error_mark_node || arg1 == error_mark_node)
11103 return const0_rtx;
11105 if (target == 0
11106 || GET_MODE (target) != tmode
11107 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11108 target = gen_reg_rtx (tmode);
11110 op1 = copy_to_mode_reg (mode1, op1);
11112 if (op0 == const0_rtx)
11114 addr = gen_rtx_MEM (tmode, op1);
11116 else
11118 op0 = copy_to_mode_reg (mode0, op0);
11119 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op0, op1));
11122 pat = GEN_FCN (icode) (target, addr);
11124 if (! pat)
11125 return 0;
11126 emit_insn (pat);
11128 return target;
11131 static rtx
11132 altivec_expand_lv_builtin (enum insn_code icode, tree exp, rtx target, bool blk)
11134 rtx pat, addr;
11135 tree arg0 = CALL_EXPR_ARG (exp, 0);
11136 tree arg1 = CALL_EXPR_ARG (exp, 1);
11137 enum machine_mode tmode = insn_data[icode].operand[0].mode;
11138 enum machine_mode mode0 = Pmode;
11139 enum machine_mode mode1 = Pmode;
11140 rtx op0 = expand_normal (arg0);
11141 rtx op1 = expand_normal (arg1);
11143 if (icode == CODE_FOR_nothing)
11144 /* Builtin not supported on this processor. */
11145 return 0;
11147 /* If we got invalid arguments bail out before generating bad rtl. */
11148 if (arg0 == error_mark_node || arg1 == error_mark_node)
11149 return const0_rtx;
11151 if (target == 0
11152 || GET_MODE (target) != tmode
11153 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11154 target = gen_reg_rtx (tmode);
11156 op1 = copy_to_mode_reg (mode1, op1);
11158 if (op0 == const0_rtx)
11160 addr = gen_rtx_MEM (blk ? BLKmode : tmode, op1);
11162 else
11164 op0 = copy_to_mode_reg (mode0, op0);
11165 addr = gen_rtx_MEM (blk ? BLKmode : tmode, gen_rtx_PLUS (Pmode, op0, op1));
11168 pat = GEN_FCN (icode) (target, addr);
11170 if (! pat)
11171 return 0;
11172 emit_insn (pat);
11174 return target;
11177 static rtx
11178 spe_expand_stv_builtin (enum insn_code icode, tree exp)
11180 tree arg0 = CALL_EXPR_ARG (exp, 0);
11181 tree arg1 = CALL_EXPR_ARG (exp, 1);
11182 tree arg2 = CALL_EXPR_ARG (exp, 2);
11183 rtx op0 = expand_normal (arg0);
11184 rtx op1 = expand_normal (arg1);
11185 rtx op2 = expand_normal (arg2);
11186 rtx pat;
11187 enum machine_mode mode0 = insn_data[icode].operand[0].mode;
11188 enum machine_mode mode1 = insn_data[icode].operand[1].mode;
11189 enum machine_mode mode2 = insn_data[icode].operand[2].mode;
11191 /* Invalid arguments. Bail before doing anything stoopid! */
11192 if (arg0 == error_mark_node
11193 || arg1 == error_mark_node
11194 || arg2 == error_mark_node)
11195 return const0_rtx;
11197 if (! (*insn_data[icode].operand[2].predicate) (op0, mode2))
11198 op0 = copy_to_mode_reg (mode2, op0);
11199 if (! (*insn_data[icode].operand[0].predicate) (op1, mode0))
11200 op1 = copy_to_mode_reg (mode0, op1);
11201 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
11202 op2 = copy_to_mode_reg (mode1, op2);
11204 pat = GEN_FCN (icode) (op1, op2, op0);
11205 if (pat)
11206 emit_insn (pat);
11207 return NULL_RTX;
11210 static rtx
11211 paired_expand_stv_builtin (enum insn_code icode, tree exp)
11213 tree arg0 = CALL_EXPR_ARG (exp, 0);
11214 tree arg1 = CALL_EXPR_ARG (exp, 1);
11215 tree arg2 = CALL_EXPR_ARG (exp, 2);
11216 rtx op0 = expand_normal (arg0);
11217 rtx op1 = expand_normal (arg1);
11218 rtx op2 = expand_normal (arg2);
11219 rtx pat, addr;
11220 enum machine_mode tmode = insn_data[icode].operand[0].mode;
11221 enum machine_mode mode1 = Pmode;
11222 enum machine_mode mode2 = Pmode;
11224 /* Invalid arguments. Bail before doing anything stoopid! */
11225 if (arg0 == error_mark_node
11226 || arg1 == error_mark_node
11227 || arg2 == error_mark_node)
11228 return const0_rtx;
11230 if (! (*insn_data[icode].operand[1].predicate) (op0, tmode))
11231 op0 = copy_to_mode_reg (tmode, op0);
11233 op2 = copy_to_mode_reg (mode2, op2);
11235 if (op1 == const0_rtx)
11237 addr = gen_rtx_MEM (tmode, op2);
11239 else
11241 op1 = copy_to_mode_reg (mode1, op1);
11242 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op1, op2));
11245 pat = GEN_FCN (icode) (addr, op0);
11246 if (pat)
11247 emit_insn (pat);
11248 return NULL_RTX;
11251 static rtx
11252 altivec_expand_stv_builtin (enum insn_code icode, tree exp)
11254 tree arg0 = CALL_EXPR_ARG (exp, 0);
11255 tree arg1 = CALL_EXPR_ARG (exp, 1);
11256 tree arg2 = CALL_EXPR_ARG (exp, 2);
11257 rtx op0 = expand_normal (arg0);
11258 rtx op1 = expand_normal (arg1);
11259 rtx op2 = expand_normal (arg2);
11260 rtx pat, addr;
11261 enum machine_mode tmode = insn_data[icode].operand[0].mode;
11262 enum machine_mode smode = insn_data[icode].operand[1].mode;
11263 enum machine_mode mode1 = Pmode;
11264 enum machine_mode mode2 = Pmode;
11266 /* Invalid arguments. Bail before doing anything stoopid! */
11267 if (arg0 == error_mark_node
11268 || arg1 == error_mark_node
11269 || arg2 == error_mark_node)
11270 return const0_rtx;
11272 if (! (*insn_data[icode].operand[1].predicate) (op0, smode))
11273 op0 = copy_to_mode_reg (smode, op0);
11275 op2 = copy_to_mode_reg (mode2, op2);
11277 if (op1 == const0_rtx)
11279 addr = gen_rtx_MEM (tmode, op2);
11281 else
11283 op1 = copy_to_mode_reg (mode1, op1);
11284 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op1, op2));
11287 pat = GEN_FCN (icode) (addr, op0);
11288 if (pat)
11289 emit_insn (pat);
11290 return NULL_RTX;
11293 static rtx
11294 rs6000_expand_ternop_builtin (enum insn_code icode, tree exp, rtx target)
11296 rtx pat;
11297 tree arg0 = CALL_EXPR_ARG (exp, 0);
11298 tree arg1 = CALL_EXPR_ARG (exp, 1);
11299 tree arg2 = CALL_EXPR_ARG (exp, 2);
11300 rtx op0 = expand_normal (arg0);
11301 rtx op1 = expand_normal (arg1);
11302 rtx op2 = expand_normal (arg2);
11303 enum machine_mode tmode = insn_data[icode].operand[0].mode;
11304 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
11305 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
11306 enum machine_mode mode2 = insn_data[icode].operand[3].mode;
11308 if (icode == CODE_FOR_nothing)
11309 /* Builtin not supported on this processor. */
11310 return 0;
11312 /* If we got invalid arguments bail out before generating bad rtl. */
11313 if (arg0 == error_mark_node
11314 || arg1 == error_mark_node
11315 || arg2 == error_mark_node)
11316 return const0_rtx;
11318 /* Check and prepare argument depending on the instruction code.
11320 Note that a switch statement instead of the sequence of tests
11321 would be incorrect as many of the CODE_FOR values could be
11322 CODE_FOR_nothing and that would yield multiple alternatives
11323 with identical values. We'd never reach here at runtime in
11324 this case. */
11325 if (icode == CODE_FOR_altivec_vsldoi_v4sf
11326 || icode == CODE_FOR_altivec_vsldoi_v4si
11327 || icode == CODE_FOR_altivec_vsldoi_v8hi
11328 || icode == CODE_FOR_altivec_vsldoi_v16qi)
11330 /* Only allow 4-bit unsigned literals. */
11331 STRIP_NOPS (arg2);
11332 if (TREE_CODE (arg2) != INTEGER_CST
11333 || TREE_INT_CST_LOW (arg2) & ~0xf)
11335 error ("argument 3 must be a 4-bit unsigned literal");
11336 return const0_rtx;
11339 else if (icode == CODE_FOR_vsx_xxpermdi_v2df
11340 || icode == CODE_FOR_vsx_xxpermdi_v2di
11341 || icode == CODE_FOR_vsx_xxsldwi_v16qi
11342 || icode == CODE_FOR_vsx_xxsldwi_v8hi
11343 || icode == CODE_FOR_vsx_xxsldwi_v4si
11344 || icode == CODE_FOR_vsx_xxsldwi_v4sf
11345 || icode == CODE_FOR_vsx_xxsldwi_v2di
11346 || icode == CODE_FOR_vsx_xxsldwi_v2df)
11348 /* Only allow 2-bit unsigned literals. */
11349 STRIP_NOPS (arg2);
11350 if (TREE_CODE (arg2) != INTEGER_CST
11351 || TREE_INT_CST_LOW (arg2) & ~0x3)
11353 error ("argument 3 must be a 2-bit unsigned literal");
11354 return const0_rtx;
11357 else if (icode == CODE_FOR_vsx_set_v2df
11358 || icode == CODE_FOR_vsx_set_v2di)
11360 /* Only allow 1-bit unsigned literals. */
11361 STRIP_NOPS (arg2);
11362 if (TREE_CODE (arg2) != INTEGER_CST
11363 || TREE_INT_CST_LOW (arg2) & ~0x1)
11365 error ("argument 3 must be a 1-bit unsigned literal");
11366 return const0_rtx;
11370 if (target == 0
11371 || GET_MODE (target) != tmode
11372 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11373 target = gen_reg_rtx (tmode);
11375 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
11376 op0 = copy_to_mode_reg (mode0, op0);
11377 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
11378 op1 = copy_to_mode_reg (mode1, op1);
11379 if (! (*insn_data[icode].operand[3].predicate) (op2, mode2))
11380 op2 = copy_to_mode_reg (mode2, op2);
11382 if (TARGET_PAIRED_FLOAT && icode == CODE_FOR_selv2sf4)
11383 pat = GEN_FCN (icode) (target, op0, op1, op2, CONST0_RTX (SFmode));
11384 else
11385 pat = GEN_FCN (icode) (target, op0, op1, op2);
11386 if (! pat)
11387 return 0;
11388 emit_insn (pat);
11390 return target;
11393 /* Expand the lvx builtins. */
11394 static rtx
11395 altivec_expand_ld_builtin (tree exp, rtx target, bool *expandedp)
11397 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11398 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11399 tree arg0;
11400 enum machine_mode tmode, mode0;
11401 rtx pat, op0;
11402 enum insn_code icode;
11404 switch (fcode)
11406 case ALTIVEC_BUILTIN_LD_INTERNAL_16qi:
11407 icode = CODE_FOR_vector_altivec_load_v16qi;
11408 break;
11409 case ALTIVEC_BUILTIN_LD_INTERNAL_8hi:
11410 icode = CODE_FOR_vector_altivec_load_v8hi;
11411 break;
11412 case ALTIVEC_BUILTIN_LD_INTERNAL_4si:
11413 icode = CODE_FOR_vector_altivec_load_v4si;
11414 break;
11415 case ALTIVEC_BUILTIN_LD_INTERNAL_4sf:
11416 icode = CODE_FOR_vector_altivec_load_v4sf;
11417 break;
11418 case ALTIVEC_BUILTIN_LD_INTERNAL_2df:
11419 icode = CODE_FOR_vector_altivec_load_v2df;
11420 break;
11421 case ALTIVEC_BUILTIN_LD_INTERNAL_2di:
11422 icode = CODE_FOR_vector_altivec_load_v2di;
11423 break;
11424 default:
11425 *expandedp = false;
11426 return NULL_RTX;
11429 *expandedp = true;
11431 arg0 = CALL_EXPR_ARG (exp, 0);
11432 op0 = expand_normal (arg0);
11433 tmode = insn_data[icode].operand[0].mode;
11434 mode0 = insn_data[icode].operand[1].mode;
11436 if (target == 0
11437 || GET_MODE (target) != tmode
11438 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11439 target = gen_reg_rtx (tmode);
11441 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
11442 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
11444 pat = GEN_FCN (icode) (target, op0);
11445 if (! pat)
11446 return 0;
11447 emit_insn (pat);
11448 return target;
11451 /* Expand the stvx builtins. */
11452 static rtx
11453 altivec_expand_st_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
11454 bool *expandedp)
11456 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11457 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11458 tree arg0, arg1;
11459 enum machine_mode mode0, mode1;
11460 rtx pat, op0, op1;
11461 enum insn_code icode;
11463 switch (fcode)
11465 case ALTIVEC_BUILTIN_ST_INTERNAL_16qi:
11466 icode = CODE_FOR_vector_altivec_store_v16qi;
11467 break;
11468 case ALTIVEC_BUILTIN_ST_INTERNAL_8hi:
11469 icode = CODE_FOR_vector_altivec_store_v8hi;
11470 break;
11471 case ALTIVEC_BUILTIN_ST_INTERNAL_4si:
11472 icode = CODE_FOR_vector_altivec_store_v4si;
11473 break;
11474 case ALTIVEC_BUILTIN_ST_INTERNAL_4sf:
11475 icode = CODE_FOR_vector_altivec_store_v4sf;
11476 break;
11477 case ALTIVEC_BUILTIN_ST_INTERNAL_2df:
11478 icode = CODE_FOR_vector_altivec_store_v2df;
11479 break;
11480 case ALTIVEC_BUILTIN_ST_INTERNAL_2di:
11481 icode = CODE_FOR_vector_altivec_store_v2di;
11482 break;
11483 default:
11484 *expandedp = false;
11485 return NULL_RTX;
11488 arg0 = CALL_EXPR_ARG (exp, 0);
11489 arg1 = CALL_EXPR_ARG (exp, 1);
11490 op0 = expand_normal (arg0);
11491 op1 = expand_normal (arg1);
11492 mode0 = insn_data[icode].operand[0].mode;
11493 mode1 = insn_data[icode].operand[1].mode;
11495 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
11496 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
11497 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
11498 op1 = copy_to_mode_reg (mode1, op1);
11500 pat = GEN_FCN (icode) (op0, op1);
11501 if (pat)
11502 emit_insn (pat);
11504 *expandedp = true;
11505 return NULL_RTX;
11508 /* Expand the dst builtins. */
11509 static rtx
11510 altivec_expand_dst_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
11511 bool *expandedp)
11513 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11514 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11515 tree arg0, arg1, arg2;
11516 enum machine_mode mode0, mode1;
11517 rtx pat, op0, op1, op2;
11518 const struct builtin_description *d;
11519 size_t i;
11521 *expandedp = false;
11523 /* Handle DST variants. */
11524 d = bdesc_dst;
11525 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
11526 if (d->code == fcode)
11528 arg0 = CALL_EXPR_ARG (exp, 0);
11529 arg1 = CALL_EXPR_ARG (exp, 1);
11530 arg2 = CALL_EXPR_ARG (exp, 2);
11531 op0 = expand_normal (arg0);
11532 op1 = expand_normal (arg1);
11533 op2 = expand_normal (arg2);
11534 mode0 = insn_data[d->icode].operand[0].mode;
11535 mode1 = insn_data[d->icode].operand[1].mode;
11537 /* Invalid arguments, bail out before generating bad rtl. */
11538 if (arg0 == error_mark_node
11539 || arg1 == error_mark_node
11540 || arg2 == error_mark_node)
11541 return const0_rtx;
11543 *expandedp = true;
11544 STRIP_NOPS (arg2);
11545 if (TREE_CODE (arg2) != INTEGER_CST
11546 || TREE_INT_CST_LOW (arg2) & ~0x3)
11548 error ("argument to %qs must be a 2-bit unsigned literal", d->name);
11549 return const0_rtx;
11552 if (! (*insn_data[d->icode].operand[0].predicate) (op0, mode0))
11553 op0 = copy_to_mode_reg (Pmode, op0);
11554 if (! (*insn_data[d->icode].operand[1].predicate) (op1, mode1))
11555 op1 = copy_to_mode_reg (mode1, op1);
11557 pat = GEN_FCN (d->icode) (op0, op1, op2);
11558 if (pat != 0)
11559 emit_insn (pat);
11561 return NULL_RTX;
11564 return NULL_RTX;
11567 /* Expand vec_init builtin. */
11568 static rtx
11569 altivec_expand_vec_init_builtin (tree type, tree exp, rtx target)
11571 enum machine_mode tmode = TYPE_MODE (type);
11572 enum machine_mode inner_mode = GET_MODE_INNER (tmode);
11573 int i, n_elt = GET_MODE_NUNITS (tmode);
11574 rtvec v = rtvec_alloc (n_elt);
11576 gcc_assert (VECTOR_MODE_P (tmode));
11577 gcc_assert (n_elt == call_expr_nargs (exp));
11579 for (i = 0; i < n_elt; ++i)
11581 rtx x = expand_normal (CALL_EXPR_ARG (exp, i));
11582 RTVEC_ELT (v, i) = gen_lowpart (inner_mode, x);
11585 if (!target || !register_operand (target, tmode))
11586 target = gen_reg_rtx (tmode);
11588 rs6000_expand_vector_init (target, gen_rtx_PARALLEL (tmode, v));
11589 return target;
11592 /* Return the integer constant in ARG. Constrain it to be in the range
11593 of the subparts of VEC_TYPE; issue an error if not. */
11595 static int
11596 get_element_number (tree vec_type, tree arg)
11598 unsigned HOST_WIDE_INT elt, max = TYPE_VECTOR_SUBPARTS (vec_type) - 1;
11600 if (!host_integerp (arg, 1)
11601 || (elt = tree_low_cst (arg, 1), elt > max))
11603 error ("selector must be an integer constant in the range 0..%wi", max);
11604 return 0;
11607 return elt;
11610 /* Expand vec_set builtin. */
11611 static rtx
11612 altivec_expand_vec_set_builtin (tree exp)
11614 enum machine_mode tmode, mode1;
11615 tree arg0, arg1, arg2;
11616 int elt;
11617 rtx op0, op1;
11619 arg0 = CALL_EXPR_ARG (exp, 0);
11620 arg1 = CALL_EXPR_ARG (exp, 1);
11621 arg2 = CALL_EXPR_ARG (exp, 2);
11623 tmode = TYPE_MODE (TREE_TYPE (arg0));
11624 mode1 = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
11625 gcc_assert (VECTOR_MODE_P (tmode));
11627 op0 = expand_expr (arg0, NULL_RTX, tmode, EXPAND_NORMAL);
11628 op1 = expand_expr (arg1, NULL_RTX, mode1, EXPAND_NORMAL);
11629 elt = get_element_number (TREE_TYPE (arg0), arg2);
11631 if (GET_MODE (op1) != mode1 && GET_MODE (op1) != VOIDmode)
11632 op1 = convert_modes (mode1, GET_MODE (op1), op1, true);
11634 op0 = force_reg (tmode, op0);
11635 op1 = force_reg (mode1, op1);
11637 rs6000_expand_vector_set (op0, op1, elt);
11639 return op0;
11642 /* Expand vec_ext builtin. */
11643 static rtx
11644 altivec_expand_vec_ext_builtin (tree exp, rtx target)
11646 enum machine_mode tmode, mode0;
11647 tree arg0, arg1;
11648 int elt;
11649 rtx op0;
11651 arg0 = CALL_EXPR_ARG (exp, 0);
11652 arg1 = CALL_EXPR_ARG (exp, 1);
11654 op0 = expand_normal (arg0);
11655 elt = get_element_number (TREE_TYPE (arg0), arg1);
11657 tmode = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
11658 mode0 = TYPE_MODE (TREE_TYPE (arg0));
11659 gcc_assert (VECTOR_MODE_P (mode0));
11661 op0 = force_reg (mode0, op0);
11663 if (optimize || !target || !register_operand (target, tmode))
11664 target = gen_reg_rtx (tmode);
11666 rs6000_expand_vector_extract (target, op0, elt);
11668 return target;
11671 /* Expand the builtin in EXP and store the result in TARGET. Store
11672 true in *EXPANDEDP if we found a builtin to expand. */
11673 static rtx
11674 altivec_expand_builtin (tree exp, rtx target, bool *expandedp)
11676 const struct builtin_description *d;
11677 const struct builtin_description_predicates *dp;
11678 size_t i;
11679 enum insn_code icode;
11680 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11681 tree arg0;
11682 rtx op0, pat;
11683 enum machine_mode tmode, mode0;
11684 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11686 if ((fcode >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
11687 && fcode <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
11688 || (fcode >= VSX_BUILTIN_OVERLOADED_FIRST
11689 && fcode <= VSX_BUILTIN_OVERLOADED_LAST))
11691 *expandedp = true;
11692 error ("unresolved overload for Altivec builtin %qF", fndecl);
11693 return const0_rtx;
11696 target = altivec_expand_ld_builtin (exp, target, expandedp);
11697 if (*expandedp)
11698 return target;
11700 target = altivec_expand_st_builtin (exp, target, expandedp);
11701 if (*expandedp)
11702 return target;
11704 target = altivec_expand_dst_builtin (exp, target, expandedp);
11705 if (*expandedp)
11706 return target;
11708 *expandedp = true;
11710 switch (fcode)
11712 case ALTIVEC_BUILTIN_STVX:
11713 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx_v4si, exp);
11714 case ALTIVEC_BUILTIN_STVEBX:
11715 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvebx, exp);
11716 case ALTIVEC_BUILTIN_STVEHX:
11717 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvehx, exp);
11718 case ALTIVEC_BUILTIN_STVEWX:
11719 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvewx, exp);
11720 case ALTIVEC_BUILTIN_STVXL:
11721 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvxl, exp);
11723 case ALTIVEC_BUILTIN_STVLX:
11724 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlx, exp);
11725 case ALTIVEC_BUILTIN_STVLXL:
11726 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlxl, exp);
11727 case ALTIVEC_BUILTIN_STVRX:
11728 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrx, exp);
11729 case ALTIVEC_BUILTIN_STVRXL:
11730 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrxl, exp);
11732 case VSX_BUILTIN_STXVD2X_V2DF:
11733 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v2df, exp);
11734 case VSX_BUILTIN_STXVD2X_V2DI:
11735 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v2di, exp);
11736 case VSX_BUILTIN_STXVW4X_V4SF:
11737 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v4sf, exp);
11738 case VSX_BUILTIN_STXVW4X_V4SI:
11739 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v4si, exp);
11740 case VSX_BUILTIN_STXVW4X_V8HI:
11741 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v8hi, exp);
11742 case VSX_BUILTIN_STXVW4X_V16QI:
11743 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v16qi, exp);
11745 case ALTIVEC_BUILTIN_MFVSCR:
11746 icode = CODE_FOR_altivec_mfvscr;
11747 tmode = insn_data[icode].operand[0].mode;
11749 if (target == 0
11750 || GET_MODE (target) != tmode
11751 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11752 target = gen_reg_rtx (tmode);
11754 pat = GEN_FCN (icode) (target);
11755 if (! pat)
11756 return 0;
11757 emit_insn (pat);
11758 return target;
11760 case ALTIVEC_BUILTIN_MTVSCR:
11761 icode = CODE_FOR_altivec_mtvscr;
11762 arg0 = CALL_EXPR_ARG (exp, 0);
11763 op0 = expand_normal (arg0);
11764 mode0 = insn_data[icode].operand[0].mode;
11766 /* If we got invalid arguments bail out before generating bad rtl. */
11767 if (arg0 == error_mark_node)
11768 return const0_rtx;
11770 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
11771 op0 = copy_to_mode_reg (mode0, op0);
11773 pat = GEN_FCN (icode) (op0);
11774 if (pat)
11775 emit_insn (pat);
11776 return NULL_RTX;
11778 case ALTIVEC_BUILTIN_DSSALL:
11779 emit_insn (gen_altivec_dssall ());
11780 return NULL_RTX;
11782 case ALTIVEC_BUILTIN_DSS:
11783 icode = CODE_FOR_altivec_dss;
11784 arg0 = CALL_EXPR_ARG (exp, 0);
11785 STRIP_NOPS (arg0);
11786 op0 = expand_normal (arg0);
11787 mode0 = insn_data[icode].operand[0].mode;
11789 /* If we got invalid arguments bail out before generating bad rtl. */
11790 if (arg0 == error_mark_node)
11791 return const0_rtx;
11793 if (TREE_CODE (arg0) != INTEGER_CST
11794 || TREE_INT_CST_LOW (arg0) & ~0x3)
11796 error ("argument to dss must be a 2-bit unsigned literal");
11797 return const0_rtx;
11800 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
11801 op0 = copy_to_mode_reg (mode0, op0);
11803 emit_insn (gen_altivec_dss (op0));
11804 return NULL_RTX;
11806 case ALTIVEC_BUILTIN_VEC_INIT_V4SI:
11807 case ALTIVEC_BUILTIN_VEC_INIT_V8HI:
11808 case ALTIVEC_BUILTIN_VEC_INIT_V16QI:
11809 case ALTIVEC_BUILTIN_VEC_INIT_V4SF:
11810 case VSX_BUILTIN_VEC_INIT_V2DF:
11811 case VSX_BUILTIN_VEC_INIT_V2DI:
11812 return altivec_expand_vec_init_builtin (TREE_TYPE (exp), exp, target);
11814 case ALTIVEC_BUILTIN_VEC_SET_V4SI:
11815 case ALTIVEC_BUILTIN_VEC_SET_V8HI:
11816 case ALTIVEC_BUILTIN_VEC_SET_V16QI:
11817 case ALTIVEC_BUILTIN_VEC_SET_V4SF:
11818 case VSX_BUILTIN_VEC_SET_V2DF:
11819 case VSX_BUILTIN_VEC_SET_V2DI:
11820 return altivec_expand_vec_set_builtin (exp);
11822 case ALTIVEC_BUILTIN_VEC_EXT_V4SI:
11823 case ALTIVEC_BUILTIN_VEC_EXT_V8HI:
11824 case ALTIVEC_BUILTIN_VEC_EXT_V16QI:
11825 case ALTIVEC_BUILTIN_VEC_EXT_V4SF:
11826 case VSX_BUILTIN_VEC_EXT_V2DF:
11827 case VSX_BUILTIN_VEC_EXT_V2DI:
11828 return altivec_expand_vec_ext_builtin (exp, target);
11830 default:
11831 break;
11832 /* Fall through. */
11835 /* Expand abs* operations. */
11836 d = bdesc_abs;
11837 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
11838 if (d->code == fcode)
11839 return altivec_expand_abs_builtin (d->icode, exp, target);
11841 /* Expand the AltiVec predicates. */
11842 dp = bdesc_altivec_preds;
11843 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
11844 if (dp->code == fcode)
11845 return altivec_expand_predicate_builtin (dp->icode, exp, target);
11847 /* LV* are funky. We initialized them differently. */
11848 switch (fcode)
11850 case ALTIVEC_BUILTIN_LVSL:
11851 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsl,
11852 exp, target, false);
11853 case ALTIVEC_BUILTIN_LVSR:
11854 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsr,
11855 exp, target, false);
11856 case ALTIVEC_BUILTIN_LVEBX:
11857 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvebx,
11858 exp, target, false);
11859 case ALTIVEC_BUILTIN_LVEHX:
11860 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvehx,
11861 exp, target, false);
11862 case ALTIVEC_BUILTIN_LVEWX:
11863 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvewx,
11864 exp, target, false);
11865 case ALTIVEC_BUILTIN_LVXL:
11866 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvxl,
11867 exp, target, false);
11868 case ALTIVEC_BUILTIN_LVX:
11869 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx_v4si,
11870 exp, target, false);
11871 case ALTIVEC_BUILTIN_LVLX:
11872 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlx,
11873 exp, target, true);
11874 case ALTIVEC_BUILTIN_LVLXL:
11875 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlxl,
11876 exp, target, true);
11877 case ALTIVEC_BUILTIN_LVRX:
11878 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrx,
11879 exp, target, true);
11880 case ALTIVEC_BUILTIN_LVRXL:
11881 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrxl,
11882 exp, target, true);
11883 case VSX_BUILTIN_LXVD2X_V2DF:
11884 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v2df,
11885 exp, target, false);
11886 case VSX_BUILTIN_LXVD2X_V2DI:
11887 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v2di,
11888 exp, target, false);
11889 case VSX_BUILTIN_LXVW4X_V4SF:
11890 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v4sf,
11891 exp, target, false);
11892 case VSX_BUILTIN_LXVW4X_V4SI:
11893 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v4si,
11894 exp, target, false);
11895 case VSX_BUILTIN_LXVW4X_V8HI:
11896 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v8hi,
11897 exp, target, false);
11898 case VSX_BUILTIN_LXVW4X_V16QI:
11899 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v16qi,
11900 exp, target, false);
11901 break;
11902 default:
11903 break;
11904 /* Fall through. */
11907 *expandedp = false;
11908 return NULL_RTX;
11911 /* Expand the builtin in EXP and store the result in TARGET. Store
11912 true in *EXPANDEDP if we found a builtin to expand. */
11913 static rtx
11914 paired_expand_builtin (tree exp, rtx target, bool * expandedp)
11916 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11917 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11918 const struct builtin_description *d;
11919 size_t i;
11921 *expandedp = true;
11923 switch (fcode)
11925 case PAIRED_BUILTIN_STX:
11926 return paired_expand_stv_builtin (CODE_FOR_paired_stx, exp);
11927 case PAIRED_BUILTIN_LX:
11928 return paired_expand_lv_builtin (CODE_FOR_paired_lx, exp, target);
11929 default:
11930 break;
11931 /* Fall through. */
11934 /* Expand the paired predicates. */
11935 d = bdesc_paired_preds;
11936 for (i = 0; i < ARRAY_SIZE (bdesc_paired_preds); i++, d++)
11937 if (d->code == fcode)
11938 return paired_expand_predicate_builtin (d->icode, exp, target);
11940 *expandedp = false;
11941 return NULL_RTX;
11944 /* Binops that need to be initialized manually, but can be expanded
11945 automagically by rs6000_expand_binop_builtin. */
11946 static struct builtin_description bdesc_2arg_spe[] =
11948 { 0, CODE_FOR_spe_evlddx, "__builtin_spe_evlddx", SPE_BUILTIN_EVLDDX },
11949 { 0, CODE_FOR_spe_evldwx, "__builtin_spe_evldwx", SPE_BUILTIN_EVLDWX },
11950 { 0, CODE_FOR_spe_evldhx, "__builtin_spe_evldhx", SPE_BUILTIN_EVLDHX },
11951 { 0, CODE_FOR_spe_evlwhex, "__builtin_spe_evlwhex", SPE_BUILTIN_EVLWHEX },
11952 { 0, CODE_FOR_spe_evlwhoux, "__builtin_spe_evlwhoux", SPE_BUILTIN_EVLWHOUX },
11953 { 0, CODE_FOR_spe_evlwhosx, "__builtin_spe_evlwhosx", SPE_BUILTIN_EVLWHOSX },
11954 { 0, CODE_FOR_spe_evlwwsplatx, "__builtin_spe_evlwwsplatx", SPE_BUILTIN_EVLWWSPLATX },
11955 { 0, CODE_FOR_spe_evlwhsplatx, "__builtin_spe_evlwhsplatx", SPE_BUILTIN_EVLWHSPLATX },
11956 { 0, CODE_FOR_spe_evlhhesplatx, "__builtin_spe_evlhhesplatx", SPE_BUILTIN_EVLHHESPLATX },
11957 { 0, CODE_FOR_spe_evlhhousplatx, "__builtin_spe_evlhhousplatx", SPE_BUILTIN_EVLHHOUSPLATX },
11958 { 0, CODE_FOR_spe_evlhhossplatx, "__builtin_spe_evlhhossplatx", SPE_BUILTIN_EVLHHOSSPLATX },
11959 { 0, CODE_FOR_spe_evldd, "__builtin_spe_evldd", SPE_BUILTIN_EVLDD },
11960 { 0, CODE_FOR_spe_evldw, "__builtin_spe_evldw", SPE_BUILTIN_EVLDW },
11961 { 0, CODE_FOR_spe_evldh, "__builtin_spe_evldh", SPE_BUILTIN_EVLDH },
11962 { 0, CODE_FOR_spe_evlwhe, "__builtin_spe_evlwhe", SPE_BUILTIN_EVLWHE },
11963 { 0, CODE_FOR_spe_evlwhou, "__builtin_spe_evlwhou", SPE_BUILTIN_EVLWHOU },
11964 { 0, CODE_FOR_spe_evlwhos, "__builtin_spe_evlwhos", SPE_BUILTIN_EVLWHOS },
11965 { 0, CODE_FOR_spe_evlwwsplat, "__builtin_spe_evlwwsplat", SPE_BUILTIN_EVLWWSPLAT },
11966 { 0, CODE_FOR_spe_evlwhsplat, "__builtin_spe_evlwhsplat", SPE_BUILTIN_EVLWHSPLAT },
11967 { 0, CODE_FOR_spe_evlhhesplat, "__builtin_spe_evlhhesplat", SPE_BUILTIN_EVLHHESPLAT },
11968 { 0, CODE_FOR_spe_evlhhousplat, "__builtin_spe_evlhhousplat", SPE_BUILTIN_EVLHHOUSPLAT },
11969 { 0, CODE_FOR_spe_evlhhossplat, "__builtin_spe_evlhhossplat", SPE_BUILTIN_EVLHHOSSPLAT }
11972 /* Expand the builtin in EXP and store the result in TARGET. Store
11973 true in *EXPANDEDP if we found a builtin to expand.
11975 This expands the SPE builtins that are not simple unary and binary
11976 operations. */
11977 static rtx
11978 spe_expand_builtin (tree exp, rtx target, bool *expandedp)
11980 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11981 tree arg1, arg0;
11982 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11983 enum insn_code icode;
11984 enum machine_mode tmode, mode0;
11985 rtx pat, op0;
11986 struct builtin_description *d;
11987 size_t i;
11989 *expandedp = true;
11991 /* Syntax check for a 5-bit unsigned immediate. */
11992 switch (fcode)
11994 case SPE_BUILTIN_EVSTDD:
11995 case SPE_BUILTIN_EVSTDH:
11996 case SPE_BUILTIN_EVSTDW:
11997 case SPE_BUILTIN_EVSTWHE:
11998 case SPE_BUILTIN_EVSTWHO:
11999 case SPE_BUILTIN_EVSTWWE:
12000 case SPE_BUILTIN_EVSTWWO:
12001 arg1 = CALL_EXPR_ARG (exp, 2);
12002 if (TREE_CODE (arg1) != INTEGER_CST
12003 || TREE_INT_CST_LOW (arg1) & ~0x1f)
12005 error ("argument 2 must be a 5-bit unsigned literal");
12006 return const0_rtx;
12008 break;
12009 default:
12010 break;
12013 /* The evsplat*i instructions are not quite generic. */
12014 switch (fcode)
12016 case SPE_BUILTIN_EVSPLATFI:
12017 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplatfi,
12018 exp, target);
12019 case SPE_BUILTIN_EVSPLATI:
12020 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplati,
12021 exp, target);
12022 default:
12023 break;
12026 d = (struct builtin_description *) bdesc_2arg_spe;
12027 for (i = 0; i < ARRAY_SIZE (bdesc_2arg_spe); ++i, ++d)
12028 if (d->code == fcode)
12029 return rs6000_expand_binop_builtin (d->icode, exp, target);
12031 d = (struct builtin_description *) bdesc_spe_predicates;
12032 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, ++d)
12033 if (d->code == fcode)
12034 return spe_expand_predicate_builtin (d->icode, exp, target);
12036 d = (struct builtin_description *) bdesc_spe_evsel;
12037 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, ++d)
12038 if (d->code == fcode)
12039 return spe_expand_evsel_builtin (d->icode, exp, target);
12041 switch (fcode)
12043 case SPE_BUILTIN_EVSTDDX:
12044 return spe_expand_stv_builtin (CODE_FOR_spe_evstddx, exp);
12045 case SPE_BUILTIN_EVSTDHX:
12046 return spe_expand_stv_builtin (CODE_FOR_spe_evstdhx, exp);
12047 case SPE_BUILTIN_EVSTDWX:
12048 return spe_expand_stv_builtin (CODE_FOR_spe_evstdwx, exp);
12049 case SPE_BUILTIN_EVSTWHEX:
12050 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhex, exp);
12051 case SPE_BUILTIN_EVSTWHOX:
12052 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhox, exp);
12053 case SPE_BUILTIN_EVSTWWEX:
12054 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwex, exp);
12055 case SPE_BUILTIN_EVSTWWOX:
12056 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwox, exp);
12057 case SPE_BUILTIN_EVSTDD:
12058 return spe_expand_stv_builtin (CODE_FOR_spe_evstdd, exp);
12059 case SPE_BUILTIN_EVSTDH:
12060 return spe_expand_stv_builtin (CODE_FOR_spe_evstdh, exp);
12061 case SPE_BUILTIN_EVSTDW:
12062 return spe_expand_stv_builtin (CODE_FOR_spe_evstdw, exp);
12063 case SPE_BUILTIN_EVSTWHE:
12064 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhe, exp);
12065 case SPE_BUILTIN_EVSTWHO:
12066 return spe_expand_stv_builtin (CODE_FOR_spe_evstwho, exp);
12067 case SPE_BUILTIN_EVSTWWE:
12068 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwe, exp);
12069 case SPE_BUILTIN_EVSTWWO:
12070 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwo, exp);
12071 case SPE_BUILTIN_MFSPEFSCR:
12072 icode = CODE_FOR_spe_mfspefscr;
12073 tmode = insn_data[icode].operand[0].mode;
12075 if (target == 0
12076 || GET_MODE (target) != tmode
12077 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
12078 target = gen_reg_rtx (tmode);
12080 pat = GEN_FCN (icode) (target);
12081 if (! pat)
12082 return 0;
12083 emit_insn (pat);
12084 return target;
12085 case SPE_BUILTIN_MTSPEFSCR:
12086 icode = CODE_FOR_spe_mtspefscr;
12087 arg0 = CALL_EXPR_ARG (exp, 0);
12088 op0 = expand_normal (arg0);
12089 mode0 = insn_data[icode].operand[0].mode;
12091 if (arg0 == error_mark_node)
12092 return const0_rtx;
12094 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
12095 op0 = copy_to_mode_reg (mode0, op0);
12097 pat = GEN_FCN (icode) (op0);
12098 if (pat)
12099 emit_insn (pat);
12100 return NULL_RTX;
12101 default:
12102 break;
12105 *expandedp = false;
12106 return NULL_RTX;
12109 static rtx
12110 paired_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
12112 rtx pat, scratch, tmp;
12113 tree form = CALL_EXPR_ARG (exp, 0);
12114 tree arg0 = CALL_EXPR_ARG (exp, 1);
12115 tree arg1 = CALL_EXPR_ARG (exp, 2);
12116 rtx op0 = expand_normal (arg0);
12117 rtx op1 = expand_normal (arg1);
12118 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
12119 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
12120 int form_int;
12121 enum rtx_code code;
12123 if (TREE_CODE (form) != INTEGER_CST)
12125 error ("argument 1 of __builtin_paired_predicate must be a constant");
12126 return const0_rtx;
12128 else
12129 form_int = TREE_INT_CST_LOW (form);
12131 gcc_assert (mode0 == mode1);
12133 if (arg0 == error_mark_node || arg1 == error_mark_node)
12134 return const0_rtx;
12136 if (target == 0
12137 || GET_MODE (target) != SImode
12138 || !(*insn_data[icode].operand[0].predicate) (target, SImode))
12139 target = gen_reg_rtx (SImode);
12140 if (!(*insn_data[icode].operand[1].predicate) (op0, mode0))
12141 op0 = copy_to_mode_reg (mode0, op0);
12142 if (!(*insn_data[icode].operand[2].predicate) (op1, mode1))
12143 op1 = copy_to_mode_reg (mode1, op1);
12145 scratch = gen_reg_rtx (CCFPmode);
12147 pat = GEN_FCN (icode) (scratch, op0, op1);
12148 if (!pat)
12149 return const0_rtx;
12151 emit_insn (pat);
12153 switch (form_int)
12155 /* LT bit. */
12156 case 0:
12157 code = LT;
12158 break;
12159 /* GT bit. */
12160 case 1:
12161 code = GT;
12162 break;
12163 /* EQ bit. */
12164 case 2:
12165 code = EQ;
12166 break;
12167 /* UN bit. */
12168 case 3:
12169 emit_insn (gen_move_from_CR_ov_bit (target, scratch));
12170 return target;
12171 default:
12172 error ("argument 1 of __builtin_paired_predicate is out of range");
12173 return const0_rtx;
12176 tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx);
12177 emit_move_insn (target, tmp);
12178 return target;
12181 static rtx
12182 spe_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
12184 rtx pat, scratch, tmp;
12185 tree form = CALL_EXPR_ARG (exp, 0);
12186 tree arg0 = CALL_EXPR_ARG (exp, 1);
12187 tree arg1 = CALL_EXPR_ARG (exp, 2);
12188 rtx op0 = expand_normal (arg0);
12189 rtx op1 = expand_normal (arg1);
12190 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
12191 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
12192 int form_int;
12193 enum rtx_code code;
12195 if (TREE_CODE (form) != INTEGER_CST)
12197 error ("argument 1 of __builtin_spe_predicate must be a constant");
12198 return const0_rtx;
12200 else
12201 form_int = TREE_INT_CST_LOW (form);
12203 gcc_assert (mode0 == mode1);
12205 if (arg0 == error_mark_node || arg1 == error_mark_node)
12206 return const0_rtx;
12208 if (target == 0
12209 || GET_MODE (target) != SImode
12210 || ! (*insn_data[icode].operand[0].predicate) (target, SImode))
12211 target = gen_reg_rtx (SImode);
12213 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
12214 op0 = copy_to_mode_reg (mode0, op0);
12215 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
12216 op1 = copy_to_mode_reg (mode1, op1);
12218 scratch = gen_reg_rtx (CCmode);
12220 pat = GEN_FCN (icode) (scratch, op0, op1);
12221 if (! pat)
12222 return const0_rtx;
12223 emit_insn (pat);
12225 /* There are 4 variants for each predicate: _any_, _all_, _upper_,
12226 _lower_. We use one compare, but look in different bits of the
12227 CR for each variant.
12229 There are 2 elements in each SPE simd type (upper/lower). The CR
12230 bits are set as follows:
12232 BIT0 | BIT 1 | BIT 2 | BIT 3
12233 U | L | (U | L) | (U & L)
12235 So, for an "all" relationship, BIT 3 would be set.
12236 For an "any" relationship, BIT 2 would be set. Etc.
12238 Following traditional nomenclature, these bits map to:
12240 BIT0 | BIT 1 | BIT 2 | BIT 3
12241 LT | GT | EQ | OV
12243 Later, we will generate rtl to look in the LT/EQ/EQ/OV bits.
12246 switch (form_int)
12248 /* All variant. OV bit. */
12249 case 0:
12250 /* We need to get to the OV bit, which is the ORDERED bit. We
12251 could generate (ordered:SI (reg:CC xx) (const_int 0)), but
12252 that's ugly and will make validate_condition_mode die.
12253 So let's just use another pattern. */
12254 emit_insn (gen_move_from_CR_ov_bit (target, scratch));
12255 return target;
12256 /* Any variant. EQ bit. */
12257 case 1:
12258 code = EQ;
12259 break;
12260 /* Upper variant. LT bit. */
12261 case 2:
12262 code = LT;
12263 break;
12264 /* Lower variant. GT bit. */
12265 case 3:
12266 code = GT;
12267 break;
12268 default:
12269 error ("argument 1 of __builtin_spe_predicate is out of range");
12270 return const0_rtx;
12273 tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx);
12274 emit_move_insn (target, tmp);
12276 return target;
12279 /* The evsel builtins look like this:
12281 e = __builtin_spe_evsel_OP (a, b, c, d);
12283 and work like this:
12285 e[upper] = a[upper] *OP* b[upper] ? c[upper] : d[upper];
12286 e[lower] = a[lower] *OP* b[lower] ? c[lower] : d[lower];
12289 static rtx
12290 spe_expand_evsel_builtin (enum insn_code icode, tree exp, rtx target)
12292 rtx pat, scratch;
12293 tree arg0 = CALL_EXPR_ARG (exp, 0);
12294 tree arg1 = CALL_EXPR_ARG (exp, 1);
12295 tree arg2 = CALL_EXPR_ARG (exp, 2);
12296 tree arg3 = CALL_EXPR_ARG (exp, 3);
12297 rtx op0 = expand_normal (arg0);
12298 rtx op1 = expand_normal (arg1);
12299 rtx op2 = expand_normal (arg2);
12300 rtx op3 = expand_normal (arg3);
12301 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
12302 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
12304 gcc_assert (mode0 == mode1);
12306 if (arg0 == error_mark_node || arg1 == error_mark_node
12307 || arg2 == error_mark_node || arg3 == error_mark_node)
12308 return const0_rtx;
12310 if (target == 0
12311 || GET_MODE (target) != mode0
12312 || ! (*insn_data[icode].operand[0].predicate) (target, mode0))
12313 target = gen_reg_rtx (mode0);
12315 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
12316 op0 = copy_to_mode_reg (mode0, op0);
12317 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
12318 op1 = copy_to_mode_reg (mode0, op1);
12319 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
12320 op2 = copy_to_mode_reg (mode0, op2);
12321 if (! (*insn_data[icode].operand[1].predicate) (op3, mode1))
12322 op3 = copy_to_mode_reg (mode0, op3);
12324 /* Generate the compare. */
12325 scratch = gen_reg_rtx (CCmode);
12326 pat = GEN_FCN (icode) (scratch, op0, op1);
12327 if (! pat)
12328 return const0_rtx;
12329 emit_insn (pat);
12331 if (mode0 == V2SImode)
12332 emit_insn (gen_spe_evsel (target, op2, op3, scratch));
12333 else
12334 emit_insn (gen_spe_evsel_fs (target, op2, op3, scratch));
12336 return target;
12339 /* Expand an expression EXP that calls a built-in function,
12340 with result going to TARGET if that's convenient
12341 (and in mode MODE if that's convenient).
12342 SUBTARGET may be used as the target for computing one of EXP's operands.
12343 IGNORE is nonzero if the value is to be ignored. */
12345 static rtx
12346 rs6000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
12347 enum machine_mode mode ATTRIBUTE_UNUSED,
12348 int ignore ATTRIBUTE_UNUSED)
12350 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
12351 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
12352 const struct builtin_description *d;
12353 size_t i;
12354 rtx ret;
12355 bool success;
12357 switch (fcode)
12359 case RS6000_BUILTIN_RECIP:
12360 return rs6000_expand_binop_builtin (CODE_FOR_recipdf3, exp, target);
12362 case RS6000_BUILTIN_RECIPF:
12363 return rs6000_expand_binop_builtin (CODE_FOR_recipsf3, exp, target);
12365 case RS6000_BUILTIN_RSQRTF:
12366 return rs6000_expand_unop_builtin (CODE_FOR_rsqrtsf2, exp, target);
12368 case RS6000_BUILTIN_RSQRT:
12369 return rs6000_expand_unop_builtin (CODE_FOR_rsqrtdf2, exp, target);
12371 case RS6000_BUILTIN_BSWAP_HI:
12372 return rs6000_expand_unop_builtin (CODE_FOR_bswaphi2, exp, target);
12374 case POWER7_BUILTIN_BPERMD:
12375 return rs6000_expand_binop_builtin (((TARGET_64BIT)
12376 ? CODE_FOR_bpermd_di
12377 : CODE_FOR_bpermd_si), exp, target);
12379 case ALTIVEC_BUILTIN_MASK_FOR_LOAD:
12380 case ALTIVEC_BUILTIN_MASK_FOR_STORE:
12382 int icode = (int) CODE_FOR_altivec_lvsr;
12383 enum machine_mode tmode = insn_data[icode].operand[0].mode;
12384 enum machine_mode mode = insn_data[icode].operand[1].mode;
12385 tree arg;
12386 rtx op, addr, pat;
12388 gcc_assert (TARGET_ALTIVEC);
12390 arg = CALL_EXPR_ARG (exp, 0);
12391 gcc_assert (POINTER_TYPE_P (TREE_TYPE (arg)));
12392 op = expand_expr (arg, NULL_RTX, Pmode, EXPAND_NORMAL);
12393 addr = memory_address (mode, op);
12394 if (fcode == ALTIVEC_BUILTIN_MASK_FOR_STORE)
12395 op = addr;
12396 else
12398 /* For the load case need to negate the address. */
12399 op = gen_reg_rtx (GET_MODE (addr));
12400 emit_insn (gen_rtx_SET (VOIDmode, op,
12401 gen_rtx_NEG (GET_MODE (addr), addr)));
12403 op = gen_rtx_MEM (mode, op);
12405 if (target == 0
12406 || GET_MODE (target) != tmode
12407 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
12408 target = gen_reg_rtx (tmode);
12410 /*pat = gen_altivec_lvsr (target, op);*/
12411 pat = GEN_FCN (icode) (target, op);
12412 if (!pat)
12413 return 0;
12414 emit_insn (pat);
12416 return target;
12419 case ALTIVEC_BUILTIN_VCFUX:
12420 case ALTIVEC_BUILTIN_VCFSX:
12421 case ALTIVEC_BUILTIN_VCTUXS:
12422 case ALTIVEC_BUILTIN_VCTSXS:
12423 /* FIXME: There's got to be a nicer way to handle this case than
12424 constructing a new CALL_EXPR. */
12425 if (call_expr_nargs (exp) == 1)
12427 exp = build_call_nary (TREE_TYPE (exp), CALL_EXPR_FN (exp),
12428 2, CALL_EXPR_ARG (exp, 0), integer_zero_node);
12430 break;
12432 default:
12433 break;
12436 if (TARGET_ALTIVEC)
12438 ret = altivec_expand_builtin (exp, target, &success);
12440 if (success)
12441 return ret;
12443 if (TARGET_SPE)
12445 ret = spe_expand_builtin (exp, target, &success);
12447 if (success)
12448 return ret;
12450 if (TARGET_PAIRED_FLOAT)
12452 ret = paired_expand_builtin (exp, target, &success);
12454 if (success)
12455 return ret;
12458 gcc_assert (TARGET_ALTIVEC || TARGET_VSX || TARGET_SPE || TARGET_PAIRED_FLOAT);
12460 /* Handle simple unary operations. */
12461 d = (struct builtin_description *) bdesc_1arg;
12462 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
12463 if (d->code == fcode)
12464 return rs6000_expand_unop_builtin (d->icode, exp, target);
12466 /* Handle simple binary operations. */
12467 d = (struct builtin_description *) bdesc_2arg;
12468 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
12469 if (d->code == fcode)
12470 return rs6000_expand_binop_builtin (d->icode, exp, target);
12472 /* Handle simple ternary operations. */
12473 d = bdesc_3arg;
12474 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
12475 if (d->code == fcode)
12476 return rs6000_expand_ternop_builtin (d->icode, exp, target);
12478 gcc_unreachable ();
12481 static void
12482 rs6000_init_builtins (void)
12484 tree tdecl;
12485 tree ftype;
12487 V2SI_type_node = build_vector_type (intSI_type_node, 2);
12488 V2SF_type_node = build_vector_type (float_type_node, 2);
12489 V2DI_type_node = build_vector_type (intDI_type_node, 2);
12490 V2DF_type_node = build_vector_type (double_type_node, 2);
12491 V4HI_type_node = build_vector_type (intHI_type_node, 4);
12492 V4SI_type_node = build_vector_type (intSI_type_node, 4);
12493 V4SF_type_node = build_vector_type (float_type_node, 4);
12494 V8HI_type_node = build_vector_type (intHI_type_node, 8);
12495 V16QI_type_node = build_vector_type (intQI_type_node, 16);
12497 unsigned_V16QI_type_node = build_vector_type (unsigned_intQI_type_node, 16);
12498 unsigned_V8HI_type_node = build_vector_type (unsigned_intHI_type_node, 8);
12499 unsigned_V4SI_type_node = build_vector_type (unsigned_intSI_type_node, 4);
12500 unsigned_V2DI_type_node = build_vector_type (unsigned_intDI_type_node, 2);
12502 opaque_V2SF_type_node = build_opaque_vector_type (float_type_node, 2);
12503 opaque_V2SI_type_node = build_opaque_vector_type (intSI_type_node, 2);
12504 opaque_p_V2SI_type_node = build_pointer_type (opaque_V2SI_type_node);
12505 opaque_V4SI_type_node = build_opaque_vector_type (intSI_type_node, 4);
12507 /* The 'vector bool ...' types must be kept distinct from 'vector unsigned ...'
12508 types, especially in C++ land. Similarly, 'vector pixel' is distinct from
12509 'vector unsigned short'. */
12511 bool_char_type_node = build_distinct_type_copy (unsigned_intQI_type_node);
12512 bool_short_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
12513 bool_int_type_node = build_distinct_type_copy (unsigned_intSI_type_node);
12514 bool_long_type_node = build_distinct_type_copy (unsigned_intDI_type_node);
12515 pixel_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
12517 long_integer_type_internal_node = long_integer_type_node;
12518 long_unsigned_type_internal_node = long_unsigned_type_node;
12519 long_long_integer_type_internal_node = long_long_integer_type_node;
12520 long_long_unsigned_type_internal_node = long_long_unsigned_type_node;
12521 intQI_type_internal_node = intQI_type_node;
12522 uintQI_type_internal_node = unsigned_intQI_type_node;
12523 intHI_type_internal_node = intHI_type_node;
12524 uintHI_type_internal_node = unsigned_intHI_type_node;
12525 intSI_type_internal_node = intSI_type_node;
12526 uintSI_type_internal_node = unsigned_intSI_type_node;
12527 intDI_type_internal_node = intDI_type_node;
12528 uintDI_type_internal_node = unsigned_intDI_type_node;
12529 float_type_internal_node = float_type_node;
12530 double_type_internal_node = double_type_node;
12531 void_type_internal_node = void_type_node;
12533 /* Initialize the modes for builtin_function_type, mapping a machine mode to
12534 tree type node. */
12535 builtin_mode_to_type[QImode][0] = integer_type_node;
12536 builtin_mode_to_type[HImode][0] = integer_type_node;
12537 builtin_mode_to_type[SImode][0] = intSI_type_node;
12538 builtin_mode_to_type[SImode][1] = unsigned_intSI_type_node;
12539 builtin_mode_to_type[DImode][0] = intDI_type_node;
12540 builtin_mode_to_type[DImode][1] = unsigned_intDI_type_node;
12541 builtin_mode_to_type[SFmode][0] = float_type_node;
12542 builtin_mode_to_type[DFmode][0] = double_type_node;
12543 builtin_mode_to_type[V2SImode][0] = V2SI_type_node;
12544 builtin_mode_to_type[V2SFmode][0] = V2SF_type_node;
12545 builtin_mode_to_type[V2DImode][0] = V2DI_type_node;
12546 builtin_mode_to_type[V2DImode][1] = unsigned_V2DI_type_node;
12547 builtin_mode_to_type[V2DFmode][0] = V2DF_type_node;
12548 builtin_mode_to_type[V4HImode][0] = V4HI_type_node;
12549 builtin_mode_to_type[V4SImode][0] = V4SI_type_node;
12550 builtin_mode_to_type[V4SImode][1] = unsigned_V4SI_type_node;
12551 builtin_mode_to_type[V4SFmode][0] = V4SF_type_node;
12552 builtin_mode_to_type[V8HImode][0] = V8HI_type_node;
12553 builtin_mode_to_type[V8HImode][1] = unsigned_V8HI_type_node;
12554 builtin_mode_to_type[V16QImode][0] = V16QI_type_node;
12555 builtin_mode_to_type[V16QImode][1] = unsigned_V16QI_type_node;
12557 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12558 get_identifier ("__bool char"),
12559 bool_char_type_node);
12560 TYPE_NAME (bool_char_type_node) = tdecl;
12561 (*lang_hooks.decls.pushdecl) (tdecl);
12562 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12563 get_identifier ("__bool short"),
12564 bool_short_type_node);
12565 TYPE_NAME (bool_short_type_node) = tdecl;
12566 (*lang_hooks.decls.pushdecl) (tdecl);
12567 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12568 get_identifier ("__bool int"),
12569 bool_int_type_node);
12570 TYPE_NAME (bool_int_type_node) = tdecl;
12571 (*lang_hooks.decls.pushdecl) (tdecl);
12572 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL, get_identifier ("__pixel"),
12573 pixel_type_node);
12574 TYPE_NAME (pixel_type_node) = tdecl;
12575 (*lang_hooks.decls.pushdecl) (tdecl);
12577 bool_V16QI_type_node = build_vector_type (bool_char_type_node, 16);
12578 bool_V8HI_type_node = build_vector_type (bool_short_type_node, 8);
12579 bool_V4SI_type_node = build_vector_type (bool_int_type_node, 4);
12580 bool_V2DI_type_node = build_vector_type (bool_long_type_node, 2);
12581 pixel_V8HI_type_node = build_vector_type (pixel_type_node, 8);
12583 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12584 get_identifier ("__vector unsigned char"),
12585 unsigned_V16QI_type_node);
12586 TYPE_NAME (unsigned_V16QI_type_node) = tdecl;
12587 (*lang_hooks.decls.pushdecl) (tdecl);
12588 tdecl = build_decl (BUILTINS_LOCATION,
12589 TYPE_DECL, get_identifier ("__vector signed char"),
12590 V16QI_type_node);
12591 TYPE_NAME (V16QI_type_node) = tdecl;
12592 (*lang_hooks.decls.pushdecl) (tdecl);
12593 tdecl = build_decl (BUILTINS_LOCATION,
12594 TYPE_DECL, get_identifier ("__vector __bool char"),
12595 bool_V16QI_type_node);
12596 TYPE_NAME ( bool_V16QI_type_node) = tdecl;
12597 (*lang_hooks.decls.pushdecl) (tdecl);
12599 tdecl = build_decl (BUILTINS_LOCATION,
12600 TYPE_DECL, get_identifier ("__vector unsigned short"),
12601 unsigned_V8HI_type_node);
12602 TYPE_NAME (unsigned_V8HI_type_node) = tdecl;
12603 (*lang_hooks.decls.pushdecl) (tdecl);
12604 tdecl = build_decl (BUILTINS_LOCATION,
12605 TYPE_DECL, get_identifier ("__vector signed short"),
12606 V8HI_type_node);
12607 TYPE_NAME (V8HI_type_node) = tdecl;
12608 (*lang_hooks.decls.pushdecl) (tdecl);
12609 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12610 get_identifier ("__vector __bool short"),
12611 bool_V8HI_type_node);
12612 TYPE_NAME (bool_V8HI_type_node) = tdecl;
12613 (*lang_hooks.decls.pushdecl) (tdecl);
12615 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12616 get_identifier ("__vector unsigned int"),
12617 unsigned_V4SI_type_node);
12618 TYPE_NAME (unsigned_V4SI_type_node) = tdecl;
12619 (*lang_hooks.decls.pushdecl) (tdecl);
12620 tdecl = build_decl (BUILTINS_LOCATION,
12621 TYPE_DECL, get_identifier ("__vector signed int"),
12622 V4SI_type_node);
12623 TYPE_NAME (V4SI_type_node) = tdecl;
12624 (*lang_hooks.decls.pushdecl) (tdecl);
12625 tdecl = build_decl (BUILTINS_LOCATION,
12626 TYPE_DECL, get_identifier ("__vector __bool int"),
12627 bool_V4SI_type_node);
12628 TYPE_NAME (bool_V4SI_type_node) = tdecl;
12629 (*lang_hooks.decls.pushdecl) (tdecl);
12631 tdecl = build_decl (BUILTINS_LOCATION,
12632 TYPE_DECL, get_identifier ("__vector float"),
12633 V4SF_type_node);
12634 TYPE_NAME (V4SF_type_node) = tdecl;
12635 (*lang_hooks.decls.pushdecl) (tdecl);
12636 tdecl = build_decl (BUILTINS_LOCATION,
12637 TYPE_DECL, get_identifier ("__vector __pixel"),
12638 pixel_V8HI_type_node);
12639 TYPE_NAME (pixel_V8HI_type_node) = tdecl;
12640 (*lang_hooks.decls.pushdecl) (tdecl);
12642 if (TARGET_VSX)
12644 tdecl = build_decl (BUILTINS_LOCATION,
12645 TYPE_DECL, get_identifier ("__vector double"),
12646 V2DF_type_node);
12647 TYPE_NAME (V2DF_type_node) = tdecl;
12648 (*lang_hooks.decls.pushdecl) (tdecl);
12650 tdecl = build_decl (BUILTINS_LOCATION,
12651 TYPE_DECL, get_identifier ("__vector long"),
12652 V2DI_type_node);
12653 TYPE_NAME (V2DI_type_node) = tdecl;
12654 (*lang_hooks.decls.pushdecl) (tdecl);
12656 tdecl = build_decl (BUILTINS_LOCATION,
12657 TYPE_DECL, get_identifier ("__vector unsigned long"),
12658 unsigned_V2DI_type_node);
12659 TYPE_NAME (unsigned_V2DI_type_node) = tdecl;
12660 (*lang_hooks.decls.pushdecl) (tdecl);
12662 tdecl = build_decl (BUILTINS_LOCATION,
12663 TYPE_DECL, get_identifier ("__vector __bool long"),
12664 bool_V2DI_type_node);
12665 TYPE_NAME (bool_V2DI_type_node) = tdecl;
12666 (*lang_hooks.decls.pushdecl) (tdecl);
12669 if (TARGET_PAIRED_FLOAT)
12670 paired_init_builtins ();
12671 if (TARGET_SPE)
12672 spe_init_builtins ();
12673 if (TARGET_ALTIVEC)
12674 altivec_init_builtins ();
12675 if (TARGET_ALTIVEC || TARGET_SPE || TARGET_PAIRED_FLOAT || TARGET_VSX)
12676 rs6000_common_init_builtins ();
12677 if (TARGET_FRE)
12679 ftype = builtin_function_type (DFmode, DFmode, DFmode, VOIDmode,
12680 RS6000_BUILTIN_RECIP,
12681 "__builtin_recipdiv");
12682 def_builtin (MASK_POPCNTB, "__builtin_recipdiv", ftype,
12683 RS6000_BUILTIN_RECIP);
12685 if (TARGET_FRES)
12687 ftype = builtin_function_type (SFmode, SFmode, SFmode, VOIDmode,
12688 RS6000_BUILTIN_RECIPF,
12689 "__builtin_recipdivf");
12690 def_builtin (MASK_PPC_GFXOPT, "__builtin_recipdivf", ftype,
12691 RS6000_BUILTIN_RECIPF);
12693 if (TARGET_FRSQRTE)
12695 ftype = builtin_function_type (DFmode, DFmode, VOIDmode, VOIDmode,
12696 RS6000_BUILTIN_RSQRT,
12697 "__builtin_rsqrt");
12698 def_builtin (MASK_PPC_GFXOPT, "__builtin_rsqrt", ftype,
12699 RS6000_BUILTIN_RSQRT);
12701 if (TARGET_FRSQRTES)
12703 ftype = builtin_function_type (SFmode, SFmode, VOIDmode, VOIDmode,
12704 RS6000_BUILTIN_RSQRTF,
12705 "__builtin_rsqrtf");
12706 def_builtin (MASK_PPC_GFXOPT, "__builtin_rsqrtf", ftype,
12707 RS6000_BUILTIN_RSQRTF);
12709 if (TARGET_POPCNTD)
12711 enum machine_mode mode = (TARGET_64BIT) ? DImode : SImode;
12712 tree ftype = builtin_function_type (mode, mode, mode, VOIDmode,
12713 POWER7_BUILTIN_BPERMD,
12714 "__builtin_bpermd");
12715 def_builtin (MASK_POPCNTD, "__builtin_bpermd", ftype,
12716 POWER7_BUILTIN_BPERMD);
12718 if (TARGET_POWERPC)
12720 /* Don't use builtin_function_type here, as it maps HI/QI to SI. */
12721 tree ftype = build_function_type_list (unsigned_intHI_type_node,
12722 unsigned_intHI_type_node,
12723 NULL_TREE);
12724 def_builtin (MASK_POWERPC, "__builtin_bswap16", ftype,
12725 RS6000_BUILTIN_BSWAP_HI);
12728 #if TARGET_XCOFF
12729 /* AIX libm provides clog as __clog. */
12730 if (built_in_decls [BUILT_IN_CLOG])
12731 set_user_assembler_name (built_in_decls [BUILT_IN_CLOG], "__clog");
12732 #endif
12734 #ifdef SUBTARGET_INIT_BUILTINS
12735 SUBTARGET_INIT_BUILTINS;
12736 #endif
12739 /* Returns the rs6000 builtin decl for CODE. */
12741 static tree
12742 rs6000_builtin_decl (unsigned code, bool initialize_p ATTRIBUTE_UNUSED)
12744 if (code >= RS6000_BUILTIN_COUNT)
12745 return error_mark_node;
12747 return rs6000_builtin_decls[code];
12750 /* Search through a set of builtins and enable the mask bits.
12751 DESC is an array of builtins.
12752 SIZE is the total number of builtins.
12753 START is the builtin enum at which to start.
12754 END is the builtin enum at which to end. */
12755 static void
12756 enable_mask_for_builtins (struct builtin_description *desc, int size,
12757 enum rs6000_builtins start,
12758 enum rs6000_builtins end)
12760 int i;
12762 for (i = 0; i < size; ++i)
12763 if (desc[i].code == start)
12764 break;
12766 if (i == size)
12767 return;
12769 for (; i < size; ++i)
12771 /* Flip all the bits on. */
12772 desc[i].mask = target_flags;
12773 if (desc[i].code == end)
12774 break;
12778 static void
12779 spe_init_builtins (void)
12781 tree endlink = void_list_node;
12782 tree puint_type_node = build_pointer_type (unsigned_type_node);
12783 tree pushort_type_node = build_pointer_type (short_unsigned_type_node);
12784 struct builtin_description *d;
12785 size_t i;
12787 tree v2si_ftype_4_v2si
12788 = build_function_type
12789 (opaque_V2SI_type_node,
12790 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12791 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12792 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12793 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12794 endlink)))));
12796 tree v2sf_ftype_4_v2sf
12797 = build_function_type
12798 (opaque_V2SF_type_node,
12799 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12800 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12801 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12802 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12803 endlink)))));
12805 tree int_ftype_int_v2si_v2si
12806 = build_function_type
12807 (integer_type_node,
12808 tree_cons (NULL_TREE, integer_type_node,
12809 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12810 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12811 endlink))));
12813 tree int_ftype_int_v2sf_v2sf
12814 = build_function_type
12815 (integer_type_node,
12816 tree_cons (NULL_TREE, integer_type_node,
12817 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12818 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12819 endlink))));
12821 tree void_ftype_v2si_puint_int
12822 = build_function_type (void_type_node,
12823 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12824 tree_cons (NULL_TREE, puint_type_node,
12825 tree_cons (NULL_TREE,
12826 integer_type_node,
12827 endlink))));
12829 tree void_ftype_v2si_puint_char
12830 = build_function_type (void_type_node,
12831 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12832 tree_cons (NULL_TREE, puint_type_node,
12833 tree_cons (NULL_TREE,
12834 char_type_node,
12835 endlink))));
12837 tree void_ftype_v2si_pv2si_int
12838 = build_function_type (void_type_node,
12839 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12840 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
12841 tree_cons (NULL_TREE,
12842 integer_type_node,
12843 endlink))));
12845 tree void_ftype_v2si_pv2si_char
12846 = build_function_type (void_type_node,
12847 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12848 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
12849 tree_cons (NULL_TREE,
12850 char_type_node,
12851 endlink))));
12853 tree void_ftype_int
12854 = build_function_type (void_type_node,
12855 tree_cons (NULL_TREE, integer_type_node, endlink));
12857 tree int_ftype_void
12858 = build_function_type (integer_type_node, endlink);
12860 tree v2si_ftype_pv2si_int
12861 = build_function_type (opaque_V2SI_type_node,
12862 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
12863 tree_cons (NULL_TREE, integer_type_node,
12864 endlink)));
12866 tree v2si_ftype_puint_int
12867 = build_function_type (opaque_V2SI_type_node,
12868 tree_cons (NULL_TREE, puint_type_node,
12869 tree_cons (NULL_TREE, integer_type_node,
12870 endlink)));
12872 tree v2si_ftype_pushort_int
12873 = build_function_type (opaque_V2SI_type_node,
12874 tree_cons (NULL_TREE, pushort_type_node,
12875 tree_cons (NULL_TREE, integer_type_node,
12876 endlink)));
12878 tree v2si_ftype_signed_char
12879 = build_function_type (opaque_V2SI_type_node,
12880 tree_cons (NULL_TREE, signed_char_type_node,
12881 endlink));
12883 /* The initialization of the simple binary and unary builtins is
12884 done in rs6000_common_init_builtins, but we have to enable the
12885 mask bits here manually because we have run out of `target_flags'
12886 bits. We really need to redesign this mask business. */
12888 enable_mask_for_builtins ((struct builtin_description *) bdesc_2arg,
12889 ARRAY_SIZE (bdesc_2arg),
12890 SPE_BUILTIN_EVADDW,
12891 SPE_BUILTIN_EVXOR);
12892 enable_mask_for_builtins ((struct builtin_description *) bdesc_1arg,
12893 ARRAY_SIZE (bdesc_1arg),
12894 SPE_BUILTIN_EVABS,
12895 SPE_BUILTIN_EVSUBFUSIAAW);
12896 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_predicates,
12897 ARRAY_SIZE (bdesc_spe_predicates),
12898 SPE_BUILTIN_EVCMPEQ,
12899 SPE_BUILTIN_EVFSTSTLT);
12900 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_evsel,
12901 ARRAY_SIZE (bdesc_spe_evsel),
12902 SPE_BUILTIN_EVSEL_CMPGTS,
12903 SPE_BUILTIN_EVSEL_FSTSTEQ);
12905 (*lang_hooks.decls.pushdecl)
12906 (build_decl (BUILTINS_LOCATION, TYPE_DECL,
12907 get_identifier ("__ev64_opaque__"),
12908 opaque_V2SI_type_node));
12910 /* Initialize irregular SPE builtins. */
12912 def_builtin (target_flags, "__builtin_spe_mtspefscr", void_ftype_int, SPE_BUILTIN_MTSPEFSCR);
12913 def_builtin (target_flags, "__builtin_spe_mfspefscr", int_ftype_void, SPE_BUILTIN_MFSPEFSCR);
12914 def_builtin (target_flags, "__builtin_spe_evstddx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDDX);
12915 def_builtin (target_flags, "__builtin_spe_evstdhx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDHX);
12916 def_builtin (target_flags, "__builtin_spe_evstdwx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDWX);
12917 def_builtin (target_flags, "__builtin_spe_evstwhex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHEX);
12918 def_builtin (target_flags, "__builtin_spe_evstwhox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHOX);
12919 def_builtin (target_flags, "__builtin_spe_evstwwex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWEX);
12920 def_builtin (target_flags, "__builtin_spe_evstwwox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWOX);
12921 def_builtin (target_flags, "__builtin_spe_evstdd", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDD);
12922 def_builtin (target_flags, "__builtin_spe_evstdh", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDH);
12923 def_builtin (target_flags, "__builtin_spe_evstdw", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDW);
12924 def_builtin (target_flags, "__builtin_spe_evstwhe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHE);
12925 def_builtin (target_flags, "__builtin_spe_evstwho", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHO);
12926 def_builtin (target_flags, "__builtin_spe_evstwwe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWE);
12927 def_builtin (target_flags, "__builtin_spe_evstwwo", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWO);
12928 def_builtin (target_flags, "__builtin_spe_evsplatfi", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATFI);
12929 def_builtin (target_flags, "__builtin_spe_evsplati", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATI);
12931 /* Loads. */
12932 def_builtin (target_flags, "__builtin_spe_evlddx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDDX);
12933 def_builtin (target_flags, "__builtin_spe_evldwx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDWX);
12934 def_builtin (target_flags, "__builtin_spe_evldhx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDHX);
12935 def_builtin (target_flags, "__builtin_spe_evlwhex", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHEX);
12936 def_builtin (target_flags, "__builtin_spe_evlwhoux", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOUX);
12937 def_builtin (target_flags, "__builtin_spe_evlwhosx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOSX);
12938 def_builtin (target_flags, "__builtin_spe_evlwwsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLATX);
12939 def_builtin (target_flags, "__builtin_spe_evlwhsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLATX);
12940 def_builtin (target_flags, "__builtin_spe_evlhhesplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLATX);
12941 def_builtin (target_flags, "__builtin_spe_evlhhousplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLATX);
12942 def_builtin (target_flags, "__builtin_spe_evlhhossplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLATX);
12943 def_builtin (target_flags, "__builtin_spe_evldd", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDD);
12944 def_builtin (target_flags, "__builtin_spe_evldw", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDW);
12945 def_builtin (target_flags, "__builtin_spe_evldh", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDH);
12946 def_builtin (target_flags, "__builtin_spe_evlhhesplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLAT);
12947 def_builtin (target_flags, "__builtin_spe_evlhhossplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLAT);
12948 def_builtin (target_flags, "__builtin_spe_evlhhousplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLAT);
12949 def_builtin (target_flags, "__builtin_spe_evlwhe", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHE);
12950 def_builtin (target_flags, "__builtin_spe_evlwhos", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOS);
12951 def_builtin (target_flags, "__builtin_spe_evlwhou", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOU);
12952 def_builtin (target_flags, "__builtin_spe_evlwhsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLAT);
12953 def_builtin (target_flags, "__builtin_spe_evlwwsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLAT);
12955 /* Predicates. */
12956 d = (struct builtin_description *) bdesc_spe_predicates;
12957 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, d++)
12959 tree type;
12961 switch (insn_data[d->icode].operand[1].mode)
12963 case V2SImode:
12964 type = int_ftype_int_v2si_v2si;
12965 break;
12966 case V2SFmode:
12967 type = int_ftype_int_v2sf_v2sf;
12968 break;
12969 default:
12970 gcc_unreachable ();
12973 def_builtin (d->mask, d->name, type, d->code);
12976 /* Evsel predicates. */
12977 d = (struct builtin_description *) bdesc_spe_evsel;
12978 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, d++)
12980 tree type;
12982 switch (insn_data[d->icode].operand[1].mode)
12984 case V2SImode:
12985 type = v2si_ftype_4_v2si;
12986 break;
12987 case V2SFmode:
12988 type = v2sf_ftype_4_v2sf;
12989 break;
12990 default:
12991 gcc_unreachable ();
12994 def_builtin (d->mask, d->name, type, d->code);
12998 static void
12999 paired_init_builtins (void)
13001 const struct builtin_description *d;
13002 size_t i;
13003 tree endlink = void_list_node;
13005 tree int_ftype_int_v2sf_v2sf
13006 = build_function_type
13007 (integer_type_node,
13008 tree_cons (NULL_TREE, integer_type_node,
13009 tree_cons (NULL_TREE, V2SF_type_node,
13010 tree_cons (NULL_TREE, V2SF_type_node,
13011 endlink))));
13012 tree pcfloat_type_node =
13013 build_pointer_type (build_qualified_type
13014 (float_type_node, TYPE_QUAL_CONST));
13016 tree v2sf_ftype_long_pcfloat = build_function_type_list (V2SF_type_node,
13017 long_integer_type_node,
13018 pcfloat_type_node,
13019 NULL_TREE);
13020 tree void_ftype_v2sf_long_pcfloat =
13021 build_function_type_list (void_type_node,
13022 V2SF_type_node,
13023 long_integer_type_node,
13024 pcfloat_type_node,
13025 NULL_TREE);
13028 def_builtin (0, "__builtin_paired_lx", v2sf_ftype_long_pcfloat,
13029 PAIRED_BUILTIN_LX);
13032 def_builtin (0, "__builtin_paired_stx", void_ftype_v2sf_long_pcfloat,
13033 PAIRED_BUILTIN_STX);
13035 /* Predicates. */
13036 d = bdesc_paired_preds;
13037 for (i = 0; i < ARRAY_SIZE (bdesc_paired_preds); ++i, d++)
13039 tree type;
13041 switch (insn_data[d->icode].operand[1].mode)
13043 case V2SFmode:
13044 type = int_ftype_int_v2sf_v2sf;
13045 break;
13046 default:
13047 gcc_unreachable ();
13050 def_builtin (d->mask, d->name, type, d->code);
13054 static void
13055 altivec_init_builtins (void)
13057 const struct builtin_description *d;
13058 const struct builtin_description_predicates *dp;
13059 size_t i;
13060 tree ftype;
13062 tree pvoid_type_node = build_pointer_type (void_type_node);
13064 tree pcvoid_type_node
13065 = build_pointer_type (build_qualified_type (void_type_node,
13066 TYPE_QUAL_CONST));
13068 tree int_ftype_opaque
13069 = build_function_type_list (integer_type_node,
13070 opaque_V4SI_type_node, NULL_TREE);
13071 tree opaque_ftype_opaque
13072 = build_function_type (integer_type_node,
13073 NULL_TREE);
13074 tree opaque_ftype_opaque_int
13075 = build_function_type_list (opaque_V4SI_type_node,
13076 opaque_V4SI_type_node, integer_type_node, NULL_TREE);
13077 tree opaque_ftype_opaque_opaque_int
13078 = build_function_type_list (opaque_V4SI_type_node,
13079 opaque_V4SI_type_node, opaque_V4SI_type_node,
13080 integer_type_node, NULL_TREE);
13081 tree int_ftype_int_opaque_opaque
13082 = build_function_type_list (integer_type_node,
13083 integer_type_node, opaque_V4SI_type_node,
13084 opaque_V4SI_type_node, NULL_TREE);
13085 tree int_ftype_int_v4si_v4si
13086 = build_function_type_list (integer_type_node,
13087 integer_type_node, V4SI_type_node,
13088 V4SI_type_node, NULL_TREE);
13089 tree void_ftype_v4si
13090 = build_function_type_list (void_type_node, V4SI_type_node, NULL_TREE);
13091 tree v8hi_ftype_void
13092 = build_function_type (V8HI_type_node, void_list_node);
13093 tree void_ftype_void
13094 = build_function_type (void_type_node, void_list_node);
13095 tree void_ftype_int
13096 = build_function_type_list (void_type_node, integer_type_node, NULL_TREE);
13098 tree opaque_ftype_long_pcvoid
13099 = build_function_type_list (opaque_V4SI_type_node,
13100 long_integer_type_node, pcvoid_type_node,
13101 NULL_TREE);
13102 tree v16qi_ftype_long_pcvoid
13103 = build_function_type_list (V16QI_type_node,
13104 long_integer_type_node, pcvoid_type_node,
13105 NULL_TREE);
13106 tree v8hi_ftype_long_pcvoid
13107 = build_function_type_list (V8HI_type_node,
13108 long_integer_type_node, pcvoid_type_node,
13109 NULL_TREE);
13110 tree v4si_ftype_long_pcvoid
13111 = build_function_type_list (V4SI_type_node,
13112 long_integer_type_node, pcvoid_type_node,
13113 NULL_TREE);
13114 tree v4sf_ftype_long_pcvoid
13115 = build_function_type_list (V4SF_type_node,
13116 long_integer_type_node, pcvoid_type_node,
13117 NULL_TREE);
13118 tree v2df_ftype_long_pcvoid
13119 = build_function_type_list (V2DF_type_node,
13120 long_integer_type_node, pcvoid_type_node,
13121 NULL_TREE);
13122 tree v2di_ftype_long_pcvoid
13123 = build_function_type_list (V2DI_type_node,
13124 long_integer_type_node, pcvoid_type_node,
13125 NULL_TREE);
13127 tree void_ftype_opaque_long_pvoid
13128 = build_function_type_list (void_type_node,
13129 opaque_V4SI_type_node, long_integer_type_node,
13130 pvoid_type_node, NULL_TREE);
13131 tree void_ftype_v4si_long_pvoid
13132 = build_function_type_list (void_type_node,
13133 V4SI_type_node, long_integer_type_node,
13134 pvoid_type_node, NULL_TREE);
13135 tree void_ftype_v16qi_long_pvoid
13136 = build_function_type_list (void_type_node,
13137 V16QI_type_node, long_integer_type_node,
13138 pvoid_type_node, NULL_TREE);
13139 tree void_ftype_v8hi_long_pvoid
13140 = build_function_type_list (void_type_node,
13141 V8HI_type_node, long_integer_type_node,
13142 pvoid_type_node, NULL_TREE);
13143 tree void_ftype_v4sf_long_pvoid
13144 = build_function_type_list (void_type_node,
13145 V4SF_type_node, long_integer_type_node,
13146 pvoid_type_node, NULL_TREE);
13147 tree void_ftype_v2df_long_pvoid
13148 = build_function_type_list (void_type_node,
13149 V2DF_type_node, long_integer_type_node,
13150 pvoid_type_node, NULL_TREE);
13151 tree void_ftype_v2di_long_pvoid
13152 = build_function_type_list (void_type_node,
13153 V2DI_type_node, long_integer_type_node,
13154 pvoid_type_node, NULL_TREE);
13155 tree int_ftype_int_v8hi_v8hi
13156 = build_function_type_list (integer_type_node,
13157 integer_type_node, V8HI_type_node,
13158 V8HI_type_node, NULL_TREE);
13159 tree int_ftype_int_v16qi_v16qi
13160 = build_function_type_list (integer_type_node,
13161 integer_type_node, V16QI_type_node,
13162 V16QI_type_node, NULL_TREE);
13163 tree int_ftype_int_v4sf_v4sf
13164 = build_function_type_list (integer_type_node,
13165 integer_type_node, V4SF_type_node,
13166 V4SF_type_node, NULL_TREE);
13167 tree int_ftype_int_v2df_v2df
13168 = build_function_type_list (integer_type_node,
13169 integer_type_node, V2DF_type_node,
13170 V2DF_type_node, NULL_TREE);
13171 tree v4si_ftype_v4si
13172 = build_function_type_list (V4SI_type_node, V4SI_type_node, NULL_TREE);
13173 tree v8hi_ftype_v8hi
13174 = build_function_type_list (V8HI_type_node, V8HI_type_node, NULL_TREE);
13175 tree v16qi_ftype_v16qi
13176 = build_function_type_list (V16QI_type_node, V16QI_type_node, NULL_TREE);
13177 tree v4sf_ftype_v4sf
13178 = build_function_type_list (V4SF_type_node, V4SF_type_node, NULL_TREE);
13179 tree v2df_ftype_v2df
13180 = build_function_type_list (V2DF_type_node, V2DF_type_node, NULL_TREE);
13181 tree void_ftype_pcvoid_int_int
13182 = build_function_type_list (void_type_node,
13183 pcvoid_type_node, integer_type_node,
13184 integer_type_node, NULL_TREE);
13186 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mtvscr", void_ftype_v4si, ALTIVEC_BUILTIN_MTVSCR);
13187 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mfvscr", v8hi_ftype_void, ALTIVEC_BUILTIN_MFVSCR);
13188 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dssall", void_ftype_void, ALTIVEC_BUILTIN_DSSALL);
13189 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dss", void_ftype_int, ALTIVEC_BUILTIN_DSS);
13190 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSL);
13191 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSR);
13192 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEBX);
13193 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEHX);
13194 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEWX);
13195 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvxl", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVXL);
13196 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVX);
13197 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVX);
13198 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvewx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVEWX);
13199 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvxl", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVXL);
13200 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvebx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVEBX);
13201 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvehx", void_ftype_v8hi_long_pvoid, ALTIVEC_BUILTIN_STVEHX);
13202 def_builtin (MASK_ALTIVEC, "__builtin_vec_ld", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LD);
13203 def_builtin (MASK_ALTIVEC, "__builtin_vec_lde", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDE);
13204 def_builtin (MASK_ALTIVEC, "__builtin_vec_ldl", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDL);
13205 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSL);
13206 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSR);
13207 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEBX);
13208 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEHX);
13209 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEWX);
13210 def_builtin (MASK_ALTIVEC, "__builtin_vec_st", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_ST);
13211 def_builtin (MASK_ALTIVEC, "__builtin_vec_ste", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STE);
13212 def_builtin (MASK_ALTIVEC, "__builtin_vec_stl", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STL);
13213 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvewx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEWX);
13214 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvebx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEBX);
13215 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvehx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEHX);
13217 def_builtin (MASK_VSX, "__builtin_vsx_lxvd2x_v2df", v2df_ftype_long_pcvoid,
13218 VSX_BUILTIN_LXVD2X_V2DF);
13219 def_builtin (MASK_VSX, "__builtin_vsx_lxvd2x_v2di", v2di_ftype_long_pcvoid,
13220 VSX_BUILTIN_LXVD2X_V2DI);
13221 def_builtin (MASK_VSX, "__builtin_vsx_lxvw4x_v4sf", v4sf_ftype_long_pcvoid,
13222 VSX_BUILTIN_LXVW4X_V4SF);
13223 def_builtin (MASK_VSX, "__builtin_vsx_lxvw4x_v4si", v4si_ftype_long_pcvoid,
13224 VSX_BUILTIN_LXVW4X_V4SI);
13225 def_builtin (MASK_VSX, "__builtin_vsx_lxvw4x_v8hi",
13226 v8hi_ftype_long_pcvoid, VSX_BUILTIN_LXVW4X_V8HI);
13227 def_builtin (MASK_VSX, "__builtin_vsx_lxvw4x_v16qi",
13228 v16qi_ftype_long_pcvoid, VSX_BUILTIN_LXVW4X_V16QI);
13229 def_builtin (MASK_VSX, "__builtin_vsx_stxvd2x_v2df",
13230 void_ftype_v2df_long_pvoid, VSX_BUILTIN_STXVD2X_V2DF);
13231 def_builtin (MASK_VSX, "__builtin_vsx_stxvd2x_v2di",
13232 void_ftype_v2di_long_pvoid, VSX_BUILTIN_STXVD2X_V2DI);
13233 def_builtin (MASK_VSX, "__builtin_vsx_stxvw4x_v4sf",
13234 void_ftype_v4sf_long_pvoid, VSX_BUILTIN_STXVW4X_V4SF);
13235 def_builtin (MASK_VSX, "__builtin_vsx_stxvw4x_v4si",
13236 void_ftype_v4si_long_pvoid, VSX_BUILTIN_STXVW4X_V4SI);
13237 def_builtin (MASK_VSX, "__builtin_vsx_stxvw4x_v8hi",
13238 void_ftype_v8hi_long_pvoid, VSX_BUILTIN_STXVW4X_V8HI);
13239 def_builtin (MASK_VSX, "__builtin_vsx_stxvw4x_v16qi",
13240 void_ftype_v16qi_long_pvoid, VSX_BUILTIN_STXVW4X_V16QI);
13241 def_builtin (MASK_VSX, "__builtin_vec_vsx_ld", opaque_ftype_long_pcvoid,
13242 VSX_BUILTIN_VEC_LD);
13243 def_builtin (MASK_VSX, "__builtin_vec_vsx_st", void_ftype_opaque_long_pvoid,
13244 VSX_BUILTIN_VEC_ST);
13246 if (rs6000_cpu == PROCESSOR_CELL)
13248 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvlx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVLX);
13249 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvlxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVLXL);
13250 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvrx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVRX);
13251 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvrxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVRXL);
13253 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvlx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVLX);
13254 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvlxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVLXL);
13255 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvrx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVRX);
13256 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvrxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVRXL);
13258 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvlx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVLX);
13259 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvlxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVLXL);
13260 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvrx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVRX);
13261 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvrxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVRXL);
13263 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvlx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVLX);
13264 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvlxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVLXL);
13265 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvrx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVRX);
13266 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvrxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVRXL);
13268 def_builtin (MASK_ALTIVEC, "__builtin_vec_step", int_ftype_opaque, ALTIVEC_BUILTIN_VEC_STEP);
13269 def_builtin (MASK_ALTIVEC, "__builtin_vec_splats", opaque_ftype_opaque, ALTIVEC_BUILTIN_VEC_SPLATS);
13270 def_builtin (MASK_ALTIVEC, "__builtin_vec_promote", opaque_ftype_opaque, ALTIVEC_BUILTIN_VEC_PROMOTE);
13272 def_builtin (MASK_ALTIVEC, "__builtin_vec_sld", opaque_ftype_opaque_opaque_int, ALTIVEC_BUILTIN_VEC_SLD);
13273 def_builtin (MASK_ALTIVEC, "__builtin_vec_splat", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_SPLAT);
13274 def_builtin (MASK_ALTIVEC, "__builtin_vec_extract", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_EXTRACT);
13275 def_builtin (MASK_ALTIVEC, "__builtin_vec_insert", opaque_ftype_opaque_opaque_int, ALTIVEC_BUILTIN_VEC_INSERT);
13276 def_builtin (MASK_ALTIVEC, "__builtin_vec_vspltw", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTW);
13277 def_builtin (MASK_ALTIVEC, "__builtin_vec_vsplth", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTH);
13278 def_builtin (MASK_ALTIVEC, "__builtin_vec_vspltb", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTB);
13279 def_builtin (MASK_ALTIVEC, "__builtin_vec_ctf", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTF);
13280 def_builtin (MASK_ALTIVEC, "__builtin_vec_vcfsx", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFSX);
13281 def_builtin (MASK_ALTIVEC, "__builtin_vec_vcfux", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFUX);
13282 def_builtin (MASK_ALTIVEC, "__builtin_vec_cts", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTS);
13283 def_builtin (MASK_ALTIVEC, "__builtin_vec_ctu", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTU);
13285 /* Add the DST variants. */
13286 d = bdesc_dst;
13287 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
13288 def_builtin (d->mask, d->name, void_ftype_pcvoid_int_int, d->code);
13290 /* Initialize the predicates. */
13291 dp = bdesc_altivec_preds;
13292 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
13294 enum machine_mode mode1;
13295 tree type;
13296 bool is_overloaded = ((dp->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
13297 && dp->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
13298 || (dp->code >= VSX_BUILTIN_OVERLOADED_FIRST
13299 && dp->code <= VSX_BUILTIN_OVERLOADED_LAST));
13301 if (is_overloaded)
13302 mode1 = VOIDmode;
13303 else
13304 mode1 = insn_data[dp->icode].operand[1].mode;
13306 switch (mode1)
13308 case VOIDmode:
13309 type = int_ftype_int_opaque_opaque;
13310 break;
13311 case V4SImode:
13312 type = int_ftype_int_v4si_v4si;
13313 break;
13314 case V8HImode:
13315 type = int_ftype_int_v8hi_v8hi;
13316 break;
13317 case V16QImode:
13318 type = int_ftype_int_v16qi_v16qi;
13319 break;
13320 case V4SFmode:
13321 type = int_ftype_int_v4sf_v4sf;
13322 break;
13323 case V2DFmode:
13324 type = int_ftype_int_v2df_v2df;
13325 break;
13326 default:
13327 gcc_unreachable ();
13330 def_builtin (dp->mask, dp->name, type, dp->code);
13333 /* Initialize the abs* operators. */
13334 d = bdesc_abs;
13335 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
13337 enum machine_mode mode0;
13338 tree type;
13340 mode0 = insn_data[d->icode].operand[0].mode;
13342 switch (mode0)
13344 case V4SImode:
13345 type = v4si_ftype_v4si;
13346 break;
13347 case V8HImode:
13348 type = v8hi_ftype_v8hi;
13349 break;
13350 case V16QImode:
13351 type = v16qi_ftype_v16qi;
13352 break;
13353 case V4SFmode:
13354 type = v4sf_ftype_v4sf;
13355 break;
13356 case V2DFmode:
13357 type = v2df_ftype_v2df;
13358 break;
13359 default:
13360 gcc_unreachable ();
13363 def_builtin (d->mask, d->name, type, d->code);
13366 if (TARGET_ALTIVEC)
13368 tree decl;
13370 /* Initialize target builtin that implements
13371 targetm.vectorize.builtin_mask_for_load. */
13373 decl = add_builtin_function ("__builtin_altivec_mask_for_load",
13374 v16qi_ftype_long_pcvoid,
13375 ALTIVEC_BUILTIN_MASK_FOR_LOAD,
13376 BUILT_IN_MD, NULL, NULL_TREE);
13377 TREE_READONLY (decl) = 1;
13378 /* Record the decl. Will be used by rs6000_builtin_mask_for_load. */
13379 altivec_builtin_mask_for_load = decl;
13382 /* Access to the vec_init patterns. */
13383 ftype = build_function_type_list (V4SI_type_node, integer_type_node,
13384 integer_type_node, integer_type_node,
13385 integer_type_node, NULL_TREE);
13386 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v4si", ftype,
13387 ALTIVEC_BUILTIN_VEC_INIT_V4SI);
13389 ftype = build_function_type_list (V8HI_type_node, short_integer_type_node,
13390 short_integer_type_node,
13391 short_integer_type_node,
13392 short_integer_type_node,
13393 short_integer_type_node,
13394 short_integer_type_node,
13395 short_integer_type_node,
13396 short_integer_type_node, NULL_TREE);
13397 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v8hi", ftype,
13398 ALTIVEC_BUILTIN_VEC_INIT_V8HI);
13400 ftype = build_function_type_list (V16QI_type_node, char_type_node,
13401 char_type_node, char_type_node,
13402 char_type_node, char_type_node,
13403 char_type_node, char_type_node,
13404 char_type_node, char_type_node,
13405 char_type_node, char_type_node,
13406 char_type_node, char_type_node,
13407 char_type_node, char_type_node,
13408 char_type_node, NULL_TREE);
13409 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v16qi", ftype,
13410 ALTIVEC_BUILTIN_VEC_INIT_V16QI);
13412 ftype = build_function_type_list (V4SF_type_node, float_type_node,
13413 float_type_node, float_type_node,
13414 float_type_node, NULL_TREE);
13415 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v4sf", ftype,
13416 ALTIVEC_BUILTIN_VEC_INIT_V4SF);
13418 if (TARGET_VSX)
13420 ftype = build_function_type_list (V2DF_type_node, double_type_node,
13421 double_type_node, NULL_TREE);
13422 def_builtin (MASK_VSX, "__builtin_vec_init_v2df", ftype,
13423 VSX_BUILTIN_VEC_INIT_V2DF);
13425 ftype = build_function_type_list (V2DI_type_node, intDI_type_node,
13426 intDI_type_node, NULL_TREE);
13427 def_builtin (MASK_VSX, "__builtin_vec_init_v2di", ftype,
13428 VSX_BUILTIN_VEC_INIT_V2DI);
13431 /* Access to the vec_set patterns. */
13432 ftype = build_function_type_list (V4SI_type_node, V4SI_type_node,
13433 intSI_type_node,
13434 integer_type_node, NULL_TREE);
13435 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v4si", ftype,
13436 ALTIVEC_BUILTIN_VEC_SET_V4SI);
13438 ftype = build_function_type_list (V8HI_type_node, V8HI_type_node,
13439 intHI_type_node,
13440 integer_type_node, NULL_TREE);
13441 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v8hi", ftype,
13442 ALTIVEC_BUILTIN_VEC_SET_V8HI);
13444 ftype = build_function_type_list (V16QI_type_node, V16QI_type_node,
13445 intQI_type_node,
13446 integer_type_node, NULL_TREE);
13447 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v16qi", ftype,
13448 ALTIVEC_BUILTIN_VEC_SET_V16QI);
13450 ftype = build_function_type_list (V4SF_type_node, V4SF_type_node,
13451 float_type_node,
13452 integer_type_node, NULL_TREE);
13453 def_builtin (MASK_ALTIVEC|MASK_VSX, "__builtin_vec_set_v4sf", ftype,
13454 ALTIVEC_BUILTIN_VEC_SET_V4SF);
13456 if (TARGET_VSX)
13458 ftype = build_function_type_list (V2DF_type_node, V2DF_type_node,
13459 double_type_node,
13460 integer_type_node, NULL_TREE);
13461 def_builtin (MASK_VSX, "__builtin_vec_set_v2df", ftype,
13462 VSX_BUILTIN_VEC_SET_V2DF);
13464 ftype = build_function_type_list (V2DI_type_node, V2DI_type_node,
13465 intDI_type_node,
13466 integer_type_node, NULL_TREE);
13467 def_builtin (MASK_VSX, "__builtin_vec_set_v2di", ftype,
13468 VSX_BUILTIN_VEC_SET_V2DI);
13471 /* Access to the vec_extract patterns. */
13472 ftype = build_function_type_list (intSI_type_node, V4SI_type_node,
13473 integer_type_node, NULL_TREE);
13474 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v4si", ftype,
13475 ALTIVEC_BUILTIN_VEC_EXT_V4SI);
13477 ftype = build_function_type_list (intHI_type_node, V8HI_type_node,
13478 integer_type_node, NULL_TREE);
13479 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v8hi", ftype,
13480 ALTIVEC_BUILTIN_VEC_EXT_V8HI);
13482 ftype = build_function_type_list (intQI_type_node, V16QI_type_node,
13483 integer_type_node, NULL_TREE);
13484 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v16qi", ftype,
13485 ALTIVEC_BUILTIN_VEC_EXT_V16QI);
13487 ftype = build_function_type_list (float_type_node, V4SF_type_node,
13488 integer_type_node, NULL_TREE);
13489 def_builtin (MASK_ALTIVEC|MASK_VSX, "__builtin_vec_ext_v4sf", ftype,
13490 ALTIVEC_BUILTIN_VEC_EXT_V4SF);
13492 if (TARGET_VSX)
13494 ftype = build_function_type_list (double_type_node, V2DF_type_node,
13495 integer_type_node, NULL_TREE);
13496 def_builtin (MASK_VSX, "__builtin_vec_ext_v2df", ftype,
13497 VSX_BUILTIN_VEC_EXT_V2DF);
13499 ftype = build_function_type_list (intDI_type_node, V2DI_type_node,
13500 integer_type_node, NULL_TREE);
13501 def_builtin (MASK_VSX, "__builtin_vec_ext_v2di", ftype,
13502 VSX_BUILTIN_VEC_EXT_V2DI);
13506 /* Hash function for builtin functions with up to 3 arguments and a return
13507 type. */
13508 static unsigned
13509 builtin_hash_function (const void *hash_entry)
13511 unsigned ret = 0;
13512 int i;
13513 const struct builtin_hash_struct *bh =
13514 (const struct builtin_hash_struct *) hash_entry;
13516 for (i = 0; i < 4; i++)
13518 ret = (ret * (unsigned)MAX_MACHINE_MODE) + ((unsigned)bh->mode[i]);
13519 ret = (ret * 2) + bh->uns_p[i];
13522 return ret;
13525 /* Compare builtin hash entries H1 and H2 for equivalence. */
13526 static int
13527 builtin_hash_eq (const void *h1, const void *h2)
13529 const struct builtin_hash_struct *p1 = (const struct builtin_hash_struct *) h1;
13530 const struct builtin_hash_struct *p2 = (const struct builtin_hash_struct *) h2;
13532 return ((p1->mode[0] == p2->mode[0])
13533 && (p1->mode[1] == p2->mode[1])
13534 && (p1->mode[2] == p2->mode[2])
13535 && (p1->mode[3] == p2->mode[3])
13536 && (p1->uns_p[0] == p2->uns_p[0])
13537 && (p1->uns_p[1] == p2->uns_p[1])
13538 && (p1->uns_p[2] == p2->uns_p[2])
13539 && (p1->uns_p[3] == p2->uns_p[3]));
13542 /* Map types for builtin functions with an explicit return type and up to 3
13543 arguments. Functions with fewer than 3 arguments use VOIDmode as the type
13544 of the argument. */
13545 static tree
13546 builtin_function_type (enum machine_mode mode_ret, enum machine_mode mode_arg0,
13547 enum machine_mode mode_arg1, enum machine_mode mode_arg2,
13548 enum rs6000_builtins builtin, const char *name)
13550 struct builtin_hash_struct h;
13551 struct builtin_hash_struct *h2;
13552 void **found;
13553 int num_args = 3;
13554 int i;
13555 tree ret_type = NULL_TREE;
13556 tree arg_type[3] = { NULL_TREE, NULL_TREE, NULL_TREE };
13557 tree args;
13559 /* Create builtin_hash_table. */
13560 if (builtin_hash_table == NULL)
13561 builtin_hash_table = htab_create_ggc (1500, builtin_hash_function,
13562 builtin_hash_eq, NULL);
13564 h.type = NULL_TREE;
13565 h.mode[0] = mode_ret;
13566 h.mode[1] = mode_arg0;
13567 h.mode[2] = mode_arg1;
13568 h.mode[3] = mode_arg2;
13569 h.uns_p[0] = 0;
13570 h.uns_p[1] = 0;
13571 h.uns_p[2] = 0;
13572 h.uns_p[3] = 0;
13574 /* If the builtin is a type that produces unsigned results or takes unsigned
13575 arguments, and it is returned as a decl for the vectorizer (such as
13576 widening multiplies, permute), make sure the arguments and return value
13577 are type correct. */
13578 switch (builtin)
13580 /* unsigned 2 argument functions. */
13581 case ALTIVEC_BUILTIN_VMULEUB_UNS:
13582 case ALTIVEC_BUILTIN_VMULEUH_UNS:
13583 case ALTIVEC_BUILTIN_VMULOUB_UNS:
13584 case ALTIVEC_BUILTIN_VMULOUH_UNS:
13585 h.uns_p[0] = 1;
13586 h.uns_p[1] = 1;
13587 h.uns_p[2] = 1;
13588 break;
13590 /* unsigned 3 argument functions. */
13591 case ALTIVEC_BUILTIN_VPERM_16QI_UNS:
13592 case ALTIVEC_BUILTIN_VPERM_8HI_UNS:
13593 case ALTIVEC_BUILTIN_VPERM_4SI_UNS:
13594 case ALTIVEC_BUILTIN_VPERM_2DI_UNS:
13595 case ALTIVEC_BUILTIN_VSEL_16QI_UNS:
13596 case ALTIVEC_BUILTIN_VSEL_8HI_UNS:
13597 case ALTIVEC_BUILTIN_VSEL_4SI_UNS:
13598 case ALTIVEC_BUILTIN_VSEL_2DI_UNS:
13599 case VSX_BUILTIN_VPERM_16QI_UNS:
13600 case VSX_BUILTIN_VPERM_8HI_UNS:
13601 case VSX_BUILTIN_VPERM_4SI_UNS:
13602 case VSX_BUILTIN_VPERM_2DI_UNS:
13603 case VSX_BUILTIN_XXSEL_16QI_UNS:
13604 case VSX_BUILTIN_XXSEL_8HI_UNS:
13605 case VSX_BUILTIN_XXSEL_4SI_UNS:
13606 case VSX_BUILTIN_XXSEL_2DI_UNS:
13607 h.uns_p[0] = 1;
13608 h.uns_p[1] = 1;
13609 h.uns_p[2] = 1;
13610 h.uns_p[3] = 1;
13611 break;
13613 /* signed permute functions with unsigned char mask. */
13614 case ALTIVEC_BUILTIN_VPERM_16QI:
13615 case ALTIVEC_BUILTIN_VPERM_8HI:
13616 case ALTIVEC_BUILTIN_VPERM_4SI:
13617 case ALTIVEC_BUILTIN_VPERM_4SF:
13618 case ALTIVEC_BUILTIN_VPERM_2DI:
13619 case ALTIVEC_BUILTIN_VPERM_2DF:
13620 case VSX_BUILTIN_VPERM_16QI:
13621 case VSX_BUILTIN_VPERM_8HI:
13622 case VSX_BUILTIN_VPERM_4SI:
13623 case VSX_BUILTIN_VPERM_4SF:
13624 case VSX_BUILTIN_VPERM_2DI:
13625 case VSX_BUILTIN_VPERM_2DF:
13626 h.uns_p[3] = 1;
13627 break;
13629 /* unsigned args, signed return. */
13630 case VSX_BUILTIN_XVCVUXDDP_UNS:
13631 case VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF:
13632 h.uns_p[1] = 1;
13633 break;
13635 /* signed args, unsigned return. */
13636 case VSX_BUILTIN_XVCVDPUXDS_UNS:
13637 case VECTOR_BUILTIN_FIXUNS_V4SF_V4SI:
13638 h.uns_p[0] = 1;
13639 break;
13641 default:
13642 break;
13645 /* Figure out how many args are present. */
13646 while (num_args > 0 && h.mode[num_args] == VOIDmode)
13647 num_args--;
13649 if (num_args == 0)
13650 fatal_error ("internal error: builtin function %s had no type", name);
13652 ret_type = builtin_mode_to_type[h.mode[0]][h.uns_p[0]];
13653 if (!ret_type && h.uns_p[0])
13654 ret_type = builtin_mode_to_type[h.mode[0]][0];
13656 if (!ret_type)
13657 fatal_error ("internal error: builtin function %s had an unexpected "
13658 "return type %s", name, GET_MODE_NAME (h.mode[0]));
13660 for (i = 0; i < num_args; i++)
13662 int m = (int) h.mode[i+1];
13663 int uns_p = h.uns_p[i+1];
13665 arg_type[i] = builtin_mode_to_type[m][uns_p];
13666 if (!arg_type[i] && uns_p)
13667 arg_type[i] = builtin_mode_to_type[m][0];
13669 if (!arg_type[i])
13670 fatal_error ("internal error: builtin function %s, argument %d "
13671 "had unexpected argument type %s", name, i,
13672 GET_MODE_NAME (m));
13675 found = htab_find_slot (builtin_hash_table, &h, INSERT);
13676 if (*found == NULL)
13678 h2 = ggc_alloc_builtin_hash_struct ();
13679 *h2 = h;
13680 *found = (void *)h2;
13681 args = void_list_node;
13683 for (i = num_args - 1; i >= 0; i--)
13684 args = tree_cons (NULL_TREE, arg_type[i], args);
13686 h2->type = build_function_type (ret_type, args);
13689 return ((struct builtin_hash_struct *)(*found))->type;
13692 static void
13693 rs6000_common_init_builtins (void)
13695 const struct builtin_description *d;
13696 size_t i;
13698 tree opaque_ftype_opaque = NULL_TREE;
13699 tree opaque_ftype_opaque_opaque = NULL_TREE;
13700 tree opaque_ftype_opaque_opaque_opaque = NULL_TREE;
13701 tree v2si_ftype_qi = NULL_TREE;
13702 tree v2si_ftype_v2si_qi = NULL_TREE;
13703 tree v2si_ftype_int_qi = NULL_TREE;
13705 if (!TARGET_PAIRED_FLOAT)
13707 builtin_mode_to_type[V2SImode][0] = opaque_V2SI_type_node;
13708 builtin_mode_to_type[V2SFmode][0] = opaque_V2SF_type_node;
13711 /* Add the ternary operators. */
13712 d = bdesc_3arg;
13713 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
13715 tree type;
13716 int mask = d->mask;
13718 if ((mask != 0 && (mask & target_flags) == 0)
13719 || (mask == 0 && !TARGET_PAIRED_FLOAT))
13720 continue;
13722 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
13723 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
13724 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
13725 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
13727 if (! (type = opaque_ftype_opaque_opaque_opaque))
13728 type = opaque_ftype_opaque_opaque_opaque
13729 = build_function_type_list (opaque_V4SI_type_node,
13730 opaque_V4SI_type_node,
13731 opaque_V4SI_type_node,
13732 opaque_V4SI_type_node,
13733 NULL_TREE);
13735 else
13737 enum insn_code icode = d->icode;
13738 if (d->name == 0 || icode == CODE_FOR_nothing)
13739 continue;
13741 type = builtin_function_type (insn_data[icode].operand[0].mode,
13742 insn_data[icode].operand[1].mode,
13743 insn_data[icode].operand[2].mode,
13744 insn_data[icode].operand[3].mode,
13745 d->code, d->name);
13748 def_builtin (d->mask, d->name, type, d->code);
13751 /* Add the binary operators. */
13752 d = bdesc_2arg;
13753 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
13755 enum machine_mode mode0, mode1, mode2;
13756 tree type;
13757 int mask = d->mask;
13759 if ((mask != 0 && (mask & target_flags) == 0)
13760 || (mask == 0 && !TARGET_PAIRED_FLOAT))
13761 continue;
13763 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
13764 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
13765 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
13766 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
13768 if (! (type = opaque_ftype_opaque_opaque))
13769 type = opaque_ftype_opaque_opaque
13770 = build_function_type_list (opaque_V4SI_type_node,
13771 opaque_V4SI_type_node,
13772 opaque_V4SI_type_node,
13773 NULL_TREE);
13775 else
13777 enum insn_code icode = d->icode;
13778 if (d->name == 0 || icode == CODE_FOR_nothing)
13779 continue;
13781 mode0 = insn_data[icode].operand[0].mode;
13782 mode1 = insn_data[icode].operand[1].mode;
13783 mode2 = insn_data[icode].operand[2].mode;
13785 if (mode0 == V2SImode && mode1 == V2SImode && mode2 == QImode)
13787 if (! (type = v2si_ftype_v2si_qi))
13788 type = v2si_ftype_v2si_qi
13789 = build_function_type_list (opaque_V2SI_type_node,
13790 opaque_V2SI_type_node,
13791 char_type_node,
13792 NULL_TREE);
13795 else if (mode0 == V2SImode && GET_MODE_CLASS (mode1) == MODE_INT
13796 && mode2 == QImode)
13798 if (! (type = v2si_ftype_int_qi))
13799 type = v2si_ftype_int_qi
13800 = build_function_type_list (opaque_V2SI_type_node,
13801 integer_type_node,
13802 char_type_node,
13803 NULL_TREE);
13806 else
13807 type = builtin_function_type (mode0, mode1, mode2, VOIDmode,
13808 d->code, d->name);
13811 def_builtin (d->mask, d->name, type, d->code);
13814 /* Add the simple unary operators. */
13815 d = (struct builtin_description *) bdesc_1arg;
13816 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
13818 enum machine_mode mode0, mode1;
13819 tree type;
13820 int mask = d->mask;
13822 if ((mask != 0 && (mask & target_flags) == 0)
13823 || (mask == 0 && !TARGET_PAIRED_FLOAT))
13824 continue;
13826 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
13827 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
13828 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
13829 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
13831 if (! (type = opaque_ftype_opaque))
13832 type = opaque_ftype_opaque
13833 = build_function_type_list (opaque_V4SI_type_node,
13834 opaque_V4SI_type_node,
13835 NULL_TREE);
13837 else
13839 enum insn_code icode = d->icode;
13840 if (d->name == 0 || icode == CODE_FOR_nothing)
13841 continue;
13843 mode0 = insn_data[icode].operand[0].mode;
13844 mode1 = insn_data[icode].operand[1].mode;
13846 if (mode0 == V2SImode && mode1 == QImode)
13848 if (! (type = v2si_ftype_qi))
13849 type = v2si_ftype_qi
13850 = build_function_type_list (opaque_V2SI_type_node,
13851 char_type_node,
13852 NULL_TREE);
13855 else
13856 type = builtin_function_type (mode0, mode1, VOIDmode, VOIDmode,
13857 d->code, d->name);
13860 def_builtin (d->mask, d->name, type, d->code);
13864 static void
13865 rs6000_init_libfuncs (void)
13867 if (DEFAULT_ABI != ABI_V4 && TARGET_XCOFF
13868 && !TARGET_POWER2 && !TARGET_POWERPC)
13870 /* AIX library routines for float->int conversion. */
13871 set_conv_libfunc (sfix_optab, SImode, DFmode, "__itrunc");
13872 set_conv_libfunc (ufix_optab, SImode, DFmode, "__uitrunc");
13873 set_conv_libfunc (sfix_optab, SImode, TFmode, "_qitrunc");
13874 set_conv_libfunc (ufix_optab, SImode, TFmode, "_quitrunc");
13877 if (!TARGET_IEEEQUAD)
13878 /* AIX/Darwin/64-bit Linux quad floating point routines. */
13879 if (!TARGET_XL_COMPAT)
13881 set_optab_libfunc (add_optab, TFmode, "__gcc_qadd");
13882 set_optab_libfunc (sub_optab, TFmode, "__gcc_qsub");
13883 set_optab_libfunc (smul_optab, TFmode, "__gcc_qmul");
13884 set_optab_libfunc (sdiv_optab, TFmode, "__gcc_qdiv");
13886 if (!(TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)))
13888 set_optab_libfunc (neg_optab, TFmode, "__gcc_qneg");
13889 set_optab_libfunc (eq_optab, TFmode, "__gcc_qeq");
13890 set_optab_libfunc (ne_optab, TFmode, "__gcc_qne");
13891 set_optab_libfunc (gt_optab, TFmode, "__gcc_qgt");
13892 set_optab_libfunc (ge_optab, TFmode, "__gcc_qge");
13893 set_optab_libfunc (lt_optab, TFmode, "__gcc_qlt");
13894 set_optab_libfunc (le_optab, TFmode, "__gcc_qle");
13896 set_conv_libfunc (sext_optab, TFmode, SFmode, "__gcc_stoq");
13897 set_conv_libfunc (sext_optab, TFmode, DFmode, "__gcc_dtoq");
13898 set_conv_libfunc (trunc_optab, SFmode, TFmode, "__gcc_qtos");
13899 set_conv_libfunc (trunc_optab, DFmode, TFmode, "__gcc_qtod");
13900 set_conv_libfunc (sfix_optab, SImode, TFmode, "__gcc_qtoi");
13901 set_conv_libfunc (ufix_optab, SImode, TFmode, "__gcc_qtou");
13902 set_conv_libfunc (sfloat_optab, TFmode, SImode, "__gcc_itoq");
13903 set_conv_libfunc (ufloat_optab, TFmode, SImode, "__gcc_utoq");
13906 if (!(TARGET_HARD_FLOAT && TARGET_FPRS))
13907 set_optab_libfunc (unord_optab, TFmode, "__gcc_qunord");
13909 else
13911 set_optab_libfunc (add_optab, TFmode, "_xlqadd");
13912 set_optab_libfunc (sub_optab, TFmode, "_xlqsub");
13913 set_optab_libfunc (smul_optab, TFmode, "_xlqmul");
13914 set_optab_libfunc (sdiv_optab, TFmode, "_xlqdiv");
13916 else
13918 /* 32-bit SVR4 quad floating point routines. */
13920 set_optab_libfunc (add_optab, TFmode, "_q_add");
13921 set_optab_libfunc (sub_optab, TFmode, "_q_sub");
13922 set_optab_libfunc (neg_optab, TFmode, "_q_neg");
13923 set_optab_libfunc (smul_optab, TFmode, "_q_mul");
13924 set_optab_libfunc (sdiv_optab, TFmode, "_q_div");
13925 if (TARGET_PPC_GPOPT || TARGET_POWER2)
13926 set_optab_libfunc (sqrt_optab, TFmode, "_q_sqrt");
13928 set_optab_libfunc (eq_optab, TFmode, "_q_feq");
13929 set_optab_libfunc (ne_optab, TFmode, "_q_fne");
13930 set_optab_libfunc (gt_optab, TFmode, "_q_fgt");
13931 set_optab_libfunc (ge_optab, TFmode, "_q_fge");
13932 set_optab_libfunc (lt_optab, TFmode, "_q_flt");
13933 set_optab_libfunc (le_optab, TFmode, "_q_fle");
13935 set_conv_libfunc (sext_optab, TFmode, SFmode, "_q_stoq");
13936 set_conv_libfunc (sext_optab, TFmode, DFmode, "_q_dtoq");
13937 set_conv_libfunc (trunc_optab, SFmode, TFmode, "_q_qtos");
13938 set_conv_libfunc (trunc_optab, DFmode, TFmode, "_q_qtod");
13939 set_conv_libfunc (sfix_optab, SImode, TFmode, "_q_qtoi");
13940 set_conv_libfunc (ufix_optab, SImode, TFmode, "_q_qtou");
13941 set_conv_libfunc (sfloat_optab, TFmode, SImode, "_q_itoq");
13942 set_conv_libfunc (ufloat_optab, TFmode, SImode, "_q_utoq");
13947 /* Expand a block clear operation, and return 1 if successful. Return 0
13948 if we should let the compiler generate normal code.
13950 operands[0] is the destination
13951 operands[1] is the length
13952 operands[3] is the alignment */
13955 expand_block_clear (rtx operands[])
13957 rtx orig_dest = operands[0];
13958 rtx bytes_rtx = operands[1];
13959 rtx align_rtx = operands[3];
13960 bool constp = (GET_CODE (bytes_rtx) == CONST_INT);
13961 HOST_WIDE_INT align;
13962 HOST_WIDE_INT bytes;
13963 int offset;
13964 int clear_bytes;
13965 int clear_step;
13967 /* If this is not a fixed size move, just call memcpy */
13968 if (! constp)
13969 return 0;
13971 /* This must be a fixed size alignment */
13972 gcc_assert (GET_CODE (align_rtx) == CONST_INT);
13973 align = INTVAL (align_rtx) * BITS_PER_UNIT;
13975 /* Anything to clear? */
13976 bytes = INTVAL (bytes_rtx);
13977 if (bytes <= 0)
13978 return 1;
13980 /* Use the builtin memset after a point, to avoid huge code bloat.
13981 When optimize_size, avoid any significant code bloat; calling
13982 memset is about 4 instructions, so allow for one instruction to
13983 load zero and three to do clearing. */
13984 if (TARGET_ALTIVEC && align >= 128)
13985 clear_step = 16;
13986 else if (TARGET_POWERPC64 && align >= 32)
13987 clear_step = 8;
13988 else if (TARGET_SPE && align >= 64)
13989 clear_step = 8;
13990 else
13991 clear_step = 4;
13993 if (optimize_size && bytes > 3 * clear_step)
13994 return 0;
13995 if (! optimize_size && bytes > 8 * clear_step)
13996 return 0;
13998 for (offset = 0; bytes > 0; offset += clear_bytes, bytes -= clear_bytes)
14000 enum machine_mode mode = BLKmode;
14001 rtx dest;
14003 if (bytes >= 16 && TARGET_ALTIVEC && align >= 128)
14005 clear_bytes = 16;
14006 mode = V4SImode;
14008 else if (bytes >= 8 && TARGET_SPE && align >= 64)
14010 clear_bytes = 8;
14011 mode = V2SImode;
14013 else if (bytes >= 8 && TARGET_POWERPC64
14014 /* 64-bit loads and stores require word-aligned
14015 displacements. */
14016 && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
14018 clear_bytes = 8;
14019 mode = DImode;
14021 else if (bytes >= 4 && (align >= 32 || !STRICT_ALIGNMENT))
14022 { /* move 4 bytes */
14023 clear_bytes = 4;
14024 mode = SImode;
14026 else if (bytes >= 2 && (align >= 16 || !STRICT_ALIGNMENT))
14027 { /* move 2 bytes */
14028 clear_bytes = 2;
14029 mode = HImode;
14031 else /* move 1 byte at a time */
14033 clear_bytes = 1;
14034 mode = QImode;
14037 dest = adjust_address (orig_dest, mode, offset);
14039 emit_move_insn (dest, CONST0_RTX (mode));
14042 return 1;
14046 /* Expand a block move operation, and return 1 if successful. Return 0
14047 if we should let the compiler generate normal code.
14049 operands[0] is the destination
14050 operands[1] is the source
14051 operands[2] is the length
14052 operands[3] is the alignment */
14054 #define MAX_MOVE_REG 4
14057 expand_block_move (rtx operands[])
14059 rtx orig_dest = operands[0];
14060 rtx orig_src = operands[1];
14061 rtx bytes_rtx = operands[2];
14062 rtx align_rtx = operands[3];
14063 int constp = (GET_CODE (bytes_rtx) == CONST_INT);
14064 int align;
14065 int bytes;
14066 int offset;
14067 int move_bytes;
14068 rtx stores[MAX_MOVE_REG];
14069 int num_reg = 0;
14071 /* If this is not a fixed size move, just call memcpy */
14072 if (! constp)
14073 return 0;
14075 /* This must be a fixed size alignment */
14076 gcc_assert (GET_CODE (align_rtx) == CONST_INT);
14077 align = INTVAL (align_rtx) * BITS_PER_UNIT;
14079 /* Anything to move? */
14080 bytes = INTVAL (bytes_rtx);
14081 if (bytes <= 0)
14082 return 1;
14084 if (bytes > rs6000_block_move_inline_limit)
14085 return 0;
14087 for (offset = 0; bytes > 0; offset += move_bytes, bytes -= move_bytes)
14089 union {
14090 rtx (*movmemsi) (rtx, rtx, rtx, rtx);
14091 rtx (*mov) (rtx, rtx);
14092 } gen_func;
14093 enum machine_mode mode = BLKmode;
14094 rtx src, dest;
14096 /* Altivec first, since it will be faster than a string move
14097 when it applies, and usually not significantly larger. */
14098 if (TARGET_ALTIVEC && bytes >= 16 && align >= 128)
14100 move_bytes = 16;
14101 mode = V4SImode;
14102 gen_func.mov = gen_movv4si;
14104 else if (TARGET_SPE && bytes >= 8 && align >= 64)
14106 move_bytes = 8;
14107 mode = V2SImode;
14108 gen_func.mov = gen_movv2si;
14110 else if (TARGET_STRING
14111 && bytes > 24 /* move up to 32 bytes at a time */
14112 && ! fixed_regs[5]
14113 && ! fixed_regs[6]
14114 && ! fixed_regs[7]
14115 && ! fixed_regs[8]
14116 && ! fixed_regs[9]
14117 && ! fixed_regs[10]
14118 && ! fixed_regs[11]
14119 && ! fixed_regs[12])
14121 move_bytes = (bytes > 32) ? 32 : bytes;
14122 gen_func.movmemsi = gen_movmemsi_8reg;
14124 else if (TARGET_STRING
14125 && bytes > 16 /* move up to 24 bytes at a time */
14126 && ! fixed_regs[5]
14127 && ! fixed_regs[6]
14128 && ! fixed_regs[7]
14129 && ! fixed_regs[8]
14130 && ! fixed_regs[9]
14131 && ! fixed_regs[10])
14133 move_bytes = (bytes > 24) ? 24 : bytes;
14134 gen_func.movmemsi = gen_movmemsi_6reg;
14136 else if (TARGET_STRING
14137 && bytes > 8 /* move up to 16 bytes at a time */
14138 && ! fixed_regs[5]
14139 && ! fixed_regs[6]
14140 && ! fixed_regs[7]
14141 && ! fixed_regs[8])
14143 move_bytes = (bytes > 16) ? 16 : bytes;
14144 gen_func.movmemsi = gen_movmemsi_4reg;
14146 else if (bytes >= 8 && TARGET_POWERPC64
14147 /* 64-bit loads and stores require word-aligned
14148 displacements. */
14149 && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
14151 move_bytes = 8;
14152 mode = DImode;
14153 gen_func.mov = gen_movdi;
14155 else if (TARGET_STRING && bytes > 4 && !TARGET_POWERPC64)
14156 { /* move up to 8 bytes at a time */
14157 move_bytes = (bytes > 8) ? 8 : bytes;
14158 gen_func.movmemsi = gen_movmemsi_2reg;
14160 else if (bytes >= 4 && (align >= 32 || !STRICT_ALIGNMENT))
14161 { /* move 4 bytes */
14162 move_bytes = 4;
14163 mode = SImode;
14164 gen_func.mov = gen_movsi;
14166 else if (bytes >= 2 && (align >= 16 || !STRICT_ALIGNMENT))
14167 { /* move 2 bytes */
14168 move_bytes = 2;
14169 mode = HImode;
14170 gen_func.mov = gen_movhi;
14172 else if (TARGET_STRING && bytes > 1)
14173 { /* move up to 4 bytes at a time */
14174 move_bytes = (bytes > 4) ? 4 : bytes;
14175 gen_func.movmemsi = gen_movmemsi_1reg;
14177 else /* move 1 byte at a time */
14179 move_bytes = 1;
14180 mode = QImode;
14181 gen_func.mov = gen_movqi;
14184 src = adjust_address (orig_src, mode, offset);
14185 dest = adjust_address (orig_dest, mode, offset);
14187 if (mode != BLKmode)
14189 rtx tmp_reg = gen_reg_rtx (mode);
14191 emit_insn ((*gen_func.mov) (tmp_reg, src));
14192 stores[num_reg++] = (*gen_func.mov) (dest, tmp_reg);
14195 if (mode == BLKmode || num_reg >= MAX_MOVE_REG || bytes == move_bytes)
14197 int i;
14198 for (i = 0; i < num_reg; i++)
14199 emit_insn (stores[i]);
14200 num_reg = 0;
14203 if (mode == BLKmode)
14205 /* Move the address into scratch registers. The movmemsi
14206 patterns require zero offset. */
14207 if (!REG_P (XEXP (src, 0)))
14209 rtx src_reg = copy_addr_to_reg (XEXP (src, 0));
14210 src = replace_equiv_address (src, src_reg);
14212 set_mem_size (src, GEN_INT (move_bytes));
14214 if (!REG_P (XEXP (dest, 0)))
14216 rtx dest_reg = copy_addr_to_reg (XEXP (dest, 0));
14217 dest = replace_equiv_address (dest, dest_reg);
14219 set_mem_size (dest, GEN_INT (move_bytes));
14221 emit_insn ((*gen_func.movmemsi) (dest, src,
14222 GEN_INT (move_bytes & 31),
14223 align_rtx));
14227 return 1;
14231 /* Return a string to perform a load_multiple operation.
14232 operands[0] is the vector.
14233 operands[1] is the source address.
14234 operands[2] is the first destination register. */
14236 const char *
14237 rs6000_output_load_multiple (rtx operands[3])
14239 /* We have to handle the case where the pseudo used to contain the address
14240 is assigned to one of the output registers. */
14241 int i, j;
14242 int words = XVECLEN (operands[0], 0);
14243 rtx xop[10];
14245 if (XVECLEN (operands[0], 0) == 1)
14246 return "{l|lwz} %2,0(%1)";
14248 for (i = 0; i < words; i++)
14249 if (refers_to_regno_p (REGNO (operands[2]) + i,
14250 REGNO (operands[2]) + i + 1, operands[1], 0))
14252 if (i == words-1)
14254 xop[0] = GEN_INT (4 * (words-1));
14255 xop[1] = operands[1];
14256 xop[2] = operands[2];
14257 output_asm_insn ("{lsi|lswi} %2,%1,%0\n\t{l|lwz} %1,%0(%1)", xop);
14258 return "";
14260 else if (i == 0)
14262 xop[0] = GEN_INT (4 * (words-1));
14263 xop[1] = operands[1];
14264 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + 1);
14265 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);
14266 return "";
14268 else
14270 for (j = 0; j < words; j++)
14271 if (j != i)
14273 xop[0] = GEN_INT (j * 4);
14274 xop[1] = operands[1];
14275 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + j);
14276 output_asm_insn ("{l|lwz} %2,%0(%1)", xop);
14278 xop[0] = GEN_INT (i * 4);
14279 xop[1] = operands[1];
14280 output_asm_insn ("{l|lwz} %1,%0(%1)", xop);
14281 return "";
14285 return "{lsi|lswi} %2,%1,%N0";
14289 /* A validation routine: say whether CODE, a condition code, and MODE
14290 match. The other alternatives either don't make sense or should
14291 never be generated. */
14293 void
14294 validate_condition_mode (enum rtx_code code, enum machine_mode mode)
14296 gcc_assert ((GET_RTX_CLASS (code) == RTX_COMPARE
14297 || GET_RTX_CLASS (code) == RTX_COMM_COMPARE)
14298 && GET_MODE_CLASS (mode) == MODE_CC);
14300 /* These don't make sense. */
14301 gcc_assert ((code != GT && code != LT && code != GE && code != LE)
14302 || mode != CCUNSmode);
14304 gcc_assert ((code != GTU && code != LTU && code != GEU && code != LEU)
14305 || mode == CCUNSmode);
14307 gcc_assert (mode == CCFPmode
14308 || (code != ORDERED && code != UNORDERED
14309 && code != UNEQ && code != LTGT
14310 && code != UNGT && code != UNLT
14311 && code != UNGE && code != UNLE));
14313 /* These should never be generated except for
14314 flag_finite_math_only. */
14315 gcc_assert (mode != CCFPmode
14316 || flag_finite_math_only
14317 || (code != LE && code != GE
14318 && code != UNEQ && code != LTGT
14319 && code != UNGT && code != UNLT));
14321 /* These are invalid; the information is not there. */
14322 gcc_assert (mode != CCEQmode || code == EQ || code == NE);
14326 /* Return 1 if ANDOP is a mask that has no bits on that are not in the
14327 mask required to convert the result of a rotate insn into a shift
14328 left insn of SHIFTOP bits. Both are known to be SImode CONST_INT. */
14331 includes_lshift_p (rtx shiftop, rtx andop)
14333 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
14335 shift_mask <<= INTVAL (shiftop);
14337 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
14340 /* Similar, but for right shift. */
14343 includes_rshift_p (rtx shiftop, rtx andop)
14345 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
14347 shift_mask >>= INTVAL (shiftop);
14349 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
14352 /* Return 1 if ANDOP is a mask suitable for use with an rldic insn
14353 to perform a left shift. It must have exactly SHIFTOP least
14354 significant 0's, then one or more 1's, then zero or more 0's. */
14357 includes_rldic_lshift_p (rtx shiftop, rtx andop)
14359 if (GET_CODE (andop) == CONST_INT)
14361 HOST_WIDE_INT c, lsb, shift_mask;
14363 c = INTVAL (andop);
14364 if (c == 0 || c == ~0)
14365 return 0;
14367 shift_mask = ~0;
14368 shift_mask <<= INTVAL (shiftop);
14370 /* Find the least significant one bit. */
14371 lsb = c & -c;
14373 /* It must coincide with the LSB of the shift mask. */
14374 if (-lsb != shift_mask)
14375 return 0;
14377 /* Invert to look for the next transition (if any). */
14378 c = ~c;
14380 /* Remove the low group of ones (originally low group of zeros). */
14381 c &= -lsb;
14383 /* Again find the lsb, and check we have all 1's above. */
14384 lsb = c & -c;
14385 return c == -lsb;
14387 else if (GET_CODE (andop) == CONST_DOUBLE
14388 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
14390 HOST_WIDE_INT low, high, lsb;
14391 HOST_WIDE_INT shift_mask_low, shift_mask_high;
14393 low = CONST_DOUBLE_LOW (andop);
14394 if (HOST_BITS_PER_WIDE_INT < 64)
14395 high = CONST_DOUBLE_HIGH (andop);
14397 if ((low == 0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == 0))
14398 || (low == ~0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0)))
14399 return 0;
14401 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
14403 shift_mask_high = ~0;
14404 if (INTVAL (shiftop) > 32)
14405 shift_mask_high <<= INTVAL (shiftop) - 32;
14407 lsb = high & -high;
14409 if (-lsb != shift_mask_high || INTVAL (shiftop) < 32)
14410 return 0;
14412 high = ~high;
14413 high &= -lsb;
14415 lsb = high & -high;
14416 return high == -lsb;
14419 shift_mask_low = ~0;
14420 shift_mask_low <<= INTVAL (shiftop);
14422 lsb = low & -low;
14424 if (-lsb != shift_mask_low)
14425 return 0;
14427 if (HOST_BITS_PER_WIDE_INT < 64)
14428 high = ~high;
14429 low = ~low;
14430 low &= -lsb;
14432 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
14434 lsb = high & -high;
14435 return high == -lsb;
14438 lsb = low & -low;
14439 return low == -lsb && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0);
14441 else
14442 return 0;
14445 /* Return 1 if ANDOP is a mask suitable for use with an rldicr insn
14446 to perform a left shift. It must have SHIFTOP or more least
14447 significant 0's, with the remainder of the word 1's. */
14450 includes_rldicr_lshift_p (rtx shiftop, rtx andop)
14452 if (GET_CODE (andop) == CONST_INT)
14454 HOST_WIDE_INT c, lsb, shift_mask;
14456 shift_mask = ~0;
14457 shift_mask <<= INTVAL (shiftop);
14458 c = INTVAL (andop);
14460 /* Find the least significant one bit. */
14461 lsb = c & -c;
14463 /* It must be covered by the shift mask.
14464 This test also rejects c == 0. */
14465 if ((lsb & shift_mask) == 0)
14466 return 0;
14468 /* Check we have all 1's above the transition, and reject all 1's. */
14469 return c == -lsb && lsb != 1;
14471 else if (GET_CODE (andop) == CONST_DOUBLE
14472 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
14474 HOST_WIDE_INT low, lsb, shift_mask_low;
14476 low = CONST_DOUBLE_LOW (andop);
14478 if (HOST_BITS_PER_WIDE_INT < 64)
14480 HOST_WIDE_INT high, shift_mask_high;
14482 high = CONST_DOUBLE_HIGH (andop);
14484 if (low == 0)
14486 shift_mask_high = ~0;
14487 if (INTVAL (shiftop) > 32)
14488 shift_mask_high <<= INTVAL (shiftop) - 32;
14490 lsb = high & -high;
14492 if ((lsb & shift_mask_high) == 0)
14493 return 0;
14495 return high == -lsb;
14497 if (high != ~0)
14498 return 0;
14501 shift_mask_low = ~0;
14502 shift_mask_low <<= INTVAL (shiftop);
14504 lsb = low & -low;
14506 if ((lsb & shift_mask_low) == 0)
14507 return 0;
14509 return low == -lsb && lsb != 1;
14511 else
14512 return 0;
14515 /* Return 1 if operands will generate a valid arguments to rlwimi
14516 instruction for insert with right shift in 64-bit mode. The mask may
14517 not start on the first bit or stop on the last bit because wrap-around
14518 effects of instruction do not correspond to semantics of RTL insn. */
14521 insvdi_rshift_rlwimi_p (rtx sizeop, rtx startop, rtx shiftop)
14523 if (INTVAL (startop) > 32
14524 && INTVAL (startop) < 64
14525 && INTVAL (sizeop) > 1
14526 && INTVAL (sizeop) + INTVAL (startop) < 64
14527 && INTVAL (shiftop) > 0
14528 && INTVAL (sizeop) + INTVAL (shiftop) < 32
14529 && (64 - (INTVAL (shiftop) & 63)) >= INTVAL (sizeop))
14530 return 1;
14532 return 0;
14535 /* Return 1 if REGNO (reg1) == REGNO (reg2) - 1 making them candidates
14536 for lfq and stfq insns iff the registers are hard registers. */
14539 registers_ok_for_quad_peep (rtx reg1, rtx reg2)
14541 /* We might have been passed a SUBREG. */
14542 if (GET_CODE (reg1) != REG || GET_CODE (reg2) != REG)
14543 return 0;
14545 /* We might have been passed non floating point registers. */
14546 if (!FP_REGNO_P (REGNO (reg1))
14547 || !FP_REGNO_P (REGNO (reg2)))
14548 return 0;
14550 return (REGNO (reg1) == REGNO (reg2) - 1);
14553 /* Return 1 if addr1 and addr2 are suitable for lfq or stfq insn.
14554 addr1 and addr2 must be in consecutive memory locations
14555 (addr2 == addr1 + 8). */
14558 mems_ok_for_quad_peep (rtx mem1, rtx mem2)
14560 rtx addr1, addr2;
14561 unsigned int reg1, reg2;
14562 int offset1, offset2;
14564 /* The mems cannot be volatile. */
14565 if (MEM_VOLATILE_P (mem1) || MEM_VOLATILE_P (mem2))
14566 return 0;
14568 addr1 = XEXP (mem1, 0);
14569 addr2 = XEXP (mem2, 0);
14571 /* Extract an offset (if used) from the first addr. */
14572 if (GET_CODE (addr1) == PLUS)
14574 /* If not a REG, return zero. */
14575 if (GET_CODE (XEXP (addr1, 0)) != REG)
14576 return 0;
14577 else
14579 reg1 = REGNO (XEXP (addr1, 0));
14580 /* The offset must be constant! */
14581 if (GET_CODE (XEXP (addr1, 1)) != CONST_INT)
14582 return 0;
14583 offset1 = INTVAL (XEXP (addr1, 1));
14586 else if (GET_CODE (addr1) != REG)
14587 return 0;
14588 else
14590 reg1 = REGNO (addr1);
14591 /* This was a simple (mem (reg)) expression. Offset is 0. */
14592 offset1 = 0;
14595 /* And now for the second addr. */
14596 if (GET_CODE (addr2) == PLUS)
14598 /* If not a REG, return zero. */
14599 if (GET_CODE (XEXP (addr2, 0)) != REG)
14600 return 0;
14601 else
14603 reg2 = REGNO (XEXP (addr2, 0));
14604 /* The offset must be constant. */
14605 if (GET_CODE (XEXP (addr2, 1)) != CONST_INT)
14606 return 0;
14607 offset2 = INTVAL (XEXP (addr2, 1));
14610 else if (GET_CODE (addr2) != REG)
14611 return 0;
14612 else
14614 reg2 = REGNO (addr2);
14615 /* This was a simple (mem (reg)) expression. Offset is 0. */
14616 offset2 = 0;
14619 /* Both of these must have the same base register. */
14620 if (reg1 != reg2)
14621 return 0;
14623 /* The offset for the second addr must be 8 more than the first addr. */
14624 if (offset2 != offset1 + 8)
14625 return 0;
14627 /* All the tests passed. addr1 and addr2 are valid for lfq or stfq
14628 instructions. */
14629 return 1;
14634 rs6000_secondary_memory_needed_rtx (enum machine_mode mode)
14636 static bool eliminated = false;
14637 rtx ret;
14639 if (mode != SDmode)
14640 ret = assign_stack_local (mode, GET_MODE_SIZE (mode), 0);
14641 else
14643 rtx mem = cfun->machine->sdmode_stack_slot;
14644 gcc_assert (mem != NULL_RTX);
14646 if (!eliminated)
14648 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
14649 cfun->machine->sdmode_stack_slot = mem;
14650 eliminated = true;
14652 ret = mem;
14655 if (TARGET_DEBUG_ADDR)
14657 fprintf (stderr, "\nrs6000_secondary_memory_needed_rtx, mode %s, rtx:\n",
14658 GET_MODE_NAME (mode));
14659 if (!ret)
14660 fprintf (stderr, "\tNULL_RTX\n");
14661 else
14662 debug_rtx (ret);
14665 return ret;
14668 static tree
14669 rs6000_check_sdmode (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
14671 /* Don't walk into types. */
14672 if (*tp == NULL_TREE || *tp == error_mark_node || TYPE_P (*tp))
14674 *walk_subtrees = 0;
14675 return NULL_TREE;
14678 switch (TREE_CODE (*tp))
14680 case VAR_DECL:
14681 case PARM_DECL:
14682 case FIELD_DECL:
14683 case RESULT_DECL:
14684 case SSA_NAME:
14685 case REAL_CST:
14686 case MEM_REF:
14687 case VIEW_CONVERT_EXPR:
14688 if (TYPE_MODE (TREE_TYPE (*tp)) == SDmode)
14689 return *tp;
14690 break;
14691 default:
14692 break;
14695 return NULL_TREE;
14698 enum reload_reg_type {
14699 GPR_REGISTER_TYPE,
14700 VECTOR_REGISTER_TYPE,
14701 OTHER_REGISTER_TYPE
14704 static enum reload_reg_type
14705 rs6000_reload_register_type (enum reg_class rclass)
14707 switch (rclass)
14709 case GENERAL_REGS:
14710 case BASE_REGS:
14711 return GPR_REGISTER_TYPE;
14713 case FLOAT_REGS:
14714 case ALTIVEC_REGS:
14715 case VSX_REGS:
14716 return VECTOR_REGISTER_TYPE;
14718 default:
14719 return OTHER_REGISTER_TYPE;
14723 /* Inform reload about cases where moving X with a mode MODE to a register in
14724 RCLASS requires an extra scratch or immediate register. Return the class
14725 needed for the immediate register.
14727 For VSX and Altivec, we may need a register to convert sp+offset into
14728 reg+sp. */
14730 static reg_class_t
14731 rs6000_secondary_reload (bool in_p,
14732 rtx x,
14733 reg_class_t rclass_i,
14734 enum machine_mode mode,
14735 secondary_reload_info *sri)
14737 enum reg_class rclass = (enum reg_class) rclass_i;
14738 reg_class_t ret = ALL_REGS;
14739 enum insn_code icode;
14740 bool default_p = false;
14742 sri->icode = CODE_FOR_nothing;
14744 /* Convert vector loads and stores into gprs to use an additional base
14745 register. */
14746 icode = rs6000_vector_reload[mode][in_p != false];
14747 if (icode != CODE_FOR_nothing)
14749 ret = NO_REGS;
14750 sri->icode = CODE_FOR_nothing;
14751 sri->extra_cost = 0;
14753 if (GET_CODE (x) == MEM)
14755 rtx addr = XEXP (x, 0);
14757 /* Loads to and stores from gprs can do reg+offset, and wouldn't need
14758 an extra register in that case, but it would need an extra
14759 register if the addressing is reg+reg or (reg+reg)&(-16). */
14760 if (rclass == GENERAL_REGS || rclass == BASE_REGS)
14762 if (!legitimate_indirect_address_p (addr, false)
14763 && !rs6000_legitimate_offset_address_p (TImode, addr, false))
14765 sri->icode = icode;
14766 /* account for splitting the loads, and converting the
14767 address from reg+reg to reg. */
14768 sri->extra_cost = (((TARGET_64BIT) ? 3 : 5)
14769 + ((GET_CODE (addr) == AND) ? 1 : 0));
14772 /* Loads to and stores from vector registers can only do reg+reg
14773 addressing. Altivec registers can also do (reg+reg)&(-16). */
14774 else if (rclass == VSX_REGS || rclass == ALTIVEC_REGS
14775 || rclass == FLOAT_REGS || rclass == NO_REGS)
14777 if (!VECTOR_MEM_ALTIVEC_P (mode)
14778 && GET_CODE (addr) == AND
14779 && GET_CODE (XEXP (addr, 1)) == CONST_INT
14780 && INTVAL (XEXP (addr, 1)) == -16
14781 && (legitimate_indirect_address_p (XEXP (addr, 0), false)
14782 || legitimate_indexed_address_p (XEXP (addr, 0), false)))
14784 sri->icode = icode;
14785 sri->extra_cost = ((GET_CODE (XEXP (addr, 0)) == PLUS)
14786 ? 2 : 1);
14788 else if (!legitimate_indirect_address_p (addr, false)
14789 && (rclass == NO_REGS
14790 || !legitimate_indexed_address_p (addr, false)))
14792 sri->icode = icode;
14793 sri->extra_cost = 1;
14795 else
14796 icode = CODE_FOR_nothing;
14798 /* Any other loads, including to pseudo registers which haven't been
14799 assigned to a register yet, default to require a scratch
14800 register. */
14801 else
14803 sri->icode = icode;
14804 sri->extra_cost = 2;
14807 else if (REG_P (x))
14809 int regno = true_regnum (x);
14811 icode = CODE_FOR_nothing;
14812 if (regno < 0 || regno >= FIRST_PSEUDO_REGISTER)
14813 default_p = true;
14814 else
14816 enum reg_class xclass = REGNO_REG_CLASS (regno);
14817 enum reload_reg_type rtype1 = rs6000_reload_register_type (rclass);
14818 enum reload_reg_type rtype2 = rs6000_reload_register_type (xclass);
14820 /* If memory is needed, use default_secondary_reload to create the
14821 stack slot. */
14822 if (rtype1 != rtype2 || rtype1 == OTHER_REGISTER_TYPE)
14823 default_p = true;
14824 else
14825 ret = NO_REGS;
14828 else
14829 default_p = true;
14831 else
14832 default_p = true;
14834 if (default_p)
14835 ret = default_secondary_reload (in_p, x, rclass, mode, sri);
14837 gcc_assert (ret != ALL_REGS);
14839 if (TARGET_DEBUG_ADDR)
14841 fprintf (stderr,
14842 "\nrs6000_secondary_reload, return %s, in_p = %s, rclass = %s, "
14843 "mode = %s",
14844 reg_class_names[ret],
14845 in_p ? "true" : "false",
14846 reg_class_names[rclass],
14847 GET_MODE_NAME (mode));
14849 if (default_p)
14850 fprintf (stderr, ", default secondary reload");
14852 if (sri->icode != CODE_FOR_nothing)
14853 fprintf (stderr, ", reload func = %s, extra cost = %d\n",
14854 insn_data[sri->icode].name, sri->extra_cost);
14855 else
14856 fprintf (stderr, "\n");
14858 debug_rtx (x);
14861 return ret;
14864 /* Fixup reload addresses for Altivec or VSX loads/stores to change SP+offset
14865 to SP+reg addressing. */
14867 void
14868 rs6000_secondary_reload_inner (rtx reg, rtx mem, rtx scratch, bool store_p)
14870 int regno = true_regnum (reg);
14871 enum machine_mode mode = GET_MODE (reg);
14872 enum reg_class rclass;
14873 rtx addr;
14874 rtx and_op2 = NULL_RTX;
14875 rtx addr_op1;
14876 rtx addr_op2;
14877 rtx scratch_or_premodify = scratch;
14878 rtx and_rtx;
14879 rtx cc_clobber;
14881 if (TARGET_DEBUG_ADDR)
14883 fprintf (stderr, "\nrs6000_secondary_reload_inner, type = %s\n",
14884 store_p ? "store" : "load");
14885 fprintf (stderr, "reg:\n");
14886 debug_rtx (reg);
14887 fprintf (stderr, "mem:\n");
14888 debug_rtx (mem);
14889 fprintf (stderr, "scratch:\n");
14890 debug_rtx (scratch);
14893 gcc_assert (regno >= 0 && regno < FIRST_PSEUDO_REGISTER);
14894 gcc_assert (GET_CODE (mem) == MEM);
14895 rclass = REGNO_REG_CLASS (regno);
14896 addr = XEXP (mem, 0);
14898 switch (rclass)
14900 /* GPRs can handle reg + small constant, all other addresses need to use
14901 the scratch register. */
14902 case GENERAL_REGS:
14903 case BASE_REGS:
14904 if (GET_CODE (addr) == AND)
14906 and_op2 = XEXP (addr, 1);
14907 addr = XEXP (addr, 0);
14910 if (GET_CODE (addr) == PRE_MODIFY)
14912 scratch_or_premodify = XEXP (addr, 0);
14913 gcc_assert (REG_P (scratch_or_premodify));
14914 gcc_assert (GET_CODE (XEXP (addr, 1)) == PLUS);
14915 addr = XEXP (addr, 1);
14918 if (GET_CODE (addr) == PLUS
14919 && (!rs6000_legitimate_offset_address_p (TImode, addr, false)
14920 || and_op2 != NULL_RTX))
14922 addr_op1 = XEXP (addr, 0);
14923 addr_op2 = XEXP (addr, 1);
14924 gcc_assert (legitimate_indirect_address_p (addr_op1, false));
14926 if (!REG_P (addr_op2)
14927 && (GET_CODE (addr_op2) != CONST_INT
14928 || !satisfies_constraint_I (addr_op2)))
14930 if (TARGET_DEBUG_ADDR)
14932 fprintf (stderr,
14933 "\nMove plus addr to register %s, mode = %s: ",
14934 rs6000_reg_names[REGNO (scratch)],
14935 GET_MODE_NAME (mode));
14936 debug_rtx (addr_op2);
14938 rs6000_emit_move (scratch, addr_op2, Pmode);
14939 addr_op2 = scratch;
14942 emit_insn (gen_rtx_SET (VOIDmode,
14943 scratch_or_premodify,
14944 gen_rtx_PLUS (Pmode,
14945 addr_op1,
14946 addr_op2)));
14948 addr = scratch_or_premodify;
14949 scratch_or_premodify = scratch;
14951 else if (!legitimate_indirect_address_p (addr, false)
14952 && !rs6000_legitimate_offset_address_p (TImode, addr, false))
14954 if (TARGET_DEBUG_ADDR)
14956 fprintf (stderr, "\nMove addr to register %s, mode = %s: ",
14957 rs6000_reg_names[REGNO (scratch_or_premodify)],
14958 GET_MODE_NAME (mode));
14959 debug_rtx (addr);
14961 rs6000_emit_move (scratch_or_premodify, addr, Pmode);
14962 addr = scratch_or_premodify;
14963 scratch_or_premodify = scratch;
14965 break;
14967 /* Float/Altivec registers can only handle reg+reg addressing. Move
14968 other addresses into a scratch register. */
14969 case FLOAT_REGS:
14970 case VSX_REGS:
14971 case ALTIVEC_REGS:
14973 /* With float regs, we need to handle the AND ourselves, since we can't
14974 use the Altivec instruction with an implicit AND -16. Allow scalar
14975 loads to float registers to use reg+offset even if VSX. */
14976 if (GET_CODE (addr) == AND
14977 && (rclass != ALTIVEC_REGS || GET_MODE_SIZE (mode) != 16
14978 || GET_CODE (XEXP (addr, 1)) != CONST_INT
14979 || INTVAL (XEXP (addr, 1)) != -16
14980 || !VECTOR_MEM_ALTIVEC_P (mode)))
14982 and_op2 = XEXP (addr, 1);
14983 addr = XEXP (addr, 0);
14986 /* If we aren't using a VSX load, save the PRE_MODIFY register and use it
14987 as the address later. */
14988 if (GET_CODE (addr) == PRE_MODIFY
14989 && (!VECTOR_MEM_VSX_P (mode)
14990 || and_op2 != NULL_RTX
14991 || !legitimate_indexed_address_p (XEXP (addr, 1), false)))
14993 scratch_or_premodify = XEXP (addr, 0);
14994 gcc_assert (legitimate_indirect_address_p (scratch_or_premodify,
14995 false));
14996 gcc_assert (GET_CODE (XEXP (addr, 1)) == PLUS);
14997 addr = XEXP (addr, 1);
15000 if (legitimate_indirect_address_p (addr, false) /* reg */
15001 || legitimate_indexed_address_p (addr, false) /* reg+reg */
15002 || GET_CODE (addr) == PRE_MODIFY /* VSX pre-modify */
15003 || (GET_CODE (addr) == AND /* Altivec memory */
15004 && GET_CODE (XEXP (addr, 1)) == CONST_INT
15005 && INTVAL (XEXP (addr, 1)) == -16
15006 && VECTOR_MEM_ALTIVEC_P (mode))
15007 || (rclass == FLOAT_REGS /* legacy float mem */
15008 && GET_MODE_SIZE (mode) == 8
15009 && and_op2 == NULL_RTX
15010 && scratch_or_premodify == scratch
15011 && rs6000_legitimate_offset_address_p (mode, addr, false)))
15014 else if (GET_CODE (addr) == PLUS)
15016 addr_op1 = XEXP (addr, 0);
15017 addr_op2 = XEXP (addr, 1);
15018 gcc_assert (REG_P (addr_op1));
15020 if (TARGET_DEBUG_ADDR)
15022 fprintf (stderr, "\nMove plus addr to register %s, mode = %s: ",
15023 rs6000_reg_names[REGNO (scratch)], GET_MODE_NAME (mode));
15024 debug_rtx (addr_op2);
15026 rs6000_emit_move (scratch, addr_op2, Pmode);
15027 emit_insn (gen_rtx_SET (VOIDmode,
15028 scratch_or_premodify,
15029 gen_rtx_PLUS (Pmode,
15030 addr_op1,
15031 scratch)));
15032 addr = scratch_or_premodify;
15033 scratch_or_premodify = scratch;
15036 else if (GET_CODE (addr) == SYMBOL_REF || GET_CODE (addr) == CONST
15037 || GET_CODE (addr) == CONST_INT || REG_P (addr))
15039 if (TARGET_DEBUG_ADDR)
15041 fprintf (stderr, "\nMove addr to register %s, mode = %s: ",
15042 rs6000_reg_names[REGNO (scratch_or_premodify)],
15043 GET_MODE_NAME (mode));
15044 debug_rtx (addr);
15047 rs6000_emit_move (scratch_or_premodify, addr, Pmode);
15048 addr = scratch_or_premodify;
15049 scratch_or_premodify = scratch;
15052 else
15053 gcc_unreachable ();
15055 break;
15057 default:
15058 gcc_unreachable ();
15061 /* If the original address involved a pre-modify that we couldn't use the VSX
15062 memory instruction with update, and we haven't taken care of already,
15063 store the address in the pre-modify register and use that as the
15064 address. */
15065 if (scratch_or_premodify != scratch && scratch_or_premodify != addr)
15067 emit_insn (gen_rtx_SET (VOIDmode, scratch_or_premodify, addr));
15068 addr = scratch_or_premodify;
15071 /* If the original address involved an AND -16 and we couldn't use an ALTIVEC
15072 memory instruction, recreate the AND now, including the clobber which is
15073 generated by the general ANDSI3/ANDDI3 patterns for the
15074 andi. instruction. */
15075 if (and_op2 != NULL_RTX)
15077 if (! legitimate_indirect_address_p (addr, false))
15079 emit_insn (gen_rtx_SET (VOIDmode, scratch, addr));
15080 addr = scratch;
15083 if (TARGET_DEBUG_ADDR)
15085 fprintf (stderr, "\nAnd addr to register %s, mode = %s: ",
15086 rs6000_reg_names[REGNO (scratch)], GET_MODE_NAME (mode));
15087 debug_rtx (and_op2);
15090 and_rtx = gen_rtx_SET (VOIDmode,
15091 scratch,
15092 gen_rtx_AND (Pmode,
15093 addr,
15094 and_op2));
15096 cc_clobber = gen_rtx_CLOBBER (CCmode, gen_rtx_SCRATCH (CCmode));
15097 emit_insn (gen_rtx_PARALLEL (VOIDmode,
15098 gen_rtvec (2, and_rtx, cc_clobber)));
15099 addr = scratch;
15102 /* Adjust the address if it changed. */
15103 if (addr != XEXP (mem, 0))
15105 mem = change_address (mem, mode, addr);
15106 if (TARGET_DEBUG_ADDR)
15107 fprintf (stderr, "\nrs6000_secondary_reload_inner, mem adjusted.\n");
15110 /* Now create the move. */
15111 if (store_p)
15112 emit_insn (gen_rtx_SET (VOIDmode, mem, reg));
15113 else
15114 emit_insn (gen_rtx_SET (VOIDmode, reg, mem));
15116 return;
15119 /* Target hook to return the cover classes for Integrated Register Allocator.
15120 Cover classes is a set of non-intersected register classes covering all hard
15121 registers used for register allocation purpose. Any move between two
15122 registers of a cover class should be cheaper than load or store of the
15123 registers. The value is array of register classes with LIM_REG_CLASSES used
15124 as the end marker.
15126 We need two IRA_COVER_CLASSES, one for pre-VSX, and the other for VSX to
15127 account for the Altivec and Floating registers being subsets of the VSX
15128 register set under VSX, but distinct register sets on pre-VSX machines. */
15130 static const reg_class_t *
15131 rs6000_ira_cover_classes (void)
15133 static const reg_class_t cover_pre_vsx[] = IRA_COVER_CLASSES_PRE_VSX;
15134 static const reg_class_t cover_vsx[] = IRA_COVER_CLASSES_VSX;
15136 return (TARGET_VSX) ? cover_vsx : cover_pre_vsx;
15139 /* Allocate a 64-bit stack slot to be used for copying SDmode
15140 values through if this function has any SDmode references. */
15142 static void
15143 rs6000_alloc_sdmode_stack_slot (void)
15145 tree t;
15146 basic_block bb;
15147 gimple_stmt_iterator gsi;
15149 gcc_assert (cfun->machine->sdmode_stack_slot == NULL_RTX);
15151 FOR_EACH_BB (bb)
15152 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
15154 tree ret = walk_gimple_op (gsi_stmt (gsi), rs6000_check_sdmode, NULL);
15155 if (ret)
15157 rtx stack = assign_stack_local (DDmode, GET_MODE_SIZE (DDmode), 0);
15158 cfun->machine->sdmode_stack_slot = adjust_address_nv (stack,
15159 SDmode, 0);
15160 return;
15164 /* Check for any SDmode parameters of the function. */
15165 for (t = DECL_ARGUMENTS (cfun->decl); t; t = DECL_CHAIN (t))
15167 if (TREE_TYPE (t) == error_mark_node)
15168 continue;
15170 if (TYPE_MODE (TREE_TYPE (t)) == SDmode
15171 || TYPE_MODE (DECL_ARG_TYPE (t)) == SDmode)
15173 rtx stack = assign_stack_local (DDmode, GET_MODE_SIZE (DDmode), 0);
15174 cfun->machine->sdmode_stack_slot = adjust_address_nv (stack,
15175 SDmode, 0);
15176 return;
15181 static void
15182 rs6000_instantiate_decls (void)
15184 if (cfun->machine->sdmode_stack_slot != NULL_RTX)
15185 instantiate_decl_rtl (cfun->machine->sdmode_stack_slot);
15188 /* Given an rtx X being reloaded into a reg required to be
15189 in class CLASS, return the class of reg to actually use.
15190 In general this is just CLASS; but on some machines
15191 in some cases it is preferable to use a more restrictive class.
15193 On the RS/6000, we have to return NO_REGS when we want to reload a
15194 floating-point CONST_DOUBLE to force it to be copied to memory.
15196 We also don't want to reload integer values into floating-point
15197 registers if we can at all help it. In fact, this can
15198 cause reload to die, if it tries to generate a reload of CTR
15199 into a FP register and discovers it doesn't have the memory location
15200 required.
15202 ??? Would it be a good idea to have reload do the converse, that is
15203 try to reload floating modes into FP registers if possible?
15206 static enum reg_class
15207 rs6000_preferred_reload_class (rtx x, enum reg_class rclass)
15209 enum machine_mode mode = GET_MODE (x);
15211 if (VECTOR_UNIT_VSX_P (mode)
15212 && x == CONST0_RTX (mode) && VSX_REG_CLASS_P (rclass))
15213 return rclass;
15215 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode)
15216 && (rclass == ALTIVEC_REGS || rclass == VSX_REGS)
15217 && easy_vector_constant (x, mode))
15218 return ALTIVEC_REGS;
15220 if (CONSTANT_P (x) && reg_classes_intersect_p (rclass, FLOAT_REGS))
15221 return NO_REGS;
15223 if (GET_MODE_CLASS (mode) == MODE_INT && rclass == NON_SPECIAL_REGS)
15224 return GENERAL_REGS;
15226 /* For VSX, prefer the traditional registers for 64-bit values because we can
15227 use the non-VSX loads. Prefer the Altivec registers if Altivec is
15228 handling the vector operations (i.e. V16QI, V8HI, and V4SI), or if we
15229 prefer Altivec loads.. */
15230 if (rclass == VSX_REGS)
15232 if (GET_MODE_SIZE (mode) <= 8)
15233 return FLOAT_REGS;
15235 if (VECTOR_UNIT_ALTIVEC_P (mode) || VECTOR_MEM_ALTIVEC_P (mode))
15236 return ALTIVEC_REGS;
15238 return rclass;
15241 return rclass;
15244 /* Debug version of rs6000_preferred_reload_class. */
15245 static enum reg_class
15246 rs6000_debug_preferred_reload_class (rtx x, enum reg_class rclass)
15248 enum reg_class ret = rs6000_preferred_reload_class (x, rclass);
15250 fprintf (stderr,
15251 "\nrs6000_preferred_reload_class, return %s, rclass = %s, "
15252 "mode = %s, x:\n",
15253 reg_class_names[ret], reg_class_names[rclass],
15254 GET_MODE_NAME (GET_MODE (x)));
15255 debug_rtx (x);
15257 return ret;
15260 /* If we are copying between FP or AltiVec registers and anything else, we need
15261 a memory location. The exception is when we are targeting ppc64 and the
15262 move to/from fpr to gpr instructions are available. Also, under VSX, you
15263 can copy vector registers from the FP register set to the Altivec register
15264 set and vice versa. */
15266 static bool
15267 rs6000_secondary_memory_needed (enum reg_class class1,
15268 enum reg_class class2,
15269 enum machine_mode mode)
15271 if (class1 == class2)
15272 return false;
15274 /* Under VSX, there are 3 register classes that values could be in (VSX_REGS,
15275 ALTIVEC_REGS, and FLOAT_REGS). We don't need to use memory to copy
15276 between these classes. But we need memory for other things that can go in
15277 FLOAT_REGS like SFmode. */
15278 if (TARGET_VSX
15279 && (VECTOR_MEM_VSX_P (mode) || VECTOR_UNIT_VSX_P (mode))
15280 && (class1 == VSX_REGS || class1 == ALTIVEC_REGS
15281 || class1 == FLOAT_REGS))
15282 return (class2 != VSX_REGS && class2 != ALTIVEC_REGS
15283 && class2 != FLOAT_REGS);
15285 if (class1 == VSX_REGS || class2 == VSX_REGS)
15286 return true;
15288 if (class1 == FLOAT_REGS
15289 && (!TARGET_MFPGPR || !TARGET_POWERPC64
15290 || ((mode != DFmode)
15291 && (mode != DDmode)
15292 && (mode != DImode))))
15293 return true;
15295 if (class2 == FLOAT_REGS
15296 && (!TARGET_MFPGPR || !TARGET_POWERPC64
15297 || ((mode != DFmode)
15298 && (mode != DDmode)
15299 && (mode != DImode))))
15300 return true;
15302 if (class1 == ALTIVEC_REGS || class2 == ALTIVEC_REGS)
15303 return true;
15305 return false;
15308 /* Debug version of rs6000_secondary_memory_needed. */
15309 static bool
15310 rs6000_debug_secondary_memory_needed (enum reg_class class1,
15311 enum reg_class class2,
15312 enum machine_mode mode)
15314 bool ret = rs6000_secondary_memory_needed (class1, class2, mode);
15316 fprintf (stderr,
15317 "rs6000_secondary_memory_needed, return: %s, class1 = %s, "
15318 "class2 = %s, mode = %s\n",
15319 ret ? "true" : "false", reg_class_names[class1],
15320 reg_class_names[class2], GET_MODE_NAME (mode));
15322 return ret;
15325 /* Return the register class of a scratch register needed to copy IN into
15326 or out of a register in RCLASS in MODE. If it can be done directly,
15327 NO_REGS is returned. */
15329 static enum reg_class
15330 rs6000_secondary_reload_class (enum reg_class rclass, enum machine_mode mode,
15331 rtx in)
15333 int regno;
15335 if (TARGET_ELF || (DEFAULT_ABI == ABI_DARWIN
15336 #if TARGET_MACHO
15337 && MACHOPIC_INDIRECT
15338 #endif
15341 /* We cannot copy a symbolic operand directly into anything
15342 other than BASE_REGS for TARGET_ELF. So indicate that a
15343 register from BASE_REGS is needed as an intermediate
15344 register.
15346 On Darwin, pic addresses require a load from memory, which
15347 needs a base register. */
15348 if (rclass != BASE_REGS
15349 && (GET_CODE (in) == SYMBOL_REF
15350 || GET_CODE (in) == HIGH
15351 || GET_CODE (in) == LABEL_REF
15352 || GET_CODE (in) == CONST))
15353 return BASE_REGS;
15356 if (GET_CODE (in) == REG)
15358 regno = REGNO (in);
15359 if (regno >= FIRST_PSEUDO_REGISTER)
15361 regno = true_regnum (in);
15362 if (regno >= FIRST_PSEUDO_REGISTER)
15363 regno = -1;
15366 else if (GET_CODE (in) == SUBREG)
15368 regno = true_regnum (in);
15369 if (regno >= FIRST_PSEUDO_REGISTER)
15370 regno = -1;
15372 else
15373 regno = -1;
15375 /* We can place anything into GENERAL_REGS and can put GENERAL_REGS
15376 into anything. */
15377 if (rclass == GENERAL_REGS || rclass == BASE_REGS
15378 || (regno >= 0 && INT_REGNO_P (regno)))
15379 return NO_REGS;
15381 /* Constants, memory, and FP registers can go into FP registers. */
15382 if ((regno == -1 || FP_REGNO_P (regno))
15383 && (rclass == FLOAT_REGS || rclass == NON_SPECIAL_REGS))
15384 return (mode != SDmode) ? NO_REGS : GENERAL_REGS;
15386 /* Memory, and FP/altivec registers can go into fp/altivec registers under
15387 VSX. */
15388 if (TARGET_VSX
15389 && (regno == -1 || VSX_REGNO_P (regno))
15390 && VSX_REG_CLASS_P (rclass))
15391 return NO_REGS;
15393 /* Memory, and AltiVec registers can go into AltiVec registers. */
15394 if ((regno == -1 || ALTIVEC_REGNO_P (regno))
15395 && rclass == ALTIVEC_REGS)
15396 return NO_REGS;
15398 /* We can copy among the CR registers. */
15399 if ((rclass == CR_REGS || rclass == CR0_REGS)
15400 && regno >= 0 && CR_REGNO_P (regno))
15401 return NO_REGS;
15403 /* Otherwise, we need GENERAL_REGS. */
15404 return GENERAL_REGS;
15407 /* Debug version of rs6000_secondary_reload_class. */
15408 static enum reg_class
15409 rs6000_debug_secondary_reload_class (enum reg_class rclass,
15410 enum machine_mode mode, rtx in)
15412 enum reg_class ret = rs6000_secondary_reload_class (rclass, mode, in);
15413 fprintf (stderr,
15414 "\nrs6000_secondary_reload_class, return %s, rclass = %s, "
15415 "mode = %s, input rtx:\n",
15416 reg_class_names[ret], reg_class_names[rclass],
15417 GET_MODE_NAME (mode));
15418 debug_rtx (in);
15420 return ret;
15423 /* Return nonzero if for CLASS a mode change from FROM to TO is invalid. */
15425 static bool
15426 rs6000_cannot_change_mode_class (enum machine_mode from,
15427 enum machine_mode to,
15428 enum reg_class rclass)
15430 unsigned from_size = GET_MODE_SIZE (from);
15431 unsigned to_size = GET_MODE_SIZE (to);
15433 if (from_size != to_size)
15435 enum reg_class xclass = (TARGET_VSX) ? VSX_REGS : FLOAT_REGS;
15436 return ((from_size < 8 || to_size < 8 || TARGET_IEEEQUAD)
15437 && reg_classes_intersect_p (xclass, rclass));
15440 if (TARGET_E500_DOUBLE
15441 && ((((to) == DFmode) + ((from) == DFmode)) == 1
15442 || (((to) == TFmode) + ((from) == TFmode)) == 1
15443 || (((to) == DDmode) + ((from) == DDmode)) == 1
15444 || (((to) == TDmode) + ((from) == TDmode)) == 1
15445 || (((to) == DImode) + ((from) == DImode)) == 1))
15446 return true;
15448 /* Since the VSX register set includes traditional floating point registers
15449 and altivec registers, just check for the size being different instead of
15450 trying to check whether the modes are vector modes. Otherwise it won't
15451 allow say DF and DI to change classes. */
15452 if (TARGET_VSX && VSX_REG_CLASS_P (rclass))
15453 return (from_size != 8 && from_size != 16);
15455 if (TARGET_ALTIVEC && rclass == ALTIVEC_REGS
15456 && (ALTIVEC_VECTOR_MODE (from) + ALTIVEC_VECTOR_MODE (to)) == 1)
15457 return true;
15459 if (TARGET_SPE && (SPE_VECTOR_MODE (from) + SPE_VECTOR_MODE (to)) == 1
15460 && reg_classes_intersect_p (GENERAL_REGS, rclass))
15461 return true;
15463 return false;
15466 /* Debug version of rs6000_cannot_change_mode_class. */
15467 static bool
15468 rs6000_debug_cannot_change_mode_class (enum machine_mode from,
15469 enum machine_mode to,
15470 enum reg_class rclass)
15472 bool ret = rs6000_cannot_change_mode_class (from, to, rclass);
15474 fprintf (stderr,
15475 "rs6000_cannot_change_mode_class, return %s, from = %s, "
15476 "to = %s, rclass = %s\n",
15477 ret ? "true" : "false",
15478 GET_MODE_NAME (from), GET_MODE_NAME (to),
15479 reg_class_names[rclass]);
15481 return ret;
15484 /* Given a comparison operation, return the bit number in CCR to test. We
15485 know this is a valid comparison.
15487 SCC_P is 1 if this is for an scc. That means that %D will have been
15488 used instead of %C, so the bits will be in different places.
15490 Return -1 if OP isn't a valid comparison for some reason. */
15493 ccr_bit (rtx op, int scc_p)
15495 enum rtx_code code = GET_CODE (op);
15496 enum machine_mode cc_mode;
15497 int cc_regnum;
15498 int base_bit;
15499 rtx reg;
15501 if (!COMPARISON_P (op))
15502 return -1;
15504 reg = XEXP (op, 0);
15506 gcc_assert (GET_CODE (reg) == REG && CR_REGNO_P (REGNO (reg)));
15508 cc_mode = GET_MODE (reg);
15509 cc_regnum = REGNO (reg);
15510 base_bit = 4 * (cc_regnum - CR0_REGNO);
15512 validate_condition_mode (code, cc_mode);
15514 /* When generating a sCOND operation, only positive conditions are
15515 allowed. */
15516 gcc_assert (!scc_p
15517 || code == EQ || code == GT || code == LT || code == UNORDERED
15518 || code == GTU || code == LTU);
15520 switch (code)
15522 case NE:
15523 return scc_p ? base_bit + 3 : base_bit + 2;
15524 case EQ:
15525 return base_bit + 2;
15526 case GT: case GTU: case UNLE:
15527 return base_bit + 1;
15528 case LT: case LTU: case UNGE:
15529 return base_bit;
15530 case ORDERED: case UNORDERED:
15531 return base_bit + 3;
15533 case GE: case GEU:
15534 /* If scc, we will have done a cror to put the bit in the
15535 unordered position. So test that bit. For integer, this is ! LT
15536 unless this is an scc insn. */
15537 return scc_p ? base_bit + 3 : base_bit;
15539 case LE: case LEU:
15540 return scc_p ? base_bit + 3 : base_bit + 1;
15542 default:
15543 gcc_unreachable ();
15547 /* Return the GOT register. */
15550 rs6000_got_register (rtx value ATTRIBUTE_UNUSED)
15552 /* The second flow pass currently (June 1999) can't update
15553 regs_ever_live without disturbing other parts of the compiler, so
15554 update it here to make the prolog/epilogue code happy. */
15555 if (!can_create_pseudo_p ()
15556 && !df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM))
15557 df_set_regs_ever_live (RS6000_PIC_OFFSET_TABLE_REGNUM, true);
15559 crtl->uses_pic_offset_table = 1;
15561 return pic_offset_table_rtx;
15564 static rs6000_stack_t stack_info;
15566 /* Function to init struct machine_function.
15567 This will be called, via a pointer variable,
15568 from push_function_context. */
15570 static struct machine_function *
15571 rs6000_init_machine_status (void)
15573 stack_info.reload_completed = 0;
15574 return ggc_alloc_cleared_machine_function ();
15577 /* These macros test for integers and extract the low-order bits. */
15578 #define INT_P(X) \
15579 ((GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST_DOUBLE) \
15580 && GET_MODE (X) == VOIDmode)
15582 #define INT_LOWPART(X) \
15583 (GET_CODE (X) == CONST_INT ? INTVAL (X) : CONST_DOUBLE_LOW (X))
15586 extract_MB (rtx op)
15588 int i;
15589 unsigned long val = INT_LOWPART (op);
15591 /* If the high bit is zero, the value is the first 1 bit we find
15592 from the left. */
15593 if ((val & 0x80000000) == 0)
15595 gcc_assert (val & 0xffffffff);
15597 i = 1;
15598 while (((val <<= 1) & 0x80000000) == 0)
15599 ++i;
15600 return i;
15603 /* If the high bit is set and the low bit is not, or the mask is all
15604 1's, the value is zero. */
15605 if ((val & 1) == 0 || (val & 0xffffffff) == 0xffffffff)
15606 return 0;
15608 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
15609 from the right. */
15610 i = 31;
15611 while (((val >>= 1) & 1) != 0)
15612 --i;
15614 return i;
15618 extract_ME (rtx op)
15620 int i;
15621 unsigned long val = INT_LOWPART (op);
15623 /* If the low bit is zero, the value is the first 1 bit we find from
15624 the right. */
15625 if ((val & 1) == 0)
15627 gcc_assert (val & 0xffffffff);
15629 i = 30;
15630 while (((val >>= 1) & 1) == 0)
15631 --i;
15633 return i;
15636 /* If the low bit is set and the high bit is not, or the mask is all
15637 1's, the value is 31. */
15638 if ((val & 0x80000000) == 0 || (val & 0xffffffff) == 0xffffffff)
15639 return 31;
15641 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
15642 from the left. */
15643 i = 0;
15644 while (((val <<= 1) & 0x80000000) != 0)
15645 ++i;
15647 return i;
15650 /* Locate some local-dynamic symbol still in use by this function
15651 so that we can print its name in some tls_ld pattern. */
15653 static const char *
15654 rs6000_get_some_local_dynamic_name (void)
15656 rtx insn;
15658 if (cfun->machine->some_ld_name)
15659 return cfun->machine->some_ld_name;
15661 for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
15662 if (INSN_P (insn)
15663 && for_each_rtx (&PATTERN (insn),
15664 rs6000_get_some_local_dynamic_name_1, 0))
15665 return cfun->machine->some_ld_name;
15667 gcc_unreachable ();
15670 /* Helper function for rs6000_get_some_local_dynamic_name. */
15672 static int
15673 rs6000_get_some_local_dynamic_name_1 (rtx *px, void *data ATTRIBUTE_UNUSED)
15675 rtx x = *px;
15677 if (GET_CODE (x) == SYMBOL_REF)
15679 const char *str = XSTR (x, 0);
15680 if (SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_DYNAMIC)
15682 cfun->machine->some_ld_name = str;
15683 return 1;
15687 return 0;
15690 /* Write out a function code label. */
15692 void
15693 rs6000_output_function_entry (FILE *file, const char *fname)
15695 if (fname[0] != '.')
15697 switch (DEFAULT_ABI)
15699 default:
15700 gcc_unreachable ();
15702 case ABI_AIX:
15703 if (DOT_SYMBOLS)
15704 putc ('.', file);
15705 else
15706 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "L.");
15707 break;
15709 case ABI_V4:
15710 case ABI_DARWIN:
15711 break;
15715 RS6000_OUTPUT_BASENAME (file, fname);
15718 /* Print an operand. Recognize special options, documented below. */
15720 #if TARGET_ELF
15721 #define SMALL_DATA_RELOC ((rs6000_sdata == SDATA_EABI) ? "sda21" : "sdarel")
15722 #define SMALL_DATA_REG ((rs6000_sdata == SDATA_EABI) ? 0 : 13)
15723 #else
15724 #define SMALL_DATA_RELOC "sda21"
15725 #define SMALL_DATA_REG 0
15726 #endif
15728 void
15729 print_operand (FILE *file, rtx x, int code)
15731 int i;
15732 HOST_WIDE_INT val;
15733 unsigned HOST_WIDE_INT uval;
15735 switch (code)
15737 case '.':
15738 /* Write out an instruction after the call which may be replaced
15739 with glue code by the loader. This depends on the AIX version. */
15740 asm_fprintf (file, RS6000_CALL_GLUE);
15741 return;
15743 /* %a is output_address. */
15745 case 'A':
15746 /* If X is a constant integer whose low-order 5 bits are zero,
15747 write 'l'. Otherwise, write 'r'. This is a kludge to fix a bug
15748 in the AIX assembler where "sri" with a zero shift count
15749 writes a trash instruction. */
15750 if (GET_CODE (x) == CONST_INT && (INTVAL (x) & 31) == 0)
15751 putc ('l', file);
15752 else
15753 putc ('r', file);
15754 return;
15756 case 'b':
15757 /* If constant, low-order 16 bits of constant, unsigned.
15758 Otherwise, write normally. */
15759 if (INT_P (x))
15760 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 0xffff);
15761 else
15762 print_operand (file, x, 0);
15763 return;
15765 case 'B':
15766 /* If the low-order bit is zero, write 'r'; otherwise, write 'l'
15767 for 64-bit mask direction. */
15768 putc (((INT_LOWPART (x) & 1) == 0 ? 'r' : 'l'), file);
15769 return;
15771 /* %c is output_addr_const if a CONSTANT_ADDRESS_P, otherwise
15772 output_operand. */
15774 case 'c':
15775 /* X is a CR register. Print the number of the GT bit of the CR. */
15776 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15777 output_operand_lossage ("invalid %%c value");
15778 else
15779 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 1);
15780 return;
15782 case 'D':
15783 /* Like 'J' but get to the GT bit only. */
15784 gcc_assert (GET_CODE (x) == REG);
15786 /* Bit 1 is GT bit. */
15787 i = 4 * (REGNO (x) - CR0_REGNO) + 1;
15789 /* Add one for shift count in rlinm for scc. */
15790 fprintf (file, "%d", i + 1);
15791 return;
15793 case 'E':
15794 /* X is a CR register. Print the number of the EQ bit of the CR */
15795 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15796 output_operand_lossage ("invalid %%E value");
15797 else
15798 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 2);
15799 return;
15801 case 'f':
15802 /* X is a CR register. Print the shift count needed to move it
15803 to the high-order four bits. */
15804 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15805 output_operand_lossage ("invalid %%f value");
15806 else
15807 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO));
15808 return;
15810 case 'F':
15811 /* Similar, but print the count for the rotate in the opposite
15812 direction. */
15813 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15814 output_operand_lossage ("invalid %%F value");
15815 else
15816 fprintf (file, "%d", 32 - 4 * (REGNO (x) - CR0_REGNO));
15817 return;
15819 case 'G':
15820 /* X is a constant integer. If it is negative, print "m",
15821 otherwise print "z". This is to make an aze or ame insn. */
15822 if (GET_CODE (x) != CONST_INT)
15823 output_operand_lossage ("invalid %%G value");
15824 else if (INTVAL (x) >= 0)
15825 putc ('z', file);
15826 else
15827 putc ('m', file);
15828 return;
15830 case 'h':
15831 /* If constant, output low-order five bits. Otherwise, write
15832 normally. */
15833 if (INT_P (x))
15834 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 31);
15835 else
15836 print_operand (file, x, 0);
15837 return;
15839 case 'H':
15840 /* If constant, output low-order six bits. Otherwise, write
15841 normally. */
15842 if (INT_P (x))
15843 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 63);
15844 else
15845 print_operand (file, x, 0);
15846 return;
15848 case 'I':
15849 /* Print `i' if this is a constant, else nothing. */
15850 if (INT_P (x))
15851 putc ('i', file);
15852 return;
15854 case 'j':
15855 /* Write the bit number in CCR for jump. */
15856 i = ccr_bit (x, 0);
15857 if (i == -1)
15858 output_operand_lossage ("invalid %%j code");
15859 else
15860 fprintf (file, "%d", i);
15861 return;
15863 case 'J':
15864 /* Similar, but add one for shift count in rlinm for scc and pass
15865 scc flag to `ccr_bit'. */
15866 i = ccr_bit (x, 1);
15867 if (i == -1)
15868 output_operand_lossage ("invalid %%J code");
15869 else
15870 /* If we want bit 31, write a shift count of zero, not 32. */
15871 fprintf (file, "%d", i == 31 ? 0 : i + 1);
15872 return;
15874 case 'k':
15875 /* X must be a constant. Write the 1's complement of the
15876 constant. */
15877 if (! INT_P (x))
15878 output_operand_lossage ("invalid %%k value");
15879 else
15880 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ~ INT_LOWPART (x));
15881 return;
15883 case 'K':
15884 /* X must be a symbolic constant on ELF. Write an
15885 expression suitable for an 'addi' that adds in the low 16
15886 bits of the MEM. */
15887 if (GET_CODE (x) == CONST)
15889 if (GET_CODE (XEXP (x, 0)) != PLUS
15890 || (GET_CODE (XEXP (XEXP (x, 0), 0)) != SYMBOL_REF
15891 && GET_CODE (XEXP (XEXP (x, 0), 0)) != LABEL_REF)
15892 || GET_CODE (XEXP (XEXP (x, 0), 1)) != CONST_INT)
15893 output_operand_lossage ("invalid %%K value");
15895 print_operand_address (file, x);
15896 fputs ("@l", file);
15897 return;
15899 /* %l is output_asm_label. */
15901 case 'L':
15902 /* Write second word of DImode or DFmode reference. Works on register
15903 or non-indexed memory only. */
15904 if (GET_CODE (x) == REG)
15905 fputs (reg_names[REGNO (x) + 1], file);
15906 else if (GET_CODE (x) == MEM)
15908 /* Handle possible auto-increment. Since it is pre-increment and
15909 we have already done it, we can just use an offset of word. */
15910 if (GET_CODE (XEXP (x, 0)) == PRE_INC
15911 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
15912 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
15913 UNITS_PER_WORD));
15914 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
15915 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
15916 UNITS_PER_WORD));
15917 else
15918 output_address (XEXP (adjust_address_nv (x, SImode,
15919 UNITS_PER_WORD),
15920 0));
15922 if (small_data_operand (x, GET_MODE (x)))
15923 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
15924 reg_names[SMALL_DATA_REG]);
15926 return;
15928 case 'm':
15929 /* MB value for a mask operand. */
15930 if (! mask_operand (x, SImode))
15931 output_operand_lossage ("invalid %%m value");
15933 fprintf (file, "%d", extract_MB (x));
15934 return;
15936 case 'M':
15937 /* ME value for a mask operand. */
15938 if (! mask_operand (x, SImode))
15939 output_operand_lossage ("invalid %%M value");
15941 fprintf (file, "%d", extract_ME (x));
15942 return;
15944 /* %n outputs the negative of its operand. */
15946 case 'N':
15947 /* Write the number of elements in the vector times 4. */
15948 if (GET_CODE (x) != PARALLEL)
15949 output_operand_lossage ("invalid %%N value");
15950 else
15951 fprintf (file, "%d", XVECLEN (x, 0) * 4);
15952 return;
15954 case 'O':
15955 /* Similar, but subtract 1 first. */
15956 if (GET_CODE (x) != PARALLEL)
15957 output_operand_lossage ("invalid %%O value");
15958 else
15959 fprintf (file, "%d", (XVECLEN (x, 0) - 1) * 4);
15960 return;
15962 case 'p':
15963 /* X is a CONST_INT that is a power of two. Output the logarithm. */
15964 if (! INT_P (x)
15965 || INT_LOWPART (x) < 0
15966 || (i = exact_log2 (INT_LOWPART (x))) < 0)
15967 output_operand_lossage ("invalid %%p value");
15968 else
15969 fprintf (file, "%d", i);
15970 return;
15972 case 'P':
15973 /* The operand must be an indirect memory reference. The result
15974 is the register name. */
15975 if (GET_CODE (x) != MEM || GET_CODE (XEXP (x, 0)) != REG
15976 || REGNO (XEXP (x, 0)) >= 32)
15977 output_operand_lossage ("invalid %%P value");
15978 else
15979 fputs (reg_names[REGNO (XEXP (x, 0))], file);
15980 return;
15982 case 'q':
15983 /* This outputs the logical code corresponding to a boolean
15984 expression. The expression may have one or both operands
15985 negated (if one, only the first one). For condition register
15986 logical operations, it will also treat the negated
15987 CR codes as NOTs, but not handle NOTs of them. */
15989 const char *const *t = 0;
15990 const char *s;
15991 enum rtx_code code = GET_CODE (x);
15992 static const char * const tbl[3][3] = {
15993 { "and", "andc", "nor" },
15994 { "or", "orc", "nand" },
15995 { "xor", "eqv", "xor" } };
15997 if (code == AND)
15998 t = tbl[0];
15999 else if (code == IOR)
16000 t = tbl[1];
16001 else if (code == XOR)
16002 t = tbl[2];
16003 else
16004 output_operand_lossage ("invalid %%q value");
16006 if (GET_CODE (XEXP (x, 0)) != NOT)
16007 s = t[0];
16008 else
16010 if (GET_CODE (XEXP (x, 1)) == NOT)
16011 s = t[2];
16012 else
16013 s = t[1];
16016 fputs (s, file);
16018 return;
16020 case 'Q':
16021 if (TARGET_MFCRF)
16022 fputc (',', file);
16023 /* FALLTHRU */
16024 else
16025 return;
16027 case 'R':
16028 /* X is a CR register. Print the mask for `mtcrf'. */
16029 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
16030 output_operand_lossage ("invalid %%R value");
16031 else
16032 fprintf (file, "%d", 128 >> (REGNO (x) - CR0_REGNO));
16033 return;
16035 case 's':
16036 /* Low 5 bits of 32 - value */
16037 if (! INT_P (x))
16038 output_operand_lossage ("invalid %%s value");
16039 else
16040 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (32 - INT_LOWPART (x)) & 31);
16041 return;
16043 case 'S':
16044 /* PowerPC64 mask position. All 0's is excluded.
16045 CONST_INT 32-bit mask is considered sign-extended so any
16046 transition must occur within the CONST_INT, not on the boundary. */
16047 if (! mask64_operand (x, DImode))
16048 output_operand_lossage ("invalid %%S value");
16050 uval = INT_LOWPART (x);
16052 if (uval & 1) /* Clear Left */
16054 #if HOST_BITS_PER_WIDE_INT > 64
16055 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
16056 #endif
16057 i = 64;
16059 else /* Clear Right */
16061 uval = ~uval;
16062 #if HOST_BITS_PER_WIDE_INT > 64
16063 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
16064 #endif
16065 i = 63;
16067 while (uval != 0)
16068 --i, uval >>= 1;
16069 gcc_assert (i >= 0);
16070 fprintf (file, "%d", i);
16071 return;
16073 case 't':
16074 /* Like 'J' but get to the OVERFLOW/UNORDERED bit. */
16075 gcc_assert (GET_CODE (x) == REG && GET_MODE (x) == CCmode);
16077 /* Bit 3 is OV bit. */
16078 i = 4 * (REGNO (x) - CR0_REGNO) + 3;
16080 /* If we want bit 31, write a shift count of zero, not 32. */
16081 fprintf (file, "%d", i == 31 ? 0 : i + 1);
16082 return;
16084 case 'T':
16085 /* Print the symbolic name of a branch target register. */
16086 if (GET_CODE (x) != REG || (REGNO (x) != LR_REGNO
16087 && REGNO (x) != CTR_REGNO))
16088 output_operand_lossage ("invalid %%T value");
16089 else if (REGNO (x) == LR_REGNO)
16090 fputs (TARGET_NEW_MNEMONICS ? "lr" : "r", file);
16091 else
16092 fputs ("ctr", file);
16093 return;
16095 case 'u':
16096 /* High-order 16 bits of constant for use in unsigned operand. */
16097 if (! INT_P (x))
16098 output_operand_lossage ("invalid %%u value");
16099 else
16100 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
16101 (INT_LOWPART (x) >> 16) & 0xffff);
16102 return;
16104 case 'v':
16105 /* High-order 16 bits of constant for use in signed operand. */
16106 if (! INT_P (x))
16107 output_operand_lossage ("invalid %%v value");
16108 else
16109 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
16110 (INT_LOWPART (x) >> 16) & 0xffff);
16111 return;
16113 case 'U':
16114 /* Print `u' if this has an auto-increment or auto-decrement. */
16115 if (GET_CODE (x) == MEM
16116 && (GET_CODE (XEXP (x, 0)) == PRE_INC
16117 || GET_CODE (XEXP (x, 0)) == PRE_DEC
16118 || GET_CODE (XEXP (x, 0)) == PRE_MODIFY))
16119 putc ('u', file);
16120 return;
16122 case 'V':
16123 /* Print the trap code for this operand. */
16124 switch (GET_CODE (x))
16126 case EQ:
16127 fputs ("eq", file); /* 4 */
16128 break;
16129 case NE:
16130 fputs ("ne", file); /* 24 */
16131 break;
16132 case LT:
16133 fputs ("lt", file); /* 16 */
16134 break;
16135 case LE:
16136 fputs ("le", file); /* 20 */
16137 break;
16138 case GT:
16139 fputs ("gt", file); /* 8 */
16140 break;
16141 case GE:
16142 fputs ("ge", file); /* 12 */
16143 break;
16144 case LTU:
16145 fputs ("llt", file); /* 2 */
16146 break;
16147 case LEU:
16148 fputs ("lle", file); /* 6 */
16149 break;
16150 case GTU:
16151 fputs ("lgt", file); /* 1 */
16152 break;
16153 case GEU:
16154 fputs ("lge", file); /* 5 */
16155 break;
16156 default:
16157 gcc_unreachable ();
16159 break;
16161 case 'w':
16162 /* If constant, low-order 16 bits of constant, signed. Otherwise, write
16163 normally. */
16164 if (INT_P (x))
16165 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
16166 ((INT_LOWPART (x) & 0xffff) ^ 0x8000) - 0x8000);
16167 else
16168 print_operand (file, x, 0);
16169 return;
16171 case 'W':
16172 /* MB value for a PowerPC64 rldic operand. */
16173 val = (GET_CODE (x) == CONST_INT
16174 ? INTVAL (x) : CONST_DOUBLE_HIGH (x));
16176 if (val < 0)
16177 i = -1;
16178 else
16179 for (i = 0; i < HOST_BITS_PER_WIDE_INT; i++)
16180 if ((val <<= 1) < 0)
16181 break;
16183 #if HOST_BITS_PER_WIDE_INT == 32
16184 if (GET_CODE (x) == CONST_INT && i >= 0)
16185 i += 32; /* zero-extend high-part was all 0's */
16186 else if (GET_CODE (x) == CONST_DOUBLE && i == 32)
16188 val = CONST_DOUBLE_LOW (x);
16190 gcc_assert (val);
16191 if (val < 0)
16192 --i;
16193 else
16194 for ( ; i < 64; i++)
16195 if ((val <<= 1) < 0)
16196 break;
16198 #endif
16200 fprintf (file, "%d", i + 1);
16201 return;
16203 case 'x':
16204 /* X is a FPR or Altivec register used in a VSX context. */
16205 if (GET_CODE (x) != REG || !VSX_REGNO_P (REGNO (x)))
16206 output_operand_lossage ("invalid %%x value");
16207 else
16209 int reg = REGNO (x);
16210 int vsx_reg = (FP_REGNO_P (reg)
16211 ? reg - 32
16212 : reg - FIRST_ALTIVEC_REGNO + 32);
16214 #ifdef TARGET_REGNAMES
16215 if (TARGET_REGNAMES)
16216 fprintf (file, "%%vs%d", vsx_reg);
16217 else
16218 #endif
16219 fprintf (file, "%d", vsx_reg);
16221 return;
16223 case 'X':
16224 if (GET_CODE (x) == MEM
16225 && (legitimate_indexed_address_p (XEXP (x, 0), 0)
16226 || (GET_CODE (XEXP (x, 0)) == PRE_MODIFY
16227 && legitimate_indexed_address_p (XEXP (XEXP (x, 0), 1), 0))))
16228 putc ('x', file);
16229 return;
16231 case 'Y':
16232 /* Like 'L', for third word of TImode */
16233 if (GET_CODE (x) == REG)
16234 fputs (reg_names[REGNO (x) + 2], file);
16235 else if (GET_CODE (x) == MEM)
16237 if (GET_CODE (XEXP (x, 0)) == PRE_INC
16238 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
16239 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
16240 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
16241 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
16242 else
16243 output_address (XEXP (adjust_address_nv (x, SImode, 8), 0));
16244 if (small_data_operand (x, GET_MODE (x)))
16245 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
16246 reg_names[SMALL_DATA_REG]);
16248 return;
16250 case 'z':
16251 /* X is a SYMBOL_REF. Write out the name preceded by a
16252 period and without any trailing data in brackets. Used for function
16253 names. If we are configured for System V (or the embedded ABI) on
16254 the PowerPC, do not emit the period, since those systems do not use
16255 TOCs and the like. */
16256 gcc_assert (GET_CODE (x) == SYMBOL_REF);
16258 /* Mark the decl as referenced so that cgraph will output the
16259 function. */
16260 if (SYMBOL_REF_DECL (x))
16261 mark_decl_referenced (SYMBOL_REF_DECL (x));
16263 /* For macho, check to see if we need a stub. */
16264 if (TARGET_MACHO)
16266 const char *name = XSTR (x, 0);
16267 #if TARGET_MACHO
16268 if (darwin_emit_branch_islands
16269 && MACHOPIC_INDIRECT
16270 && machopic_classify_symbol (x) == MACHOPIC_UNDEFINED_FUNCTION)
16271 name = machopic_indirection_name (x, /*stub_p=*/true);
16272 #endif
16273 assemble_name (file, name);
16275 else if (!DOT_SYMBOLS)
16276 assemble_name (file, XSTR (x, 0));
16277 else
16278 rs6000_output_function_entry (file, XSTR (x, 0));
16279 return;
16281 case 'Z':
16282 /* Like 'L', for last word of TImode. */
16283 if (GET_CODE (x) == REG)
16284 fputs (reg_names[REGNO (x) + 3], file);
16285 else if (GET_CODE (x) == MEM)
16287 if (GET_CODE (XEXP (x, 0)) == PRE_INC
16288 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
16289 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
16290 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
16291 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
16292 else
16293 output_address (XEXP (adjust_address_nv (x, SImode, 12), 0));
16294 if (small_data_operand (x, GET_MODE (x)))
16295 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
16296 reg_names[SMALL_DATA_REG]);
16298 return;
16300 /* Print AltiVec or SPE memory operand. */
16301 case 'y':
16303 rtx tmp;
16305 gcc_assert (GET_CODE (x) == MEM);
16307 tmp = XEXP (x, 0);
16309 /* Ugly hack because %y is overloaded. */
16310 if ((TARGET_SPE || TARGET_E500_DOUBLE)
16311 && (GET_MODE_SIZE (GET_MODE (x)) == 8
16312 || GET_MODE (x) == TFmode
16313 || GET_MODE (x) == TImode))
16315 /* Handle [reg]. */
16316 if (GET_CODE (tmp) == REG)
16318 fprintf (file, "0(%s)", reg_names[REGNO (tmp)]);
16319 break;
16321 /* Handle [reg+UIMM]. */
16322 else if (GET_CODE (tmp) == PLUS &&
16323 GET_CODE (XEXP (tmp, 1)) == CONST_INT)
16325 int x;
16327 gcc_assert (GET_CODE (XEXP (tmp, 0)) == REG);
16329 x = INTVAL (XEXP (tmp, 1));
16330 fprintf (file, "%d(%s)", x, reg_names[REGNO (XEXP (tmp, 0))]);
16331 break;
16334 /* Fall through. Must be [reg+reg]. */
16336 if (VECTOR_MEM_ALTIVEC_P (GET_MODE (x))
16337 && GET_CODE (tmp) == AND
16338 && GET_CODE (XEXP (tmp, 1)) == CONST_INT
16339 && INTVAL (XEXP (tmp, 1)) == -16)
16340 tmp = XEXP (tmp, 0);
16341 else if (VECTOR_MEM_VSX_P (GET_MODE (x))
16342 && GET_CODE (tmp) == PRE_MODIFY)
16343 tmp = XEXP (tmp, 1);
16344 if (GET_CODE (tmp) == REG)
16345 fprintf (file, "0,%s", reg_names[REGNO (tmp)]);
16346 else
16348 if (!GET_CODE (tmp) == PLUS
16349 || !REG_P (XEXP (tmp, 0))
16350 || !REG_P (XEXP (tmp, 1)))
16352 output_operand_lossage ("invalid %%y value, try using the 'Z' constraint");
16353 break;
16356 if (REGNO (XEXP (tmp, 0)) == 0)
16357 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 1)) ],
16358 reg_names[ REGNO (XEXP (tmp, 0)) ]);
16359 else
16360 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 0)) ],
16361 reg_names[ REGNO (XEXP (tmp, 1)) ]);
16363 break;
16366 case 0:
16367 if (GET_CODE (x) == REG)
16368 fprintf (file, "%s", reg_names[REGNO (x)]);
16369 else if (GET_CODE (x) == MEM)
16371 /* We need to handle PRE_INC and PRE_DEC here, since we need to
16372 know the width from the mode. */
16373 if (GET_CODE (XEXP (x, 0)) == PRE_INC)
16374 fprintf (file, "%d(%s)", GET_MODE_SIZE (GET_MODE (x)),
16375 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
16376 else if (GET_CODE (XEXP (x, 0)) == PRE_DEC)
16377 fprintf (file, "%d(%s)", - GET_MODE_SIZE (GET_MODE (x)),
16378 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
16379 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
16380 output_address (XEXP (XEXP (x, 0), 1));
16381 else
16382 output_address (XEXP (x, 0));
16384 else
16386 if (toc_relative_expr_p (x))
16387 /* This hack along with a corresponding hack in
16388 rs6000_output_addr_const_extra arranges to output addends
16389 where the assembler expects to find them. eg.
16390 (const (plus (unspec [symbol_ref ("x") tocrel]) 4))
16391 without this hack would be output as "x@toc+4". We
16392 want "x+4@toc". */
16393 output_addr_const (file, tocrel_base);
16394 else
16395 output_addr_const (file, x);
16397 return;
16399 case '&':
16400 assemble_name (file, rs6000_get_some_local_dynamic_name ());
16401 return;
16403 default:
16404 output_operand_lossage ("invalid %%xn code");
16408 /* Print the address of an operand. */
16410 void
16411 print_operand_address (FILE *file, rtx x)
16413 if (GET_CODE (x) == REG)
16414 fprintf (file, "0(%s)", reg_names[ REGNO (x) ]);
16415 else if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST
16416 || GET_CODE (x) == LABEL_REF)
16418 output_addr_const (file, x);
16419 if (small_data_operand (x, GET_MODE (x)))
16420 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
16421 reg_names[SMALL_DATA_REG]);
16422 else
16423 gcc_assert (!TARGET_TOC);
16425 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == REG)
16427 gcc_assert (REG_P (XEXP (x, 0)));
16428 if (REGNO (XEXP (x, 0)) == 0)
16429 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 1)) ],
16430 reg_names[ REGNO (XEXP (x, 0)) ]);
16431 else
16432 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 0)) ],
16433 reg_names[ REGNO (XEXP (x, 1)) ]);
16435 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == CONST_INT)
16436 fprintf (file, HOST_WIDE_INT_PRINT_DEC "(%s)",
16437 INTVAL (XEXP (x, 1)), reg_names[ REGNO (XEXP (x, 0)) ]);
16438 #if TARGET_MACHO
16439 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
16440 && CONSTANT_P (XEXP (x, 1)))
16442 fprintf (file, "lo16(");
16443 output_addr_const (file, XEXP (x, 1));
16444 fprintf (file, ")(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
16446 #endif
16447 else if (legitimate_constant_pool_address_p (x, true))
16449 /* This hack along with a corresponding hack in
16450 rs6000_output_addr_const_extra arranges to output addends
16451 where the assembler expects to find them. eg.
16452 (lo_sum (reg 9)
16453 . (const (plus (unspec [symbol_ref ("x") tocrel]) 8)))
16454 without this hack would be output as "x@toc+8@l(9)". We
16455 want "x+8@toc@l(9)". */
16456 output_addr_const (file, tocrel_base);
16457 if (GET_CODE (x) == LO_SUM)
16458 fprintf (file, "@l(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
16459 else
16460 fprintf (file, "(%s)", reg_names[REGNO (XEXP (x, 0))]);
16462 #if TARGET_ELF
16463 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
16464 && CONSTANT_P (XEXP (x, 1)))
16466 output_addr_const (file, XEXP (x, 1));
16467 fprintf (file, "@l(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
16469 #endif
16470 else
16471 gcc_unreachable ();
16474 /* Implement TARGET_OUTPUT_ADDR_CONST_EXTRA. */
16476 static bool
16477 rs6000_output_addr_const_extra (FILE *file, rtx x)
16479 if (GET_CODE (x) == UNSPEC)
16480 switch (XINT (x, 1))
16482 case UNSPEC_TOCREL:
16483 gcc_assert (GET_CODE (XVECEXP (x, 0, 0)) == SYMBOL_REF);
16484 output_addr_const (file, XVECEXP (x, 0, 0));
16485 if (x == tocrel_base && tocrel_offset != const0_rtx)
16487 if (INTVAL (tocrel_offset) >= 0)
16488 fprintf (file, "+");
16489 output_addr_const (file, tocrel_offset);
16491 if (!TARGET_AIX || (TARGET_ELF && TARGET_MINIMAL_TOC))
16493 putc ('-', file);
16494 assemble_name (file, toc_label_name);
16496 else if (TARGET_ELF)
16497 fputs ("@toc", file);
16498 return true;
16500 #if TARGET_MACHO
16501 case UNSPEC_MACHOPIC_OFFSET:
16502 output_addr_const (file, XVECEXP (x, 0, 0));
16503 putc ('-', file);
16504 machopic_output_function_base_name (file);
16505 return true;
16506 #endif
16508 return false;
16511 /* Target hook for assembling integer objects. The PowerPC version has
16512 to handle fixup entries for relocatable code if RELOCATABLE_NEEDS_FIXUP
16513 is defined. It also needs to handle DI-mode objects on 64-bit
16514 targets. */
16516 static bool
16517 rs6000_assemble_integer (rtx x, unsigned int size, int aligned_p)
16519 #ifdef RELOCATABLE_NEEDS_FIXUP
16520 /* Special handling for SI values. */
16521 if (RELOCATABLE_NEEDS_FIXUP && size == 4 && aligned_p)
16523 static int recurse = 0;
16525 /* For -mrelocatable, we mark all addresses that need to be fixed up
16526 in the .fixup section. */
16527 if (TARGET_RELOCATABLE
16528 && in_section != toc_section
16529 && in_section != text_section
16530 && !unlikely_text_section_p (in_section)
16531 && !recurse
16532 && GET_CODE (x) != CONST_INT
16533 && GET_CODE (x) != CONST_DOUBLE
16534 && CONSTANT_P (x))
16536 char buf[256];
16538 recurse = 1;
16539 ASM_GENERATE_INTERNAL_LABEL (buf, "LCP", fixuplabelno);
16540 fixuplabelno++;
16541 ASM_OUTPUT_LABEL (asm_out_file, buf);
16542 fprintf (asm_out_file, "\t.long\t(");
16543 output_addr_const (asm_out_file, x);
16544 fprintf (asm_out_file, ")@fixup\n");
16545 fprintf (asm_out_file, "\t.section\t\".fixup\",\"aw\"\n");
16546 ASM_OUTPUT_ALIGN (asm_out_file, 2);
16547 fprintf (asm_out_file, "\t.long\t");
16548 assemble_name (asm_out_file, buf);
16549 fprintf (asm_out_file, "\n\t.previous\n");
16550 recurse = 0;
16551 return true;
16553 /* Remove initial .'s to turn a -mcall-aixdesc function
16554 address into the address of the descriptor, not the function
16555 itself. */
16556 else if (GET_CODE (x) == SYMBOL_REF
16557 && XSTR (x, 0)[0] == '.'
16558 && DEFAULT_ABI == ABI_AIX)
16560 const char *name = XSTR (x, 0);
16561 while (*name == '.')
16562 name++;
16564 fprintf (asm_out_file, "\t.long\t%s\n", name);
16565 return true;
16568 #endif /* RELOCATABLE_NEEDS_FIXUP */
16569 return default_assemble_integer (x, size, aligned_p);
16572 #ifdef HAVE_GAS_HIDDEN
16573 /* Emit an assembler directive to set symbol visibility for DECL to
16574 VISIBILITY_TYPE. */
16576 static void
16577 rs6000_assemble_visibility (tree decl, int vis)
16579 /* Functions need to have their entry point symbol visibility set as
16580 well as their descriptor symbol visibility. */
16581 if (DEFAULT_ABI == ABI_AIX
16582 && DOT_SYMBOLS
16583 && TREE_CODE (decl) == FUNCTION_DECL)
16585 static const char * const visibility_types[] = {
16586 NULL, "internal", "hidden", "protected"
16589 const char *name, *type;
16591 name = ((* targetm.strip_name_encoding)
16592 (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))));
16593 type = visibility_types[vis];
16595 fprintf (asm_out_file, "\t.%s\t%s\n", type, name);
16596 fprintf (asm_out_file, "\t.%s\t.%s\n", type, name);
16598 else
16599 default_assemble_visibility (decl, vis);
16601 #endif
16603 enum rtx_code
16604 rs6000_reverse_condition (enum machine_mode mode, enum rtx_code code)
16606 /* Reversal of FP compares takes care -- an ordered compare
16607 becomes an unordered compare and vice versa. */
16608 if (mode == CCFPmode
16609 && (!flag_finite_math_only
16610 || code == UNLT || code == UNLE || code == UNGT || code == UNGE
16611 || code == UNEQ || code == LTGT))
16612 return reverse_condition_maybe_unordered (code);
16613 else
16614 return reverse_condition (code);
16617 /* Generate a compare for CODE. Return a brand-new rtx that
16618 represents the result of the compare. */
16620 static rtx
16621 rs6000_generate_compare (rtx cmp, enum machine_mode mode)
16623 enum machine_mode comp_mode;
16624 rtx compare_result;
16625 enum rtx_code code = GET_CODE (cmp);
16626 rtx op0 = XEXP (cmp, 0);
16627 rtx op1 = XEXP (cmp, 1);
16629 if (FLOAT_MODE_P (mode))
16630 comp_mode = CCFPmode;
16631 else if (code == GTU || code == LTU
16632 || code == GEU || code == LEU)
16633 comp_mode = CCUNSmode;
16634 else if ((code == EQ || code == NE)
16635 && GET_CODE (op0) == SUBREG
16636 && GET_CODE (op1) == SUBREG
16637 && SUBREG_PROMOTED_UNSIGNED_P (op0)
16638 && SUBREG_PROMOTED_UNSIGNED_P (op1))
16639 /* These are unsigned values, perhaps there will be a later
16640 ordering compare that can be shared with this one.
16641 Unfortunately we cannot detect the signedness of the operands
16642 for non-subregs. */
16643 comp_mode = CCUNSmode;
16644 else
16645 comp_mode = CCmode;
16647 /* First, the compare. */
16648 compare_result = gen_reg_rtx (comp_mode);
16650 /* E500 FP compare instructions on the GPRs. Yuck! */
16651 if ((!TARGET_FPRS && TARGET_HARD_FLOAT)
16652 && FLOAT_MODE_P (mode))
16654 rtx cmp, or_result, compare_result2;
16655 enum machine_mode op_mode = GET_MODE (op0);
16657 if (op_mode == VOIDmode)
16658 op_mode = GET_MODE (op1);
16660 /* The E500 FP compare instructions toggle the GT bit (CR bit 1) only.
16661 This explains the following mess. */
16663 switch (code)
16665 case EQ: case UNEQ: case NE: case LTGT:
16666 switch (op_mode)
16668 case SFmode:
16669 cmp = (flag_finite_math_only && !flag_trapping_math)
16670 ? gen_tstsfeq_gpr (compare_result, op0, op1)
16671 : gen_cmpsfeq_gpr (compare_result, op0, op1);
16672 break;
16674 case DFmode:
16675 cmp = (flag_finite_math_only && !flag_trapping_math)
16676 ? gen_tstdfeq_gpr (compare_result, op0, op1)
16677 : gen_cmpdfeq_gpr (compare_result, op0, op1);
16678 break;
16680 case TFmode:
16681 cmp = (flag_finite_math_only && !flag_trapping_math)
16682 ? gen_tsttfeq_gpr (compare_result, op0, op1)
16683 : gen_cmptfeq_gpr (compare_result, op0, op1);
16684 break;
16686 default:
16687 gcc_unreachable ();
16689 break;
16691 case GT: case GTU: case UNGT: case UNGE: case GE: case GEU:
16692 switch (op_mode)
16694 case SFmode:
16695 cmp = (flag_finite_math_only && !flag_trapping_math)
16696 ? gen_tstsfgt_gpr (compare_result, op0, op1)
16697 : gen_cmpsfgt_gpr (compare_result, op0, op1);
16698 break;
16700 case DFmode:
16701 cmp = (flag_finite_math_only && !flag_trapping_math)
16702 ? gen_tstdfgt_gpr (compare_result, op0, op1)
16703 : gen_cmpdfgt_gpr (compare_result, op0, op1);
16704 break;
16706 case TFmode:
16707 cmp = (flag_finite_math_only && !flag_trapping_math)
16708 ? gen_tsttfgt_gpr (compare_result, op0, op1)
16709 : gen_cmptfgt_gpr (compare_result, op0, op1);
16710 break;
16712 default:
16713 gcc_unreachable ();
16715 break;
16717 case LT: case LTU: case UNLT: case UNLE: case LE: case LEU:
16718 switch (op_mode)
16720 case SFmode:
16721 cmp = (flag_finite_math_only && !flag_trapping_math)
16722 ? gen_tstsflt_gpr (compare_result, op0, op1)
16723 : gen_cmpsflt_gpr (compare_result, op0, op1);
16724 break;
16726 case DFmode:
16727 cmp = (flag_finite_math_only && !flag_trapping_math)
16728 ? gen_tstdflt_gpr (compare_result, op0, op1)
16729 : gen_cmpdflt_gpr (compare_result, op0, op1);
16730 break;
16732 case TFmode:
16733 cmp = (flag_finite_math_only && !flag_trapping_math)
16734 ? gen_tsttflt_gpr (compare_result, op0, op1)
16735 : gen_cmptflt_gpr (compare_result, op0, op1);
16736 break;
16738 default:
16739 gcc_unreachable ();
16741 break;
16742 default:
16743 gcc_unreachable ();
16746 /* Synthesize LE and GE from LT/GT || EQ. */
16747 if (code == LE || code == GE || code == LEU || code == GEU)
16749 emit_insn (cmp);
16751 switch (code)
16753 case LE: code = LT; break;
16754 case GE: code = GT; break;
16755 case LEU: code = LT; break;
16756 case GEU: code = GT; break;
16757 default: gcc_unreachable ();
16760 compare_result2 = gen_reg_rtx (CCFPmode);
16762 /* Do the EQ. */
16763 switch (op_mode)
16765 case SFmode:
16766 cmp = (flag_finite_math_only && !flag_trapping_math)
16767 ? gen_tstsfeq_gpr (compare_result2, op0, op1)
16768 : gen_cmpsfeq_gpr (compare_result2, op0, op1);
16769 break;
16771 case DFmode:
16772 cmp = (flag_finite_math_only && !flag_trapping_math)
16773 ? gen_tstdfeq_gpr (compare_result2, op0, op1)
16774 : gen_cmpdfeq_gpr (compare_result2, op0, op1);
16775 break;
16777 case TFmode:
16778 cmp = (flag_finite_math_only && !flag_trapping_math)
16779 ? gen_tsttfeq_gpr (compare_result2, op0, op1)
16780 : gen_cmptfeq_gpr (compare_result2, op0, op1);
16781 break;
16783 default:
16784 gcc_unreachable ();
16786 emit_insn (cmp);
16788 /* OR them together. */
16789 or_result = gen_reg_rtx (CCFPmode);
16790 cmp = gen_e500_cr_ior_compare (or_result, compare_result,
16791 compare_result2);
16792 compare_result = or_result;
16793 code = EQ;
16795 else
16797 if (code == NE || code == LTGT)
16798 code = NE;
16799 else
16800 code = EQ;
16803 emit_insn (cmp);
16805 else
16807 /* Generate XLC-compatible TFmode compare as PARALLEL with extra
16808 CLOBBERs to match cmptf_internal2 pattern. */
16809 if (comp_mode == CCFPmode && TARGET_XL_COMPAT
16810 && GET_MODE (op0) == TFmode
16811 && !TARGET_IEEEQUAD
16812 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128)
16813 emit_insn (gen_rtx_PARALLEL (VOIDmode,
16814 gen_rtvec (10,
16815 gen_rtx_SET (VOIDmode,
16816 compare_result,
16817 gen_rtx_COMPARE (comp_mode, op0, op1)),
16818 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16819 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16820 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16821 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16822 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16823 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16824 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16825 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16826 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (Pmode)))));
16827 else if (GET_CODE (op1) == UNSPEC
16828 && XINT (op1, 1) == UNSPEC_SP_TEST)
16830 rtx op1b = XVECEXP (op1, 0, 0);
16831 comp_mode = CCEQmode;
16832 compare_result = gen_reg_rtx (CCEQmode);
16833 if (TARGET_64BIT)
16834 emit_insn (gen_stack_protect_testdi (compare_result, op0, op1b));
16835 else
16836 emit_insn (gen_stack_protect_testsi (compare_result, op0, op1b));
16838 else
16839 emit_insn (gen_rtx_SET (VOIDmode, compare_result,
16840 gen_rtx_COMPARE (comp_mode, op0, op1)));
16843 /* Some kinds of FP comparisons need an OR operation;
16844 under flag_finite_math_only we don't bother. */
16845 if (FLOAT_MODE_P (mode)
16846 && !flag_finite_math_only
16847 && !(TARGET_HARD_FLOAT && !TARGET_FPRS)
16848 && (code == LE || code == GE
16849 || code == UNEQ || code == LTGT
16850 || code == UNGT || code == UNLT))
16852 enum rtx_code or1, or2;
16853 rtx or1_rtx, or2_rtx, compare2_rtx;
16854 rtx or_result = gen_reg_rtx (CCEQmode);
16856 switch (code)
16858 case LE: or1 = LT; or2 = EQ; break;
16859 case GE: or1 = GT; or2 = EQ; break;
16860 case UNEQ: or1 = UNORDERED; or2 = EQ; break;
16861 case LTGT: or1 = LT; or2 = GT; break;
16862 case UNGT: or1 = UNORDERED; or2 = GT; break;
16863 case UNLT: or1 = UNORDERED; or2 = LT; break;
16864 default: gcc_unreachable ();
16866 validate_condition_mode (or1, comp_mode);
16867 validate_condition_mode (or2, comp_mode);
16868 or1_rtx = gen_rtx_fmt_ee (or1, SImode, compare_result, const0_rtx);
16869 or2_rtx = gen_rtx_fmt_ee (or2, SImode, compare_result, const0_rtx);
16870 compare2_rtx = gen_rtx_COMPARE (CCEQmode,
16871 gen_rtx_IOR (SImode, or1_rtx, or2_rtx),
16872 const_true_rtx);
16873 emit_insn (gen_rtx_SET (VOIDmode, or_result, compare2_rtx));
16875 compare_result = or_result;
16876 code = EQ;
16879 validate_condition_mode (code, GET_MODE (compare_result));
16881 return gen_rtx_fmt_ee (code, VOIDmode, compare_result, const0_rtx);
16885 /* Emit the RTL for an sISEL pattern. */
16887 void
16888 rs6000_emit_sISEL (enum machine_mode mode ATTRIBUTE_UNUSED, rtx operands[])
16890 rs6000_emit_int_cmove (operands[0], operands[1], const1_rtx, const0_rtx);
16893 void
16894 rs6000_emit_sCOND (enum machine_mode mode, rtx operands[])
16896 rtx condition_rtx;
16897 enum machine_mode op_mode;
16898 enum rtx_code cond_code;
16899 rtx result = operands[0];
16901 if (TARGET_ISEL && (mode == SImode || mode == DImode))
16903 rs6000_emit_sISEL (mode, operands);
16904 return;
16907 condition_rtx = rs6000_generate_compare (operands[1], mode);
16908 cond_code = GET_CODE (condition_rtx);
16910 if (FLOAT_MODE_P (mode)
16911 && !TARGET_FPRS && TARGET_HARD_FLOAT)
16913 rtx t;
16915 PUT_MODE (condition_rtx, SImode);
16916 t = XEXP (condition_rtx, 0);
16918 gcc_assert (cond_code == NE || cond_code == EQ);
16920 if (cond_code == NE)
16921 emit_insn (gen_e500_flip_gt_bit (t, t));
16923 emit_insn (gen_move_from_CR_gt_bit (result, t));
16924 return;
16927 if (cond_code == NE
16928 || cond_code == GE || cond_code == LE
16929 || cond_code == GEU || cond_code == LEU
16930 || cond_code == ORDERED || cond_code == UNGE || cond_code == UNLE)
16932 rtx not_result = gen_reg_rtx (CCEQmode);
16933 rtx not_op, rev_cond_rtx;
16934 enum machine_mode cc_mode;
16936 cc_mode = GET_MODE (XEXP (condition_rtx, 0));
16938 rev_cond_rtx = gen_rtx_fmt_ee (rs6000_reverse_condition (cc_mode, cond_code),
16939 SImode, XEXP (condition_rtx, 0), const0_rtx);
16940 not_op = gen_rtx_COMPARE (CCEQmode, rev_cond_rtx, const0_rtx);
16941 emit_insn (gen_rtx_SET (VOIDmode, not_result, not_op));
16942 condition_rtx = gen_rtx_EQ (VOIDmode, not_result, const0_rtx);
16945 op_mode = GET_MODE (XEXP (operands[1], 0));
16946 if (op_mode == VOIDmode)
16947 op_mode = GET_MODE (XEXP (operands[1], 1));
16949 if (TARGET_POWERPC64 && (op_mode == DImode || FLOAT_MODE_P (mode)))
16951 PUT_MODE (condition_rtx, DImode);
16952 convert_move (result, condition_rtx, 0);
16954 else
16956 PUT_MODE (condition_rtx, SImode);
16957 emit_insn (gen_rtx_SET (VOIDmode, result, condition_rtx));
16961 /* Emit a branch of kind CODE to location LOC. */
16963 void
16964 rs6000_emit_cbranch (enum machine_mode mode, rtx operands[])
16966 rtx condition_rtx, loc_ref;
16968 condition_rtx = rs6000_generate_compare (operands[0], mode);
16969 loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands[3]);
16970 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
16971 gen_rtx_IF_THEN_ELSE (VOIDmode, condition_rtx,
16972 loc_ref, pc_rtx)));
16975 /* Return the string to output a conditional branch to LABEL, which is
16976 the operand number of the label, or -1 if the branch is really a
16977 conditional return.
16979 OP is the conditional expression. XEXP (OP, 0) is assumed to be a
16980 condition code register and its mode specifies what kind of
16981 comparison we made.
16983 REVERSED is nonzero if we should reverse the sense of the comparison.
16985 INSN is the insn. */
16987 char *
16988 output_cbranch (rtx op, const char *label, int reversed, rtx insn)
16990 static char string[64];
16991 enum rtx_code code = GET_CODE (op);
16992 rtx cc_reg = XEXP (op, 0);
16993 enum machine_mode mode = GET_MODE (cc_reg);
16994 int cc_regno = REGNO (cc_reg) - CR0_REGNO;
16995 int need_longbranch = label != NULL && get_attr_length (insn) == 8;
16996 int really_reversed = reversed ^ need_longbranch;
16997 char *s = string;
16998 const char *ccode;
16999 const char *pred;
17000 rtx note;
17002 validate_condition_mode (code, mode);
17004 /* Work out which way this really branches. We could use
17005 reverse_condition_maybe_unordered here always but this
17006 makes the resulting assembler clearer. */
17007 if (really_reversed)
17009 /* Reversal of FP compares takes care -- an ordered compare
17010 becomes an unordered compare and vice versa. */
17011 if (mode == CCFPmode)
17012 code = reverse_condition_maybe_unordered (code);
17013 else
17014 code = reverse_condition (code);
17017 if ((!TARGET_FPRS && TARGET_HARD_FLOAT) && mode == CCFPmode)
17019 /* The efscmp/tst* instructions twiddle bit 2, which maps nicely
17020 to the GT bit. */
17021 switch (code)
17023 case EQ:
17024 /* Opposite of GT. */
17025 code = GT;
17026 break;
17028 case NE:
17029 code = UNLE;
17030 break;
17032 default:
17033 gcc_unreachable ();
17037 switch (code)
17039 /* Not all of these are actually distinct opcodes, but
17040 we distinguish them for clarity of the resulting assembler. */
17041 case NE: case LTGT:
17042 ccode = "ne"; break;
17043 case EQ: case UNEQ:
17044 ccode = "eq"; break;
17045 case GE: case GEU:
17046 ccode = "ge"; break;
17047 case GT: case GTU: case UNGT:
17048 ccode = "gt"; break;
17049 case LE: case LEU:
17050 ccode = "le"; break;
17051 case LT: case LTU: case UNLT:
17052 ccode = "lt"; break;
17053 case UNORDERED: ccode = "un"; break;
17054 case ORDERED: ccode = "nu"; break;
17055 case UNGE: ccode = "nl"; break;
17056 case UNLE: ccode = "ng"; break;
17057 default:
17058 gcc_unreachable ();
17061 /* Maybe we have a guess as to how likely the branch is.
17062 The old mnemonics don't have a way to specify this information. */
17063 pred = "";
17064 note = find_reg_note (insn, REG_BR_PROB, NULL_RTX);
17065 if (note != NULL_RTX)
17067 /* PROB is the difference from 50%. */
17068 int prob = INTVAL (XEXP (note, 0)) - REG_BR_PROB_BASE / 2;
17070 /* Only hint for highly probable/improbable branches on newer
17071 cpus as static prediction overrides processor dynamic
17072 prediction. For older cpus we may as well always hint, but
17073 assume not taken for branches that are very close to 50% as a
17074 mispredicted taken branch is more expensive than a
17075 mispredicted not-taken branch. */
17076 if (rs6000_always_hint
17077 || (abs (prob) > REG_BR_PROB_BASE / 100 * 48
17078 && br_prob_note_reliable_p (note)))
17080 if (abs (prob) > REG_BR_PROB_BASE / 20
17081 && ((prob > 0) ^ need_longbranch))
17082 pred = "+";
17083 else
17084 pred = "-";
17088 if (label == NULL)
17089 s += sprintf (s, "{b%sr|b%slr%s} ", ccode, ccode, pred);
17090 else
17091 s += sprintf (s, "{b%s|b%s%s} ", ccode, ccode, pred);
17093 /* We need to escape any '%' characters in the reg_names string.
17094 Assume they'd only be the first character.... */
17095 if (reg_names[cc_regno + CR0_REGNO][0] == '%')
17096 *s++ = '%';
17097 s += sprintf (s, "%s", reg_names[cc_regno + CR0_REGNO]);
17099 if (label != NULL)
17101 /* If the branch distance was too far, we may have to use an
17102 unconditional branch to go the distance. */
17103 if (need_longbranch)
17104 s += sprintf (s, ",$+8\n\tb %s", label);
17105 else
17106 s += sprintf (s, ",%s", label);
17109 return string;
17112 /* Return the string to flip the GT bit on a CR. */
17113 char *
17114 output_e500_flip_gt_bit (rtx dst, rtx src)
17116 static char string[64];
17117 int a, b;
17119 gcc_assert (GET_CODE (dst) == REG && CR_REGNO_P (REGNO (dst))
17120 && GET_CODE (src) == REG && CR_REGNO_P (REGNO (src)));
17122 /* GT bit. */
17123 a = 4 * (REGNO (dst) - CR0_REGNO) + 1;
17124 b = 4 * (REGNO (src) - CR0_REGNO) + 1;
17126 sprintf (string, "crnot %d,%d", a, b);
17127 return string;
17130 /* Return insn for VSX or Altivec comparisons. */
17132 static rtx
17133 rs6000_emit_vector_compare_inner (enum rtx_code code, rtx op0, rtx op1)
17135 rtx mask;
17136 enum machine_mode mode = GET_MODE (op0);
17138 switch (code)
17140 default:
17141 break;
17143 case GE:
17144 if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
17145 return NULL_RTX;
17147 case EQ:
17148 case GT:
17149 case GTU:
17150 mask = gen_reg_rtx (mode);
17151 emit_insn (gen_rtx_SET (VOIDmode,
17152 mask,
17153 gen_rtx_fmt_ee (code, mode, op0, op1)));
17154 return mask;
17157 return NULL_RTX;
17160 /* Emit vector compare for operands OP0 and OP1 using code RCODE.
17161 DMODE is expected destination mode. This is a recursive function. */
17163 static rtx
17164 rs6000_emit_vector_compare (enum rtx_code rcode,
17165 rtx op0, rtx op1,
17166 enum machine_mode dmode)
17168 rtx mask;
17169 bool swap_operands = false;
17170 bool try_again = false;
17172 gcc_assert (VECTOR_UNIT_ALTIVEC_OR_VSX_P (dmode));
17173 gcc_assert (GET_MODE (op0) == GET_MODE (op1));
17175 /* See if the comparison works as is. */
17176 mask = rs6000_emit_vector_compare_inner (rcode, op0, op1);
17177 if (mask)
17178 return mask;
17180 switch (rcode)
17182 case LT:
17183 rcode = GT;
17184 swap_operands = true;
17185 try_again = true;
17186 break;
17187 case LTU:
17188 rcode = GTU;
17189 swap_operands = true;
17190 try_again = true;
17191 break;
17192 case NE:
17193 case UNLE:
17194 case UNLT:
17195 case UNGE:
17196 case UNGT:
17197 /* Invert condition and try again.
17198 e.g., A != B becomes ~(A==B). */
17200 enum rtx_code rev_code;
17201 enum insn_code nor_code;
17202 rtx mask2;
17204 rev_code = reverse_condition_maybe_unordered (rcode);
17205 if (rev_code == UNKNOWN)
17206 return NULL_RTX;
17208 nor_code = optab_handler (one_cmpl_optab, dmode);
17209 if (nor_code == CODE_FOR_nothing)
17210 return NULL_RTX;
17212 mask2 = rs6000_emit_vector_compare (rev_code, op0, op1, dmode);
17213 if (!mask2)
17214 return NULL_RTX;
17216 mask = gen_reg_rtx (dmode);
17217 emit_insn (GEN_FCN (nor_code) (mask, mask2));
17218 return mask;
17220 break;
17221 case GE:
17222 case GEU:
17223 case LE:
17224 case LEU:
17225 /* Try GT/GTU/LT/LTU OR EQ */
17227 rtx c_rtx, eq_rtx;
17228 enum insn_code ior_code;
17229 enum rtx_code new_code;
17231 switch (rcode)
17233 case GE:
17234 new_code = GT;
17235 break;
17237 case GEU:
17238 new_code = GTU;
17239 break;
17241 case LE:
17242 new_code = LT;
17243 break;
17245 case LEU:
17246 new_code = LTU;
17247 break;
17249 default:
17250 gcc_unreachable ();
17253 ior_code = optab_handler (ior_optab, dmode);
17254 if (ior_code == CODE_FOR_nothing)
17255 return NULL_RTX;
17257 c_rtx = rs6000_emit_vector_compare (new_code, op0, op1, dmode);
17258 if (!c_rtx)
17259 return NULL_RTX;
17261 eq_rtx = rs6000_emit_vector_compare (EQ, op0, op1, dmode);
17262 if (!eq_rtx)
17263 return NULL_RTX;
17265 mask = gen_reg_rtx (dmode);
17266 emit_insn (GEN_FCN (ior_code) (mask, c_rtx, eq_rtx));
17267 return mask;
17269 break;
17270 default:
17271 return NULL_RTX;
17274 if (try_again)
17276 if (swap_operands)
17278 rtx tmp;
17279 tmp = op0;
17280 op0 = op1;
17281 op1 = tmp;
17284 mask = rs6000_emit_vector_compare_inner (rcode, op0, op1);
17285 if (mask)
17286 return mask;
17289 /* You only get two chances. */
17290 return NULL_RTX;
17293 /* Emit vector conditional expression. DEST is destination. OP_TRUE and
17294 OP_FALSE are two VEC_COND_EXPR operands. CC_OP0 and CC_OP1 are the two
17295 operands for the relation operation COND. */
17298 rs6000_emit_vector_cond_expr (rtx dest, rtx op_true, rtx op_false,
17299 rtx cond, rtx cc_op0, rtx cc_op1)
17301 enum machine_mode dest_mode = GET_MODE (dest);
17302 enum rtx_code rcode = GET_CODE (cond);
17303 enum machine_mode cc_mode = CCmode;
17304 rtx mask;
17305 rtx cond2;
17306 rtx tmp;
17307 bool invert_move = false;
17309 if (VECTOR_UNIT_NONE_P (dest_mode))
17310 return 0;
17312 switch (rcode)
17314 /* Swap operands if we can, and fall back to doing the operation as
17315 specified, and doing a NOR to invert the test. */
17316 case NE:
17317 case UNLE:
17318 case UNLT:
17319 case UNGE:
17320 case UNGT:
17321 /* Invert condition and try again.
17322 e.g., A = (B != C) ? D : E becomes A = (B == C) ? E : D. */
17323 invert_move = true;
17324 rcode = reverse_condition_maybe_unordered (rcode);
17325 if (rcode == UNKNOWN)
17326 return 0;
17327 break;
17329 /* Mark unsigned tests with CCUNSmode. */
17330 case GTU:
17331 case GEU:
17332 case LTU:
17333 case LEU:
17334 cc_mode = CCUNSmode;
17335 break;
17337 default:
17338 break;
17341 /* Get the vector mask for the given relational operations. */
17342 mask = rs6000_emit_vector_compare (rcode, cc_op0, cc_op1, dest_mode);
17344 if (!mask)
17345 return 0;
17347 if (invert_move)
17349 tmp = op_true;
17350 op_true = op_false;
17351 op_false = tmp;
17354 cond2 = gen_rtx_fmt_ee (NE, cc_mode, mask, const0_rtx);
17355 emit_insn (gen_rtx_SET (VOIDmode,
17356 dest,
17357 gen_rtx_IF_THEN_ELSE (dest_mode,
17358 cond2,
17359 op_true,
17360 op_false)));
17361 return 1;
17364 /* Emit a conditional move: move TRUE_COND to DEST if OP of the
17365 operands of the last comparison is nonzero/true, FALSE_COND if it
17366 is zero/false. Return 0 if the hardware has no such operation. */
17369 rs6000_emit_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
17371 enum rtx_code code = GET_CODE (op);
17372 rtx op0 = XEXP (op, 0);
17373 rtx op1 = XEXP (op, 1);
17374 REAL_VALUE_TYPE c1;
17375 enum machine_mode compare_mode = GET_MODE (op0);
17376 enum machine_mode result_mode = GET_MODE (dest);
17377 rtx temp;
17378 bool is_against_zero;
17380 /* These modes should always match. */
17381 if (GET_MODE (op1) != compare_mode
17382 /* In the isel case however, we can use a compare immediate, so
17383 op1 may be a small constant. */
17384 && (!TARGET_ISEL || !short_cint_operand (op1, VOIDmode)))
17385 return 0;
17386 if (GET_MODE (true_cond) != result_mode)
17387 return 0;
17388 if (GET_MODE (false_cond) != result_mode)
17389 return 0;
17391 /* First, work out if the hardware can do this at all, or
17392 if it's too slow.... */
17393 if (!FLOAT_MODE_P (compare_mode))
17395 if (TARGET_ISEL)
17396 return rs6000_emit_int_cmove (dest, op, true_cond, false_cond);
17397 return 0;
17399 else if (TARGET_HARD_FLOAT && !TARGET_FPRS
17400 && SCALAR_FLOAT_MODE_P (compare_mode))
17401 return 0;
17403 is_against_zero = op1 == CONST0_RTX (compare_mode);
17405 /* A floating-point subtract might overflow, underflow, or produce
17406 an inexact result, thus changing the floating-point flags, so it
17407 can't be generated if we care about that. It's safe if one side
17408 of the construct is zero, since then no subtract will be
17409 generated. */
17410 if (SCALAR_FLOAT_MODE_P (compare_mode)
17411 && flag_trapping_math && ! is_against_zero)
17412 return 0;
17414 /* Eliminate half of the comparisons by switching operands, this
17415 makes the remaining code simpler. */
17416 if (code == UNLT || code == UNGT || code == UNORDERED || code == NE
17417 || code == LTGT || code == LT || code == UNLE)
17419 code = reverse_condition_maybe_unordered (code);
17420 temp = true_cond;
17421 true_cond = false_cond;
17422 false_cond = temp;
17425 /* UNEQ and LTGT take four instructions for a comparison with zero,
17426 it'll probably be faster to use a branch here too. */
17427 if (code == UNEQ && HONOR_NANS (compare_mode))
17428 return 0;
17430 if (GET_CODE (op1) == CONST_DOUBLE)
17431 REAL_VALUE_FROM_CONST_DOUBLE (c1, op1);
17433 /* We're going to try to implement comparisons by performing
17434 a subtract, then comparing against zero. Unfortunately,
17435 Inf - Inf is NaN which is not zero, and so if we don't
17436 know that the operand is finite and the comparison
17437 would treat EQ different to UNORDERED, we can't do it. */
17438 if (HONOR_INFINITIES (compare_mode)
17439 && code != GT && code != UNGE
17440 && (GET_CODE (op1) != CONST_DOUBLE || real_isinf (&c1))
17441 /* Constructs of the form (a OP b ? a : b) are safe. */
17442 && ((! rtx_equal_p (op0, false_cond) && ! rtx_equal_p (op1, false_cond))
17443 || (! rtx_equal_p (op0, true_cond)
17444 && ! rtx_equal_p (op1, true_cond))))
17445 return 0;
17447 /* At this point we know we can use fsel. */
17449 /* Reduce the comparison to a comparison against zero. */
17450 if (! is_against_zero)
17452 temp = gen_reg_rtx (compare_mode);
17453 emit_insn (gen_rtx_SET (VOIDmode, temp,
17454 gen_rtx_MINUS (compare_mode, op0, op1)));
17455 op0 = temp;
17456 op1 = CONST0_RTX (compare_mode);
17459 /* If we don't care about NaNs we can reduce some of the comparisons
17460 down to faster ones. */
17461 if (! HONOR_NANS (compare_mode))
17462 switch (code)
17464 case GT:
17465 code = LE;
17466 temp = true_cond;
17467 true_cond = false_cond;
17468 false_cond = temp;
17469 break;
17470 case UNGE:
17471 code = GE;
17472 break;
17473 case UNEQ:
17474 code = EQ;
17475 break;
17476 default:
17477 break;
17480 /* Now, reduce everything down to a GE. */
17481 switch (code)
17483 case GE:
17484 break;
17486 case LE:
17487 temp = gen_reg_rtx (compare_mode);
17488 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
17489 op0 = temp;
17490 break;
17492 case ORDERED:
17493 temp = gen_reg_rtx (compare_mode);
17494 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_ABS (compare_mode, op0)));
17495 op0 = temp;
17496 break;
17498 case EQ:
17499 temp = gen_reg_rtx (compare_mode);
17500 emit_insn (gen_rtx_SET (VOIDmode, temp,
17501 gen_rtx_NEG (compare_mode,
17502 gen_rtx_ABS (compare_mode, op0))));
17503 op0 = temp;
17504 break;
17506 case UNGE:
17507 /* a UNGE 0 <-> (a GE 0 || -a UNLT 0) */
17508 temp = gen_reg_rtx (result_mode);
17509 emit_insn (gen_rtx_SET (VOIDmode, temp,
17510 gen_rtx_IF_THEN_ELSE (result_mode,
17511 gen_rtx_GE (VOIDmode,
17512 op0, op1),
17513 true_cond, false_cond)));
17514 false_cond = true_cond;
17515 true_cond = temp;
17517 temp = gen_reg_rtx (compare_mode);
17518 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
17519 op0 = temp;
17520 break;
17522 case GT:
17523 /* a GT 0 <-> (a GE 0 && -a UNLT 0) */
17524 temp = gen_reg_rtx (result_mode);
17525 emit_insn (gen_rtx_SET (VOIDmode, temp,
17526 gen_rtx_IF_THEN_ELSE (result_mode,
17527 gen_rtx_GE (VOIDmode,
17528 op0, op1),
17529 true_cond, false_cond)));
17530 true_cond = false_cond;
17531 false_cond = temp;
17533 temp = gen_reg_rtx (compare_mode);
17534 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
17535 op0 = temp;
17536 break;
17538 default:
17539 gcc_unreachable ();
17542 emit_insn (gen_rtx_SET (VOIDmode, dest,
17543 gen_rtx_IF_THEN_ELSE (result_mode,
17544 gen_rtx_GE (VOIDmode,
17545 op0, op1),
17546 true_cond, false_cond)));
17547 return 1;
17550 /* Same as above, but for ints (isel). */
17552 static int
17553 rs6000_emit_int_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
17555 rtx condition_rtx, cr;
17556 enum machine_mode mode = GET_MODE (dest);
17557 enum rtx_code cond_code;
17558 rtx (*isel_func) (rtx, rtx, rtx, rtx, rtx);
17559 bool signedp;
17561 if (mode != SImode && (!TARGET_POWERPC64 || mode != DImode))
17562 return 0;
17564 /* We still have to do the compare, because isel doesn't do a
17565 compare, it just looks at the CRx bits set by a previous compare
17566 instruction. */
17567 condition_rtx = rs6000_generate_compare (op, mode);
17568 cond_code = GET_CODE (condition_rtx);
17569 cr = XEXP (condition_rtx, 0);
17570 signedp = GET_MODE (cr) == CCmode;
17572 isel_func = (mode == SImode
17573 ? (signedp ? gen_isel_signed_si : gen_isel_unsigned_si)
17574 : (signedp ? gen_isel_signed_di : gen_isel_unsigned_di));
17576 switch (cond_code)
17578 case LT: case GT: case LTU: case GTU: case EQ:
17579 /* isel handles these directly. */
17580 break;
17582 default:
17583 /* We need to swap the sense of the comparison. */
17585 rtx t = true_cond;
17586 true_cond = false_cond;
17587 false_cond = t;
17588 PUT_CODE (condition_rtx, reverse_condition (cond_code));
17590 break;
17593 false_cond = force_reg (mode, false_cond);
17594 if (true_cond != const0_rtx)
17595 true_cond = force_reg (mode, true_cond);
17597 emit_insn (isel_func (dest, condition_rtx, true_cond, false_cond, cr));
17599 return 1;
17602 const char *
17603 output_isel (rtx *operands)
17605 enum rtx_code code;
17607 code = GET_CODE (operands[1]);
17609 if (code == GE || code == GEU || code == LE || code == LEU || code == NE)
17611 gcc_assert (GET_CODE (operands[2]) == REG
17612 && GET_CODE (operands[3]) == REG);
17613 PUT_CODE (operands[1], reverse_condition (code));
17614 return "isel %0,%3,%2,%j1";
17617 return "isel %0,%2,%3,%j1";
17620 void
17621 rs6000_emit_minmax (rtx dest, enum rtx_code code, rtx op0, rtx op1)
17623 enum machine_mode mode = GET_MODE (op0);
17624 enum rtx_code c;
17625 rtx target;
17627 /* VSX/altivec have direct min/max insns. */
17628 if ((code == SMAX || code == SMIN)
17629 && (VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode)
17630 || (mode == SFmode && VECTOR_UNIT_VSX_P (DFmode))))
17632 emit_insn (gen_rtx_SET (VOIDmode,
17633 dest,
17634 gen_rtx_fmt_ee (code, mode, op0, op1)));
17635 return;
17638 if (code == SMAX || code == SMIN)
17639 c = GE;
17640 else
17641 c = GEU;
17643 if (code == SMAX || code == UMAX)
17644 target = emit_conditional_move (dest, c, op0, op1, mode,
17645 op0, op1, mode, 0);
17646 else
17647 target = emit_conditional_move (dest, c, op0, op1, mode,
17648 op1, op0, mode, 0);
17649 gcc_assert (target);
17650 if (target != dest)
17651 emit_move_insn (dest, target);
17654 /* Emit instructions to perform a load-reserved/store-conditional operation.
17655 The operation performed is an atomic
17656 (set M (CODE:MODE M OP))
17657 If not NULL, BEFORE is atomically set to M before the operation, and
17658 AFTER is set to M after the operation (that is, (CODE:MODE M OP)).
17659 If SYNC_P then a memory barrier is emitted before the operation.
17660 Either OP or M may be wrapped in a NOT operation. */
17662 void
17663 rs6000_emit_sync (enum rtx_code code, enum machine_mode mode,
17664 rtx m, rtx op, rtx before_param, rtx after_param,
17665 bool sync_p)
17667 enum machine_mode used_mode;
17668 rtx the_op, set_before, set_after, set_atomic, cc_scratch, before, after;
17669 rtx used_m;
17670 rtvec vec;
17671 HOST_WIDE_INT imask = GET_MODE_MASK (mode);
17672 rtx shift = NULL_RTX;
17674 if (sync_p)
17675 emit_insn (gen_lwsync ());
17677 used_m = m;
17679 /* If this is smaller than SImode, we'll have to use SImode with
17680 adjustments. */
17681 if (mode == QImode || mode == HImode)
17683 rtx newop, oldop;
17685 if (MEM_ALIGN (used_m) >= 32)
17687 int ishift = 0;
17688 if (BYTES_BIG_ENDIAN)
17689 ishift = GET_MODE_BITSIZE (SImode) - GET_MODE_BITSIZE (mode);
17691 shift = GEN_INT (ishift);
17692 used_m = change_address (used_m, SImode, 0);
17694 else
17696 rtx addrSI, aligned_addr;
17697 int shift_mask = mode == QImode ? 0x18 : 0x10;
17699 addrSI = gen_lowpart_common (SImode,
17700 force_reg (Pmode, XEXP (used_m, 0)));
17701 addrSI = force_reg (SImode, addrSI);
17702 shift = gen_reg_rtx (SImode);
17704 emit_insn (gen_rlwinm (shift, addrSI, GEN_INT (3),
17705 GEN_INT (shift_mask)));
17706 emit_insn (gen_xorsi3 (shift, shift, GEN_INT (shift_mask)));
17708 aligned_addr = expand_binop (Pmode, and_optab,
17709 XEXP (used_m, 0),
17710 GEN_INT (-4), NULL_RTX,
17711 1, OPTAB_LIB_WIDEN);
17712 used_m = change_address (used_m, SImode, aligned_addr);
17713 set_mem_align (used_m, 32);
17715 /* It's safe to keep the old alias set of USED_M, because
17716 the operation is atomic and only affects the original
17717 USED_M. */
17718 m = used_m;
17720 if (GET_CODE (op) == NOT)
17722 oldop = lowpart_subreg (SImode, XEXP (op, 0), mode);
17723 oldop = gen_rtx_NOT (SImode, oldop);
17725 else
17726 oldop = lowpart_subreg (SImode, op, mode);
17728 switch (code)
17730 case IOR:
17731 case XOR:
17732 newop = expand_binop (SImode, and_optab,
17733 oldop, GEN_INT (imask), NULL_RTX,
17734 1, OPTAB_LIB_WIDEN);
17735 emit_insn (gen_ashlsi3 (newop, newop, shift));
17736 break;
17738 case NOT: /* NAND */
17739 newop = expand_binop (SImode, ior_optab,
17740 oldop, GEN_INT (~imask), NULL_RTX,
17741 1, OPTAB_LIB_WIDEN);
17742 emit_insn (gen_rotlsi3 (newop, newop, shift));
17743 break;
17745 case AND:
17746 newop = expand_binop (SImode, ior_optab,
17747 oldop, GEN_INT (~imask), NULL_RTX,
17748 1, OPTAB_LIB_WIDEN);
17749 emit_insn (gen_rotlsi3 (newop, newop, shift));
17750 break;
17752 case PLUS:
17753 case MINUS:
17755 rtx mask;
17757 newop = expand_binop (SImode, and_optab,
17758 oldop, GEN_INT (imask), NULL_RTX,
17759 1, OPTAB_LIB_WIDEN);
17760 emit_insn (gen_ashlsi3 (newop, newop, shift));
17762 mask = gen_reg_rtx (SImode);
17763 emit_move_insn (mask, GEN_INT (imask));
17764 emit_insn (gen_ashlsi3 (mask, mask, shift));
17766 if (code == PLUS)
17767 newop = gen_rtx_PLUS (SImode, m, newop);
17768 else
17769 newop = gen_rtx_MINUS (SImode, m, newop);
17770 newop = gen_rtx_AND (SImode, newop, mask);
17771 newop = gen_rtx_IOR (SImode, newop,
17772 gen_rtx_AND (SImode,
17773 gen_rtx_NOT (SImode, mask),
17774 m));
17775 break;
17778 default:
17779 gcc_unreachable ();
17782 op = newop;
17783 used_mode = SImode;
17784 before = gen_reg_rtx (used_mode);
17785 after = gen_reg_rtx (used_mode);
17787 else
17789 used_mode = mode;
17790 before = before_param;
17791 after = after_param;
17793 if (before == NULL_RTX)
17794 before = gen_reg_rtx (used_mode);
17795 if (after == NULL_RTX)
17796 after = gen_reg_rtx (used_mode);
17799 if ((code == PLUS || code == MINUS)
17800 && used_mode != mode)
17801 the_op = op; /* Computed above. */
17802 else if (GET_CODE (op) == NOT && GET_CODE (m) != NOT)
17803 the_op = gen_rtx_fmt_ee (code, used_mode, op, m);
17804 else if (code == NOT)
17805 the_op = gen_rtx_fmt_ee (IOR, used_mode,
17806 gen_rtx_NOT (used_mode, m),
17807 gen_rtx_NOT (used_mode, op));
17808 else
17809 the_op = gen_rtx_fmt_ee (code, used_mode, m, op);
17811 set_after = gen_rtx_SET (VOIDmode, after, the_op);
17812 set_before = gen_rtx_SET (VOIDmode, before, used_m);
17813 set_atomic = gen_rtx_SET (VOIDmode, used_m,
17814 gen_rtx_UNSPEC (used_mode,
17815 gen_rtvec (1, the_op),
17816 UNSPEC_SYNC_OP));
17817 cc_scratch = gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (CCmode));
17819 if ((code == PLUS || code == MINUS) && used_mode != mode)
17820 vec = gen_rtvec (5, set_after, set_before, set_atomic, cc_scratch,
17821 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (SImode)));
17822 else
17823 vec = gen_rtvec (4, set_after, set_before, set_atomic, cc_scratch);
17824 emit_insn (gen_rtx_PARALLEL (VOIDmode, vec));
17826 /* Shift and mask the return values properly. */
17827 if (used_mode != mode && before_param)
17829 emit_insn (gen_lshrsi3 (before, before, shift));
17830 convert_move (before_param, before, 1);
17833 if (used_mode != mode && after_param)
17835 emit_insn (gen_lshrsi3 (after, after, shift));
17836 convert_move (after_param, after, 1);
17839 /* The previous sequence will end with a branch that's dependent on
17840 the conditional store, so placing an isync will ensure that no
17841 other instructions (especially, no load or store instructions)
17842 can start before the atomic operation completes. */
17843 if (sync_p)
17844 emit_insn (gen_isync ());
17847 /* A subroutine of the atomic operation splitters. Jump to LABEL if
17848 COND is true. Mark the jump as unlikely to be taken. */
17850 static void
17851 emit_unlikely_jump (rtx cond, rtx label)
17853 rtx very_unlikely = GEN_INT (REG_BR_PROB_BASE / 100 - 1);
17854 rtx x;
17856 x = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, label, pc_rtx);
17857 x = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, x));
17858 add_reg_note (x, REG_BR_PROB, very_unlikely);
17861 /* A subroutine of the atomic operation splitters. Emit a load-locked
17862 instruction in MODE. */
17864 static void
17865 emit_load_locked (enum machine_mode mode, rtx reg, rtx mem)
17867 rtx (*fn) (rtx, rtx) = NULL;
17868 if (mode == SImode)
17869 fn = gen_load_locked_si;
17870 else if (mode == DImode)
17871 fn = gen_load_locked_di;
17872 emit_insn (fn (reg, mem));
17875 /* A subroutine of the atomic operation splitters. Emit a store-conditional
17876 instruction in MODE. */
17878 static void
17879 emit_store_conditional (enum machine_mode mode, rtx res, rtx mem, rtx val)
17881 rtx (*fn) (rtx, rtx, rtx) = NULL;
17882 if (mode == SImode)
17883 fn = gen_store_conditional_si;
17884 else if (mode == DImode)
17885 fn = gen_store_conditional_di;
17887 /* Emit sync before stwcx. to address PPC405 Erratum. */
17888 if (PPC405_ERRATUM77)
17889 emit_insn (gen_memory_barrier ());
17891 emit_insn (fn (res, mem, val));
17894 /* Expand an atomic fetch-and-operate pattern. CODE is the binary operation
17895 to perform. MEM is the memory on which to operate. VAL is the second
17896 operand of the binary operator. BEFORE and AFTER are optional locations to
17897 return the value of MEM either before of after the operation. SCRATCH is
17898 a scratch register. */
17900 void
17901 rs6000_split_atomic_op (enum rtx_code code, rtx mem, rtx val,
17902 rtx before, rtx after, rtx scratch)
17904 enum machine_mode mode = GET_MODE (mem);
17905 rtx label, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
17907 emit_insn (gen_lwsync ());
17909 label = gen_label_rtx ();
17910 emit_label (label);
17911 label = gen_rtx_LABEL_REF (VOIDmode, label);
17913 if (before == NULL_RTX)
17914 before = scratch;
17915 emit_load_locked (mode, before, mem);
17917 if (code == NOT)
17918 x = gen_rtx_IOR (mode,
17919 gen_rtx_NOT (mode, before),
17920 gen_rtx_NOT (mode, val));
17921 else if (code == AND)
17922 x = gen_rtx_UNSPEC (mode, gen_rtvec (2, before, val), UNSPEC_AND);
17923 else
17924 x = gen_rtx_fmt_ee (code, mode, before, val);
17926 if (after != NULL_RTX)
17927 emit_insn (gen_rtx_SET (VOIDmode, after, copy_rtx (x)));
17928 emit_insn (gen_rtx_SET (VOIDmode, scratch, x));
17930 emit_store_conditional (mode, cond, mem, scratch);
17932 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17933 emit_unlikely_jump (x, label);
17935 emit_insn (gen_isync ());
17938 /* Expand an atomic compare and swap operation. MEM is the memory on which
17939 to operate. OLDVAL is the old value to be compared. NEWVAL is the new
17940 value to be stored. SCRATCH is a scratch GPR. */
17942 void
17943 rs6000_split_compare_and_swap (rtx retval, rtx mem, rtx oldval, rtx newval,
17944 rtx scratch)
17946 enum machine_mode mode = GET_MODE (mem);
17947 rtx label1, label2, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
17949 emit_insn (gen_lwsync ());
17951 label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
17952 label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
17953 emit_label (XEXP (label1, 0));
17955 emit_load_locked (mode, retval, mem);
17957 x = gen_rtx_COMPARE (CCmode, retval, oldval);
17958 emit_insn (gen_rtx_SET (VOIDmode, cond, x));
17960 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17961 emit_unlikely_jump (x, label2);
17963 emit_move_insn (scratch, newval);
17964 emit_store_conditional (mode, cond, mem, scratch);
17966 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17967 emit_unlikely_jump (x, label1);
17969 emit_insn (gen_isync ());
17970 emit_label (XEXP (label2, 0));
17973 /* Expand an atomic test and set operation. MEM is the memory on which
17974 to operate. VAL is the value set. SCRATCH is a scratch GPR. */
17976 void
17977 rs6000_split_lock_test_and_set (rtx retval, rtx mem, rtx val, rtx scratch)
17979 enum machine_mode mode = GET_MODE (mem);
17980 rtx label, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
17982 label = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
17983 emit_label (XEXP (label, 0));
17985 emit_load_locked (mode, retval, mem);
17986 emit_move_insn (scratch, val);
17987 emit_store_conditional (mode, cond, mem, scratch);
17989 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17990 emit_unlikely_jump (x, label);
17992 emit_insn (gen_isync ());
17995 void
17996 rs6000_expand_compare_and_swapqhi (rtx dst, rtx mem, rtx oldval, rtx newval)
17998 enum machine_mode mode = GET_MODE (mem);
17999 rtx addrSI, align, wdst, shift, mask;
18000 HOST_WIDE_INT shift_mask = mode == QImode ? 0x18 : 0x10;
18001 HOST_WIDE_INT imask = GET_MODE_MASK (mode);
18003 /* Shift amount for subword relative to aligned word. */
18004 addrSI = force_reg (GET_MODE (XEXP (mem, 0)), XEXP (mem, 0));
18005 addrSI = force_reg (SImode, gen_lowpart_common (SImode, addrSI));
18006 shift = gen_reg_rtx (SImode);
18007 emit_insn (gen_rlwinm (shift, addrSI, GEN_INT (3),
18008 GEN_INT (shift_mask)));
18009 emit_insn (gen_xorsi3 (shift, shift, GEN_INT (shift_mask)));
18011 /* Shift and mask old value into position within word. */
18012 oldval = convert_modes (SImode, mode, oldval, 1);
18013 oldval = expand_binop (SImode, and_optab,
18014 oldval, GEN_INT (imask), NULL_RTX,
18015 1, OPTAB_LIB_WIDEN);
18016 emit_insn (gen_ashlsi3 (oldval, oldval, shift));
18018 /* Shift and mask new value into position within word. */
18019 newval = convert_modes (SImode, mode, newval, 1);
18020 newval = expand_binop (SImode, and_optab,
18021 newval, GEN_INT (imask), NULL_RTX,
18022 1, OPTAB_LIB_WIDEN);
18023 emit_insn (gen_ashlsi3 (newval, newval, shift));
18025 /* Mask for insertion. */
18026 mask = gen_reg_rtx (SImode);
18027 emit_move_insn (mask, GEN_INT (imask));
18028 emit_insn (gen_ashlsi3 (mask, mask, shift));
18030 /* Address of aligned word containing subword. */
18031 align = expand_binop (Pmode, and_optab, XEXP (mem, 0), GEN_INT (-4),
18032 NULL_RTX, 1, OPTAB_LIB_WIDEN);
18033 mem = change_address (mem, SImode, align);
18034 set_mem_align (mem, 32);
18035 MEM_VOLATILE_P (mem) = 1;
18037 wdst = gen_reg_rtx (SImode);
18038 emit_insn (gen_sync_compare_and_swapqhi_internal (wdst, mask,
18039 oldval, newval, mem));
18041 /* Shift the result back. */
18042 emit_insn (gen_lshrsi3 (wdst, wdst, shift));
18044 emit_move_insn (dst, gen_lowpart (mode, wdst));
18047 void
18048 rs6000_split_compare_and_swapqhi (rtx dest, rtx mask,
18049 rtx oldval, rtx newval, rtx mem,
18050 rtx scratch)
18052 rtx label1, label2, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
18054 emit_insn (gen_lwsync ());
18055 label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
18056 label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
18057 emit_label (XEXP (label1, 0));
18059 emit_load_locked (SImode, scratch, mem);
18061 /* Mask subword within loaded value for comparison with oldval.
18062 Use UNSPEC_AND to avoid clobber.*/
18063 emit_insn (gen_rtx_SET (SImode, dest,
18064 gen_rtx_UNSPEC (SImode,
18065 gen_rtvec (2, scratch, mask),
18066 UNSPEC_AND)));
18068 x = gen_rtx_COMPARE (CCmode, dest, oldval);
18069 emit_insn (gen_rtx_SET (VOIDmode, cond, x));
18071 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
18072 emit_unlikely_jump (x, label2);
18074 /* Clear subword within loaded value for insertion of new value. */
18075 emit_insn (gen_rtx_SET (SImode, scratch,
18076 gen_rtx_AND (SImode,
18077 gen_rtx_NOT (SImode, mask), scratch)));
18078 emit_insn (gen_iorsi3 (scratch, scratch, newval));
18079 emit_store_conditional (SImode, cond, mem, scratch);
18081 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
18082 emit_unlikely_jump (x, label1);
18084 emit_insn (gen_isync ());
18085 emit_label (XEXP (label2, 0));
18089 /* Emit instructions to move SRC to DST. Called by splitters for
18090 multi-register moves. It will emit at most one instruction for
18091 each register that is accessed; that is, it won't emit li/lis pairs
18092 (or equivalent for 64-bit code). One of SRC or DST must be a hard
18093 register. */
18095 void
18096 rs6000_split_multireg_move (rtx dst, rtx src)
18098 /* The register number of the first register being moved. */
18099 int reg;
18100 /* The mode that is to be moved. */
18101 enum machine_mode mode;
18102 /* The mode that the move is being done in, and its size. */
18103 enum machine_mode reg_mode;
18104 int reg_mode_size;
18105 /* The number of registers that will be moved. */
18106 int nregs;
18108 reg = REG_P (dst) ? REGNO (dst) : REGNO (src);
18109 mode = GET_MODE (dst);
18110 nregs = hard_regno_nregs[reg][mode];
18111 if (FP_REGNO_P (reg))
18112 reg_mode = DECIMAL_FLOAT_MODE_P (mode) ? DDmode :
18113 ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? DFmode : SFmode);
18114 else if (ALTIVEC_REGNO_P (reg))
18115 reg_mode = V16QImode;
18116 else if (TARGET_E500_DOUBLE && mode == TFmode)
18117 reg_mode = DFmode;
18118 else
18119 reg_mode = word_mode;
18120 reg_mode_size = GET_MODE_SIZE (reg_mode);
18122 gcc_assert (reg_mode_size * nregs == GET_MODE_SIZE (mode));
18124 if (REG_P (src) && REG_P (dst) && (REGNO (src) < REGNO (dst)))
18126 /* Move register range backwards, if we might have destructive
18127 overlap. */
18128 int i;
18129 for (i = nregs - 1; i >= 0; i--)
18130 emit_insn (gen_rtx_SET (VOIDmode,
18131 simplify_gen_subreg (reg_mode, dst, mode,
18132 i * reg_mode_size),
18133 simplify_gen_subreg (reg_mode, src, mode,
18134 i * reg_mode_size)));
18136 else
18138 int i;
18139 int j = -1;
18140 bool used_update = false;
18141 rtx restore_basereg = NULL_RTX;
18143 if (MEM_P (src) && INT_REGNO_P (reg))
18145 rtx breg;
18147 if (GET_CODE (XEXP (src, 0)) == PRE_INC
18148 || GET_CODE (XEXP (src, 0)) == PRE_DEC)
18150 rtx delta_rtx;
18151 breg = XEXP (XEXP (src, 0), 0);
18152 delta_rtx = (GET_CODE (XEXP (src, 0)) == PRE_INC
18153 ? GEN_INT (GET_MODE_SIZE (GET_MODE (src)))
18154 : GEN_INT (-GET_MODE_SIZE (GET_MODE (src))));
18155 emit_insn (gen_add3_insn (breg, breg, delta_rtx));
18156 src = replace_equiv_address (src, breg);
18158 else if (! rs6000_offsettable_memref_p (src))
18160 if (GET_CODE (XEXP (src, 0)) == PRE_MODIFY)
18162 rtx basereg = XEXP (XEXP (src, 0), 0);
18163 if (TARGET_UPDATE)
18165 rtx ndst = simplify_gen_subreg (reg_mode, dst, mode, 0);
18166 emit_insn (gen_rtx_SET (VOIDmode, ndst,
18167 gen_rtx_MEM (reg_mode, XEXP (src, 0))));
18168 used_update = true;
18170 else
18171 emit_insn (gen_rtx_SET (VOIDmode, basereg,
18172 XEXP (XEXP (src, 0), 1)));
18173 src = replace_equiv_address (src, basereg);
18175 else
18177 rtx basereg = gen_rtx_REG (Pmode, reg);
18178 emit_insn (gen_rtx_SET (VOIDmode, basereg, XEXP (src, 0)));
18179 src = replace_equiv_address (src, basereg);
18183 breg = XEXP (src, 0);
18184 if (GET_CODE (breg) == PLUS || GET_CODE (breg) == LO_SUM)
18185 breg = XEXP (breg, 0);
18187 /* If the base register we are using to address memory is
18188 also a destination reg, then change that register last. */
18189 if (REG_P (breg)
18190 && REGNO (breg) >= REGNO (dst)
18191 && REGNO (breg) < REGNO (dst) + nregs)
18192 j = REGNO (breg) - REGNO (dst);
18194 else if (MEM_P (dst) && INT_REGNO_P (reg))
18196 rtx breg;
18198 if (GET_CODE (XEXP (dst, 0)) == PRE_INC
18199 || GET_CODE (XEXP (dst, 0)) == PRE_DEC)
18201 rtx delta_rtx;
18202 breg = XEXP (XEXP (dst, 0), 0);
18203 delta_rtx = (GET_CODE (XEXP (dst, 0)) == PRE_INC
18204 ? GEN_INT (GET_MODE_SIZE (GET_MODE (dst)))
18205 : GEN_INT (-GET_MODE_SIZE (GET_MODE (dst))));
18207 /* We have to update the breg before doing the store.
18208 Use store with update, if available. */
18210 if (TARGET_UPDATE)
18212 rtx nsrc = simplify_gen_subreg (reg_mode, src, mode, 0);
18213 emit_insn (TARGET_32BIT
18214 ? (TARGET_POWERPC64
18215 ? gen_movdi_si_update (breg, breg, delta_rtx, nsrc)
18216 : gen_movsi_update (breg, breg, delta_rtx, nsrc))
18217 : gen_movdi_di_update (breg, breg, delta_rtx, nsrc));
18218 used_update = true;
18220 else
18221 emit_insn (gen_add3_insn (breg, breg, delta_rtx));
18222 dst = replace_equiv_address (dst, breg);
18224 else if (!rs6000_offsettable_memref_p (dst)
18225 && GET_CODE (XEXP (dst, 0)) != LO_SUM)
18227 if (GET_CODE (XEXP (dst, 0)) == PRE_MODIFY)
18229 rtx basereg = XEXP (XEXP (dst, 0), 0);
18230 if (TARGET_UPDATE)
18232 rtx nsrc = simplify_gen_subreg (reg_mode, src, mode, 0);
18233 emit_insn (gen_rtx_SET (VOIDmode,
18234 gen_rtx_MEM (reg_mode, XEXP (dst, 0)), nsrc));
18235 used_update = true;
18237 else
18238 emit_insn (gen_rtx_SET (VOIDmode, basereg,
18239 XEXP (XEXP (dst, 0), 1)));
18240 dst = replace_equiv_address (dst, basereg);
18242 else
18244 rtx basereg = XEXP (XEXP (dst, 0), 0);
18245 rtx offsetreg = XEXP (XEXP (dst, 0), 1);
18246 gcc_assert (GET_CODE (XEXP (dst, 0)) == PLUS
18247 && REG_P (basereg)
18248 && REG_P (offsetreg)
18249 && REGNO (basereg) != REGNO (offsetreg));
18250 if (REGNO (basereg) == 0)
18252 rtx tmp = offsetreg;
18253 offsetreg = basereg;
18254 basereg = tmp;
18256 emit_insn (gen_add3_insn (basereg, basereg, offsetreg));
18257 restore_basereg = gen_sub3_insn (basereg, basereg, offsetreg);
18258 dst = replace_equiv_address (dst, basereg);
18261 else if (GET_CODE (XEXP (dst, 0)) != LO_SUM)
18262 gcc_assert (rs6000_offsettable_memref_p (dst));
18265 for (i = 0; i < nregs; i++)
18267 /* Calculate index to next subword. */
18268 ++j;
18269 if (j == nregs)
18270 j = 0;
18272 /* If compiler already emitted move of first word by
18273 store with update, no need to do anything. */
18274 if (j == 0 && used_update)
18275 continue;
18277 emit_insn (gen_rtx_SET (VOIDmode,
18278 simplify_gen_subreg (reg_mode, dst, mode,
18279 j * reg_mode_size),
18280 simplify_gen_subreg (reg_mode, src, mode,
18281 j * reg_mode_size)));
18283 if (restore_basereg != NULL_RTX)
18284 emit_insn (restore_basereg);
18289 /* This page contains routines that are used to determine what the
18290 function prologue and epilogue code will do and write them out. */
18292 /* Return the first fixed-point register that is required to be
18293 saved. 32 if none. */
18296 first_reg_to_save (void)
18298 int first_reg;
18300 /* Find lowest numbered live register. */
18301 for (first_reg = 13; first_reg <= 31; first_reg++)
18302 if (df_regs_ever_live_p (first_reg)
18303 && (! call_used_regs[first_reg]
18304 || (first_reg == RS6000_PIC_OFFSET_TABLE_REGNUM
18305 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
18306 || (DEFAULT_ABI == ABI_DARWIN && flag_pic)
18307 || (TARGET_TOC && TARGET_MINIMAL_TOC)))))
18308 break;
18310 #if TARGET_MACHO
18311 if (flag_pic
18312 && crtl->uses_pic_offset_table
18313 && first_reg > RS6000_PIC_OFFSET_TABLE_REGNUM)
18314 return RS6000_PIC_OFFSET_TABLE_REGNUM;
18315 #endif
18317 return first_reg;
18320 /* Similar, for FP regs. */
18323 first_fp_reg_to_save (void)
18325 int first_reg;
18327 /* Find lowest numbered live register. */
18328 for (first_reg = 14 + 32; first_reg <= 63; first_reg++)
18329 if (df_regs_ever_live_p (first_reg))
18330 break;
18332 return first_reg;
18335 /* Similar, for AltiVec regs. */
18337 static int
18338 first_altivec_reg_to_save (void)
18340 int i;
18342 /* Stack frame remains as is unless we are in AltiVec ABI. */
18343 if (! TARGET_ALTIVEC_ABI)
18344 return LAST_ALTIVEC_REGNO + 1;
18346 /* On Darwin, the unwind routines are compiled without
18347 TARGET_ALTIVEC, and use save_world to save/restore the
18348 altivec registers when necessary. */
18349 if (DEFAULT_ABI == ABI_DARWIN && crtl->calls_eh_return
18350 && ! TARGET_ALTIVEC)
18351 return FIRST_ALTIVEC_REGNO + 20;
18353 /* Find lowest numbered live register. */
18354 for (i = FIRST_ALTIVEC_REGNO + 20; i <= LAST_ALTIVEC_REGNO; ++i)
18355 if (df_regs_ever_live_p (i))
18356 break;
18358 return i;
18361 /* Return a 32-bit mask of the AltiVec registers we need to set in
18362 VRSAVE. Bit n of the return value is 1 if Vn is live. The MSB in
18363 the 32-bit word is 0. */
18365 static unsigned int
18366 compute_vrsave_mask (void)
18368 unsigned int i, mask = 0;
18370 /* On Darwin, the unwind routines are compiled without
18371 TARGET_ALTIVEC, and use save_world to save/restore the
18372 call-saved altivec registers when necessary. */
18373 if (DEFAULT_ABI == ABI_DARWIN && crtl->calls_eh_return
18374 && ! TARGET_ALTIVEC)
18375 mask |= 0xFFF;
18377 /* First, find out if we use _any_ altivec registers. */
18378 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
18379 if (df_regs_ever_live_p (i))
18380 mask |= ALTIVEC_REG_BIT (i);
18382 if (mask == 0)
18383 return mask;
18385 /* Next, remove the argument registers from the set. These must
18386 be in the VRSAVE mask set by the caller, so we don't need to add
18387 them in again. More importantly, the mask we compute here is
18388 used to generate CLOBBERs in the set_vrsave insn, and we do not
18389 wish the argument registers to die. */
18390 for (i = crtl->args.info.vregno - 1; i >= ALTIVEC_ARG_MIN_REG; --i)
18391 mask &= ~ALTIVEC_REG_BIT (i);
18393 /* Similarly, remove the return value from the set. */
18395 bool yes = false;
18396 diddle_return_value (is_altivec_return_reg, &yes);
18397 if (yes)
18398 mask &= ~ALTIVEC_REG_BIT (ALTIVEC_ARG_RETURN);
18401 return mask;
18404 /* For a very restricted set of circumstances, we can cut down the
18405 size of prologues/epilogues by calling our own save/restore-the-world
18406 routines. */
18408 static void
18409 compute_save_world_info (rs6000_stack_t *info_ptr)
18411 info_ptr->world_save_p = 1;
18412 info_ptr->world_save_p
18413 = (WORLD_SAVE_P (info_ptr)
18414 && DEFAULT_ABI == ABI_DARWIN
18415 && ! (cfun->calls_setjmp && flag_exceptions)
18416 && info_ptr->first_fp_reg_save == FIRST_SAVED_FP_REGNO
18417 && info_ptr->first_gp_reg_save == FIRST_SAVED_GP_REGNO
18418 && info_ptr->first_altivec_reg_save == FIRST_SAVED_ALTIVEC_REGNO
18419 && info_ptr->cr_save_p);
18421 /* This will not work in conjunction with sibcalls. Make sure there
18422 are none. (This check is expensive, but seldom executed.) */
18423 if (WORLD_SAVE_P (info_ptr))
18425 rtx insn;
18426 for ( insn = get_last_insn_anywhere (); insn; insn = PREV_INSN (insn))
18427 if ( GET_CODE (insn) == CALL_INSN
18428 && SIBLING_CALL_P (insn))
18430 info_ptr->world_save_p = 0;
18431 break;
18435 if (WORLD_SAVE_P (info_ptr))
18437 /* Even if we're not touching VRsave, make sure there's room on the
18438 stack for it, if it looks like we're calling SAVE_WORLD, which
18439 will attempt to save it. */
18440 info_ptr->vrsave_size = 4;
18442 /* If we are going to save the world, we need to save the link register too. */
18443 info_ptr->lr_save_p = 1;
18445 /* "Save" the VRsave register too if we're saving the world. */
18446 if (info_ptr->vrsave_mask == 0)
18447 info_ptr->vrsave_mask = compute_vrsave_mask ();
18449 /* Because the Darwin register save/restore routines only handle
18450 F14 .. F31 and V20 .. V31 as per the ABI, perform a consistency
18451 check. */
18452 gcc_assert (info_ptr->first_fp_reg_save >= FIRST_SAVED_FP_REGNO
18453 && (info_ptr->first_altivec_reg_save
18454 >= FIRST_SAVED_ALTIVEC_REGNO));
18456 return;
18460 static void
18461 is_altivec_return_reg (rtx reg, void *xyes)
18463 bool *yes = (bool *) xyes;
18464 if (REGNO (reg) == ALTIVEC_ARG_RETURN)
18465 *yes = true;
18469 /* Determine the strategy for savings/restoring registers. */
18471 enum {
18472 SAVRES_MULTIPLE = 0x1,
18473 SAVE_INLINE_FPRS = 0x2,
18474 SAVE_INLINE_GPRS = 0x4,
18475 REST_INLINE_FPRS = 0x8,
18476 REST_INLINE_GPRS = 0x10,
18477 SAVE_NOINLINE_GPRS_SAVES_LR = 0x20,
18478 SAVE_NOINLINE_FPRS_SAVES_LR = 0x40,
18479 REST_NOINLINE_FPRS_DOESNT_RESTORE_LR = 0x80
18482 static int
18483 rs6000_savres_strategy (rs6000_stack_t *info,
18484 bool using_static_chain_p)
18486 int strategy = 0;
18488 if (TARGET_MULTIPLE
18489 && !TARGET_POWERPC64
18490 && !(TARGET_SPE_ABI && info->spe_64bit_regs_used)
18491 && info->first_gp_reg_save < 31
18492 && no_global_regs_above (info->first_gp_reg_save, /*gpr=*/true))
18493 strategy |= SAVRES_MULTIPLE;
18495 if (crtl->calls_eh_return
18496 || cfun->machine->ra_need_lr
18497 || info->total_size > 32767)
18498 strategy |= (SAVE_INLINE_FPRS | REST_INLINE_FPRS
18499 | SAVE_INLINE_GPRS | REST_INLINE_GPRS);
18501 if (info->first_fp_reg_save == 64
18502 || FP_SAVE_INLINE (info->first_fp_reg_save)
18503 /* The out-of-line FP routines use double-precision stores;
18504 we can't use those routines if we don't have such stores. */
18505 || (TARGET_HARD_FLOAT && !TARGET_DOUBLE_FLOAT)
18506 || !no_global_regs_above (info->first_fp_reg_save, /*gpr=*/false))
18507 strategy |= SAVE_INLINE_FPRS | REST_INLINE_FPRS;
18509 if (info->first_gp_reg_save == 32
18510 || GP_SAVE_INLINE (info->first_gp_reg_save)
18511 || !((strategy & SAVRES_MULTIPLE)
18512 || no_global_regs_above (info->first_gp_reg_save, /*gpr=*/true)))
18513 strategy |= SAVE_INLINE_GPRS | REST_INLINE_GPRS;
18515 /* Don't bother to try to save things out-of-line if r11 is occupied
18516 by the static chain. It would require too much fiddling and the
18517 static chain is rarely used anyway. */
18518 if (using_static_chain_p)
18519 strategy |= SAVE_INLINE_FPRS | SAVE_INLINE_GPRS;
18521 /* If we are going to use store multiple, then don't even bother
18522 with the out-of-line routines, since the store-multiple
18523 instruction will always be smaller. */
18524 if ((strategy & SAVRES_MULTIPLE))
18525 strategy |= SAVE_INLINE_GPRS;
18527 /* The situation is more complicated with load multiple. We'd
18528 prefer to use the out-of-line routines for restores, since the
18529 "exit" out-of-line routines can handle the restore of LR and the
18530 frame teardown. However if doesn't make sense to use the
18531 out-of-line routine if that is the only reason we'd need to save
18532 LR, and we can't use the "exit" out-of-line gpr restore if we
18533 have saved some fprs; In those cases it is advantageous to use
18534 load multiple when available. */
18535 if ((strategy & SAVRES_MULTIPLE)
18536 && (!info->lr_save_p
18537 || info->first_fp_reg_save != 64))
18538 strategy |= REST_INLINE_GPRS;
18540 /* We can only use load multiple or the out-of-line routines to
18541 restore if we've used store multiple or out-of-line routines
18542 in the prologue, i.e. if we've saved all the registers from
18543 first_gp_reg_save. Otherwise, we risk loading garbage. */
18544 if ((strategy & (SAVE_INLINE_GPRS | SAVRES_MULTIPLE)) == SAVE_INLINE_GPRS)
18545 strategy |= REST_INLINE_GPRS;
18547 /* Saving CR interferes with the exit routines used on the SPE, so
18548 just punt here. */
18549 if (TARGET_SPE_ABI
18550 && info->spe_64bit_regs_used
18551 && info->cr_save_p)
18552 strategy |= REST_INLINE_GPRS;
18554 #ifdef POWERPC_LINUX
18555 if (TARGET_64BIT)
18557 if (!(strategy & SAVE_INLINE_FPRS))
18558 strategy |= SAVE_NOINLINE_FPRS_SAVES_LR;
18559 else if (!(strategy & SAVE_INLINE_GPRS)
18560 && info->first_fp_reg_save == 64)
18561 strategy |= SAVE_NOINLINE_GPRS_SAVES_LR;
18563 #else
18564 if (TARGET_AIX && !(strategy & REST_INLINE_FPRS))
18565 strategy |= REST_NOINLINE_FPRS_DOESNT_RESTORE_LR;
18566 #endif
18567 return strategy;
18570 /* Calculate the stack information for the current function. This is
18571 complicated by having two separate calling sequences, the AIX calling
18572 sequence and the V.4 calling sequence.
18574 AIX (and Darwin/Mac OS X) stack frames look like:
18575 32-bit 64-bit
18576 SP----> +---------------------------------------+
18577 | back chain to caller | 0 0
18578 +---------------------------------------+
18579 | saved CR | 4 8 (8-11)
18580 +---------------------------------------+
18581 | saved LR | 8 16
18582 +---------------------------------------+
18583 | reserved for compilers | 12 24
18584 +---------------------------------------+
18585 | reserved for binders | 16 32
18586 +---------------------------------------+
18587 | saved TOC pointer | 20 40
18588 +---------------------------------------+
18589 | Parameter save area (P) | 24 48
18590 +---------------------------------------+
18591 | Alloca space (A) | 24+P etc.
18592 +---------------------------------------+
18593 | Local variable space (L) | 24+P+A
18594 +---------------------------------------+
18595 | Float/int conversion temporary (X) | 24+P+A+L
18596 +---------------------------------------+
18597 | Save area for AltiVec registers (W) | 24+P+A+L+X
18598 +---------------------------------------+
18599 | AltiVec alignment padding (Y) | 24+P+A+L+X+W
18600 +---------------------------------------+
18601 | Save area for VRSAVE register (Z) | 24+P+A+L+X+W+Y
18602 +---------------------------------------+
18603 | Save area for GP registers (G) | 24+P+A+X+L+X+W+Y+Z
18604 +---------------------------------------+
18605 | Save area for FP registers (F) | 24+P+A+X+L+X+W+Y+Z+G
18606 +---------------------------------------+
18607 old SP->| back chain to caller's caller |
18608 +---------------------------------------+
18610 The required alignment for AIX configurations is two words (i.e., 8
18611 or 16 bytes).
18614 V.4 stack frames look like:
18616 SP----> +---------------------------------------+
18617 | back chain to caller | 0
18618 +---------------------------------------+
18619 | caller's saved LR | 4
18620 +---------------------------------------+
18621 | Parameter save area (P) | 8
18622 +---------------------------------------+
18623 | Alloca space (A) | 8+P
18624 +---------------------------------------+
18625 | Varargs save area (V) | 8+P+A
18626 +---------------------------------------+
18627 | Local variable space (L) | 8+P+A+V
18628 +---------------------------------------+
18629 | Float/int conversion temporary (X) | 8+P+A+V+L
18630 +---------------------------------------+
18631 | Save area for AltiVec registers (W) | 8+P+A+V+L+X
18632 +---------------------------------------+
18633 | AltiVec alignment padding (Y) | 8+P+A+V+L+X+W
18634 +---------------------------------------+
18635 | Save area for VRSAVE register (Z) | 8+P+A+V+L+X+W+Y
18636 +---------------------------------------+
18637 | SPE: area for 64-bit GP registers |
18638 +---------------------------------------+
18639 | SPE alignment padding |
18640 +---------------------------------------+
18641 | saved CR (C) | 8+P+A+V+L+X+W+Y+Z
18642 +---------------------------------------+
18643 | Save area for GP registers (G) | 8+P+A+V+L+X+W+Y+Z+C
18644 +---------------------------------------+
18645 | Save area for FP registers (F) | 8+P+A+V+L+X+W+Y+Z+C+G
18646 +---------------------------------------+
18647 old SP->| back chain to caller's caller |
18648 +---------------------------------------+
18650 The required alignment for V.4 is 16 bytes, or 8 bytes if -meabi is
18651 given. (But note below and in sysv4.h that we require only 8 and
18652 may round up the size of our stack frame anyways. The historical
18653 reason is early versions of powerpc-linux which didn't properly
18654 align the stack at program startup. A happy side-effect is that
18655 -mno-eabi libraries can be used with -meabi programs.)
18657 The EABI configuration defaults to the V.4 layout. However,
18658 the stack alignment requirements may differ. If -mno-eabi is not
18659 given, the required stack alignment is 8 bytes; if -mno-eabi is
18660 given, the required alignment is 16 bytes. (But see V.4 comment
18661 above.) */
18663 #ifndef ABI_STACK_BOUNDARY
18664 #define ABI_STACK_BOUNDARY STACK_BOUNDARY
18665 #endif
18667 static rs6000_stack_t *
18668 rs6000_stack_info (void)
18670 #ifdef ENABLE_CHECKING
18671 static rs6000_stack_t info_save;
18672 #endif
18673 rs6000_stack_t *info_ptr = &stack_info;
18674 int reg_size = TARGET_32BIT ? 4 : 8;
18675 int ehrd_size;
18676 int save_align;
18677 int first_gp;
18678 HOST_WIDE_INT non_fixed_size;
18679 bool using_static_chain_p;
18681 #ifdef ENABLE_CHECKING
18682 memcpy (&info_save, &stack_info, sizeof stack_info);
18683 #else
18684 if (reload_completed && info_ptr->reload_completed)
18685 return info_ptr;
18686 #endif
18688 memset (&stack_info, 0, sizeof (stack_info));
18689 info_ptr->reload_completed = reload_completed;
18691 if (TARGET_SPE)
18693 /* Cache value so we don't rescan instruction chain over and over. */
18694 if (cfun->machine->insn_chain_scanned_p == 0)
18695 cfun->machine->insn_chain_scanned_p
18696 = spe_func_has_64bit_regs_p () + 1;
18697 info_ptr->spe_64bit_regs_used = cfun->machine->insn_chain_scanned_p - 1;
18700 /* Select which calling sequence. */
18701 info_ptr->abi = DEFAULT_ABI;
18703 /* Calculate which registers need to be saved & save area size. */
18704 info_ptr->first_gp_reg_save = first_reg_to_save ();
18705 /* Assume that we will have to save RS6000_PIC_OFFSET_TABLE_REGNUM,
18706 even if it currently looks like we won't. Reload may need it to
18707 get at a constant; if so, it will have already created a constant
18708 pool entry for it. */
18709 if (((TARGET_TOC && TARGET_MINIMAL_TOC)
18710 || (flag_pic == 1 && DEFAULT_ABI == ABI_V4)
18711 || (flag_pic && DEFAULT_ABI == ABI_DARWIN))
18712 && crtl->uses_const_pool
18713 && info_ptr->first_gp_reg_save > RS6000_PIC_OFFSET_TABLE_REGNUM)
18714 first_gp = RS6000_PIC_OFFSET_TABLE_REGNUM;
18715 else
18716 first_gp = info_ptr->first_gp_reg_save;
18718 info_ptr->gp_size = reg_size * (32 - first_gp);
18720 /* For the SPE, we have an additional upper 32-bits on each GPR.
18721 Ideally we should save the entire 64-bits only when the upper
18722 half is used in SIMD instructions. Since we only record
18723 registers live (not the size they are used in), this proves
18724 difficult because we'd have to traverse the instruction chain at
18725 the right time, taking reload into account. This is a real pain,
18726 so we opt to save the GPRs in 64-bits always if but one register
18727 gets used in 64-bits. Otherwise, all the registers in the frame
18728 get saved in 32-bits.
18730 So... since when we save all GPRs (except the SP) in 64-bits, the
18731 traditional GP save area will be empty. */
18732 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
18733 info_ptr->gp_size = 0;
18735 info_ptr->first_fp_reg_save = first_fp_reg_to_save ();
18736 info_ptr->fp_size = 8 * (64 - info_ptr->first_fp_reg_save);
18738 info_ptr->first_altivec_reg_save = first_altivec_reg_to_save ();
18739 info_ptr->altivec_size = 16 * (LAST_ALTIVEC_REGNO + 1
18740 - info_ptr->first_altivec_reg_save);
18742 /* Does this function call anything? */
18743 info_ptr->calls_p = (! current_function_is_leaf
18744 || cfun->machine->ra_needs_full_frame);
18746 /* Determine if we need to save the condition code registers. */
18747 if (df_regs_ever_live_p (CR2_REGNO)
18748 || df_regs_ever_live_p (CR3_REGNO)
18749 || df_regs_ever_live_p (CR4_REGNO))
18751 info_ptr->cr_save_p = 1;
18752 if (DEFAULT_ABI == ABI_V4)
18753 info_ptr->cr_size = reg_size;
18756 /* If the current function calls __builtin_eh_return, then we need
18757 to allocate stack space for registers that will hold data for
18758 the exception handler. */
18759 if (crtl->calls_eh_return)
18761 unsigned int i;
18762 for (i = 0; EH_RETURN_DATA_REGNO (i) != INVALID_REGNUM; ++i)
18763 continue;
18765 /* SPE saves EH registers in 64-bits. */
18766 ehrd_size = i * (TARGET_SPE_ABI
18767 && info_ptr->spe_64bit_regs_used != 0
18768 ? UNITS_PER_SPE_WORD : UNITS_PER_WORD);
18770 else
18771 ehrd_size = 0;
18773 /* Determine various sizes. */
18774 info_ptr->reg_size = reg_size;
18775 info_ptr->fixed_size = RS6000_SAVE_AREA;
18776 info_ptr->vars_size = RS6000_ALIGN (get_frame_size (), 8);
18777 info_ptr->parm_size = RS6000_ALIGN (crtl->outgoing_args_size,
18778 TARGET_ALTIVEC ? 16 : 8);
18779 if (FRAME_GROWS_DOWNWARD)
18780 info_ptr->vars_size
18781 += RS6000_ALIGN (info_ptr->fixed_size + info_ptr->vars_size
18782 + info_ptr->parm_size,
18783 ABI_STACK_BOUNDARY / BITS_PER_UNIT)
18784 - (info_ptr->fixed_size + info_ptr->vars_size
18785 + info_ptr->parm_size);
18787 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
18788 info_ptr->spe_gp_size = 8 * (32 - first_gp);
18789 else
18790 info_ptr->spe_gp_size = 0;
18792 if (TARGET_ALTIVEC_ABI)
18793 info_ptr->vrsave_mask = compute_vrsave_mask ();
18794 else
18795 info_ptr->vrsave_mask = 0;
18797 if (TARGET_ALTIVEC_VRSAVE && info_ptr->vrsave_mask)
18798 info_ptr->vrsave_size = 4;
18799 else
18800 info_ptr->vrsave_size = 0;
18802 compute_save_world_info (info_ptr);
18804 /* Calculate the offsets. */
18805 switch (DEFAULT_ABI)
18807 case ABI_NONE:
18808 default:
18809 gcc_unreachable ();
18811 case ABI_AIX:
18812 case ABI_DARWIN:
18813 info_ptr->fp_save_offset = - info_ptr->fp_size;
18814 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
18816 if (TARGET_ALTIVEC_ABI)
18818 info_ptr->vrsave_save_offset
18819 = info_ptr->gp_save_offset - info_ptr->vrsave_size;
18821 /* Align stack so vector save area is on a quadword boundary.
18822 The padding goes above the vectors. */
18823 if (info_ptr->altivec_size != 0)
18824 info_ptr->altivec_padding_size
18825 = info_ptr->vrsave_save_offset & 0xF;
18826 else
18827 info_ptr->altivec_padding_size = 0;
18829 info_ptr->altivec_save_offset
18830 = info_ptr->vrsave_save_offset
18831 - info_ptr->altivec_padding_size
18832 - info_ptr->altivec_size;
18833 gcc_assert (info_ptr->altivec_size == 0
18834 || info_ptr->altivec_save_offset % 16 == 0);
18836 /* Adjust for AltiVec case. */
18837 info_ptr->ehrd_offset = info_ptr->altivec_save_offset - ehrd_size;
18839 else
18840 info_ptr->ehrd_offset = info_ptr->gp_save_offset - ehrd_size;
18841 info_ptr->cr_save_offset = reg_size; /* first word when 64-bit. */
18842 info_ptr->lr_save_offset = 2*reg_size;
18843 break;
18845 case ABI_V4:
18846 info_ptr->fp_save_offset = - info_ptr->fp_size;
18847 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
18848 info_ptr->cr_save_offset = info_ptr->gp_save_offset - info_ptr->cr_size;
18850 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
18852 /* Align stack so SPE GPR save area is aligned on a
18853 double-word boundary. */
18854 if (info_ptr->spe_gp_size != 0 && info_ptr->cr_save_offset != 0)
18855 info_ptr->spe_padding_size
18856 = 8 - (-info_ptr->cr_save_offset % 8);
18857 else
18858 info_ptr->spe_padding_size = 0;
18860 info_ptr->spe_gp_save_offset
18861 = info_ptr->cr_save_offset
18862 - info_ptr->spe_padding_size
18863 - info_ptr->spe_gp_size;
18865 /* Adjust for SPE case. */
18866 info_ptr->ehrd_offset = info_ptr->spe_gp_save_offset;
18868 else if (TARGET_ALTIVEC_ABI)
18870 info_ptr->vrsave_save_offset
18871 = info_ptr->cr_save_offset - info_ptr->vrsave_size;
18873 /* Align stack so vector save area is on a quadword boundary. */
18874 if (info_ptr->altivec_size != 0)
18875 info_ptr->altivec_padding_size
18876 = 16 - (-info_ptr->vrsave_save_offset % 16);
18877 else
18878 info_ptr->altivec_padding_size = 0;
18880 info_ptr->altivec_save_offset
18881 = info_ptr->vrsave_save_offset
18882 - info_ptr->altivec_padding_size
18883 - info_ptr->altivec_size;
18885 /* Adjust for AltiVec case. */
18886 info_ptr->ehrd_offset = info_ptr->altivec_save_offset;
18888 else
18889 info_ptr->ehrd_offset = info_ptr->cr_save_offset;
18890 info_ptr->ehrd_offset -= ehrd_size;
18891 info_ptr->lr_save_offset = reg_size;
18892 break;
18895 save_align = (TARGET_ALTIVEC_ABI || DEFAULT_ABI == ABI_DARWIN) ? 16 : 8;
18896 info_ptr->save_size = RS6000_ALIGN (info_ptr->fp_size
18897 + info_ptr->gp_size
18898 + info_ptr->altivec_size
18899 + info_ptr->altivec_padding_size
18900 + info_ptr->spe_gp_size
18901 + info_ptr->spe_padding_size
18902 + ehrd_size
18903 + info_ptr->cr_size
18904 + info_ptr->vrsave_size,
18905 save_align);
18907 non_fixed_size = (info_ptr->vars_size
18908 + info_ptr->parm_size
18909 + info_ptr->save_size);
18911 info_ptr->total_size = RS6000_ALIGN (non_fixed_size + info_ptr->fixed_size,
18912 ABI_STACK_BOUNDARY / BITS_PER_UNIT);
18914 /* Determine if we need to save the link register. */
18915 if (info_ptr->calls_p
18916 || (DEFAULT_ABI == ABI_AIX
18917 && crtl->profile
18918 && !TARGET_PROFILE_KERNEL)
18919 || (DEFAULT_ABI == ABI_V4 && cfun->calls_alloca)
18920 #ifdef TARGET_RELOCATABLE
18921 || (TARGET_RELOCATABLE && (get_pool_size () != 0))
18922 #endif
18923 || rs6000_ra_ever_killed ())
18924 info_ptr->lr_save_p = 1;
18926 using_static_chain_p = (cfun->static_chain_decl != NULL_TREE
18927 && df_regs_ever_live_p (STATIC_CHAIN_REGNUM)
18928 && call_used_regs[STATIC_CHAIN_REGNUM]);
18929 info_ptr->savres_strategy = rs6000_savres_strategy (info_ptr,
18930 using_static_chain_p);
18932 if (!(info_ptr->savres_strategy & SAVE_INLINE_GPRS)
18933 || !(info_ptr->savres_strategy & SAVE_INLINE_FPRS)
18934 || !(info_ptr->savres_strategy & REST_INLINE_GPRS)
18935 || !(info_ptr->savres_strategy & REST_INLINE_FPRS))
18936 info_ptr->lr_save_p = 1;
18938 if (info_ptr->lr_save_p)
18939 df_set_regs_ever_live (LR_REGNO, true);
18941 /* Determine if we need to allocate any stack frame:
18943 For AIX we need to push the stack if a frame pointer is needed
18944 (because the stack might be dynamically adjusted), if we are
18945 debugging, if we make calls, or if the sum of fp_save, gp_save,
18946 and local variables are more than the space needed to save all
18947 non-volatile registers: 32-bit: 18*8 + 19*4 = 220 or 64-bit: 18*8
18948 + 18*8 = 288 (GPR13 reserved).
18950 For V.4 we don't have the stack cushion that AIX uses, but assume
18951 that the debugger can handle stackless frames. */
18953 if (info_ptr->calls_p)
18954 info_ptr->push_p = 1;
18956 else if (DEFAULT_ABI == ABI_V4)
18957 info_ptr->push_p = non_fixed_size != 0;
18959 else if (frame_pointer_needed)
18960 info_ptr->push_p = 1;
18962 else if (TARGET_XCOFF && write_symbols != NO_DEBUG)
18963 info_ptr->push_p = 1;
18965 else
18966 info_ptr->push_p = non_fixed_size > (TARGET_32BIT ? 220 : 288);
18968 /* Zero offsets if we're not saving those registers. */
18969 if (info_ptr->fp_size == 0)
18970 info_ptr->fp_save_offset = 0;
18972 if (info_ptr->gp_size == 0)
18973 info_ptr->gp_save_offset = 0;
18975 if (! TARGET_ALTIVEC_ABI || info_ptr->altivec_size == 0)
18976 info_ptr->altivec_save_offset = 0;
18978 if (! TARGET_ALTIVEC_ABI || info_ptr->vrsave_mask == 0)
18979 info_ptr->vrsave_save_offset = 0;
18981 if (! TARGET_SPE_ABI
18982 || info_ptr->spe_64bit_regs_used == 0
18983 || info_ptr->spe_gp_size == 0)
18984 info_ptr->spe_gp_save_offset = 0;
18986 if (! info_ptr->lr_save_p)
18987 info_ptr->lr_save_offset = 0;
18989 if (! info_ptr->cr_save_p)
18990 info_ptr->cr_save_offset = 0;
18992 #ifdef ENABLE_CHECKING
18993 gcc_assert (!(reload_completed && info_save.reload_completed)
18994 || memcmp (&info_save, &stack_info, sizeof stack_info) == 0);
18995 #endif
18996 return info_ptr;
18999 /* Return true if the current function uses any GPRs in 64-bit SIMD
19000 mode. */
19002 static bool
19003 spe_func_has_64bit_regs_p (void)
19005 rtx insns, insn;
19007 /* Functions that save and restore all the call-saved registers will
19008 need to save/restore the registers in 64-bits. */
19009 if (crtl->calls_eh_return
19010 || cfun->calls_setjmp
19011 || crtl->has_nonlocal_goto)
19012 return true;
19014 insns = get_insns ();
19016 for (insn = NEXT_INSN (insns); insn != NULL_RTX; insn = NEXT_INSN (insn))
19018 if (INSN_P (insn))
19020 rtx i;
19022 /* FIXME: This should be implemented with attributes...
19024 (set_attr "spe64" "true")....then,
19025 if (get_spe64(insn)) return true;
19027 It's the only reliable way to do the stuff below. */
19029 i = PATTERN (insn);
19030 if (GET_CODE (i) == SET)
19032 enum machine_mode mode = GET_MODE (SET_SRC (i));
19034 if (SPE_VECTOR_MODE (mode))
19035 return true;
19036 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode))
19037 return true;
19042 return false;
19045 static void
19046 debug_stack_info (rs6000_stack_t *info)
19048 const char *abi_string;
19050 if (! info)
19051 info = rs6000_stack_info ();
19053 fprintf (stderr, "\nStack information for function %s:\n",
19054 ((current_function_decl && DECL_NAME (current_function_decl))
19055 ? IDENTIFIER_POINTER (DECL_NAME (current_function_decl))
19056 : "<unknown>"));
19058 switch (info->abi)
19060 default: abi_string = "Unknown"; break;
19061 case ABI_NONE: abi_string = "NONE"; break;
19062 case ABI_AIX: abi_string = "AIX"; break;
19063 case ABI_DARWIN: abi_string = "Darwin"; break;
19064 case ABI_V4: abi_string = "V.4"; break;
19067 fprintf (stderr, "\tABI = %5s\n", abi_string);
19069 if (TARGET_ALTIVEC_ABI)
19070 fprintf (stderr, "\tALTIVEC ABI extensions enabled.\n");
19072 if (TARGET_SPE_ABI)
19073 fprintf (stderr, "\tSPE ABI extensions enabled.\n");
19075 if (info->first_gp_reg_save != 32)
19076 fprintf (stderr, "\tfirst_gp_reg_save = %5d\n", info->first_gp_reg_save);
19078 if (info->first_fp_reg_save != 64)
19079 fprintf (stderr, "\tfirst_fp_reg_save = %5d\n", info->first_fp_reg_save);
19081 if (info->first_altivec_reg_save <= LAST_ALTIVEC_REGNO)
19082 fprintf (stderr, "\tfirst_altivec_reg_save = %5d\n",
19083 info->first_altivec_reg_save);
19085 if (info->lr_save_p)
19086 fprintf (stderr, "\tlr_save_p = %5d\n", info->lr_save_p);
19088 if (info->cr_save_p)
19089 fprintf (stderr, "\tcr_save_p = %5d\n", info->cr_save_p);
19091 if (info->vrsave_mask)
19092 fprintf (stderr, "\tvrsave_mask = 0x%x\n", info->vrsave_mask);
19094 if (info->push_p)
19095 fprintf (stderr, "\tpush_p = %5d\n", info->push_p);
19097 if (info->calls_p)
19098 fprintf (stderr, "\tcalls_p = %5d\n", info->calls_p);
19100 if (info->gp_save_offset)
19101 fprintf (stderr, "\tgp_save_offset = %5d\n", info->gp_save_offset);
19103 if (info->fp_save_offset)
19104 fprintf (stderr, "\tfp_save_offset = %5d\n", info->fp_save_offset);
19106 if (info->altivec_save_offset)
19107 fprintf (stderr, "\taltivec_save_offset = %5d\n",
19108 info->altivec_save_offset);
19110 if (info->spe_gp_save_offset)
19111 fprintf (stderr, "\tspe_gp_save_offset = %5d\n",
19112 info->spe_gp_save_offset);
19114 if (info->vrsave_save_offset)
19115 fprintf (stderr, "\tvrsave_save_offset = %5d\n",
19116 info->vrsave_save_offset);
19118 if (info->lr_save_offset)
19119 fprintf (stderr, "\tlr_save_offset = %5d\n", info->lr_save_offset);
19121 if (info->cr_save_offset)
19122 fprintf (stderr, "\tcr_save_offset = %5d\n", info->cr_save_offset);
19124 if (info->varargs_save_offset)
19125 fprintf (stderr, "\tvarargs_save_offset = %5d\n", info->varargs_save_offset);
19127 if (info->total_size)
19128 fprintf (stderr, "\ttotal_size = "HOST_WIDE_INT_PRINT_DEC"\n",
19129 info->total_size);
19131 if (info->vars_size)
19132 fprintf (stderr, "\tvars_size = "HOST_WIDE_INT_PRINT_DEC"\n",
19133 info->vars_size);
19135 if (info->parm_size)
19136 fprintf (stderr, "\tparm_size = %5d\n", info->parm_size);
19138 if (info->fixed_size)
19139 fprintf (stderr, "\tfixed_size = %5d\n", info->fixed_size);
19141 if (info->gp_size)
19142 fprintf (stderr, "\tgp_size = %5d\n", info->gp_size);
19144 if (info->spe_gp_size)
19145 fprintf (stderr, "\tspe_gp_size = %5d\n", info->spe_gp_size);
19147 if (info->fp_size)
19148 fprintf (stderr, "\tfp_size = %5d\n", info->fp_size);
19150 if (info->altivec_size)
19151 fprintf (stderr, "\taltivec_size = %5d\n", info->altivec_size);
19153 if (info->vrsave_size)
19154 fprintf (stderr, "\tvrsave_size = %5d\n", info->vrsave_size);
19156 if (info->altivec_padding_size)
19157 fprintf (stderr, "\taltivec_padding_size= %5d\n",
19158 info->altivec_padding_size);
19160 if (info->spe_padding_size)
19161 fprintf (stderr, "\tspe_padding_size = %5d\n",
19162 info->spe_padding_size);
19164 if (info->cr_size)
19165 fprintf (stderr, "\tcr_size = %5d\n", info->cr_size);
19167 if (info->save_size)
19168 fprintf (stderr, "\tsave_size = %5d\n", info->save_size);
19170 if (info->reg_size != 4)
19171 fprintf (stderr, "\treg_size = %5d\n", info->reg_size);
19173 fprintf (stderr, "\n");
19177 rs6000_return_addr (int count, rtx frame)
19179 /* Currently we don't optimize very well between prolog and body
19180 code and for PIC code the code can be actually quite bad, so
19181 don't try to be too clever here. */
19182 if (count != 0 || (DEFAULT_ABI != ABI_AIX && flag_pic))
19184 cfun->machine->ra_needs_full_frame = 1;
19186 return
19187 gen_rtx_MEM
19188 (Pmode,
19189 memory_address
19190 (Pmode,
19191 plus_constant (copy_to_reg
19192 (gen_rtx_MEM (Pmode,
19193 memory_address (Pmode, frame))),
19194 RETURN_ADDRESS_OFFSET)));
19197 cfun->machine->ra_need_lr = 1;
19198 return get_hard_reg_initial_val (Pmode, LR_REGNO);
19201 /* Say whether a function is a candidate for sibcall handling or not.
19202 We do not allow indirect calls to be optimized into sibling calls.
19203 Also, we can't do it if there are any vector parameters; there's
19204 nowhere to put the VRsave code so it works; note that functions with
19205 vector parameters are required to have a prototype, so the argument
19206 type info must be available here. (The tail recursion case can work
19207 with vector parameters, but there's no way to distinguish here.) */
19208 static bool
19209 rs6000_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED)
19211 tree type;
19212 if (decl)
19214 if (TARGET_ALTIVEC_VRSAVE)
19216 for (type = TYPE_ARG_TYPES (TREE_TYPE (decl));
19217 type; type = TREE_CHAIN (type))
19219 if (TREE_CODE (TREE_VALUE (type)) == VECTOR_TYPE)
19220 return false;
19223 if (DEFAULT_ABI == ABI_DARWIN
19224 || ((*targetm.binds_local_p) (decl)
19225 && (DEFAULT_ABI != ABI_AIX || !DECL_EXTERNAL (decl))))
19227 tree attr_list = TYPE_ATTRIBUTES (TREE_TYPE (decl));
19229 if (!lookup_attribute ("longcall", attr_list)
19230 || lookup_attribute ("shortcall", attr_list))
19231 return true;
19234 return false;
19237 /* NULL if INSN insn is valid within a low-overhead loop.
19238 Otherwise return why doloop cannot be applied.
19239 PowerPC uses the COUNT register for branch on table instructions. */
19241 static const char *
19242 rs6000_invalid_within_doloop (const_rtx insn)
19244 if (CALL_P (insn))
19245 return "Function call in the loop.";
19247 if (JUMP_P (insn)
19248 && (GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC
19249 || GET_CODE (PATTERN (insn)) == ADDR_VEC))
19250 return "Computed branch in the loop.";
19252 return NULL;
19255 static int
19256 rs6000_ra_ever_killed (void)
19258 rtx top;
19259 rtx reg;
19260 rtx insn;
19262 if (cfun->is_thunk)
19263 return 0;
19265 if (cfun->machine->lr_save_state)
19266 return cfun->machine->lr_save_state - 1;
19268 /* regs_ever_live has LR marked as used if any sibcalls are present,
19269 but this should not force saving and restoring in the
19270 pro/epilogue. Likewise, reg_set_between_p thinks a sibcall
19271 clobbers LR, so that is inappropriate. */
19273 /* Also, the prologue can generate a store into LR that
19274 doesn't really count, like this:
19276 move LR->R0
19277 bcl to set PIC register
19278 move LR->R31
19279 move R0->LR
19281 When we're called from the epilogue, we need to avoid counting
19282 this as a store. */
19284 push_topmost_sequence ();
19285 top = get_insns ();
19286 pop_topmost_sequence ();
19287 reg = gen_rtx_REG (Pmode, LR_REGNO);
19289 for (insn = NEXT_INSN (top); insn != NULL_RTX; insn = NEXT_INSN (insn))
19291 if (INSN_P (insn))
19293 if (CALL_P (insn))
19295 if (!SIBLING_CALL_P (insn))
19296 return 1;
19298 else if (find_regno_note (insn, REG_INC, LR_REGNO))
19299 return 1;
19300 else if (set_of (reg, insn) != NULL_RTX
19301 && !prologue_epilogue_contains (insn))
19302 return 1;
19305 return 0;
19308 /* Emit instructions needed to load the TOC register.
19309 This is only needed when TARGET_TOC, TARGET_MINIMAL_TOC, and there is
19310 a constant pool; or for SVR4 -fpic. */
19312 void
19313 rs6000_emit_load_toc_table (int fromprolog)
19315 rtx dest;
19316 dest = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
19318 if (TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI != ABI_AIX && flag_pic)
19320 char buf[30];
19321 rtx lab, tmp1, tmp2, got;
19323 lab = gen_label_rtx ();
19324 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (lab));
19325 lab = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
19326 if (flag_pic == 2)
19327 got = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
19328 else
19329 got = rs6000_got_sym ();
19330 tmp1 = tmp2 = dest;
19331 if (!fromprolog)
19333 tmp1 = gen_reg_rtx (Pmode);
19334 tmp2 = gen_reg_rtx (Pmode);
19336 emit_insn (gen_load_toc_v4_PIC_1 (lab));
19337 emit_move_insn (tmp1, gen_rtx_REG (Pmode, LR_REGNO));
19338 emit_insn (gen_load_toc_v4_PIC_3b (tmp2, tmp1, got, lab));
19339 emit_insn (gen_load_toc_v4_PIC_3c (dest, tmp2, got, lab));
19341 else if (TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 1)
19343 emit_insn (gen_load_toc_v4_pic_si ());
19344 emit_move_insn (dest, gen_rtx_REG (Pmode, LR_REGNO));
19346 else if (TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2)
19348 char buf[30];
19349 rtx temp0 = (fromprolog
19350 ? gen_rtx_REG (Pmode, 0)
19351 : gen_reg_rtx (Pmode));
19353 if (fromprolog)
19355 rtx symF, symL;
19357 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
19358 symF = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
19360 ASM_GENERATE_INTERNAL_LABEL (buf, "LCL", rs6000_pic_labelno);
19361 symL = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
19363 emit_insn (gen_load_toc_v4_PIC_1 (symF));
19364 emit_move_insn (dest, gen_rtx_REG (Pmode, LR_REGNO));
19365 emit_insn (gen_load_toc_v4_PIC_2 (temp0, dest, symL, symF));
19367 else
19369 rtx tocsym, lab;
19371 tocsym = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
19372 lab = gen_label_rtx ();
19373 emit_insn (gen_load_toc_v4_PIC_1b (tocsym, lab));
19374 emit_move_insn (dest, gen_rtx_REG (Pmode, LR_REGNO));
19375 emit_move_insn (temp0, gen_rtx_MEM (Pmode, dest));
19377 emit_insn (gen_addsi3 (dest, temp0, dest));
19379 else if (TARGET_ELF && !TARGET_AIX && flag_pic == 0 && TARGET_MINIMAL_TOC)
19381 /* This is for AIX code running in non-PIC ELF32. */
19382 char buf[30];
19383 rtx realsym;
19384 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
19385 realsym = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
19387 emit_insn (gen_elf_high (dest, realsym));
19388 emit_insn (gen_elf_low (dest, dest, realsym));
19390 else
19392 gcc_assert (DEFAULT_ABI == ABI_AIX);
19394 if (TARGET_32BIT)
19395 emit_insn (gen_load_toc_aix_si (dest));
19396 else
19397 emit_insn (gen_load_toc_aix_di (dest));
19401 /* Emit instructions to restore the link register after determining where
19402 its value has been stored. */
19404 void
19405 rs6000_emit_eh_reg_restore (rtx source, rtx scratch)
19407 rs6000_stack_t *info = rs6000_stack_info ();
19408 rtx operands[2];
19410 operands[0] = source;
19411 operands[1] = scratch;
19413 if (info->lr_save_p)
19415 rtx frame_rtx = stack_pointer_rtx;
19416 HOST_WIDE_INT sp_offset = 0;
19417 rtx tmp;
19419 if (frame_pointer_needed
19420 || cfun->calls_alloca
19421 || info->total_size > 32767)
19423 tmp = gen_frame_mem (Pmode, frame_rtx);
19424 emit_move_insn (operands[1], tmp);
19425 frame_rtx = operands[1];
19427 else if (info->push_p)
19428 sp_offset = info->total_size;
19430 tmp = plus_constant (frame_rtx, info->lr_save_offset + sp_offset);
19431 tmp = gen_frame_mem (Pmode, tmp);
19432 emit_move_insn (tmp, operands[0]);
19434 else
19435 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO), operands[0]);
19437 /* Freeze lr_save_p. We've just emitted rtl that depends on the
19438 state of lr_save_p so any change from here on would be a bug. In
19439 particular, stop rs6000_ra_ever_killed from considering the SET
19440 of lr we may have added just above. */
19441 cfun->machine->lr_save_state = info->lr_save_p + 1;
19444 static GTY(()) alias_set_type set = -1;
19446 alias_set_type
19447 get_TOC_alias_set (void)
19449 if (set == -1)
19450 set = new_alias_set ();
19451 return set;
19454 /* This returns nonzero if the current function uses the TOC. This is
19455 determined by the presence of (use (unspec ... UNSPEC_TOC)), which
19456 is generated by the ABI_V4 load_toc_* patterns. */
19457 #if TARGET_ELF
19458 static int
19459 uses_TOC (void)
19461 rtx insn;
19463 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
19464 if (INSN_P (insn))
19466 rtx pat = PATTERN (insn);
19467 int i;
19469 if (GET_CODE (pat) == PARALLEL)
19470 for (i = 0; i < XVECLEN (pat, 0); i++)
19472 rtx sub = XVECEXP (pat, 0, i);
19473 if (GET_CODE (sub) == USE)
19475 sub = XEXP (sub, 0);
19476 if (GET_CODE (sub) == UNSPEC
19477 && XINT (sub, 1) == UNSPEC_TOC)
19478 return 1;
19482 return 0;
19484 #endif
19487 create_TOC_reference (rtx symbol, rtx largetoc_reg)
19489 rtx tocrel, tocreg;
19491 if (TARGET_DEBUG_ADDR)
19493 if (GET_CODE (symbol) == SYMBOL_REF)
19494 fprintf (stderr, "\ncreate_TOC_reference, (symbol_ref %s)\n",
19495 XSTR (symbol, 0));
19496 else
19498 fprintf (stderr, "\ncreate_TOC_reference, code %s:\n",
19499 GET_RTX_NAME (GET_CODE (symbol)));
19500 debug_rtx (symbol);
19504 if (!can_create_pseudo_p ())
19505 df_set_regs_ever_live (TOC_REGISTER, true);
19507 tocrel = gen_rtx_CONST (Pmode,
19508 gen_rtx_UNSPEC (Pmode, gen_rtvec (1, symbol),
19509 UNSPEC_TOCREL));
19510 tocreg = gen_rtx_REG (Pmode, TOC_REGISTER);
19511 if (TARGET_CMODEL != CMODEL_SMALL)
19513 rtx hi = gen_rtx_PLUS (Pmode, tocreg, gen_rtx_HIGH (Pmode, tocrel));
19514 if (largetoc_reg != NULL)
19516 emit_move_insn (largetoc_reg, hi);
19517 hi = largetoc_reg;
19519 return gen_rtx_LO_SUM (Pmode, hi, copy_rtx (tocrel));
19521 else
19522 return gen_rtx_PLUS (Pmode, tocreg, tocrel);
19525 /* Issue assembly directives that create a reference to the given DWARF
19526 FRAME_TABLE_LABEL from the current function section. */
19527 void
19528 rs6000_aix_asm_output_dwarf_table_ref (char * frame_table_label)
19530 fprintf (asm_out_file, "\t.ref %s\n",
19531 TARGET_STRIP_NAME_ENCODING (frame_table_label));
19534 /* This ties together stack memory (MEM with an alias set of frame_alias_set)
19535 and the change to the stack pointer. */
19537 static void
19538 rs6000_emit_stack_tie (void)
19540 rtx mem = gen_frame_mem (BLKmode,
19541 gen_rtx_REG (Pmode, STACK_POINTER_REGNUM));
19543 emit_insn (gen_stack_tie (mem));
19546 /* Emit the correct code for allocating stack space, as insns.
19547 If COPY_REG, make sure a copy of the old frame is left there.
19548 The generated code may use hard register 0 as a temporary. */
19550 static void
19551 rs6000_emit_allocate_stack (HOST_WIDE_INT size, rtx copy_reg)
19553 rtx insn;
19554 rtx stack_reg = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
19555 rtx tmp_reg = gen_rtx_REG (Pmode, 0);
19556 rtx todec = gen_int_mode (-size, Pmode);
19557 rtx par, set, mem;
19559 if (INTVAL (todec) != -size)
19561 warning (0, "stack frame too large");
19562 emit_insn (gen_trap ());
19563 return;
19566 if (crtl->limit_stack)
19568 if (REG_P (stack_limit_rtx)
19569 && REGNO (stack_limit_rtx) > 1
19570 && REGNO (stack_limit_rtx) <= 31)
19572 emit_insn (gen_add3_insn (tmp_reg, stack_limit_rtx, GEN_INT (size)));
19573 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
19574 const0_rtx));
19576 else if (GET_CODE (stack_limit_rtx) == SYMBOL_REF
19577 && TARGET_32BIT
19578 && DEFAULT_ABI == ABI_V4)
19580 rtx toload = gen_rtx_CONST (VOIDmode,
19581 gen_rtx_PLUS (Pmode,
19582 stack_limit_rtx,
19583 GEN_INT (size)));
19585 emit_insn (gen_elf_high (tmp_reg, toload));
19586 emit_insn (gen_elf_low (tmp_reg, tmp_reg, toload));
19587 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
19588 const0_rtx));
19590 else
19591 warning (0, "stack limit expression is not supported");
19594 if (copy_reg)
19595 emit_move_insn (copy_reg, stack_reg);
19597 if (size > 32767)
19599 /* Need a note here so that try_split doesn't get confused. */
19600 if (get_last_insn () == NULL_RTX)
19601 emit_note (NOTE_INSN_DELETED);
19602 insn = emit_move_insn (tmp_reg, todec);
19603 try_split (PATTERN (insn), insn, 0);
19604 todec = tmp_reg;
19607 insn = emit_insn (TARGET_32BIT
19608 ? gen_movsi_update_stack (stack_reg, stack_reg,
19609 todec, stack_reg)
19610 : gen_movdi_di_update_stack (stack_reg, stack_reg,
19611 todec, stack_reg));
19612 /* Since we didn't use gen_frame_mem to generate the MEM, grab
19613 it now and set the alias set/attributes. The above gen_*_update
19614 calls will generate a PARALLEL with the MEM set being the first
19615 operation. */
19616 par = PATTERN (insn);
19617 gcc_assert (GET_CODE (par) == PARALLEL);
19618 set = XVECEXP (par, 0, 0);
19619 gcc_assert (GET_CODE (set) == SET);
19620 mem = SET_DEST (set);
19621 gcc_assert (MEM_P (mem));
19622 MEM_NOTRAP_P (mem) = 1;
19623 set_mem_alias_set (mem, get_frame_alias_set ());
19625 RTX_FRAME_RELATED_P (insn) = 1;
19626 add_reg_note (insn, REG_FRAME_RELATED_EXPR,
19627 gen_rtx_SET (VOIDmode, stack_reg,
19628 gen_rtx_PLUS (Pmode, stack_reg,
19629 GEN_INT (-size))));
19632 #define PROBE_INTERVAL (1 << STACK_CHECK_PROBE_INTERVAL_EXP)
19634 #if PROBE_INTERVAL > 32768
19635 #error Cannot use indexed addressing mode for stack probing
19636 #endif
19638 /* Emit code to probe a range of stack addresses from FIRST to FIRST+SIZE,
19639 inclusive. These are offsets from the current stack pointer. */
19641 static void
19642 rs6000_emit_probe_stack_range (HOST_WIDE_INT first, HOST_WIDE_INT size)
19644 /* See if we have a constant small number of probes to generate. If so,
19645 that's the easy case. */
19646 if (first + size <= 32768)
19648 HOST_WIDE_INT i;
19650 /* Probe at FIRST + N * PROBE_INTERVAL for values of N from 1 until
19651 it exceeds SIZE. If only one probe is needed, this will not
19652 generate any code. Then probe at FIRST + SIZE. */
19653 for (i = PROBE_INTERVAL; i < size; i += PROBE_INTERVAL)
19654 emit_stack_probe (plus_constant (stack_pointer_rtx, -(first + i)));
19656 emit_stack_probe (plus_constant (stack_pointer_rtx, -(first + size)));
19659 /* Otherwise, do the same as above, but in a loop. Note that we must be
19660 extra careful with variables wrapping around because we might be at
19661 the very top (or the very bottom) of the address space and we have
19662 to be able to handle this case properly; in particular, we use an
19663 equality test for the loop condition. */
19664 else
19666 HOST_WIDE_INT rounded_size;
19667 rtx r12 = gen_rtx_REG (Pmode, 12);
19668 rtx r0 = gen_rtx_REG (Pmode, 0);
19670 /* Sanity check for the addressing mode we're going to use. */
19671 gcc_assert (first <= 32768);
19673 /* Step 1: round SIZE to the previous multiple of the interval. */
19675 rounded_size = size & -PROBE_INTERVAL;
19678 /* Step 2: compute initial and final value of the loop counter. */
19680 /* TEST_ADDR = SP + FIRST. */
19681 emit_insn (gen_rtx_SET (VOIDmode, r12,
19682 plus_constant (stack_pointer_rtx, -first)));
19684 /* LAST_ADDR = SP + FIRST + ROUNDED_SIZE. */
19685 if (rounded_size > 32768)
19687 emit_move_insn (r0, GEN_INT (-rounded_size));
19688 emit_insn (gen_rtx_SET (VOIDmode, r0,
19689 gen_rtx_PLUS (Pmode, r12, r0)));
19691 else
19692 emit_insn (gen_rtx_SET (VOIDmode, r0,
19693 plus_constant (r12, -rounded_size)));
19696 /* Step 3: the loop
19698 while (TEST_ADDR != LAST_ADDR)
19700 TEST_ADDR = TEST_ADDR + PROBE_INTERVAL
19701 probe at TEST_ADDR
19704 probes at FIRST + N * PROBE_INTERVAL for values of N from 1
19705 until it is equal to ROUNDED_SIZE. */
19707 if (TARGET_64BIT)
19708 emit_insn (gen_probe_stack_rangedi (r12, r12, r0));
19709 else
19710 emit_insn (gen_probe_stack_rangesi (r12, r12, r0));
19713 /* Step 4: probe at FIRST + SIZE if we cannot assert at compile-time
19714 that SIZE is equal to ROUNDED_SIZE. */
19716 if (size != rounded_size)
19717 emit_stack_probe (plus_constant (r12, rounded_size - size));
19721 /* Probe a range of stack addresses from REG1 to REG2 inclusive. These are
19722 absolute addresses. */
19724 const char *
19725 output_probe_stack_range (rtx reg1, rtx reg2)
19727 static int labelno = 0;
19728 char loop_lab[32], end_lab[32];
19729 rtx xops[2];
19731 ASM_GENERATE_INTERNAL_LABEL (loop_lab, "LPSRL", labelno);
19732 ASM_GENERATE_INTERNAL_LABEL (end_lab, "LPSRE", labelno++);
19734 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, loop_lab);
19736 /* Jump to END_LAB if TEST_ADDR == LAST_ADDR. */
19737 xops[0] = reg1;
19738 xops[1] = reg2;
19739 if (TARGET_64BIT)
19740 output_asm_insn ("{cmp|cmpd} 0,%0,%1", xops);
19741 else
19742 output_asm_insn ("{cmp|cmpw} 0,%0,%1", xops);
19744 fputs ("\tbeq 0,", asm_out_file);
19745 assemble_name_raw (asm_out_file, end_lab);
19746 fputc ('\n', asm_out_file);
19748 /* TEST_ADDR = TEST_ADDR + PROBE_INTERVAL. */
19749 xops[1] = GEN_INT (-PROBE_INTERVAL);
19750 output_asm_insn ("{cal %0,%1(%0)|addi %0,%0,%1}", xops);
19752 /* Probe at TEST_ADDR and branch. */
19753 output_asm_insn ("{st|stw} 0,0(%0)", xops);
19754 fprintf (asm_out_file, "\tb ");
19755 assemble_name_raw (asm_out_file, loop_lab);
19756 fputc ('\n', asm_out_file);
19758 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, end_lab);
19760 return "";
19763 /* Add to 'insn' a note which is PATTERN (INSN) but with REG replaced
19764 with (plus:P (reg 1) VAL), and with REG2 replaced with RREG if REG2
19765 is not NULL. It would be nice if dwarf2out_frame_debug_expr could
19766 deduce these equivalences by itself so it wasn't necessary to hold
19767 its hand so much. */
19769 static void
19770 rs6000_frame_related (rtx insn, rtx reg, HOST_WIDE_INT val,
19771 rtx reg2, rtx rreg)
19773 rtx real, temp;
19775 /* copy_rtx will not make unique copies of registers, so we need to
19776 ensure we don't have unwanted sharing here. */
19777 if (reg == reg2)
19778 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
19780 if (reg == rreg)
19781 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
19783 real = copy_rtx (PATTERN (insn));
19785 if (reg2 != NULL_RTX)
19786 real = replace_rtx (real, reg2, rreg);
19788 real = replace_rtx (real, reg,
19789 gen_rtx_PLUS (Pmode, gen_rtx_REG (Pmode,
19790 STACK_POINTER_REGNUM),
19791 GEN_INT (val)));
19793 /* We expect that 'real' is either a SET or a PARALLEL containing
19794 SETs (and possibly other stuff). In a PARALLEL, all the SETs
19795 are important so they all have to be marked RTX_FRAME_RELATED_P. */
19797 if (GET_CODE (real) == SET)
19799 rtx set = real;
19801 temp = simplify_rtx (SET_SRC (set));
19802 if (temp)
19803 SET_SRC (set) = temp;
19804 temp = simplify_rtx (SET_DEST (set));
19805 if (temp)
19806 SET_DEST (set) = temp;
19807 if (GET_CODE (SET_DEST (set)) == MEM)
19809 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
19810 if (temp)
19811 XEXP (SET_DEST (set), 0) = temp;
19814 else
19816 int i;
19818 gcc_assert (GET_CODE (real) == PARALLEL);
19819 for (i = 0; i < XVECLEN (real, 0); i++)
19820 if (GET_CODE (XVECEXP (real, 0, i)) == SET)
19822 rtx set = XVECEXP (real, 0, i);
19824 temp = simplify_rtx (SET_SRC (set));
19825 if (temp)
19826 SET_SRC (set) = temp;
19827 temp = simplify_rtx (SET_DEST (set));
19828 if (temp)
19829 SET_DEST (set) = temp;
19830 if (GET_CODE (SET_DEST (set)) == MEM)
19832 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
19833 if (temp)
19834 XEXP (SET_DEST (set), 0) = temp;
19836 RTX_FRAME_RELATED_P (set) = 1;
19840 RTX_FRAME_RELATED_P (insn) = 1;
19841 add_reg_note (insn, REG_FRAME_RELATED_EXPR, real);
19844 /* Returns an insn that has a vrsave set operation with the
19845 appropriate CLOBBERs. */
19847 static rtx
19848 generate_set_vrsave (rtx reg, rs6000_stack_t *info, int epiloguep)
19850 int nclobs, i;
19851 rtx insn, clobs[TOTAL_ALTIVEC_REGS + 1];
19852 rtx vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
19854 clobs[0]
19855 = gen_rtx_SET (VOIDmode,
19856 vrsave,
19857 gen_rtx_UNSPEC_VOLATILE (SImode,
19858 gen_rtvec (2, reg, vrsave),
19859 UNSPECV_SET_VRSAVE));
19861 nclobs = 1;
19863 /* We need to clobber the registers in the mask so the scheduler
19864 does not move sets to VRSAVE before sets of AltiVec registers.
19866 However, if the function receives nonlocal gotos, reload will set
19867 all call saved registers live. We will end up with:
19869 (set (reg 999) (mem))
19870 (parallel [ (set (reg vrsave) (unspec blah))
19871 (clobber (reg 999))])
19873 The clobber will cause the store into reg 999 to be dead, and
19874 flow will attempt to delete an epilogue insn. In this case, we
19875 need an unspec use/set of the register. */
19877 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
19878 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
19880 if (!epiloguep || call_used_regs [i])
19881 clobs[nclobs++] = gen_rtx_CLOBBER (VOIDmode,
19882 gen_rtx_REG (V4SImode, i));
19883 else
19885 rtx reg = gen_rtx_REG (V4SImode, i);
19887 clobs[nclobs++]
19888 = gen_rtx_SET (VOIDmode,
19889 reg,
19890 gen_rtx_UNSPEC (V4SImode,
19891 gen_rtvec (1, reg), 27));
19895 insn = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (nclobs));
19897 for (i = 0; i < nclobs; ++i)
19898 XVECEXP (insn, 0, i) = clobs[i];
19900 return insn;
19903 /* Save a register into the frame, and emit RTX_FRAME_RELATED_P notes.
19904 Save REGNO into [FRAME_REG + OFFSET] in mode MODE. */
19906 static void
19907 emit_frame_save (rtx frame_reg, rtx frame_ptr, enum machine_mode mode,
19908 unsigned int regno, int offset, HOST_WIDE_INT total_size)
19910 rtx reg, offset_rtx, insn, mem, addr, int_rtx;
19911 rtx replacea, replaceb;
19913 int_rtx = GEN_INT (offset);
19915 /* Some cases that need register indexed addressing. */
19916 if ((TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
19917 || (TARGET_VSX && VSX_VECTOR_MODE (mode))
19918 || (TARGET_E500_DOUBLE && mode == DFmode)
19919 || (TARGET_SPE_ABI
19920 && SPE_VECTOR_MODE (mode)
19921 && !SPE_CONST_OFFSET_OK (offset)))
19923 /* Whomever calls us must make sure r11 is available in the
19924 flow path of instructions in the prologue. */
19925 offset_rtx = gen_rtx_REG (Pmode, 11);
19926 emit_move_insn (offset_rtx, int_rtx);
19928 replacea = offset_rtx;
19929 replaceb = int_rtx;
19931 else
19933 offset_rtx = int_rtx;
19934 replacea = NULL_RTX;
19935 replaceb = NULL_RTX;
19938 reg = gen_rtx_REG (mode, regno);
19939 addr = gen_rtx_PLUS (Pmode, frame_reg, offset_rtx);
19940 mem = gen_frame_mem (mode, addr);
19942 insn = emit_move_insn (mem, reg);
19944 rs6000_frame_related (insn, frame_ptr, total_size, replacea, replaceb);
19947 /* Emit an offset memory reference suitable for a frame store, while
19948 converting to a valid addressing mode. */
19950 static rtx
19951 gen_frame_mem_offset (enum machine_mode mode, rtx reg, int offset)
19953 rtx int_rtx, offset_rtx;
19955 int_rtx = GEN_INT (offset);
19957 if ((TARGET_SPE_ABI && SPE_VECTOR_MODE (mode))
19958 || (TARGET_E500_DOUBLE && mode == DFmode))
19960 offset_rtx = gen_rtx_REG (Pmode, FIXED_SCRATCH);
19961 emit_move_insn (offset_rtx, int_rtx);
19963 else
19964 offset_rtx = int_rtx;
19966 return gen_frame_mem (mode, gen_rtx_PLUS (Pmode, reg, offset_rtx));
19969 /* Look for user-defined global regs. We should not save and restore these,
19970 and cannot use stmw/lmw if there are any in its range. */
19972 static bool
19973 no_global_regs_above (int first, bool gpr)
19975 int i;
19976 int last = gpr ? 32 : 64;
19977 for (i = first; i < last; i++)
19978 if (global_regs[i])
19979 return false;
19980 return true;
19983 #ifndef TARGET_FIX_AND_CONTINUE
19984 #define TARGET_FIX_AND_CONTINUE 0
19985 #endif
19987 /* It's really GPR 13 and FPR 14, but we need the smaller of the two. */
19988 #define FIRST_SAVRES_REGISTER FIRST_SAVED_GP_REGNO
19989 #define LAST_SAVRES_REGISTER 31
19990 #define N_SAVRES_REGISTERS (LAST_SAVRES_REGISTER - FIRST_SAVRES_REGISTER + 1)
19992 static GTY(()) rtx savres_routine_syms[N_SAVRES_REGISTERS][8];
19994 /* Temporary holding space for an out-of-line register save/restore
19995 routine name. */
19996 static char savres_routine_name[30];
19998 /* Return the name for an out-of-line register save/restore routine.
19999 We are saving/restoring GPRs if GPR is true. */
20001 static char *
20002 rs6000_savres_routine_name (rs6000_stack_t *info, int regno,
20003 bool savep, bool gpr, bool lr)
20005 const char *prefix = "";
20006 const char *suffix = "";
20008 /* Different targets are supposed to define
20009 {SAVE,RESTORE}_FP_{PREFIX,SUFFIX} with the idea that the needed
20010 routine name could be defined with:
20012 sprintf (name, "%s%d%s", SAVE_FP_PREFIX, regno, SAVE_FP_SUFFIX)
20014 This is a nice idea in practice, but in reality, things are
20015 complicated in several ways:
20017 - ELF targets have save/restore routines for GPRs.
20019 - SPE targets use different prefixes for 32/64-bit registers, and
20020 neither of them fit neatly in the FOO_{PREFIX,SUFFIX} regimen.
20022 - PPC64 ELF targets have routines for save/restore of GPRs that
20023 differ in what they do with the link register, so having a set
20024 prefix doesn't work. (We only use one of the save routines at
20025 the moment, though.)
20027 - PPC32 elf targets have "exit" versions of the restore routines
20028 that restore the link register and can save some extra space.
20029 These require an extra suffix. (There are also "tail" versions
20030 of the restore routines and "GOT" versions of the save routines,
20031 but we don't generate those at present. Same problems apply,
20032 though.)
20034 We deal with all this by synthesizing our own prefix/suffix and
20035 using that for the simple sprintf call shown above. */
20036 if (TARGET_SPE)
20038 /* No floating point saves on the SPE. */
20039 gcc_assert (gpr);
20041 if (savep)
20042 prefix = info->spe_64bit_regs_used ? "_save64gpr_" : "_save32gpr_";
20043 else
20044 prefix = info->spe_64bit_regs_used ? "_rest64gpr_" : "_rest32gpr_";
20046 if (lr)
20047 suffix = "_x";
20049 else if (DEFAULT_ABI == ABI_V4)
20051 if (TARGET_64BIT)
20052 goto aix_names;
20054 if (gpr)
20055 prefix = savep ? "_savegpr_" : "_restgpr_";
20056 else
20057 prefix = savep ? "_savefpr_" : "_restfpr_";
20059 if (lr)
20060 suffix = "_x";
20062 else if (DEFAULT_ABI == ABI_AIX)
20064 #ifndef POWERPC_LINUX
20065 /* No out-of-line save/restore routines for GPRs on AIX. */
20066 gcc_assert (!TARGET_AIX || !gpr);
20067 #endif
20069 aix_names:
20070 if (gpr)
20071 prefix = (savep
20072 ? (lr ? "_savegpr0_" : "_savegpr1_")
20073 : (lr ? "_restgpr0_" : "_restgpr1_"));
20074 #ifdef POWERPC_LINUX
20075 else if (lr)
20076 prefix = (savep ? "_savefpr_" : "_restfpr_");
20077 #endif
20078 else
20080 prefix = savep ? SAVE_FP_PREFIX : RESTORE_FP_PREFIX;
20081 suffix = savep ? SAVE_FP_SUFFIX : RESTORE_FP_SUFFIX;
20084 else if (DEFAULT_ABI == ABI_DARWIN)
20085 sorry ("out-of-line save/restore routines not supported on Darwin");
20087 sprintf (savres_routine_name, "%s%d%s", prefix, regno, suffix);
20089 return savres_routine_name;
20092 /* Return an RTL SYMBOL_REF for an out-of-line register save/restore routine.
20093 We are saving/restoring GPRs if GPR is true. */
20095 static rtx
20096 rs6000_savres_routine_sym (rs6000_stack_t *info, bool savep,
20097 bool gpr, bool lr)
20099 int regno = gpr ? info->first_gp_reg_save : (info->first_fp_reg_save - 32);
20100 rtx sym;
20101 int select = ((savep ? 1 : 0) << 2
20102 | ((TARGET_SPE_ABI
20103 /* On the SPE, we never have any FPRs, but we do have
20104 32/64-bit versions of the routines. */
20105 ? (info->spe_64bit_regs_used ? 1 : 0)
20106 : (gpr ? 1 : 0)) << 1)
20107 | (lr ? 1: 0));
20109 /* Don't generate bogus routine names. */
20110 gcc_assert (FIRST_SAVRES_REGISTER <= regno
20111 && regno <= LAST_SAVRES_REGISTER);
20113 sym = savres_routine_syms[regno-FIRST_SAVRES_REGISTER][select];
20115 if (sym == NULL)
20117 char *name;
20119 name = rs6000_savres_routine_name (info, regno, savep, gpr, lr);
20121 sym = savres_routine_syms[regno-FIRST_SAVRES_REGISTER][select]
20122 = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (name));
20123 SYMBOL_REF_FLAGS (sym) |= SYMBOL_FLAG_FUNCTION;
20126 return sym;
20129 /* Emit a sequence of insns, including a stack tie if needed, for
20130 resetting the stack pointer. If SAVRES is true, then don't reset the
20131 stack pointer, but move the base of the frame into r11 for use by
20132 out-of-line register restore routines. */
20134 static rtx
20135 rs6000_emit_stack_reset (rs6000_stack_t *info,
20136 rtx sp_reg_rtx, rtx frame_reg_rtx,
20137 int sp_offset, bool savres)
20139 /* This blockage is needed so that sched doesn't decide to move
20140 the sp change before the register restores. */
20141 if (frame_reg_rtx != sp_reg_rtx
20142 || (TARGET_SPE_ABI
20143 && info->spe_64bit_regs_used != 0
20144 && info->first_gp_reg_save != 32))
20145 rs6000_emit_stack_tie ();
20147 if (frame_reg_rtx != sp_reg_rtx)
20149 if (sp_offset != 0)
20151 rtx dest_reg = savres ? gen_rtx_REG (Pmode, 11) : sp_reg_rtx;
20152 return emit_insn (gen_add3_insn (dest_reg, frame_reg_rtx,
20153 GEN_INT (sp_offset)));
20155 else if (!savres)
20156 return emit_move_insn (sp_reg_rtx, frame_reg_rtx);
20158 else if (sp_offset != 0)
20160 /* If we are restoring registers out-of-line, we will be using the
20161 "exit" variants of the restore routines, which will reset the
20162 stack for us. But we do need to point r11 into the right place
20163 for those routines. */
20164 rtx dest_reg = (savres
20165 ? gen_rtx_REG (Pmode, 11)
20166 : sp_reg_rtx);
20168 rtx insn = emit_insn (gen_add3_insn (dest_reg, sp_reg_rtx,
20169 GEN_INT (sp_offset)));
20170 if (!savres)
20171 return insn;
20173 return NULL_RTX;
20176 /* Construct a parallel rtx describing the effect of a call to an
20177 out-of-line register save/restore routine. */
20179 static rtx
20180 rs6000_make_savres_rtx (rs6000_stack_t *info,
20181 rtx frame_reg_rtx, int save_area_offset,
20182 enum machine_mode reg_mode,
20183 bool savep, bool gpr, bool lr)
20185 int i;
20186 int offset, start_reg, end_reg, n_regs;
20187 int reg_size = GET_MODE_SIZE (reg_mode);
20188 rtx sym;
20189 rtvec p;
20191 offset = 0;
20192 start_reg = (gpr
20193 ? info->first_gp_reg_save
20194 : info->first_fp_reg_save);
20195 end_reg = gpr ? 32 : 64;
20196 n_regs = end_reg - start_reg;
20197 p = rtvec_alloc ((lr ? 4 : 3) + n_regs);
20199 if (!savep && lr)
20200 RTVEC_ELT (p, offset++) = gen_rtx_RETURN (VOIDmode);
20202 RTVEC_ELT (p, offset++)
20203 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 65));
20205 sym = rs6000_savres_routine_sym (info, savep, gpr, lr);
20206 RTVEC_ELT (p, offset++) = gen_rtx_USE (VOIDmode, sym);
20207 RTVEC_ELT (p, offset++)
20208 = gen_rtx_USE (VOIDmode,
20209 gen_rtx_REG (Pmode, DEFAULT_ABI != ABI_AIX ? 11
20210 : gpr && !lr ? 12
20211 : 1));
20213 for (i = 0; i < end_reg - start_reg; i++)
20215 rtx addr, reg, mem;
20216 reg = gen_rtx_REG (reg_mode, start_reg + i);
20217 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20218 GEN_INT (save_area_offset + reg_size*i));
20219 mem = gen_frame_mem (reg_mode, addr);
20221 RTVEC_ELT (p, i + offset) = gen_rtx_SET (VOIDmode,
20222 savep ? mem : reg,
20223 savep ? reg : mem);
20226 if (savep && lr)
20228 rtx addr, reg, mem;
20229 reg = gen_rtx_REG (Pmode, 0);
20230 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20231 GEN_INT (info->lr_save_offset));
20232 mem = gen_frame_mem (Pmode, addr);
20233 RTVEC_ELT (p, i + offset) = gen_rtx_SET (VOIDmode, mem, reg);
20236 return gen_rtx_PARALLEL (VOIDmode, p);
20239 /* Determine whether the gp REG is really used. */
20241 static bool
20242 rs6000_reg_live_or_pic_offset_p (int reg)
20244 /* If the function calls eh_return, claim used all the registers that would
20245 be checked for liveness otherwise. This is required for the PIC offset
20246 register with -mminimal-toc on AIX, as it is advertised as "fixed" for
20247 register allocation purposes in this case. */
20249 return (((crtl->calls_eh_return || df_regs_ever_live_p (reg))
20250 && (!call_used_regs[reg]
20251 || (reg == RS6000_PIC_OFFSET_TABLE_REGNUM
20252 && !TARGET_SINGLE_PIC_BASE
20253 && TARGET_TOC && TARGET_MINIMAL_TOC)))
20254 || (reg == RS6000_PIC_OFFSET_TABLE_REGNUM
20255 && !TARGET_SINGLE_PIC_BASE
20256 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
20257 || (DEFAULT_ABI == ABI_DARWIN && flag_pic))));
20260 /* Emit function prologue as insns. */
20262 void
20263 rs6000_emit_prologue (void)
20265 rs6000_stack_t *info = rs6000_stack_info ();
20266 enum machine_mode reg_mode = Pmode;
20267 int reg_size = TARGET_32BIT ? 4 : 8;
20268 rtx sp_reg_rtx = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
20269 rtx frame_ptr_rtx = gen_rtx_REG (Pmode, 12);
20270 rtx frame_reg_rtx = sp_reg_rtx;
20271 rtx cr_save_rtx = NULL_RTX;
20272 rtx insn;
20273 int strategy;
20274 int saving_FPRs_inline;
20275 int saving_GPRs_inline;
20276 int using_store_multiple;
20277 int using_static_chain_p = (cfun->static_chain_decl != NULL_TREE
20278 && df_regs_ever_live_p (STATIC_CHAIN_REGNUM)
20279 && call_used_regs[STATIC_CHAIN_REGNUM]);
20280 HOST_WIDE_INT sp_offset = 0;
20282 if (flag_stack_usage)
20283 current_function_static_stack_size = info->total_size;
20285 if (flag_stack_check == STATIC_BUILTIN_STACK_CHECK && info->total_size)
20286 rs6000_emit_probe_stack_range (STACK_CHECK_PROTECT, info->total_size);
20288 if (TARGET_FIX_AND_CONTINUE)
20290 /* gdb on darwin arranges to forward a function from the old
20291 address by modifying the first 5 instructions of the function
20292 to branch to the overriding function. This is necessary to
20293 permit function pointers that point to the old function to
20294 actually forward to the new function. */
20295 emit_insn (gen_nop ());
20296 emit_insn (gen_nop ());
20297 emit_insn (gen_nop ());
20298 emit_insn (gen_nop ());
20299 emit_insn (gen_nop ());
20302 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
20304 reg_mode = V2SImode;
20305 reg_size = 8;
20308 strategy = info->savres_strategy;
20309 using_store_multiple = strategy & SAVRES_MULTIPLE;
20310 saving_FPRs_inline = strategy & SAVE_INLINE_FPRS;
20311 saving_GPRs_inline = strategy & SAVE_INLINE_GPRS;
20313 /* For V.4, update stack before we do any saving and set back pointer. */
20314 if (! WORLD_SAVE_P (info)
20315 && info->push_p
20316 && (DEFAULT_ABI == ABI_V4
20317 || crtl->calls_eh_return))
20319 bool need_r11 = (TARGET_SPE
20320 ? (!saving_GPRs_inline
20321 && info->spe_64bit_regs_used == 0)
20322 : (!saving_FPRs_inline || !saving_GPRs_inline));
20323 rtx copy_reg = need_r11 ? gen_rtx_REG (Pmode, 11) : NULL;
20325 if (info->total_size < 32767)
20326 sp_offset = info->total_size;
20327 else if (need_r11)
20328 frame_reg_rtx = copy_reg;
20329 else if (info->cr_save_p
20330 || info->lr_save_p
20331 || info->first_fp_reg_save < 64
20332 || info->first_gp_reg_save < 32
20333 || info->altivec_size != 0
20334 || info->vrsave_mask != 0
20335 || crtl->calls_eh_return)
20337 copy_reg = frame_ptr_rtx;
20338 frame_reg_rtx = copy_reg;
20340 else
20342 /* The prologue won't be saving any regs so there is no need
20343 to set up a frame register to access any frame save area.
20344 We also won't be using sp_offset anywhere below, but set
20345 the correct value anyway to protect against future
20346 changes to this function. */
20347 sp_offset = info->total_size;
20349 rs6000_emit_allocate_stack (info->total_size, copy_reg);
20350 if (frame_reg_rtx != sp_reg_rtx)
20351 rs6000_emit_stack_tie ();
20354 /* Handle world saves specially here. */
20355 if (WORLD_SAVE_P (info))
20357 int i, j, sz;
20358 rtx treg;
20359 rtvec p;
20360 rtx reg0;
20362 /* save_world expects lr in r0. */
20363 reg0 = gen_rtx_REG (Pmode, 0);
20364 if (info->lr_save_p)
20366 insn = emit_move_insn (reg0,
20367 gen_rtx_REG (Pmode, LR_REGNO));
20368 RTX_FRAME_RELATED_P (insn) = 1;
20371 /* The SAVE_WORLD and RESTORE_WORLD routines make a number of
20372 assumptions about the offsets of various bits of the stack
20373 frame. */
20374 gcc_assert (info->gp_save_offset == -220
20375 && info->fp_save_offset == -144
20376 && info->lr_save_offset == 8
20377 && info->cr_save_offset == 4
20378 && info->push_p
20379 && info->lr_save_p
20380 && (!crtl->calls_eh_return
20381 || info->ehrd_offset == -432)
20382 && info->vrsave_save_offset == -224
20383 && info->altivec_save_offset == -416);
20385 treg = gen_rtx_REG (SImode, 11);
20386 emit_move_insn (treg, GEN_INT (-info->total_size));
20388 /* SAVE_WORLD takes the caller's LR in R0 and the frame size
20389 in R11. It also clobbers R12, so beware! */
20391 /* Preserve CR2 for save_world prologues */
20392 sz = 5;
20393 sz += 32 - info->first_gp_reg_save;
20394 sz += 64 - info->first_fp_reg_save;
20395 sz += LAST_ALTIVEC_REGNO - info->first_altivec_reg_save + 1;
20396 p = rtvec_alloc (sz);
20397 j = 0;
20398 RTVEC_ELT (p, j++) = gen_rtx_CLOBBER (VOIDmode,
20399 gen_rtx_REG (SImode,
20400 LR_REGNO));
20401 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
20402 gen_rtx_SYMBOL_REF (Pmode,
20403 "*save_world"));
20404 /* We do floats first so that the instruction pattern matches
20405 properly. */
20406 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
20408 rtx reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20409 ? DFmode : SFmode),
20410 info->first_fp_reg_save + i);
20411 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20412 GEN_INT (info->fp_save_offset
20413 + sp_offset + 8 * i));
20414 rtx mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20415 ? DFmode : SFmode), addr);
20417 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
20419 for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++)
20421 rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i);
20422 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20423 GEN_INT (info->altivec_save_offset
20424 + sp_offset + 16 * i));
20425 rtx mem = gen_frame_mem (V4SImode, addr);
20427 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
20429 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20431 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20432 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20433 GEN_INT (info->gp_save_offset
20434 + sp_offset + reg_size * i));
20435 rtx mem = gen_frame_mem (reg_mode, addr);
20437 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
20441 /* CR register traditionally saved as CR2. */
20442 rtx reg = gen_rtx_REG (reg_mode, CR2_REGNO);
20443 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20444 GEN_INT (info->cr_save_offset
20445 + sp_offset));
20446 rtx mem = gen_frame_mem (reg_mode, addr);
20448 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
20450 /* Explain about use of R0. */
20451 if (info->lr_save_p)
20453 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20454 GEN_INT (info->lr_save_offset
20455 + sp_offset));
20456 rtx mem = gen_frame_mem (reg_mode, addr);
20458 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg0);
20460 /* Explain what happens to the stack pointer. */
20462 rtx newval = gen_rtx_PLUS (Pmode, sp_reg_rtx, treg);
20463 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, sp_reg_rtx, newval);
20466 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
20467 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20468 treg, GEN_INT (-info->total_size));
20469 sp_offset = info->total_size;
20472 /* If we use the link register, get it into r0. */
20473 if (!WORLD_SAVE_P (info) && info->lr_save_p)
20475 rtx addr, reg, mem;
20477 insn = emit_move_insn (gen_rtx_REG (Pmode, 0),
20478 gen_rtx_REG (Pmode, LR_REGNO));
20479 RTX_FRAME_RELATED_P (insn) = 1;
20481 if (!(strategy & (SAVE_NOINLINE_GPRS_SAVES_LR
20482 | SAVE_NOINLINE_FPRS_SAVES_LR)))
20484 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20485 GEN_INT (info->lr_save_offset + sp_offset));
20486 reg = gen_rtx_REG (Pmode, 0);
20487 mem = gen_rtx_MEM (Pmode, addr);
20488 /* This should not be of rs6000_sr_alias_set, because of
20489 __builtin_return_address. */
20491 insn = emit_move_insn (mem, reg);
20492 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20493 NULL_RTX, NULL_RTX);
20497 /* If we need to save CR, put it into r12 or r11. */
20498 if (!WORLD_SAVE_P (info) && info->cr_save_p && frame_reg_rtx != frame_ptr_rtx)
20500 rtx set;
20502 cr_save_rtx
20503 = gen_rtx_REG (SImode, DEFAULT_ABI == ABI_AIX && !saving_GPRs_inline
20504 ? 11 : 12);
20505 insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
20506 RTX_FRAME_RELATED_P (insn) = 1;
20507 /* Now, there's no way that dwarf2out_frame_debug_expr is going
20508 to understand '(unspec:SI [(reg:CC 68) ...] UNSPEC_MOVESI_FROM_CR)'.
20509 But that's OK. All we have to do is specify that _one_ condition
20510 code register is saved in this stack slot. The thrower's epilogue
20511 will then restore all the call-saved registers.
20512 We use CR2_REGNO (70) to be compatible with gcc-2.95 on Linux. */
20513 set = gen_rtx_SET (VOIDmode, cr_save_rtx,
20514 gen_rtx_REG (SImode, CR2_REGNO));
20515 add_reg_note (insn, REG_FRAME_RELATED_EXPR, set);
20518 /* Do any required saving of fpr's. If only one or two to save, do
20519 it ourselves. Otherwise, call function. */
20520 if (!WORLD_SAVE_P (info) && saving_FPRs_inline)
20522 int i;
20523 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
20524 if ((df_regs_ever_live_p (info->first_fp_reg_save+i)
20525 && ! call_used_regs[info->first_fp_reg_save+i]))
20526 emit_frame_save (frame_reg_rtx, frame_ptr_rtx,
20527 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20528 ? DFmode : SFmode,
20529 info->first_fp_reg_save + i,
20530 info->fp_save_offset + sp_offset + 8 * i,
20531 info->total_size);
20533 else if (!WORLD_SAVE_P (info) && info->first_fp_reg_save != 64)
20535 rtx par;
20537 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
20538 info->fp_save_offset + sp_offset,
20539 DFmode,
20540 /*savep=*/true, /*gpr=*/false,
20541 /*lr=*/(strategy
20542 & SAVE_NOINLINE_FPRS_SAVES_LR)
20543 != 0);
20544 insn = emit_insn (par);
20545 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20546 NULL_RTX, NULL_RTX);
20549 /* Save GPRs. This is done as a PARALLEL if we are using
20550 the store-multiple instructions. */
20551 if (!WORLD_SAVE_P (info)
20552 && TARGET_SPE_ABI
20553 && info->spe_64bit_regs_used != 0
20554 && info->first_gp_reg_save != 32)
20556 int i;
20557 rtx spe_save_area_ptr;
20559 /* Determine whether we can address all of the registers that need
20560 to be saved with an offset from the stack pointer that fits in
20561 the small const field for SPE memory instructions. */
20562 int spe_regs_addressable_via_sp
20563 = (SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset
20564 + (32 - info->first_gp_reg_save - 1) * reg_size)
20565 && saving_GPRs_inline);
20566 int spe_offset;
20568 if (spe_regs_addressable_via_sp)
20570 spe_save_area_ptr = frame_reg_rtx;
20571 spe_offset = info->spe_gp_save_offset + sp_offset;
20573 else
20575 /* Make r11 point to the start of the SPE save area. We need
20576 to be careful here if r11 is holding the static chain. If
20577 it is, then temporarily save it in r0. We would use r0 as
20578 our base register here, but using r0 as a base register in
20579 loads and stores means something different from what we
20580 would like. */
20581 int ool_adjust = (saving_GPRs_inline
20583 : (info->first_gp_reg_save
20584 - (FIRST_SAVRES_REGISTER+1))*8);
20585 HOST_WIDE_INT offset = (info->spe_gp_save_offset
20586 + sp_offset - ool_adjust);
20588 if (using_static_chain_p)
20590 rtx r0 = gen_rtx_REG (Pmode, 0);
20591 gcc_assert (info->first_gp_reg_save > 11);
20593 emit_move_insn (r0, gen_rtx_REG (Pmode, 11));
20596 spe_save_area_ptr = gen_rtx_REG (Pmode, 11);
20597 insn = emit_insn (gen_addsi3 (spe_save_area_ptr,
20598 frame_reg_rtx,
20599 GEN_INT (offset)));
20600 /* We need to make sure the move to r11 gets noted for
20601 properly outputting unwind information. */
20602 if (!saving_GPRs_inline)
20603 rs6000_frame_related (insn, frame_reg_rtx, offset,
20604 NULL_RTX, NULL_RTX);
20605 spe_offset = 0;
20608 if (saving_GPRs_inline)
20610 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20611 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
20613 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20614 rtx offset, addr, mem;
20616 /* We're doing all this to ensure that the offset fits into
20617 the immediate offset of 'evstdd'. */
20618 gcc_assert (SPE_CONST_OFFSET_OK (reg_size * i + spe_offset));
20620 offset = GEN_INT (reg_size * i + spe_offset);
20621 addr = gen_rtx_PLUS (Pmode, spe_save_area_ptr, offset);
20622 mem = gen_rtx_MEM (V2SImode, addr);
20624 insn = emit_move_insn (mem, reg);
20626 rs6000_frame_related (insn, spe_save_area_ptr,
20627 info->spe_gp_save_offset
20628 + sp_offset + reg_size * i,
20629 offset, const0_rtx);
20632 else
20634 rtx par;
20636 par = rs6000_make_savres_rtx (info, gen_rtx_REG (Pmode, 11),
20637 0, reg_mode,
20638 /*savep=*/true, /*gpr=*/true,
20639 /*lr=*/false);
20640 insn = emit_insn (par);
20641 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20642 NULL_RTX, NULL_RTX);
20646 /* Move the static chain pointer back. */
20647 if (using_static_chain_p && !spe_regs_addressable_via_sp)
20648 emit_move_insn (gen_rtx_REG (Pmode, 11), gen_rtx_REG (Pmode, 0));
20650 else if (!WORLD_SAVE_P (info) && !saving_GPRs_inline)
20652 rtx par;
20654 /* Need to adjust r11 (r12) if we saved any FPRs. */
20655 if (info->first_fp_reg_save != 64)
20657 rtx dest_reg = gen_rtx_REG (reg_mode, DEFAULT_ABI == ABI_AIX
20658 ? 12 : 11);
20659 rtx offset = GEN_INT (sp_offset
20660 + (-8 * (64-info->first_fp_reg_save)));
20661 emit_insn (gen_add3_insn (dest_reg, frame_reg_rtx, offset));
20664 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
20665 info->gp_save_offset + sp_offset,
20666 reg_mode,
20667 /*savep=*/true, /*gpr=*/true,
20668 /*lr=*/(strategy
20669 & SAVE_NOINLINE_GPRS_SAVES_LR)
20670 != 0);
20671 insn = emit_insn (par);
20672 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20673 NULL_RTX, NULL_RTX);
20675 else if (!WORLD_SAVE_P (info) && using_store_multiple)
20677 rtvec p;
20678 int i;
20679 p = rtvec_alloc (32 - info->first_gp_reg_save);
20680 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20682 rtx addr, reg, mem;
20683 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20684 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20685 GEN_INT (info->gp_save_offset
20686 + sp_offset
20687 + reg_size * i));
20688 mem = gen_frame_mem (reg_mode, addr);
20690 RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, mem, reg);
20692 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
20693 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20694 NULL_RTX, NULL_RTX);
20696 else if (!WORLD_SAVE_P (info))
20698 int i;
20699 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20700 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
20702 rtx addr, reg, mem;
20703 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20705 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20706 GEN_INT (info->gp_save_offset
20707 + sp_offset
20708 + reg_size * i));
20709 mem = gen_frame_mem (reg_mode, addr);
20711 insn = emit_move_insn (mem, reg);
20712 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20713 NULL_RTX, NULL_RTX);
20717 /* ??? There's no need to emit actual instructions here, but it's the
20718 easiest way to get the frame unwind information emitted. */
20719 if (crtl->calls_eh_return)
20721 unsigned int i, regno;
20723 for (i = 0; ; ++i)
20725 regno = EH_RETURN_DATA_REGNO (i);
20726 if (regno == INVALID_REGNUM)
20727 break;
20729 emit_frame_save (frame_reg_rtx, frame_ptr_rtx, reg_mode, regno,
20730 info->ehrd_offset + sp_offset
20731 + reg_size * (int) i,
20732 info->total_size);
20736 /* In AIX ABI we need to make sure r2 is really saved. */
20737 if (TARGET_AIX && crtl->calls_eh_return)
20739 rtx tmp_reg, tmp_reg_si, hi, lo, compare_result, toc_save_done, jump;
20740 long toc_restore_insn;
20742 gcc_assert (frame_reg_rtx == frame_ptr_rtx
20743 || frame_reg_rtx == sp_reg_rtx);
20744 tmp_reg = gen_rtx_REG (Pmode, 11);
20745 tmp_reg_si = gen_rtx_REG (SImode, 11);
20746 if (using_static_chain_p)
20747 emit_move_insn (gen_rtx_REG (Pmode, 0), tmp_reg);
20748 gcc_assert (saving_GPRs_inline && saving_FPRs_inline);
20749 emit_move_insn (tmp_reg, gen_rtx_REG (Pmode, LR_REGNO));
20750 /* Peek at instruction to which this function returns. If it's
20751 restoring r2, then we know we've already saved r2. We can't
20752 unconditionally save r2 because the value we have will already
20753 be updated if we arrived at this function via a plt call or
20754 toc adjusting stub. */
20755 emit_move_insn (tmp_reg_si, gen_rtx_MEM (SImode, tmp_reg));
20756 toc_restore_insn = TARGET_32BIT ? 0x80410014 : 0xE8410028;
20757 hi = gen_int_mode (toc_restore_insn & ~0xffff, SImode);
20758 emit_insn (gen_xorsi3 (tmp_reg_si, tmp_reg_si, hi));
20759 compare_result = gen_rtx_REG (CCUNSmode, CR0_REGNO);
20760 validate_condition_mode (EQ, CCUNSmode);
20761 lo = gen_int_mode (toc_restore_insn & 0xffff, SImode);
20762 emit_insn (gen_rtx_SET (VOIDmode, compare_result,
20763 gen_rtx_COMPARE (CCUNSmode, tmp_reg_si, lo)));
20764 toc_save_done = gen_label_rtx ();
20765 jump = gen_rtx_IF_THEN_ELSE (VOIDmode,
20766 gen_rtx_EQ (VOIDmode, compare_result,
20767 const0_rtx),
20768 gen_rtx_LABEL_REF (VOIDmode, toc_save_done),
20769 pc_rtx);
20770 jump = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, jump));
20771 JUMP_LABEL (jump) = toc_save_done;
20772 LABEL_NUSES (toc_save_done) += 1;
20774 emit_frame_save (frame_reg_rtx, frame_ptr_rtx, reg_mode, 2,
20775 sp_offset + 5 * reg_size, info->total_size);
20776 emit_label (toc_save_done);
20777 if (using_static_chain_p)
20778 emit_move_insn (tmp_reg, gen_rtx_REG (Pmode, 0));
20781 /* Save CR if we use any that must be preserved. */
20782 if (!WORLD_SAVE_P (info) && info->cr_save_p)
20784 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20785 GEN_INT (info->cr_save_offset + sp_offset));
20786 rtx mem = gen_frame_mem (SImode, addr);
20787 /* See the large comment above about why CR2_REGNO is used. */
20788 rtx magic_eh_cr_reg = gen_rtx_REG (SImode, CR2_REGNO);
20790 /* If r12 was used to hold the original sp, copy cr into r0 now
20791 that it's free. */
20792 if (REGNO (frame_reg_rtx) == 12)
20794 rtx set;
20796 cr_save_rtx = gen_rtx_REG (SImode, 0);
20797 insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
20798 RTX_FRAME_RELATED_P (insn) = 1;
20799 set = gen_rtx_SET (VOIDmode, cr_save_rtx, magic_eh_cr_reg);
20800 add_reg_note (insn, REG_FRAME_RELATED_EXPR, set);
20802 insn = emit_move_insn (mem, cr_save_rtx);
20804 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20805 NULL_RTX, NULL_RTX);
20808 /* Update stack and set back pointer unless this is V.4,
20809 for which it was done previously. */
20810 if (!WORLD_SAVE_P (info) && info->push_p
20811 && !(DEFAULT_ABI == ABI_V4 || crtl->calls_eh_return))
20813 rtx copy_reg = NULL;
20815 if (info->total_size < 32767)
20816 sp_offset = info->total_size;
20817 else if (info->altivec_size != 0
20818 || info->vrsave_mask != 0)
20820 copy_reg = frame_ptr_rtx;
20821 frame_reg_rtx = copy_reg;
20823 else
20824 sp_offset = info->total_size;
20825 rs6000_emit_allocate_stack (info->total_size, copy_reg);
20826 if (frame_reg_rtx != sp_reg_rtx)
20827 rs6000_emit_stack_tie ();
20830 /* Set frame pointer, if needed. */
20831 if (frame_pointer_needed)
20833 insn = emit_move_insn (gen_rtx_REG (Pmode, HARD_FRAME_POINTER_REGNUM),
20834 sp_reg_rtx);
20835 RTX_FRAME_RELATED_P (insn) = 1;
20838 /* Save AltiVec registers if needed. Save here because the red zone does
20839 not include AltiVec registers. */
20840 if (!WORLD_SAVE_P (info) && TARGET_ALTIVEC_ABI && info->altivec_size != 0)
20842 int i;
20844 /* There should be a non inline version of this, for when we
20845 are saving lots of vector registers. */
20846 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
20847 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
20849 rtx areg, savereg, mem;
20850 int offset;
20852 offset = info->altivec_save_offset + sp_offset
20853 + 16 * (i - info->first_altivec_reg_save);
20855 savereg = gen_rtx_REG (V4SImode, i);
20857 areg = gen_rtx_REG (Pmode, 0);
20858 emit_move_insn (areg, GEN_INT (offset));
20860 /* AltiVec addressing mode is [reg+reg]. */
20861 mem = gen_frame_mem (V4SImode,
20862 gen_rtx_PLUS (Pmode, frame_reg_rtx, areg));
20864 insn = emit_move_insn (mem, savereg);
20866 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20867 areg, GEN_INT (offset));
20871 /* VRSAVE is a bit vector representing which AltiVec registers
20872 are used. The OS uses this to determine which vector
20873 registers to save on a context switch. We need to save
20874 VRSAVE on the stack frame, add whatever AltiVec registers we
20875 used in this function, and do the corresponding magic in the
20876 epilogue. */
20878 if (TARGET_ALTIVEC && TARGET_ALTIVEC_VRSAVE
20879 && info->vrsave_mask != 0)
20881 rtx reg, mem, vrsave;
20882 int offset;
20884 /* Get VRSAVE onto a GPR. Note that ABI_V4 might be using r12
20885 as frame_reg_rtx and r11 as the static chain pointer for
20886 nested functions. */
20887 reg = gen_rtx_REG (SImode, 0);
20888 vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
20889 if (TARGET_MACHO)
20890 emit_insn (gen_get_vrsave_internal (reg));
20891 else
20892 emit_insn (gen_rtx_SET (VOIDmode, reg, vrsave));
20894 if (!WORLD_SAVE_P (info))
20896 /* Save VRSAVE. */
20897 offset = info->vrsave_save_offset + sp_offset;
20898 mem = gen_frame_mem (SImode,
20899 gen_rtx_PLUS (Pmode, frame_reg_rtx,
20900 GEN_INT (offset)));
20901 insn = emit_move_insn (mem, reg);
20904 /* Include the registers in the mask. */
20905 emit_insn (gen_iorsi3 (reg, reg, GEN_INT ((int) info->vrsave_mask)));
20907 insn = emit_insn (generate_set_vrsave (reg, info, 0));
20910 if (TARGET_SINGLE_PIC_BASE)
20911 return; /* Do not set PIC register */
20913 /* If we are using RS6000_PIC_OFFSET_TABLE_REGNUM, we need to set it up. */
20914 if ((TARGET_TOC && TARGET_MINIMAL_TOC && get_pool_size () != 0)
20915 || (DEFAULT_ABI == ABI_V4
20916 && (flag_pic == 1 || (flag_pic && TARGET_SECURE_PLT))
20917 && df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM)))
20919 /* If emit_load_toc_table will use the link register, we need to save
20920 it. We use R12 for this purpose because emit_load_toc_table
20921 can use register 0. This allows us to use a plain 'blr' to return
20922 from the procedure more often. */
20923 int save_LR_around_toc_setup = (TARGET_ELF
20924 && DEFAULT_ABI != ABI_AIX
20925 && flag_pic
20926 && ! info->lr_save_p
20927 && EDGE_COUNT (EXIT_BLOCK_PTR->preds) > 0);
20928 if (save_LR_around_toc_setup)
20930 rtx lr = gen_rtx_REG (Pmode, LR_REGNO);
20932 insn = emit_move_insn (frame_ptr_rtx, lr);
20933 RTX_FRAME_RELATED_P (insn) = 1;
20935 rs6000_emit_load_toc_table (TRUE);
20937 insn = emit_move_insn (lr, frame_ptr_rtx);
20938 RTX_FRAME_RELATED_P (insn) = 1;
20940 else
20941 rs6000_emit_load_toc_table (TRUE);
20944 #if TARGET_MACHO
20945 if (DEFAULT_ABI == ABI_DARWIN
20946 && flag_pic && crtl->uses_pic_offset_table)
20948 rtx lr = gen_rtx_REG (Pmode, LR_REGNO);
20949 rtx src = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
20951 /* Save and restore LR locally around this call (in R0). */
20952 if (!info->lr_save_p)
20953 emit_move_insn (gen_rtx_REG (Pmode, 0), lr);
20955 emit_insn (gen_load_macho_picbase (src));
20957 emit_move_insn (gen_rtx_REG (Pmode,
20958 RS6000_PIC_OFFSET_TABLE_REGNUM),
20959 lr);
20961 if (!info->lr_save_p)
20962 emit_move_insn (lr, gen_rtx_REG (Pmode, 0));
20964 #endif
20967 /* Write function prologue. */
20969 static void
20970 rs6000_output_function_prologue (FILE *file,
20971 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
20973 rs6000_stack_t *info = rs6000_stack_info ();
20975 if (TARGET_DEBUG_STACK)
20976 debug_stack_info (info);
20978 /* Write .extern for any function we will call to save and restore
20979 fp values. */
20980 if (info->first_fp_reg_save < 64)
20982 char *name;
20983 int regno = info->first_fp_reg_save - 32;
20985 if ((info->savres_strategy & SAVE_INLINE_FPRS) == 0)
20987 name = rs6000_savres_routine_name (info, regno, /*savep=*/true,
20988 /*gpr=*/false, /*lr=*/false);
20989 fprintf (file, "\t.extern %s\n", name);
20991 if ((info->savres_strategy & REST_INLINE_FPRS) == 0)
20993 name = rs6000_savres_routine_name (info, regno, /*savep=*/false,
20994 /*gpr=*/false, /*lr=*/true);
20995 fprintf (file, "\t.extern %s\n", name);
20999 /* Write .extern for AIX common mode routines, if needed. */
21000 if (! TARGET_POWER && ! TARGET_POWERPC && ! common_mode_defined)
21002 fputs ("\t.extern __mulh\n", file);
21003 fputs ("\t.extern __mull\n", file);
21004 fputs ("\t.extern __divss\n", file);
21005 fputs ("\t.extern __divus\n", file);
21006 fputs ("\t.extern __quoss\n", file);
21007 fputs ("\t.extern __quous\n", file);
21008 common_mode_defined = 1;
21011 if (! HAVE_prologue)
21013 rtx prologue;
21015 start_sequence ();
21017 /* A NOTE_INSN_DELETED is supposed to be at the start and end of
21018 the "toplevel" insn chain. */
21019 emit_note (NOTE_INSN_DELETED);
21020 rs6000_emit_prologue ();
21021 emit_note (NOTE_INSN_DELETED);
21023 /* Expand INSN_ADDRESSES so final() doesn't crash. */
21025 rtx insn;
21026 unsigned addr = 0;
21027 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
21029 INSN_ADDRESSES_NEW (insn, addr);
21030 addr += 4;
21034 prologue = get_insns ();
21035 end_sequence ();
21037 if (TARGET_DEBUG_STACK)
21038 debug_rtx_list (prologue, 100);
21040 emit_insn_before_noloc (prologue, BB_HEAD (ENTRY_BLOCK_PTR->next_bb),
21041 ENTRY_BLOCK_PTR);
21044 rs6000_pic_labelno++;
21047 /* Non-zero if vmx regs are restored before the frame pop, zero if
21048 we restore after the pop when possible. */
21049 #define ALWAYS_RESTORE_ALTIVEC_BEFORE_POP 0
21051 /* Reload CR from REG. */
21053 static void
21054 rs6000_restore_saved_cr (rtx reg, int using_mfcr_multiple)
21056 int count = 0;
21057 int i;
21059 if (using_mfcr_multiple)
21061 for (i = 0; i < 8; i++)
21062 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
21063 count++;
21064 gcc_assert (count);
21067 if (using_mfcr_multiple && count > 1)
21069 rtvec p;
21070 int ndx;
21072 p = rtvec_alloc (count);
21074 ndx = 0;
21075 for (i = 0; i < 8; i++)
21076 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
21078 rtvec r = rtvec_alloc (2);
21079 RTVEC_ELT (r, 0) = reg;
21080 RTVEC_ELT (r, 1) = GEN_INT (1 << (7-i));
21081 RTVEC_ELT (p, ndx) =
21082 gen_rtx_SET (VOIDmode, gen_rtx_REG (CCmode, CR0_REGNO+i),
21083 gen_rtx_UNSPEC (CCmode, r, UNSPEC_MOVESI_TO_CR));
21084 ndx++;
21086 emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
21087 gcc_assert (ndx == count);
21089 else
21090 for (i = 0; i < 8; i++)
21091 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
21093 emit_insn (gen_movsi_to_cr_one (gen_rtx_REG (CCmode,
21094 CR0_REGNO+i),
21095 reg));
21099 /* Return true if OFFSET from stack pointer can be clobbered by signals.
21100 V.4 doesn't have any stack cushion, AIX ABIs have 220 or 288 bytes
21101 below stack pointer not cloberred by signals. */
21103 static inline bool
21104 offset_below_red_zone_p (HOST_WIDE_INT offset)
21106 return offset < (DEFAULT_ABI == ABI_V4
21108 : TARGET_32BIT ? -220 : -288);
21111 /* Emit function epilogue as insns. */
21113 void
21114 rs6000_emit_epilogue (int sibcall)
21116 rs6000_stack_t *info;
21117 int restoring_GPRs_inline;
21118 int restoring_FPRs_inline;
21119 int using_load_multiple;
21120 int using_mtcr_multiple;
21121 int use_backchain_to_restore_sp;
21122 int restore_lr;
21123 int strategy;
21124 int sp_offset = 0;
21125 rtx sp_reg_rtx = gen_rtx_REG (Pmode, 1);
21126 rtx frame_reg_rtx = sp_reg_rtx;
21127 rtx cfa_restores = NULL_RTX;
21128 rtx insn;
21129 rtx cr_save_reg = NULL_RTX;
21130 enum machine_mode reg_mode = Pmode;
21131 int reg_size = TARGET_32BIT ? 4 : 8;
21132 int i;
21134 info = rs6000_stack_info ();
21136 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
21138 reg_mode = V2SImode;
21139 reg_size = 8;
21142 strategy = info->savres_strategy;
21143 using_load_multiple = strategy & SAVRES_MULTIPLE;
21144 restoring_FPRs_inline = sibcall || (strategy & REST_INLINE_FPRS);
21145 restoring_GPRs_inline = sibcall || (strategy & REST_INLINE_GPRS);
21146 using_mtcr_multiple = (rs6000_cpu == PROCESSOR_PPC601
21147 || rs6000_cpu == PROCESSOR_PPC603
21148 || rs6000_cpu == PROCESSOR_PPC750
21149 || optimize_size);
21150 /* Restore via the backchain when we have a large frame, since this
21151 is more efficient than an addis, addi pair. The second condition
21152 here will not trigger at the moment; We don't actually need a
21153 frame pointer for alloca, but the generic parts of the compiler
21154 give us one anyway. */
21155 use_backchain_to_restore_sp = (info->total_size > 32767
21156 || info->total_size
21157 + (info->lr_save_p ? info->lr_save_offset : 0)
21158 > 32767
21159 || (cfun->calls_alloca
21160 && !frame_pointer_needed));
21161 restore_lr = (info->lr_save_p
21162 && (restoring_FPRs_inline
21163 || (strategy & REST_NOINLINE_FPRS_DOESNT_RESTORE_LR))
21164 && (restoring_GPRs_inline
21165 || info->first_fp_reg_save < 64));
21167 if (WORLD_SAVE_P (info))
21169 int i, j;
21170 char rname[30];
21171 const char *alloc_rname;
21172 rtvec p;
21174 /* eh_rest_world_r10 will return to the location saved in the LR
21175 stack slot (which is not likely to be our caller.)
21176 Input: R10 -- stack adjustment. Clobbers R0, R11, R12, R7, R8.
21177 rest_world is similar, except any R10 parameter is ignored.
21178 The exception-handling stuff that was here in 2.95 is no
21179 longer necessary. */
21181 p = rtvec_alloc (9
21183 + 32 - info->first_gp_reg_save
21184 + LAST_ALTIVEC_REGNO + 1 - info->first_altivec_reg_save
21185 + 63 + 1 - info->first_fp_reg_save);
21187 strcpy (rname, ((crtl->calls_eh_return) ?
21188 "*eh_rest_world_r10" : "*rest_world"));
21189 alloc_rname = ggc_strdup (rname);
21191 j = 0;
21192 RTVEC_ELT (p, j++) = gen_rtx_RETURN (VOIDmode);
21193 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
21194 gen_rtx_REG (Pmode,
21195 LR_REGNO));
21196 RTVEC_ELT (p, j++)
21197 = gen_rtx_USE (VOIDmode, gen_rtx_SYMBOL_REF (Pmode, alloc_rname));
21198 /* The instruction pattern requires a clobber here;
21199 it is shared with the restVEC helper. */
21200 RTVEC_ELT (p, j++)
21201 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 11));
21204 /* CR register traditionally saved as CR2. */
21205 rtx reg = gen_rtx_REG (reg_mode, CR2_REGNO);
21206 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21207 GEN_INT (info->cr_save_offset));
21208 rtx mem = gen_frame_mem (reg_mode, addr);
21210 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
21213 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
21215 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
21216 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21217 GEN_INT (info->gp_save_offset
21218 + reg_size * i));
21219 rtx mem = gen_frame_mem (reg_mode, addr);
21221 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
21223 for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++)
21225 rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i);
21226 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21227 GEN_INT (info->altivec_save_offset
21228 + 16 * i));
21229 rtx mem = gen_frame_mem (V4SImode, addr);
21231 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
21233 for (i = 0; info->first_fp_reg_save + i <= 63; i++)
21235 rtx reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
21236 ? DFmode : SFmode),
21237 info->first_fp_reg_save + i);
21238 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21239 GEN_INT (info->fp_save_offset
21240 + 8 * i));
21241 rtx mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
21242 ? DFmode : SFmode), addr);
21244 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
21246 RTVEC_ELT (p, j++)
21247 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 0));
21248 RTVEC_ELT (p, j++)
21249 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 12));
21250 RTVEC_ELT (p, j++)
21251 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 7));
21252 RTVEC_ELT (p, j++)
21253 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 8));
21254 RTVEC_ELT (p, j++)
21255 = gen_rtx_USE (VOIDmode, gen_rtx_REG (SImode, 10));
21256 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
21258 return;
21261 /* frame_reg_rtx + sp_offset points to the top of this stack frame. */
21262 if (info->push_p)
21263 sp_offset = info->total_size;
21265 /* Restore AltiVec registers if we must do so before adjusting the
21266 stack. */
21267 if (TARGET_ALTIVEC_ABI
21268 && info->altivec_size != 0
21269 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
21270 || (DEFAULT_ABI != ABI_V4
21271 && offset_below_red_zone_p (info->altivec_save_offset))))
21273 int i;
21275 if (use_backchain_to_restore_sp)
21277 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
21278 emit_move_insn (frame_reg_rtx,
21279 gen_rtx_MEM (Pmode, sp_reg_rtx));
21280 sp_offset = 0;
21282 else if (frame_pointer_needed)
21283 frame_reg_rtx = hard_frame_pointer_rtx;
21285 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
21286 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
21288 rtx addr, areg, mem, reg;
21290 areg = gen_rtx_REG (Pmode, 0);
21291 emit_move_insn
21292 (areg, GEN_INT (info->altivec_save_offset
21293 + sp_offset
21294 + 16 * (i - info->first_altivec_reg_save)));
21296 /* AltiVec addressing mode is [reg+reg]. */
21297 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
21298 mem = gen_frame_mem (V4SImode, addr);
21300 reg = gen_rtx_REG (V4SImode, i);
21301 emit_move_insn (reg, mem);
21302 if (offset_below_red_zone_p (info->altivec_save_offset
21303 + (i - info->first_altivec_reg_save)
21304 * 16))
21305 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21306 cfa_restores);
21310 /* Restore VRSAVE if we must do so before adjusting the stack. */
21311 if (TARGET_ALTIVEC
21312 && TARGET_ALTIVEC_VRSAVE
21313 && info->vrsave_mask != 0
21314 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
21315 || (DEFAULT_ABI != ABI_V4
21316 && offset_below_red_zone_p (info->vrsave_save_offset))))
21318 rtx addr, mem, reg;
21320 if (frame_reg_rtx == sp_reg_rtx)
21322 if (use_backchain_to_restore_sp)
21324 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
21325 emit_move_insn (frame_reg_rtx,
21326 gen_rtx_MEM (Pmode, sp_reg_rtx));
21327 sp_offset = 0;
21329 else if (frame_pointer_needed)
21330 frame_reg_rtx = hard_frame_pointer_rtx;
21333 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21334 GEN_INT (info->vrsave_save_offset + sp_offset));
21335 mem = gen_frame_mem (SImode, addr);
21336 reg = gen_rtx_REG (SImode, 12);
21337 emit_move_insn (reg, mem);
21339 emit_insn (generate_set_vrsave (reg, info, 1));
21342 insn = NULL_RTX;
21343 /* If we have a large stack frame, restore the old stack pointer
21344 using the backchain. */
21345 if (use_backchain_to_restore_sp)
21347 if (frame_reg_rtx == sp_reg_rtx)
21349 /* Under V.4, don't reset the stack pointer until after we're done
21350 loading the saved registers. */
21351 if (DEFAULT_ABI == ABI_V4)
21352 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
21354 insn = emit_move_insn (frame_reg_rtx,
21355 gen_rtx_MEM (Pmode, sp_reg_rtx));
21356 sp_offset = 0;
21358 else if (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
21359 && DEFAULT_ABI == ABI_V4)
21360 /* frame_reg_rtx has been set up by the altivec restore. */
21362 else
21364 insn = emit_move_insn (sp_reg_rtx, frame_reg_rtx);
21365 frame_reg_rtx = sp_reg_rtx;
21368 /* If we have a frame pointer, we can restore the old stack pointer
21369 from it. */
21370 else if (frame_pointer_needed)
21372 frame_reg_rtx = sp_reg_rtx;
21373 if (DEFAULT_ABI == ABI_V4)
21374 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
21375 /* Prevent reordering memory accesses against stack pointer restore. */
21376 else if (cfun->calls_alloca
21377 || offset_below_red_zone_p (-info->total_size))
21379 rtx mem1 = gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx);
21380 rtx mem2 = gen_rtx_MEM (BLKmode, sp_reg_rtx);
21381 MEM_NOTRAP_P (mem1) = 1;
21382 MEM_NOTRAP_P (mem2) = 1;
21383 emit_insn (gen_frame_tie (mem1, mem2));
21386 insn = emit_insn (gen_add3_insn (frame_reg_rtx, hard_frame_pointer_rtx,
21387 GEN_INT (info->total_size)));
21388 sp_offset = 0;
21390 else if (info->push_p
21391 && DEFAULT_ABI != ABI_V4
21392 && !crtl->calls_eh_return)
21394 /* Prevent reordering memory accesses against stack pointer restore. */
21395 if (cfun->calls_alloca
21396 || offset_below_red_zone_p (-info->total_size))
21398 rtx mem = gen_rtx_MEM (BLKmode, sp_reg_rtx);
21399 MEM_NOTRAP_P (mem) = 1;
21400 emit_insn (gen_stack_tie (mem));
21402 insn = emit_insn (gen_add3_insn (sp_reg_rtx, sp_reg_rtx,
21403 GEN_INT (info->total_size)));
21404 sp_offset = 0;
21406 if (insn && frame_reg_rtx == sp_reg_rtx)
21408 if (cfa_restores)
21410 REG_NOTES (insn) = cfa_restores;
21411 cfa_restores = NULL_RTX;
21413 add_reg_note (insn, REG_CFA_DEF_CFA, sp_reg_rtx);
21414 RTX_FRAME_RELATED_P (insn) = 1;
21417 /* Restore AltiVec registers if we have not done so already. */
21418 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
21419 && TARGET_ALTIVEC_ABI
21420 && info->altivec_size != 0
21421 && (DEFAULT_ABI == ABI_V4
21422 || !offset_below_red_zone_p (info->altivec_save_offset)))
21424 int i;
21426 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
21427 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
21429 rtx addr, areg, mem, reg;
21431 areg = gen_rtx_REG (Pmode, 0);
21432 emit_move_insn
21433 (areg, GEN_INT (info->altivec_save_offset
21434 + sp_offset
21435 + 16 * (i - info->first_altivec_reg_save)));
21437 /* AltiVec addressing mode is [reg+reg]. */
21438 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
21439 mem = gen_frame_mem (V4SImode, addr);
21441 reg = gen_rtx_REG (V4SImode, i);
21442 emit_move_insn (reg, mem);
21443 if (DEFAULT_ABI == ABI_V4)
21444 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21445 cfa_restores);
21449 /* Restore VRSAVE if we have not done so already. */
21450 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
21451 && TARGET_ALTIVEC
21452 && TARGET_ALTIVEC_VRSAVE
21453 && info->vrsave_mask != 0
21454 && (DEFAULT_ABI == ABI_V4
21455 || !offset_below_red_zone_p (info->vrsave_save_offset)))
21457 rtx addr, mem, reg;
21459 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21460 GEN_INT (info->vrsave_save_offset + sp_offset));
21461 mem = gen_frame_mem (SImode, addr);
21462 reg = gen_rtx_REG (SImode, 12);
21463 emit_move_insn (reg, mem);
21465 emit_insn (generate_set_vrsave (reg, info, 1));
21468 /* Get the old lr if we saved it. If we are restoring registers
21469 out-of-line, then the out-of-line routines can do this for us. */
21470 if (restore_lr && restoring_GPRs_inline)
21472 rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
21473 info->lr_save_offset + sp_offset);
21475 emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
21478 /* Get the old cr if we saved it. */
21479 if (info->cr_save_p)
21481 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21482 GEN_INT (info->cr_save_offset + sp_offset));
21483 rtx mem = gen_frame_mem (SImode, addr);
21485 cr_save_reg = gen_rtx_REG (SImode,
21486 DEFAULT_ABI == ABI_AIX
21487 && !restoring_GPRs_inline
21488 && info->first_fp_reg_save < 64
21489 ? 11 : 12);
21490 emit_move_insn (cr_save_reg, mem);
21493 /* Set LR here to try to overlap restores below. LR is always saved
21494 above incoming stack, so it never needs REG_CFA_RESTORE. */
21495 if (restore_lr && restoring_GPRs_inline)
21496 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO),
21497 gen_rtx_REG (Pmode, 0));
21499 /* Load exception handler data registers, if needed. */
21500 if (crtl->calls_eh_return)
21502 unsigned int i, regno;
21504 if (TARGET_AIX)
21506 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21507 GEN_INT (sp_offset + 5 * reg_size));
21508 rtx mem = gen_frame_mem (reg_mode, addr);
21510 emit_move_insn (gen_rtx_REG (reg_mode, 2), mem);
21513 for (i = 0; ; ++i)
21515 rtx mem;
21517 regno = EH_RETURN_DATA_REGNO (i);
21518 if (regno == INVALID_REGNUM)
21519 break;
21521 mem = gen_frame_mem_offset (reg_mode, frame_reg_rtx,
21522 info->ehrd_offset + sp_offset
21523 + reg_size * (int) i);
21525 emit_move_insn (gen_rtx_REG (reg_mode, regno), mem);
21529 /* Restore GPRs. This is done as a PARALLEL if we are using
21530 the load-multiple instructions. */
21531 if (TARGET_SPE_ABI
21532 && info->spe_64bit_regs_used != 0
21533 && info->first_gp_reg_save != 32)
21535 /* Determine whether we can address all of the registers that need
21536 to be saved with an offset from the stack pointer that fits in
21537 the small const field for SPE memory instructions. */
21538 int spe_regs_addressable_via_sp
21539 = (SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset
21540 + (32 - info->first_gp_reg_save - 1) * reg_size)
21541 && restoring_GPRs_inline);
21542 int spe_offset;
21544 if (spe_regs_addressable_via_sp)
21545 spe_offset = info->spe_gp_save_offset + sp_offset;
21546 else
21548 rtx old_frame_reg_rtx = frame_reg_rtx;
21549 /* Make r11 point to the start of the SPE save area. We worried about
21550 not clobbering it when we were saving registers in the prologue.
21551 There's no need to worry here because the static chain is passed
21552 anew to every function. */
21553 int ool_adjust = (restoring_GPRs_inline
21555 : (info->first_gp_reg_save
21556 - (FIRST_SAVRES_REGISTER+1))*8);
21558 if (frame_reg_rtx == sp_reg_rtx)
21559 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
21560 emit_insn (gen_addsi3 (frame_reg_rtx, old_frame_reg_rtx,
21561 GEN_INT (info->spe_gp_save_offset
21562 + sp_offset
21563 - ool_adjust)));
21564 /* Keep the invariant that frame_reg_rtx + sp_offset points
21565 at the top of the stack frame. */
21566 sp_offset = -info->spe_gp_save_offset;
21568 spe_offset = 0;
21571 if (restoring_GPRs_inline)
21573 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
21574 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
21576 rtx offset, addr, mem, reg;
21578 /* We're doing all this to ensure that the immediate offset
21579 fits into the immediate field of 'evldd'. */
21580 gcc_assert (SPE_CONST_OFFSET_OK (spe_offset + reg_size * i));
21582 offset = GEN_INT (spe_offset + reg_size * i);
21583 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, offset);
21584 mem = gen_rtx_MEM (V2SImode, addr);
21585 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
21587 insn = emit_move_insn (reg, mem);
21588 if (DEFAULT_ABI == ABI_V4)
21590 if (frame_pointer_needed
21591 && info->first_gp_reg_save + i
21592 == HARD_FRAME_POINTER_REGNUM)
21594 add_reg_note (insn, REG_CFA_DEF_CFA,
21595 plus_constant (frame_reg_rtx,
21596 sp_offset));
21597 RTX_FRAME_RELATED_P (insn) = 1;
21600 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21601 cfa_restores);
21605 else
21607 rtx par;
21609 par = rs6000_make_savres_rtx (info, gen_rtx_REG (Pmode, 11),
21610 0, reg_mode,
21611 /*savep=*/false, /*gpr=*/true,
21612 /*lr=*/true);
21613 emit_jump_insn (par);
21614 /* We don't want anybody else emitting things after we jumped
21615 back. */
21616 return;
21619 else if (!restoring_GPRs_inline)
21621 /* We are jumping to an out-of-line function. */
21622 bool can_use_exit = info->first_fp_reg_save == 64;
21623 rtx par;
21625 /* Emit stack reset code if we need it. */
21626 if (can_use_exit)
21627 rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx,
21628 sp_offset, can_use_exit);
21629 else
21631 emit_insn (gen_add3_insn (gen_rtx_REG (Pmode, DEFAULT_ABI == ABI_AIX
21632 ? 12 : 11),
21633 frame_reg_rtx,
21634 GEN_INT (sp_offset - info->fp_size)));
21635 if (REGNO (frame_reg_rtx) == 11)
21636 sp_offset += info->fp_size;
21639 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
21640 info->gp_save_offset, reg_mode,
21641 /*savep=*/false, /*gpr=*/true,
21642 /*lr=*/can_use_exit);
21644 if (can_use_exit)
21646 if (info->cr_save_p)
21648 rs6000_restore_saved_cr (cr_save_reg, using_mtcr_multiple);
21649 if (DEFAULT_ABI == ABI_V4)
21650 cfa_restores
21651 = alloc_reg_note (REG_CFA_RESTORE,
21652 gen_rtx_REG (SImode, CR2_REGNO),
21653 cfa_restores);
21656 emit_jump_insn (par);
21658 /* We don't want anybody else emitting things after we jumped
21659 back. */
21660 return;
21663 insn = emit_insn (par);
21664 if (DEFAULT_ABI == ABI_V4)
21666 if (frame_pointer_needed)
21668 add_reg_note (insn, REG_CFA_DEF_CFA,
21669 plus_constant (frame_reg_rtx, sp_offset));
21670 RTX_FRAME_RELATED_P (insn) = 1;
21673 for (i = info->first_gp_reg_save; i < 32; i++)
21674 cfa_restores
21675 = alloc_reg_note (REG_CFA_RESTORE,
21676 gen_rtx_REG (reg_mode, i), cfa_restores);
21679 else if (using_load_multiple)
21681 rtvec p;
21682 p = rtvec_alloc (32 - info->first_gp_reg_save);
21683 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
21685 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21686 GEN_INT (info->gp_save_offset
21687 + sp_offset
21688 + reg_size * i));
21689 rtx mem = gen_frame_mem (reg_mode, addr);
21690 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
21692 RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, reg, mem);
21693 if (DEFAULT_ABI == ABI_V4)
21694 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21695 cfa_restores);
21697 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
21698 if (DEFAULT_ABI == ABI_V4 && frame_pointer_needed)
21700 add_reg_note (insn, REG_CFA_DEF_CFA,
21701 plus_constant (frame_reg_rtx, sp_offset));
21702 RTX_FRAME_RELATED_P (insn) = 1;
21705 else
21707 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
21708 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
21710 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21711 GEN_INT (info->gp_save_offset
21712 + sp_offset
21713 + reg_size * i));
21714 rtx mem = gen_frame_mem (reg_mode, addr);
21715 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
21717 insn = emit_move_insn (reg, mem);
21718 if (DEFAULT_ABI == ABI_V4)
21720 if (frame_pointer_needed
21721 && info->first_gp_reg_save + i
21722 == HARD_FRAME_POINTER_REGNUM)
21724 add_reg_note (insn, REG_CFA_DEF_CFA,
21725 plus_constant (frame_reg_rtx, sp_offset));
21726 RTX_FRAME_RELATED_P (insn) = 1;
21729 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21730 cfa_restores);
21735 if (restore_lr && !restoring_GPRs_inline)
21737 rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
21738 info->lr_save_offset + sp_offset);
21740 emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
21741 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO),
21742 gen_rtx_REG (Pmode, 0));
21745 /* Restore fpr's if we need to do it without calling a function. */
21746 if (restoring_FPRs_inline)
21747 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
21748 if ((df_regs_ever_live_p (info->first_fp_reg_save+i)
21749 && ! call_used_regs[info->first_fp_reg_save+i]))
21751 rtx addr, mem, reg;
21752 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21753 GEN_INT (info->fp_save_offset
21754 + sp_offset
21755 + 8 * i));
21756 mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
21757 ? DFmode : SFmode), addr);
21758 reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
21759 ? DFmode : SFmode),
21760 info->first_fp_reg_save + i);
21762 emit_move_insn (reg, mem);
21763 if (DEFAULT_ABI == ABI_V4)
21764 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21765 cfa_restores);
21768 /* If we saved cr, restore it here. Just those that were used. */
21769 if (info->cr_save_p)
21771 rs6000_restore_saved_cr (cr_save_reg, using_mtcr_multiple);
21772 if (DEFAULT_ABI == ABI_V4)
21773 cfa_restores
21774 = alloc_reg_note (REG_CFA_RESTORE, gen_rtx_REG (SImode, CR2_REGNO),
21775 cfa_restores);
21778 /* If this is V.4, unwind the stack pointer after all of the loads
21779 have been done. */
21780 insn = rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx,
21781 sp_offset, !restoring_FPRs_inline);
21782 if (insn)
21784 if (cfa_restores)
21786 REG_NOTES (insn) = cfa_restores;
21787 cfa_restores = NULL_RTX;
21789 add_reg_note (insn, REG_CFA_DEF_CFA, sp_reg_rtx);
21790 RTX_FRAME_RELATED_P (insn) = 1;
21793 if (crtl->calls_eh_return)
21795 rtx sa = EH_RETURN_STACKADJ_RTX;
21796 emit_insn (gen_add3_insn (sp_reg_rtx, sp_reg_rtx, sa));
21799 if (!sibcall)
21801 rtvec p;
21802 bool lr = (strategy & REST_NOINLINE_FPRS_DOESNT_RESTORE_LR) == 0;
21803 if (! restoring_FPRs_inline)
21804 p = rtvec_alloc (4 + 64 - info->first_fp_reg_save);
21805 else
21806 p = rtvec_alloc (2);
21808 RTVEC_ELT (p, 0) = gen_rtx_RETURN (VOIDmode);
21809 RTVEC_ELT (p, 1) = ((restoring_FPRs_inline || !lr)
21810 ? gen_rtx_USE (VOIDmode, gen_rtx_REG (Pmode, 65))
21811 : gen_rtx_CLOBBER (VOIDmode,
21812 gen_rtx_REG (Pmode, 65)));
21814 /* If we have to restore more than two FP registers, branch to the
21815 restore function. It will return to our caller. */
21816 if (! restoring_FPRs_inline)
21818 int i;
21819 rtx sym;
21821 sym = rs6000_savres_routine_sym (info,
21822 /*savep=*/false,
21823 /*gpr=*/false,
21824 /*lr=*/lr);
21825 RTVEC_ELT (p, 2) = gen_rtx_USE (VOIDmode, sym);
21826 RTVEC_ELT (p, 3) = gen_rtx_USE (VOIDmode,
21827 gen_rtx_REG (Pmode,
21828 DEFAULT_ABI == ABI_AIX
21829 ? 1 : 11));
21830 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
21832 rtx addr, mem;
21833 addr = gen_rtx_PLUS (Pmode, sp_reg_rtx,
21834 GEN_INT (info->fp_save_offset + 8*i));
21835 mem = gen_frame_mem (DFmode, addr);
21837 RTVEC_ELT (p, i+4) =
21838 gen_rtx_SET (VOIDmode,
21839 gen_rtx_REG (DFmode, info->first_fp_reg_save + i),
21840 mem);
21844 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
21848 /* Write function epilogue. */
21850 static void
21851 rs6000_output_function_epilogue (FILE *file,
21852 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
21854 if (! HAVE_epilogue)
21856 rtx insn = get_last_insn ();
21857 /* If the last insn was a BARRIER, we don't have to write anything except
21858 the trace table. */
21859 if (GET_CODE (insn) == NOTE)
21860 insn = prev_nonnote_insn (insn);
21861 if (insn == 0 || GET_CODE (insn) != BARRIER)
21863 /* This is slightly ugly, but at least we don't have two
21864 copies of the epilogue-emitting code. */
21865 start_sequence ();
21867 /* A NOTE_INSN_DELETED is supposed to be at the start
21868 and end of the "toplevel" insn chain. */
21869 emit_note (NOTE_INSN_DELETED);
21870 rs6000_emit_epilogue (FALSE);
21871 emit_note (NOTE_INSN_DELETED);
21873 /* Expand INSN_ADDRESSES so final() doesn't crash. */
21875 rtx insn;
21876 unsigned addr = 0;
21877 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
21879 INSN_ADDRESSES_NEW (insn, addr);
21880 addr += 4;
21884 if (TARGET_DEBUG_STACK)
21885 debug_rtx_list (get_insns (), 100);
21886 final (get_insns (), file, FALSE);
21887 end_sequence ();
21891 #if TARGET_MACHO
21892 macho_branch_islands ();
21893 /* Mach-O doesn't support labels at the end of objects, so if
21894 it looks like we might want one, insert a NOP. */
21896 rtx insn = get_last_insn ();
21897 while (insn
21898 && NOTE_P (insn)
21899 && NOTE_KIND (insn) != NOTE_INSN_DELETED_LABEL)
21900 insn = PREV_INSN (insn);
21901 if (insn
21902 && (LABEL_P (insn)
21903 || (NOTE_P (insn)
21904 && NOTE_KIND (insn) == NOTE_INSN_DELETED_LABEL)))
21905 fputs ("\tnop\n", file);
21907 #endif
21909 /* Output a traceback table here. See /usr/include/sys/debug.h for info
21910 on its format.
21912 We don't output a traceback table if -finhibit-size-directive was
21913 used. The documentation for -finhibit-size-directive reads
21914 ``don't output a @code{.size} assembler directive, or anything
21915 else that would cause trouble if the function is split in the
21916 middle, and the two halves are placed at locations far apart in
21917 memory.'' The traceback table has this property, since it
21918 includes the offset from the start of the function to the
21919 traceback table itself.
21921 System V.4 Powerpc's (and the embedded ABI derived from it) use a
21922 different traceback table. */
21923 if (DEFAULT_ABI == ABI_AIX && ! flag_inhibit_size_directive
21924 && rs6000_traceback != traceback_none && !cfun->is_thunk)
21926 const char *fname = NULL;
21927 const char *language_string = lang_hooks.name;
21928 int fixed_parms = 0, float_parms = 0, parm_info = 0;
21929 int i;
21930 int optional_tbtab;
21931 rs6000_stack_t *info = rs6000_stack_info ();
21933 if (rs6000_traceback == traceback_full)
21934 optional_tbtab = 1;
21935 else if (rs6000_traceback == traceback_part)
21936 optional_tbtab = 0;
21937 else
21938 optional_tbtab = !optimize_size && !TARGET_ELF;
21940 if (optional_tbtab)
21942 fname = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0);
21943 while (*fname == '.') /* V.4 encodes . in the name */
21944 fname++;
21946 /* Need label immediately before tbtab, so we can compute
21947 its offset from the function start. */
21948 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
21949 ASM_OUTPUT_LABEL (file, fname);
21952 /* The .tbtab pseudo-op can only be used for the first eight
21953 expressions, since it can't handle the possibly variable
21954 length fields that follow. However, if you omit the optional
21955 fields, the assembler outputs zeros for all optional fields
21956 anyways, giving each variable length field is minimum length
21957 (as defined in sys/debug.h). Thus we can not use the .tbtab
21958 pseudo-op at all. */
21960 /* An all-zero word flags the start of the tbtab, for debuggers
21961 that have to find it by searching forward from the entry
21962 point or from the current pc. */
21963 fputs ("\t.long 0\n", file);
21965 /* Tbtab format type. Use format type 0. */
21966 fputs ("\t.byte 0,", file);
21968 /* Language type. Unfortunately, there does not seem to be any
21969 official way to discover the language being compiled, so we
21970 use language_string.
21971 C is 0. Fortran is 1. Pascal is 2. Ada is 3. C++ is 9.
21972 Java is 13. Objective-C is 14. Objective-C++ isn't assigned
21973 a number, so for now use 9. LTO isn't assigned a number either,
21974 so for now use 0. */
21975 if (! strcmp (language_string, "GNU C")
21976 || ! strcmp (language_string, "GNU GIMPLE"))
21977 i = 0;
21978 else if (! strcmp (language_string, "GNU F77")
21979 || ! strcmp (language_string, "GNU Fortran"))
21980 i = 1;
21981 else if (! strcmp (language_string, "GNU Pascal"))
21982 i = 2;
21983 else if (! strcmp (language_string, "GNU Ada"))
21984 i = 3;
21985 else if (! strcmp (language_string, "GNU C++")
21986 || ! strcmp (language_string, "GNU Objective-C++"))
21987 i = 9;
21988 else if (! strcmp (language_string, "GNU Java"))
21989 i = 13;
21990 else if (! strcmp (language_string, "GNU Objective-C"))
21991 i = 14;
21992 else
21993 gcc_unreachable ();
21994 fprintf (file, "%d,", i);
21996 /* 8 single bit fields: global linkage (not set for C extern linkage,
21997 apparently a PL/I convention?), out-of-line epilogue/prologue, offset
21998 from start of procedure stored in tbtab, internal function, function
21999 has controlled storage, function has no toc, function uses fp,
22000 function logs/aborts fp operations. */
22001 /* Assume that fp operations are used if any fp reg must be saved. */
22002 fprintf (file, "%d,",
22003 (optional_tbtab << 5) | ((info->first_fp_reg_save != 64) << 1));
22005 /* 6 bitfields: function is interrupt handler, name present in
22006 proc table, function calls alloca, on condition directives
22007 (controls stack walks, 3 bits), saves condition reg, saves
22008 link reg. */
22009 /* The `function calls alloca' bit seems to be set whenever reg 31 is
22010 set up as a frame pointer, even when there is no alloca call. */
22011 fprintf (file, "%d,",
22012 ((optional_tbtab << 6)
22013 | ((optional_tbtab & frame_pointer_needed) << 5)
22014 | (info->cr_save_p << 1)
22015 | (info->lr_save_p)));
22017 /* 3 bitfields: saves backchain, fixup code, number of fpr saved
22018 (6 bits). */
22019 fprintf (file, "%d,",
22020 (info->push_p << 7) | (64 - info->first_fp_reg_save));
22022 /* 2 bitfields: spare bits (2 bits), number of gpr saved (6 bits). */
22023 fprintf (file, "%d,", (32 - first_reg_to_save ()));
22025 if (optional_tbtab)
22027 /* Compute the parameter info from the function decl argument
22028 list. */
22029 tree decl;
22030 int next_parm_info_bit = 31;
22032 for (decl = DECL_ARGUMENTS (current_function_decl);
22033 decl; decl = DECL_CHAIN (decl))
22035 rtx parameter = DECL_INCOMING_RTL (decl);
22036 enum machine_mode mode = GET_MODE (parameter);
22038 if (GET_CODE (parameter) == REG)
22040 if (SCALAR_FLOAT_MODE_P (mode))
22042 int bits;
22044 float_parms++;
22046 switch (mode)
22048 case SFmode:
22049 case SDmode:
22050 bits = 0x2;
22051 break;
22053 case DFmode:
22054 case DDmode:
22055 case TFmode:
22056 case TDmode:
22057 bits = 0x3;
22058 break;
22060 default:
22061 gcc_unreachable ();
22064 /* If only one bit will fit, don't or in this entry. */
22065 if (next_parm_info_bit > 0)
22066 parm_info |= (bits << (next_parm_info_bit - 1));
22067 next_parm_info_bit -= 2;
22069 else
22071 fixed_parms += ((GET_MODE_SIZE (mode)
22072 + (UNITS_PER_WORD - 1))
22073 / UNITS_PER_WORD);
22074 next_parm_info_bit -= 1;
22080 /* Number of fixed point parameters. */
22081 /* This is actually the number of words of fixed point parameters; thus
22082 an 8 byte struct counts as 2; and thus the maximum value is 8. */
22083 fprintf (file, "%d,", fixed_parms);
22085 /* 2 bitfields: number of floating point parameters (7 bits), parameters
22086 all on stack. */
22087 /* This is actually the number of fp registers that hold parameters;
22088 and thus the maximum value is 13. */
22089 /* Set parameters on stack bit if parameters are not in their original
22090 registers, regardless of whether they are on the stack? Xlc
22091 seems to set the bit when not optimizing. */
22092 fprintf (file, "%d\n", ((float_parms << 1) | (! optimize)));
22094 if (! optional_tbtab)
22095 return;
22097 /* Optional fields follow. Some are variable length. */
22099 /* Parameter types, left adjusted bit fields: 0 fixed, 10 single float,
22100 11 double float. */
22101 /* There is an entry for each parameter in a register, in the order that
22102 they occur in the parameter list. Any intervening arguments on the
22103 stack are ignored. If the list overflows a long (max possible length
22104 34 bits) then completely leave off all elements that don't fit. */
22105 /* Only emit this long if there was at least one parameter. */
22106 if (fixed_parms || float_parms)
22107 fprintf (file, "\t.long %d\n", parm_info);
22109 /* Offset from start of code to tb table. */
22110 fputs ("\t.long ", file);
22111 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
22112 RS6000_OUTPUT_BASENAME (file, fname);
22113 putc ('-', file);
22114 rs6000_output_function_entry (file, fname);
22115 putc ('\n', file);
22117 /* Interrupt handler mask. */
22118 /* Omit this long, since we never set the interrupt handler bit
22119 above. */
22121 /* Number of CTL (controlled storage) anchors. */
22122 /* Omit this long, since the has_ctl bit is never set above. */
22124 /* Displacement into stack of each CTL anchor. */
22125 /* Omit this list of longs, because there are no CTL anchors. */
22127 /* Length of function name. */
22128 if (*fname == '*')
22129 ++fname;
22130 fprintf (file, "\t.short %d\n", (int) strlen (fname));
22132 /* Function name. */
22133 assemble_string (fname, strlen (fname));
22135 /* Register for alloca automatic storage; this is always reg 31.
22136 Only emit this if the alloca bit was set above. */
22137 if (frame_pointer_needed)
22138 fputs ("\t.byte 31\n", file);
22140 fputs ("\t.align 2\n", file);
22144 /* A C compound statement that outputs the assembler code for a thunk
22145 function, used to implement C++ virtual function calls with
22146 multiple inheritance. The thunk acts as a wrapper around a virtual
22147 function, adjusting the implicit object parameter before handing
22148 control off to the real function.
22150 First, emit code to add the integer DELTA to the location that
22151 contains the incoming first argument. Assume that this argument
22152 contains a pointer, and is the one used to pass the `this' pointer
22153 in C++. This is the incoming argument *before* the function
22154 prologue, e.g. `%o0' on a sparc. The addition must preserve the
22155 values of all other incoming arguments.
22157 After the addition, emit code to jump to FUNCTION, which is a
22158 `FUNCTION_DECL'. This is a direct pure jump, not a call, and does
22159 not touch the return address. Hence returning from FUNCTION will
22160 return to whoever called the current `thunk'.
22162 The effect must be as if FUNCTION had been called directly with the
22163 adjusted first argument. This macro is responsible for emitting
22164 all of the code for a thunk function; output_function_prologue()
22165 and output_function_epilogue() are not invoked.
22167 The THUNK_FNDECL is redundant. (DELTA and FUNCTION have already
22168 been extracted from it.) It might possibly be useful on some
22169 targets, but probably not.
22171 If you do not define this macro, the target-independent code in the
22172 C++ frontend will generate a less efficient heavyweight thunk that
22173 calls FUNCTION instead of jumping to it. The generic approach does
22174 not support varargs. */
22176 static void
22177 rs6000_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
22178 HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
22179 tree function)
22181 rtx this_rtx, insn, funexp;
22183 reload_completed = 1;
22184 epilogue_completed = 1;
22186 /* Mark the end of the (empty) prologue. */
22187 emit_note (NOTE_INSN_PROLOGUE_END);
22189 /* Find the "this" pointer. If the function returns a structure,
22190 the structure return pointer is in r3. */
22191 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function))
22192 this_rtx = gen_rtx_REG (Pmode, 4);
22193 else
22194 this_rtx = gen_rtx_REG (Pmode, 3);
22196 /* Apply the constant offset, if required. */
22197 if (delta)
22198 emit_insn (gen_add3_insn (this_rtx, this_rtx, GEN_INT (delta)));
22200 /* Apply the offset from the vtable, if required. */
22201 if (vcall_offset)
22203 rtx vcall_offset_rtx = GEN_INT (vcall_offset);
22204 rtx tmp = gen_rtx_REG (Pmode, 12);
22206 emit_move_insn (tmp, gen_rtx_MEM (Pmode, this_rtx));
22207 if (((unsigned HOST_WIDE_INT) vcall_offset) + 0x8000 >= 0x10000)
22209 emit_insn (gen_add3_insn (tmp, tmp, vcall_offset_rtx));
22210 emit_move_insn (tmp, gen_rtx_MEM (Pmode, tmp));
22212 else
22214 rtx loc = gen_rtx_PLUS (Pmode, tmp, vcall_offset_rtx);
22216 emit_move_insn (tmp, gen_rtx_MEM (Pmode, loc));
22218 emit_insn (gen_add3_insn (this_rtx, this_rtx, tmp));
22221 /* Generate a tail call to the target function. */
22222 if (!TREE_USED (function))
22224 assemble_external (function);
22225 TREE_USED (function) = 1;
22227 funexp = XEXP (DECL_RTL (function), 0);
22228 funexp = gen_rtx_MEM (FUNCTION_MODE, funexp);
22230 #if TARGET_MACHO
22231 if (MACHOPIC_INDIRECT)
22232 funexp = machopic_indirect_call_target (funexp);
22233 #endif
22235 /* gen_sibcall expects reload to convert scratch pseudo to LR so we must
22236 generate sibcall RTL explicitly. */
22237 insn = emit_call_insn (
22238 gen_rtx_PARALLEL (VOIDmode,
22239 gen_rtvec (4,
22240 gen_rtx_CALL (VOIDmode,
22241 funexp, const0_rtx),
22242 gen_rtx_USE (VOIDmode, const0_rtx),
22243 gen_rtx_USE (VOIDmode,
22244 gen_rtx_REG (SImode,
22245 LR_REGNO)),
22246 gen_rtx_RETURN (VOIDmode))));
22247 SIBLING_CALL_P (insn) = 1;
22248 emit_barrier ();
22250 /* Run just enough of rest_of_compilation to get the insns emitted.
22251 There's not really enough bulk here to make other passes such as
22252 instruction scheduling worth while. Note that use_thunk calls
22253 assemble_start_function and assemble_end_function. */
22254 insn = get_insns ();
22255 insn_locators_alloc ();
22256 shorten_branches (insn);
22257 final_start_function (insn, file, 1);
22258 final (insn, file, 1);
22259 final_end_function ();
22261 reload_completed = 0;
22262 epilogue_completed = 0;
22265 /* A quick summary of the various types of 'constant-pool tables'
22266 under PowerPC:
22268 Target Flags Name One table per
22269 AIX (none) AIX TOC object file
22270 AIX -mfull-toc AIX TOC object file
22271 AIX -mminimal-toc AIX minimal TOC translation unit
22272 SVR4/EABI (none) SVR4 SDATA object file
22273 SVR4/EABI -fpic SVR4 pic object file
22274 SVR4/EABI -fPIC SVR4 PIC translation unit
22275 SVR4/EABI -mrelocatable EABI TOC function
22276 SVR4/EABI -maix AIX TOC object file
22277 SVR4/EABI -maix -mminimal-toc
22278 AIX minimal TOC translation unit
22280 Name Reg. Set by entries contains:
22281 made by addrs? fp? sum?
22283 AIX TOC 2 crt0 as Y option option
22284 AIX minimal TOC 30 prolog gcc Y Y option
22285 SVR4 SDATA 13 crt0 gcc N Y N
22286 SVR4 pic 30 prolog ld Y not yet N
22287 SVR4 PIC 30 prolog gcc Y option option
22288 EABI TOC 30 prolog gcc Y option option
22292 /* Hash functions for the hash table. */
22294 static unsigned
22295 rs6000_hash_constant (rtx k)
22297 enum rtx_code code = GET_CODE (k);
22298 enum machine_mode mode = GET_MODE (k);
22299 unsigned result = (code << 3) ^ mode;
22300 const char *format;
22301 int flen, fidx;
22303 format = GET_RTX_FORMAT (code);
22304 flen = strlen (format);
22305 fidx = 0;
22307 switch (code)
22309 case LABEL_REF:
22310 return result * 1231 + (unsigned) INSN_UID (XEXP (k, 0));
22312 case CONST_DOUBLE:
22313 if (mode != VOIDmode)
22314 return real_hash (CONST_DOUBLE_REAL_VALUE (k)) * result;
22315 flen = 2;
22316 break;
22318 case CODE_LABEL:
22319 fidx = 3;
22320 break;
22322 default:
22323 break;
22326 for (; fidx < flen; fidx++)
22327 switch (format[fidx])
22329 case 's':
22331 unsigned i, len;
22332 const char *str = XSTR (k, fidx);
22333 len = strlen (str);
22334 result = result * 613 + len;
22335 for (i = 0; i < len; i++)
22336 result = result * 613 + (unsigned) str[i];
22337 break;
22339 case 'u':
22340 case 'e':
22341 result = result * 1231 + rs6000_hash_constant (XEXP (k, fidx));
22342 break;
22343 case 'i':
22344 case 'n':
22345 result = result * 613 + (unsigned) XINT (k, fidx);
22346 break;
22347 case 'w':
22348 if (sizeof (unsigned) >= sizeof (HOST_WIDE_INT))
22349 result = result * 613 + (unsigned) XWINT (k, fidx);
22350 else
22352 size_t i;
22353 for (i = 0; i < sizeof (HOST_WIDE_INT) / sizeof (unsigned); i++)
22354 result = result * 613 + (unsigned) (XWINT (k, fidx)
22355 >> CHAR_BIT * i);
22357 break;
22358 case '0':
22359 break;
22360 default:
22361 gcc_unreachable ();
22364 return result;
22367 static unsigned
22368 toc_hash_function (const void *hash_entry)
22370 const struct toc_hash_struct *thc =
22371 (const struct toc_hash_struct *) hash_entry;
22372 return rs6000_hash_constant (thc->key) ^ thc->key_mode;
22375 /* Compare H1 and H2 for equivalence. */
22377 static int
22378 toc_hash_eq (const void *h1, const void *h2)
22380 rtx r1 = ((const struct toc_hash_struct *) h1)->key;
22381 rtx r2 = ((const struct toc_hash_struct *) h2)->key;
22383 if (((const struct toc_hash_struct *) h1)->key_mode
22384 != ((const struct toc_hash_struct *) h2)->key_mode)
22385 return 0;
22387 return rtx_equal_p (r1, r2);
22390 /* These are the names given by the C++ front-end to vtables, and
22391 vtable-like objects. Ideally, this logic should not be here;
22392 instead, there should be some programmatic way of inquiring as
22393 to whether or not an object is a vtable. */
22395 #define VTABLE_NAME_P(NAME) \
22396 (strncmp ("_vt.", name, strlen ("_vt.")) == 0 \
22397 || strncmp ("_ZTV", name, strlen ("_ZTV")) == 0 \
22398 || strncmp ("_ZTT", name, strlen ("_ZTT")) == 0 \
22399 || strncmp ("_ZTI", name, strlen ("_ZTI")) == 0 \
22400 || strncmp ("_ZTC", name, strlen ("_ZTC")) == 0)
22402 #ifdef NO_DOLLAR_IN_LABEL
22403 /* Return a GGC-allocated character string translating dollar signs in
22404 input NAME to underscores. Used by XCOFF ASM_OUTPUT_LABELREF. */
22406 const char *
22407 rs6000_xcoff_strip_dollar (const char *name)
22409 char *strip, *p;
22410 int len;
22412 p = strchr (name, '$');
22414 if (p == 0 || p == name)
22415 return name;
22417 len = strlen (name);
22418 strip = (char *) alloca (len + 1);
22419 strcpy (strip, name);
22420 p = strchr (strip, '$');
22421 while (p)
22423 *p = '_';
22424 p = strchr (p + 1, '$');
22427 return ggc_alloc_string (strip, len);
22429 #endif
22431 void
22432 rs6000_output_symbol_ref (FILE *file, rtx x)
22434 /* Currently C++ toc references to vtables can be emitted before it
22435 is decided whether the vtable is public or private. If this is
22436 the case, then the linker will eventually complain that there is
22437 a reference to an unknown section. Thus, for vtables only,
22438 we emit the TOC reference to reference the symbol and not the
22439 section. */
22440 const char *name = XSTR (x, 0);
22442 if (VTABLE_NAME_P (name))
22444 RS6000_OUTPUT_BASENAME (file, name);
22446 else
22447 assemble_name (file, name);
22450 /* Output a TOC entry. We derive the entry name from what is being
22451 written. */
22453 void
22454 output_toc (FILE *file, rtx x, int labelno, enum machine_mode mode)
22456 char buf[256];
22457 const char *name = buf;
22458 rtx base = x;
22459 HOST_WIDE_INT offset = 0;
22461 gcc_assert (!TARGET_NO_TOC);
22463 /* When the linker won't eliminate them, don't output duplicate
22464 TOC entries (this happens on AIX if there is any kind of TOC,
22465 and on SVR4 under -fPIC or -mrelocatable). Don't do this for
22466 CODE_LABELs. */
22467 if (TARGET_TOC && GET_CODE (x) != LABEL_REF)
22469 struct toc_hash_struct *h;
22470 void * * found;
22472 /* Create toc_hash_table. This can't be done at TARGET_OPTION_OVERRIDE
22473 time because GGC is not initialized at that point. */
22474 if (toc_hash_table == NULL)
22475 toc_hash_table = htab_create_ggc (1021, toc_hash_function,
22476 toc_hash_eq, NULL);
22478 h = ggc_alloc_toc_hash_struct ();
22479 h->key = x;
22480 h->key_mode = mode;
22481 h->labelno = labelno;
22483 found = htab_find_slot (toc_hash_table, h, INSERT);
22484 if (*found == NULL)
22485 *found = h;
22486 else /* This is indeed a duplicate.
22487 Set this label equal to that label. */
22489 fputs ("\t.set ", file);
22490 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
22491 fprintf (file, "%d,", labelno);
22492 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
22493 fprintf (file, "%d\n", ((*(const struct toc_hash_struct **)
22494 found)->labelno));
22495 return;
22499 /* If we're going to put a double constant in the TOC, make sure it's
22500 aligned properly when strict alignment is on. */
22501 if (GET_CODE (x) == CONST_DOUBLE
22502 && STRICT_ALIGNMENT
22503 && GET_MODE_BITSIZE (mode) >= 64
22504 && ! (TARGET_NO_FP_IN_TOC && ! TARGET_MINIMAL_TOC)) {
22505 ASM_OUTPUT_ALIGN (file, 3);
22508 (*targetm.asm_out.internal_label) (file, "LC", labelno);
22510 /* Handle FP constants specially. Note that if we have a minimal
22511 TOC, things we put here aren't actually in the TOC, so we can allow
22512 FP constants. */
22513 if (GET_CODE (x) == CONST_DOUBLE &&
22514 (GET_MODE (x) == TFmode || GET_MODE (x) == TDmode))
22516 REAL_VALUE_TYPE rv;
22517 long k[4];
22519 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
22520 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
22521 REAL_VALUE_TO_TARGET_DECIMAL128 (rv, k);
22522 else
22523 REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv, k);
22525 if (TARGET_64BIT)
22527 if (TARGET_MINIMAL_TOC)
22528 fputs (DOUBLE_INT_ASM_OP, file);
22529 else
22530 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
22531 k[0] & 0xffffffff, k[1] & 0xffffffff,
22532 k[2] & 0xffffffff, k[3] & 0xffffffff);
22533 fprintf (file, "0x%lx%08lx,0x%lx%08lx\n",
22534 k[0] & 0xffffffff, k[1] & 0xffffffff,
22535 k[2] & 0xffffffff, k[3] & 0xffffffff);
22536 return;
22538 else
22540 if (TARGET_MINIMAL_TOC)
22541 fputs ("\t.long ", file);
22542 else
22543 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
22544 k[0] & 0xffffffff, k[1] & 0xffffffff,
22545 k[2] & 0xffffffff, k[3] & 0xffffffff);
22546 fprintf (file, "0x%lx,0x%lx,0x%lx,0x%lx\n",
22547 k[0] & 0xffffffff, k[1] & 0xffffffff,
22548 k[2] & 0xffffffff, k[3] & 0xffffffff);
22549 return;
22552 else if (GET_CODE (x) == CONST_DOUBLE &&
22553 (GET_MODE (x) == DFmode || GET_MODE (x) == DDmode))
22555 REAL_VALUE_TYPE rv;
22556 long k[2];
22558 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
22560 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
22561 REAL_VALUE_TO_TARGET_DECIMAL64 (rv, k);
22562 else
22563 REAL_VALUE_TO_TARGET_DOUBLE (rv, k);
22565 if (TARGET_64BIT)
22567 if (TARGET_MINIMAL_TOC)
22568 fputs (DOUBLE_INT_ASM_OP, file);
22569 else
22570 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
22571 k[0] & 0xffffffff, k[1] & 0xffffffff);
22572 fprintf (file, "0x%lx%08lx\n",
22573 k[0] & 0xffffffff, k[1] & 0xffffffff);
22574 return;
22576 else
22578 if (TARGET_MINIMAL_TOC)
22579 fputs ("\t.long ", file);
22580 else
22581 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
22582 k[0] & 0xffffffff, k[1] & 0xffffffff);
22583 fprintf (file, "0x%lx,0x%lx\n",
22584 k[0] & 0xffffffff, k[1] & 0xffffffff);
22585 return;
22588 else if (GET_CODE (x) == CONST_DOUBLE &&
22589 (GET_MODE (x) == SFmode || GET_MODE (x) == SDmode))
22591 REAL_VALUE_TYPE rv;
22592 long l;
22594 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
22595 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
22596 REAL_VALUE_TO_TARGET_DECIMAL32 (rv, l);
22597 else
22598 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
22600 if (TARGET_64BIT)
22602 if (TARGET_MINIMAL_TOC)
22603 fputs (DOUBLE_INT_ASM_OP, file);
22604 else
22605 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
22606 fprintf (file, "0x%lx00000000\n", l & 0xffffffff);
22607 return;
22609 else
22611 if (TARGET_MINIMAL_TOC)
22612 fputs ("\t.long ", file);
22613 else
22614 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
22615 fprintf (file, "0x%lx\n", l & 0xffffffff);
22616 return;
22619 else if (GET_MODE (x) == VOIDmode
22620 && (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE))
22622 unsigned HOST_WIDE_INT low;
22623 HOST_WIDE_INT high;
22625 if (GET_CODE (x) == CONST_DOUBLE)
22627 low = CONST_DOUBLE_LOW (x);
22628 high = CONST_DOUBLE_HIGH (x);
22630 else
22631 #if HOST_BITS_PER_WIDE_INT == 32
22633 low = INTVAL (x);
22634 high = (low & 0x80000000) ? ~0 : 0;
22636 #else
22638 low = INTVAL (x) & 0xffffffff;
22639 high = (HOST_WIDE_INT) INTVAL (x) >> 32;
22641 #endif
22643 /* TOC entries are always Pmode-sized, but since this
22644 is a bigendian machine then if we're putting smaller
22645 integer constants in the TOC we have to pad them.
22646 (This is still a win over putting the constants in
22647 a separate constant pool, because then we'd have
22648 to have both a TOC entry _and_ the actual constant.)
22650 For a 32-bit target, CONST_INT values are loaded and shifted
22651 entirely within `low' and can be stored in one TOC entry. */
22653 /* It would be easy to make this work, but it doesn't now. */
22654 gcc_assert (!TARGET_64BIT || POINTER_SIZE >= GET_MODE_BITSIZE (mode));
22656 if (POINTER_SIZE > GET_MODE_BITSIZE (mode))
22658 #if HOST_BITS_PER_WIDE_INT == 32
22659 lshift_double (low, high, POINTER_SIZE - GET_MODE_BITSIZE (mode),
22660 POINTER_SIZE, &low, &high, 0);
22661 #else
22662 low |= high << 32;
22663 low <<= POINTER_SIZE - GET_MODE_BITSIZE (mode);
22664 high = (HOST_WIDE_INT) low >> 32;
22665 low &= 0xffffffff;
22666 #endif
22669 if (TARGET_64BIT)
22671 if (TARGET_MINIMAL_TOC)
22672 fputs (DOUBLE_INT_ASM_OP, file);
22673 else
22674 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
22675 (long) high & 0xffffffff, (long) low & 0xffffffff);
22676 fprintf (file, "0x%lx%08lx\n",
22677 (long) high & 0xffffffff, (long) low & 0xffffffff);
22678 return;
22680 else
22682 if (POINTER_SIZE < GET_MODE_BITSIZE (mode))
22684 if (TARGET_MINIMAL_TOC)
22685 fputs ("\t.long ", file);
22686 else
22687 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
22688 (long) high & 0xffffffff, (long) low & 0xffffffff);
22689 fprintf (file, "0x%lx,0x%lx\n",
22690 (long) high & 0xffffffff, (long) low & 0xffffffff);
22692 else
22694 if (TARGET_MINIMAL_TOC)
22695 fputs ("\t.long ", file);
22696 else
22697 fprintf (file, "\t.tc IS_%lx[TC],", (long) low & 0xffffffff);
22698 fprintf (file, "0x%lx\n", (long) low & 0xffffffff);
22700 return;
22704 if (GET_CODE (x) == CONST)
22706 gcc_assert (GET_CODE (XEXP (x, 0)) == PLUS
22707 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT);
22709 base = XEXP (XEXP (x, 0), 0);
22710 offset = INTVAL (XEXP (XEXP (x, 0), 1));
22713 switch (GET_CODE (base))
22715 case SYMBOL_REF:
22716 name = XSTR (base, 0);
22717 break;
22719 case LABEL_REF:
22720 ASM_GENERATE_INTERNAL_LABEL (buf, "L",
22721 CODE_LABEL_NUMBER (XEXP (base, 0)));
22722 break;
22724 case CODE_LABEL:
22725 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (base));
22726 break;
22728 default:
22729 gcc_unreachable ();
22732 if (TARGET_MINIMAL_TOC)
22733 fputs (TARGET_32BIT ? "\t.long " : DOUBLE_INT_ASM_OP, file);
22734 else
22736 fputs ("\t.tc ", file);
22737 RS6000_OUTPUT_BASENAME (file, name);
22739 if (offset < 0)
22740 fprintf (file, ".N" HOST_WIDE_INT_PRINT_UNSIGNED, - offset);
22741 else if (offset)
22742 fprintf (file, ".P" HOST_WIDE_INT_PRINT_UNSIGNED, offset);
22744 fputs ("[TC],", file);
22747 /* Currently C++ toc references to vtables can be emitted before it
22748 is decided whether the vtable is public or private. If this is
22749 the case, then the linker will eventually complain that there is
22750 a TOC reference to an unknown section. Thus, for vtables only,
22751 we emit the TOC reference to reference the symbol and not the
22752 section. */
22753 if (VTABLE_NAME_P (name))
22755 RS6000_OUTPUT_BASENAME (file, name);
22756 if (offset < 0)
22757 fprintf (file, HOST_WIDE_INT_PRINT_DEC, offset);
22758 else if (offset > 0)
22759 fprintf (file, "+" HOST_WIDE_INT_PRINT_DEC, offset);
22761 else
22762 output_addr_const (file, x);
22763 putc ('\n', file);
22766 /* Output an assembler pseudo-op to write an ASCII string of N characters
22767 starting at P to FILE.
22769 On the RS/6000, we have to do this using the .byte operation and
22770 write out special characters outside the quoted string.
22771 Also, the assembler is broken; very long strings are truncated,
22772 so we must artificially break them up early. */
22774 void
22775 output_ascii (FILE *file, const char *p, int n)
22777 char c;
22778 int i, count_string;
22779 const char *for_string = "\t.byte \"";
22780 const char *for_decimal = "\t.byte ";
22781 const char *to_close = NULL;
22783 count_string = 0;
22784 for (i = 0; i < n; i++)
22786 c = *p++;
22787 if (c >= ' ' && c < 0177)
22789 if (for_string)
22790 fputs (for_string, file);
22791 putc (c, file);
22793 /* Write two quotes to get one. */
22794 if (c == '"')
22796 putc (c, file);
22797 ++count_string;
22800 for_string = NULL;
22801 for_decimal = "\"\n\t.byte ";
22802 to_close = "\"\n";
22803 ++count_string;
22805 if (count_string >= 512)
22807 fputs (to_close, file);
22809 for_string = "\t.byte \"";
22810 for_decimal = "\t.byte ";
22811 to_close = NULL;
22812 count_string = 0;
22815 else
22817 if (for_decimal)
22818 fputs (for_decimal, file);
22819 fprintf (file, "%d", c);
22821 for_string = "\n\t.byte \"";
22822 for_decimal = ", ";
22823 to_close = "\n";
22824 count_string = 0;
22828 /* Now close the string if we have written one. Then end the line. */
22829 if (to_close)
22830 fputs (to_close, file);
22833 /* Generate a unique section name for FILENAME for a section type
22834 represented by SECTION_DESC. Output goes into BUF.
22836 SECTION_DESC can be any string, as long as it is different for each
22837 possible section type.
22839 We name the section in the same manner as xlc. The name begins with an
22840 underscore followed by the filename (after stripping any leading directory
22841 names) with the last period replaced by the string SECTION_DESC. If
22842 FILENAME does not contain a period, SECTION_DESC is appended to the end of
22843 the name. */
22845 void
22846 rs6000_gen_section_name (char **buf, const char *filename,
22847 const char *section_desc)
22849 const char *q, *after_last_slash, *last_period = 0;
22850 char *p;
22851 int len;
22853 after_last_slash = filename;
22854 for (q = filename; *q; q++)
22856 if (*q == '/')
22857 after_last_slash = q + 1;
22858 else if (*q == '.')
22859 last_period = q;
22862 len = strlen (after_last_slash) + strlen (section_desc) + 2;
22863 *buf = (char *) xmalloc (len);
22865 p = *buf;
22866 *p++ = '_';
22868 for (q = after_last_slash; *q; q++)
22870 if (q == last_period)
22872 strcpy (p, section_desc);
22873 p += strlen (section_desc);
22874 break;
22877 else if (ISALNUM (*q))
22878 *p++ = *q;
22881 if (last_period == 0)
22882 strcpy (p, section_desc);
22883 else
22884 *p = '\0';
22887 /* Emit profile function. */
22889 void
22890 output_profile_hook (int labelno ATTRIBUTE_UNUSED)
22892 /* Non-standard profiling for kernels, which just saves LR then calls
22893 _mcount without worrying about arg saves. The idea is to change
22894 the function prologue as little as possible as it isn't easy to
22895 account for arg save/restore code added just for _mcount. */
22896 if (TARGET_PROFILE_KERNEL)
22897 return;
22899 if (DEFAULT_ABI == ABI_AIX)
22901 #ifndef NO_PROFILE_COUNTERS
22902 # define NO_PROFILE_COUNTERS 0
22903 #endif
22904 if (NO_PROFILE_COUNTERS)
22905 emit_library_call (init_one_libfunc (RS6000_MCOUNT),
22906 LCT_NORMAL, VOIDmode, 0);
22907 else
22909 char buf[30];
22910 const char *label_name;
22911 rtx fun;
22913 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
22914 label_name = (*targetm.strip_name_encoding) (ggc_strdup (buf));
22915 fun = gen_rtx_SYMBOL_REF (Pmode, label_name);
22917 emit_library_call (init_one_libfunc (RS6000_MCOUNT),
22918 LCT_NORMAL, VOIDmode, 1, fun, Pmode);
22921 else if (DEFAULT_ABI == ABI_DARWIN)
22923 const char *mcount_name = RS6000_MCOUNT;
22924 int caller_addr_regno = LR_REGNO;
22926 /* Be conservative and always set this, at least for now. */
22927 crtl->uses_pic_offset_table = 1;
22929 #if TARGET_MACHO
22930 /* For PIC code, set up a stub and collect the caller's address
22931 from r0, which is where the prologue puts it. */
22932 if (MACHOPIC_INDIRECT
22933 && crtl->uses_pic_offset_table)
22934 caller_addr_regno = 0;
22935 #endif
22936 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, mcount_name),
22937 LCT_NORMAL, VOIDmode, 1,
22938 gen_rtx_REG (Pmode, caller_addr_regno), Pmode);
22942 /* Write function profiler code. */
22944 void
22945 output_function_profiler (FILE *file, int labelno)
22947 char buf[100];
22949 switch (DEFAULT_ABI)
22951 default:
22952 gcc_unreachable ();
22954 case ABI_V4:
22955 if (!TARGET_32BIT)
22957 warning (0, "no profiling of 64-bit code for this ABI");
22958 return;
22960 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
22961 fprintf (file, "\tmflr %s\n", reg_names[0]);
22962 if (NO_PROFILE_COUNTERS)
22964 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
22965 reg_names[0], reg_names[1]);
22967 else if (TARGET_SECURE_PLT && flag_pic)
22969 asm_fprintf (file, "\tbcl 20,31,1f\n1:\n\t{st|stw} %s,4(%s)\n",
22970 reg_names[0], reg_names[1]);
22971 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
22972 asm_fprintf (file, "\t{cau|addis} %s,%s,",
22973 reg_names[12], reg_names[12]);
22974 assemble_name (file, buf);
22975 asm_fprintf (file, "-1b@ha\n\t{cal|la} %s,", reg_names[0]);
22976 assemble_name (file, buf);
22977 asm_fprintf (file, "-1b@l(%s)\n", reg_names[12]);
22979 else if (flag_pic == 1)
22981 fputs ("\tbl _GLOBAL_OFFSET_TABLE_@local-4\n", file);
22982 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
22983 reg_names[0], reg_names[1]);
22984 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
22985 asm_fprintf (file, "\t{l|lwz} %s,", reg_names[0]);
22986 assemble_name (file, buf);
22987 asm_fprintf (file, "@got(%s)\n", reg_names[12]);
22989 else if (flag_pic > 1)
22991 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
22992 reg_names[0], reg_names[1]);
22993 /* Now, we need to get the address of the label. */
22994 fputs ("\tbcl 20,31,1f\n\t.long ", file);
22995 assemble_name (file, buf);
22996 fputs ("-.\n1:", file);
22997 asm_fprintf (file, "\tmflr %s\n", reg_names[11]);
22998 asm_fprintf (file, "\t{l|lwz} %s,0(%s)\n",
22999 reg_names[0], reg_names[11]);
23000 asm_fprintf (file, "\t{cax|add} %s,%s,%s\n",
23001 reg_names[0], reg_names[0], reg_names[11]);
23003 else
23005 asm_fprintf (file, "\t{liu|lis} %s,", reg_names[12]);
23006 assemble_name (file, buf);
23007 fputs ("@ha\n", file);
23008 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
23009 reg_names[0], reg_names[1]);
23010 asm_fprintf (file, "\t{cal|la} %s,", reg_names[0]);
23011 assemble_name (file, buf);
23012 asm_fprintf (file, "@l(%s)\n", reg_names[12]);
23015 /* ABI_V4 saves the static chain reg with ASM_OUTPUT_REG_PUSH. */
23016 fprintf (file, "\tbl %s%s\n",
23017 RS6000_MCOUNT, flag_pic ? "@plt" : "");
23018 break;
23020 case ABI_AIX:
23021 case ABI_DARWIN:
23022 if (!TARGET_PROFILE_KERNEL)
23024 /* Don't do anything, done in output_profile_hook (). */
23026 else
23028 gcc_assert (!TARGET_32BIT);
23030 asm_fprintf (file, "\tmflr %s\n", reg_names[0]);
23031 asm_fprintf (file, "\tstd %s,16(%s)\n", reg_names[0], reg_names[1]);
23033 if (cfun->static_chain_decl != NULL)
23035 asm_fprintf (file, "\tstd %s,24(%s)\n",
23036 reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
23037 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
23038 asm_fprintf (file, "\tld %s,24(%s)\n",
23039 reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
23041 else
23042 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
23044 break;
23050 /* The following variable value is the last issued insn. */
23052 static rtx last_scheduled_insn;
23054 /* The following variable helps to balance issuing of load and
23055 store instructions */
23057 static int load_store_pendulum;
23059 /* Power4 load update and store update instructions are cracked into a
23060 load or store and an integer insn which are executed in the same cycle.
23061 Branches have their own dispatch slot which does not count against the
23062 GCC issue rate, but it changes the program flow so there are no other
23063 instructions to issue in this cycle. */
23065 static int
23066 rs6000_variable_issue_1 (rtx insn, int more)
23068 last_scheduled_insn = insn;
23069 if (GET_CODE (PATTERN (insn)) == USE
23070 || GET_CODE (PATTERN (insn)) == CLOBBER)
23072 cached_can_issue_more = more;
23073 return cached_can_issue_more;
23076 if (insn_terminates_group_p (insn, current_group))
23078 cached_can_issue_more = 0;
23079 return cached_can_issue_more;
23082 /* If no reservation, but reach here */
23083 if (recog_memoized (insn) < 0)
23084 return more;
23086 if (rs6000_sched_groups)
23088 if (is_microcoded_insn (insn))
23089 cached_can_issue_more = 0;
23090 else if (is_cracked_insn (insn))
23091 cached_can_issue_more = more > 2 ? more - 2 : 0;
23092 else
23093 cached_can_issue_more = more - 1;
23095 return cached_can_issue_more;
23098 if (rs6000_cpu_attr == CPU_CELL && is_nonpipeline_insn (insn))
23099 return 0;
23101 cached_can_issue_more = more - 1;
23102 return cached_can_issue_more;
23105 static int
23106 rs6000_variable_issue (FILE *stream, int verbose, rtx insn, int more)
23108 int r = rs6000_variable_issue_1 (insn, more);
23109 if (verbose)
23110 fprintf (stream, "// rs6000_variable_issue (more = %d) = %d\n", more, r);
23111 return r;
23114 /* Adjust the cost of a scheduling dependency. Return the new cost of
23115 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
23117 static int
23118 rs6000_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
23120 enum attr_type attr_type;
23122 if (! recog_memoized (insn))
23123 return 0;
23125 switch (REG_NOTE_KIND (link))
23127 case REG_DEP_TRUE:
23129 /* Data dependency; DEP_INSN writes a register that INSN reads
23130 some cycles later. */
23132 /* Separate a load from a narrower, dependent store. */
23133 if (rs6000_sched_groups
23134 && GET_CODE (PATTERN (insn)) == SET
23135 && GET_CODE (PATTERN (dep_insn)) == SET
23136 && GET_CODE (XEXP (PATTERN (insn), 1)) == MEM
23137 && GET_CODE (XEXP (PATTERN (dep_insn), 0)) == MEM
23138 && (GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (insn), 1)))
23139 > GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (dep_insn), 0)))))
23140 return cost + 14;
23142 attr_type = get_attr_type (insn);
23144 switch (attr_type)
23146 case TYPE_JMPREG:
23147 /* Tell the first scheduling pass about the latency between
23148 a mtctr and bctr (and mtlr and br/blr). The first
23149 scheduling pass will not know about this latency since
23150 the mtctr instruction, which has the latency associated
23151 to it, will be generated by reload. */
23152 return TARGET_POWER ? 5 : 4;
23153 case TYPE_BRANCH:
23154 /* Leave some extra cycles between a compare and its
23155 dependent branch, to inhibit expensive mispredicts. */
23156 if ((rs6000_cpu_attr == CPU_PPC603
23157 || rs6000_cpu_attr == CPU_PPC604
23158 || rs6000_cpu_attr == CPU_PPC604E
23159 || rs6000_cpu_attr == CPU_PPC620
23160 || rs6000_cpu_attr == CPU_PPC630
23161 || rs6000_cpu_attr == CPU_PPC750
23162 || rs6000_cpu_attr == CPU_PPC7400
23163 || rs6000_cpu_attr == CPU_PPC7450
23164 || rs6000_cpu_attr == CPU_POWER4
23165 || rs6000_cpu_attr == CPU_POWER5
23166 || rs6000_cpu_attr == CPU_POWER7
23167 || rs6000_cpu_attr == CPU_CELL)
23168 && recog_memoized (dep_insn)
23169 && (INSN_CODE (dep_insn) >= 0))
23171 switch (get_attr_type (dep_insn))
23173 case TYPE_CMP:
23174 case TYPE_COMPARE:
23175 case TYPE_DELAYED_COMPARE:
23176 case TYPE_IMUL_COMPARE:
23177 case TYPE_LMUL_COMPARE:
23178 case TYPE_FPCOMPARE:
23179 case TYPE_CR_LOGICAL:
23180 case TYPE_DELAYED_CR:
23181 return cost + 2;
23182 default:
23183 break;
23185 break;
23187 case TYPE_STORE:
23188 case TYPE_STORE_U:
23189 case TYPE_STORE_UX:
23190 case TYPE_FPSTORE:
23191 case TYPE_FPSTORE_U:
23192 case TYPE_FPSTORE_UX:
23193 if ((rs6000_cpu == PROCESSOR_POWER6)
23194 && recog_memoized (dep_insn)
23195 && (INSN_CODE (dep_insn) >= 0))
23198 if (GET_CODE (PATTERN (insn)) != SET)
23199 /* If this happens, we have to extend this to schedule
23200 optimally. Return default for now. */
23201 return cost;
23203 /* Adjust the cost for the case where the value written
23204 by a fixed point operation is used as the address
23205 gen value on a store. */
23206 switch (get_attr_type (dep_insn))
23208 case TYPE_LOAD:
23209 case TYPE_LOAD_U:
23210 case TYPE_LOAD_UX:
23211 case TYPE_CNTLZ:
23213 if (! store_data_bypass_p (dep_insn, insn))
23214 return 4;
23215 break;
23217 case TYPE_LOAD_EXT:
23218 case TYPE_LOAD_EXT_U:
23219 case TYPE_LOAD_EXT_UX:
23220 case TYPE_VAR_SHIFT_ROTATE:
23221 case TYPE_VAR_DELAYED_COMPARE:
23223 if (! store_data_bypass_p (dep_insn, insn))
23224 return 6;
23225 break;
23227 case TYPE_INTEGER:
23228 case TYPE_COMPARE:
23229 case TYPE_FAST_COMPARE:
23230 case TYPE_EXTS:
23231 case TYPE_SHIFT:
23232 case TYPE_INSERT_WORD:
23233 case TYPE_INSERT_DWORD:
23234 case TYPE_FPLOAD_U:
23235 case TYPE_FPLOAD_UX:
23236 case TYPE_STORE_U:
23237 case TYPE_STORE_UX:
23238 case TYPE_FPSTORE_U:
23239 case TYPE_FPSTORE_UX:
23241 if (! store_data_bypass_p (dep_insn, insn))
23242 return 3;
23243 break;
23245 case TYPE_IMUL:
23246 case TYPE_IMUL2:
23247 case TYPE_IMUL3:
23248 case TYPE_LMUL:
23249 case TYPE_IMUL_COMPARE:
23250 case TYPE_LMUL_COMPARE:
23252 if (! store_data_bypass_p (dep_insn, insn))
23253 return 17;
23254 break;
23256 case TYPE_IDIV:
23258 if (! store_data_bypass_p (dep_insn, insn))
23259 return 45;
23260 break;
23262 case TYPE_LDIV:
23264 if (! store_data_bypass_p (dep_insn, insn))
23265 return 57;
23266 break;
23268 default:
23269 break;
23272 break;
23274 case TYPE_LOAD:
23275 case TYPE_LOAD_U:
23276 case TYPE_LOAD_UX:
23277 case TYPE_LOAD_EXT:
23278 case TYPE_LOAD_EXT_U:
23279 case TYPE_LOAD_EXT_UX:
23280 if ((rs6000_cpu == PROCESSOR_POWER6)
23281 && recog_memoized (dep_insn)
23282 && (INSN_CODE (dep_insn) >= 0))
23285 /* Adjust the cost for the case where the value written
23286 by a fixed point instruction is used within the address
23287 gen portion of a subsequent load(u)(x) */
23288 switch (get_attr_type (dep_insn))
23290 case TYPE_LOAD:
23291 case TYPE_LOAD_U:
23292 case TYPE_LOAD_UX:
23293 case TYPE_CNTLZ:
23295 if (set_to_load_agen (dep_insn, insn))
23296 return 4;
23297 break;
23299 case TYPE_LOAD_EXT:
23300 case TYPE_LOAD_EXT_U:
23301 case TYPE_LOAD_EXT_UX:
23302 case TYPE_VAR_SHIFT_ROTATE:
23303 case TYPE_VAR_DELAYED_COMPARE:
23305 if (set_to_load_agen (dep_insn, insn))
23306 return 6;
23307 break;
23309 case TYPE_INTEGER:
23310 case TYPE_COMPARE:
23311 case TYPE_FAST_COMPARE:
23312 case TYPE_EXTS:
23313 case TYPE_SHIFT:
23314 case TYPE_INSERT_WORD:
23315 case TYPE_INSERT_DWORD:
23316 case TYPE_FPLOAD_U:
23317 case TYPE_FPLOAD_UX:
23318 case TYPE_STORE_U:
23319 case TYPE_STORE_UX:
23320 case TYPE_FPSTORE_U:
23321 case TYPE_FPSTORE_UX:
23323 if (set_to_load_agen (dep_insn, insn))
23324 return 3;
23325 break;
23327 case TYPE_IMUL:
23328 case TYPE_IMUL2:
23329 case TYPE_IMUL3:
23330 case TYPE_LMUL:
23331 case TYPE_IMUL_COMPARE:
23332 case TYPE_LMUL_COMPARE:
23334 if (set_to_load_agen (dep_insn, insn))
23335 return 17;
23336 break;
23338 case TYPE_IDIV:
23340 if (set_to_load_agen (dep_insn, insn))
23341 return 45;
23342 break;
23344 case TYPE_LDIV:
23346 if (set_to_load_agen (dep_insn, insn))
23347 return 57;
23348 break;
23350 default:
23351 break;
23354 break;
23356 case TYPE_FPLOAD:
23357 if ((rs6000_cpu == PROCESSOR_POWER6)
23358 && recog_memoized (dep_insn)
23359 && (INSN_CODE (dep_insn) >= 0)
23360 && (get_attr_type (dep_insn) == TYPE_MFFGPR))
23361 return 2;
23363 default:
23364 break;
23367 /* Fall out to return default cost. */
23369 break;
23371 case REG_DEP_OUTPUT:
23372 /* Output dependency; DEP_INSN writes a register that INSN writes some
23373 cycles later. */
23374 if ((rs6000_cpu == PROCESSOR_POWER6)
23375 && recog_memoized (dep_insn)
23376 && (INSN_CODE (dep_insn) >= 0))
23378 attr_type = get_attr_type (insn);
23380 switch (attr_type)
23382 case TYPE_FP:
23383 if (get_attr_type (dep_insn) == TYPE_FP)
23384 return 1;
23385 break;
23386 case TYPE_FPLOAD:
23387 if (get_attr_type (dep_insn) == TYPE_MFFGPR)
23388 return 2;
23389 break;
23390 default:
23391 break;
23394 case REG_DEP_ANTI:
23395 /* Anti dependency; DEP_INSN reads a register that INSN writes some
23396 cycles later. */
23397 return 0;
23399 default:
23400 gcc_unreachable ();
23403 return cost;
23406 /* Debug version of rs6000_adjust_cost. */
23408 static int
23409 rs6000_debug_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
23411 int ret = rs6000_adjust_cost (insn, link, dep_insn, cost);
23413 if (ret != cost)
23415 const char *dep;
23417 switch (REG_NOTE_KIND (link))
23419 default: dep = "unknown depencency"; break;
23420 case REG_DEP_TRUE: dep = "data dependency"; break;
23421 case REG_DEP_OUTPUT: dep = "output dependency"; break;
23422 case REG_DEP_ANTI: dep = "anti depencency"; break;
23425 fprintf (stderr,
23426 "\nrs6000_adjust_cost, final cost = %d, orig cost = %d, "
23427 "%s, insn:\n", ret, cost, dep);
23429 debug_rtx (insn);
23432 return ret;
23435 /* The function returns a true if INSN is microcoded.
23436 Return false otherwise. */
23438 static bool
23439 is_microcoded_insn (rtx insn)
23441 if (!insn || !NONDEBUG_INSN_P (insn)
23442 || GET_CODE (PATTERN (insn)) == USE
23443 || GET_CODE (PATTERN (insn)) == CLOBBER)
23444 return false;
23446 if (rs6000_cpu_attr == CPU_CELL)
23447 return get_attr_cell_micro (insn) == CELL_MICRO_ALWAYS;
23449 if (rs6000_sched_groups)
23451 enum attr_type type = get_attr_type (insn);
23452 if (type == TYPE_LOAD_EXT_U
23453 || type == TYPE_LOAD_EXT_UX
23454 || type == TYPE_LOAD_UX
23455 || type == TYPE_STORE_UX
23456 || type == TYPE_MFCR)
23457 return true;
23460 return false;
23463 /* The function returns true if INSN is cracked into 2 instructions
23464 by the processor (and therefore occupies 2 issue slots). */
23466 static bool
23467 is_cracked_insn (rtx insn)
23469 if (!insn || !NONDEBUG_INSN_P (insn)
23470 || GET_CODE (PATTERN (insn)) == USE
23471 || GET_CODE (PATTERN (insn)) == CLOBBER)
23472 return false;
23474 if (rs6000_sched_groups)
23476 enum attr_type type = get_attr_type (insn);
23477 if (type == TYPE_LOAD_U || type == TYPE_STORE_U
23478 || type == TYPE_FPLOAD_U || type == TYPE_FPSTORE_U
23479 || type == TYPE_FPLOAD_UX || type == TYPE_FPSTORE_UX
23480 || type == TYPE_LOAD_EXT || type == TYPE_DELAYED_CR
23481 || type == TYPE_COMPARE || type == TYPE_DELAYED_COMPARE
23482 || type == TYPE_IMUL_COMPARE || type == TYPE_LMUL_COMPARE
23483 || type == TYPE_IDIV || type == TYPE_LDIV
23484 || type == TYPE_INSERT_WORD)
23485 return true;
23488 return false;
23491 /* The function returns true if INSN can be issued only from
23492 the branch slot. */
23494 static bool
23495 is_branch_slot_insn (rtx insn)
23497 if (!insn || !NONDEBUG_INSN_P (insn)
23498 || GET_CODE (PATTERN (insn)) == USE
23499 || GET_CODE (PATTERN (insn)) == CLOBBER)
23500 return false;
23502 if (rs6000_sched_groups)
23504 enum attr_type type = get_attr_type (insn);
23505 if (type == TYPE_BRANCH || type == TYPE_JMPREG)
23506 return true;
23507 return false;
23510 return false;
23513 /* The function returns true if out_inst sets a value that is
23514 used in the address generation computation of in_insn */
23515 static bool
23516 set_to_load_agen (rtx out_insn, rtx in_insn)
23518 rtx out_set, in_set;
23520 /* For performance reasons, only handle the simple case where
23521 both loads are a single_set. */
23522 out_set = single_set (out_insn);
23523 if (out_set)
23525 in_set = single_set (in_insn);
23526 if (in_set)
23527 return reg_mentioned_p (SET_DEST (out_set), SET_SRC (in_set));
23530 return false;
23533 /* The function returns true if the target storage location of
23534 out_insn is adjacent to the target storage location of in_insn */
23535 /* Return 1 if memory locations are adjacent. */
23537 static bool
23538 adjacent_mem_locations (rtx insn1, rtx insn2)
23541 rtx a = get_store_dest (PATTERN (insn1));
23542 rtx b = get_store_dest (PATTERN (insn2));
23544 if ((GET_CODE (XEXP (a, 0)) == REG
23545 || (GET_CODE (XEXP (a, 0)) == PLUS
23546 && GET_CODE (XEXP (XEXP (a, 0), 1)) == CONST_INT))
23547 && (GET_CODE (XEXP (b, 0)) == REG
23548 || (GET_CODE (XEXP (b, 0)) == PLUS
23549 && GET_CODE (XEXP (XEXP (b, 0), 1)) == CONST_INT)))
23551 HOST_WIDE_INT val0 = 0, val1 = 0, val_diff;
23552 rtx reg0, reg1;
23554 if (GET_CODE (XEXP (a, 0)) == PLUS)
23556 reg0 = XEXP (XEXP (a, 0), 0);
23557 val0 = INTVAL (XEXP (XEXP (a, 0), 1));
23559 else
23560 reg0 = XEXP (a, 0);
23562 if (GET_CODE (XEXP (b, 0)) == PLUS)
23564 reg1 = XEXP (XEXP (b, 0), 0);
23565 val1 = INTVAL (XEXP (XEXP (b, 0), 1));
23567 else
23568 reg1 = XEXP (b, 0);
23570 val_diff = val1 - val0;
23572 return ((REGNO (reg0) == REGNO (reg1))
23573 && ((MEM_SIZE (a) && val_diff == INTVAL (MEM_SIZE (a)))
23574 || (MEM_SIZE (b) && val_diff == -INTVAL (MEM_SIZE (b)))));
23577 return false;
23580 /* A C statement (sans semicolon) to update the integer scheduling
23581 priority INSN_PRIORITY (INSN). Increase the priority to execute the
23582 INSN earlier, reduce the priority to execute INSN later. Do not
23583 define this macro if you do not need to adjust the scheduling
23584 priorities of insns. */
23586 static int
23587 rs6000_adjust_priority (rtx insn ATTRIBUTE_UNUSED, int priority)
23589 /* On machines (like the 750) which have asymmetric integer units,
23590 where one integer unit can do multiply and divides and the other
23591 can't, reduce the priority of multiply/divide so it is scheduled
23592 before other integer operations. */
23594 #if 0
23595 if (! INSN_P (insn))
23596 return priority;
23598 if (GET_CODE (PATTERN (insn)) == USE)
23599 return priority;
23601 switch (rs6000_cpu_attr) {
23602 case CPU_PPC750:
23603 switch (get_attr_type (insn))
23605 default:
23606 break;
23608 case TYPE_IMUL:
23609 case TYPE_IDIV:
23610 fprintf (stderr, "priority was %#x (%d) before adjustment\n",
23611 priority, priority);
23612 if (priority >= 0 && priority < 0x01000000)
23613 priority >>= 3;
23614 break;
23617 #endif
23619 if (insn_must_be_first_in_group (insn)
23620 && reload_completed
23621 && current_sched_info->sched_max_insns_priority
23622 && rs6000_sched_restricted_insns_priority)
23625 /* Prioritize insns that can be dispatched only in the first
23626 dispatch slot. */
23627 if (rs6000_sched_restricted_insns_priority == 1)
23628 /* Attach highest priority to insn. This means that in
23629 haifa-sched.c:ready_sort(), dispatch-slot restriction considerations
23630 precede 'priority' (critical path) considerations. */
23631 return current_sched_info->sched_max_insns_priority;
23632 else if (rs6000_sched_restricted_insns_priority == 2)
23633 /* Increase priority of insn by a minimal amount. This means that in
23634 haifa-sched.c:ready_sort(), only 'priority' (critical path)
23635 considerations precede dispatch-slot restriction considerations. */
23636 return (priority + 1);
23639 if (rs6000_cpu == PROCESSOR_POWER6
23640 && ((load_store_pendulum == -2 && is_load_insn (insn))
23641 || (load_store_pendulum == 2 && is_store_insn (insn))))
23642 /* Attach highest priority to insn if the scheduler has just issued two
23643 stores and this instruction is a load, or two loads and this instruction
23644 is a store. Power6 wants loads and stores scheduled alternately
23645 when possible */
23646 return current_sched_info->sched_max_insns_priority;
23648 return priority;
23651 /* Return true if the instruction is nonpipelined on the Cell. */
23652 static bool
23653 is_nonpipeline_insn (rtx insn)
23655 enum attr_type type;
23656 if (!insn || !NONDEBUG_INSN_P (insn)
23657 || GET_CODE (PATTERN (insn)) == USE
23658 || GET_CODE (PATTERN (insn)) == CLOBBER)
23659 return false;
23661 type = get_attr_type (insn);
23662 if (type == TYPE_IMUL
23663 || type == TYPE_IMUL2
23664 || type == TYPE_IMUL3
23665 || type == TYPE_LMUL
23666 || type == TYPE_IDIV
23667 || type == TYPE_LDIV
23668 || type == TYPE_SDIV
23669 || type == TYPE_DDIV
23670 || type == TYPE_SSQRT
23671 || type == TYPE_DSQRT
23672 || type == TYPE_MFCR
23673 || type == TYPE_MFCRF
23674 || type == TYPE_MFJMPR)
23676 return true;
23678 return false;
23682 /* Return how many instructions the machine can issue per cycle. */
23684 static int
23685 rs6000_issue_rate (void)
23687 /* Unless scheduling for register pressure, use issue rate of 1 for
23688 first scheduling pass to decrease degradation. */
23689 if (!reload_completed && !flag_sched_pressure)
23690 return 1;
23692 switch (rs6000_cpu_attr) {
23693 case CPU_RIOS1: /* ? */
23694 case CPU_RS64A:
23695 case CPU_PPC601: /* ? */
23696 case CPU_PPC7450:
23697 return 3;
23698 case CPU_PPC440:
23699 case CPU_PPC603:
23700 case CPU_PPC750:
23701 case CPU_PPC7400:
23702 case CPU_PPC8540:
23703 case CPU_CELL:
23704 case CPU_PPCE300C2:
23705 case CPU_PPCE300C3:
23706 case CPU_PPCE500MC:
23707 case CPU_PPCE500MC64:
23708 case CPU_TITAN:
23709 return 2;
23710 case CPU_RIOS2:
23711 case CPU_PPC476:
23712 case CPU_PPC604:
23713 case CPU_PPC604E:
23714 case CPU_PPC620:
23715 case CPU_PPC630:
23716 return 4;
23717 case CPU_POWER4:
23718 case CPU_POWER5:
23719 case CPU_POWER6:
23720 case CPU_POWER7:
23721 return 5;
23722 default:
23723 return 1;
23727 /* Return how many instructions to look ahead for better insn
23728 scheduling. */
23730 static int
23731 rs6000_use_sched_lookahead (void)
23733 if (rs6000_cpu_attr == CPU_PPC8540)
23734 return 4;
23735 if (rs6000_cpu_attr == CPU_CELL)
23736 return (reload_completed ? 8 : 0);
23737 return 0;
23740 /* We are choosing insn from the ready queue. Return nonzero if INSN can be chosen. */
23741 static int
23742 rs6000_use_sched_lookahead_guard (rtx insn)
23744 if (rs6000_cpu_attr != CPU_CELL)
23745 return 1;
23747 if (insn == NULL_RTX || !INSN_P (insn))
23748 abort ();
23750 if (!reload_completed
23751 || is_nonpipeline_insn (insn)
23752 || is_microcoded_insn (insn))
23753 return 0;
23755 return 1;
23758 /* Determine is PAT refers to memory. */
23760 static bool
23761 is_mem_ref (rtx pat)
23763 const char * fmt;
23764 int i, j;
23765 bool ret = false;
23767 /* stack_tie does not produce any real memory traffic. */
23768 if (GET_CODE (pat) == UNSPEC
23769 && XINT (pat, 1) == UNSPEC_TIE)
23770 return false;
23772 if (GET_CODE (pat) == MEM)
23773 return true;
23775 /* Recursively process the pattern. */
23776 fmt = GET_RTX_FORMAT (GET_CODE (pat));
23778 for (i = GET_RTX_LENGTH (GET_CODE (pat)) - 1; i >= 0 && !ret; i--)
23780 if (fmt[i] == 'e')
23781 ret |= is_mem_ref (XEXP (pat, i));
23782 else if (fmt[i] == 'E')
23783 for (j = XVECLEN (pat, i) - 1; j >= 0; j--)
23784 ret |= is_mem_ref (XVECEXP (pat, i, j));
23787 return ret;
23790 /* Determine if PAT is a PATTERN of a load insn. */
23792 static bool
23793 is_load_insn1 (rtx pat)
23795 if (!pat || pat == NULL_RTX)
23796 return false;
23798 if (GET_CODE (pat) == SET)
23799 return is_mem_ref (SET_SRC (pat));
23801 if (GET_CODE (pat) == PARALLEL)
23803 int i;
23805 for (i = 0; i < XVECLEN (pat, 0); i++)
23806 if (is_load_insn1 (XVECEXP (pat, 0, i)))
23807 return true;
23810 return false;
23813 /* Determine if INSN loads from memory. */
23815 static bool
23816 is_load_insn (rtx insn)
23818 if (!insn || !INSN_P (insn))
23819 return false;
23821 if (GET_CODE (insn) == CALL_INSN)
23822 return false;
23824 return is_load_insn1 (PATTERN (insn));
23827 /* Determine if PAT is a PATTERN of a store insn. */
23829 static bool
23830 is_store_insn1 (rtx pat)
23832 if (!pat || pat == NULL_RTX)
23833 return false;
23835 if (GET_CODE (pat) == SET)
23836 return is_mem_ref (SET_DEST (pat));
23838 if (GET_CODE (pat) == PARALLEL)
23840 int i;
23842 for (i = 0; i < XVECLEN (pat, 0); i++)
23843 if (is_store_insn1 (XVECEXP (pat, 0, i)))
23844 return true;
23847 return false;
23850 /* Determine if INSN stores to memory. */
23852 static bool
23853 is_store_insn (rtx insn)
23855 if (!insn || !INSN_P (insn))
23856 return false;
23858 return is_store_insn1 (PATTERN (insn));
23861 /* Return the dest of a store insn. */
23863 static rtx
23864 get_store_dest (rtx pat)
23866 gcc_assert (is_store_insn1 (pat));
23868 if (GET_CODE (pat) == SET)
23869 return SET_DEST (pat);
23870 else if (GET_CODE (pat) == PARALLEL)
23872 int i;
23874 for (i = 0; i < XVECLEN (pat, 0); i++)
23876 rtx inner_pat = XVECEXP (pat, 0, i);
23877 if (GET_CODE (inner_pat) == SET
23878 && is_mem_ref (SET_DEST (inner_pat)))
23879 return inner_pat;
23882 /* We shouldn't get here, because we should have either a simple
23883 store insn or a store with update which are covered above. */
23884 gcc_unreachable();
23887 /* Returns whether the dependence between INSN and NEXT is considered
23888 costly by the given target. */
23890 static bool
23891 rs6000_is_costly_dependence (dep_t dep, int cost, int distance)
23893 rtx insn;
23894 rtx next;
23896 /* If the flag is not enabled - no dependence is considered costly;
23897 allow all dependent insns in the same group.
23898 This is the most aggressive option. */
23899 if (rs6000_sched_costly_dep == no_dep_costly)
23900 return false;
23902 /* If the flag is set to 1 - a dependence is always considered costly;
23903 do not allow dependent instructions in the same group.
23904 This is the most conservative option. */
23905 if (rs6000_sched_costly_dep == all_deps_costly)
23906 return true;
23908 insn = DEP_PRO (dep);
23909 next = DEP_CON (dep);
23911 if (rs6000_sched_costly_dep == store_to_load_dep_costly
23912 && is_load_insn (next)
23913 && is_store_insn (insn))
23914 /* Prevent load after store in the same group. */
23915 return true;
23917 if (rs6000_sched_costly_dep == true_store_to_load_dep_costly
23918 && is_load_insn (next)
23919 && is_store_insn (insn)
23920 && DEP_TYPE (dep) == REG_DEP_TRUE)
23921 /* Prevent load after store in the same group if it is a true
23922 dependence. */
23923 return true;
23925 /* The flag is set to X; dependences with latency >= X are considered costly,
23926 and will not be scheduled in the same group. */
23927 if (rs6000_sched_costly_dep <= max_dep_latency
23928 && ((cost - distance) >= (int)rs6000_sched_costly_dep))
23929 return true;
23931 return false;
23934 /* Return the next insn after INSN that is found before TAIL is reached,
23935 skipping any "non-active" insns - insns that will not actually occupy
23936 an issue slot. Return NULL_RTX if such an insn is not found. */
23938 static rtx
23939 get_next_active_insn (rtx insn, rtx tail)
23941 if (insn == NULL_RTX || insn == tail)
23942 return NULL_RTX;
23944 while (1)
23946 insn = NEXT_INSN (insn);
23947 if (insn == NULL_RTX || insn == tail)
23948 return NULL_RTX;
23950 if (CALL_P (insn)
23951 || JUMP_P (insn)
23952 || (NONJUMP_INSN_P (insn)
23953 && GET_CODE (PATTERN (insn)) != USE
23954 && GET_CODE (PATTERN (insn)) != CLOBBER
23955 && INSN_CODE (insn) != CODE_FOR_stack_tie))
23956 break;
23958 return insn;
23961 /* We are about to begin issuing insns for this clock cycle. */
23963 static int
23964 rs6000_sched_reorder (FILE *dump ATTRIBUTE_UNUSED, int sched_verbose,
23965 rtx *ready ATTRIBUTE_UNUSED,
23966 int *pn_ready ATTRIBUTE_UNUSED,
23967 int clock_var ATTRIBUTE_UNUSED)
23969 int n_ready = *pn_ready;
23971 if (sched_verbose)
23972 fprintf (dump, "// rs6000_sched_reorder :\n");
23974 /* Reorder the ready list, if the second to last ready insn
23975 is a nonepipeline insn. */
23976 if (rs6000_cpu_attr == CPU_CELL && n_ready > 1)
23978 if (is_nonpipeline_insn (ready[n_ready - 1])
23979 && (recog_memoized (ready[n_ready - 2]) > 0))
23980 /* Simply swap first two insns. */
23982 rtx tmp = ready[n_ready - 1];
23983 ready[n_ready - 1] = ready[n_ready - 2];
23984 ready[n_ready - 2] = tmp;
23988 if (rs6000_cpu == PROCESSOR_POWER6)
23989 load_store_pendulum = 0;
23991 return rs6000_issue_rate ();
23994 /* Like rs6000_sched_reorder, but called after issuing each insn. */
23996 static int
23997 rs6000_sched_reorder2 (FILE *dump, int sched_verbose, rtx *ready,
23998 int *pn_ready, int clock_var ATTRIBUTE_UNUSED)
24000 if (sched_verbose)
24001 fprintf (dump, "// rs6000_sched_reorder2 :\n");
24003 /* For Power6, we need to handle some special cases to try and keep the
24004 store queue from overflowing and triggering expensive flushes.
24006 This code monitors how load and store instructions are being issued
24007 and skews the ready list one way or the other to increase the likelihood
24008 that a desired instruction is issued at the proper time.
24010 A couple of things are done. First, we maintain a "load_store_pendulum"
24011 to track the current state of load/store issue.
24013 - If the pendulum is at zero, then no loads or stores have been
24014 issued in the current cycle so we do nothing.
24016 - If the pendulum is 1, then a single load has been issued in this
24017 cycle and we attempt to locate another load in the ready list to
24018 issue with it.
24020 - If the pendulum is -2, then two stores have already been
24021 issued in this cycle, so we increase the priority of the first load
24022 in the ready list to increase it's likelihood of being chosen first
24023 in the next cycle.
24025 - If the pendulum is -1, then a single store has been issued in this
24026 cycle and we attempt to locate another store in the ready list to
24027 issue with it, preferring a store to an adjacent memory location to
24028 facilitate store pairing in the store queue.
24030 - If the pendulum is 2, then two loads have already been
24031 issued in this cycle, so we increase the priority of the first store
24032 in the ready list to increase it's likelihood of being chosen first
24033 in the next cycle.
24035 - If the pendulum < -2 or > 2, then do nothing.
24037 Note: This code covers the most common scenarios. There exist non
24038 load/store instructions which make use of the LSU and which
24039 would need to be accounted for to strictly model the behavior
24040 of the machine. Those instructions are currently unaccounted
24041 for to help minimize compile time overhead of this code.
24043 if (rs6000_cpu == PROCESSOR_POWER6 && last_scheduled_insn)
24045 int pos;
24046 int i;
24047 rtx tmp;
24049 if (is_store_insn (last_scheduled_insn))
24050 /* Issuing a store, swing the load_store_pendulum to the left */
24051 load_store_pendulum--;
24052 else if (is_load_insn (last_scheduled_insn))
24053 /* Issuing a load, swing the load_store_pendulum to the right */
24054 load_store_pendulum++;
24055 else
24056 return cached_can_issue_more;
24058 /* If the pendulum is balanced, or there is only one instruction on
24059 the ready list, then all is well, so return. */
24060 if ((load_store_pendulum == 0) || (*pn_ready <= 1))
24061 return cached_can_issue_more;
24063 if (load_store_pendulum == 1)
24065 /* A load has been issued in this cycle. Scan the ready list
24066 for another load to issue with it */
24067 pos = *pn_ready-1;
24069 while (pos >= 0)
24071 if (is_load_insn (ready[pos]))
24073 /* Found a load. Move it to the head of the ready list,
24074 and adjust it's priority so that it is more likely to
24075 stay there */
24076 tmp = ready[pos];
24077 for (i=pos; i<*pn_ready-1; i++)
24078 ready[i] = ready[i + 1];
24079 ready[*pn_ready-1] = tmp;
24081 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
24082 INSN_PRIORITY (tmp)++;
24083 break;
24085 pos--;
24088 else if (load_store_pendulum == -2)
24090 /* Two stores have been issued in this cycle. Increase the
24091 priority of the first load in the ready list to favor it for
24092 issuing in the next cycle. */
24093 pos = *pn_ready-1;
24095 while (pos >= 0)
24097 if (is_load_insn (ready[pos])
24098 && !sel_sched_p ()
24099 && INSN_PRIORITY_KNOWN (ready[pos]))
24101 INSN_PRIORITY (ready[pos])++;
24103 /* Adjust the pendulum to account for the fact that a load
24104 was found and increased in priority. This is to prevent
24105 increasing the priority of multiple loads */
24106 load_store_pendulum--;
24108 break;
24110 pos--;
24113 else if (load_store_pendulum == -1)
24115 /* A store has been issued in this cycle. Scan the ready list for
24116 another store to issue with it, preferring a store to an adjacent
24117 memory location */
24118 int first_store_pos = -1;
24120 pos = *pn_ready-1;
24122 while (pos >= 0)
24124 if (is_store_insn (ready[pos]))
24126 /* Maintain the index of the first store found on the
24127 list */
24128 if (first_store_pos == -1)
24129 first_store_pos = pos;
24131 if (is_store_insn (last_scheduled_insn)
24132 && adjacent_mem_locations (last_scheduled_insn,ready[pos]))
24134 /* Found an adjacent store. Move it to the head of the
24135 ready list, and adjust it's priority so that it is
24136 more likely to stay there */
24137 tmp = ready[pos];
24138 for (i=pos; i<*pn_ready-1; i++)
24139 ready[i] = ready[i + 1];
24140 ready[*pn_ready-1] = tmp;
24142 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
24143 INSN_PRIORITY (tmp)++;
24145 first_store_pos = -1;
24147 break;
24150 pos--;
24153 if (first_store_pos >= 0)
24155 /* An adjacent store wasn't found, but a non-adjacent store was,
24156 so move the non-adjacent store to the front of the ready
24157 list, and adjust its priority so that it is more likely to
24158 stay there. */
24159 tmp = ready[first_store_pos];
24160 for (i=first_store_pos; i<*pn_ready-1; i++)
24161 ready[i] = ready[i + 1];
24162 ready[*pn_ready-1] = tmp;
24163 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
24164 INSN_PRIORITY (tmp)++;
24167 else if (load_store_pendulum == 2)
24169 /* Two loads have been issued in this cycle. Increase the priority
24170 of the first store in the ready list to favor it for issuing in
24171 the next cycle. */
24172 pos = *pn_ready-1;
24174 while (pos >= 0)
24176 if (is_store_insn (ready[pos])
24177 && !sel_sched_p ()
24178 && INSN_PRIORITY_KNOWN (ready[pos]))
24180 INSN_PRIORITY (ready[pos])++;
24182 /* Adjust the pendulum to account for the fact that a store
24183 was found and increased in priority. This is to prevent
24184 increasing the priority of multiple stores */
24185 load_store_pendulum++;
24187 break;
24189 pos--;
24194 return cached_can_issue_more;
24197 /* Return whether the presence of INSN causes a dispatch group termination
24198 of group WHICH_GROUP.
24200 If WHICH_GROUP == current_group, this function will return true if INSN
24201 causes the termination of the current group (i.e, the dispatch group to
24202 which INSN belongs). This means that INSN will be the last insn in the
24203 group it belongs to.
24205 If WHICH_GROUP == previous_group, this function will return true if INSN
24206 causes the termination of the previous group (i.e, the dispatch group that
24207 precedes the group to which INSN belongs). This means that INSN will be
24208 the first insn in the group it belongs to). */
24210 static bool
24211 insn_terminates_group_p (rtx insn, enum group_termination which_group)
24213 bool first, last;
24215 if (! insn)
24216 return false;
24218 first = insn_must_be_first_in_group (insn);
24219 last = insn_must_be_last_in_group (insn);
24221 if (first && last)
24222 return true;
24224 if (which_group == current_group)
24225 return last;
24226 else if (which_group == previous_group)
24227 return first;
24229 return false;
24233 static bool
24234 insn_must_be_first_in_group (rtx insn)
24236 enum attr_type type;
24238 if (!insn
24239 || GET_CODE (insn) == NOTE
24240 || DEBUG_INSN_P (insn)
24241 || GET_CODE (PATTERN (insn)) == USE
24242 || GET_CODE (PATTERN (insn)) == CLOBBER)
24243 return false;
24245 switch (rs6000_cpu)
24247 case PROCESSOR_POWER5:
24248 if (is_cracked_insn (insn))
24249 return true;
24250 case PROCESSOR_POWER4:
24251 if (is_microcoded_insn (insn))
24252 return true;
24254 if (!rs6000_sched_groups)
24255 return false;
24257 type = get_attr_type (insn);
24259 switch (type)
24261 case TYPE_MFCR:
24262 case TYPE_MFCRF:
24263 case TYPE_MTCR:
24264 case TYPE_DELAYED_CR:
24265 case TYPE_CR_LOGICAL:
24266 case TYPE_MTJMPR:
24267 case TYPE_MFJMPR:
24268 case TYPE_IDIV:
24269 case TYPE_LDIV:
24270 case TYPE_LOAD_L:
24271 case TYPE_STORE_C:
24272 case TYPE_ISYNC:
24273 case TYPE_SYNC:
24274 return true;
24275 default:
24276 break;
24278 break;
24279 case PROCESSOR_POWER6:
24280 type = get_attr_type (insn);
24282 switch (type)
24284 case TYPE_INSERT_DWORD:
24285 case TYPE_EXTS:
24286 case TYPE_CNTLZ:
24287 case TYPE_SHIFT:
24288 case TYPE_VAR_SHIFT_ROTATE:
24289 case TYPE_TRAP:
24290 case TYPE_IMUL:
24291 case TYPE_IMUL2:
24292 case TYPE_IMUL3:
24293 case TYPE_LMUL:
24294 case TYPE_IDIV:
24295 case TYPE_INSERT_WORD:
24296 case TYPE_DELAYED_COMPARE:
24297 case TYPE_IMUL_COMPARE:
24298 case TYPE_LMUL_COMPARE:
24299 case TYPE_FPCOMPARE:
24300 case TYPE_MFCR:
24301 case TYPE_MTCR:
24302 case TYPE_MFJMPR:
24303 case TYPE_MTJMPR:
24304 case TYPE_ISYNC:
24305 case TYPE_SYNC:
24306 case TYPE_LOAD_L:
24307 case TYPE_STORE_C:
24308 case TYPE_LOAD_U:
24309 case TYPE_LOAD_UX:
24310 case TYPE_LOAD_EXT_UX:
24311 case TYPE_STORE_U:
24312 case TYPE_STORE_UX:
24313 case TYPE_FPLOAD_U:
24314 case TYPE_FPLOAD_UX:
24315 case TYPE_FPSTORE_U:
24316 case TYPE_FPSTORE_UX:
24317 return true;
24318 default:
24319 break;
24321 break;
24322 case PROCESSOR_POWER7:
24323 type = get_attr_type (insn);
24325 switch (type)
24327 case TYPE_CR_LOGICAL:
24328 case TYPE_MFCR:
24329 case TYPE_MFCRF:
24330 case TYPE_MTCR:
24331 case TYPE_IDIV:
24332 case TYPE_LDIV:
24333 case TYPE_COMPARE:
24334 case TYPE_DELAYED_COMPARE:
24335 case TYPE_VAR_DELAYED_COMPARE:
24336 case TYPE_ISYNC:
24337 case TYPE_LOAD_L:
24338 case TYPE_STORE_C:
24339 case TYPE_LOAD_U:
24340 case TYPE_LOAD_UX:
24341 case TYPE_LOAD_EXT:
24342 case TYPE_LOAD_EXT_U:
24343 case TYPE_LOAD_EXT_UX:
24344 case TYPE_STORE_U:
24345 case TYPE_STORE_UX:
24346 case TYPE_FPLOAD_U:
24347 case TYPE_FPLOAD_UX:
24348 case TYPE_FPSTORE_U:
24349 case TYPE_FPSTORE_UX:
24350 case TYPE_MFJMPR:
24351 case TYPE_MTJMPR:
24352 return true;
24353 default:
24354 break;
24356 break;
24357 default:
24358 break;
24361 return false;
24364 static bool
24365 insn_must_be_last_in_group (rtx insn)
24367 enum attr_type type;
24369 if (!insn
24370 || GET_CODE (insn) == NOTE
24371 || DEBUG_INSN_P (insn)
24372 || GET_CODE (PATTERN (insn)) == USE
24373 || GET_CODE (PATTERN (insn)) == CLOBBER)
24374 return false;
24376 switch (rs6000_cpu) {
24377 case PROCESSOR_POWER4:
24378 case PROCESSOR_POWER5:
24379 if (is_microcoded_insn (insn))
24380 return true;
24382 if (is_branch_slot_insn (insn))
24383 return true;
24385 break;
24386 case PROCESSOR_POWER6:
24387 type = get_attr_type (insn);
24389 switch (type)
24391 case TYPE_EXTS:
24392 case TYPE_CNTLZ:
24393 case TYPE_SHIFT:
24394 case TYPE_VAR_SHIFT_ROTATE:
24395 case TYPE_TRAP:
24396 case TYPE_IMUL:
24397 case TYPE_IMUL2:
24398 case TYPE_IMUL3:
24399 case TYPE_LMUL:
24400 case TYPE_IDIV:
24401 case TYPE_DELAYED_COMPARE:
24402 case TYPE_IMUL_COMPARE:
24403 case TYPE_LMUL_COMPARE:
24404 case TYPE_FPCOMPARE:
24405 case TYPE_MFCR:
24406 case TYPE_MTCR:
24407 case TYPE_MFJMPR:
24408 case TYPE_MTJMPR:
24409 case TYPE_ISYNC:
24410 case TYPE_SYNC:
24411 case TYPE_LOAD_L:
24412 case TYPE_STORE_C:
24413 return true;
24414 default:
24415 break;
24417 break;
24418 case PROCESSOR_POWER7:
24419 type = get_attr_type (insn);
24421 switch (type)
24423 case TYPE_ISYNC:
24424 case TYPE_SYNC:
24425 case TYPE_LOAD_L:
24426 case TYPE_STORE_C:
24427 case TYPE_LOAD_EXT_U:
24428 case TYPE_LOAD_EXT_UX:
24429 case TYPE_STORE_UX:
24430 return true;
24431 default:
24432 break;
24434 break;
24435 default:
24436 break;
24439 return false;
24442 /* Return true if it is recommended to keep NEXT_INSN "far" (in a separate
24443 dispatch group) from the insns in GROUP_INSNS. Return false otherwise. */
24445 static bool
24446 is_costly_group (rtx *group_insns, rtx next_insn)
24448 int i;
24449 int issue_rate = rs6000_issue_rate ();
24451 for (i = 0; i < issue_rate; i++)
24453 sd_iterator_def sd_it;
24454 dep_t dep;
24455 rtx insn = group_insns[i];
24457 if (!insn)
24458 continue;
24460 FOR_EACH_DEP (insn, SD_LIST_FORW, sd_it, dep)
24462 rtx next = DEP_CON (dep);
24464 if (next == next_insn
24465 && rs6000_is_costly_dependence (dep, dep_cost (dep), 0))
24466 return true;
24470 return false;
24473 /* Utility of the function redefine_groups.
24474 Check if it is too costly to schedule NEXT_INSN together with GROUP_INSNS
24475 in the same dispatch group. If so, insert nops before NEXT_INSN, in order
24476 to keep it "far" (in a separate group) from GROUP_INSNS, following
24477 one of the following schemes, depending on the value of the flag
24478 -minsert_sched_nops = X:
24479 (1) X == sched_finish_regroup_exact: insert exactly as many nops as needed
24480 in order to force NEXT_INSN into a separate group.
24481 (2) X < sched_finish_regroup_exact: insert exactly X nops.
24482 GROUP_END, CAN_ISSUE_MORE and GROUP_COUNT record the state after nop
24483 insertion (has a group just ended, how many vacant issue slots remain in the
24484 last group, and how many dispatch groups were encountered so far). */
24486 static int
24487 force_new_group (int sched_verbose, FILE *dump, rtx *group_insns,
24488 rtx next_insn, bool *group_end, int can_issue_more,
24489 int *group_count)
24491 rtx nop;
24492 bool force;
24493 int issue_rate = rs6000_issue_rate ();
24494 bool end = *group_end;
24495 int i;
24497 if (next_insn == NULL_RTX || DEBUG_INSN_P (next_insn))
24498 return can_issue_more;
24500 if (rs6000_sched_insert_nops > sched_finish_regroup_exact)
24501 return can_issue_more;
24503 force = is_costly_group (group_insns, next_insn);
24504 if (!force)
24505 return can_issue_more;
24507 if (sched_verbose > 6)
24508 fprintf (dump,"force: group count = %d, can_issue_more = %d\n",
24509 *group_count ,can_issue_more);
24511 if (rs6000_sched_insert_nops == sched_finish_regroup_exact)
24513 if (*group_end)
24514 can_issue_more = 0;
24516 /* Since only a branch can be issued in the last issue_slot, it is
24517 sufficient to insert 'can_issue_more - 1' nops if next_insn is not
24518 a branch. If next_insn is a branch, we insert 'can_issue_more' nops;
24519 in this case the last nop will start a new group and the branch
24520 will be forced to the new group. */
24521 if (can_issue_more && !is_branch_slot_insn (next_insn))
24522 can_issue_more--;
24524 while (can_issue_more > 0)
24526 nop = gen_nop ();
24527 emit_insn_before (nop, next_insn);
24528 can_issue_more--;
24531 *group_end = true;
24532 return 0;
24535 if (rs6000_sched_insert_nops < sched_finish_regroup_exact)
24537 int n_nops = rs6000_sched_insert_nops;
24539 /* Nops can't be issued from the branch slot, so the effective
24540 issue_rate for nops is 'issue_rate - 1'. */
24541 if (can_issue_more == 0)
24542 can_issue_more = issue_rate;
24543 can_issue_more--;
24544 if (can_issue_more == 0)
24546 can_issue_more = issue_rate - 1;
24547 (*group_count)++;
24548 end = true;
24549 for (i = 0; i < issue_rate; i++)
24551 group_insns[i] = 0;
24555 while (n_nops > 0)
24557 nop = gen_nop ();
24558 emit_insn_before (nop, next_insn);
24559 if (can_issue_more == issue_rate - 1) /* new group begins */
24560 end = false;
24561 can_issue_more--;
24562 if (can_issue_more == 0)
24564 can_issue_more = issue_rate - 1;
24565 (*group_count)++;
24566 end = true;
24567 for (i = 0; i < issue_rate; i++)
24569 group_insns[i] = 0;
24572 n_nops--;
24575 /* Scale back relative to 'issue_rate' (instead of 'issue_rate - 1'). */
24576 can_issue_more++;
24578 /* Is next_insn going to start a new group? */
24579 *group_end
24580 = (end
24581 || (can_issue_more == 1 && !is_branch_slot_insn (next_insn))
24582 || (can_issue_more <= 2 && is_cracked_insn (next_insn))
24583 || (can_issue_more < issue_rate &&
24584 insn_terminates_group_p (next_insn, previous_group)));
24585 if (*group_end && end)
24586 (*group_count)--;
24588 if (sched_verbose > 6)
24589 fprintf (dump, "done force: group count = %d, can_issue_more = %d\n",
24590 *group_count, can_issue_more);
24591 return can_issue_more;
24594 return can_issue_more;
24597 /* This function tries to synch the dispatch groups that the compiler "sees"
24598 with the dispatch groups that the processor dispatcher is expected to
24599 form in practice. It tries to achieve this synchronization by forcing the
24600 estimated processor grouping on the compiler (as opposed to the function
24601 'pad_goups' which tries to force the scheduler's grouping on the processor).
24603 The function scans the insn sequence between PREV_HEAD_INSN and TAIL and
24604 examines the (estimated) dispatch groups that will be formed by the processor
24605 dispatcher. It marks these group boundaries to reflect the estimated
24606 processor grouping, overriding the grouping that the scheduler had marked.
24607 Depending on the value of the flag '-minsert-sched-nops' this function can
24608 force certain insns into separate groups or force a certain distance between
24609 them by inserting nops, for example, if there exists a "costly dependence"
24610 between the insns.
24612 The function estimates the group boundaries that the processor will form as
24613 follows: It keeps track of how many vacant issue slots are available after
24614 each insn. A subsequent insn will start a new group if one of the following
24615 4 cases applies:
24616 - no more vacant issue slots remain in the current dispatch group.
24617 - only the last issue slot, which is the branch slot, is vacant, but the next
24618 insn is not a branch.
24619 - only the last 2 or less issue slots, including the branch slot, are vacant,
24620 which means that a cracked insn (which occupies two issue slots) can't be
24621 issued in this group.
24622 - less than 'issue_rate' slots are vacant, and the next insn always needs to
24623 start a new group. */
24625 static int
24626 redefine_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail)
24628 rtx insn, next_insn;
24629 int issue_rate;
24630 int can_issue_more;
24631 int slot, i;
24632 bool group_end;
24633 int group_count = 0;
24634 rtx *group_insns;
24636 /* Initialize. */
24637 issue_rate = rs6000_issue_rate ();
24638 group_insns = XALLOCAVEC (rtx, issue_rate);
24639 for (i = 0; i < issue_rate; i++)
24641 group_insns[i] = 0;
24643 can_issue_more = issue_rate;
24644 slot = 0;
24645 insn = get_next_active_insn (prev_head_insn, tail);
24646 group_end = false;
24648 while (insn != NULL_RTX)
24650 slot = (issue_rate - can_issue_more);
24651 group_insns[slot] = insn;
24652 can_issue_more =
24653 rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more);
24654 if (insn_terminates_group_p (insn, current_group))
24655 can_issue_more = 0;
24657 next_insn = get_next_active_insn (insn, tail);
24658 if (next_insn == NULL_RTX)
24659 return group_count + 1;
24661 /* Is next_insn going to start a new group? */
24662 group_end
24663 = (can_issue_more == 0
24664 || (can_issue_more == 1 && !is_branch_slot_insn (next_insn))
24665 || (can_issue_more <= 2 && is_cracked_insn (next_insn))
24666 || (can_issue_more < issue_rate &&
24667 insn_terminates_group_p (next_insn, previous_group)));
24669 can_issue_more = force_new_group (sched_verbose, dump, group_insns,
24670 next_insn, &group_end, can_issue_more,
24671 &group_count);
24673 if (group_end)
24675 group_count++;
24676 can_issue_more = 0;
24677 for (i = 0; i < issue_rate; i++)
24679 group_insns[i] = 0;
24683 if (GET_MODE (next_insn) == TImode && can_issue_more)
24684 PUT_MODE (next_insn, VOIDmode);
24685 else if (!can_issue_more && GET_MODE (next_insn) != TImode)
24686 PUT_MODE (next_insn, TImode);
24688 insn = next_insn;
24689 if (can_issue_more == 0)
24690 can_issue_more = issue_rate;
24691 } /* while */
24693 return group_count;
24696 /* Scan the insn sequence between PREV_HEAD_INSN and TAIL and examine the
24697 dispatch group boundaries that the scheduler had marked. Pad with nops
24698 any dispatch groups which have vacant issue slots, in order to force the
24699 scheduler's grouping on the processor dispatcher. The function
24700 returns the number of dispatch groups found. */
24702 static int
24703 pad_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail)
24705 rtx insn, next_insn;
24706 rtx nop;
24707 int issue_rate;
24708 int can_issue_more;
24709 int group_end;
24710 int group_count = 0;
24712 /* Initialize issue_rate. */
24713 issue_rate = rs6000_issue_rate ();
24714 can_issue_more = issue_rate;
24716 insn = get_next_active_insn (prev_head_insn, tail);
24717 next_insn = get_next_active_insn (insn, tail);
24719 while (insn != NULL_RTX)
24721 can_issue_more =
24722 rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more);
24724 group_end = (next_insn == NULL_RTX || GET_MODE (next_insn) == TImode);
24726 if (next_insn == NULL_RTX)
24727 break;
24729 if (group_end)
24731 /* If the scheduler had marked group termination at this location
24732 (between insn and next_insn), and neither insn nor next_insn will
24733 force group termination, pad the group with nops to force group
24734 termination. */
24735 if (can_issue_more
24736 && (rs6000_sched_insert_nops == sched_finish_pad_groups)
24737 && !insn_terminates_group_p (insn, current_group)
24738 && !insn_terminates_group_p (next_insn, previous_group))
24740 if (!is_branch_slot_insn (next_insn))
24741 can_issue_more--;
24743 while (can_issue_more)
24745 nop = gen_nop ();
24746 emit_insn_before (nop, next_insn);
24747 can_issue_more--;
24751 can_issue_more = issue_rate;
24752 group_count++;
24755 insn = next_insn;
24756 next_insn = get_next_active_insn (insn, tail);
24759 return group_count;
24762 /* We're beginning a new block. Initialize data structures as necessary. */
24764 static void
24765 rs6000_sched_init (FILE *dump ATTRIBUTE_UNUSED,
24766 int sched_verbose ATTRIBUTE_UNUSED,
24767 int max_ready ATTRIBUTE_UNUSED)
24769 last_scheduled_insn = NULL_RTX;
24770 load_store_pendulum = 0;
24773 /* The following function is called at the end of scheduling BB.
24774 After reload, it inserts nops at insn group bundling. */
24776 static void
24777 rs6000_sched_finish (FILE *dump, int sched_verbose)
24779 int n_groups;
24781 if (sched_verbose)
24782 fprintf (dump, "=== Finishing schedule.\n");
24784 if (reload_completed && rs6000_sched_groups)
24786 /* Do not run sched_finish hook when selective scheduling enabled. */
24787 if (sel_sched_p ())
24788 return;
24790 if (rs6000_sched_insert_nops == sched_finish_none)
24791 return;
24793 if (rs6000_sched_insert_nops == sched_finish_pad_groups)
24794 n_groups = pad_groups (dump, sched_verbose,
24795 current_sched_info->prev_head,
24796 current_sched_info->next_tail);
24797 else
24798 n_groups = redefine_groups (dump, sched_verbose,
24799 current_sched_info->prev_head,
24800 current_sched_info->next_tail);
24802 if (sched_verbose >= 6)
24804 fprintf (dump, "ngroups = %d\n", n_groups);
24805 print_rtl (dump, current_sched_info->prev_head);
24806 fprintf (dump, "Done finish_sched\n");
24811 struct _rs6000_sched_context
24813 short cached_can_issue_more;
24814 rtx last_scheduled_insn;
24815 int load_store_pendulum;
24818 typedef struct _rs6000_sched_context rs6000_sched_context_def;
24819 typedef rs6000_sched_context_def *rs6000_sched_context_t;
24821 /* Allocate store for new scheduling context. */
24822 static void *
24823 rs6000_alloc_sched_context (void)
24825 return xmalloc (sizeof (rs6000_sched_context_def));
24828 /* If CLEAN_P is true then initializes _SC with clean data,
24829 and from the global context otherwise. */
24830 static void
24831 rs6000_init_sched_context (void *_sc, bool clean_p)
24833 rs6000_sched_context_t sc = (rs6000_sched_context_t) _sc;
24835 if (clean_p)
24837 sc->cached_can_issue_more = 0;
24838 sc->last_scheduled_insn = NULL_RTX;
24839 sc->load_store_pendulum = 0;
24841 else
24843 sc->cached_can_issue_more = cached_can_issue_more;
24844 sc->last_scheduled_insn = last_scheduled_insn;
24845 sc->load_store_pendulum = load_store_pendulum;
24849 /* Sets the global scheduling context to the one pointed to by _SC. */
24850 static void
24851 rs6000_set_sched_context (void *_sc)
24853 rs6000_sched_context_t sc = (rs6000_sched_context_t) _sc;
24855 gcc_assert (sc != NULL);
24857 cached_can_issue_more = sc->cached_can_issue_more;
24858 last_scheduled_insn = sc->last_scheduled_insn;
24859 load_store_pendulum = sc->load_store_pendulum;
24862 /* Free _SC. */
24863 static void
24864 rs6000_free_sched_context (void *_sc)
24866 gcc_assert (_sc != NULL);
24868 free (_sc);
24872 /* Length in units of the trampoline for entering a nested function. */
24875 rs6000_trampoline_size (void)
24877 int ret = 0;
24879 switch (DEFAULT_ABI)
24881 default:
24882 gcc_unreachable ();
24884 case ABI_AIX:
24885 ret = (TARGET_32BIT) ? 12 : 24;
24886 break;
24888 case ABI_DARWIN:
24889 case ABI_V4:
24890 ret = (TARGET_32BIT) ? 40 : 48;
24891 break;
24894 return ret;
24897 /* Emit RTL insns to initialize the variable parts of a trampoline.
24898 FNADDR is an RTX for the address of the function's pure code.
24899 CXT is an RTX for the static chain value for the function. */
24901 static void
24902 rs6000_trampoline_init (rtx m_tramp, tree fndecl, rtx cxt)
24904 int regsize = (TARGET_32BIT) ? 4 : 8;
24905 rtx fnaddr = XEXP (DECL_RTL (fndecl), 0);
24906 rtx ctx_reg = force_reg (Pmode, cxt);
24907 rtx addr = force_reg (Pmode, XEXP (m_tramp, 0));
24909 switch (DEFAULT_ABI)
24911 default:
24912 gcc_unreachable ();
24914 /* Under AIX, just build the 3 word function descriptor */
24915 case ABI_AIX:
24917 rtx fnmem = gen_const_mem (Pmode, force_reg (Pmode, fnaddr));
24918 rtx fn_reg = gen_reg_rtx (Pmode);
24919 rtx toc_reg = gen_reg_rtx (Pmode);
24921 /* Macro to shorten the code expansions below. */
24922 # define MEM_PLUS(MEM, OFFSET) adjust_address (MEM, Pmode, OFFSET)
24924 m_tramp = replace_equiv_address (m_tramp, addr);
24926 emit_move_insn (fn_reg, MEM_PLUS (fnmem, 0));
24927 emit_move_insn (toc_reg, MEM_PLUS (fnmem, regsize));
24928 emit_move_insn (MEM_PLUS (m_tramp, 0), fn_reg);
24929 emit_move_insn (MEM_PLUS (m_tramp, regsize), toc_reg);
24930 emit_move_insn (MEM_PLUS (m_tramp, 2*regsize), ctx_reg);
24932 # undef MEM_PLUS
24934 break;
24936 /* Under V.4/eabi/darwin, __trampoline_setup does the real work. */
24937 case ABI_DARWIN:
24938 case ABI_V4:
24939 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__trampoline_setup"),
24940 LCT_NORMAL, VOIDmode, 4,
24941 addr, Pmode,
24942 GEN_INT (rs6000_trampoline_size ()), SImode,
24943 fnaddr, Pmode,
24944 ctx_reg, Pmode);
24945 break;
24950 /* Returns TRUE iff the target attribute indicated by ATTR_ID takes a plain
24951 identifier as an argument, so the front end shouldn't look it up. */
24953 static bool
24954 rs6000_attribute_takes_identifier_p (const_tree attr_id)
24956 return is_attribute_p ("altivec", attr_id);
24959 /* Handle the "altivec" attribute. The attribute may have
24960 arguments as follows:
24962 __attribute__((altivec(vector__)))
24963 __attribute__((altivec(pixel__))) (always followed by 'unsigned short')
24964 __attribute__((altivec(bool__))) (always followed by 'unsigned')
24966 and may appear more than once (e.g., 'vector bool char') in a
24967 given declaration. */
24969 static tree
24970 rs6000_handle_altivec_attribute (tree *node,
24971 tree name ATTRIBUTE_UNUSED,
24972 tree args,
24973 int flags ATTRIBUTE_UNUSED,
24974 bool *no_add_attrs)
24976 tree type = *node, result = NULL_TREE;
24977 enum machine_mode mode;
24978 int unsigned_p;
24979 char altivec_type
24980 = ((args && TREE_CODE (args) == TREE_LIST && TREE_VALUE (args)
24981 && TREE_CODE (TREE_VALUE (args)) == IDENTIFIER_NODE)
24982 ? *IDENTIFIER_POINTER (TREE_VALUE (args))
24983 : '?');
24985 while (POINTER_TYPE_P (type)
24986 || TREE_CODE (type) == FUNCTION_TYPE
24987 || TREE_CODE (type) == METHOD_TYPE
24988 || TREE_CODE (type) == ARRAY_TYPE)
24989 type = TREE_TYPE (type);
24991 mode = TYPE_MODE (type);
24993 /* Check for invalid AltiVec type qualifiers. */
24994 if (type == long_double_type_node)
24995 error ("use of %<long double%> in AltiVec types is invalid");
24996 else if (type == boolean_type_node)
24997 error ("use of boolean types in AltiVec types is invalid");
24998 else if (TREE_CODE (type) == COMPLEX_TYPE)
24999 error ("use of %<complex%> in AltiVec types is invalid");
25000 else if (DECIMAL_FLOAT_MODE_P (mode))
25001 error ("use of decimal floating point types in AltiVec types is invalid");
25002 else if (!TARGET_VSX)
25004 if (type == long_unsigned_type_node || type == long_integer_type_node)
25006 if (TARGET_64BIT)
25007 error ("use of %<long%> in AltiVec types is invalid for "
25008 "64-bit code without -mvsx");
25009 else if (rs6000_warn_altivec_long)
25010 warning (0, "use of %<long%> in AltiVec types is deprecated; "
25011 "use %<int%>");
25013 else if (type == long_long_unsigned_type_node
25014 || type == long_long_integer_type_node)
25015 error ("use of %<long long%> in AltiVec types is invalid without "
25016 "-mvsx");
25017 else if (type == double_type_node)
25018 error ("use of %<double%> in AltiVec types is invalid without -mvsx");
25021 switch (altivec_type)
25023 case 'v':
25024 unsigned_p = TYPE_UNSIGNED (type);
25025 switch (mode)
25027 case DImode:
25028 result = (unsigned_p ? unsigned_V2DI_type_node : V2DI_type_node);
25029 break;
25030 case SImode:
25031 result = (unsigned_p ? unsigned_V4SI_type_node : V4SI_type_node);
25032 break;
25033 case HImode:
25034 result = (unsigned_p ? unsigned_V8HI_type_node : V8HI_type_node);
25035 break;
25036 case QImode:
25037 result = (unsigned_p ? unsigned_V16QI_type_node : V16QI_type_node);
25038 break;
25039 case SFmode: result = V4SF_type_node; break;
25040 case DFmode: result = V2DF_type_node; break;
25041 /* If the user says 'vector int bool', we may be handed the 'bool'
25042 attribute _before_ the 'vector' attribute, and so select the
25043 proper type in the 'b' case below. */
25044 case V4SImode: case V8HImode: case V16QImode: case V4SFmode:
25045 case V2DImode: case V2DFmode:
25046 result = type;
25047 default: break;
25049 break;
25050 case 'b':
25051 switch (mode)
25053 case DImode: case V2DImode: result = bool_V2DI_type_node; break;
25054 case SImode: case V4SImode: result = bool_V4SI_type_node; break;
25055 case HImode: case V8HImode: result = bool_V8HI_type_node; break;
25056 case QImode: case V16QImode: result = bool_V16QI_type_node;
25057 default: break;
25059 break;
25060 case 'p':
25061 switch (mode)
25063 case V8HImode: result = pixel_V8HI_type_node;
25064 default: break;
25066 default: break;
25069 /* Propagate qualifiers attached to the element type
25070 onto the vector type. */
25071 if (result && result != type && TYPE_QUALS (type))
25072 result = build_qualified_type (result, TYPE_QUALS (type));
25074 *no_add_attrs = true; /* No need to hang on to the attribute. */
25076 if (result)
25077 *node = lang_hooks.types.reconstruct_complex_type (*node, result);
25079 return NULL_TREE;
25082 /* AltiVec defines four built-in scalar types that serve as vector
25083 elements; we must teach the compiler how to mangle them. */
25085 static const char *
25086 rs6000_mangle_type (const_tree type)
25088 type = TYPE_MAIN_VARIANT (type);
25090 if (TREE_CODE (type) != VOID_TYPE && TREE_CODE (type) != BOOLEAN_TYPE
25091 && TREE_CODE (type) != INTEGER_TYPE && TREE_CODE (type) != REAL_TYPE)
25092 return NULL;
25094 if (type == bool_char_type_node) return "U6__boolc";
25095 if (type == bool_short_type_node) return "U6__bools";
25096 if (type == pixel_type_node) return "u7__pixel";
25097 if (type == bool_int_type_node) return "U6__booli";
25098 if (type == bool_long_type_node) return "U6__booll";
25100 /* Mangle IBM extended float long double as `g' (__float128) on
25101 powerpc*-linux where long-double-64 previously was the default. */
25102 if (TYPE_MAIN_VARIANT (type) == long_double_type_node
25103 && TARGET_ELF
25104 && TARGET_LONG_DOUBLE_128
25105 && !TARGET_IEEEQUAD)
25106 return "g";
25108 /* For all other types, use normal C++ mangling. */
25109 return NULL;
25112 /* Handle a "longcall" or "shortcall" attribute; arguments as in
25113 struct attribute_spec.handler. */
25115 static tree
25116 rs6000_handle_longcall_attribute (tree *node, tree name,
25117 tree args ATTRIBUTE_UNUSED,
25118 int flags ATTRIBUTE_UNUSED,
25119 bool *no_add_attrs)
25121 if (TREE_CODE (*node) != FUNCTION_TYPE
25122 && TREE_CODE (*node) != FIELD_DECL
25123 && TREE_CODE (*node) != TYPE_DECL)
25125 warning (OPT_Wattributes, "%qE attribute only applies to functions",
25126 name);
25127 *no_add_attrs = true;
25130 return NULL_TREE;
25133 /* Set longcall attributes on all functions declared when
25134 rs6000_default_long_calls is true. */
25135 static void
25136 rs6000_set_default_type_attributes (tree type)
25138 if (rs6000_default_long_calls
25139 && (TREE_CODE (type) == FUNCTION_TYPE
25140 || TREE_CODE (type) == METHOD_TYPE))
25141 TYPE_ATTRIBUTES (type) = tree_cons (get_identifier ("longcall"),
25142 NULL_TREE,
25143 TYPE_ATTRIBUTES (type));
25145 #if TARGET_MACHO
25146 darwin_set_default_type_attributes (type);
25147 #endif
25150 /* Return a reference suitable for calling a function with the
25151 longcall attribute. */
25154 rs6000_longcall_ref (rtx call_ref)
25156 const char *call_name;
25157 tree node;
25159 if (GET_CODE (call_ref) != SYMBOL_REF)
25160 return call_ref;
25162 /* System V adds '.' to the internal name, so skip them. */
25163 call_name = XSTR (call_ref, 0);
25164 if (*call_name == '.')
25166 while (*call_name == '.')
25167 call_name++;
25169 node = get_identifier (call_name);
25170 call_ref = gen_rtx_SYMBOL_REF (VOIDmode, IDENTIFIER_POINTER (node));
25173 return force_reg (Pmode, call_ref);
25176 #ifndef TARGET_USE_MS_BITFIELD_LAYOUT
25177 #define TARGET_USE_MS_BITFIELD_LAYOUT 0
25178 #endif
25180 /* Handle a "ms_struct" or "gcc_struct" attribute; arguments as in
25181 struct attribute_spec.handler. */
25182 static tree
25183 rs6000_handle_struct_attribute (tree *node, tree name,
25184 tree args ATTRIBUTE_UNUSED,
25185 int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
25187 tree *type = NULL;
25188 if (DECL_P (*node))
25190 if (TREE_CODE (*node) == TYPE_DECL)
25191 type = &TREE_TYPE (*node);
25193 else
25194 type = node;
25196 if (!(type && (TREE_CODE (*type) == RECORD_TYPE
25197 || TREE_CODE (*type) == UNION_TYPE)))
25199 warning (OPT_Wattributes, "%qE attribute ignored", name);
25200 *no_add_attrs = true;
25203 else if ((is_attribute_p ("ms_struct", name)
25204 && lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (*type)))
25205 || ((is_attribute_p ("gcc_struct", name)
25206 && lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (*type)))))
25208 warning (OPT_Wattributes, "%qE incompatible attribute ignored",
25209 name);
25210 *no_add_attrs = true;
25213 return NULL_TREE;
25216 static bool
25217 rs6000_ms_bitfield_layout_p (const_tree record_type)
25219 return (TARGET_USE_MS_BITFIELD_LAYOUT &&
25220 !lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (record_type)))
25221 || lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (record_type));
25224 #ifdef USING_ELFOS_H
25226 /* A get_unnamed_section callback, used for switching to toc_section. */
25228 static void
25229 rs6000_elf_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
25231 if (DEFAULT_ABI == ABI_AIX
25232 && TARGET_MINIMAL_TOC
25233 && !TARGET_RELOCATABLE)
25235 if (!toc_initialized)
25237 toc_initialized = 1;
25238 fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);
25239 (*targetm.asm_out.internal_label) (asm_out_file, "LCTOC", 0);
25240 fprintf (asm_out_file, "\t.tc ");
25241 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1[TC],");
25242 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
25243 fprintf (asm_out_file, "\n");
25245 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
25246 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
25247 fprintf (asm_out_file, " = .+32768\n");
25249 else
25250 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
25252 else if (DEFAULT_ABI == ABI_AIX && !TARGET_RELOCATABLE)
25253 fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);
25254 else
25256 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
25257 if (!toc_initialized)
25259 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
25260 fprintf (asm_out_file, " = .+32768\n");
25261 toc_initialized = 1;
25266 /* Implement TARGET_ASM_INIT_SECTIONS. */
25268 static void
25269 rs6000_elf_asm_init_sections (void)
25271 toc_section
25272 = get_unnamed_section (0, rs6000_elf_output_toc_section_asm_op, NULL);
25274 sdata2_section
25275 = get_unnamed_section (SECTION_WRITE, output_section_asm_op,
25276 SDATA2_SECTION_ASM_OP);
25279 /* Implement TARGET_SELECT_RTX_SECTION. */
25281 static section *
25282 rs6000_elf_select_rtx_section (enum machine_mode mode, rtx x,
25283 unsigned HOST_WIDE_INT align)
25285 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
25286 return toc_section;
25287 else
25288 return default_elf_select_rtx_section (mode, x, align);
25291 /* For a SYMBOL_REF, set generic flags and then perform some
25292 target-specific processing.
25294 When the AIX ABI is requested on a non-AIX system, replace the
25295 function name with the real name (with a leading .) rather than the
25296 function descriptor name. This saves a lot of overriding code to
25297 read the prefixes. */
25299 static void
25300 rs6000_elf_encode_section_info (tree decl, rtx rtl, int first)
25302 default_encode_section_info (decl, rtl, first);
25304 if (first
25305 && TREE_CODE (decl) == FUNCTION_DECL
25306 && !TARGET_AIX
25307 && DEFAULT_ABI == ABI_AIX)
25309 rtx sym_ref = XEXP (rtl, 0);
25310 size_t len = strlen (XSTR (sym_ref, 0));
25311 char *str = XALLOCAVEC (char, len + 2);
25312 str[0] = '.';
25313 memcpy (str + 1, XSTR (sym_ref, 0), len + 1);
25314 XSTR (sym_ref, 0) = ggc_alloc_string (str, len + 1);
25318 static inline bool
25319 compare_section_name (const char *section, const char *templ)
25321 int len;
25323 len = strlen (templ);
25324 return (strncmp (section, templ, len) == 0
25325 && (section[len] == 0 || section[len] == '.'));
25328 bool
25329 rs6000_elf_in_small_data_p (const_tree decl)
25331 if (rs6000_sdata == SDATA_NONE)
25332 return false;
25334 /* We want to merge strings, so we never consider them small data. */
25335 if (TREE_CODE (decl) == STRING_CST)
25336 return false;
25338 /* Functions are never in the small data area. */
25339 if (TREE_CODE (decl) == FUNCTION_DECL)
25340 return false;
25342 if (TREE_CODE (decl) == VAR_DECL && DECL_SECTION_NAME (decl))
25344 const char *section = TREE_STRING_POINTER (DECL_SECTION_NAME (decl));
25345 if (compare_section_name (section, ".sdata")
25346 || compare_section_name (section, ".sdata2")
25347 || compare_section_name (section, ".gnu.linkonce.s")
25348 || compare_section_name (section, ".sbss")
25349 || compare_section_name (section, ".sbss2")
25350 || compare_section_name (section, ".gnu.linkonce.sb")
25351 || strcmp (section, ".PPC.EMB.sdata0") == 0
25352 || strcmp (section, ".PPC.EMB.sbss0") == 0)
25353 return true;
25355 else
25357 HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (decl));
25359 if (size > 0
25360 && size <= g_switch_value
25361 /* If it's not public, and we're not going to reference it there,
25362 there's no need to put it in the small data section. */
25363 && (rs6000_sdata != SDATA_DATA || TREE_PUBLIC (decl)))
25364 return true;
25367 return false;
25370 #endif /* USING_ELFOS_H */
25372 /* Implement TARGET_USE_BLOCKS_FOR_CONSTANT_P. */
25374 static bool
25375 rs6000_use_blocks_for_constant_p (enum machine_mode mode, const_rtx x)
25377 return !ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode);
25380 /* Return a REG that occurs in ADDR with coefficient 1.
25381 ADDR can be effectively incremented by incrementing REG.
25383 r0 is special and we must not select it as an address
25384 register by this routine since our caller will try to
25385 increment the returned register via an "la" instruction. */
25388 find_addr_reg (rtx addr)
25390 while (GET_CODE (addr) == PLUS)
25392 if (GET_CODE (XEXP (addr, 0)) == REG
25393 && REGNO (XEXP (addr, 0)) != 0)
25394 addr = XEXP (addr, 0);
25395 else if (GET_CODE (XEXP (addr, 1)) == REG
25396 && REGNO (XEXP (addr, 1)) != 0)
25397 addr = XEXP (addr, 1);
25398 else if (CONSTANT_P (XEXP (addr, 0)))
25399 addr = XEXP (addr, 1);
25400 else if (CONSTANT_P (XEXP (addr, 1)))
25401 addr = XEXP (addr, 0);
25402 else
25403 gcc_unreachable ();
25405 gcc_assert (GET_CODE (addr) == REG && REGNO (addr) != 0);
25406 return addr;
25409 void
25410 rs6000_fatal_bad_address (rtx op)
25412 fatal_insn ("bad address", op);
25415 #if TARGET_MACHO
25417 typedef struct branch_island_d {
25418 tree function_name;
25419 tree label_name;
25420 int line_number;
25421 } branch_island;
25423 DEF_VEC_O(branch_island);
25424 DEF_VEC_ALLOC_O(branch_island,gc);
25426 static VEC(branch_island,gc) *branch_islands;
25428 /* Remember to generate a branch island for far calls to the given
25429 function. */
25431 static void
25432 add_compiler_branch_island (tree label_name, tree function_name,
25433 int line_number)
25435 branch_island *bi = VEC_safe_push (branch_island, gc, branch_islands, NULL);
25437 bi->function_name = function_name;
25438 bi->label_name = label_name;
25439 bi->line_number = line_number;
25442 /* Generate far-jump branch islands for everything recorded in
25443 branch_islands. Invoked immediately after the last instruction of
25444 the epilogue has been emitted; the branch islands must be appended
25445 to, and contiguous with, the function body. Mach-O stubs are
25446 generated in machopic_output_stub(). */
25448 static void
25449 macho_branch_islands (void)
25451 char tmp_buf[512];
25453 while (!VEC_empty (branch_island, branch_islands))
25455 branch_island *bi = VEC_last (branch_island, branch_islands);
25456 const char *label = IDENTIFIER_POINTER (bi->label_name);
25457 const char *name = IDENTIFIER_POINTER (bi->function_name);
25458 char name_buf[512];
25459 /* Cheap copy of the details from the Darwin ASM_OUTPUT_LABELREF(). */
25460 if (name[0] == '*' || name[0] == '&')
25461 strcpy (name_buf, name+1);
25462 else
25464 name_buf[0] = '_';
25465 strcpy (name_buf+1, name);
25467 strcpy (tmp_buf, "\n");
25468 strcat (tmp_buf, label);
25469 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
25470 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
25471 dbxout_stabd (N_SLINE, bi->line_number);
25472 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
25473 if (flag_pic)
25475 strcat (tmp_buf, ":\n\tmflr r0\n\tbcl 20,31,");
25476 strcat (tmp_buf, label);
25477 strcat (tmp_buf, "_pic\n");
25478 strcat (tmp_buf, label);
25479 strcat (tmp_buf, "_pic:\n\tmflr r11\n");
25481 strcat (tmp_buf, "\taddis r11,r11,ha16(");
25482 strcat (tmp_buf, name_buf);
25483 strcat (tmp_buf, " - ");
25484 strcat (tmp_buf, label);
25485 strcat (tmp_buf, "_pic)\n");
25487 strcat (tmp_buf, "\tmtlr r0\n");
25489 strcat (tmp_buf, "\taddi r12,r11,lo16(");
25490 strcat (tmp_buf, name_buf);
25491 strcat (tmp_buf, " - ");
25492 strcat (tmp_buf, label);
25493 strcat (tmp_buf, "_pic)\n");
25495 strcat (tmp_buf, "\tmtctr r12\n\tbctr\n");
25497 else
25499 strcat (tmp_buf, ":\nlis r12,hi16(");
25500 strcat (tmp_buf, name_buf);
25501 strcat (tmp_buf, ")\n\tori r12,r12,lo16(");
25502 strcat (tmp_buf, name_buf);
25503 strcat (tmp_buf, ")\n\tmtctr r12\n\tbctr");
25505 output_asm_insn (tmp_buf, 0);
25506 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
25507 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
25508 dbxout_stabd (N_SLINE, bi->line_number);
25509 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
25510 VEC_pop (branch_island, branch_islands);
25514 /* NO_PREVIOUS_DEF checks in the link list whether the function name is
25515 already there or not. */
25517 static int
25518 no_previous_def (tree function_name)
25520 branch_island *bi;
25521 unsigned ix;
25523 FOR_EACH_VEC_ELT (branch_island, branch_islands, ix, bi)
25524 if (function_name == bi->function_name)
25525 return 0;
25526 return 1;
25529 /* GET_PREV_LABEL gets the label name from the previous definition of
25530 the function. */
25532 static tree
25533 get_prev_label (tree function_name)
25535 branch_island *bi;
25536 unsigned ix;
25538 FOR_EACH_VEC_ELT (branch_island, branch_islands, ix, bi)
25539 if (function_name == bi->function_name)
25540 return bi->label_name;
25541 return NULL_TREE;
25544 /* INSN is either a function call or a millicode call. It may have an
25545 unconditional jump in its delay slot.
25547 CALL_DEST is the routine we are calling. */
25549 char *
25550 output_call (rtx insn, rtx *operands, int dest_operand_number,
25551 int cookie_operand_number)
25553 static char buf[256];
25554 if (darwin_emit_branch_islands
25555 && GET_CODE (operands[dest_operand_number]) == SYMBOL_REF
25556 && (INTVAL (operands[cookie_operand_number]) & CALL_LONG))
25558 tree labelname;
25559 tree funname = get_identifier (XSTR (operands[dest_operand_number], 0));
25561 if (no_previous_def (funname))
25563 rtx label_rtx = gen_label_rtx ();
25564 char *label_buf, temp_buf[256];
25565 ASM_GENERATE_INTERNAL_LABEL (temp_buf, "L",
25566 CODE_LABEL_NUMBER (label_rtx));
25567 label_buf = temp_buf[0] == '*' ? temp_buf + 1 : temp_buf;
25568 labelname = get_identifier (label_buf);
25569 add_compiler_branch_island (labelname, funname, insn_line (insn));
25571 else
25572 labelname = get_prev_label (funname);
25574 /* "jbsr foo, L42" is Mach-O for "Link as 'bl foo' if a 'bl'
25575 instruction will reach 'foo', otherwise link as 'bl L42'".
25576 "L42" should be a 'branch island', that will do a far jump to
25577 'foo'. Branch islands are generated in
25578 macho_branch_islands(). */
25579 sprintf (buf, "jbsr %%z%d,%.246s",
25580 dest_operand_number, IDENTIFIER_POINTER (labelname));
25582 else
25583 sprintf (buf, "bl %%z%d", dest_operand_number);
25584 return buf;
25587 /* Generate PIC and indirect symbol stubs. */
25589 void
25590 machopic_output_stub (FILE *file, const char *symb, const char *stub)
25592 unsigned int length;
25593 char *symbol_name, *lazy_ptr_name;
25594 char *local_label_0;
25595 static int label = 0;
25597 /* Lose our funky encoding stuff so it doesn't contaminate the stub. */
25598 symb = (*targetm.strip_name_encoding) (symb);
25601 length = strlen (symb);
25602 symbol_name = XALLOCAVEC (char, length + 32);
25603 GEN_SYMBOL_NAME_FOR_SYMBOL (symbol_name, symb, length);
25605 lazy_ptr_name = XALLOCAVEC (char, length + 32);
25606 GEN_LAZY_PTR_NAME_FOR_SYMBOL (lazy_ptr_name, symb, length);
25608 if (flag_pic == 2)
25609 switch_to_section (darwin_sections[machopic_picsymbol_stub1_section]);
25610 else
25611 switch_to_section (darwin_sections[machopic_symbol_stub1_section]);
25613 if (flag_pic == 2)
25615 fprintf (file, "\t.align 5\n");
25617 fprintf (file, "%s:\n", stub);
25618 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
25620 label++;
25621 local_label_0 = XALLOCAVEC (char, sizeof ("\"L00000000000$spb\""));
25622 sprintf (local_label_0, "\"L%011d$spb\"", label);
25624 fprintf (file, "\tmflr r0\n");
25625 fprintf (file, "\tbcl 20,31,%s\n", local_label_0);
25626 fprintf (file, "%s:\n\tmflr r11\n", local_label_0);
25627 fprintf (file, "\taddis r11,r11,ha16(%s-%s)\n",
25628 lazy_ptr_name, local_label_0);
25629 fprintf (file, "\tmtlr r0\n");
25630 fprintf (file, "\t%s r12,lo16(%s-%s)(r11)\n",
25631 (TARGET_64BIT ? "ldu" : "lwzu"),
25632 lazy_ptr_name, local_label_0);
25633 fprintf (file, "\tmtctr r12\n");
25634 fprintf (file, "\tbctr\n");
25636 else
25638 fprintf (file, "\t.align 4\n");
25640 fprintf (file, "%s:\n", stub);
25641 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
25643 fprintf (file, "\tlis r11,ha16(%s)\n", lazy_ptr_name);
25644 fprintf (file, "\t%s r12,lo16(%s)(r11)\n",
25645 (TARGET_64BIT ? "ldu" : "lwzu"),
25646 lazy_ptr_name);
25647 fprintf (file, "\tmtctr r12\n");
25648 fprintf (file, "\tbctr\n");
25651 switch_to_section (darwin_sections[machopic_lazy_symbol_ptr_section]);
25652 fprintf (file, "%s:\n", lazy_ptr_name);
25653 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
25654 fprintf (file, "%sdyld_stub_binding_helper\n",
25655 (TARGET_64BIT ? DOUBLE_INT_ASM_OP : "\t.long\t"));
25658 /* Legitimize PIC addresses. If the address is already
25659 position-independent, we return ORIG. Newly generated
25660 position-independent addresses go into a reg. This is REG if non
25661 zero, otherwise we allocate register(s) as necessary. */
25663 #define SMALL_INT(X) ((UINTVAL (X) + 0x8000) < 0x10000)
25666 rs6000_machopic_legitimize_pic_address (rtx orig, enum machine_mode mode,
25667 rtx reg)
25669 rtx base, offset;
25671 if (reg == NULL && ! reload_in_progress && ! reload_completed)
25672 reg = gen_reg_rtx (Pmode);
25674 if (GET_CODE (orig) == CONST)
25676 rtx reg_temp;
25678 if (GET_CODE (XEXP (orig, 0)) == PLUS
25679 && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx)
25680 return orig;
25682 gcc_assert (GET_CODE (XEXP (orig, 0)) == PLUS);
25684 /* Use a different reg for the intermediate value, as
25685 it will be marked UNCHANGING. */
25686 reg_temp = !can_create_pseudo_p () ? reg : gen_reg_rtx (Pmode);
25687 base = rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 0),
25688 Pmode, reg_temp);
25689 offset =
25690 rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 1),
25691 Pmode, reg);
25693 if (GET_CODE (offset) == CONST_INT)
25695 if (SMALL_INT (offset))
25696 return plus_constant (base, INTVAL (offset));
25697 else if (! reload_in_progress && ! reload_completed)
25698 offset = force_reg (Pmode, offset);
25699 else
25701 rtx mem = force_const_mem (Pmode, orig);
25702 return machopic_legitimize_pic_address (mem, Pmode, reg);
25705 return gen_rtx_PLUS (Pmode, base, offset);
25708 /* Fall back on generic machopic code. */
25709 return machopic_legitimize_pic_address (orig, mode, reg);
25712 /* Output a .machine directive for the Darwin assembler, and call
25713 the generic start_file routine. */
25715 static void
25716 rs6000_darwin_file_start (void)
25718 static const struct
25720 const char *arg;
25721 const char *name;
25722 int if_set;
25723 } mapping[] = {
25724 { "ppc64", "ppc64", MASK_64BIT },
25725 { "970", "ppc970", MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64 },
25726 { "power4", "ppc970", 0 },
25727 { "G5", "ppc970", 0 },
25728 { "7450", "ppc7450", 0 },
25729 { "7400", "ppc7400", MASK_ALTIVEC },
25730 { "G4", "ppc7400", 0 },
25731 { "750", "ppc750", 0 },
25732 { "740", "ppc750", 0 },
25733 { "G3", "ppc750", 0 },
25734 { "604e", "ppc604e", 0 },
25735 { "604", "ppc604", 0 },
25736 { "603e", "ppc603", 0 },
25737 { "603", "ppc603", 0 },
25738 { "601", "ppc601", 0 },
25739 { NULL, "ppc", 0 } };
25740 const char *cpu_id = "";
25741 size_t i;
25743 rs6000_file_start ();
25744 darwin_file_start ();
25746 /* Determine the argument to -mcpu=. Default to G3 if not specified. */
25747 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
25748 if (rs6000_select[i].set_arch_p && rs6000_select[i].string
25749 && rs6000_select[i].string[0] != '\0')
25750 cpu_id = rs6000_select[i].string;
25752 /* Look through the mapping array. Pick the first name that either
25753 matches the argument, has a bit set in IF_SET that is also set
25754 in the target flags, or has a NULL name. */
25756 i = 0;
25757 while (mapping[i].arg != NULL
25758 && strcmp (mapping[i].arg, cpu_id) != 0
25759 && (mapping[i].if_set & target_flags) == 0)
25760 i++;
25762 fprintf (asm_out_file, "\t.machine %s\n", mapping[i].name);
25765 #endif /* TARGET_MACHO */
25767 #if TARGET_ELF
25768 static int
25769 rs6000_elf_reloc_rw_mask (void)
25771 if (flag_pic)
25772 return 3;
25773 else if (DEFAULT_ABI == ABI_AIX)
25774 return 2;
25775 else
25776 return 0;
25779 /* Record an element in the table of global constructors. SYMBOL is
25780 a SYMBOL_REF of the function to be called; PRIORITY is a number
25781 between 0 and MAX_INIT_PRIORITY.
25783 This differs from default_named_section_asm_out_constructor in
25784 that we have special handling for -mrelocatable. */
25786 static void
25787 rs6000_elf_asm_out_constructor (rtx symbol, int priority)
25789 const char *section = ".ctors";
25790 char buf[16];
25792 if (priority != DEFAULT_INIT_PRIORITY)
25794 sprintf (buf, ".ctors.%.5u",
25795 /* Invert the numbering so the linker puts us in the proper
25796 order; constructors are run from right to left, and the
25797 linker sorts in increasing order. */
25798 MAX_INIT_PRIORITY - priority);
25799 section = buf;
25802 switch_to_section (get_section (section, SECTION_WRITE, NULL));
25803 assemble_align (POINTER_SIZE);
25805 if (TARGET_RELOCATABLE)
25807 fputs ("\t.long (", asm_out_file);
25808 output_addr_const (asm_out_file, symbol);
25809 fputs (")@fixup\n", asm_out_file);
25811 else
25812 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
25815 static void
25816 rs6000_elf_asm_out_destructor (rtx symbol, int priority)
25818 const char *section = ".dtors";
25819 char buf[16];
25821 if (priority != DEFAULT_INIT_PRIORITY)
25823 sprintf (buf, ".dtors.%.5u",
25824 /* Invert the numbering so the linker puts us in the proper
25825 order; constructors are run from right to left, and the
25826 linker sorts in increasing order. */
25827 MAX_INIT_PRIORITY - priority);
25828 section = buf;
25831 switch_to_section (get_section (section, SECTION_WRITE, NULL));
25832 assemble_align (POINTER_SIZE);
25834 if (TARGET_RELOCATABLE)
25836 fputs ("\t.long (", asm_out_file);
25837 output_addr_const (asm_out_file, symbol);
25838 fputs (")@fixup\n", asm_out_file);
25840 else
25841 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
25844 void
25845 rs6000_elf_declare_function_name (FILE *file, const char *name, tree decl)
25847 if (TARGET_64BIT)
25849 fputs ("\t.section\t\".opd\",\"aw\"\n\t.align 3\n", file);
25850 ASM_OUTPUT_LABEL (file, name);
25851 fputs (DOUBLE_INT_ASM_OP, file);
25852 rs6000_output_function_entry (file, name);
25853 fputs (",.TOC.@tocbase,0\n\t.previous\n", file);
25854 if (DOT_SYMBOLS)
25856 fputs ("\t.size\t", file);
25857 assemble_name (file, name);
25858 fputs (",24\n\t.type\t.", file);
25859 assemble_name (file, name);
25860 fputs (",@function\n", file);
25861 if (TREE_PUBLIC (decl) && ! DECL_WEAK (decl))
25863 fputs ("\t.globl\t.", file);
25864 assemble_name (file, name);
25865 putc ('\n', file);
25868 else
25869 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
25870 ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
25871 rs6000_output_function_entry (file, name);
25872 fputs (":\n", file);
25873 return;
25876 if (TARGET_RELOCATABLE
25877 && !TARGET_SECURE_PLT
25878 && (get_pool_size () != 0 || crtl->profile)
25879 && uses_TOC ())
25881 char buf[256];
25883 (*targetm.asm_out.internal_label) (file, "LCL", rs6000_pic_labelno);
25885 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
25886 fprintf (file, "\t.long ");
25887 assemble_name (file, buf);
25888 putc ('-', file);
25889 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
25890 assemble_name (file, buf);
25891 putc ('\n', file);
25894 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
25895 ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
25897 if (DEFAULT_ABI == ABI_AIX)
25899 const char *desc_name, *orig_name;
25901 orig_name = (*targetm.strip_name_encoding) (name);
25902 desc_name = orig_name;
25903 while (*desc_name == '.')
25904 desc_name++;
25906 if (TREE_PUBLIC (decl))
25907 fprintf (file, "\t.globl %s\n", desc_name);
25909 fprintf (file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
25910 fprintf (file, "%s:\n", desc_name);
25911 fprintf (file, "\t.long %s\n", orig_name);
25912 fputs ("\t.long _GLOBAL_OFFSET_TABLE_\n", file);
25913 if (DEFAULT_ABI == ABI_AIX)
25914 fputs ("\t.long 0\n", file);
25915 fprintf (file, "\t.previous\n");
25917 ASM_OUTPUT_LABEL (file, name);
25920 static void
25921 rs6000_elf_file_end (void)
25923 #ifdef HAVE_AS_GNU_ATTRIBUTE
25924 if (TARGET_32BIT && DEFAULT_ABI == ABI_V4)
25926 if (rs6000_passes_float)
25927 fprintf (asm_out_file, "\t.gnu_attribute 4, %d\n",
25928 ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT) ? 1
25929 : (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT) ? 3
25930 : 2));
25931 if (rs6000_passes_vector)
25932 fprintf (asm_out_file, "\t.gnu_attribute 8, %d\n",
25933 (TARGET_ALTIVEC_ABI ? 2
25934 : TARGET_SPE_ABI ? 3
25935 : 1));
25936 if (rs6000_returns_struct)
25937 fprintf (asm_out_file, "\t.gnu_attribute 12, %d\n",
25938 aix_struct_return ? 2 : 1);
25940 #endif
25941 #ifdef POWERPC_LINUX
25942 if (TARGET_32BIT)
25943 file_end_indicate_exec_stack ();
25944 #endif
25946 #endif
25948 #if TARGET_XCOFF
25949 static void
25950 rs6000_xcoff_asm_output_anchor (rtx symbol)
25952 char buffer[100];
25954 sprintf (buffer, "$ + " HOST_WIDE_INT_PRINT_DEC,
25955 SYMBOL_REF_BLOCK_OFFSET (symbol));
25956 ASM_OUTPUT_DEF (asm_out_file, XSTR (symbol, 0), buffer);
25959 static void
25960 rs6000_xcoff_asm_globalize_label (FILE *stream, const char *name)
25962 fputs (GLOBAL_ASM_OP, stream);
25963 RS6000_OUTPUT_BASENAME (stream, name);
25964 putc ('\n', stream);
25967 /* A get_unnamed_decl callback, used for read-only sections. PTR
25968 points to the section string variable. */
25970 static void
25971 rs6000_xcoff_output_readonly_section_asm_op (const void *directive)
25973 fprintf (asm_out_file, "\t.csect %s[RO],%s\n",
25974 *(const char *const *) directive,
25975 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR);
25978 /* Likewise for read-write sections. */
25980 static void
25981 rs6000_xcoff_output_readwrite_section_asm_op (const void *directive)
25983 fprintf (asm_out_file, "\t.csect %s[RW],%s\n",
25984 *(const char *const *) directive,
25985 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR);
25988 /* A get_unnamed_section callback, used for switching to toc_section. */
25990 static void
25991 rs6000_xcoff_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
25993 if (TARGET_MINIMAL_TOC)
25995 /* toc_section is always selected at least once from
25996 rs6000_xcoff_file_start, so this is guaranteed to
25997 always be defined once and only once in each file. */
25998 if (!toc_initialized)
26000 fputs ("\t.toc\nLCTOC..1:\n", asm_out_file);
26001 fputs ("\t.tc toc_table[TC],toc_table[RW]\n", asm_out_file);
26002 toc_initialized = 1;
26004 fprintf (asm_out_file, "\t.csect toc_table[RW]%s\n",
26005 (TARGET_32BIT ? "" : ",3"));
26007 else
26008 fputs ("\t.toc\n", asm_out_file);
26011 /* Implement TARGET_ASM_INIT_SECTIONS. */
26013 static void
26014 rs6000_xcoff_asm_init_sections (void)
26016 read_only_data_section
26017 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
26018 &xcoff_read_only_section_name);
26020 private_data_section
26021 = get_unnamed_section (SECTION_WRITE,
26022 rs6000_xcoff_output_readwrite_section_asm_op,
26023 &xcoff_private_data_section_name);
26025 read_only_private_data_section
26026 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
26027 &xcoff_private_data_section_name);
26029 toc_section
26030 = get_unnamed_section (0, rs6000_xcoff_output_toc_section_asm_op, NULL);
26032 readonly_data_section = read_only_data_section;
26033 exception_section = data_section;
26036 static int
26037 rs6000_xcoff_reloc_rw_mask (void)
26039 return 3;
26042 static void
26043 rs6000_xcoff_asm_named_section (const char *name, unsigned int flags,
26044 tree decl ATTRIBUTE_UNUSED)
26046 int smclass;
26047 static const char * const suffix[3] = { "PR", "RO", "RW" };
26049 if (flags & SECTION_CODE)
26050 smclass = 0;
26051 else if (flags & SECTION_WRITE)
26052 smclass = 2;
26053 else
26054 smclass = 1;
26056 fprintf (asm_out_file, "\t.csect %s%s[%s],%u\n",
26057 (flags & SECTION_CODE) ? "." : "",
26058 name, suffix[smclass], flags & SECTION_ENTSIZE);
26061 static section *
26062 rs6000_xcoff_select_section (tree decl, int reloc,
26063 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
26065 if (decl_readonly_section (decl, reloc))
26067 if (TREE_PUBLIC (decl))
26068 return read_only_data_section;
26069 else
26070 return read_only_private_data_section;
26072 else
26074 if (TREE_PUBLIC (decl))
26075 return data_section;
26076 else
26077 return private_data_section;
26081 static void
26082 rs6000_xcoff_unique_section (tree decl, int reloc ATTRIBUTE_UNUSED)
26084 const char *name;
26086 /* Use select_section for private and uninitialized data. */
26087 if (!TREE_PUBLIC (decl)
26088 || DECL_COMMON (decl)
26089 || DECL_INITIAL (decl) == NULL_TREE
26090 || DECL_INITIAL (decl) == error_mark_node
26091 || (flag_zero_initialized_in_bss
26092 && initializer_zerop (DECL_INITIAL (decl))))
26093 return;
26095 name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
26096 name = (*targetm.strip_name_encoding) (name);
26097 DECL_SECTION_NAME (decl) = build_string (strlen (name), name);
26100 /* Select section for constant in constant pool.
26102 On RS/6000, all constants are in the private read-only data area.
26103 However, if this is being placed in the TOC it must be output as a
26104 toc entry. */
26106 static section *
26107 rs6000_xcoff_select_rtx_section (enum machine_mode mode, rtx x,
26108 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
26110 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
26111 return toc_section;
26112 else
26113 return read_only_private_data_section;
26116 /* Remove any trailing [DS] or the like from the symbol name. */
26118 static const char *
26119 rs6000_xcoff_strip_name_encoding (const char *name)
26121 size_t len;
26122 if (*name == '*')
26123 name++;
26124 len = strlen (name);
26125 if (name[len - 1] == ']')
26126 return ggc_alloc_string (name, len - 4);
26127 else
26128 return name;
26131 /* Section attributes. AIX is always PIC. */
26133 static unsigned int
26134 rs6000_xcoff_section_type_flags (tree decl, const char *name, int reloc)
26136 unsigned int align;
26137 unsigned int flags = default_section_type_flags (decl, name, reloc);
26139 /* Align to at least UNIT size. */
26140 if (flags & SECTION_CODE)
26141 align = MIN_UNITS_PER_WORD;
26142 else
26143 /* Increase alignment of large objects if not already stricter. */
26144 align = MAX ((DECL_ALIGN (decl) / BITS_PER_UNIT),
26145 int_size_in_bytes (TREE_TYPE (decl)) > MIN_UNITS_PER_WORD
26146 ? UNITS_PER_FP_WORD : MIN_UNITS_PER_WORD);
26148 return flags | (exact_log2 (align) & SECTION_ENTSIZE);
26151 /* Output at beginning of assembler file.
26153 Initialize the section names for the RS/6000 at this point.
26155 Specify filename, including full path, to assembler.
26157 We want to go into the TOC section so at least one .toc will be emitted.
26158 Also, in order to output proper .bs/.es pairs, we need at least one static
26159 [RW] section emitted.
26161 Finally, declare mcount when profiling to make the assembler happy. */
26163 static void
26164 rs6000_xcoff_file_start (void)
26166 rs6000_gen_section_name (&xcoff_bss_section_name,
26167 main_input_filename, ".bss_");
26168 rs6000_gen_section_name (&xcoff_private_data_section_name,
26169 main_input_filename, ".rw_");
26170 rs6000_gen_section_name (&xcoff_read_only_section_name,
26171 main_input_filename, ".ro_");
26173 fputs ("\t.file\t", asm_out_file);
26174 output_quoted_string (asm_out_file, main_input_filename);
26175 fputc ('\n', asm_out_file);
26176 if (write_symbols != NO_DEBUG)
26177 switch_to_section (private_data_section);
26178 switch_to_section (text_section);
26179 if (profile_flag)
26180 fprintf (asm_out_file, "\t.extern %s\n", RS6000_MCOUNT);
26181 rs6000_file_start ();
26184 /* Output at end of assembler file.
26185 On the RS/6000, referencing data should automatically pull in text. */
26187 static void
26188 rs6000_xcoff_file_end (void)
26190 switch_to_section (text_section);
26191 fputs ("_section_.text:\n", asm_out_file);
26192 switch_to_section (data_section);
26193 fputs (TARGET_32BIT
26194 ? "\t.long _section_.text\n" : "\t.llong _section_.text\n",
26195 asm_out_file);
26197 #endif /* TARGET_XCOFF */
26199 /* Compute a (partial) cost for rtx X. Return true if the complete
26200 cost has been computed, and false if subexpressions should be
26201 scanned. In either case, *TOTAL contains the cost result. */
26203 static bool
26204 rs6000_rtx_costs (rtx x, int code, int outer_code, int *total,
26205 bool speed)
26207 enum machine_mode mode = GET_MODE (x);
26209 switch (code)
26211 /* On the RS/6000, if it is valid in the insn, it is free. */
26212 case CONST_INT:
26213 if (((outer_code == SET
26214 || outer_code == PLUS
26215 || outer_code == MINUS)
26216 && (satisfies_constraint_I (x)
26217 || satisfies_constraint_L (x)))
26218 || (outer_code == AND
26219 && (satisfies_constraint_K (x)
26220 || (mode == SImode
26221 ? satisfies_constraint_L (x)
26222 : satisfies_constraint_J (x))
26223 || mask_operand (x, mode)
26224 || (mode == DImode
26225 && mask64_operand (x, DImode))))
26226 || ((outer_code == IOR || outer_code == XOR)
26227 && (satisfies_constraint_K (x)
26228 || (mode == SImode
26229 ? satisfies_constraint_L (x)
26230 : satisfies_constraint_J (x))))
26231 || outer_code == ASHIFT
26232 || outer_code == ASHIFTRT
26233 || outer_code == LSHIFTRT
26234 || outer_code == ROTATE
26235 || outer_code == ROTATERT
26236 || outer_code == ZERO_EXTRACT
26237 || (outer_code == MULT
26238 && satisfies_constraint_I (x))
26239 || ((outer_code == DIV || outer_code == UDIV
26240 || outer_code == MOD || outer_code == UMOD)
26241 && exact_log2 (INTVAL (x)) >= 0)
26242 || (outer_code == COMPARE
26243 && (satisfies_constraint_I (x)
26244 || satisfies_constraint_K (x)))
26245 || ((outer_code == EQ || outer_code == NE)
26246 && (satisfies_constraint_I (x)
26247 || satisfies_constraint_K (x)
26248 || (mode == SImode
26249 ? satisfies_constraint_L (x)
26250 : satisfies_constraint_J (x))))
26251 || (outer_code == GTU
26252 && satisfies_constraint_I (x))
26253 || (outer_code == LTU
26254 && satisfies_constraint_P (x)))
26256 *total = 0;
26257 return true;
26259 else if ((outer_code == PLUS
26260 && reg_or_add_cint_operand (x, VOIDmode))
26261 || (outer_code == MINUS
26262 && reg_or_sub_cint_operand (x, VOIDmode))
26263 || ((outer_code == SET
26264 || outer_code == IOR
26265 || outer_code == XOR)
26266 && (INTVAL (x)
26267 & ~ (unsigned HOST_WIDE_INT) 0xffffffff) == 0))
26269 *total = COSTS_N_INSNS (1);
26270 return true;
26272 /* FALLTHRU */
26274 case CONST_DOUBLE:
26275 if (mode == DImode && code == CONST_DOUBLE)
26277 if ((outer_code == IOR || outer_code == XOR)
26278 && CONST_DOUBLE_HIGH (x) == 0
26279 && (CONST_DOUBLE_LOW (x)
26280 & ~ (unsigned HOST_WIDE_INT) 0xffff) == 0)
26282 *total = 0;
26283 return true;
26285 else if ((outer_code == AND && and64_2_operand (x, DImode))
26286 || ((outer_code == SET
26287 || outer_code == IOR
26288 || outer_code == XOR)
26289 && CONST_DOUBLE_HIGH (x) == 0))
26291 *total = COSTS_N_INSNS (1);
26292 return true;
26295 /* FALLTHRU */
26297 case CONST:
26298 case HIGH:
26299 case SYMBOL_REF:
26300 case MEM:
26301 /* When optimizing for size, MEM should be slightly more expensive
26302 than generating address, e.g., (plus (reg) (const)).
26303 L1 cache latency is about two instructions. */
26304 *total = !speed ? COSTS_N_INSNS (1) + 1 : COSTS_N_INSNS (2);
26305 return true;
26307 case LABEL_REF:
26308 *total = 0;
26309 return true;
26311 case PLUS:
26312 case MINUS:
26313 if (FLOAT_MODE_P (mode))
26314 *total = rs6000_cost->fp;
26315 else
26316 *total = COSTS_N_INSNS (1);
26317 return false;
26319 case MULT:
26320 if (GET_CODE (XEXP (x, 1)) == CONST_INT
26321 && satisfies_constraint_I (XEXP (x, 1)))
26323 if (INTVAL (XEXP (x, 1)) >= -256
26324 && INTVAL (XEXP (x, 1)) <= 255)
26325 *total = rs6000_cost->mulsi_const9;
26326 else
26327 *total = rs6000_cost->mulsi_const;
26329 else if (mode == SFmode)
26330 *total = rs6000_cost->fp;
26331 else if (FLOAT_MODE_P (mode))
26332 *total = rs6000_cost->dmul;
26333 else if (mode == DImode)
26334 *total = rs6000_cost->muldi;
26335 else
26336 *total = rs6000_cost->mulsi;
26337 return false;
26339 case FMA:
26340 if (mode == SFmode)
26341 *total = rs6000_cost->fp;
26342 else
26343 *total = rs6000_cost->dmul;
26344 break;
26346 case DIV:
26347 case MOD:
26348 if (FLOAT_MODE_P (mode))
26350 *total = mode == DFmode ? rs6000_cost->ddiv
26351 : rs6000_cost->sdiv;
26352 return false;
26354 /* FALLTHRU */
26356 case UDIV:
26357 case UMOD:
26358 if (GET_CODE (XEXP (x, 1)) == CONST_INT
26359 && exact_log2 (INTVAL (XEXP (x, 1))) >= 0)
26361 if (code == DIV || code == MOD)
26362 /* Shift, addze */
26363 *total = COSTS_N_INSNS (2);
26364 else
26365 /* Shift */
26366 *total = COSTS_N_INSNS (1);
26368 else
26370 if (GET_MODE (XEXP (x, 1)) == DImode)
26371 *total = rs6000_cost->divdi;
26372 else
26373 *total = rs6000_cost->divsi;
26375 /* Add in shift and subtract for MOD. */
26376 if (code == MOD || code == UMOD)
26377 *total += COSTS_N_INSNS (2);
26378 return false;
26380 case CTZ:
26381 case FFS:
26382 *total = COSTS_N_INSNS (4);
26383 return false;
26385 case POPCOUNT:
26386 *total = COSTS_N_INSNS (TARGET_POPCNTD ? 1 : 6);
26387 return false;
26389 case PARITY:
26390 *total = COSTS_N_INSNS (TARGET_CMPB ? 2 : 6);
26391 return false;
26393 case NOT:
26394 if (outer_code == AND || outer_code == IOR || outer_code == XOR)
26396 *total = 0;
26397 return false;
26399 /* FALLTHRU */
26401 case AND:
26402 case CLZ:
26403 case IOR:
26404 case XOR:
26405 case ZERO_EXTRACT:
26406 *total = COSTS_N_INSNS (1);
26407 return false;
26409 case ASHIFT:
26410 case ASHIFTRT:
26411 case LSHIFTRT:
26412 case ROTATE:
26413 case ROTATERT:
26414 /* Handle mul_highpart. */
26415 if (outer_code == TRUNCATE
26416 && GET_CODE (XEXP (x, 0)) == MULT)
26418 if (mode == DImode)
26419 *total = rs6000_cost->muldi;
26420 else
26421 *total = rs6000_cost->mulsi;
26422 return true;
26424 else if (outer_code == AND)
26425 *total = 0;
26426 else
26427 *total = COSTS_N_INSNS (1);
26428 return false;
26430 case SIGN_EXTEND:
26431 case ZERO_EXTEND:
26432 if (GET_CODE (XEXP (x, 0)) == MEM)
26433 *total = 0;
26434 else
26435 *total = COSTS_N_INSNS (1);
26436 return false;
26438 case COMPARE:
26439 case NEG:
26440 case ABS:
26441 if (!FLOAT_MODE_P (mode))
26443 *total = COSTS_N_INSNS (1);
26444 return false;
26446 /* FALLTHRU */
26448 case FLOAT:
26449 case UNSIGNED_FLOAT:
26450 case FIX:
26451 case UNSIGNED_FIX:
26452 case FLOAT_TRUNCATE:
26453 *total = rs6000_cost->fp;
26454 return false;
26456 case FLOAT_EXTEND:
26457 if (mode == DFmode)
26458 *total = 0;
26459 else
26460 *total = rs6000_cost->fp;
26461 return false;
26463 case UNSPEC:
26464 switch (XINT (x, 1))
26466 case UNSPEC_FRSP:
26467 *total = rs6000_cost->fp;
26468 return true;
26470 default:
26471 break;
26473 break;
26475 case CALL:
26476 case IF_THEN_ELSE:
26477 if (!speed)
26479 *total = COSTS_N_INSNS (1);
26480 return true;
26482 else if (FLOAT_MODE_P (mode)
26483 && TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS)
26485 *total = rs6000_cost->fp;
26486 return false;
26488 break;
26490 case EQ:
26491 case GTU:
26492 case LTU:
26493 /* Carry bit requires mode == Pmode.
26494 NEG or PLUS already counted so only add one. */
26495 if (mode == Pmode
26496 && (outer_code == NEG || outer_code == PLUS))
26498 *total = COSTS_N_INSNS (1);
26499 return true;
26501 if (outer_code == SET)
26503 if (XEXP (x, 1) == const0_rtx)
26505 if (TARGET_ISEL && !TARGET_MFCRF)
26506 *total = COSTS_N_INSNS (8);
26507 else
26508 *total = COSTS_N_INSNS (2);
26509 return true;
26511 else if (mode == Pmode)
26513 *total = COSTS_N_INSNS (3);
26514 return false;
26517 /* FALLTHRU */
26519 case GT:
26520 case LT:
26521 case UNORDERED:
26522 if (outer_code == SET && (XEXP (x, 1) == const0_rtx))
26524 if (TARGET_ISEL && !TARGET_MFCRF)
26525 *total = COSTS_N_INSNS (8);
26526 else
26527 *total = COSTS_N_INSNS (2);
26528 return true;
26530 /* CC COMPARE. */
26531 if (outer_code == COMPARE)
26533 *total = 0;
26534 return true;
26536 break;
26538 default:
26539 break;
26542 return false;
26545 /* Debug form of r6000_rtx_costs that is selected if -mdebug=cost. */
26547 static bool
26548 rs6000_debug_rtx_costs (rtx x, int code, int outer_code, int *total,
26549 bool speed)
26551 bool ret = rs6000_rtx_costs (x, code, outer_code, total, speed);
26553 fprintf (stderr,
26554 "\nrs6000_rtx_costs, return = %s, code = %s, outer_code = %s, "
26555 "total = %d, speed = %s, x:\n",
26556 ret ? "complete" : "scan inner",
26557 GET_RTX_NAME (code),
26558 GET_RTX_NAME (outer_code),
26559 *total,
26560 speed ? "true" : "false");
26562 debug_rtx (x);
26564 return ret;
26567 /* Debug form of ADDRESS_COST that is selected if -mdebug=cost. */
26569 static int
26570 rs6000_debug_address_cost (rtx x, bool speed)
26572 int ret = TARGET_ADDRESS_COST (x, speed);
26574 fprintf (stderr, "\nrs6000_address_cost, return = %d, speed = %s, x:\n",
26575 ret, speed ? "true" : "false");
26576 debug_rtx (x);
26578 return ret;
26582 /* A C expression returning the cost of moving data from a register of class
26583 CLASS1 to one of CLASS2. */
26585 static int
26586 rs6000_register_move_cost (enum machine_mode mode,
26587 reg_class_t from, reg_class_t to)
26589 int ret;
26591 /* Moves from/to GENERAL_REGS. */
26592 if (reg_classes_intersect_p (to, GENERAL_REGS)
26593 || reg_classes_intersect_p (from, GENERAL_REGS))
26595 if (! reg_classes_intersect_p (to, GENERAL_REGS))
26596 from = to;
26598 if (from == FLOAT_REGS || from == ALTIVEC_REGS || from == VSX_REGS)
26599 ret = (rs6000_memory_move_cost (mode, from, false)
26600 + rs6000_memory_move_cost (mode, GENERAL_REGS, false));
26602 /* It's more expensive to move CR_REGS than CR0_REGS because of the
26603 shift. */
26604 else if (from == CR_REGS)
26605 ret = 4;
26607 /* Power6 has slower LR/CTR moves so make them more expensive than
26608 memory in order to bias spills to memory .*/
26609 else if (rs6000_cpu == PROCESSOR_POWER6
26610 && reg_classes_intersect_p (from, LINK_OR_CTR_REGS))
26611 ret = 6 * hard_regno_nregs[0][mode];
26613 else
26614 /* A move will cost one instruction per GPR moved. */
26615 ret = 2 * hard_regno_nregs[0][mode];
26618 /* If we have VSX, we can easily move between FPR or Altivec registers. */
26619 else if (VECTOR_UNIT_VSX_P (mode)
26620 && reg_classes_intersect_p (to, VSX_REGS)
26621 && reg_classes_intersect_p (from, VSX_REGS))
26622 ret = 2 * hard_regno_nregs[32][mode];
26624 /* Moving between two similar registers is just one instruction. */
26625 else if (reg_classes_intersect_p (to, from))
26626 ret = (mode == TFmode || mode == TDmode) ? 4 : 2;
26628 /* Everything else has to go through GENERAL_REGS. */
26629 else
26630 ret = (rs6000_register_move_cost (mode, GENERAL_REGS, to)
26631 + rs6000_register_move_cost (mode, from, GENERAL_REGS));
26633 if (TARGET_DEBUG_COST)
26634 fprintf (stderr,
26635 "rs6000_register_move_cost:, ret=%d, mode=%s, from=%s, to=%s\n",
26636 ret, GET_MODE_NAME (mode), reg_class_names[from],
26637 reg_class_names[to]);
26639 return ret;
26642 /* A C expressions returning the cost of moving data of MODE from a register to
26643 or from memory. */
26645 static int
26646 rs6000_memory_move_cost (enum machine_mode mode, reg_class_t rclass,
26647 bool in ATTRIBUTE_UNUSED)
26649 int ret;
26651 if (reg_classes_intersect_p (rclass, GENERAL_REGS))
26652 ret = 4 * hard_regno_nregs[0][mode];
26653 else if (reg_classes_intersect_p (rclass, FLOAT_REGS))
26654 ret = 4 * hard_regno_nregs[32][mode];
26655 else if (reg_classes_intersect_p (rclass, ALTIVEC_REGS))
26656 ret = 4 * hard_regno_nregs[FIRST_ALTIVEC_REGNO][mode];
26657 else
26658 ret = 4 + rs6000_register_move_cost (mode, rclass, GENERAL_REGS);
26660 if (TARGET_DEBUG_COST)
26661 fprintf (stderr,
26662 "rs6000_memory_move_cost: ret=%d, mode=%s, rclass=%s, in=%d\n",
26663 ret, GET_MODE_NAME (mode), reg_class_names[rclass], in);
26665 return ret;
26668 /* Returns a code for a target-specific builtin that implements
26669 reciprocal of the function, or NULL_TREE if not available. */
26671 static tree
26672 rs6000_builtin_reciprocal (unsigned int fn, bool md_fn,
26673 bool sqrt ATTRIBUTE_UNUSED)
26675 if (optimize_insn_for_size_p ())
26676 return NULL_TREE;
26678 if (md_fn)
26679 switch (fn)
26681 case VSX_BUILTIN_XVSQRTDP:
26682 if (!RS6000_RECIP_AUTO_RSQRTE_P (V2DFmode))
26683 return NULL_TREE;
26685 return rs6000_builtin_decls[VSX_BUILTIN_VEC_RSQRT_V2DF];
26687 case VSX_BUILTIN_XVSQRTSP:
26688 if (!RS6000_RECIP_AUTO_RSQRTE_P (V4SFmode))
26689 return NULL_TREE;
26691 return rs6000_builtin_decls[VSX_BUILTIN_VEC_RSQRT_V4SF];
26693 default:
26694 return NULL_TREE;
26697 else
26698 switch (fn)
26700 case BUILT_IN_SQRT:
26701 if (!RS6000_RECIP_AUTO_RSQRTE_P (DFmode))
26702 return NULL_TREE;
26704 return rs6000_builtin_decls[RS6000_BUILTIN_RSQRT];
26706 case BUILT_IN_SQRTF:
26707 if (!RS6000_RECIP_AUTO_RSQRTE_P (SFmode))
26708 return NULL_TREE;
26710 return rs6000_builtin_decls[RS6000_BUILTIN_RSQRTF];
26712 default:
26713 return NULL_TREE;
26717 /* Load up a constant. If the mode is a vector mode, splat the value across
26718 all of the vector elements. */
26720 static rtx
26721 rs6000_load_constant_and_splat (enum machine_mode mode, REAL_VALUE_TYPE dconst)
26723 rtx reg;
26725 if (mode == SFmode || mode == DFmode)
26727 rtx d = CONST_DOUBLE_FROM_REAL_VALUE (dconst, mode);
26728 reg = force_reg (mode, d);
26730 else if (mode == V4SFmode)
26732 rtx d = CONST_DOUBLE_FROM_REAL_VALUE (dconst, SFmode);
26733 rtvec v = gen_rtvec (4, d, d, d, d);
26734 reg = gen_reg_rtx (mode);
26735 rs6000_expand_vector_init (reg, gen_rtx_PARALLEL (mode, v));
26737 else if (mode == V2DFmode)
26739 rtx d = CONST_DOUBLE_FROM_REAL_VALUE (dconst, DFmode);
26740 rtvec v = gen_rtvec (2, d, d);
26741 reg = gen_reg_rtx (mode);
26742 rs6000_expand_vector_init (reg, gen_rtx_PARALLEL (mode, v));
26744 else
26745 gcc_unreachable ();
26747 return reg;
26750 /* Generate an FMA instruction. */
26752 static void
26753 rs6000_emit_madd (rtx target, rtx m1, rtx m2, rtx a)
26755 enum machine_mode mode = GET_MODE (target);
26756 rtx dst;
26758 dst = expand_ternary_op (mode, fma_optab, m1, m2, a, target, 0);
26759 gcc_assert (dst != NULL);
26761 if (dst != target)
26762 emit_move_insn (target, dst);
26765 /* Generate a FMSUB instruction: dst = fma(m1, m2, -a). */
26767 static void
26768 rs6000_emit_msub (rtx target, rtx m1, rtx m2, rtx a)
26770 enum machine_mode mode = GET_MODE (target);
26771 rtx dst;
26773 /* Altivec does not support fms directly;
26774 generate in terms of fma in that case. */
26775 if (optab_handler (fms_optab, mode) != CODE_FOR_nothing)
26776 dst = expand_ternary_op (mode, fms_optab, m1, m2, a, target, 0);
26777 else
26779 a = expand_unop (mode, neg_optab, a, NULL_RTX, 0);
26780 dst = expand_ternary_op (mode, fma_optab, m1, m2, a, target, 0);
26782 gcc_assert (dst != NULL);
26784 if (dst != target)
26785 emit_move_insn (target, dst);
26788 /* Generate a FNMSUB instruction: dst = -fma(m1, m2, -a). */
26790 static void
26791 rs6000_emit_nmsub (rtx dst, rtx m1, rtx m2, rtx a)
26793 enum machine_mode mode = GET_MODE (dst);
26794 rtx r;
26796 /* This is a tad more complicated, since the fnma_optab is for
26797 a different expression: fma(-m1, m2, a), which is the same
26798 thing except in the case of signed zeros.
26800 Fortunately we know that if FMA is supported that FNMSUB is
26801 also supported in the ISA. Just expand it directly. */
26803 gcc_assert (optab_handler (fma_optab, mode) != CODE_FOR_nothing);
26805 r = gen_rtx_NEG (mode, a);
26806 r = gen_rtx_FMA (mode, m1, m2, r);
26807 r = gen_rtx_NEG (mode, r);
26808 emit_insn (gen_rtx_SET (VOIDmode, dst, r));
26811 /* Newton-Raphson approximation of floating point divide with just 2 passes
26812 (either single precision floating point, or newer machines with higher
26813 accuracy estimates). Support both scalar and vector divide. Assumes no
26814 trapping math and finite arguments. */
26816 static void
26817 rs6000_emit_swdiv_high_precision (rtx dst, rtx n, rtx d)
26819 enum machine_mode mode = GET_MODE (dst);
26820 rtx x0, e0, e1, y1, u0, v0;
26821 enum insn_code code = optab_handler (smul_optab, mode);
26822 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (code);
26823 rtx one = rs6000_load_constant_and_splat (mode, dconst1);
26825 gcc_assert (code != CODE_FOR_nothing);
26827 /* x0 = 1./d estimate */
26828 x0 = gen_reg_rtx (mode);
26829 emit_insn (gen_rtx_SET (VOIDmode, x0,
26830 gen_rtx_UNSPEC (mode, gen_rtvec (1, d),
26831 UNSPEC_FRES)));
26833 e0 = gen_reg_rtx (mode);
26834 rs6000_emit_nmsub (e0, d, x0, one); /* e0 = 1. - (d * x0) */
26836 e1 = gen_reg_rtx (mode);
26837 rs6000_emit_madd (e1, e0, e0, e0); /* e1 = (e0 * e0) + e0 */
26839 y1 = gen_reg_rtx (mode);
26840 rs6000_emit_madd (y1, e1, x0, x0); /* y1 = (e1 * x0) + x0 */
26842 u0 = gen_reg_rtx (mode);
26843 emit_insn (gen_mul (u0, n, y1)); /* u0 = n * y1 */
26845 v0 = gen_reg_rtx (mode);
26846 rs6000_emit_nmsub (v0, d, u0, n); /* v0 = n - (d * u0) */
26848 rs6000_emit_madd (dst, v0, y1, u0); /* dst = (v0 * y1) + u0 */
26851 /* Newton-Raphson approximation of floating point divide that has a low
26852 precision estimate. Assumes no trapping math and finite arguments. */
26854 static void
26855 rs6000_emit_swdiv_low_precision (rtx dst, rtx n, rtx d)
26857 enum machine_mode mode = GET_MODE (dst);
26858 rtx x0, e0, e1, e2, y1, y2, y3, u0, v0, one;
26859 enum insn_code code = optab_handler (smul_optab, mode);
26860 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (code);
26862 gcc_assert (code != CODE_FOR_nothing);
26864 one = rs6000_load_constant_and_splat (mode, dconst1);
26866 /* x0 = 1./d estimate */
26867 x0 = gen_reg_rtx (mode);
26868 emit_insn (gen_rtx_SET (VOIDmode, x0,
26869 gen_rtx_UNSPEC (mode, gen_rtvec (1, d),
26870 UNSPEC_FRES)));
26872 e0 = gen_reg_rtx (mode);
26873 rs6000_emit_nmsub (e0, d, x0, one); /* e0 = 1. - d * x0 */
26875 y1 = gen_reg_rtx (mode);
26876 rs6000_emit_madd (y1, e0, x0, x0); /* y1 = x0 + e0 * x0 */
26878 e1 = gen_reg_rtx (mode);
26879 emit_insn (gen_mul (e1, e0, e0)); /* e1 = e0 * e0 */
26881 y2 = gen_reg_rtx (mode);
26882 rs6000_emit_madd (y2, e1, y1, y1); /* y2 = y1 + e1 * y1 */
26884 e2 = gen_reg_rtx (mode);
26885 emit_insn (gen_mul (e2, e1, e1)); /* e2 = e1 * e1 */
26887 y3 = gen_reg_rtx (mode);
26888 rs6000_emit_madd (y3, e2, y2, y2); /* y3 = y2 + e2 * y2 */
26890 u0 = gen_reg_rtx (mode);
26891 emit_insn (gen_mul (u0, n, y3)); /* u0 = n * y3 */
26893 v0 = gen_reg_rtx (mode);
26894 rs6000_emit_nmsub (v0, d, u0, n); /* v0 = n - d * u0 */
26896 rs6000_emit_madd (dst, v0, y3, u0); /* dst = u0 + v0 * y3 */
26899 /* Newton-Raphson approximation of floating point divide DST = N/D. If NOTE_P,
26900 add a reg_note saying that this was a division. Support both scalar and
26901 vector divide. Assumes no trapping math and finite arguments. */
26903 void
26904 rs6000_emit_swdiv (rtx dst, rtx n, rtx d, bool note_p)
26906 enum machine_mode mode = GET_MODE (dst);
26908 if (RS6000_RECIP_HIGH_PRECISION_P (mode))
26909 rs6000_emit_swdiv_high_precision (dst, n, d);
26910 else
26911 rs6000_emit_swdiv_low_precision (dst, n, d);
26913 if (note_p)
26914 add_reg_note (get_last_insn (), REG_EQUAL, gen_rtx_DIV (mode, n, d));
26917 /* Newton-Raphson approximation of single/double-precision floating point
26918 rsqrt. Assumes no trapping math and finite arguments. */
26920 void
26921 rs6000_emit_swrsqrt (rtx dst, rtx src)
26923 enum machine_mode mode = GET_MODE (src);
26924 rtx x0 = gen_reg_rtx (mode);
26925 rtx y = gen_reg_rtx (mode);
26926 int passes = (TARGET_RECIP_PRECISION) ? 2 : 3;
26927 REAL_VALUE_TYPE dconst3_2;
26928 int i;
26929 rtx halfthree;
26930 enum insn_code code = optab_handler (smul_optab, mode);
26931 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (code);
26933 gcc_assert (code != CODE_FOR_nothing);
26935 /* Load up the constant 1.5 either as a scalar, or as a vector. */
26936 real_from_integer (&dconst3_2, VOIDmode, 3, 0, 0);
26937 SET_REAL_EXP (&dconst3_2, REAL_EXP (&dconst3_2) - 1);
26939 halfthree = rs6000_load_constant_and_splat (mode, dconst3_2);
26941 /* x0 = rsqrt estimate */
26942 emit_insn (gen_rtx_SET (VOIDmode, x0,
26943 gen_rtx_UNSPEC (mode, gen_rtvec (1, src),
26944 UNSPEC_RSQRT)));
26946 /* y = 0.5 * src = 1.5 * src - src -> fewer constants */
26947 rs6000_emit_msub (y, src, halfthree, src);
26949 for (i = 0; i < passes; i++)
26951 rtx x1 = gen_reg_rtx (mode);
26952 rtx u = gen_reg_rtx (mode);
26953 rtx v = gen_reg_rtx (mode);
26955 /* x1 = x0 * (1.5 - y * (x0 * x0)) */
26956 emit_insn (gen_mul (u, x0, x0));
26957 rs6000_emit_nmsub (v, y, u, halfthree);
26958 emit_insn (gen_mul (x1, x0, v));
26959 x0 = x1;
26962 emit_move_insn (dst, x0);
26963 return;
26966 /* Emit popcount intrinsic on TARGET_POPCNTB (Power5) and TARGET_POPCNTD
26967 (Power7) targets. DST is the target, and SRC is the argument operand. */
26969 void
26970 rs6000_emit_popcount (rtx dst, rtx src)
26972 enum machine_mode mode = GET_MODE (dst);
26973 rtx tmp1, tmp2;
26975 /* Use the PPC ISA 2.06 popcnt{w,d} instruction if we can. */
26976 if (TARGET_POPCNTD)
26978 if (mode == SImode)
26979 emit_insn (gen_popcntdsi2 (dst, src));
26980 else
26981 emit_insn (gen_popcntddi2 (dst, src));
26982 return;
26985 tmp1 = gen_reg_rtx (mode);
26987 if (mode == SImode)
26989 emit_insn (gen_popcntbsi2 (tmp1, src));
26990 tmp2 = expand_mult (SImode, tmp1, GEN_INT (0x01010101),
26991 NULL_RTX, 0);
26992 tmp2 = force_reg (SImode, tmp2);
26993 emit_insn (gen_lshrsi3 (dst, tmp2, GEN_INT (24)));
26995 else
26997 emit_insn (gen_popcntbdi2 (tmp1, src));
26998 tmp2 = expand_mult (DImode, tmp1,
26999 GEN_INT ((HOST_WIDE_INT)
27000 0x01010101 << 32 | 0x01010101),
27001 NULL_RTX, 0);
27002 tmp2 = force_reg (DImode, tmp2);
27003 emit_insn (gen_lshrdi3 (dst, tmp2, GEN_INT (56)));
27008 /* Emit parity intrinsic on TARGET_POPCNTB targets. DST is the
27009 target, and SRC is the argument operand. */
27011 void
27012 rs6000_emit_parity (rtx dst, rtx src)
27014 enum machine_mode mode = GET_MODE (dst);
27015 rtx tmp;
27017 tmp = gen_reg_rtx (mode);
27019 /* Use the PPC ISA 2.05 prtyw/prtyd instruction if we can. */
27020 if (TARGET_CMPB)
27022 if (mode == SImode)
27024 emit_insn (gen_popcntbsi2 (tmp, src));
27025 emit_insn (gen_paritysi2_cmpb (dst, tmp));
27027 else
27029 emit_insn (gen_popcntbdi2 (tmp, src));
27030 emit_insn (gen_paritydi2_cmpb (dst, tmp));
27032 return;
27035 if (mode == SImode)
27037 /* Is mult+shift >= shift+xor+shift+xor? */
27038 if (rs6000_cost->mulsi_const >= COSTS_N_INSNS (3))
27040 rtx tmp1, tmp2, tmp3, tmp4;
27042 tmp1 = gen_reg_rtx (SImode);
27043 emit_insn (gen_popcntbsi2 (tmp1, src));
27045 tmp2 = gen_reg_rtx (SImode);
27046 emit_insn (gen_lshrsi3 (tmp2, tmp1, GEN_INT (16)));
27047 tmp3 = gen_reg_rtx (SImode);
27048 emit_insn (gen_xorsi3 (tmp3, tmp1, tmp2));
27050 tmp4 = gen_reg_rtx (SImode);
27051 emit_insn (gen_lshrsi3 (tmp4, tmp3, GEN_INT (8)));
27052 emit_insn (gen_xorsi3 (tmp, tmp3, tmp4));
27054 else
27055 rs6000_emit_popcount (tmp, src);
27056 emit_insn (gen_andsi3 (dst, tmp, const1_rtx));
27058 else
27060 /* Is mult+shift >= shift+xor+shift+xor+shift+xor? */
27061 if (rs6000_cost->muldi >= COSTS_N_INSNS (5))
27063 rtx tmp1, tmp2, tmp3, tmp4, tmp5, tmp6;
27065 tmp1 = gen_reg_rtx (DImode);
27066 emit_insn (gen_popcntbdi2 (tmp1, src));
27068 tmp2 = gen_reg_rtx (DImode);
27069 emit_insn (gen_lshrdi3 (tmp2, tmp1, GEN_INT (32)));
27070 tmp3 = gen_reg_rtx (DImode);
27071 emit_insn (gen_xordi3 (tmp3, tmp1, tmp2));
27073 tmp4 = gen_reg_rtx (DImode);
27074 emit_insn (gen_lshrdi3 (tmp4, tmp3, GEN_INT (16)));
27075 tmp5 = gen_reg_rtx (DImode);
27076 emit_insn (gen_xordi3 (tmp5, tmp3, tmp4));
27078 tmp6 = gen_reg_rtx (DImode);
27079 emit_insn (gen_lshrdi3 (tmp6, tmp5, GEN_INT (8)));
27080 emit_insn (gen_xordi3 (tmp, tmp5, tmp6));
27082 else
27083 rs6000_emit_popcount (tmp, src);
27084 emit_insn (gen_anddi3 (dst, tmp, const1_rtx));
27088 /* Return an RTX representing where to find the function value of a
27089 function returning MODE. */
27090 static rtx
27091 rs6000_complex_function_value (enum machine_mode mode)
27093 unsigned int regno;
27094 rtx r1, r2;
27095 enum machine_mode inner = GET_MODE_INNER (mode);
27096 unsigned int inner_bytes = GET_MODE_SIZE (inner);
27098 if (FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
27099 regno = FP_ARG_RETURN;
27100 else
27102 regno = GP_ARG_RETURN;
27104 /* 32-bit is OK since it'll go in r3/r4. */
27105 if (TARGET_32BIT && inner_bytes >= 4)
27106 return gen_rtx_REG (mode, regno);
27109 if (inner_bytes >= 8)
27110 return gen_rtx_REG (mode, regno);
27112 r1 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno),
27113 const0_rtx);
27114 r2 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno + 1),
27115 GEN_INT (inner_bytes));
27116 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
27119 /* Target hook for TARGET_FUNCTION_VALUE.
27121 On the SPE, both FPs and vectors are returned in r3.
27123 On RS/6000 an integer value is in r3 and a floating-point value is in
27124 fp1, unless -msoft-float. */
27127 rs6000_function_value (const_tree valtype,
27128 const_tree fn_decl_or_type ATTRIBUTE_UNUSED,
27129 bool outgoing ATTRIBUTE_UNUSED)
27131 enum machine_mode mode;
27132 unsigned int regno;
27134 /* Special handling for structs in darwin64. */
27135 if (TARGET_MACHO
27136 && rs6000_darwin64_struct_check_p (TYPE_MODE (valtype), valtype))
27138 CUMULATIVE_ARGS valcum;
27139 rtx valret;
27141 valcum.words = 0;
27142 valcum.fregno = FP_ARG_MIN_REG;
27143 valcum.vregno = ALTIVEC_ARG_MIN_REG;
27144 /* Do a trial code generation as if this were going to be passed as
27145 an argument; if any part goes in memory, we return NULL. */
27146 valret = rs6000_darwin64_record_arg (&valcum, valtype, true, /* retval= */ true);
27147 if (valret)
27148 return valret;
27149 /* Otherwise fall through to standard ABI rules. */
27152 if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DImode)
27154 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
27155 return gen_rtx_PARALLEL (DImode,
27156 gen_rtvec (2,
27157 gen_rtx_EXPR_LIST (VOIDmode,
27158 gen_rtx_REG (SImode, GP_ARG_RETURN),
27159 const0_rtx),
27160 gen_rtx_EXPR_LIST (VOIDmode,
27161 gen_rtx_REG (SImode,
27162 GP_ARG_RETURN + 1),
27163 GEN_INT (4))));
27165 if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DCmode)
27167 return gen_rtx_PARALLEL (DCmode,
27168 gen_rtvec (4,
27169 gen_rtx_EXPR_LIST (VOIDmode,
27170 gen_rtx_REG (SImode, GP_ARG_RETURN),
27171 const0_rtx),
27172 gen_rtx_EXPR_LIST (VOIDmode,
27173 gen_rtx_REG (SImode,
27174 GP_ARG_RETURN + 1),
27175 GEN_INT (4)),
27176 gen_rtx_EXPR_LIST (VOIDmode,
27177 gen_rtx_REG (SImode,
27178 GP_ARG_RETURN + 2),
27179 GEN_INT (8)),
27180 gen_rtx_EXPR_LIST (VOIDmode,
27181 gen_rtx_REG (SImode,
27182 GP_ARG_RETURN + 3),
27183 GEN_INT (12))));
27186 mode = TYPE_MODE (valtype);
27187 if ((INTEGRAL_TYPE_P (valtype) && GET_MODE_BITSIZE (mode) < BITS_PER_WORD)
27188 || POINTER_TYPE_P (valtype))
27189 mode = TARGET_32BIT ? SImode : DImode;
27191 if (DECIMAL_FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
27192 /* _Decimal128 must use an even/odd register pair. */
27193 regno = (mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN;
27194 else if (SCALAR_FLOAT_TYPE_P (valtype) && TARGET_HARD_FLOAT && TARGET_FPRS
27195 && ((TARGET_SINGLE_FLOAT && (mode == SFmode)) || TARGET_DOUBLE_FLOAT))
27196 regno = FP_ARG_RETURN;
27197 else if (TREE_CODE (valtype) == COMPLEX_TYPE
27198 && targetm.calls.split_complex_arg)
27199 return rs6000_complex_function_value (mode);
27200 else if (TREE_CODE (valtype) == VECTOR_TYPE
27201 && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI
27202 && ALTIVEC_VECTOR_MODE (mode))
27203 regno = ALTIVEC_ARG_RETURN;
27204 else if (TREE_CODE (valtype) == VECTOR_TYPE
27205 && TARGET_VSX && TARGET_ALTIVEC_ABI
27206 && VSX_VECTOR_MODE (mode))
27207 regno = ALTIVEC_ARG_RETURN;
27208 else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
27209 && (mode == DFmode || mode == DCmode
27210 || mode == TFmode || mode == TCmode))
27211 return spe_build_register_parallel (mode, GP_ARG_RETURN);
27212 else
27213 regno = GP_ARG_RETURN;
27215 return gen_rtx_REG (mode, regno);
27218 /* Define how to find the value returned by a library function
27219 assuming the value has mode MODE. */
27221 rs6000_libcall_value (enum machine_mode mode)
27223 unsigned int regno;
27225 if (TARGET_32BIT && TARGET_POWERPC64 && mode == DImode)
27227 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
27228 return gen_rtx_PARALLEL (DImode,
27229 gen_rtvec (2,
27230 gen_rtx_EXPR_LIST (VOIDmode,
27231 gen_rtx_REG (SImode, GP_ARG_RETURN),
27232 const0_rtx),
27233 gen_rtx_EXPR_LIST (VOIDmode,
27234 gen_rtx_REG (SImode,
27235 GP_ARG_RETURN + 1),
27236 GEN_INT (4))));
27239 if (DECIMAL_FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
27240 /* _Decimal128 must use an even/odd register pair. */
27241 regno = (mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN;
27242 else if (SCALAR_FLOAT_MODE_P (mode)
27243 && TARGET_HARD_FLOAT && TARGET_FPRS
27244 && ((TARGET_SINGLE_FLOAT && mode == SFmode) || TARGET_DOUBLE_FLOAT))
27245 regno = FP_ARG_RETURN;
27246 else if (ALTIVEC_VECTOR_MODE (mode)
27247 && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI)
27248 regno = ALTIVEC_ARG_RETURN;
27249 else if (VSX_VECTOR_MODE (mode)
27250 && TARGET_VSX && TARGET_ALTIVEC_ABI)
27251 regno = ALTIVEC_ARG_RETURN;
27252 else if (COMPLEX_MODE_P (mode) && targetm.calls.split_complex_arg)
27253 return rs6000_complex_function_value (mode);
27254 else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
27255 && (mode == DFmode || mode == DCmode
27256 || mode == TFmode || mode == TCmode))
27257 return spe_build_register_parallel (mode, GP_ARG_RETURN);
27258 else
27259 regno = GP_ARG_RETURN;
27261 return gen_rtx_REG (mode, regno);
27265 /* Given FROM and TO register numbers, say whether this elimination is allowed.
27266 Frame pointer elimination is automatically handled.
27268 For the RS/6000, if frame pointer elimination is being done, we would like
27269 to convert ap into fp, not sp.
27271 We need r30 if -mminimal-toc was specified, and there are constant pool
27272 references. */
27274 bool
27275 rs6000_can_eliminate (const int from, const int to)
27277 return (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM
27278 ? ! frame_pointer_needed
27279 : from == RS6000_PIC_OFFSET_TABLE_REGNUM
27280 ? ! TARGET_MINIMAL_TOC || TARGET_NO_TOC || get_pool_size () == 0
27281 : true);
27284 /* Define the offset between two registers, FROM to be eliminated and its
27285 replacement TO, at the start of a routine. */
27286 HOST_WIDE_INT
27287 rs6000_initial_elimination_offset (int from, int to)
27289 rs6000_stack_t *info = rs6000_stack_info ();
27290 HOST_WIDE_INT offset;
27292 if (from == HARD_FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
27293 offset = info->push_p ? 0 : -info->total_size;
27294 else if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
27296 offset = info->push_p ? 0 : -info->total_size;
27297 if (FRAME_GROWS_DOWNWARD)
27298 offset += info->fixed_size + info->vars_size + info->parm_size;
27300 else if (from == FRAME_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
27301 offset = FRAME_GROWS_DOWNWARD
27302 ? info->fixed_size + info->vars_size + info->parm_size
27303 : 0;
27304 else if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
27305 offset = info->total_size;
27306 else if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
27307 offset = info->push_p ? info->total_size : 0;
27308 else if (from == RS6000_PIC_OFFSET_TABLE_REGNUM)
27309 offset = 0;
27310 else
27311 gcc_unreachable ();
27313 return offset;
27316 static rtx
27317 rs6000_dwarf_register_span (rtx reg)
27319 rtx parts[8];
27320 int i, words;
27321 unsigned regno = REGNO (reg);
27322 enum machine_mode mode = GET_MODE (reg);
27324 if (TARGET_SPE
27325 && regno < 32
27326 && (SPE_VECTOR_MODE (GET_MODE (reg))
27327 || (TARGET_E500_DOUBLE && FLOAT_MODE_P (mode)
27328 && mode != SFmode && mode != SDmode && mode != SCmode)))
27330 else
27331 return NULL_RTX;
27333 regno = REGNO (reg);
27335 /* The duality of the SPE register size wreaks all kinds of havoc.
27336 This is a way of distinguishing r0 in 32-bits from r0 in
27337 64-bits. */
27338 words = (GET_MODE_SIZE (mode) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD;
27339 gcc_assert (words <= 4);
27340 for (i = 0; i < words; i++, regno++)
27342 if (BYTES_BIG_ENDIAN)
27344 parts[2 * i] = gen_rtx_REG (SImode, regno + 1200);
27345 parts[2 * i + 1] = gen_rtx_REG (SImode, regno);
27347 else
27349 parts[2 * i] = gen_rtx_REG (SImode, regno);
27350 parts[2 * i + 1] = gen_rtx_REG (SImode, regno + 1200);
27354 return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (words * 2, parts));
27357 /* Fill in sizes for SPE register high parts in table used by unwinder. */
27359 static void
27360 rs6000_init_dwarf_reg_sizes_extra (tree address)
27362 if (TARGET_SPE)
27364 int i;
27365 enum machine_mode mode = TYPE_MODE (char_type_node);
27366 rtx addr = expand_expr (address, NULL_RTX, VOIDmode, EXPAND_NORMAL);
27367 rtx mem = gen_rtx_MEM (BLKmode, addr);
27368 rtx value = gen_int_mode (4, mode);
27370 for (i = 1201; i < 1232; i++)
27372 int column = DWARF_REG_TO_UNWIND_COLUMN (i);
27373 HOST_WIDE_INT offset
27374 = DWARF_FRAME_REGNUM (column) * GET_MODE_SIZE (mode);
27376 emit_move_insn (adjust_address (mem, mode, offset), value);
27381 /* Map internal gcc register numbers to DWARF2 register numbers. */
27383 unsigned int
27384 rs6000_dbx_register_number (unsigned int regno)
27386 if (regno <= 63 || write_symbols != DWARF2_DEBUG)
27387 return regno;
27388 if (regno == MQ_REGNO)
27389 return 100;
27390 if (regno == LR_REGNO)
27391 return 108;
27392 if (regno == CTR_REGNO)
27393 return 109;
27394 if (CR_REGNO_P (regno))
27395 return regno - CR0_REGNO + 86;
27396 if (regno == CA_REGNO)
27397 return 101; /* XER */
27398 if (ALTIVEC_REGNO_P (regno))
27399 return regno - FIRST_ALTIVEC_REGNO + 1124;
27400 if (regno == VRSAVE_REGNO)
27401 return 356;
27402 if (regno == VSCR_REGNO)
27403 return 67;
27404 if (regno == SPE_ACC_REGNO)
27405 return 99;
27406 if (regno == SPEFSCR_REGNO)
27407 return 612;
27408 /* SPE high reg number. We get these values of regno from
27409 rs6000_dwarf_register_span. */
27410 gcc_assert (regno >= 1200 && regno < 1232);
27411 return regno;
27414 /* target hook eh_return_filter_mode */
27415 static enum machine_mode
27416 rs6000_eh_return_filter_mode (void)
27418 return TARGET_32BIT ? SImode : word_mode;
27421 /* Target hook for scalar_mode_supported_p. */
27422 static bool
27423 rs6000_scalar_mode_supported_p (enum machine_mode mode)
27425 if (DECIMAL_FLOAT_MODE_P (mode))
27426 return default_decimal_float_supported_p ();
27427 else
27428 return default_scalar_mode_supported_p (mode);
27431 /* Target hook for vector_mode_supported_p. */
27432 static bool
27433 rs6000_vector_mode_supported_p (enum machine_mode mode)
27436 if (TARGET_PAIRED_FLOAT && PAIRED_VECTOR_MODE (mode))
27437 return true;
27439 if (TARGET_SPE && SPE_VECTOR_MODE (mode))
27440 return true;
27442 else if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode))
27443 return true;
27445 else
27446 return false;
27449 /* Target hook for invalid_arg_for_unprototyped_fn. */
27450 static const char *
27451 invalid_arg_for_unprototyped_fn (const_tree typelist, const_tree funcdecl, const_tree val)
27453 return (!rs6000_darwin64_abi
27454 && typelist == 0
27455 && TREE_CODE (TREE_TYPE (val)) == VECTOR_TYPE
27456 && (funcdecl == NULL_TREE
27457 || (TREE_CODE (funcdecl) == FUNCTION_DECL
27458 && DECL_BUILT_IN_CLASS (funcdecl) != BUILT_IN_MD)))
27459 ? N_("AltiVec argument passed to unprototyped function")
27460 : NULL;
27463 /* For TARGET_SECURE_PLT 32-bit PIC code we can save PIC register
27464 setup by using __stack_chk_fail_local hidden function instead of
27465 calling __stack_chk_fail directly. Otherwise it is better to call
27466 __stack_chk_fail directly. */
27468 static tree
27469 rs6000_stack_protect_fail (void)
27471 return (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
27472 ? default_hidden_stack_protect_fail ()
27473 : default_external_stack_protect_fail ();
27476 void
27477 rs6000_final_prescan_insn (rtx insn, rtx *operand ATTRIBUTE_UNUSED,
27478 int num_operands ATTRIBUTE_UNUSED)
27480 if (rs6000_warn_cell_microcode)
27482 const char *temp;
27483 int insn_code_number = recog_memoized (insn);
27484 location_t location = locator_location (INSN_LOCATOR (insn));
27486 /* Punt on insns we cannot recognize. */
27487 if (insn_code_number < 0)
27488 return;
27490 temp = get_insn_template (insn_code_number, insn);
27492 if (get_attr_cell_micro (insn) == CELL_MICRO_ALWAYS)
27493 warning_at (location, OPT_mwarn_cell_microcode,
27494 "emitting microcode insn %s\t[%s] #%d",
27495 temp, insn_data[INSN_CODE (insn)].name, INSN_UID (insn));
27496 else if (get_attr_cell_micro (insn) == CELL_MICRO_CONDITIONAL)
27497 warning_at (location, OPT_mwarn_cell_microcode,
27498 "emitting conditional microcode insn %s\t[%s] #%d",
27499 temp, insn_data[INSN_CODE (insn)].name, INSN_UID (insn));
27504 /* Mask options that we want to support inside of attribute((target)) and
27505 #pragma GCC target operations. Note, we do not include things like
27506 64/32-bit, endianess, hard/soft floating point, etc. that would have
27507 different calling sequences. */
27509 struct rs6000_opt_mask {
27510 const char *name; /* option name */
27511 int mask; /* mask to set */
27512 bool invert; /* invert sense of mask */
27513 bool valid_target; /* option is a target option */
27516 static struct rs6000_opt_mask const rs6000_opt_masks[] =
27518 { "altivec", MASK_ALTIVEC, false, true },
27519 { "cmpb", MASK_CMPB, false, true },
27520 { "dlmzb", MASK_DLMZB, false, true },
27521 { "fprnd", MASK_FPRND, false, true },
27522 { "hard-dfp", MASK_DFP, false, true },
27523 { "isel", MASK_ISEL, false, true },
27524 { "mfcrf", MASK_MFCRF, false, true },
27525 { "mfpgpr", MASK_MFPGPR, false, true },
27526 { "mulhw", MASK_MULHW, false, true },
27527 { "multiple", MASK_MULTIPLE, false, true },
27528 { "update", MASK_NO_UPDATE, true , true },
27529 { "popcntb", MASK_POPCNTB, false, true },
27530 { "popcntd", MASK_POPCNTD, false, true },
27531 { "powerpc-gfxopt", MASK_PPC_GFXOPT, false, true },
27532 { "powerpc-gpopt", MASK_PPC_GPOPT, false, true },
27533 { "recip-precision", MASK_RECIP_PRECISION, false, true },
27534 { "string", MASK_STRING, false, true },
27535 { "vsx", MASK_VSX, false, true },
27536 #ifdef MASK_64BIT
27537 #if TARGET_AIX_OS
27538 { "aix64", MASK_64BIT, false, false },
27539 { "aix32", MASK_64BIT, true, false },
27540 #else
27541 { "64", MASK_64BIT, false, false },
27542 { "32", MASK_64BIT, true, false },
27543 #endif
27544 #endif
27545 #ifdef MASK_EABI
27546 { "eabi", MASK_EABI, false, false },
27547 #endif
27548 #ifdef MASK_LITTLE_ENDIAN
27549 { "little", MASK_LITTLE_ENDIAN, false, false },
27550 { "big", MASK_LITTLE_ENDIAN, true, false },
27551 #endif
27552 #ifdef MASK_RELOCATABLE
27553 { "relocatable", MASK_RELOCATABLE, false, false },
27554 #endif
27555 #ifdef MASK_STRICT_ALIGN
27556 { "strict-align", MASK_STRICT_ALIGN, false, false },
27557 #endif
27558 { "power", MASK_POWER, false, false },
27559 { "power2", MASK_POWER2, false, false },
27560 { "powerpc", MASK_POWERPC, false, false },
27561 { "soft-float", MASK_SOFT_FLOAT, false, false },
27562 { "string", MASK_STRING, false, false },
27565 /* Option variables that we want to support inside attribute((target)) and
27566 #pragma GCC target operations. */
27568 struct rs6000_opt_var {
27569 const char *name; /* option name */
27570 size_t global_offset; /* offset of the option in global_options. */
27571 size_t target_offset; /* offset of the option in target optiosn. */
27574 static struct rs6000_opt_var const rs6000_opt_vars[] =
27576 { "friz",
27577 offsetof (struct gcc_options, x_TARGET_FRIZ),
27578 offsetof (struct cl_target_option, x_TARGET_FRIZ), },
27579 { "avoid-indexed-addresses",
27580 offsetof (struct gcc_options, x_TARGET_AVOID_XFORM),
27581 offsetof (struct cl_target_option, x_TARGET_AVOID_XFORM) },
27582 { "paired",
27583 offsetof (struct gcc_options, x_rs6000_paired_float),
27584 offsetof (struct cl_target_option, x_rs6000_paired_float), },
27585 { "longcall",
27586 offsetof (struct gcc_options, x_rs6000_default_long_calls),
27587 offsetof (struct cl_target_option, x_rs6000_default_long_calls), },
27590 /* Inner function to handle attribute((target("..."))) and #pragma GCC target
27591 parsing. Return true if there were no errors. */
27593 static bool
27594 rs6000_inner_target_options (tree args, bool attr_p)
27596 bool ret = true;
27598 if (args == NULL_TREE)
27601 else if (TREE_CODE (args) == STRING_CST)
27603 char *p = ASTRDUP (TREE_STRING_POINTER (args));
27604 char *q;
27606 while ((q = strtok (p, ",")) != NULL)
27608 bool error_p = false;
27609 bool not_valid_p = false;
27610 const char *cpu_opt = NULL;
27612 p = NULL;
27613 if (strncmp (q, "cpu=", 4) == 0)
27615 int cpu_index = rs6000_cpu_name_lookup (q+4);
27616 if (cpu_index >= 0)
27617 rs6000_cpu_index = cpu_index;
27618 else
27620 error_p = true;
27621 cpu_opt = q+4;
27624 else if (strncmp (q, "tune=", 5) == 0)
27626 int tune_index = rs6000_cpu_name_lookup (q+5);
27627 if (tune_index >= 0)
27628 rs6000_tune_index = tune_index;
27629 else
27631 error_p = true;
27632 cpu_opt = q+5;
27635 else
27637 size_t i;
27638 bool invert = false;
27639 char *r = q;
27641 error_p = true;
27642 if (strncmp (r, "no-", 3) == 0)
27644 invert = true;
27645 r += 3;
27648 for (i = 0; i < ARRAY_SIZE (rs6000_opt_masks); i++)
27649 if (strcmp (r, rs6000_opt_masks[i].name) == 0)
27651 int mask = rs6000_opt_masks[i].mask;
27653 if (!rs6000_opt_masks[i].valid_target)
27654 not_valid_p = true;
27655 else
27657 error_p = false;
27658 target_flags_explicit |= mask;
27660 if (rs6000_opt_masks[i].invert)
27661 invert = !invert;
27663 if (invert)
27664 target_flags &= ~mask;
27665 else
27666 target_flags |= mask;
27668 break;
27671 if (error_p && !not_valid_p)
27673 for (i = 0; i < ARRAY_SIZE (rs6000_opt_vars); i++)
27674 if (strcmp (r, rs6000_opt_vars[i].name) == 0)
27676 size_t j = rs6000_opt_vars[i].global_offset;
27677 ((int *) &global_options)[j] = !invert;
27678 error_p = false;
27679 break;
27684 if (error_p)
27686 const char *eprefix, *esuffix;
27688 ret = false;
27689 if (attr_p)
27691 eprefix = "__attribute__((__target__(";
27692 esuffix = ")))";
27694 else
27696 eprefix = "#pragma GCC target ";
27697 esuffix = "";
27700 if (cpu_opt)
27701 error ("invalid cpu \"%s\" for %s\"%s\"%s", cpu_opt, eprefix,
27702 q, esuffix);
27703 else if (not_valid_p)
27704 error ("%s\"%s\"%s is not allowed", eprefix, q, esuffix);
27705 else
27706 error ("%s\"%s\"%s is invalid", eprefix, q, esuffix);
27711 else if (TREE_CODE (args) == TREE_LIST)
27715 tree value = TREE_VALUE (args);
27716 if (value)
27718 bool ret2 = rs6000_inner_target_options (value, attr_p);
27719 if (!ret2)
27720 ret = false;
27722 args = TREE_CHAIN (args);
27724 while (args != NULL_TREE);
27727 else
27728 gcc_unreachable ();
27730 return ret;
27733 /* Print out the target options as a list for -mdebug=target. */
27735 static void
27736 rs6000_debug_target_options (tree args, const char *prefix)
27738 if (args == NULL_TREE)
27739 fprintf (stderr, "%s<NULL>", prefix);
27741 else if (TREE_CODE (args) == STRING_CST)
27743 char *p = ASTRDUP (TREE_STRING_POINTER (args));
27744 char *q;
27746 while ((q = strtok (p, ",")) != NULL)
27748 p = NULL;
27749 fprintf (stderr, "%s\"%s\"", prefix, q);
27750 prefix = ", ";
27754 else if (TREE_CODE (args) == TREE_LIST)
27758 tree value = TREE_VALUE (args);
27759 if (value)
27761 rs6000_debug_target_options (value, prefix);
27762 prefix = ", ";
27764 args = TREE_CHAIN (args);
27766 while (args != NULL_TREE);
27769 else
27770 gcc_unreachable ();
27772 return;
27776 /* Hook to validate attribute((target("..."))). */
27778 static bool
27779 rs6000_valid_attribute_p (tree fndecl,
27780 tree ARG_UNUSED (name),
27781 tree args,
27782 int flags)
27784 struct cl_target_option cur_target;
27785 bool ret;
27786 tree old_optimize = build_optimization_node ();
27787 tree new_target, new_optimize;
27788 tree func_optimize = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl);
27790 gcc_assert ((fndecl != NULL_TREE) && (args != NULL_TREE));
27792 if (TARGET_DEBUG_TARGET)
27794 tree tname = DECL_NAME (fndecl);
27795 fprintf (stderr, "\n==================== rs6000_valid_attribute_p:\n");
27796 if (tname)
27797 fprintf (stderr, "function: %.*s\n",
27798 (int) IDENTIFIER_LENGTH (tname),
27799 IDENTIFIER_POINTER (tname));
27800 else
27801 fprintf (stderr, "function: unknown\n");
27803 fprintf (stderr, "args:");
27804 rs6000_debug_target_options (args, " ");
27805 fprintf (stderr, "\n");
27807 if (flags)
27808 fprintf (stderr, "flags: 0x%x\n", flags);
27810 fprintf (stderr, "--------------------\n");
27813 old_optimize = build_optimization_node ();
27814 func_optimize = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl);
27816 /* If the function changed the optimization levels as well as setting target
27817 options, start with the optimizations specified. */
27818 if (func_optimize && func_optimize != old_optimize)
27819 cl_optimization_restore (&global_options,
27820 TREE_OPTIMIZATION (func_optimize));
27822 /* The target attributes may also change some optimization flags, so update
27823 the optimization options if necessary. */
27824 cl_target_option_save (&cur_target, &global_options);
27825 rs6000_cpu_index = rs6000_tune_index = -1;
27826 ret = rs6000_inner_target_options (args, true);
27828 /* Set up any additional state. */
27829 if (ret)
27831 ret = rs6000_option_override_internal (false);
27832 new_target = build_target_option_node ();
27834 else
27835 new_target = NULL;
27837 new_optimize = build_optimization_node ();
27839 if (!new_target)
27840 ret = false;
27842 else if (fndecl)
27844 DECL_FUNCTION_SPECIFIC_TARGET (fndecl) = new_target;
27846 if (old_optimize != new_optimize)
27847 DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl) = new_optimize;
27850 cl_target_option_restore (&global_options, &cur_target);
27852 if (old_optimize != new_optimize)
27853 cl_optimization_restore (&global_options,
27854 TREE_OPTIMIZATION (old_optimize));
27856 return ret;
27860 /* Hook to validate the current #pragma GCC target and set the state, and
27861 update the macros based on what was changed. If ARGS is NULL, then
27862 POP_TARGET is used to reset the options. */
27864 bool
27865 rs6000_pragma_target_parse (tree args, tree pop_target)
27867 tree cur_tree;
27868 bool ret;
27870 if (TARGET_DEBUG_TARGET)
27872 fprintf (stderr, "\n==================== rs6000_pragma_target_parse\n");
27873 fprintf (stderr, "args:");
27874 rs6000_debug_target_options (args, " ");
27875 fprintf (stderr, "\n");
27877 if (pop_target)
27879 fprintf (stderr, "pop_target:\n");
27880 debug_tree (pop_target);
27882 else
27883 fprintf (stderr, "pop_target: <NULL>\n");
27885 fprintf (stderr, "--------------------\n");
27888 if (! args)
27890 ret = true;
27891 cur_tree = ((pop_target)
27892 ? pop_target
27893 : target_option_default_node);
27894 cl_target_option_restore (&global_options,
27895 TREE_TARGET_OPTION (cur_tree));
27897 else
27899 rs6000_cpu_index = rs6000_tune_index = -1;
27900 ret = rs6000_inner_target_options (args, false);
27901 cur_tree = build_target_option_node ();
27903 if (!cur_tree)
27904 ret = false;
27907 if (cur_tree)
27908 target_option_current_node = cur_tree;
27910 return ret;
27914 /* Remember the last target of rs6000_set_current_function. */
27915 static GTY(()) tree rs6000_previous_fndecl;
27917 /* Establish appropriate back-end context for processing the function
27918 FNDECL. The argument might be NULL to indicate processing at top
27919 level, outside of any function scope. */
27920 static void
27921 rs6000_set_current_function (tree fndecl)
27923 tree old_tree = (rs6000_previous_fndecl
27924 ? DECL_FUNCTION_SPECIFIC_TARGET (rs6000_previous_fndecl)
27925 : NULL_TREE);
27927 tree new_tree = (fndecl
27928 ? DECL_FUNCTION_SPECIFIC_TARGET (fndecl)
27929 : NULL_TREE);
27931 if (TARGET_DEBUG_TARGET)
27933 bool print_final = false;
27934 fprintf (stderr, "\n==================== rs6000_set_current_function");
27936 if (fndecl)
27937 fprintf (stderr, ", fndecl %s (%p)",
27938 (DECL_NAME (fndecl)
27939 ? IDENTIFIER_POINTER (DECL_NAME (fndecl))
27940 : "<unknown>"), (void *)fndecl);
27942 if (rs6000_previous_fndecl)
27943 fprintf (stderr, ", prev_fndecl (%p)", (void *)rs6000_previous_fndecl);
27945 fprintf (stderr, "\n");
27946 if (new_tree)
27948 fprintf (stderr, "\nnew fndecl target specific options:\n");
27949 debug_tree (new_tree);
27950 print_final = true;
27953 if (old_tree)
27955 fprintf (stderr, "\nold fndecl target specific options:\n");
27956 debug_tree (old_tree);
27957 print_final = true;
27960 if (print_final)
27961 fprintf (stderr, "--------------------\n");
27964 /* Only change the context if the function changes. This hook is called
27965 several times in the course of compiling a function, and we don't want to
27966 slow things down too much or call target_reinit when it isn't safe. */
27967 if (fndecl && fndecl != rs6000_previous_fndecl)
27969 rs6000_previous_fndecl = fndecl;
27970 if (old_tree == new_tree)
27973 else if (new_tree)
27975 cl_target_option_restore (&global_options,
27976 TREE_TARGET_OPTION (new_tree));
27977 target_reinit ();
27980 else if (old_tree)
27982 struct cl_target_option *def
27983 = TREE_TARGET_OPTION (target_option_current_node);
27985 cl_target_option_restore (&global_options, def);
27986 target_reinit ();
27992 /* Save the current options */
27994 static void
27995 rs6000_function_specific_save (struct cl_target_option *ptr)
27997 ptr->rs6000_target_flags_explicit = target_flags_explicit;
28000 /* Restore the current options */
28002 static void
28003 rs6000_function_specific_restore (struct cl_target_option *ptr)
28005 target_flags_explicit = ptr->rs6000_target_flags_explicit;
28006 (void) rs6000_option_override_internal (false);
28009 /* Print the current options */
28011 static void
28012 rs6000_function_specific_print (FILE *file, int indent,
28013 struct cl_target_option *ptr)
28015 size_t i;
28016 int flags = ptr->x_target_flags;
28018 /* Print the various mask options. */
28019 for (i = 0; i < ARRAY_SIZE (rs6000_opt_masks); i++)
28020 if ((flags & rs6000_opt_masks[i].mask) != 0)
28022 flags &= ~ rs6000_opt_masks[i].mask;
28023 fprintf (file, "%*s-m%s%s\n", indent, "",
28024 rs6000_opt_masks[i].invert ? "no-" : "",
28025 rs6000_opt_masks[i].name);
28028 /* Print the various options that are variables. */
28029 for (i = 0; i < ARRAY_SIZE (rs6000_opt_vars); i++)
28031 size_t j = rs6000_opt_vars[i].target_offset;
28032 if (((signed char *) ptr)[j])
28033 fprintf (file, "%*s-m%s\n", indent, "",
28034 rs6000_opt_vars[i].name);
28039 /* Hook to determine if one function can safely inline another. */
28041 static bool
28042 rs6000_can_inline_p (tree caller, tree callee)
28044 bool ret = false;
28045 tree caller_tree = DECL_FUNCTION_SPECIFIC_TARGET (caller);
28046 tree callee_tree = DECL_FUNCTION_SPECIFIC_TARGET (callee);
28048 /* If callee has no option attributes, then it is ok to inline. */
28049 if (!callee_tree)
28050 ret = true;
28052 /* If caller has no option attributes, but callee does then it is not ok to
28053 inline. */
28054 else if (!caller_tree)
28055 ret = false;
28057 else
28059 struct cl_target_option *caller_opts = TREE_TARGET_OPTION (caller_tree);
28060 struct cl_target_option *callee_opts = TREE_TARGET_OPTION (callee_tree);
28062 /* Callee's options should a subset of the caller's, i.e. a vsx function
28063 can inline an altivec function but a non-vsx function can't inline a
28064 vsx function. */
28065 if ((caller_opts->x_target_flags & callee_opts->x_target_flags)
28066 == callee_opts->x_target_flags)
28067 ret = true;
28070 if (TARGET_DEBUG_TARGET)
28071 fprintf (stderr, "rs6000_can_inline_p:, caller %s, callee %s, %s inline\n",
28072 (DECL_NAME (caller)
28073 ? IDENTIFIER_POINTER (DECL_NAME (caller))
28074 : "<unknown>"),
28075 (DECL_NAME (callee)
28076 ? IDENTIFIER_POINTER (DECL_NAME (callee))
28077 : "<unknown>"),
28078 (ret ? "can" : "cannot"));
28080 return ret;
28083 /* Allocate a stack temp and fixup the address so it meets the particular
28084 memory requirements (either offetable or REG+REG addressing). */
28087 rs6000_allocate_stack_temp (enum machine_mode mode,
28088 bool offsettable_p,
28089 bool reg_reg_p)
28091 rtx stack = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
28092 rtx addr = XEXP (stack, 0);
28093 int strict_p = (reload_in_progress || reload_completed);
28095 if (!legitimate_indirect_address_p (addr, strict_p))
28097 if (offsettable_p
28098 && !rs6000_legitimate_offset_address_p (mode, addr, strict_p))
28099 stack = replace_equiv_address (stack, copy_addr_to_reg (addr));
28101 else if (reg_reg_p && !legitimate_indexed_address_p (addr, strict_p))
28102 stack = replace_equiv_address (stack, copy_addr_to_reg (addr));
28105 return stack;
28108 /* Given a memory reference, if it is not a reg or reg+reg addressing, convert
28109 to such a form to deal with memory reference instructions like STFIWX that
28110 only take reg+reg addressing. */
28113 rs6000_address_for_fpconvert (rtx x)
28115 int strict_p = (reload_in_progress || reload_completed);
28116 rtx addr;
28118 gcc_assert (MEM_P (x));
28119 addr = XEXP (x, 0);
28120 if (! legitimate_indirect_address_p (addr, strict_p)
28121 && ! legitimate_indexed_address_p (addr, strict_p))
28123 if (GET_CODE (addr) == PRE_INC || GET_CODE (addr) == PRE_DEC)
28125 rtx reg = XEXP (addr, 0);
28126 HOST_WIDE_INT size = GET_MODE_SIZE (GET_MODE (x));
28127 rtx size_rtx = GEN_INT ((GET_CODE (addr) == PRE_DEC) ? -size : size);
28128 gcc_assert (REG_P (reg));
28129 emit_insn (gen_add3_insn (reg, reg, size_rtx));
28130 addr = reg;
28132 else if (GET_CODE (addr) == PRE_MODIFY)
28134 rtx reg = XEXP (addr, 0);
28135 rtx expr = XEXP (addr, 1);
28136 gcc_assert (REG_P (reg));
28137 gcc_assert (GET_CODE (expr) == PLUS);
28138 emit_insn (gen_add3_insn (reg, XEXP (expr, 0), XEXP (expr, 1)));
28139 addr = reg;
28142 x = replace_equiv_address (x, copy_addr_to_reg (addr));
28145 return x;
28148 /* Given a memory reference, if it is not in the form for altivec memory
28149 reference instructions (i.e. reg or reg+reg addressing with AND of -16),
28150 convert to the altivec format. */
28153 rs6000_address_for_altivec (rtx x)
28155 gcc_assert (MEM_P (x));
28156 if (!altivec_indexed_or_indirect_operand (x, GET_MODE (x)))
28158 rtx addr = XEXP (x, 0);
28159 int strict_p = (reload_in_progress || reload_completed);
28161 if (!legitimate_indexed_address_p (addr, strict_p)
28162 && !legitimate_indirect_address_p (addr, strict_p))
28163 addr = copy_to_mode_reg (Pmode, addr);
28165 addr = gen_rtx_AND (Pmode, addr, GEN_INT (-16));
28166 x = change_address (x, GET_MODE (x), addr);
28169 return x;
28173 #include "gt-rs6000.h"