Merge from mainline (167278:168000).
[official-gcc/graphite-test-results.git] / gcc / config / rs6000 / rs6000.c
blobbc27f73b8f437a4f159b050e5ecd83f4117e2113
1 /* Subroutines used for code generation on IBM RS/6000.
2 Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
4 Free Software Foundation, Inc.
5 Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
7 This file is part of GCC.
9 GCC is free software; you can redistribute it and/or modify it
10 under the terms of the GNU General Public License as published
11 by the Free Software Foundation; either version 3, or (at your
12 option) any later version.
14 GCC is distributed in the hope that it will be useful, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
17 License for more details.
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING3. If not see
21 <http://www.gnu.org/licenses/>. */
23 #include "config.h"
24 #include "system.h"
25 #include "coretypes.h"
26 #include "tm.h"
27 #include "rtl.h"
28 #include "regs.h"
29 #include "hard-reg-set.h"
30 #include "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;
188 /* Value is TRUE if register/mode pair is acceptable. */
189 bool rs6000_hard_regno_mode_ok_p[NUM_MACHINE_MODES][FIRST_PSEUDO_REGISTER];
191 /* Maximum number of registers needed for a given register class and mode. */
192 unsigned char rs6000_class_max_nregs[NUM_MACHINE_MODES][LIM_REG_CLASSES];
194 /* How many registers are needed for a given register and mode. */
195 unsigned char rs6000_hard_regno_nregs[NUM_MACHINE_MODES][FIRST_PSEUDO_REGISTER];
197 /* Map register number to register class. */
198 enum reg_class rs6000_regno_regclass[FIRST_PSEUDO_REGISTER];
200 /* Reload functions based on the type and the vector unit. */
201 static enum insn_code rs6000_vector_reload[NUM_MACHINE_MODES][2];
203 /* Built in types. */
204 tree rs6000_builtin_types[RS6000_BTI_MAX];
205 tree rs6000_builtin_decls[RS6000_BUILTIN_COUNT];
207 /* Flag to say the TOC is initialized */
208 int toc_initialized;
209 char toc_label_name[10];
211 /* Cached value of rs6000_variable_issue. This is cached in
212 rs6000_variable_issue hook and returned from rs6000_sched_reorder2. */
213 static short cached_can_issue_more;
215 static GTY(()) section *read_only_data_section;
216 static GTY(()) section *private_data_section;
217 static GTY(()) section *read_only_private_data_section;
218 static GTY(()) section *sdata2_section;
219 static GTY(()) section *toc_section;
221 /* True for any options that were explicitly set. */
222 static struct {
223 bool aix_struct_ret; /* True if -maix-struct-ret was used. */
224 bool alignment; /* True if -malign- was used. */
225 bool spe_abi; /* True if -mabi=spe/no-spe was used. */
226 bool altivec_abi; /* True if -mabi=altivec/no-altivec used. */
227 bool spe; /* True if -mspe= was used. */
228 bool float_gprs; /* True if -mfloat-gprs= was used. */
229 bool long_double; /* True if -mlong-double- was used. */
230 bool ieee; /* True if -mabi=ieee/ibmlongdouble used. */
231 bool vrsave; /* True if -mvrsave was used. */
232 bool cmodel; /* True if -mcmodel was used. */
233 } rs6000_explicit_options;
235 struct builtin_description
237 /* mask is not const because we're going to alter it below. This
238 nonsense will go away when we rewrite the -march infrastructure
239 to give us more target flag bits. */
240 unsigned int mask;
241 const enum insn_code icode;
242 const char *const name;
243 const enum rs6000_builtins code;
246 /* Describe the vector unit used for modes. */
247 enum rs6000_vector rs6000_vector_unit[NUM_MACHINE_MODES];
248 enum rs6000_vector rs6000_vector_mem[NUM_MACHINE_MODES];
250 /* Register classes for various constraints that are based on the target
251 switches. */
252 enum reg_class rs6000_constraints[RS6000_CONSTRAINT_MAX];
254 /* Describe the alignment of a vector. */
255 int rs6000_vector_align[NUM_MACHINE_MODES];
257 /* Map selected modes to types for builtins. */
258 static GTY(()) tree builtin_mode_to_type[MAX_MACHINE_MODE][2];
260 /* What modes to automatically generate reciprocal divide estimate (fre) and
261 reciprocal sqrt (frsqrte) for. */
262 unsigned char rs6000_recip_bits[MAX_MACHINE_MODE];
264 /* Masks to determine which reciprocal esitmate instructions to generate
265 automatically. */
266 enum rs6000_recip_mask {
267 RECIP_SF_DIV = 0x001, /* Use divide estimate */
268 RECIP_DF_DIV = 0x002,
269 RECIP_V4SF_DIV = 0x004,
270 RECIP_V2DF_DIV = 0x008,
272 RECIP_SF_RSQRT = 0x010, /* Use reciprocal sqrt estimate. */
273 RECIP_DF_RSQRT = 0x020,
274 RECIP_V4SF_RSQRT = 0x040,
275 RECIP_V2DF_RSQRT = 0x080,
277 /* Various combination of flags for -mrecip=xxx. */
278 RECIP_NONE = 0,
279 RECIP_ALL = (RECIP_SF_DIV | RECIP_DF_DIV | RECIP_V4SF_DIV
280 | RECIP_V2DF_DIV | RECIP_SF_RSQRT | RECIP_DF_RSQRT
281 | RECIP_V4SF_RSQRT | RECIP_V2DF_RSQRT),
283 RECIP_HIGH_PRECISION = RECIP_ALL,
285 /* On low precision machines like the power5, don't enable double precision
286 reciprocal square root estimate, since it isn't accurate enough. */
287 RECIP_LOW_PRECISION = (RECIP_ALL & ~(RECIP_DF_RSQRT | RECIP_V2DF_RSQRT))
290 /* -mrecip options. */
291 static struct
293 const char *string; /* option name */
294 unsigned int mask; /* mask bits to set */
295 } recip_options[] = {
296 { "all", RECIP_ALL },
297 { "none", RECIP_NONE },
298 { "div", (RECIP_SF_DIV | RECIP_DF_DIV | RECIP_V4SF_DIV
299 | RECIP_V2DF_DIV) },
300 { "divf", (RECIP_SF_DIV | RECIP_V4SF_DIV) },
301 { "divd", (RECIP_DF_DIV | RECIP_V2DF_DIV) },
302 { "rsqrt", (RECIP_SF_RSQRT | RECIP_DF_RSQRT | RECIP_V4SF_RSQRT
303 | RECIP_V2DF_RSQRT) },
304 { "rsqrtf", (RECIP_SF_RSQRT | RECIP_V4SF_RSQRT) },
305 { "rsqrtd", (RECIP_DF_RSQRT | RECIP_V2DF_RSQRT) },
308 /* 2 argument gen function typedef. */
309 typedef rtx (*gen_2arg_fn_t) (rtx, rtx, rtx);
312 /* Target cpu costs. */
314 struct processor_costs {
315 const int mulsi; /* cost of SImode multiplication. */
316 const int mulsi_const; /* cost of SImode multiplication by constant. */
317 const int mulsi_const9; /* cost of SImode mult by short constant. */
318 const int muldi; /* cost of DImode multiplication. */
319 const int divsi; /* cost of SImode division. */
320 const int divdi; /* cost of DImode division. */
321 const int fp; /* cost of simple SFmode and DFmode insns. */
322 const int dmul; /* cost of DFmode multiplication (and fmadd). */
323 const int sdiv; /* cost of SFmode division (fdivs). */
324 const int ddiv; /* cost of DFmode division (fdiv). */
325 const int cache_line_size; /* cache line size in bytes. */
326 const int l1_cache_size; /* size of l1 cache, in kilobytes. */
327 const int l2_cache_size; /* size of l2 cache, in kilobytes. */
328 const int simultaneous_prefetches; /* number of parallel prefetch
329 operations. */
332 const struct processor_costs *rs6000_cost;
334 /* Processor costs (relative to an add) */
336 /* Instruction size costs on 32bit processors. */
337 static const
338 struct processor_costs size32_cost = {
339 COSTS_N_INSNS (1), /* mulsi */
340 COSTS_N_INSNS (1), /* mulsi_const */
341 COSTS_N_INSNS (1), /* mulsi_const9 */
342 COSTS_N_INSNS (1), /* muldi */
343 COSTS_N_INSNS (1), /* divsi */
344 COSTS_N_INSNS (1), /* divdi */
345 COSTS_N_INSNS (1), /* fp */
346 COSTS_N_INSNS (1), /* dmul */
347 COSTS_N_INSNS (1), /* sdiv */
348 COSTS_N_INSNS (1), /* ddiv */
355 /* Instruction size costs on 64bit processors. */
356 static const
357 struct processor_costs size64_cost = {
358 COSTS_N_INSNS (1), /* mulsi */
359 COSTS_N_INSNS (1), /* mulsi_const */
360 COSTS_N_INSNS (1), /* mulsi_const9 */
361 COSTS_N_INSNS (1), /* muldi */
362 COSTS_N_INSNS (1), /* divsi */
363 COSTS_N_INSNS (1), /* divdi */
364 COSTS_N_INSNS (1), /* fp */
365 COSTS_N_INSNS (1), /* dmul */
366 COSTS_N_INSNS (1), /* sdiv */
367 COSTS_N_INSNS (1), /* ddiv */
368 128,
374 /* Instruction costs on RIOS1 processors. */
375 static const
376 struct processor_costs rios1_cost = {
377 COSTS_N_INSNS (5), /* mulsi */
378 COSTS_N_INSNS (4), /* mulsi_const */
379 COSTS_N_INSNS (3), /* mulsi_const9 */
380 COSTS_N_INSNS (5), /* muldi */
381 COSTS_N_INSNS (19), /* divsi */
382 COSTS_N_INSNS (19), /* divdi */
383 COSTS_N_INSNS (2), /* fp */
384 COSTS_N_INSNS (2), /* dmul */
385 COSTS_N_INSNS (19), /* sdiv */
386 COSTS_N_INSNS (19), /* ddiv */
387 128, /* cache line size */
388 64, /* l1 cache */
389 512, /* l2 cache */
390 0, /* streams */
393 /* Instruction costs on RIOS2 processors. */
394 static const
395 struct processor_costs rios2_cost = {
396 COSTS_N_INSNS (2), /* mulsi */
397 COSTS_N_INSNS (2), /* mulsi_const */
398 COSTS_N_INSNS (2), /* mulsi_const9 */
399 COSTS_N_INSNS (2), /* muldi */
400 COSTS_N_INSNS (13), /* divsi */
401 COSTS_N_INSNS (13), /* divdi */
402 COSTS_N_INSNS (2), /* fp */
403 COSTS_N_INSNS (2), /* dmul */
404 COSTS_N_INSNS (17), /* sdiv */
405 COSTS_N_INSNS (17), /* ddiv */
406 256, /* cache line size */
407 256, /* l1 cache */
408 1024, /* l2 cache */
409 0, /* streams */
412 /* Instruction costs on RS64A processors. */
413 static const
414 struct processor_costs rs64a_cost = {
415 COSTS_N_INSNS (20), /* mulsi */
416 COSTS_N_INSNS (12), /* mulsi_const */
417 COSTS_N_INSNS (8), /* mulsi_const9 */
418 COSTS_N_INSNS (34), /* muldi */
419 COSTS_N_INSNS (65), /* divsi */
420 COSTS_N_INSNS (67), /* divdi */
421 COSTS_N_INSNS (4), /* fp */
422 COSTS_N_INSNS (4), /* dmul */
423 COSTS_N_INSNS (31), /* sdiv */
424 COSTS_N_INSNS (31), /* ddiv */
425 128, /* cache line size */
426 128, /* l1 cache */
427 2048, /* l2 cache */
428 1, /* streams */
431 /* Instruction costs on MPCCORE processors. */
432 static const
433 struct processor_costs mpccore_cost = {
434 COSTS_N_INSNS (2), /* mulsi */
435 COSTS_N_INSNS (2), /* mulsi_const */
436 COSTS_N_INSNS (2), /* mulsi_const9 */
437 COSTS_N_INSNS (2), /* muldi */
438 COSTS_N_INSNS (6), /* divsi */
439 COSTS_N_INSNS (6), /* divdi */
440 COSTS_N_INSNS (4), /* fp */
441 COSTS_N_INSNS (5), /* dmul */
442 COSTS_N_INSNS (10), /* sdiv */
443 COSTS_N_INSNS (17), /* ddiv */
444 32, /* cache line size */
445 4, /* l1 cache */
446 16, /* l2 cache */
447 1, /* streams */
450 /* Instruction costs on PPC403 processors. */
451 static const
452 struct processor_costs ppc403_cost = {
453 COSTS_N_INSNS (4), /* mulsi */
454 COSTS_N_INSNS (4), /* mulsi_const */
455 COSTS_N_INSNS (4), /* mulsi_const9 */
456 COSTS_N_INSNS (4), /* muldi */
457 COSTS_N_INSNS (33), /* divsi */
458 COSTS_N_INSNS (33), /* divdi */
459 COSTS_N_INSNS (11), /* fp */
460 COSTS_N_INSNS (11), /* dmul */
461 COSTS_N_INSNS (11), /* sdiv */
462 COSTS_N_INSNS (11), /* ddiv */
463 32, /* cache line size */
464 4, /* l1 cache */
465 16, /* l2 cache */
466 1, /* streams */
469 /* Instruction costs on PPC405 processors. */
470 static const
471 struct processor_costs ppc405_cost = {
472 COSTS_N_INSNS (5), /* mulsi */
473 COSTS_N_INSNS (4), /* mulsi_const */
474 COSTS_N_INSNS (3), /* mulsi_const9 */
475 COSTS_N_INSNS (5), /* muldi */
476 COSTS_N_INSNS (35), /* divsi */
477 COSTS_N_INSNS (35), /* divdi */
478 COSTS_N_INSNS (11), /* fp */
479 COSTS_N_INSNS (11), /* dmul */
480 COSTS_N_INSNS (11), /* sdiv */
481 COSTS_N_INSNS (11), /* ddiv */
482 32, /* cache line size */
483 16, /* l1 cache */
484 128, /* l2 cache */
485 1, /* streams */
488 /* Instruction costs on PPC440 processors. */
489 static const
490 struct processor_costs ppc440_cost = {
491 COSTS_N_INSNS (3), /* mulsi */
492 COSTS_N_INSNS (2), /* mulsi_const */
493 COSTS_N_INSNS (2), /* mulsi_const9 */
494 COSTS_N_INSNS (3), /* muldi */
495 COSTS_N_INSNS (34), /* divsi */
496 COSTS_N_INSNS (34), /* divdi */
497 COSTS_N_INSNS (5), /* fp */
498 COSTS_N_INSNS (5), /* dmul */
499 COSTS_N_INSNS (19), /* sdiv */
500 COSTS_N_INSNS (33), /* ddiv */
501 32, /* cache line size */
502 32, /* l1 cache */
503 256, /* l2 cache */
504 1, /* streams */
507 /* Instruction costs on PPC476 processors. */
508 static const
509 struct processor_costs ppc476_cost = {
510 COSTS_N_INSNS (4), /* mulsi */
511 COSTS_N_INSNS (4), /* mulsi_const */
512 COSTS_N_INSNS (4), /* mulsi_const9 */
513 COSTS_N_INSNS (4), /* muldi */
514 COSTS_N_INSNS (11), /* divsi */
515 COSTS_N_INSNS (11), /* divdi */
516 COSTS_N_INSNS (6), /* fp */
517 COSTS_N_INSNS (6), /* dmul */
518 COSTS_N_INSNS (19), /* sdiv */
519 COSTS_N_INSNS (33), /* ddiv */
520 32, /* l1 cache line size */
521 32, /* l1 cache */
522 512, /* l2 cache */
523 1, /* streams */
526 /* Instruction costs on PPC601 processors. */
527 static const
528 struct processor_costs ppc601_cost = {
529 COSTS_N_INSNS (5), /* mulsi */
530 COSTS_N_INSNS (5), /* mulsi_const */
531 COSTS_N_INSNS (5), /* mulsi_const9 */
532 COSTS_N_INSNS (5), /* muldi */
533 COSTS_N_INSNS (36), /* divsi */
534 COSTS_N_INSNS (36), /* divdi */
535 COSTS_N_INSNS (4), /* fp */
536 COSTS_N_INSNS (5), /* dmul */
537 COSTS_N_INSNS (17), /* sdiv */
538 COSTS_N_INSNS (31), /* ddiv */
539 32, /* cache line size */
540 32, /* l1 cache */
541 256, /* l2 cache */
542 1, /* streams */
545 /* Instruction costs on PPC603 processors. */
546 static const
547 struct processor_costs ppc603_cost = {
548 COSTS_N_INSNS (5), /* mulsi */
549 COSTS_N_INSNS (3), /* mulsi_const */
550 COSTS_N_INSNS (2), /* mulsi_const9 */
551 COSTS_N_INSNS (5), /* muldi */
552 COSTS_N_INSNS (37), /* divsi */
553 COSTS_N_INSNS (37), /* divdi */
554 COSTS_N_INSNS (3), /* fp */
555 COSTS_N_INSNS (4), /* dmul */
556 COSTS_N_INSNS (18), /* sdiv */
557 COSTS_N_INSNS (33), /* ddiv */
558 32, /* cache line size */
559 8, /* l1 cache */
560 64, /* l2 cache */
561 1, /* streams */
564 /* Instruction costs on PPC604 processors. */
565 static const
566 struct processor_costs ppc604_cost = {
567 COSTS_N_INSNS (4), /* mulsi */
568 COSTS_N_INSNS (4), /* mulsi_const */
569 COSTS_N_INSNS (4), /* mulsi_const9 */
570 COSTS_N_INSNS (4), /* muldi */
571 COSTS_N_INSNS (20), /* divsi */
572 COSTS_N_INSNS (20), /* divdi */
573 COSTS_N_INSNS (3), /* fp */
574 COSTS_N_INSNS (3), /* dmul */
575 COSTS_N_INSNS (18), /* sdiv */
576 COSTS_N_INSNS (32), /* ddiv */
577 32, /* cache line size */
578 16, /* l1 cache */
579 512, /* l2 cache */
580 1, /* streams */
583 /* Instruction costs on PPC604e processors. */
584 static const
585 struct processor_costs ppc604e_cost = {
586 COSTS_N_INSNS (2), /* mulsi */
587 COSTS_N_INSNS (2), /* mulsi_const */
588 COSTS_N_INSNS (2), /* mulsi_const9 */
589 COSTS_N_INSNS (2), /* muldi */
590 COSTS_N_INSNS (20), /* divsi */
591 COSTS_N_INSNS (20), /* divdi */
592 COSTS_N_INSNS (3), /* fp */
593 COSTS_N_INSNS (3), /* dmul */
594 COSTS_N_INSNS (18), /* sdiv */
595 COSTS_N_INSNS (32), /* ddiv */
596 32, /* cache line size */
597 32, /* l1 cache */
598 1024, /* l2 cache */
599 1, /* streams */
602 /* Instruction costs on PPC620 processors. */
603 static const
604 struct processor_costs ppc620_cost = {
605 COSTS_N_INSNS (5), /* mulsi */
606 COSTS_N_INSNS (4), /* mulsi_const */
607 COSTS_N_INSNS (3), /* mulsi_const9 */
608 COSTS_N_INSNS (7), /* muldi */
609 COSTS_N_INSNS (21), /* divsi */
610 COSTS_N_INSNS (37), /* divdi */
611 COSTS_N_INSNS (3), /* fp */
612 COSTS_N_INSNS (3), /* dmul */
613 COSTS_N_INSNS (18), /* sdiv */
614 COSTS_N_INSNS (32), /* ddiv */
615 128, /* cache line size */
616 32, /* l1 cache */
617 1024, /* l2 cache */
618 1, /* streams */
621 /* Instruction costs on PPC630 processors. */
622 static const
623 struct processor_costs ppc630_cost = {
624 COSTS_N_INSNS (5), /* mulsi */
625 COSTS_N_INSNS (4), /* mulsi_const */
626 COSTS_N_INSNS (3), /* mulsi_const9 */
627 COSTS_N_INSNS (7), /* muldi */
628 COSTS_N_INSNS (21), /* divsi */
629 COSTS_N_INSNS (37), /* divdi */
630 COSTS_N_INSNS (3), /* fp */
631 COSTS_N_INSNS (3), /* dmul */
632 COSTS_N_INSNS (17), /* sdiv */
633 COSTS_N_INSNS (21), /* ddiv */
634 128, /* cache line size */
635 64, /* l1 cache */
636 1024, /* l2 cache */
637 1, /* streams */
640 /* Instruction costs on Cell processor. */
641 /* COSTS_N_INSNS (1) ~ one add. */
642 static const
643 struct processor_costs ppccell_cost = {
644 COSTS_N_INSNS (9/2)+2, /* mulsi */
645 COSTS_N_INSNS (6/2), /* mulsi_const */
646 COSTS_N_INSNS (6/2), /* mulsi_const9 */
647 COSTS_N_INSNS (15/2)+2, /* muldi */
648 COSTS_N_INSNS (38/2), /* divsi */
649 COSTS_N_INSNS (70/2), /* divdi */
650 COSTS_N_INSNS (10/2), /* fp */
651 COSTS_N_INSNS (10/2), /* dmul */
652 COSTS_N_INSNS (74/2), /* sdiv */
653 COSTS_N_INSNS (74/2), /* ddiv */
654 128, /* cache line size */
655 32, /* l1 cache */
656 512, /* l2 cache */
657 6, /* streams */
660 /* Instruction costs on PPC750 and PPC7400 processors. */
661 static const
662 struct processor_costs ppc750_cost = {
663 COSTS_N_INSNS (5), /* mulsi */
664 COSTS_N_INSNS (3), /* mulsi_const */
665 COSTS_N_INSNS (2), /* mulsi_const9 */
666 COSTS_N_INSNS (5), /* muldi */
667 COSTS_N_INSNS (17), /* divsi */
668 COSTS_N_INSNS (17), /* divdi */
669 COSTS_N_INSNS (3), /* fp */
670 COSTS_N_INSNS (3), /* dmul */
671 COSTS_N_INSNS (17), /* sdiv */
672 COSTS_N_INSNS (31), /* ddiv */
673 32, /* cache line size */
674 32, /* l1 cache */
675 512, /* l2 cache */
676 1, /* streams */
679 /* Instruction costs on PPC7450 processors. */
680 static const
681 struct processor_costs ppc7450_cost = {
682 COSTS_N_INSNS (4), /* mulsi */
683 COSTS_N_INSNS (3), /* mulsi_const */
684 COSTS_N_INSNS (3), /* mulsi_const9 */
685 COSTS_N_INSNS (4), /* muldi */
686 COSTS_N_INSNS (23), /* divsi */
687 COSTS_N_INSNS (23), /* divdi */
688 COSTS_N_INSNS (5), /* fp */
689 COSTS_N_INSNS (5), /* dmul */
690 COSTS_N_INSNS (21), /* sdiv */
691 COSTS_N_INSNS (35), /* ddiv */
692 32, /* cache line size */
693 32, /* l1 cache */
694 1024, /* l2 cache */
695 1, /* streams */
698 /* Instruction costs on PPC8540 processors. */
699 static const
700 struct processor_costs ppc8540_cost = {
701 COSTS_N_INSNS (4), /* mulsi */
702 COSTS_N_INSNS (4), /* mulsi_const */
703 COSTS_N_INSNS (4), /* mulsi_const9 */
704 COSTS_N_INSNS (4), /* muldi */
705 COSTS_N_INSNS (19), /* divsi */
706 COSTS_N_INSNS (19), /* divdi */
707 COSTS_N_INSNS (4), /* fp */
708 COSTS_N_INSNS (4), /* dmul */
709 COSTS_N_INSNS (29), /* sdiv */
710 COSTS_N_INSNS (29), /* ddiv */
711 32, /* cache line size */
712 32, /* l1 cache */
713 256, /* l2 cache */
714 1, /* prefetch streams /*/
717 /* Instruction costs on E300C2 and E300C3 cores. */
718 static const
719 struct processor_costs ppce300c2c3_cost = {
720 COSTS_N_INSNS (4), /* mulsi */
721 COSTS_N_INSNS (4), /* mulsi_const */
722 COSTS_N_INSNS (4), /* mulsi_const9 */
723 COSTS_N_INSNS (4), /* muldi */
724 COSTS_N_INSNS (19), /* divsi */
725 COSTS_N_INSNS (19), /* divdi */
726 COSTS_N_INSNS (3), /* fp */
727 COSTS_N_INSNS (4), /* dmul */
728 COSTS_N_INSNS (18), /* sdiv */
729 COSTS_N_INSNS (33), /* ddiv */
731 16, /* l1 cache */
732 16, /* l2 cache */
733 1, /* prefetch streams /*/
736 /* Instruction costs on PPCE500MC processors. */
737 static const
738 struct processor_costs ppce500mc_cost = {
739 COSTS_N_INSNS (4), /* mulsi */
740 COSTS_N_INSNS (4), /* mulsi_const */
741 COSTS_N_INSNS (4), /* mulsi_const9 */
742 COSTS_N_INSNS (4), /* muldi */
743 COSTS_N_INSNS (14), /* divsi */
744 COSTS_N_INSNS (14), /* divdi */
745 COSTS_N_INSNS (8), /* fp */
746 COSTS_N_INSNS (10), /* dmul */
747 COSTS_N_INSNS (36), /* sdiv */
748 COSTS_N_INSNS (66), /* ddiv */
749 64, /* cache line size */
750 32, /* l1 cache */
751 128, /* l2 cache */
752 1, /* prefetch streams /*/
755 /* Instruction costs on PPCE500MC64 processors. */
756 static const
757 struct processor_costs ppce500mc64_cost = {
758 COSTS_N_INSNS (4), /* mulsi */
759 COSTS_N_INSNS (4), /* mulsi_const */
760 COSTS_N_INSNS (4), /* mulsi_const9 */
761 COSTS_N_INSNS (4), /* muldi */
762 COSTS_N_INSNS (14), /* divsi */
763 COSTS_N_INSNS (14), /* divdi */
764 COSTS_N_INSNS (4), /* fp */
765 COSTS_N_INSNS (10), /* dmul */
766 COSTS_N_INSNS (36), /* sdiv */
767 COSTS_N_INSNS (66), /* ddiv */
768 64, /* cache line size */
769 32, /* l1 cache */
770 128, /* l2 cache */
771 1, /* prefetch streams /*/
774 /* Instruction costs on AppliedMicro Titan processors. */
775 static const
776 struct processor_costs titan_cost = {
777 COSTS_N_INSNS (5), /* mulsi */
778 COSTS_N_INSNS (5), /* mulsi_const */
779 COSTS_N_INSNS (5), /* mulsi_const9 */
780 COSTS_N_INSNS (5), /* muldi */
781 COSTS_N_INSNS (18), /* divsi */
782 COSTS_N_INSNS (18), /* divdi */
783 COSTS_N_INSNS (10), /* fp */
784 COSTS_N_INSNS (10), /* dmul */
785 COSTS_N_INSNS (46), /* sdiv */
786 COSTS_N_INSNS (72), /* ddiv */
787 32, /* cache line size */
788 32, /* l1 cache */
789 512, /* l2 cache */
790 1, /* prefetch streams /*/
793 /* Instruction costs on POWER4 and POWER5 processors. */
794 static const
795 struct processor_costs power4_cost = {
796 COSTS_N_INSNS (3), /* mulsi */
797 COSTS_N_INSNS (2), /* mulsi_const */
798 COSTS_N_INSNS (2), /* mulsi_const9 */
799 COSTS_N_INSNS (4), /* muldi */
800 COSTS_N_INSNS (18), /* divsi */
801 COSTS_N_INSNS (34), /* divdi */
802 COSTS_N_INSNS (3), /* fp */
803 COSTS_N_INSNS (3), /* dmul */
804 COSTS_N_INSNS (17), /* sdiv */
805 COSTS_N_INSNS (17), /* ddiv */
806 128, /* cache line size */
807 32, /* l1 cache */
808 1024, /* l2 cache */
809 8, /* prefetch streams /*/
812 /* Instruction costs on POWER6 processors. */
813 static const
814 struct processor_costs power6_cost = {
815 COSTS_N_INSNS (8), /* mulsi */
816 COSTS_N_INSNS (8), /* mulsi_const */
817 COSTS_N_INSNS (8), /* mulsi_const9 */
818 COSTS_N_INSNS (8), /* muldi */
819 COSTS_N_INSNS (22), /* divsi */
820 COSTS_N_INSNS (28), /* divdi */
821 COSTS_N_INSNS (3), /* fp */
822 COSTS_N_INSNS (3), /* dmul */
823 COSTS_N_INSNS (13), /* sdiv */
824 COSTS_N_INSNS (16), /* ddiv */
825 128, /* cache line size */
826 64, /* l1 cache */
827 2048, /* l2 cache */
828 16, /* prefetch streams */
831 /* Instruction costs on POWER7 processors. */
832 static const
833 struct processor_costs power7_cost = {
834 COSTS_N_INSNS (2), /* mulsi */
835 COSTS_N_INSNS (2), /* mulsi_const */
836 COSTS_N_INSNS (2), /* mulsi_const9 */
837 COSTS_N_INSNS (2), /* muldi */
838 COSTS_N_INSNS (18), /* divsi */
839 COSTS_N_INSNS (34), /* divdi */
840 COSTS_N_INSNS (3), /* fp */
841 COSTS_N_INSNS (3), /* dmul */
842 COSTS_N_INSNS (13), /* sdiv */
843 COSTS_N_INSNS (16), /* ddiv */
844 128, /* cache line size */
845 32, /* l1 cache */
846 256, /* l2 cache */
847 12, /* prefetch streams */
850 /* Instruction costs on POWER A2 processors. */
851 static const
852 struct processor_costs ppca2_cost = {
853 COSTS_N_INSNS (16), /* mulsi */
854 COSTS_N_INSNS (16), /* mulsi_const */
855 COSTS_N_INSNS (16), /* mulsi_const9 */
856 COSTS_N_INSNS (16), /* muldi */
857 COSTS_N_INSNS (22), /* divsi */
858 COSTS_N_INSNS (28), /* divdi */
859 COSTS_N_INSNS (3), /* fp */
860 COSTS_N_INSNS (3), /* dmul */
861 COSTS_N_INSNS (59), /* sdiv */
862 COSTS_N_INSNS (72), /* ddiv */
864 16, /* l1 cache */
865 2048, /* l2 cache */
866 16, /* prefetch streams */
870 /* Table that classifies rs6000 builtin functions (pure, const, etc.). */
871 #undef RS6000_BUILTIN
872 #undef RS6000_BUILTIN_EQUATE
873 #define RS6000_BUILTIN(NAME, TYPE) TYPE,
874 #define RS6000_BUILTIN_EQUATE(NAME, VALUE)
876 static const enum rs6000_btc builtin_classify[(int)RS6000_BUILTIN_COUNT] =
878 #include "rs6000-builtin.def"
881 #undef RS6000_BUILTIN
882 #undef RS6000_BUILTIN_EQUATE
884 /* Support for -mveclibabi=<xxx> to control which vector library to use. */
885 static tree (*rs6000_veclib_handler) (tree, tree, tree);
888 static bool rs6000_function_ok_for_sibcall (tree, tree);
889 static const char *rs6000_invalid_within_doloop (const_rtx);
890 static bool rs6000_legitimate_address_p (enum machine_mode, rtx, bool);
891 static bool rs6000_debug_legitimate_address_p (enum machine_mode, rtx, bool);
892 static rtx rs6000_generate_compare (rtx, enum machine_mode);
893 static void rs6000_emit_stack_tie (void);
894 static void rs6000_frame_related (rtx, rtx, HOST_WIDE_INT, rtx, rtx);
895 static bool spe_func_has_64bit_regs_p (void);
896 static void emit_frame_save (rtx, rtx, enum machine_mode, unsigned int,
897 int, HOST_WIDE_INT);
898 static rtx gen_frame_mem_offset (enum machine_mode, rtx, int);
899 static unsigned rs6000_hash_constant (rtx);
900 static unsigned toc_hash_function (const void *);
901 static int toc_hash_eq (const void *, const void *);
902 static bool reg_offset_addressing_ok_p (enum machine_mode);
903 static bool virtual_stack_registers_memory_p (rtx);
904 static bool constant_pool_expr_p (rtx);
905 static bool legitimate_small_data_p (enum machine_mode, rtx);
906 static bool legitimate_lo_sum_address_p (enum machine_mode, rtx, int);
907 static struct machine_function * rs6000_init_machine_status (void);
908 static bool rs6000_assemble_integer (rtx, unsigned int, int);
909 static bool no_global_regs_above (int, bool);
910 #ifdef HAVE_GAS_HIDDEN
911 static void rs6000_assemble_visibility (tree, int);
912 #endif
913 static int rs6000_ra_ever_killed (void);
914 static bool rs6000_attribute_takes_identifier_p (const_tree);
915 static tree rs6000_handle_longcall_attribute (tree *, tree, tree, int, bool *);
916 static tree rs6000_handle_altivec_attribute (tree *, tree, tree, int, bool *);
917 static bool rs6000_ms_bitfield_layout_p (const_tree);
918 static tree rs6000_handle_struct_attribute (tree *, tree, tree, int, bool *);
919 static void rs6000_eliminate_indexed_memrefs (rtx operands[2]);
920 static const char *rs6000_mangle_type (const_tree);
921 static void rs6000_set_default_type_attributes (tree);
922 static rtx rs6000_savres_routine_sym (rs6000_stack_t *, bool, bool, bool);
923 static rtx rs6000_emit_stack_reset (rs6000_stack_t *, rtx, rtx, int, bool);
924 static rtx rs6000_make_savres_rtx (rs6000_stack_t *, rtx, int,
925 enum machine_mode, bool, bool, bool);
926 static bool rs6000_reg_live_or_pic_offset_p (int);
927 static tree rs6000_builtin_vectorized_libmass (tree, tree, tree);
928 static tree rs6000_builtin_vectorized_function (tree, tree, tree);
929 static void rs6000_restore_saved_cr (rtx, int);
930 static bool rs6000_output_addr_const_extra (FILE *, rtx);
931 static void rs6000_output_function_prologue (FILE *, HOST_WIDE_INT);
932 static void rs6000_output_function_epilogue (FILE *, HOST_WIDE_INT);
933 static void rs6000_output_mi_thunk (FILE *, tree, HOST_WIDE_INT, HOST_WIDE_INT,
934 tree);
935 static rtx rs6000_emit_set_long_const (rtx, HOST_WIDE_INT, HOST_WIDE_INT);
936 static bool rs6000_return_in_memory (const_tree, const_tree);
937 static rtx rs6000_function_value (const_tree, const_tree, bool);
938 static void rs6000_file_start (void);
939 #if TARGET_ELF
940 static int rs6000_elf_reloc_rw_mask (void);
941 static void rs6000_elf_asm_out_constructor (rtx, int);
942 static void rs6000_elf_asm_out_destructor (rtx, int);
943 static void rs6000_elf_end_indicate_exec_stack (void) ATTRIBUTE_UNUSED;
944 static void rs6000_elf_asm_init_sections (void);
945 static section *rs6000_elf_select_rtx_section (enum machine_mode, rtx,
946 unsigned HOST_WIDE_INT);
947 static void rs6000_elf_encode_section_info (tree, rtx, int)
948 ATTRIBUTE_UNUSED;
949 #endif
950 static bool rs6000_use_blocks_for_constant_p (enum machine_mode, const_rtx);
951 static void rs6000_alloc_sdmode_stack_slot (void);
952 static void rs6000_instantiate_decls (void);
953 #if TARGET_XCOFF
954 static void rs6000_xcoff_asm_output_anchor (rtx);
955 static void rs6000_xcoff_asm_globalize_label (FILE *, const char *);
956 static void rs6000_xcoff_asm_init_sections (void);
957 static int rs6000_xcoff_reloc_rw_mask (void);
958 static void rs6000_xcoff_asm_named_section (const char *, unsigned int, tree);
959 static section *rs6000_xcoff_select_section (tree, int,
960 unsigned HOST_WIDE_INT);
961 static void rs6000_xcoff_unique_section (tree, int);
962 static section *rs6000_xcoff_select_rtx_section
963 (enum machine_mode, rtx, unsigned HOST_WIDE_INT);
964 static const char * rs6000_xcoff_strip_name_encoding (const char *);
965 static unsigned int rs6000_xcoff_section_type_flags (tree, const char *, int);
966 static void rs6000_xcoff_file_start (void);
967 static void rs6000_xcoff_file_end (void);
968 #endif
969 static int rs6000_variable_issue (FILE *, int, rtx, int);
970 static int rs6000_register_move_cost (enum machine_mode,
971 reg_class_t, reg_class_t);
972 static int rs6000_memory_move_cost (enum machine_mode, reg_class_t, bool);
973 static bool rs6000_rtx_costs (rtx, int, int, int *, bool);
974 static bool rs6000_debug_rtx_costs (rtx, int, int, int *, bool);
975 static int rs6000_debug_address_cost (rtx, bool);
976 static int rs6000_adjust_cost (rtx, rtx, rtx, int);
977 static int rs6000_debug_adjust_cost (rtx, rtx, rtx, int);
978 static void rs6000_sched_init (FILE *, int, int);
979 static bool is_microcoded_insn (rtx);
980 static bool is_nonpipeline_insn (rtx);
981 static bool is_cracked_insn (rtx);
982 static bool is_branch_slot_insn (rtx);
983 static bool is_load_insn (rtx);
984 static rtx get_store_dest (rtx pat);
985 static bool is_store_insn (rtx);
986 static bool set_to_load_agen (rtx,rtx);
987 static bool adjacent_mem_locations (rtx,rtx);
988 static int rs6000_adjust_priority (rtx, int);
989 static int rs6000_issue_rate (void);
990 static bool rs6000_is_costly_dependence (dep_t, int, int);
991 static rtx get_next_active_insn (rtx, rtx);
992 static bool insn_terminates_group_p (rtx , enum group_termination);
993 static bool insn_must_be_first_in_group (rtx);
994 static bool insn_must_be_last_in_group (rtx);
995 static bool is_costly_group (rtx *, rtx);
996 static int force_new_group (int, FILE *, rtx *, rtx, bool *, int, int *);
997 static int redefine_groups (FILE *, int, rtx, rtx);
998 static int pad_groups (FILE *, int, rtx, rtx);
999 static void rs6000_sched_finish (FILE *, int);
1000 static int rs6000_sched_reorder (FILE *, int, rtx *, int *, int);
1001 static int rs6000_sched_reorder2 (FILE *, int, rtx *, int *, int);
1002 static int rs6000_use_sched_lookahead (void);
1003 static int rs6000_use_sched_lookahead_guard (rtx);
1004 static void * rs6000_alloc_sched_context (void);
1005 static void rs6000_init_sched_context (void *, bool);
1006 static void rs6000_set_sched_context (void *);
1007 static void rs6000_free_sched_context (void *);
1008 static tree rs6000_builtin_reciprocal (unsigned int, bool, bool);
1009 static tree rs6000_builtin_mask_for_load (void);
1010 static tree rs6000_builtin_mul_widen_even (tree);
1011 static tree rs6000_builtin_mul_widen_odd (tree);
1012 static tree rs6000_builtin_conversion (unsigned int, tree, tree);
1013 static tree rs6000_builtin_vec_perm (tree, tree *);
1014 static bool rs6000_builtin_support_vector_misalignment (enum
1015 machine_mode,
1016 const_tree,
1017 int, bool);
1018 static int rs6000_builtin_vectorization_cost (enum vect_cost_for_stmt,
1019 tree, int);
1020 static enum machine_mode rs6000_preferred_simd_mode (enum machine_mode);
1022 static void def_builtin (int, const char *, tree, int);
1023 static bool rs6000_vector_alignment_reachable (const_tree, bool);
1024 static void rs6000_init_builtins (void);
1025 static tree rs6000_builtin_decl (unsigned, bool);
1027 static rtx rs6000_expand_unop_builtin (enum insn_code, tree, rtx);
1028 static rtx rs6000_expand_binop_builtin (enum insn_code, tree, rtx);
1029 static rtx rs6000_expand_ternop_builtin (enum insn_code, tree, rtx);
1030 static rtx rs6000_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
1031 static void altivec_init_builtins (void);
1032 static unsigned builtin_hash_function (const void *);
1033 static int builtin_hash_eq (const void *, const void *);
1034 static tree builtin_function_type (enum machine_mode, enum machine_mode,
1035 enum machine_mode, enum machine_mode,
1036 enum rs6000_builtins, const char *name);
1037 static void rs6000_common_init_builtins (void);
1038 static void rs6000_init_libfuncs (void);
1040 static void paired_init_builtins (void);
1041 static rtx paired_expand_builtin (tree, rtx, bool *);
1042 static rtx paired_expand_lv_builtin (enum insn_code, tree, rtx);
1043 static rtx paired_expand_stv_builtin (enum insn_code, tree);
1044 static rtx paired_expand_predicate_builtin (enum insn_code, tree, rtx);
1046 static void enable_mask_for_builtins (struct builtin_description *, int,
1047 enum rs6000_builtins,
1048 enum rs6000_builtins);
1049 static void spe_init_builtins (void);
1050 static rtx spe_expand_builtin (tree, rtx, bool *);
1051 static rtx spe_expand_stv_builtin (enum insn_code, tree);
1052 static rtx spe_expand_predicate_builtin (enum insn_code, tree, rtx);
1053 static rtx spe_expand_evsel_builtin (enum insn_code, tree, rtx);
1054 static int rs6000_emit_int_cmove (rtx, rtx, rtx, rtx);
1055 static rs6000_stack_t *rs6000_stack_info (void);
1056 static void debug_stack_info (rs6000_stack_t *);
1058 static rtx altivec_expand_builtin (tree, rtx, bool *);
1059 static rtx altivec_expand_ld_builtin (tree, rtx, bool *);
1060 static rtx altivec_expand_st_builtin (tree, rtx, bool *);
1061 static rtx altivec_expand_dst_builtin (tree, rtx, bool *);
1062 static rtx altivec_expand_abs_builtin (enum insn_code, tree, rtx);
1063 static rtx altivec_expand_predicate_builtin (enum insn_code, tree, rtx);
1064 static rtx altivec_expand_stv_builtin (enum insn_code, tree);
1065 static rtx altivec_expand_vec_init_builtin (tree, tree, rtx);
1066 static rtx altivec_expand_vec_set_builtin (tree);
1067 static rtx altivec_expand_vec_ext_builtin (tree, rtx);
1068 static int get_element_number (tree, tree);
1069 static void rs6000_option_override (void);
1070 static void rs6000_option_init_struct (struct gcc_options *);
1071 static void rs6000_option_default_params (void);
1072 static bool rs6000_handle_option (size_t, const char *, int);
1073 static int rs6000_loop_align_max_skip (rtx);
1074 static void rs6000_parse_yes_no_option (const char *, const char *, int *);
1075 static int first_altivec_reg_to_save (void);
1076 static unsigned int compute_vrsave_mask (void);
1077 static void compute_save_world_info (rs6000_stack_t *info_ptr);
1078 static void is_altivec_return_reg (rtx, void *);
1079 static rtx generate_set_vrsave (rtx, rs6000_stack_t *, int);
1080 int easy_vector_constant (rtx, enum machine_mode);
1081 static rtx rs6000_dwarf_register_span (rtx);
1082 static void rs6000_init_dwarf_reg_sizes_extra (tree);
1083 static rtx rs6000_legitimize_address (rtx, rtx, enum machine_mode);
1084 static rtx rs6000_debug_legitimize_address (rtx, rtx, enum machine_mode);
1085 static rtx rs6000_legitimize_tls_address (rtx, enum tls_model);
1086 static void rs6000_output_dwarf_dtprel (FILE *, int, rtx) ATTRIBUTE_UNUSED;
1087 static rtx rs6000_delegitimize_address (rtx);
1088 static rtx rs6000_tls_get_addr (void);
1089 static rtx rs6000_got_sym (void);
1090 static int rs6000_tls_symbol_ref_1 (rtx *, void *);
1091 static const char *rs6000_get_some_local_dynamic_name (void);
1092 static int rs6000_get_some_local_dynamic_name_1 (rtx *, void *);
1093 static rtx rs6000_complex_function_value (enum machine_mode);
1094 static rtx rs6000_spe_function_arg (const CUMULATIVE_ARGS *,
1095 enum machine_mode, const_tree);
1096 static void rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS *,
1097 HOST_WIDE_INT, int);
1098 static void rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS *,
1099 const_tree,
1100 HOST_WIDE_INT);
1101 static void rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS *,
1102 HOST_WIDE_INT,
1103 rtx[], int *);
1104 static void rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *,
1105 const_tree, HOST_WIDE_INT,
1106 rtx[], int *);
1107 static rtx rs6000_darwin64_record_arg (CUMULATIVE_ARGS *, const_tree, bool, bool);
1108 static rtx rs6000_mixed_function_arg (enum machine_mode, const_tree, int);
1109 static void rs6000_function_arg_advance (CUMULATIVE_ARGS *, enum machine_mode,
1110 const_tree, bool);
1111 static rtx rs6000_function_arg (CUMULATIVE_ARGS *, enum machine_mode,
1112 const_tree, bool);
1113 static unsigned int rs6000_function_arg_boundary (enum machine_mode,
1114 const_tree);
1115 static void rs6000_move_block_from_reg (int regno, rtx x, int nregs);
1116 static void setup_incoming_varargs (CUMULATIVE_ARGS *,
1117 enum machine_mode, tree,
1118 int *, int);
1119 static bool rs6000_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode,
1120 const_tree, bool);
1121 static int rs6000_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode,
1122 tree, bool);
1123 static const char *invalid_arg_for_unprototyped_fn (const_tree, const_tree, const_tree);
1124 #if TARGET_MACHO
1125 static void macho_branch_islands (void);
1126 static int no_previous_def (tree function_name);
1127 static tree get_prev_label (tree function_name);
1128 static void rs6000_darwin_file_start (void);
1129 #endif
1131 static tree rs6000_build_builtin_va_list (void);
1132 static void rs6000_va_start (tree, rtx);
1133 static tree rs6000_gimplify_va_arg (tree, tree, gimple_seq *, gimple_seq *);
1134 static bool rs6000_must_pass_in_stack (enum machine_mode, const_tree);
1135 static bool rs6000_scalar_mode_supported_p (enum machine_mode);
1136 static bool rs6000_vector_mode_supported_p (enum machine_mode);
1137 static rtx rs6000_emit_vector_compare_inner (enum rtx_code, rtx, rtx);
1138 static rtx rs6000_emit_vector_compare (enum rtx_code, rtx, rtx,
1139 enum machine_mode);
1140 static tree rs6000_stack_protect_fail (void);
1142 static rtx rs6000_legitimize_reload_address (rtx, enum machine_mode, int, int,
1143 int, int *);
1145 static rtx rs6000_debug_legitimize_reload_address (rtx, enum machine_mode, int,
1146 int, int, int *);
1148 rtx (*rs6000_legitimize_reload_address_ptr) (rtx, enum machine_mode, int, int,
1149 int, int *)
1150 = rs6000_legitimize_reload_address;
1152 static bool rs6000_mode_dependent_address_p (const_rtx);
1153 static bool rs6000_mode_dependent_address (const_rtx);
1154 static bool rs6000_debug_mode_dependent_address (const_rtx);
1155 static bool (*rs6000_mode_dependent_address_ptr) (const_rtx)
1156 = rs6000_mode_dependent_address;
1158 static enum reg_class rs6000_secondary_reload_class (enum reg_class,
1159 enum machine_mode, rtx);
1160 static enum reg_class rs6000_debug_secondary_reload_class (enum reg_class,
1161 enum machine_mode,
1162 rtx);
1163 enum reg_class (*rs6000_secondary_reload_class_ptr) (enum reg_class,
1164 enum machine_mode, rtx)
1165 = rs6000_secondary_reload_class;
1167 static enum reg_class rs6000_preferred_reload_class (rtx, enum reg_class);
1168 static enum reg_class rs6000_debug_preferred_reload_class (rtx,
1169 enum reg_class);
1170 enum reg_class (*rs6000_preferred_reload_class_ptr) (rtx, enum reg_class)
1171 = rs6000_preferred_reload_class;
1173 static bool rs6000_secondary_memory_needed (enum reg_class, enum reg_class,
1174 enum machine_mode);
1176 static bool rs6000_debug_secondary_memory_needed (enum reg_class,
1177 enum reg_class,
1178 enum machine_mode);
1180 bool (*rs6000_secondary_memory_needed_ptr) (enum reg_class, enum reg_class,
1181 enum machine_mode)
1182 = rs6000_secondary_memory_needed;
1184 static bool rs6000_cannot_change_mode_class (enum machine_mode,
1185 enum machine_mode,
1186 enum reg_class);
1187 static bool rs6000_debug_cannot_change_mode_class (enum machine_mode,
1188 enum machine_mode,
1189 enum reg_class);
1191 bool (*rs6000_cannot_change_mode_class_ptr) (enum machine_mode,
1192 enum machine_mode,
1193 enum reg_class)
1194 = rs6000_cannot_change_mode_class;
1196 static reg_class_t rs6000_secondary_reload (bool, rtx, reg_class_t,
1197 enum machine_mode,
1198 struct secondary_reload_info *);
1200 static const reg_class_t *rs6000_ira_cover_classes (void);
1202 const int INSN_NOT_AVAILABLE = -1;
1203 static enum machine_mode rs6000_eh_return_filter_mode (void);
1204 static bool rs6000_can_eliminate (const int, const int);
1205 static void rs6000_conditional_register_usage (void);
1206 static void rs6000_trampoline_init (rtx, tree, rtx);
1208 /* Hash table stuff for keeping track of TOC entries. */
1210 struct GTY(()) toc_hash_struct
1212 /* `key' will satisfy CONSTANT_P; in fact, it will satisfy
1213 ASM_OUTPUT_SPECIAL_POOL_ENTRY_P. */
1214 rtx key;
1215 enum machine_mode key_mode;
1216 int labelno;
1219 static GTY ((param_is (struct toc_hash_struct))) htab_t toc_hash_table;
1221 /* Hash table to keep track of the argument types for builtin functions. */
1223 struct GTY(()) builtin_hash_struct
1225 tree type;
1226 enum machine_mode mode[4]; /* return value + 3 arguments. */
1227 unsigned char uns_p[4]; /* and whether the types are unsigned. */
1230 static GTY ((param_is (struct builtin_hash_struct))) htab_t builtin_hash_table;
1232 static bool rs6000_valid_attribute_p (tree, tree, tree, int);
1233 static void rs6000_function_specific_save (struct cl_target_option *);
1234 static void rs6000_function_specific_restore (struct cl_target_option *);
1235 static void rs6000_function_specific_print (FILE *, int,
1236 struct cl_target_option *);
1237 static bool rs6000_can_inline_p (tree, tree);
1238 static void rs6000_set_current_function (tree);
1241 /* Default register names. */
1242 char rs6000_reg_names[][8] =
1244 "0", "1", "2", "3", "4", "5", "6", "7",
1245 "8", "9", "10", "11", "12", "13", "14", "15",
1246 "16", "17", "18", "19", "20", "21", "22", "23",
1247 "24", "25", "26", "27", "28", "29", "30", "31",
1248 "0", "1", "2", "3", "4", "5", "6", "7",
1249 "8", "9", "10", "11", "12", "13", "14", "15",
1250 "16", "17", "18", "19", "20", "21", "22", "23",
1251 "24", "25", "26", "27", "28", "29", "30", "31",
1252 "mq", "lr", "ctr","ap",
1253 "0", "1", "2", "3", "4", "5", "6", "7",
1254 "ca",
1255 /* AltiVec registers. */
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 "vrsave", "vscr",
1261 /* SPE registers. */
1262 "spe_acc", "spefscr",
1263 /* Soft frame pointer. */
1264 "sfp"
1267 #ifdef TARGET_REGNAMES
1268 static const char alt_reg_names[][8] =
1270 "%r0", "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7",
1271 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15",
1272 "%r16", "%r17", "%r18", "%r19", "%r20", "%r21", "%r22", "%r23",
1273 "%r24", "%r25", "%r26", "%r27", "%r28", "%r29", "%r30", "%r31",
1274 "%f0", "%f1", "%f2", "%f3", "%f4", "%f5", "%f6", "%f7",
1275 "%f8", "%f9", "%f10", "%f11", "%f12", "%f13", "%f14", "%f15",
1276 "%f16", "%f17", "%f18", "%f19", "%f20", "%f21", "%f22", "%f23",
1277 "%f24", "%f25", "%f26", "%f27", "%f28", "%f29", "%f30", "%f31",
1278 "mq", "lr", "ctr", "ap",
1279 "%cr0", "%cr1", "%cr2", "%cr3", "%cr4", "%cr5", "%cr6", "%cr7",
1280 "ca",
1281 /* AltiVec registers. */
1282 "%v0", "%v1", "%v2", "%v3", "%v4", "%v5", "%v6", "%v7",
1283 "%v8", "%v9", "%v10", "%v11", "%v12", "%v13", "%v14", "%v15",
1284 "%v16", "%v17", "%v18", "%v19", "%v20", "%v21", "%v22", "%v23",
1285 "%v24", "%v25", "%v26", "%v27", "%v28", "%v29", "%v30", "%v31",
1286 "vrsave", "vscr",
1287 /* SPE registers. */
1288 "spe_acc", "spefscr",
1289 /* Soft frame pointer. */
1290 "sfp"
1292 #endif
1294 /* Table of valid machine attributes. */
1296 static const struct attribute_spec rs6000_attribute_table[] =
1298 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
1299 { "altivec", 1, 1, false, true, false, rs6000_handle_altivec_attribute },
1300 { "longcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute },
1301 { "shortcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute },
1302 { "ms_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute },
1303 { "gcc_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute },
1304 #ifdef SUBTARGET_ATTRIBUTE_TABLE
1305 SUBTARGET_ATTRIBUTE_TABLE,
1306 #endif
1307 { NULL, 0, 0, false, false, false, NULL }
1310 /* Implement TARGET_OPTION_OPTIMIZATION_TABLE. */
1311 static const struct default_options rs6000_option_optimization_table[] =
1313 { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 },
1314 { OPT_LEVELS_NONE, 0, NULL, 0 }
1317 #ifndef MASK_STRICT_ALIGN
1318 #define MASK_STRICT_ALIGN 0
1319 #endif
1320 #ifndef TARGET_PROFILE_KERNEL
1321 #define TARGET_PROFILE_KERNEL 0
1322 #endif
1324 /* The VRSAVE bitmask puts bit %v0 as the most significant bit. */
1325 #define ALTIVEC_REG_BIT(REGNO) (0x80000000 >> ((REGNO) - FIRST_ALTIVEC_REGNO))
1327 /* Initialize the GCC target structure. */
1328 #undef TARGET_ATTRIBUTE_TABLE
1329 #define TARGET_ATTRIBUTE_TABLE rs6000_attribute_table
1330 #undef TARGET_SET_DEFAULT_TYPE_ATTRIBUTES
1331 #define TARGET_SET_DEFAULT_TYPE_ATTRIBUTES rs6000_set_default_type_attributes
1332 #undef TARGET_ATTRIBUTE_TAKES_IDENTIFIER_P
1333 #define TARGET_ATTRIBUTE_TAKES_IDENTIFIER_P rs6000_attribute_takes_identifier_p
1335 #undef TARGET_ASM_ALIGNED_DI_OP
1336 #define TARGET_ASM_ALIGNED_DI_OP DOUBLE_INT_ASM_OP
1338 /* Default unaligned ops are only provided for ELF. Find the ops needed
1339 for non-ELF systems. */
1340 #ifndef OBJECT_FORMAT_ELF
1341 #if TARGET_XCOFF
1342 /* For XCOFF. rs6000_assemble_integer will handle unaligned DIs on
1343 64-bit targets. */
1344 #undef TARGET_ASM_UNALIGNED_HI_OP
1345 #define TARGET_ASM_UNALIGNED_HI_OP "\t.vbyte\t2,"
1346 #undef TARGET_ASM_UNALIGNED_SI_OP
1347 #define TARGET_ASM_UNALIGNED_SI_OP "\t.vbyte\t4,"
1348 #undef TARGET_ASM_UNALIGNED_DI_OP
1349 #define TARGET_ASM_UNALIGNED_DI_OP "\t.vbyte\t8,"
1350 #else
1351 /* For Darwin. */
1352 #undef TARGET_ASM_UNALIGNED_HI_OP
1353 #define TARGET_ASM_UNALIGNED_HI_OP "\t.short\t"
1354 #undef TARGET_ASM_UNALIGNED_SI_OP
1355 #define TARGET_ASM_UNALIGNED_SI_OP "\t.long\t"
1356 #undef TARGET_ASM_UNALIGNED_DI_OP
1357 #define TARGET_ASM_UNALIGNED_DI_OP "\t.quad\t"
1358 #undef TARGET_ASM_ALIGNED_DI_OP
1359 #define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t"
1360 #endif
1361 #endif
1363 /* This hook deals with fixups for relocatable code and DI-mode objects
1364 in 64-bit code. */
1365 #undef TARGET_ASM_INTEGER
1366 #define TARGET_ASM_INTEGER rs6000_assemble_integer
1368 #ifdef HAVE_GAS_HIDDEN
1369 #undef TARGET_ASM_ASSEMBLE_VISIBILITY
1370 #define TARGET_ASM_ASSEMBLE_VISIBILITY rs6000_assemble_visibility
1371 #endif
1373 #undef TARGET_HAVE_TLS
1374 #define TARGET_HAVE_TLS HAVE_AS_TLS
1376 #undef TARGET_CANNOT_FORCE_CONST_MEM
1377 #define TARGET_CANNOT_FORCE_CONST_MEM rs6000_tls_referenced_p
1379 #undef TARGET_DELEGITIMIZE_ADDRESS
1380 #define TARGET_DELEGITIMIZE_ADDRESS rs6000_delegitimize_address
1382 #undef TARGET_ASM_FUNCTION_PROLOGUE
1383 #define TARGET_ASM_FUNCTION_PROLOGUE rs6000_output_function_prologue
1384 #undef TARGET_ASM_FUNCTION_EPILOGUE
1385 #define TARGET_ASM_FUNCTION_EPILOGUE rs6000_output_function_epilogue
1387 #undef TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA
1388 #define TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA rs6000_output_addr_const_extra
1390 #undef TARGET_LEGITIMIZE_ADDRESS
1391 #define TARGET_LEGITIMIZE_ADDRESS rs6000_legitimize_address
1393 #undef TARGET_SCHED_VARIABLE_ISSUE
1394 #define TARGET_SCHED_VARIABLE_ISSUE rs6000_variable_issue
1396 #undef TARGET_SCHED_ISSUE_RATE
1397 #define TARGET_SCHED_ISSUE_RATE rs6000_issue_rate
1398 #undef TARGET_SCHED_ADJUST_COST
1399 #define TARGET_SCHED_ADJUST_COST rs6000_adjust_cost
1400 #undef TARGET_SCHED_ADJUST_PRIORITY
1401 #define TARGET_SCHED_ADJUST_PRIORITY rs6000_adjust_priority
1402 #undef TARGET_SCHED_IS_COSTLY_DEPENDENCE
1403 #define TARGET_SCHED_IS_COSTLY_DEPENDENCE rs6000_is_costly_dependence
1404 #undef TARGET_SCHED_INIT
1405 #define TARGET_SCHED_INIT rs6000_sched_init
1406 #undef TARGET_SCHED_FINISH
1407 #define TARGET_SCHED_FINISH rs6000_sched_finish
1408 #undef TARGET_SCHED_REORDER
1409 #define TARGET_SCHED_REORDER rs6000_sched_reorder
1410 #undef TARGET_SCHED_REORDER2
1411 #define TARGET_SCHED_REORDER2 rs6000_sched_reorder2
1413 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
1414 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD rs6000_use_sched_lookahead
1416 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD
1417 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD rs6000_use_sched_lookahead_guard
1419 #undef TARGET_SCHED_ALLOC_SCHED_CONTEXT
1420 #define TARGET_SCHED_ALLOC_SCHED_CONTEXT rs6000_alloc_sched_context
1421 #undef TARGET_SCHED_INIT_SCHED_CONTEXT
1422 #define TARGET_SCHED_INIT_SCHED_CONTEXT rs6000_init_sched_context
1423 #undef TARGET_SCHED_SET_SCHED_CONTEXT
1424 #define TARGET_SCHED_SET_SCHED_CONTEXT rs6000_set_sched_context
1425 #undef TARGET_SCHED_FREE_SCHED_CONTEXT
1426 #define TARGET_SCHED_FREE_SCHED_CONTEXT rs6000_free_sched_context
1428 #undef TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD
1429 #define TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD rs6000_builtin_mask_for_load
1430 #undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN
1431 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN rs6000_builtin_mul_widen_even
1432 #undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD
1433 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD rs6000_builtin_mul_widen_odd
1434 #undef TARGET_VECTORIZE_BUILTIN_CONVERSION
1435 #define TARGET_VECTORIZE_BUILTIN_CONVERSION rs6000_builtin_conversion
1436 #undef TARGET_VECTORIZE_BUILTIN_VEC_PERM
1437 #define TARGET_VECTORIZE_BUILTIN_VEC_PERM rs6000_builtin_vec_perm
1438 #undef TARGET_VECTORIZE_SUPPORT_VECTOR_MISALIGNMENT
1439 #define TARGET_VECTORIZE_SUPPORT_VECTOR_MISALIGNMENT \
1440 rs6000_builtin_support_vector_misalignment
1441 #undef TARGET_VECTORIZE_VECTOR_ALIGNMENT_REACHABLE
1442 #define TARGET_VECTORIZE_VECTOR_ALIGNMENT_REACHABLE rs6000_vector_alignment_reachable
1443 #undef TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST
1444 #define TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST \
1445 rs6000_builtin_vectorization_cost
1446 #undef TARGET_VECTORIZE_PREFERRED_SIMD_MODE
1447 #define TARGET_VECTORIZE_PREFERRED_SIMD_MODE \
1448 rs6000_preferred_simd_mode
1450 #undef TARGET_INIT_BUILTINS
1451 #define TARGET_INIT_BUILTINS rs6000_init_builtins
1452 #undef TARGET_BUILTIN_DECL
1453 #define TARGET_BUILTIN_DECL rs6000_builtin_decl
1455 #undef TARGET_EXPAND_BUILTIN
1456 #define TARGET_EXPAND_BUILTIN rs6000_expand_builtin
1458 #undef TARGET_MANGLE_TYPE
1459 #define TARGET_MANGLE_TYPE rs6000_mangle_type
1461 #undef TARGET_INIT_LIBFUNCS
1462 #define TARGET_INIT_LIBFUNCS rs6000_init_libfuncs
1464 #if TARGET_MACHO
1465 #undef TARGET_BINDS_LOCAL_P
1466 #define TARGET_BINDS_LOCAL_P darwin_binds_local_p
1467 #endif
1469 #undef TARGET_MS_BITFIELD_LAYOUT_P
1470 #define TARGET_MS_BITFIELD_LAYOUT_P rs6000_ms_bitfield_layout_p
1472 #undef TARGET_ASM_OUTPUT_MI_THUNK
1473 #define TARGET_ASM_OUTPUT_MI_THUNK rs6000_output_mi_thunk
1475 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
1476 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true
1478 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
1479 #define TARGET_FUNCTION_OK_FOR_SIBCALL rs6000_function_ok_for_sibcall
1481 #undef TARGET_INVALID_WITHIN_DOLOOP
1482 #define TARGET_INVALID_WITHIN_DOLOOP rs6000_invalid_within_doloop
1484 #undef TARGET_REGISTER_MOVE_COST
1485 #define TARGET_REGISTER_MOVE_COST rs6000_register_move_cost
1486 #undef TARGET_MEMORY_MOVE_COST
1487 #define TARGET_MEMORY_MOVE_COST rs6000_memory_move_cost
1488 #undef TARGET_RTX_COSTS
1489 #define TARGET_RTX_COSTS rs6000_rtx_costs
1490 #undef TARGET_ADDRESS_COST
1491 #define TARGET_ADDRESS_COST hook_int_rtx_bool_0
1493 #undef TARGET_DWARF_REGISTER_SPAN
1494 #define TARGET_DWARF_REGISTER_SPAN rs6000_dwarf_register_span
1496 #undef TARGET_INIT_DWARF_REG_SIZES_EXTRA
1497 #define TARGET_INIT_DWARF_REG_SIZES_EXTRA rs6000_init_dwarf_reg_sizes_extra
1499 /* On rs6000, function arguments are promoted, as are function return
1500 values. */
1501 #undef TARGET_PROMOTE_FUNCTION_MODE
1502 #define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote
1504 #undef TARGET_RETURN_IN_MEMORY
1505 #define TARGET_RETURN_IN_MEMORY rs6000_return_in_memory
1507 #undef TARGET_SETUP_INCOMING_VARARGS
1508 #define TARGET_SETUP_INCOMING_VARARGS setup_incoming_varargs
1510 /* Always strict argument naming on rs6000. */
1511 #undef TARGET_STRICT_ARGUMENT_NAMING
1512 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
1513 #undef TARGET_PRETEND_OUTGOING_VARARGS_NAMED
1514 #define TARGET_PRETEND_OUTGOING_VARARGS_NAMED hook_bool_CUMULATIVE_ARGS_true
1515 #undef TARGET_SPLIT_COMPLEX_ARG
1516 #define TARGET_SPLIT_COMPLEX_ARG hook_bool_const_tree_true
1517 #undef TARGET_MUST_PASS_IN_STACK
1518 #define TARGET_MUST_PASS_IN_STACK rs6000_must_pass_in_stack
1519 #undef TARGET_PASS_BY_REFERENCE
1520 #define TARGET_PASS_BY_REFERENCE rs6000_pass_by_reference
1521 #undef TARGET_ARG_PARTIAL_BYTES
1522 #define TARGET_ARG_PARTIAL_BYTES rs6000_arg_partial_bytes
1523 #undef TARGET_FUNCTION_ARG_ADVANCE
1524 #define TARGET_FUNCTION_ARG_ADVANCE rs6000_function_arg_advance
1525 #undef TARGET_FUNCTION_ARG
1526 #define TARGET_FUNCTION_ARG rs6000_function_arg
1527 #undef TARGET_FUNCTION_ARG_BOUNDARY
1528 #define TARGET_FUNCTION_ARG_BOUNDARY rs6000_function_arg_boundary
1530 #undef TARGET_BUILD_BUILTIN_VA_LIST
1531 #define TARGET_BUILD_BUILTIN_VA_LIST rs6000_build_builtin_va_list
1533 #undef TARGET_EXPAND_BUILTIN_VA_START
1534 #define TARGET_EXPAND_BUILTIN_VA_START rs6000_va_start
1536 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
1537 #define TARGET_GIMPLIFY_VA_ARG_EXPR rs6000_gimplify_va_arg
1539 #undef TARGET_EH_RETURN_FILTER_MODE
1540 #define TARGET_EH_RETURN_FILTER_MODE rs6000_eh_return_filter_mode
1542 #undef TARGET_SCALAR_MODE_SUPPORTED_P
1543 #define TARGET_SCALAR_MODE_SUPPORTED_P rs6000_scalar_mode_supported_p
1545 #undef TARGET_VECTOR_MODE_SUPPORTED_P
1546 #define TARGET_VECTOR_MODE_SUPPORTED_P rs6000_vector_mode_supported_p
1548 #undef TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN
1549 #define TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN invalid_arg_for_unprototyped_fn
1551 #undef TARGET_HANDLE_OPTION
1552 #define TARGET_HANDLE_OPTION rs6000_handle_option
1554 #undef TARGET_ASM_LOOP_ALIGN_MAX_SKIP
1555 #define TARGET_ASM_LOOP_ALIGN_MAX_SKIP rs6000_loop_align_max_skip
1557 #undef TARGET_OPTION_OVERRIDE
1558 #define TARGET_OPTION_OVERRIDE rs6000_option_override
1560 #undef TARGET_OPTION_INIT_STRUCT
1561 #define TARGET_OPTION_INIT_STRUCT rs6000_option_init_struct
1563 #undef TARGET_OPTION_DEFAULT_PARAMS
1564 #define TARGET_OPTION_DEFAULT_PARAMS rs6000_option_default_params
1566 #undef TARGET_OPTION_OPTIMIZATION_TABLE
1567 #define TARGET_OPTION_OPTIMIZATION_TABLE rs6000_option_optimization_table
1569 #undef TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION
1570 #define TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION \
1571 rs6000_builtin_vectorized_function
1573 #undef TARGET_DEFAULT_TARGET_FLAGS
1574 #define TARGET_DEFAULT_TARGET_FLAGS \
1575 (TARGET_DEFAULT)
1577 #undef TARGET_STACK_PROTECT_FAIL
1578 #define TARGET_STACK_PROTECT_FAIL rs6000_stack_protect_fail
1580 /* MPC604EUM 3.5.2 Weak Consistency between Multiple Processors
1581 The PowerPC architecture requires only weak consistency among
1582 processors--that is, memory accesses between processors need not be
1583 sequentially consistent and memory accesses among processors can occur
1584 in any order. The ability to order memory accesses weakly provides
1585 opportunities for more efficient use of the system bus. Unless a
1586 dependency exists, the 604e allows read operations to precede store
1587 operations. */
1588 #undef TARGET_RELAXED_ORDERING
1589 #define TARGET_RELAXED_ORDERING true
1591 #ifdef HAVE_AS_TLS
1592 #undef TARGET_ASM_OUTPUT_DWARF_DTPREL
1593 #define TARGET_ASM_OUTPUT_DWARF_DTPREL rs6000_output_dwarf_dtprel
1594 #endif
1596 /* Use a 32-bit anchor range. This leads to sequences like:
1598 addis tmp,anchor,high
1599 add dest,tmp,low
1601 where tmp itself acts as an anchor, and can be shared between
1602 accesses to the same 64k page. */
1603 #undef TARGET_MIN_ANCHOR_OFFSET
1604 #define TARGET_MIN_ANCHOR_OFFSET -0x7fffffff - 1
1605 #undef TARGET_MAX_ANCHOR_OFFSET
1606 #define TARGET_MAX_ANCHOR_OFFSET 0x7fffffff
1607 #undef TARGET_USE_BLOCKS_FOR_CONSTANT_P
1608 #define TARGET_USE_BLOCKS_FOR_CONSTANT_P rs6000_use_blocks_for_constant_p
1610 #undef TARGET_BUILTIN_RECIPROCAL
1611 #define TARGET_BUILTIN_RECIPROCAL rs6000_builtin_reciprocal
1613 #undef TARGET_EXPAND_TO_RTL_HOOK
1614 #define TARGET_EXPAND_TO_RTL_HOOK rs6000_alloc_sdmode_stack_slot
1616 #undef TARGET_INSTANTIATE_DECLS
1617 #define TARGET_INSTANTIATE_DECLS rs6000_instantiate_decls
1619 #undef TARGET_SECONDARY_RELOAD
1620 #define TARGET_SECONDARY_RELOAD rs6000_secondary_reload
1622 #undef TARGET_IRA_COVER_CLASSES
1623 #define TARGET_IRA_COVER_CLASSES rs6000_ira_cover_classes
1625 #undef TARGET_LEGITIMATE_ADDRESS_P
1626 #define TARGET_LEGITIMATE_ADDRESS_P rs6000_legitimate_address_p
1628 #undef TARGET_MODE_DEPENDENT_ADDRESS_P
1629 #define TARGET_MODE_DEPENDENT_ADDRESS_P rs6000_mode_dependent_address_p
1631 #undef TARGET_CAN_ELIMINATE
1632 #define TARGET_CAN_ELIMINATE rs6000_can_eliminate
1634 #undef TARGET_CONDITIONAL_REGISTER_USAGE
1635 #define TARGET_CONDITIONAL_REGISTER_USAGE rs6000_conditional_register_usage
1637 #undef TARGET_TRAMPOLINE_INIT
1638 #define TARGET_TRAMPOLINE_INIT rs6000_trampoline_init
1640 #undef TARGET_FUNCTION_VALUE
1641 #define TARGET_FUNCTION_VALUE rs6000_function_value
1643 #undef TARGET_OPTION_VALID_ATTRIBUTE_P
1644 #define TARGET_OPTION_VALID_ATTRIBUTE_P rs6000_valid_attribute_p
1646 #undef TARGET_OPTION_SAVE
1647 #define TARGET_OPTION_SAVE rs6000_function_specific_save
1649 #undef TARGET_OPTION_RESTORE
1650 #define TARGET_OPTION_RESTORE rs6000_function_specific_restore
1652 #undef TARGET_OPTION_PRINT
1653 #define TARGET_OPTION_PRINT rs6000_function_specific_print
1655 #undef TARGET_CAN_INLINE_P
1656 #define TARGET_CAN_INLINE_P rs6000_can_inline_p
1658 #undef TARGET_SET_CURRENT_FUNCTION
1659 #define TARGET_SET_CURRENT_FUNCTION rs6000_set_current_function
1661 struct gcc_target targetm = TARGET_INITIALIZER;
1664 /* Simplifications for entries below. */
1666 enum {
1667 POWERPC_BASE_MASK = MASK_POWERPC | MASK_NEW_MNEMONICS,
1668 POWERPC_7400_MASK = POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_ALTIVEC
1671 /* Some OSs don't support saving the high part of 64-bit registers on context
1672 switch. Other OSs don't support saving Altivec registers. On those OSs, we
1673 don't touch the MASK_POWERPC64 or MASK_ALTIVEC settings; if the user wants
1674 either, the user must explicitly specify them and we won't interfere with
1675 the user's specification. */
1677 enum {
1678 POWER_MASKS = MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING,
1679 POWERPC_MASKS = (POWERPC_BASE_MASK | MASK_PPC_GPOPT | MASK_STRICT_ALIGN
1680 | MASK_PPC_GFXOPT | MASK_POWERPC64 | MASK_ALTIVEC
1681 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_MULHW
1682 | MASK_DLMZB | MASK_CMPB | MASK_MFPGPR | MASK_DFP
1683 | MASK_POPCNTD | MASK_VSX | MASK_ISEL | MASK_NO_UPDATE
1684 | MASK_RECIP_PRECISION)
1687 /* Masks for instructions set at various powerpc ISAs. */
1688 enum {
1689 ISA_2_1_MASKS = MASK_MFCRF,
1690 ISA_2_2_MASKS = (ISA_2_1_MASKS | MASK_POPCNTB),
1691 ISA_2_4_MASKS = (ISA_2_2_MASKS | MASK_FPRND),
1693 /* For ISA 2.05, do not add MFPGPR, since it isn't in ISA 2.06, and don't add
1694 ALTIVEC, since in general it isn't a win on power6. In ISA 2.04, fsel,
1695 fre, fsqrt, etc. were no longer documented as optional. Group masks by
1696 server and embedded. */
1697 ISA_2_5_MASKS_EMBEDDED = (ISA_2_2_MASKS | MASK_CMPB | MASK_RECIP_PRECISION
1698 | MASK_PPC_GFXOPT | MASK_PPC_GPOPT),
1699 ISA_2_5_MASKS_SERVER = (ISA_2_5_MASKS_EMBEDDED | MASK_DFP),
1701 /* For ISA 2.06, don't add ISEL, since in general it isn't a win, but
1702 altivec is a win so enable it. */
1703 ISA_2_6_MASKS_EMBEDDED = (ISA_2_5_MASKS_EMBEDDED | MASK_POPCNTD),
1704 ISA_2_6_MASKS_SERVER = (ISA_2_5_MASKS_SERVER | MASK_POPCNTD | MASK_ALTIVEC
1705 | MASK_VSX)
1708 /* This table occasionally claims that a processor does not support a
1709 particular feature even though it does, but the feature is slower than the
1710 alternative. Thus, it shouldn't be relied on as a complete description of
1711 the processor's support.
1713 Please keep this list in order, and don't forget to update the documentation
1714 in invoke.texi when adding a new processor or flag. */
1716 struct rs6000_ptt
1718 const char *const name; /* Canonical processor name. */
1719 const enum processor_type processor; /* Processor type enum value. */
1720 const int target_enable; /* Target flags to enable. */
1723 static struct rs6000_ptt const processor_target_table[] =
1725 {"401", PROCESSOR_PPC403, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
1726 {"403", PROCESSOR_PPC403,
1727 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_STRICT_ALIGN},
1728 {"405", PROCESSOR_PPC405,
1729 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
1730 {"405fp", PROCESSOR_PPC405,
1731 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
1732 {"440", PROCESSOR_PPC440,
1733 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
1734 {"440fp", PROCESSOR_PPC440,
1735 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
1736 {"464", PROCESSOR_PPC440,
1737 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
1738 {"464fp", PROCESSOR_PPC440,
1739 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
1740 {"476", PROCESSOR_PPC476,
1741 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_PPC_GFXOPT | MASK_MFCRF
1742 | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_MULHW | MASK_DLMZB},
1743 {"476fp", PROCESSOR_PPC476,
1744 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_MFCRF | MASK_POPCNTB
1745 | MASK_FPRND | MASK_CMPB | MASK_MULHW | MASK_DLMZB},
1746 {"505", PROCESSOR_MPCCORE, POWERPC_BASE_MASK},
1747 {"601", PROCESSOR_PPC601,
1748 MASK_POWER | POWERPC_BASE_MASK | MASK_MULTIPLE | MASK_STRING},
1749 {"602", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1750 {"603", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1751 {"603e", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1752 {"604", PROCESSOR_PPC604, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1753 {"604e", PROCESSOR_PPC604e, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1754 {"620", PROCESSOR_PPC620,
1755 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
1756 {"630", PROCESSOR_PPC630,
1757 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
1758 {"740", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1759 {"7400", PROCESSOR_PPC7400, POWERPC_7400_MASK},
1760 {"7450", PROCESSOR_PPC7450, POWERPC_7400_MASK},
1761 {"750", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1762 {"801", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
1763 {"821", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
1764 {"823", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
1765 {"8540", PROCESSOR_PPC8540, POWERPC_BASE_MASK | MASK_STRICT_ALIGN
1766 | MASK_ISEL},
1767 /* 8548 has a dummy entry for now. */
1768 {"8548", PROCESSOR_PPC8540, POWERPC_BASE_MASK | MASK_STRICT_ALIGN
1769 | MASK_ISEL},
1770 {"a2", PROCESSOR_PPCA2,
1771 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64 | MASK_POPCNTB
1772 | MASK_CMPB | MASK_NO_UPDATE },
1773 {"e300c2", PROCESSOR_PPCE300C2, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
1774 {"e300c3", PROCESSOR_PPCE300C3, POWERPC_BASE_MASK},
1775 {"e500mc", PROCESSOR_PPCE500MC, POWERPC_BASE_MASK | MASK_PPC_GFXOPT
1776 | MASK_ISEL},
1777 {"e500mc64", PROCESSOR_PPCE500MC64, POWERPC_BASE_MASK | MASK_POWERPC64
1778 | MASK_PPC_GFXOPT | MASK_ISEL},
1779 {"860", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
1780 {"970", PROCESSOR_POWER4,
1781 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
1782 {"cell", PROCESSOR_CELL,
1783 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
1784 {"common", PROCESSOR_COMMON, MASK_NEW_MNEMONICS},
1785 {"ec603e", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
1786 {"G3", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1787 {"G4", PROCESSOR_PPC7450, POWERPC_7400_MASK},
1788 {"G5", PROCESSOR_POWER4,
1789 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
1790 {"titan", PROCESSOR_TITAN,
1791 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
1792 {"power", PROCESSOR_POWER, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
1793 {"power2", PROCESSOR_POWER,
1794 MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING},
1795 {"power3", PROCESSOR_PPC630,
1796 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
1797 {"power4", PROCESSOR_POWER4,
1798 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
1799 | MASK_MFCRF},
1800 {"power5", PROCESSOR_POWER5,
1801 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
1802 | MASK_MFCRF | MASK_POPCNTB},
1803 {"power5+", PROCESSOR_POWER5,
1804 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
1805 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND},
1806 {"power6", PROCESSOR_POWER6,
1807 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
1808 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP
1809 | MASK_RECIP_PRECISION},
1810 {"power6x", PROCESSOR_POWER6,
1811 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
1812 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP
1813 | MASK_MFPGPR | MASK_RECIP_PRECISION},
1814 {"power7", PROCESSOR_POWER7, /* Don't add MASK_ISEL by default */
1815 POWERPC_7400_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_MFCRF
1816 | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP | MASK_POPCNTD
1817 | MASK_VSX | MASK_RECIP_PRECISION},
1818 {"powerpc", PROCESSOR_POWERPC, POWERPC_BASE_MASK},
1819 {"powerpc64", PROCESSOR_POWERPC64,
1820 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
1821 {"rios", PROCESSOR_RIOS1, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
1822 {"rios1", PROCESSOR_RIOS1, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
1823 {"rios2", PROCESSOR_RIOS2,
1824 MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING},
1825 {"rsc", PROCESSOR_PPC601, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
1826 {"rsc1", PROCESSOR_PPC601, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
1827 {"rs64", PROCESSOR_RS64A,
1828 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64}
1831 /* Look up a processor name for -mcpu=xxx and -mtune=xxx. Return -1 if the
1832 name is invalid. */
1834 static int
1835 rs6000_cpu_name_lookup (const char *name)
1837 size_t i;
1839 if (name != NULL)
1841 for (i = 0; i < ARRAY_SIZE (processor_target_table); i++)
1842 if (! strcmp (name, processor_target_table[i].name))
1843 return (int)i;
1846 return -1;
1850 /* Return number of consecutive hard regs needed starting at reg REGNO
1851 to hold something of mode MODE.
1852 This is ordinarily the length in words of a value of mode MODE
1853 but can be less for certain modes in special long registers.
1855 For the SPE, GPRs are 64 bits but only 32 bits are visible in
1856 scalar instructions. The upper 32 bits are only available to the
1857 SIMD instructions.
1859 POWER and PowerPC GPRs hold 32 bits worth;
1860 PowerPC64 GPRs and FPRs point register holds 64 bits worth. */
1862 static int
1863 rs6000_hard_regno_nregs_internal (int regno, enum machine_mode mode)
1865 unsigned HOST_WIDE_INT reg_size;
1867 if (FP_REGNO_P (regno))
1868 reg_size = (VECTOR_MEM_VSX_P (mode)
1869 ? UNITS_PER_VSX_WORD
1870 : UNITS_PER_FP_WORD);
1872 else if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode))
1873 reg_size = UNITS_PER_SPE_WORD;
1875 else if (ALTIVEC_REGNO_P (regno))
1876 reg_size = UNITS_PER_ALTIVEC_WORD;
1878 /* The value returned for SCmode in the E500 double case is 2 for
1879 ABI compatibility; storing an SCmode value in a single register
1880 would require function_arg and rs6000_spe_function_arg to handle
1881 SCmode so as to pass the value correctly in a pair of
1882 registers. */
1883 else if (TARGET_E500_DOUBLE && FLOAT_MODE_P (mode) && mode != SCmode
1884 && !DECIMAL_FLOAT_MODE_P (mode))
1885 reg_size = UNITS_PER_FP_WORD;
1887 else
1888 reg_size = UNITS_PER_WORD;
1890 return (GET_MODE_SIZE (mode) + reg_size - 1) / reg_size;
1893 /* Value is 1 if hard register REGNO can hold a value of machine-mode
1894 MODE. */
1895 static int
1896 rs6000_hard_regno_mode_ok (int regno, enum machine_mode mode)
1898 int last_regno = regno + rs6000_hard_regno_nregs[mode][regno] - 1;
1900 /* VSX registers that overlap the FPR registers are larger than for non-VSX
1901 implementations. Don't allow an item to be split between a FP register
1902 and an Altivec register. */
1903 if (VECTOR_MEM_VSX_P (mode))
1905 if (FP_REGNO_P (regno))
1906 return FP_REGNO_P (last_regno);
1908 if (ALTIVEC_REGNO_P (regno))
1909 return ALTIVEC_REGNO_P (last_regno);
1912 /* The GPRs can hold any mode, but values bigger than one register
1913 cannot go past R31. */
1914 if (INT_REGNO_P (regno))
1915 return INT_REGNO_P (last_regno);
1917 /* The float registers (except for VSX vector modes) can only hold floating
1918 modes and DImode. This excludes the 32-bit decimal float mode for
1919 now. */
1920 if (FP_REGNO_P (regno))
1922 if (SCALAR_FLOAT_MODE_P (mode)
1923 && (mode != TDmode || (regno % 2) == 0)
1924 && FP_REGNO_P (last_regno))
1925 return 1;
1927 if (GET_MODE_CLASS (mode) == MODE_INT
1928 && GET_MODE_SIZE (mode) == UNITS_PER_FP_WORD)
1929 return 1;
1931 if (PAIRED_SIMD_REGNO_P (regno) && TARGET_PAIRED_FLOAT
1932 && PAIRED_VECTOR_MODE (mode))
1933 return 1;
1935 return 0;
1938 /* The CR register can only hold CC modes. */
1939 if (CR_REGNO_P (regno))
1940 return GET_MODE_CLASS (mode) == MODE_CC;
1942 if (CA_REGNO_P (regno))
1943 return mode == BImode;
1945 /* AltiVec only in AldyVec registers. */
1946 if (ALTIVEC_REGNO_P (regno))
1947 return VECTOR_MEM_ALTIVEC_OR_VSX_P (mode);
1949 /* ...but GPRs can hold SIMD data on the SPE in one register. */
1950 if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode))
1951 return 1;
1953 /* We cannot put TImode anywhere except general register and it must be able
1954 to fit within the register set. In the future, allow TImode in the
1955 Altivec or VSX registers. */
1957 return GET_MODE_SIZE (mode) <= UNITS_PER_WORD;
1960 /* Print interesting facts about registers. */
1961 static void
1962 rs6000_debug_reg_print (int first_regno, int last_regno, const char *reg_name)
1964 int r, m;
1966 for (r = first_regno; r <= last_regno; ++r)
1968 const char *comma = "";
1969 int len;
1971 if (first_regno == last_regno)
1972 fprintf (stderr, "%s:\t", reg_name);
1973 else
1974 fprintf (stderr, "%s%d:\t", reg_name, r - first_regno);
1976 len = 8;
1977 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1978 if (rs6000_hard_regno_mode_ok_p[m][r] && rs6000_hard_regno_nregs[m][r])
1980 if (len > 70)
1982 fprintf (stderr, ",\n\t");
1983 len = 8;
1984 comma = "";
1987 if (rs6000_hard_regno_nregs[m][r] > 1)
1988 len += fprintf (stderr, "%s%s/%d", comma, GET_MODE_NAME (m),
1989 rs6000_hard_regno_nregs[m][r]);
1990 else
1991 len += fprintf (stderr, "%s%s", comma, GET_MODE_NAME (m));
1993 comma = ", ";
1996 if (call_used_regs[r])
1998 if (len > 70)
2000 fprintf (stderr, ",\n\t");
2001 len = 8;
2002 comma = "";
2005 len += fprintf (stderr, "%s%s", comma, "call-used");
2006 comma = ", ";
2009 if (fixed_regs[r])
2011 if (len > 70)
2013 fprintf (stderr, ",\n\t");
2014 len = 8;
2015 comma = "";
2018 len += fprintf (stderr, "%s%s", comma, "fixed");
2019 comma = ", ";
2022 if (len > 70)
2024 fprintf (stderr, ",\n\t");
2025 comma = "";
2028 fprintf (stderr, "%sregno = %d\n", comma, r);
2032 #define DEBUG_FMT_D "%-32s= %d\n"
2033 #define DEBUG_FMT_S "%-32s= %s\n"
2035 /* Print various interesting information with -mdebug=reg. */
2036 static void
2037 rs6000_debug_reg_global (void)
2039 static const char *const tf[2] = { "false", "true" };
2040 const char *nl = (const char *)0;
2041 int m;
2042 char costly_num[20];
2043 char nop_num[20];
2044 const char *costly_str;
2045 const char *nop_str;
2046 const char *trace_str;
2047 const char *abi_str;
2048 const char *cmodel_str;
2050 /* Map enum rs6000_vector to string. */
2051 static const char *rs6000_debug_vector_unit[] = {
2052 "none",
2053 "altivec",
2054 "vsx",
2055 "paired",
2056 "spe",
2057 "other"
2060 fprintf (stderr, "Register information: (last virtual reg = %d)\n",
2061 LAST_VIRTUAL_REGISTER);
2062 rs6000_debug_reg_print (0, 31, "gr");
2063 rs6000_debug_reg_print (32, 63, "fp");
2064 rs6000_debug_reg_print (FIRST_ALTIVEC_REGNO,
2065 LAST_ALTIVEC_REGNO,
2066 "vs");
2067 rs6000_debug_reg_print (LR_REGNO, LR_REGNO, "lr");
2068 rs6000_debug_reg_print (CTR_REGNO, CTR_REGNO, "ctr");
2069 rs6000_debug_reg_print (CR0_REGNO, CR7_REGNO, "cr");
2070 rs6000_debug_reg_print (MQ_REGNO, MQ_REGNO, "mq");
2071 rs6000_debug_reg_print (CA_REGNO, CA_REGNO, "ca");
2072 rs6000_debug_reg_print (VRSAVE_REGNO, VRSAVE_REGNO, "vrsave");
2073 rs6000_debug_reg_print (VSCR_REGNO, VSCR_REGNO, "vscr");
2074 rs6000_debug_reg_print (SPE_ACC_REGNO, SPE_ACC_REGNO, "spe_a");
2075 rs6000_debug_reg_print (SPEFSCR_REGNO, SPEFSCR_REGNO, "spe_f");
2077 fprintf (stderr,
2078 "\n"
2079 "d reg_class = %s\n"
2080 "f reg_class = %s\n"
2081 "v reg_class = %s\n"
2082 "wa reg_class = %s\n"
2083 "wd reg_class = %s\n"
2084 "wf reg_class = %s\n"
2085 "ws reg_class = %s\n\n",
2086 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_d]],
2087 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_f]],
2088 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_v]],
2089 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wa]],
2090 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wd]],
2091 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wf]],
2092 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_ws]]);
2094 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2095 if (rs6000_vector_unit[m] || rs6000_vector_mem[m])
2097 nl = "\n";
2098 fprintf (stderr, "Vector mode: %-5s arithmetic: %-8s move: %-8s\n",
2099 GET_MODE_NAME (m),
2100 rs6000_debug_vector_unit[ rs6000_vector_unit[m] ],
2101 rs6000_debug_vector_unit[ rs6000_vector_mem[m] ]);
2104 if (nl)
2105 fputs (nl, stderr);
2107 if (rs6000_recip_control)
2109 fprintf (stderr, "\nReciprocal mask = 0x%x\n", rs6000_recip_control);
2111 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2112 if (rs6000_recip_bits[m])
2114 fprintf (stderr,
2115 "Reciprocal estimate mode: %-5s divide: %s rsqrt: %s\n",
2116 GET_MODE_NAME (m),
2117 (RS6000_RECIP_AUTO_RE_P (m)
2118 ? "auto"
2119 : (RS6000_RECIP_HAVE_RE_P (m) ? "have" : "none")),
2120 (RS6000_RECIP_AUTO_RSQRTE_P (m)
2121 ? "auto"
2122 : (RS6000_RECIP_HAVE_RSQRTE_P (m) ? "have" : "none")));
2125 fputs ("\n", stderr);
2128 if (rs6000_cpu_index >= 0)
2129 fprintf (stderr, DEBUG_FMT_S, "cpu",
2130 processor_target_table[rs6000_cpu_index].name);
2132 if (rs6000_tune_index >= 0)
2133 fprintf (stderr, DEBUG_FMT_S, "tune",
2134 processor_target_table[rs6000_tune_index].name);
2136 switch (rs6000_sched_costly_dep)
2138 case max_dep_latency:
2139 costly_str = "max_dep_latency";
2140 break;
2142 case no_dep_costly:
2143 costly_str = "no_dep_costly";
2144 break;
2146 case all_deps_costly:
2147 costly_str = "all_deps_costly";
2148 break;
2150 case true_store_to_load_dep_costly:
2151 costly_str = "true_store_to_load_dep_costly";
2152 break;
2154 case store_to_load_dep_costly:
2155 costly_str = "store_to_load_dep_costly";
2156 break;
2158 default:
2159 costly_str = costly_num;
2160 sprintf (costly_num, "%d", (int)rs6000_sched_costly_dep);
2161 break;
2164 fprintf (stderr, DEBUG_FMT_S, "sched_costly_dep", costly_str);
2166 switch (rs6000_sched_insert_nops)
2168 case sched_finish_regroup_exact:
2169 nop_str = "sched_finish_regroup_exact";
2170 break;
2172 case sched_finish_pad_groups:
2173 nop_str = "sched_finish_pad_groups";
2174 break;
2176 case sched_finish_none:
2177 nop_str = "sched_finish_none";
2178 break;
2180 default:
2181 nop_str = nop_num;
2182 sprintf (nop_num, "%d", (int)rs6000_sched_insert_nops);
2183 break;
2186 fprintf (stderr, DEBUG_FMT_S, "sched_insert_nops", nop_str);
2188 switch (rs6000_sdata)
2190 default:
2191 case SDATA_NONE:
2192 break;
2194 case SDATA_DATA:
2195 fprintf (stderr, DEBUG_FMT_S, "sdata", "data");
2196 break;
2198 case SDATA_SYSV:
2199 fprintf (stderr, DEBUG_FMT_S, "sdata", "sysv");
2200 break;
2202 case SDATA_EABI:
2203 fprintf (stderr, DEBUG_FMT_S, "sdata", "eabi");
2204 break;
2208 switch (rs6000_traceback)
2210 case traceback_default: trace_str = "default"; break;
2211 case traceback_none: trace_str = "none"; break;
2212 case traceback_part: trace_str = "part"; break;
2213 case traceback_full: trace_str = "full"; break;
2214 default: trace_str = "unknown"; break;
2217 fprintf (stderr, DEBUG_FMT_S, "traceback", trace_str);
2219 switch (rs6000_current_cmodel)
2221 case CMODEL_SMALL: cmodel_str = "small"; break;
2222 case CMODEL_MEDIUM: cmodel_str = "medium"; break;
2223 case CMODEL_LARGE: cmodel_str = "large"; break;
2224 default: cmodel_str = "unknown"; break;
2227 fprintf (stderr, DEBUG_FMT_S, "cmodel", cmodel_str);
2229 switch (rs6000_current_abi)
2231 case ABI_NONE: abi_str = "none"; break;
2232 case ABI_AIX: abi_str = "aix"; break;
2233 case ABI_V4: abi_str = "V4"; break;
2234 case ABI_DARWIN: abi_str = "darwin"; break;
2235 default: abi_str = "unknown"; break;
2238 fprintf (stderr, DEBUG_FMT_S, "abi", abi_str);
2240 if (rs6000_altivec_abi)
2241 fprintf (stderr, DEBUG_FMT_S, "altivec_abi", "true");
2243 if (rs6000_spe_abi)
2244 fprintf (stderr, DEBUG_FMT_S, "spe_abi", "true");
2246 if (rs6000_darwin64_abi)
2247 fprintf (stderr, DEBUG_FMT_S, "darwin64_abi", "true");
2249 if (rs6000_float_gprs)
2250 fprintf (stderr, DEBUG_FMT_S, "float_gprs", "true");
2252 fprintf (stderr, DEBUG_FMT_S, "always_hint", tf[!!rs6000_always_hint]);
2253 fprintf (stderr, DEBUG_FMT_S, "align_branch",
2254 tf[!!rs6000_align_branch_targets]);
2255 fprintf (stderr, DEBUG_FMT_D, "tls_size", rs6000_tls_size);
2256 fprintf (stderr, DEBUG_FMT_D, "long_double_size",
2257 rs6000_long_double_type_size);
2258 fprintf (stderr, DEBUG_FMT_D, "sched_restricted_insns_priority",
2259 (int)rs6000_sched_restricted_insns_priority);
2262 /* Initialize the various global tables that are based on register size. */
2263 static void
2264 rs6000_init_hard_regno_mode_ok (bool global_init_p)
2266 int r, m, c;
2267 int align64;
2268 int align32;
2270 /* Precalculate REGNO_REG_CLASS. */
2271 rs6000_regno_regclass[0] = GENERAL_REGS;
2272 for (r = 1; r < 32; ++r)
2273 rs6000_regno_regclass[r] = BASE_REGS;
2275 for (r = 32; r < 64; ++r)
2276 rs6000_regno_regclass[r] = FLOAT_REGS;
2278 for (r = 64; r < FIRST_PSEUDO_REGISTER; ++r)
2279 rs6000_regno_regclass[r] = NO_REGS;
2281 for (r = FIRST_ALTIVEC_REGNO; r <= LAST_ALTIVEC_REGNO; ++r)
2282 rs6000_regno_regclass[r] = ALTIVEC_REGS;
2284 rs6000_regno_regclass[CR0_REGNO] = CR0_REGS;
2285 for (r = CR1_REGNO; r <= CR7_REGNO; ++r)
2286 rs6000_regno_regclass[r] = CR_REGS;
2288 rs6000_regno_regclass[MQ_REGNO] = MQ_REGS;
2289 rs6000_regno_regclass[LR_REGNO] = LINK_REGS;
2290 rs6000_regno_regclass[CTR_REGNO] = CTR_REGS;
2291 rs6000_regno_regclass[CA_REGNO] = CA_REGS;
2292 rs6000_regno_regclass[VRSAVE_REGNO] = VRSAVE_REGS;
2293 rs6000_regno_regclass[VSCR_REGNO] = VRSAVE_REGS;
2294 rs6000_regno_regclass[SPE_ACC_REGNO] = SPE_ACC_REGS;
2295 rs6000_regno_regclass[SPEFSCR_REGNO] = SPEFSCR_REGS;
2296 rs6000_regno_regclass[ARG_POINTER_REGNUM] = BASE_REGS;
2297 rs6000_regno_regclass[FRAME_POINTER_REGNUM] = BASE_REGS;
2299 /* Precalculate vector information, this must be set up before the
2300 rs6000_hard_regno_nregs_internal below. */
2301 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2303 rs6000_vector_unit[m] = rs6000_vector_mem[m] = VECTOR_NONE;
2304 rs6000_vector_reload[m][0] = CODE_FOR_nothing;
2305 rs6000_vector_reload[m][1] = CODE_FOR_nothing;
2308 for (c = 0; c < (int)(int)RS6000_CONSTRAINT_MAX; c++)
2309 rs6000_constraints[c] = NO_REGS;
2311 /* The VSX hardware allows native alignment for vectors, but control whether the compiler
2312 believes it can use native alignment or still uses 128-bit alignment. */
2313 if (TARGET_VSX && !TARGET_VSX_ALIGN_128)
2315 align64 = 64;
2316 align32 = 32;
2318 else
2320 align64 = 128;
2321 align32 = 128;
2324 /* V2DF mode, VSX only. */
2325 if (TARGET_VSX)
2327 rs6000_vector_unit[V2DFmode] = VECTOR_VSX;
2328 rs6000_vector_mem[V2DFmode] = VECTOR_VSX;
2329 rs6000_vector_align[V2DFmode] = align64;
2332 /* V4SF mode, either VSX or Altivec. */
2333 if (TARGET_VSX)
2335 rs6000_vector_unit[V4SFmode] = VECTOR_VSX;
2336 rs6000_vector_mem[V4SFmode] = VECTOR_VSX;
2337 rs6000_vector_align[V4SFmode] = align32;
2339 else if (TARGET_ALTIVEC)
2341 rs6000_vector_unit[V4SFmode] = VECTOR_ALTIVEC;
2342 rs6000_vector_mem[V4SFmode] = VECTOR_ALTIVEC;
2343 rs6000_vector_align[V4SFmode] = align32;
2346 /* V16QImode, V8HImode, V4SImode are Altivec only, but possibly do VSX loads
2347 and stores. */
2348 if (TARGET_ALTIVEC)
2350 rs6000_vector_unit[V4SImode] = VECTOR_ALTIVEC;
2351 rs6000_vector_unit[V8HImode] = VECTOR_ALTIVEC;
2352 rs6000_vector_unit[V16QImode] = VECTOR_ALTIVEC;
2353 rs6000_vector_align[V4SImode] = align32;
2354 rs6000_vector_align[V8HImode] = align32;
2355 rs6000_vector_align[V16QImode] = align32;
2357 if (TARGET_VSX)
2359 rs6000_vector_mem[V4SImode] = VECTOR_VSX;
2360 rs6000_vector_mem[V8HImode] = VECTOR_VSX;
2361 rs6000_vector_mem[V16QImode] = VECTOR_VSX;
2363 else
2365 rs6000_vector_mem[V4SImode] = VECTOR_ALTIVEC;
2366 rs6000_vector_mem[V8HImode] = VECTOR_ALTIVEC;
2367 rs6000_vector_mem[V16QImode] = VECTOR_ALTIVEC;
2371 /* V2DImode, only allow under VSX, which can do V2DI insert/splat/extract.
2372 Altivec doesn't have 64-bit support. */
2373 if (TARGET_VSX)
2375 rs6000_vector_mem[V2DImode] = VECTOR_VSX;
2376 rs6000_vector_unit[V2DImode] = VECTOR_NONE;
2377 rs6000_vector_align[V2DImode] = align64;
2380 /* DFmode, see if we want to use the VSX unit. */
2381 if (TARGET_VSX && TARGET_VSX_SCALAR_DOUBLE)
2383 rs6000_vector_unit[DFmode] = VECTOR_VSX;
2384 rs6000_vector_mem[DFmode]
2385 = (TARGET_VSX_SCALAR_MEMORY ? VECTOR_VSX : VECTOR_NONE);
2386 rs6000_vector_align[DFmode] = align64;
2389 /* TODO add SPE and paired floating point vector support. */
2391 /* Register class constaints for the constraints that depend on compile
2392 switches. */
2393 if (TARGET_HARD_FLOAT && TARGET_FPRS)
2394 rs6000_constraints[RS6000_CONSTRAINT_f] = FLOAT_REGS;
2396 if (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
2397 rs6000_constraints[RS6000_CONSTRAINT_d] = FLOAT_REGS;
2399 if (TARGET_VSX)
2401 /* At present, we just use VSX_REGS, but we have different constraints
2402 based on the use, in case we want to fine tune the default register
2403 class used. wa = any VSX register, wf = register class to use for
2404 V4SF, wd = register class to use for V2DF, and ws = register classs to
2405 use for DF scalars. */
2406 rs6000_constraints[RS6000_CONSTRAINT_wa] = VSX_REGS;
2407 rs6000_constraints[RS6000_CONSTRAINT_wf] = VSX_REGS;
2408 rs6000_constraints[RS6000_CONSTRAINT_wd] = VSX_REGS;
2409 rs6000_constraints[RS6000_CONSTRAINT_ws] = (TARGET_VSX_SCALAR_MEMORY
2410 ? VSX_REGS
2411 : FLOAT_REGS);
2414 if (TARGET_ALTIVEC)
2415 rs6000_constraints[RS6000_CONSTRAINT_v] = ALTIVEC_REGS;
2417 /* Set up the reload helper functions. */
2418 if (TARGET_VSX || TARGET_ALTIVEC)
2420 if (TARGET_64BIT)
2422 rs6000_vector_reload[V16QImode][0] = CODE_FOR_reload_v16qi_di_store;
2423 rs6000_vector_reload[V16QImode][1] = CODE_FOR_reload_v16qi_di_load;
2424 rs6000_vector_reload[V8HImode][0] = CODE_FOR_reload_v8hi_di_store;
2425 rs6000_vector_reload[V8HImode][1] = CODE_FOR_reload_v8hi_di_load;
2426 rs6000_vector_reload[V4SImode][0] = CODE_FOR_reload_v4si_di_store;
2427 rs6000_vector_reload[V4SImode][1] = CODE_FOR_reload_v4si_di_load;
2428 rs6000_vector_reload[V2DImode][0] = CODE_FOR_reload_v2di_di_store;
2429 rs6000_vector_reload[V2DImode][1] = CODE_FOR_reload_v2di_di_load;
2430 rs6000_vector_reload[V4SFmode][0] = CODE_FOR_reload_v4sf_di_store;
2431 rs6000_vector_reload[V4SFmode][1] = CODE_FOR_reload_v4sf_di_load;
2432 rs6000_vector_reload[V2DFmode][0] = CODE_FOR_reload_v2df_di_store;
2433 rs6000_vector_reload[V2DFmode][1] = CODE_FOR_reload_v2df_di_load;
2435 else
2437 rs6000_vector_reload[V16QImode][0] = CODE_FOR_reload_v16qi_si_store;
2438 rs6000_vector_reload[V16QImode][1] = CODE_FOR_reload_v16qi_si_load;
2439 rs6000_vector_reload[V8HImode][0] = CODE_FOR_reload_v8hi_si_store;
2440 rs6000_vector_reload[V8HImode][1] = CODE_FOR_reload_v8hi_si_load;
2441 rs6000_vector_reload[V4SImode][0] = CODE_FOR_reload_v4si_si_store;
2442 rs6000_vector_reload[V4SImode][1] = CODE_FOR_reload_v4si_si_load;
2443 rs6000_vector_reload[V2DImode][0] = CODE_FOR_reload_v2di_si_store;
2444 rs6000_vector_reload[V2DImode][1] = CODE_FOR_reload_v2di_si_load;
2445 rs6000_vector_reload[V4SFmode][0] = CODE_FOR_reload_v4sf_si_store;
2446 rs6000_vector_reload[V4SFmode][1] = CODE_FOR_reload_v4sf_si_load;
2447 rs6000_vector_reload[V2DFmode][0] = CODE_FOR_reload_v2df_si_store;
2448 rs6000_vector_reload[V2DFmode][1] = CODE_FOR_reload_v2df_si_load;
2452 /* Precalculate HARD_REGNO_NREGS. */
2453 for (r = 0; r < FIRST_PSEUDO_REGISTER; ++r)
2454 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2455 rs6000_hard_regno_nregs[m][r]
2456 = rs6000_hard_regno_nregs_internal (r, (enum machine_mode)m);
2458 /* Precalculate HARD_REGNO_MODE_OK. */
2459 for (r = 0; r < FIRST_PSEUDO_REGISTER; ++r)
2460 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2461 if (rs6000_hard_regno_mode_ok (r, (enum machine_mode)m))
2462 rs6000_hard_regno_mode_ok_p[m][r] = true;
2464 /* Precalculate CLASS_MAX_NREGS sizes. */
2465 for (c = 0; c < LIM_REG_CLASSES; ++c)
2467 int reg_size;
2469 if (TARGET_VSX && VSX_REG_CLASS_P (c))
2470 reg_size = UNITS_PER_VSX_WORD;
2472 else if (c == ALTIVEC_REGS)
2473 reg_size = UNITS_PER_ALTIVEC_WORD;
2475 else if (c == FLOAT_REGS)
2476 reg_size = UNITS_PER_FP_WORD;
2478 else
2479 reg_size = UNITS_PER_WORD;
2481 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2482 rs6000_class_max_nregs[m][c]
2483 = (GET_MODE_SIZE (m) + reg_size - 1) / reg_size;
2486 if (TARGET_E500_DOUBLE)
2487 rs6000_class_max_nregs[DFmode][GENERAL_REGS] = 1;
2489 /* Calculate which modes to automatically generate code to use a the
2490 reciprocal divide and square root instructions. In the future, possibly
2491 automatically generate the instructions even if the user did not specify
2492 -mrecip. The older machines double precision reciprocal sqrt estimate is
2493 not accurate enough. */
2494 memset (rs6000_recip_bits, 0, sizeof (rs6000_recip_bits));
2495 if (TARGET_FRES)
2496 rs6000_recip_bits[SFmode] = RS6000_RECIP_MASK_HAVE_RE;
2497 if (TARGET_FRE)
2498 rs6000_recip_bits[DFmode] = RS6000_RECIP_MASK_HAVE_RE;
2499 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode))
2500 rs6000_recip_bits[V4SFmode] = RS6000_RECIP_MASK_HAVE_RE;
2501 if (VECTOR_UNIT_VSX_P (V2DFmode))
2502 rs6000_recip_bits[V2DFmode] = RS6000_RECIP_MASK_HAVE_RE;
2504 if (TARGET_FRSQRTES)
2505 rs6000_recip_bits[SFmode] |= RS6000_RECIP_MASK_HAVE_RSQRTE;
2506 if (TARGET_FRSQRTE)
2507 rs6000_recip_bits[DFmode] |= RS6000_RECIP_MASK_HAVE_RSQRTE;
2508 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode))
2509 rs6000_recip_bits[V4SFmode] |= RS6000_RECIP_MASK_HAVE_RSQRTE;
2510 if (VECTOR_UNIT_VSX_P (V2DFmode))
2511 rs6000_recip_bits[V2DFmode] |= RS6000_RECIP_MASK_HAVE_RSQRTE;
2513 if (rs6000_recip_control)
2515 if (!flag_finite_math_only)
2516 warning (0, "-mrecip requires -ffinite-math or -ffast-math");
2517 if (flag_trapping_math)
2518 warning (0, "-mrecip requires -fno-trapping-math or -ffast-math");
2519 if (!flag_reciprocal_math)
2520 warning (0, "-mrecip requires -freciprocal-math or -ffast-math");
2521 if (flag_finite_math_only && !flag_trapping_math && flag_reciprocal_math)
2523 if (RS6000_RECIP_HAVE_RE_P (SFmode)
2524 && (rs6000_recip_control & RECIP_SF_DIV) != 0)
2525 rs6000_recip_bits[SFmode] |= RS6000_RECIP_MASK_AUTO_RE;
2527 if (RS6000_RECIP_HAVE_RE_P (DFmode)
2528 && (rs6000_recip_control & RECIP_DF_DIV) != 0)
2529 rs6000_recip_bits[DFmode] |= RS6000_RECIP_MASK_AUTO_RE;
2531 if (RS6000_RECIP_HAVE_RE_P (V4SFmode)
2532 && (rs6000_recip_control & RECIP_V4SF_DIV) != 0)
2533 rs6000_recip_bits[V4SFmode] |= RS6000_RECIP_MASK_AUTO_RE;
2535 if (RS6000_RECIP_HAVE_RE_P (V2DFmode)
2536 && (rs6000_recip_control & RECIP_V2DF_DIV) != 0)
2537 rs6000_recip_bits[V2DFmode] |= RS6000_RECIP_MASK_AUTO_RE;
2539 if (RS6000_RECIP_HAVE_RSQRTE_P (SFmode)
2540 && (rs6000_recip_control & RECIP_SF_RSQRT) != 0)
2541 rs6000_recip_bits[SFmode] |= RS6000_RECIP_MASK_AUTO_RSQRTE;
2543 if (RS6000_RECIP_HAVE_RSQRTE_P (DFmode)
2544 && (rs6000_recip_control & RECIP_DF_RSQRT) != 0)
2545 rs6000_recip_bits[DFmode] |= RS6000_RECIP_MASK_AUTO_RSQRTE;
2547 if (RS6000_RECIP_HAVE_RSQRTE_P (V4SFmode)
2548 && (rs6000_recip_control & RECIP_V4SF_RSQRT) != 0)
2549 rs6000_recip_bits[V4SFmode] |= RS6000_RECIP_MASK_AUTO_RSQRTE;
2551 if (RS6000_RECIP_HAVE_RSQRTE_P (V2DFmode)
2552 && (rs6000_recip_control & RECIP_V2DF_RSQRT) != 0)
2553 rs6000_recip_bits[V2DFmode] |= RS6000_RECIP_MASK_AUTO_RSQRTE;
2557 if (global_init_p || TARGET_DEBUG_TARGET)
2559 if (TARGET_DEBUG_REG)
2560 rs6000_debug_reg_global ();
2562 if (TARGET_DEBUG_COST || TARGET_DEBUG_REG)
2563 fprintf (stderr,
2564 "SImode variable mult cost = %d\n"
2565 "SImode constant mult cost = %d\n"
2566 "SImode short constant mult cost = %d\n"
2567 "DImode multipliciation cost = %d\n"
2568 "SImode division cost = %d\n"
2569 "DImode division cost = %d\n"
2570 "Simple fp operation cost = %d\n"
2571 "DFmode multiplication cost = %d\n"
2572 "SFmode division cost = %d\n"
2573 "DFmode division cost = %d\n"
2574 "cache line size = %d\n"
2575 "l1 cache size = %d\n"
2576 "l2 cache size = %d\n"
2577 "simultaneous prefetches = %d\n"
2578 "\n",
2579 rs6000_cost->mulsi,
2580 rs6000_cost->mulsi_const,
2581 rs6000_cost->mulsi_const9,
2582 rs6000_cost->muldi,
2583 rs6000_cost->divsi,
2584 rs6000_cost->divdi,
2585 rs6000_cost->fp,
2586 rs6000_cost->dmul,
2587 rs6000_cost->sdiv,
2588 rs6000_cost->ddiv,
2589 rs6000_cost->cache_line_size,
2590 rs6000_cost->l1_cache_size,
2591 rs6000_cost->l2_cache_size,
2592 rs6000_cost->simultaneous_prefetches);
2596 #if TARGET_MACHO
2597 /* The Darwin version of SUBTARGET_OVERRIDE_OPTIONS. */
2599 static void
2600 darwin_rs6000_override_options (void)
2602 /* The Darwin ABI always includes AltiVec, can't be (validly) turned
2603 off. */
2604 rs6000_altivec_abi = 1;
2605 TARGET_ALTIVEC_VRSAVE = 1;
2607 if (DEFAULT_ABI == ABI_DARWIN
2608 && TARGET_64BIT)
2609 darwin_one_byte_bool = 1;
2611 if (TARGET_64BIT && ! TARGET_POWERPC64)
2613 target_flags |= MASK_POWERPC64;
2614 warning (0, "-m64 requires PowerPC64 architecture, enabling");
2616 if (flag_mkernel)
2618 rs6000_default_long_calls = 1;
2619 target_flags |= MASK_SOFT_FLOAT;
2622 /* Make -m64 imply -maltivec. Darwin's 64-bit ABI includes
2623 Altivec. */
2624 if (!flag_mkernel && !flag_apple_kext
2625 && TARGET_64BIT
2626 && ! (target_flags_explicit & MASK_ALTIVEC))
2627 target_flags |= MASK_ALTIVEC;
2629 /* Unless the user (not the configurer) has explicitly overridden
2630 it with -mcpu=G3 or -mno-altivec, then 10.5+ targets default to
2631 G4 unless targetting the kernel. */
2632 if (!flag_mkernel
2633 && !flag_apple_kext
2634 && strverscmp (darwin_macosx_version_min, "10.5") >= 0
2635 && ! (target_flags_explicit & MASK_ALTIVEC)
2636 && ! rs6000_select[1].string)
2638 target_flags |= MASK_ALTIVEC;
2641 #endif
2643 /* If not otherwise specified by a target, make 'long double' equivalent to
2644 'double'. */
2646 #ifndef RS6000_DEFAULT_LONG_DOUBLE_SIZE
2647 #define RS6000_DEFAULT_LONG_DOUBLE_SIZE 64
2648 #endif
2650 /* Override command line options. Mostly we process the processor type and
2651 sometimes adjust other TARGET_ options. */
2653 static bool
2654 rs6000_option_override_internal (bool global_init_p)
2656 bool ret = true;
2657 const char *default_cpu = OPTION_TARGET_CPU_DEFAULT;
2658 int set_masks;
2659 int cpu_index;
2660 int tune_index;
2661 struct cl_target_option *main_target_opt
2662 = ((global_init_p || target_option_default_node == NULL)
2663 ? NULL : TREE_TARGET_OPTION (target_option_default_node));
2665 /* Numerous experiment shows that IRA based loop pressure
2666 calculation works better for RTL loop invariant motion on targets
2667 with enough (>= 32) registers. It is an expensive optimization.
2668 So it is on only for peak performance. */
2669 if (optimize >= 3 && global_init_p)
2670 flag_ira_loop_pressure = 1;
2672 /* Set the pointer size. */
2673 if (TARGET_64BIT)
2675 rs6000_pmode = (int)DImode;
2676 rs6000_pointer_size = 64;
2678 else
2680 rs6000_pmode = (int)SImode;
2681 rs6000_pointer_size = 32;
2684 set_masks = POWER_MASKS | POWERPC_MASKS | MASK_SOFT_FLOAT;
2685 #ifdef OS_MISSING_POWERPC64
2686 if (OS_MISSING_POWERPC64)
2687 set_masks &= ~MASK_POWERPC64;
2688 #endif
2689 #ifdef OS_MISSING_ALTIVEC
2690 if (OS_MISSING_ALTIVEC)
2691 set_masks &= ~MASK_ALTIVEC;
2692 #endif
2694 /* Don't override by the processor default if given explicitly. */
2695 set_masks &= ~target_flags_explicit;
2697 /* Identify the processor type. */
2698 if (!default_cpu)
2700 if (TARGET_POWERPC64)
2701 default_cpu = "powerpc64";
2702 else if (TARGET_POWERPC)
2703 default_cpu = "powerpc";
2706 /* Process the -mcpu=<xxx> and -mtune=<xxx> argument. If the user changed
2707 the cpu in a target attribute or pragma, but did not specify a tuning
2708 option, use the cpu for the tuning option rather than the option specified
2709 with -mtune on the command line. */
2710 if (rs6000_cpu_index > 0)
2711 cpu_index = rs6000_cpu_index;
2712 else if (main_target_opt != NULL && main_target_opt->x_rs6000_cpu_index > 0)
2713 rs6000_cpu_index = cpu_index = main_target_opt->x_rs6000_cpu_index;
2714 else
2715 rs6000_cpu_index = cpu_index = rs6000_cpu_name_lookup (default_cpu);
2717 if (rs6000_tune_index > 0)
2718 tune_index = rs6000_tune_index;
2719 else
2720 rs6000_tune_index = tune_index = cpu_index;
2722 if (cpu_index >= 0)
2724 target_flags &= ~set_masks;
2725 target_flags |= (processor_target_table[cpu_index].target_enable
2726 & set_masks);
2729 rs6000_cpu = ((tune_index >= 0)
2730 ? processor_target_table[tune_index].processor
2731 : (TARGET_POWERPC64
2732 ? PROCESSOR_DEFAULT64
2733 : PROCESSOR_DEFAULT));
2735 if (rs6000_cpu == PROCESSOR_PPCE300C2 || rs6000_cpu == PROCESSOR_PPCE300C3
2736 || rs6000_cpu == PROCESSOR_PPCE500MC || rs6000_cpu == PROCESSOR_PPCE500MC64)
2738 if (TARGET_ALTIVEC)
2739 error ("AltiVec not supported in this target");
2740 if (TARGET_SPE)
2741 error ("SPE not supported in this target");
2744 /* Disable Cell microcode if we are optimizing for the Cell
2745 and not optimizing for size. */
2746 if (rs6000_gen_cell_microcode == -1)
2747 rs6000_gen_cell_microcode = !(rs6000_cpu == PROCESSOR_CELL
2748 && !optimize_size);
2750 /* If we are optimizing big endian systems for space and it's OK to
2751 use instructions that would be microcoded on the Cell, use the
2752 load/store multiple and string instructions. */
2753 if (BYTES_BIG_ENDIAN && optimize_size && rs6000_gen_cell_microcode)
2754 target_flags |= ~target_flags_explicit & (MASK_MULTIPLE | MASK_STRING);
2756 /* Don't allow -mmultiple or -mstring on little endian systems
2757 unless the cpu is a 750, because the hardware doesn't support the
2758 instructions used in little endian mode, and causes an alignment
2759 trap. The 750 does not cause an alignment trap (except when the
2760 target is unaligned). */
2762 if (!BYTES_BIG_ENDIAN && rs6000_cpu != PROCESSOR_PPC750)
2764 if (TARGET_MULTIPLE)
2766 target_flags &= ~MASK_MULTIPLE;
2767 if ((target_flags_explicit & MASK_MULTIPLE) != 0)
2768 warning (0, "-mmultiple is not supported on little endian systems");
2771 if (TARGET_STRING)
2773 target_flags &= ~MASK_STRING;
2774 if ((target_flags_explicit & MASK_STRING) != 0)
2775 warning (0, "-mstring is not supported on little endian systems");
2779 /* Add some warnings for VSX. */
2780 if (TARGET_VSX)
2782 const char *msg = NULL;
2783 if (!TARGET_HARD_FLOAT || !TARGET_FPRS
2784 || !TARGET_SINGLE_FLOAT || !TARGET_DOUBLE_FLOAT)
2786 if (target_flags_explicit & MASK_VSX)
2787 msg = N_("-mvsx requires hardware floating point");
2788 else
2789 target_flags &= ~ MASK_VSX;
2791 else if (TARGET_PAIRED_FLOAT)
2792 msg = N_("-mvsx and -mpaired are incompatible");
2793 /* The hardware will allow VSX and little endian, but until we make sure
2794 things like vector select, etc. work don't allow VSX on little endian
2795 systems at this point. */
2796 else if (!BYTES_BIG_ENDIAN)
2797 msg = N_("-mvsx used with little endian code");
2798 else if (TARGET_AVOID_XFORM > 0)
2799 msg = N_("-mvsx needs indexed addressing");
2800 else if (!TARGET_ALTIVEC && (target_flags_explicit & MASK_ALTIVEC))
2802 if (target_flags_explicit & MASK_VSX)
2803 msg = N_("-mvsx and -mno-altivec are incompatible");
2804 else
2805 msg = N_("-mno-altivec disables vsx");
2808 if (msg)
2810 warning (0, msg);
2811 target_flags &= ~ MASK_VSX;
2812 target_flags_explicit |= MASK_VSX;
2816 /* For the newer switches (vsx, dfp, etc.) set some of the older options,
2817 unless the user explicitly used the -mno-<option> to disable the code. */
2818 if (TARGET_VSX)
2819 target_flags |= (ISA_2_6_MASKS_SERVER & ~target_flags_explicit);
2820 else if (TARGET_POPCNTD)
2821 target_flags |= (ISA_2_6_MASKS_EMBEDDED & ~target_flags_explicit);
2822 else if (TARGET_DFP)
2823 target_flags |= (ISA_2_5_MASKS_SERVER & ~target_flags_explicit);
2824 else if (TARGET_CMPB)
2825 target_flags |= (ISA_2_5_MASKS_EMBEDDED & ~target_flags_explicit);
2826 else if (TARGET_FPRND)
2827 target_flags |= (ISA_2_4_MASKS & ~target_flags_explicit);
2828 else if (TARGET_POPCNTB)
2829 target_flags |= (ISA_2_2_MASKS & ~target_flags_explicit);
2830 else if (TARGET_ALTIVEC)
2831 target_flags |= (MASK_PPC_GFXOPT & ~target_flags_explicit);
2833 /* E500mc does "better" if we inline more aggressively. Respect the
2834 user's opinion, though. */
2835 if (rs6000_block_move_inline_limit == 0
2836 && (rs6000_cpu == PROCESSOR_PPCE500MC
2837 || rs6000_cpu == PROCESSOR_PPCE500MC64))
2838 rs6000_block_move_inline_limit = 128;
2840 /* store_one_arg depends on expand_block_move to handle at least the
2841 size of reg_parm_stack_space. */
2842 if (rs6000_block_move_inline_limit < (TARGET_POWERPC64 ? 64 : 32))
2843 rs6000_block_move_inline_limit = (TARGET_POWERPC64 ? 64 : 32);
2845 if (global_init_p)
2847 /* If the appropriate debug option is enabled, replace the target hooks
2848 with debug versions that call the real version and then prints
2849 debugging information. */
2850 if (TARGET_DEBUG_COST)
2852 targetm.rtx_costs = rs6000_debug_rtx_costs;
2853 targetm.address_cost = rs6000_debug_address_cost;
2854 targetm.sched.adjust_cost = rs6000_debug_adjust_cost;
2857 if (TARGET_DEBUG_ADDR)
2859 targetm.legitimate_address_p = rs6000_debug_legitimate_address_p;
2860 targetm.legitimize_address = rs6000_debug_legitimize_address;
2861 rs6000_secondary_reload_class_ptr
2862 = rs6000_debug_secondary_reload_class;
2863 rs6000_secondary_memory_needed_ptr
2864 = rs6000_debug_secondary_memory_needed;
2865 rs6000_cannot_change_mode_class_ptr
2866 = rs6000_debug_cannot_change_mode_class;
2867 rs6000_preferred_reload_class_ptr
2868 = rs6000_debug_preferred_reload_class;
2869 rs6000_legitimize_reload_address_ptr
2870 = rs6000_debug_legitimize_reload_address;
2871 rs6000_mode_dependent_address_ptr
2872 = rs6000_debug_mode_dependent_address;
2875 if (rs6000_veclibabi_name)
2877 if (strcmp (rs6000_veclibabi_name, "mass") == 0)
2878 rs6000_veclib_handler = rs6000_builtin_vectorized_libmass;
2879 else
2881 error ("unknown vectorization library ABI type (%s) for "
2882 "-mveclibabi= switch", rs6000_veclibabi_name);
2883 ret = false;
2888 if (!rs6000_explicit_options.long_double)
2890 if (main_target_opt != NULL
2891 && (main_target_opt->x_rs6000_long_double_type_size
2892 != RS6000_DEFAULT_LONG_DOUBLE_SIZE))
2893 error ("target attribute or pragma changes long double size");
2894 else
2895 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
2898 #ifndef POWERPC_LINUX
2899 if (!rs6000_explicit_options.ieee)
2900 rs6000_ieeequad = 1;
2901 #endif
2903 /* Disable VSX and Altivec silently if the user switched cpus to power7 in a
2904 target attribute or pragma which automatically enables both options,
2905 unless the altivec ABI was set. This is set by default for 64-bit, but
2906 not for 32-bit. */
2907 if (main_target_opt != NULL && !main_target_opt->x_rs6000_altivec_abi)
2908 target_flags &= ~((MASK_VSX | MASK_ALTIVEC) & ~target_flags_explicit);
2910 /* Enable Altivec ABI for AIX -maltivec. */
2911 if (TARGET_XCOFF && (TARGET_ALTIVEC || TARGET_VSX))
2913 if (main_target_opt != NULL && !main_target_opt->x_rs6000_altivec_abi)
2914 error ("target attribute or pragma changes AltiVec ABI");
2915 else
2916 rs6000_altivec_abi = 1;
2919 /* The AltiVec ABI is the default for PowerPC-64 GNU/Linux. For
2920 PowerPC-32 GNU/Linux, -maltivec implies the AltiVec ABI. It can
2921 be explicitly overridden in either case. */
2922 if (TARGET_ELF)
2924 if (!rs6000_explicit_options.altivec_abi
2925 && (TARGET_64BIT || TARGET_ALTIVEC || TARGET_VSX))
2927 if (main_target_opt != NULL &&
2928 !main_target_opt->x_rs6000_altivec_abi)
2929 error ("target attribute or pragma changes AltiVec ABI");
2930 else
2931 rs6000_altivec_abi = 1;
2934 /* Enable VRSAVE for AltiVec ABI, unless explicitly overridden. */
2935 if (!rs6000_explicit_options.vrsave)
2936 TARGET_ALTIVEC_VRSAVE = rs6000_altivec_abi;
2939 /* Set the Darwin64 ABI as default for 64-bit Darwin.
2940 So far, the only darwin64 targets are also MACH-O. */
2941 if (TARGET_MACHO
2942 && DEFAULT_ABI == ABI_DARWIN
2943 && TARGET_64BIT)
2945 if (main_target_opt != NULL && !main_target_opt->x_rs6000_darwin64_abi)
2946 error ("target attribute or pragma changes darwin64 ABI");
2947 else
2949 rs6000_darwin64_abi = 1;
2950 /* Default to natural alignment, for better performance. */
2951 rs6000_alignment_flags = MASK_ALIGN_NATURAL;
2955 /* Place FP constants in the constant pool instead of TOC
2956 if section anchors enabled. */
2957 if (flag_section_anchors)
2958 TARGET_NO_FP_IN_TOC = 1;
2960 #ifdef SUBTARGET_OVERRIDE_OPTIONS
2961 SUBTARGET_OVERRIDE_OPTIONS;
2962 #endif
2963 #ifdef SUBSUBTARGET_OVERRIDE_OPTIONS
2964 SUBSUBTARGET_OVERRIDE_OPTIONS;
2965 #endif
2966 #ifdef SUB3TARGET_OVERRIDE_OPTIONS
2967 SUB3TARGET_OVERRIDE_OPTIONS;
2968 #endif
2970 if (TARGET_E500 || rs6000_cpu == PROCESSOR_PPCE500MC
2971 || rs6000_cpu == PROCESSOR_PPCE500MC64)
2973 /* The e500 and e500mc do not have string instructions, and we set
2974 MASK_STRING above when optimizing for size. */
2975 if ((target_flags & MASK_STRING) != 0)
2976 target_flags = target_flags & ~MASK_STRING;
2978 else if (rs6000_select[1].string != NULL)
2980 /* For the powerpc-eabispe configuration, we set all these by
2981 default, so let's unset them if we manually set another
2982 CPU that is not the E500. */
2983 if (main_target_opt != NULL
2984 && ((main_target_opt->x_rs6000_spe_abi != rs6000_spe_abi)
2985 || (main_target_opt->x_rs6000_spe != rs6000_spe)
2986 || (main_target_opt->x_rs6000_float_gprs != rs6000_float_gprs)))
2987 error ("target attribute or pragma changes SPE ABI");
2988 else
2990 if (!rs6000_explicit_options.spe_abi)
2991 rs6000_spe_abi = 0;
2992 if (!rs6000_explicit_options.spe)
2993 rs6000_spe = 0;
2994 if (!rs6000_explicit_options.float_gprs)
2995 rs6000_float_gprs = 0;
2997 if (!(target_flags_explicit & MASK_ISEL))
2998 target_flags &= ~MASK_ISEL;
3001 /* Detect invalid option combinations with E500. */
3002 CHECK_E500_OPTIONS;
3004 rs6000_always_hint = (rs6000_cpu != PROCESSOR_POWER4
3005 && rs6000_cpu != PROCESSOR_POWER5
3006 && rs6000_cpu != PROCESSOR_POWER6
3007 && rs6000_cpu != PROCESSOR_POWER7
3008 && rs6000_cpu != PROCESSOR_PPCA2
3009 && rs6000_cpu != PROCESSOR_CELL);
3010 rs6000_sched_groups = (rs6000_cpu == PROCESSOR_POWER4
3011 || rs6000_cpu == PROCESSOR_POWER5
3012 || rs6000_cpu == PROCESSOR_POWER7);
3013 rs6000_align_branch_targets = (rs6000_cpu == PROCESSOR_POWER4
3014 || rs6000_cpu == PROCESSOR_POWER5
3015 || rs6000_cpu == PROCESSOR_POWER6
3016 || rs6000_cpu == PROCESSOR_POWER7
3017 || rs6000_cpu == PROCESSOR_PPCE500MC
3018 || rs6000_cpu == PROCESSOR_PPCE500MC64);
3020 /* Allow debug switches to override the above settings. These are set to -1
3021 in rs6000.opt to indicate the user hasn't directly set the switch. */
3022 if (TARGET_ALWAYS_HINT >= 0)
3023 rs6000_always_hint = TARGET_ALWAYS_HINT;
3025 if (TARGET_SCHED_GROUPS >= 0)
3026 rs6000_sched_groups = TARGET_SCHED_GROUPS;
3028 if (TARGET_ALIGN_BRANCH_TARGETS >= 0)
3029 rs6000_align_branch_targets = TARGET_ALIGN_BRANCH_TARGETS;
3031 rs6000_sched_restricted_insns_priority
3032 = (rs6000_sched_groups ? 1 : 0);
3034 /* Handle -msched-costly-dep option. */
3035 rs6000_sched_costly_dep
3036 = (rs6000_sched_groups ? store_to_load_dep_costly : no_dep_costly);
3038 if (rs6000_sched_costly_dep_str)
3040 if (! strcmp (rs6000_sched_costly_dep_str, "no"))
3041 rs6000_sched_costly_dep = no_dep_costly;
3042 else if (! strcmp (rs6000_sched_costly_dep_str, "all"))
3043 rs6000_sched_costly_dep = all_deps_costly;
3044 else if (! strcmp (rs6000_sched_costly_dep_str, "true_store_to_load"))
3045 rs6000_sched_costly_dep = true_store_to_load_dep_costly;
3046 else if (! strcmp (rs6000_sched_costly_dep_str, "store_to_load"))
3047 rs6000_sched_costly_dep = store_to_load_dep_costly;
3048 else
3049 rs6000_sched_costly_dep = ((enum rs6000_dependence_cost)
3050 atoi (rs6000_sched_costly_dep_str));
3053 /* Handle -minsert-sched-nops option. */
3054 rs6000_sched_insert_nops
3055 = (rs6000_sched_groups ? sched_finish_regroup_exact : sched_finish_none);
3057 if (rs6000_sched_insert_nops_str)
3059 if (! strcmp (rs6000_sched_insert_nops_str, "no"))
3060 rs6000_sched_insert_nops = sched_finish_none;
3061 else if (! strcmp (rs6000_sched_insert_nops_str, "pad"))
3062 rs6000_sched_insert_nops = sched_finish_pad_groups;
3063 else if (! strcmp (rs6000_sched_insert_nops_str, "regroup_exact"))
3064 rs6000_sched_insert_nops = sched_finish_regroup_exact;
3065 else
3066 rs6000_sched_insert_nops = ((enum rs6000_nop_insertion)
3067 atoi (rs6000_sched_insert_nops_str));
3070 if (global_init_p)
3072 #ifdef TARGET_REGNAMES
3073 /* If the user desires alternate register names, copy in the
3074 alternate names now. */
3075 if (TARGET_REGNAMES)
3076 memcpy (rs6000_reg_names, alt_reg_names, sizeof (rs6000_reg_names));
3077 #endif
3079 /* Set aix_struct_return last, after the ABI is determined.
3080 If -maix-struct-return or -msvr4-struct-return was explicitly
3081 used, don't override with the ABI default. */
3082 if (!rs6000_explicit_options.aix_struct_ret)
3083 aix_struct_return = (DEFAULT_ABI != ABI_V4 || DRAFT_V4_STRUCT_RET);
3085 #if 0
3086 /* IBM XL compiler defaults to unsigned bitfields. */
3087 if (TARGET_XL_COMPAT)
3088 flag_signed_bitfields = 0;
3089 #endif
3091 if (TARGET_LONG_DOUBLE_128 && !TARGET_IEEEQUAD)
3092 REAL_MODE_FORMAT (TFmode) = &ibm_extended_format;
3094 if (TARGET_TOC)
3095 ASM_GENERATE_INTERNAL_LABEL (toc_label_name, "LCTOC", 1);
3097 /* We can only guarantee the availability of DI pseudo-ops when
3098 assembling for 64-bit targets. */
3099 if (!TARGET_64BIT)
3101 targetm.asm_out.aligned_op.di = NULL;
3102 targetm.asm_out.unaligned_op.di = NULL;
3106 /* Set branch target alignment, if not optimizing for size. */
3107 if (!optimize_size)
3109 /* Cell wants to be aligned 8byte for dual issue. Titan wants to be
3110 aligned 8byte to avoid misprediction by the branch predictor. */
3111 if (rs6000_cpu == PROCESSOR_TITAN
3112 || rs6000_cpu == PROCESSOR_CELL)
3114 if (align_functions <= 0)
3115 align_functions = 8;
3116 if (align_jumps <= 0)
3117 align_jumps = 8;
3118 if (align_loops <= 0)
3119 align_loops = 8;
3121 if (rs6000_align_branch_targets)
3123 if (align_functions <= 0)
3124 align_functions = 16;
3125 if (align_jumps <= 0)
3126 align_jumps = 16;
3127 if (align_loops <= 0)
3129 can_override_loop_align = 1;
3130 align_loops = 16;
3133 if (align_jumps_max_skip <= 0)
3134 align_jumps_max_skip = 15;
3135 if (align_loops_max_skip <= 0)
3136 align_loops_max_skip = 15;
3139 /* Arrange to save and restore machine status around nested functions. */
3140 init_machine_status = rs6000_init_machine_status;
3142 /* We should always be splitting complex arguments, but we can't break
3143 Linux and Darwin ABIs at the moment. For now, only AIX is fixed. */
3144 if (DEFAULT_ABI != ABI_AIX)
3145 targetm.calls.split_complex_arg = NULL;
3148 /* Initialize rs6000_cost with the appropriate target costs. */
3149 if (optimize_size)
3150 rs6000_cost = TARGET_POWERPC64 ? &size64_cost : &size32_cost;
3151 else
3152 switch (rs6000_cpu)
3154 case PROCESSOR_RIOS1:
3155 rs6000_cost = &rios1_cost;
3156 break;
3158 case PROCESSOR_RIOS2:
3159 rs6000_cost = &rios2_cost;
3160 break;
3162 case PROCESSOR_RS64A:
3163 rs6000_cost = &rs64a_cost;
3164 break;
3166 case PROCESSOR_MPCCORE:
3167 rs6000_cost = &mpccore_cost;
3168 break;
3170 case PROCESSOR_PPC403:
3171 rs6000_cost = &ppc403_cost;
3172 break;
3174 case PROCESSOR_PPC405:
3175 rs6000_cost = &ppc405_cost;
3176 break;
3178 case PROCESSOR_PPC440:
3179 rs6000_cost = &ppc440_cost;
3180 break;
3182 case PROCESSOR_PPC476:
3183 rs6000_cost = &ppc476_cost;
3184 break;
3186 case PROCESSOR_PPC601:
3187 rs6000_cost = &ppc601_cost;
3188 break;
3190 case PROCESSOR_PPC603:
3191 rs6000_cost = &ppc603_cost;
3192 break;
3194 case PROCESSOR_PPC604:
3195 rs6000_cost = &ppc604_cost;
3196 break;
3198 case PROCESSOR_PPC604e:
3199 rs6000_cost = &ppc604e_cost;
3200 break;
3202 case PROCESSOR_PPC620:
3203 rs6000_cost = &ppc620_cost;
3204 break;
3206 case PROCESSOR_PPC630:
3207 rs6000_cost = &ppc630_cost;
3208 break;
3210 case PROCESSOR_CELL:
3211 rs6000_cost = &ppccell_cost;
3212 break;
3214 case PROCESSOR_PPC750:
3215 case PROCESSOR_PPC7400:
3216 rs6000_cost = &ppc750_cost;
3217 break;
3219 case PROCESSOR_PPC7450:
3220 rs6000_cost = &ppc7450_cost;
3221 break;
3223 case PROCESSOR_PPC8540:
3224 rs6000_cost = &ppc8540_cost;
3225 break;
3227 case PROCESSOR_PPCE300C2:
3228 case PROCESSOR_PPCE300C3:
3229 rs6000_cost = &ppce300c2c3_cost;
3230 break;
3232 case PROCESSOR_PPCE500MC:
3233 rs6000_cost = &ppce500mc_cost;
3234 break;
3236 case PROCESSOR_PPCE500MC64:
3237 rs6000_cost = &ppce500mc64_cost;
3238 break;
3240 case PROCESSOR_TITAN:
3241 rs6000_cost = &titan_cost;
3242 break;
3244 case PROCESSOR_POWER4:
3245 case PROCESSOR_POWER5:
3246 rs6000_cost = &power4_cost;
3247 break;
3249 case PROCESSOR_POWER6:
3250 rs6000_cost = &power6_cost;
3251 break;
3253 case PROCESSOR_POWER7:
3254 rs6000_cost = &power7_cost;
3255 break;
3257 case PROCESSOR_PPCA2:
3258 rs6000_cost = &ppca2_cost;
3259 break;
3261 default:
3262 gcc_unreachable ();
3265 if (global_init_p)
3267 maybe_set_param_value (PARAM_SIMULTANEOUS_PREFETCHES,
3268 rs6000_cost->simultaneous_prefetches,
3269 global_options.x_param_values,
3270 global_options_set.x_param_values);
3271 maybe_set_param_value (PARAM_L1_CACHE_SIZE, rs6000_cost->l1_cache_size,
3272 global_options.x_param_values,
3273 global_options_set.x_param_values);
3274 maybe_set_param_value (PARAM_L1_CACHE_LINE_SIZE,
3275 rs6000_cost->cache_line_size,
3276 global_options.x_param_values,
3277 global_options_set.x_param_values);
3278 maybe_set_param_value (PARAM_L2_CACHE_SIZE, rs6000_cost->l2_cache_size,
3279 global_options.x_param_values,
3280 global_options_set.x_param_values);
3282 /* If using typedef char *va_list, signal that
3283 __builtin_va_start (&ap, 0) can be optimized to
3284 ap = __builtin_next_arg (0). */
3285 if (DEFAULT_ABI != ABI_V4)
3286 targetm.expand_builtin_va_start = NULL;
3289 /* Set up single/double float flags.
3290 If TARGET_HARD_FLOAT is set, but neither single or double is set,
3291 then set both flags. */
3292 if (TARGET_HARD_FLOAT && TARGET_FPRS
3293 && rs6000_single_float == 0 && rs6000_double_float == 0)
3294 rs6000_single_float = rs6000_double_float = 1;
3296 /* Reset single and double FP flags if target is E500. */
3297 if (TARGET_E500)
3299 rs6000_single_float = rs6000_double_float = 0;
3300 if (TARGET_E500_SINGLE)
3301 rs6000_single_float = 1;
3302 if (TARGET_E500_DOUBLE)
3303 rs6000_single_float = rs6000_double_float = 1;
3306 if (main_target_opt)
3308 if (main_target_opt->x_rs6000_single_float != rs6000_single_float)
3309 error ("target attribute or pragma changes single precision floating "
3310 "point");
3311 if (main_target_opt->x_rs6000_double_float != rs6000_double_float)
3312 error ("target attribute or pragma changes double precision floating "
3313 "point");
3316 /* If not explicitly specified via option, decide whether to generate indexed
3317 load/store instructions. */
3318 if (TARGET_AVOID_XFORM == -1)
3319 /* Avoid indexed addressing when targeting Power6 in order to avoid
3320 the DERAT mispredict penalty. */
3321 TARGET_AVOID_XFORM = (rs6000_cpu == PROCESSOR_POWER6 && TARGET_CMPB);
3323 /* Set the -mrecip options. */
3324 if (rs6000_recip_name)
3326 char *p = ASTRDUP (rs6000_recip_name);
3327 char *q;
3328 unsigned int mask, i;
3329 bool invert;
3331 while ((q = strtok (p, ",")) != NULL)
3333 p = NULL;
3334 if (*q == '!')
3336 invert = true;
3337 q++;
3339 else
3340 invert = false;
3342 if (!strcmp (q, "default"))
3343 mask = ((TARGET_RECIP_PRECISION)
3344 ? RECIP_HIGH_PRECISION : RECIP_LOW_PRECISION);
3345 else
3347 for (i = 0; i < ARRAY_SIZE (recip_options); i++)
3348 if (!strcmp (q, recip_options[i].string))
3350 mask = recip_options[i].mask;
3351 break;
3354 if (i == ARRAY_SIZE (recip_options))
3356 error ("unknown option for -mrecip=%s", q);
3357 invert = false;
3358 mask = 0;
3359 ret = false;
3363 if (invert)
3364 rs6000_recip_control &= ~mask;
3365 else
3366 rs6000_recip_control |= mask;
3370 rs6000_init_hard_regno_mode_ok (global_init_p);
3372 /* Save the initial options in case the user does function specific options */
3373 if (global_init_p)
3374 target_option_default_node = target_option_current_node
3375 = build_target_option_node ();
3377 return ret;
3380 /* Implement TARGET_OPTION_OVERRIDE. On the RS/6000 this is used to
3381 define the target cpu type. */
3383 static void
3384 rs6000_option_override (void)
3386 (void) rs6000_option_override_internal (true);
3390 /* Implement targetm.vectorize.builtin_mask_for_load. */
3391 static tree
3392 rs6000_builtin_mask_for_load (void)
3394 if (TARGET_ALTIVEC || TARGET_VSX)
3395 return altivec_builtin_mask_for_load;
3396 else
3397 return 0;
3400 /* Implement LOOP_ALIGN. */
3402 rs6000_loop_align (rtx label)
3404 basic_block bb;
3405 int ninsns;
3407 /* Don't override loop alignment if -falign-loops was specified. */
3408 if (!can_override_loop_align)
3409 return align_loops_log;
3411 bb = BLOCK_FOR_INSN (label);
3412 ninsns = num_loop_insns(bb->loop_father);
3414 /* Align small loops to 32 bytes to fit in an icache sector, otherwise return default. */
3415 if (ninsns > 4 && ninsns <= 8
3416 && (rs6000_cpu == PROCESSOR_POWER4
3417 || rs6000_cpu == PROCESSOR_POWER5
3418 || rs6000_cpu == PROCESSOR_POWER6
3419 || rs6000_cpu == PROCESSOR_POWER7))
3420 return 5;
3421 else
3422 return align_loops_log;
3425 /* Implement TARGET_LOOP_ALIGN_MAX_SKIP. */
3426 static int
3427 rs6000_loop_align_max_skip (rtx label)
3429 return (1 << rs6000_loop_align (label)) - 1;
3432 /* Implement targetm.vectorize.builtin_conversion.
3433 Returns a decl of a function that implements conversion of an integer vector
3434 into a floating-point vector, or vice-versa. DEST_TYPE is the
3435 destination type and SRC_TYPE the source type of the conversion.
3436 Return NULL_TREE if it is not available. */
3437 static tree
3438 rs6000_builtin_conversion (unsigned int tcode, tree dest_type, tree src_type)
3440 enum tree_code code = (enum tree_code) tcode;
3442 switch (code)
3444 case FIX_TRUNC_EXPR:
3445 switch (TYPE_MODE (dest_type))
3447 case V2DImode:
3448 if (!VECTOR_UNIT_VSX_P (V2DFmode))
3449 return NULL_TREE;
3451 return TYPE_UNSIGNED (dest_type)
3452 ? rs6000_builtin_decls[VSX_BUILTIN_XVCVDPUXDS_UNS]
3453 : rs6000_builtin_decls[VSX_BUILTIN_XVCVDPSXDS];
3455 case V4SImode:
3456 if (VECTOR_UNIT_NONE_P (V4SImode) || VECTOR_UNIT_NONE_P (V4SFmode))
3457 return NULL_TREE;
3459 return TYPE_UNSIGNED (dest_type)
3460 ? rs6000_builtin_decls[VECTOR_BUILTIN_FIXUNS_V4SF_V4SI]
3461 : rs6000_builtin_decls[VECTOR_BUILTIN_FIX_V4SF_V4SI];
3463 default:
3464 return NULL_TREE;
3467 case FLOAT_EXPR:
3468 switch (TYPE_MODE (src_type))
3470 case V2DImode:
3471 if (!VECTOR_UNIT_VSX_P (V2DFmode))
3472 return NULL_TREE;
3474 return TYPE_UNSIGNED (src_type)
3475 ? rs6000_builtin_decls[VSX_BUILTIN_XVCVUXDDP]
3476 : rs6000_builtin_decls[VSX_BUILTIN_XVCVSXDDP];
3478 case V4SImode:
3479 if (VECTOR_UNIT_NONE_P (V4SImode) || VECTOR_UNIT_NONE_P (V4SFmode))
3480 return NULL_TREE;
3482 return TYPE_UNSIGNED (src_type)
3483 ? rs6000_builtin_decls[VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF]
3484 : rs6000_builtin_decls[VECTOR_BUILTIN_FLOAT_V4SI_V4SF];
3486 default:
3487 return NULL_TREE;
3490 default:
3491 return NULL_TREE;
3495 /* Implement targetm.vectorize.builtin_mul_widen_even. */
3496 static tree
3497 rs6000_builtin_mul_widen_even (tree type)
3499 if (!TARGET_ALTIVEC)
3500 return NULL_TREE;
3502 switch (TYPE_MODE (type))
3504 case V8HImode:
3505 return TYPE_UNSIGNED (type)
3506 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULEUH_UNS]
3507 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULESH];
3509 case V16QImode:
3510 return TYPE_UNSIGNED (type)
3511 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULEUB_UNS]
3512 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULESB];
3513 default:
3514 return NULL_TREE;
3518 /* Implement targetm.vectorize.builtin_mul_widen_odd. */
3519 static tree
3520 rs6000_builtin_mul_widen_odd (tree type)
3522 if (!TARGET_ALTIVEC)
3523 return NULL_TREE;
3525 switch (TYPE_MODE (type))
3527 case V8HImode:
3528 return TYPE_UNSIGNED (type)
3529 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOUH_UNS]
3530 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOSH];
3532 case V16QImode:
3533 return TYPE_UNSIGNED (type)
3534 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOUB_UNS]
3535 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOSB];
3536 default:
3537 return NULL_TREE;
3542 /* Return true iff, data reference of TYPE can reach vector alignment (16)
3543 after applying N number of iterations. This routine does not determine
3544 how may iterations are required to reach desired alignment. */
3546 static bool
3547 rs6000_vector_alignment_reachable (const_tree type ATTRIBUTE_UNUSED, bool is_packed)
3549 if (is_packed)
3550 return false;
3552 if (TARGET_32BIT)
3554 if (rs6000_alignment_flags == MASK_ALIGN_NATURAL)
3555 return true;
3557 if (rs6000_alignment_flags == MASK_ALIGN_POWER)
3558 return true;
3560 return false;
3562 else
3564 if (TARGET_MACHO)
3565 return false;
3567 /* Assuming that all other types are naturally aligned. CHECKME! */
3568 return true;
3572 /* Return true if the vector misalignment factor is supported by the
3573 target. */
3574 bool
3575 rs6000_builtin_support_vector_misalignment (enum machine_mode mode,
3576 const_tree type,
3577 int misalignment,
3578 bool is_packed)
3580 if (TARGET_VSX)
3582 /* Return if movmisalign pattern is not supported for this mode. */
3583 if (optab_handler (movmisalign_optab, mode) == CODE_FOR_nothing)
3584 return false;
3586 if (misalignment == -1)
3588 /* Misalignment factor is unknown at compile time but we know
3589 it's word aligned. */
3590 if (rs6000_vector_alignment_reachable (type, is_packed))
3592 int element_size = TREE_INT_CST_LOW (TYPE_SIZE (type));
3594 if (element_size == 64 || element_size == 32)
3595 return true;
3598 return false;
3601 /* VSX supports word-aligned vector. */
3602 if (misalignment % 4 == 0)
3603 return true;
3605 return false;
3608 /* Implement targetm.vectorize.builtin_vec_perm. */
3609 tree
3610 rs6000_builtin_vec_perm (tree type, tree *mask_element_type)
3612 tree inner_type = TREE_TYPE (type);
3613 bool uns_p = TYPE_UNSIGNED (inner_type);
3614 tree d;
3616 *mask_element_type = unsigned_char_type_node;
3618 switch (TYPE_MODE (type))
3620 case V16QImode:
3621 d = (uns_p
3622 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_16QI_UNS]
3623 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_16QI]);
3624 break;
3626 case V8HImode:
3627 d = (uns_p
3628 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_8HI_UNS]
3629 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_8HI]);
3630 break;
3632 case V4SImode:
3633 d = (uns_p
3634 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SI_UNS]
3635 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SI]);
3636 break;
3638 case V4SFmode:
3639 d = rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SF];
3640 break;
3642 case V2DFmode:
3643 if (!TARGET_ALLOW_DF_PERMUTE)
3644 return NULL_TREE;
3646 d = rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DF];
3647 break;
3649 case V2DImode:
3650 if (!TARGET_ALLOW_DF_PERMUTE)
3651 return NULL_TREE;
3653 d = (uns_p
3654 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DI_UNS]
3655 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DI]);
3656 break;
3658 default:
3659 return NULL_TREE;
3662 gcc_assert (d);
3663 return d;
3667 /* Implement targetm.vectorize.builtin_vectorization_cost. */
3668 static int
3669 rs6000_builtin_vectorization_cost (enum vect_cost_for_stmt type_of_cost,
3670 tree vectype, int misalign)
3672 unsigned elements;
3674 switch (type_of_cost)
3676 case scalar_stmt:
3677 case scalar_load:
3678 case scalar_store:
3679 case vector_stmt:
3680 case vector_load:
3681 case vector_store:
3682 case vec_to_scalar:
3683 case scalar_to_vec:
3684 case cond_branch_not_taken:
3685 case vec_perm:
3686 return 1;
3688 case cond_branch_taken:
3689 return 3;
3691 case unaligned_load:
3692 if (TARGET_VSX && TARGET_ALLOW_MOVMISALIGN)
3694 elements = TYPE_VECTOR_SUBPARTS (vectype);
3695 if (elements == 2)
3696 /* Double word aligned. */
3697 return 2;
3699 if (elements == 4)
3701 switch (misalign)
3703 case 8:
3704 /* Double word aligned. */
3705 return 2;
3707 case -1:
3708 /* Unknown misalignment. */
3709 case 4:
3710 case 12:
3711 /* Word aligned. */
3712 return 22;
3714 default:
3715 gcc_unreachable ();
3720 if (TARGET_ALTIVEC)
3721 /* Misaligned loads are not supported. */
3722 gcc_unreachable ();
3724 return 2;
3726 case unaligned_store:
3727 if (TARGET_VSX && TARGET_ALLOW_MOVMISALIGN)
3729 elements = TYPE_VECTOR_SUBPARTS (vectype);
3730 if (elements == 2)
3731 /* Double word aligned. */
3732 return 2;
3734 if (elements == 4)
3736 switch (misalign)
3738 case 8:
3739 /* Double word aligned. */
3740 return 2;
3742 case -1:
3743 /* Unknown misalignment. */
3744 case 4:
3745 case 12:
3746 /* Word aligned. */
3747 return 23;
3749 default:
3750 gcc_unreachable ();
3755 if (TARGET_ALTIVEC)
3756 /* Misaligned stores are not supported. */
3757 gcc_unreachable ();
3759 return 2;
3761 default:
3762 gcc_unreachable ();
3766 /* Implement targetm.vectorize.preferred_simd_mode. */
3768 static enum machine_mode
3769 rs6000_preferred_simd_mode (enum machine_mode mode)
3771 if (TARGET_VSX)
3772 switch (mode)
3774 case DFmode:
3775 return V2DFmode;
3776 default:;
3778 if (TARGET_ALTIVEC || TARGET_VSX)
3779 switch (mode)
3781 case SFmode:
3782 return V4SFmode;
3783 case DImode:
3784 return V2DImode;
3785 case SImode:
3786 return V4SImode;
3787 case HImode:
3788 return V8HImode;
3789 case QImode:
3790 return V16QImode;
3791 default:;
3793 if (TARGET_SPE)
3794 switch (mode)
3796 case SFmode:
3797 return V2SFmode;
3798 case SImode:
3799 return V2SImode;
3800 default:;
3802 if (TARGET_PAIRED_FLOAT
3803 && mode == SFmode)
3804 return V2SFmode;
3805 return word_mode;
3808 /* Handle generic options of the form -mfoo=yes/no.
3809 NAME is the option name.
3810 VALUE is the option value.
3811 FLAG is the pointer to the flag where to store a 1 or 0, depending on
3812 whether the option value is 'yes' or 'no' respectively. */
3813 static void
3814 rs6000_parse_yes_no_option (const char *name, const char *value, int *flag)
3816 if (value == 0)
3817 return;
3818 else if (!strcmp (value, "yes"))
3819 *flag = 1;
3820 else if (!strcmp (value, "no"))
3821 *flag = 0;
3822 else
3823 error ("unknown -m%s= option specified: '%s'", name, value);
3826 /* Implement TARGET_OPTION_INIT_STRUCT. */
3828 static void
3829 rs6000_option_init_struct (struct gcc_options *opts)
3831 if (DEFAULT_ABI == ABI_DARWIN)
3832 /* The Darwin libraries never set errno, so we might as well
3833 avoid calling them when that's the only reason we would. */
3834 opts->x_flag_errno_math = 0;
3836 /* Enable section anchors by default. */
3837 if (!TARGET_MACHO)
3838 opts->x_flag_section_anchors = 1;
3841 /* Implement TARGET_OPTION_DEFAULT_PARAMS. */
3843 static void
3844 rs6000_option_default_params (void)
3846 /* Double growth factor to counter reduced min jump length. */
3847 set_default_param_value (PARAM_MAX_GROW_COPY_BB_INSNS, 16);
3850 static enum fpu_type_t
3851 rs6000_parse_fpu_option (const char *option)
3853 if (!strcmp("none", option)) return FPU_NONE;
3854 if (!strcmp("sp_lite", option)) return FPU_SF_LITE;
3855 if (!strcmp("dp_lite", option)) return FPU_DF_LITE;
3856 if (!strcmp("sp_full", option)) return FPU_SF_FULL;
3857 if (!strcmp("dp_full", option)) return FPU_DF_FULL;
3858 error("unknown value %s for -mfpu", option);
3859 return FPU_NONE;
3863 /* Handler for the Mathematical Acceleration Subsystem (mass) interface to a
3864 library with vectorized intrinsics. */
3866 static tree
3867 rs6000_builtin_vectorized_libmass (tree fndecl, tree type_out, tree type_in)
3869 char name[32];
3870 const char *suffix = NULL;
3871 tree fntype, new_fndecl, bdecl = NULL_TREE;
3872 int n_args = 1;
3873 const char *bname;
3874 enum machine_mode el_mode, in_mode;
3875 int n, in_n;
3877 /* Libmass is suitable for unsafe math only as it does not correctly support
3878 parts of IEEE with the required precision such as denormals. Only support
3879 it if we have VSX to use the simd d2 or f4 functions.
3880 XXX: Add variable length support. */
3881 if (!flag_unsafe_math_optimizations || !TARGET_VSX)
3882 return NULL_TREE;
3884 el_mode = TYPE_MODE (TREE_TYPE (type_out));
3885 n = TYPE_VECTOR_SUBPARTS (type_out);
3886 in_mode = TYPE_MODE (TREE_TYPE (type_in));
3887 in_n = TYPE_VECTOR_SUBPARTS (type_in);
3888 if (el_mode != in_mode
3889 || n != in_n)
3890 return NULL_TREE;
3892 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
3894 enum built_in_function fn = DECL_FUNCTION_CODE (fndecl);
3895 switch (fn)
3897 case BUILT_IN_ATAN2:
3898 case BUILT_IN_HYPOT:
3899 case BUILT_IN_POW:
3900 n_args = 2;
3901 /* fall through */
3903 case BUILT_IN_ACOS:
3904 case BUILT_IN_ACOSH:
3905 case BUILT_IN_ASIN:
3906 case BUILT_IN_ASINH:
3907 case BUILT_IN_ATAN:
3908 case BUILT_IN_ATANH:
3909 case BUILT_IN_CBRT:
3910 case BUILT_IN_COS:
3911 case BUILT_IN_COSH:
3912 case BUILT_IN_ERF:
3913 case BUILT_IN_ERFC:
3914 case BUILT_IN_EXP2:
3915 case BUILT_IN_EXP:
3916 case BUILT_IN_EXPM1:
3917 case BUILT_IN_LGAMMA:
3918 case BUILT_IN_LOG10:
3919 case BUILT_IN_LOG1P:
3920 case BUILT_IN_LOG2:
3921 case BUILT_IN_LOG:
3922 case BUILT_IN_SIN:
3923 case BUILT_IN_SINH:
3924 case BUILT_IN_SQRT:
3925 case BUILT_IN_TAN:
3926 case BUILT_IN_TANH:
3927 bdecl = implicit_built_in_decls[fn];
3928 suffix = "d2"; /* pow -> powd2 */
3929 if (el_mode != DFmode
3930 || n != 2)
3931 return NULL_TREE;
3932 break;
3934 case BUILT_IN_ATAN2F:
3935 case BUILT_IN_HYPOTF:
3936 case BUILT_IN_POWF:
3937 n_args = 2;
3938 /* fall through */
3940 case BUILT_IN_ACOSF:
3941 case BUILT_IN_ACOSHF:
3942 case BUILT_IN_ASINF:
3943 case BUILT_IN_ASINHF:
3944 case BUILT_IN_ATANF:
3945 case BUILT_IN_ATANHF:
3946 case BUILT_IN_CBRTF:
3947 case BUILT_IN_COSF:
3948 case BUILT_IN_COSHF:
3949 case BUILT_IN_ERFF:
3950 case BUILT_IN_ERFCF:
3951 case BUILT_IN_EXP2F:
3952 case BUILT_IN_EXPF:
3953 case BUILT_IN_EXPM1F:
3954 case BUILT_IN_LGAMMAF:
3955 case BUILT_IN_LOG10F:
3956 case BUILT_IN_LOG1PF:
3957 case BUILT_IN_LOG2F:
3958 case BUILT_IN_LOGF:
3959 case BUILT_IN_SINF:
3960 case BUILT_IN_SINHF:
3961 case BUILT_IN_SQRTF:
3962 case BUILT_IN_TANF:
3963 case BUILT_IN_TANHF:
3964 bdecl = implicit_built_in_decls[fn];
3965 suffix = "4"; /* powf -> powf4 */
3966 if (el_mode != SFmode
3967 || n != 4)
3968 return NULL_TREE;
3969 break;
3971 default:
3972 return NULL_TREE;
3975 else
3976 return NULL_TREE;
3978 gcc_assert (suffix != NULL);
3979 bname = IDENTIFIER_POINTER (DECL_NAME (bdecl));
3980 strcpy (name, bname + sizeof ("__builtin_") - 1);
3981 strcat (name, suffix);
3983 if (n_args == 1)
3984 fntype = build_function_type_list (type_out, type_in, NULL);
3985 else if (n_args == 2)
3986 fntype = build_function_type_list (type_out, type_in, type_in, NULL);
3987 else
3988 gcc_unreachable ();
3990 /* Build a function declaration for the vectorized function. */
3991 new_fndecl = build_decl (BUILTINS_LOCATION,
3992 FUNCTION_DECL, get_identifier (name), fntype);
3993 TREE_PUBLIC (new_fndecl) = 1;
3994 DECL_EXTERNAL (new_fndecl) = 1;
3995 DECL_IS_NOVOPS (new_fndecl) = 1;
3996 TREE_READONLY (new_fndecl) = 1;
3998 return new_fndecl;
4001 /* Returns a function decl for a vectorized version of the builtin function
4002 with builtin function code FN and the result vector type TYPE, or NULL_TREE
4003 if it is not available. */
4005 static tree
4006 rs6000_builtin_vectorized_function (tree fndecl, tree type_out,
4007 tree type_in)
4009 enum machine_mode in_mode, out_mode;
4010 int in_n, out_n;
4012 if (TREE_CODE (type_out) != VECTOR_TYPE
4013 || TREE_CODE (type_in) != VECTOR_TYPE
4014 || !TARGET_VECTORIZE_BUILTINS)
4015 return NULL_TREE;
4017 out_mode = TYPE_MODE (TREE_TYPE (type_out));
4018 out_n = TYPE_VECTOR_SUBPARTS (type_out);
4019 in_mode = TYPE_MODE (TREE_TYPE (type_in));
4020 in_n = TYPE_VECTOR_SUBPARTS (type_in);
4022 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
4024 enum built_in_function fn = DECL_FUNCTION_CODE (fndecl);
4025 switch (fn)
4027 case BUILT_IN_COPYSIGN:
4028 if (VECTOR_UNIT_VSX_P (V2DFmode)
4029 && out_mode == DFmode && out_n == 2
4030 && in_mode == DFmode && in_n == 2)
4031 return rs6000_builtin_decls[VSX_BUILTIN_CPSGNDP];
4032 break;
4033 case BUILT_IN_COPYSIGNF:
4034 if (out_mode != SFmode || out_n != 4
4035 || in_mode != SFmode || in_n != 4)
4036 break;
4037 if (VECTOR_UNIT_VSX_P (V4SFmode))
4038 return rs6000_builtin_decls[VSX_BUILTIN_CPSGNSP];
4039 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
4040 return rs6000_builtin_decls[ALTIVEC_BUILTIN_COPYSIGN_V4SF];
4041 break;
4042 case BUILT_IN_SQRT:
4043 if (VECTOR_UNIT_VSX_P (V2DFmode)
4044 && out_mode == DFmode && out_n == 2
4045 && in_mode == DFmode && in_n == 2)
4046 return rs6000_builtin_decls[VSX_BUILTIN_XVSQRTDP];
4047 break;
4048 case BUILT_IN_SQRTF:
4049 if (VECTOR_UNIT_VSX_P (V4SFmode)
4050 && out_mode == SFmode && out_n == 4
4051 && in_mode == SFmode && in_n == 4)
4052 return rs6000_builtin_decls[VSX_BUILTIN_XVSQRTSP];
4053 break;
4054 case BUILT_IN_CEIL:
4055 if (VECTOR_UNIT_VSX_P (V2DFmode)
4056 && out_mode == DFmode && out_n == 2
4057 && in_mode == DFmode && in_n == 2)
4058 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIP];
4059 break;
4060 case BUILT_IN_CEILF:
4061 if (out_mode != SFmode || out_n != 4
4062 || in_mode != SFmode || in_n != 4)
4063 break;
4064 if (VECTOR_UNIT_VSX_P (V4SFmode))
4065 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIP];
4066 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
4067 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIP];
4068 break;
4069 case BUILT_IN_FLOOR:
4070 if (VECTOR_UNIT_VSX_P (V2DFmode)
4071 && out_mode == DFmode && out_n == 2
4072 && in_mode == DFmode && in_n == 2)
4073 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIM];
4074 break;
4075 case BUILT_IN_FLOORF:
4076 if (out_mode != SFmode || out_n != 4
4077 || in_mode != SFmode || in_n != 4)
4078 break;
4079 if (VECTOR_UNIT_VSX_P (V4SFmode))
4080 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIM];
4081 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
4082 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIM];
4083 break;
4084 case BUILT_IN_FMA:
4085 if (VECTOR_UNIT_VSX_P (V2DFmode)
4086 && out_mode == DFmode && out_n == 2
4087 && in_mode == DFmode && in_n == 2)
4088 return rs6000_builtin_decls[VSX_BUILTIN_XVMADDDP];
4089 break;
4090 case BUILT_IN_FMAF:
4091 if (VECTOR_UNIT_VSX_P (V4SFmode)
4092 && out_mode == SFmode && out_n == 4
4093 && in_mode == SFmode && in_n == 4)
4094 return rs6000_builtin_decls[VSX_BUILTIN_XVMADDSP];
4095 else if (VECTOR_UNIT_ALTIVEC_P (V4SFmode)
4096 && out_mode == SFmode && out_n == 4
4097 && in_mode == SFmode && in_n == 4)
4098 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VMADDFP];
4099 break;
4100 case BUILT_IN_TRUNC:
4101 if (VECTOR_UNIT_VSX_P (V2DFmode)
4102 && out_mode == DFmode && out_n == 2
4103 && in_mode == DFmode && in_n == 2)
4104 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIZ];
4105 break;
4106 case BUILT_IN_TRUNCF:
4107 if (out_mode != SFmode || out_n != 4
4108 || in_mode != SFmode || in_n != 4)
4109 break;
4110 if (VECTOR_UNIT_VSX_P (V4SFmode))
4111 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIZ];
4112 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
4113 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIZ];
4114 break;
4115 case BUILT_IN_NEARBYINT:
4116 if (VECTOR_UNIT_VSX_P (V2DFmode)
4117 && flag_unsafe_math_optimizations
4118 && out_mode == DFmode && out_n == 2
4119 && in_mode == DFmode && in_n == 2)
4120 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPI];
4121 break;
4122 case BUILT_IN_NEARBYINTF:
4123 if (VECTOR_UNIT_VSX_P (V4SFmode)
4124 && flag_unsafe_math_optimizations
4125 && out_mode == SFmode && out_n == 4
4126 && in_mode == SFmode && in_n == 4)
4127 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPI];
4128 break;
4129 case BUILT_IN_RINT:
4130 if (VECTOR_UNIT_VSX_P (V2DFmode)
4131 && !flag_trapping_math
4132 && out_mode == DFmode && out_n == 2
4133 && in_mode == DFmode && in_n == 2)
4134 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIC];
4135 break;
4136 case BUILT_IN_RINTF:
4137 if (VECTOR_UNIT_VSX_P (V4SFmode)
4138 && !flag_trapping_math
4139 && out_mode == SFmode && out_n == 4
4140 && in_mode == SFmode && in_n == 4)
4141 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIC];
4142 break;
4143 default:
4144 break;
4148 else if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
4150 enum rs6000_builtins fn
4151 = (enum rs6000_builtins)DECL_FUNCTION_CODE (fndecl);
4152 switch (fn)
4154 case RS6000_BUILTIN_RSQRTF:
4155 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)
4156 && out_mode == SFmode && out_n == 4
4157 && in_mode == SFmode && in_n == 4)
4158 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRSQRTFP];
4159 break;
4160 case RS6000_BUILTIN_RSQRT:
4161 if (VECTOR_UNIT_VSX_P (V2DFmode)
4162 && out_mode == DFmode && out_n == 2
4163 && in_mode == DFmode && in_n == 2)
4164 return rs6000_builtin_decls[VSX_BUILTIN_VEC_RSQRT_V2DF];
4165 break;
4166 case RS6000_BUILTIN_RECIPF:
4167 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)
4168 && out_mode == SFmode && out_n == 4
4169 && in_mode == SFmode && in_n == 4)
4170 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRECIPFP];
4171 break;
4172 case RS6000_BUILTIN_RECIP:
4173 if (VECTOR_UNIT_VSX_P (V2DFmode)
4174 && out_mode == DFmode && out_n == 2
4175 && in_mode == DFmode && in_n == 2)
4176 return rs6000_builtin_decls[VSX_BUILTIN_RECIP_V2DF];
4177 break;
4178 default:
4179 break;
4183 /* Generate calls to libmass if appropriate. */
4184 if (rs6000_veclib_handler)
4185 return rs6000_veclib_handler (fndecl, type_out, type_in);
4187 return NULL_TREE;
4191 /* Implement TARGET_HANDLE_OPTION. */
4193 static bool
4194 rs6000_handle_option (size_t code, const char *arg, int value)
4196 enum fpu_type_t fpu_type = FPU_NONE;
4197 int isel;
4198 char *p, *q;
4200 switch (code)
4202 case OPT_mno_power:
4203 target_flags &= ~(MASK_POWER | MASK_POWER2
4204 | MASK_MULTIPLE | MASK_STRING);
4205 target_flags_explicit |= (MASK_POWER | MASK_POWER2
4206 | MASK_MULTIPLE | MASK_STRING);
4207 break;
4208 case OPT_mno_powerpc:
4209 target_flags &= ~(MASK_POWERPC | MASK_PPC_GPOPT
4210 | MASK_PPC_GFXOPT | MASK_POWERPC64);
4211 target_flags_explicit |= (MASK_POWERPC | MASK_PPC_GPOPT
4212 | MASK_PPC_GFXOPT | MASK_POWERPC64);
4213 break;
4214 case OPT_mfull_toc:
4215 target_flags &= ~MASK_MINIMAL_TOC;
4216 TARGET_NO_FP_IN_TOC = 0;
4217 TARGET_NO_SUM_IN_TOC = 0;
4218 target_flags_explicit |= MASK_MINIMAL_TOC;
4219 #ifdef TARGET_USES_SYSV4_OPT
4220 /* Note, V.4 no longer uses a normal TOC, so make -mfull-toc, be
4221 just the same as -mminimal-toc. */
4222 target_flags |= MASK_MINIMAL_TOC;
4223 target_flags_explicit |= MASK_MINIMAL_TOC;
4224 #endif
4225 break;
4227 #ifdef TARGET_USES_SYSV4_OPT
4228 case OPT_mtoc:
4229 /* Make -mtoc behave like -mminimal-toc. */
4230 target_flags |= MASK_MINIMAL_TOC;
4231 target_flags_explicit |= MASK_MINIMAL_TOC;
4232 break;
4233 #endif
4235 #if defined (HAVE_LD_LARGE_TOC) && defined (TARGET_USES_LINUX64_OPT)
4236 case OPT_mcmodel_:
4237 if (strcmp (arg, "small") == 0)
4238 rs6000_current_cmodel = CMODEL_SMALL;
4239 else if (strcmp (arg, "medium") == 0)
4240 rs6000_current_cmodel = CMODEL_MEDIUM;
4241 else if (strcmp (arg, "large") == 0)
4242 rs6000_current_cmodel = CMODEL_LARGE;
4243 else
4245 error ("invalid option for -mcmodel: '%s'", arg);
4246 return false;
4248 rs6000_explicit_options.cmodel = true;
4249 #endif
4251 #ifdef TARGET_USES_AIX64_OPT
4252 case OPT_maix64:
4253 #else
4254 case OPT_m64:
4255 #endif
4256 target_flags |= MASK_POWERPC64 | MASK_POWERPC;
4257 target_flags |= ~target_flags_explicit & MASK_PPC_GFXOPT;
4258 target_flags_explicit |= MASK_POWERPC64 | MASK_POWERPC;
4259 break;
4261 #ifdef TARGET_USES_AIX64_OPT
4262 case OPT_maix32:
4263 #else
4264 case OPT_m32:
4265 #endif
4266 target_flags &= ~MASK_POWERPC64;
4267 target_flags_explicit |= MASK_POWERPC64;
4268 break;
4270 case OPT_minsert_sched_nops_:
4271 rs6000_sched_insert_nops_str = arg;
4272 break;
4274 case OPT_mminimal_toc:
4275 if (value == 1)
4277 TARGET_NO_FP_IN_TOC = 0;
4278 TARGET_NO_SUM_IN_TOC = 0;
4280 break;
4282 case OPT_mpower:
4283 if (value == 1)
4285 target_flags |= (MASK_MULTIPLE | MASK_STRING);
4286 target_flags_explicit |= (MASK_MULTIPLE | MASK_STRING);
4288 break;
4290 case OPT_mpower2:
4291 if (value == 1)
4293 target_flags |= (MASK_POWER | MASK_MULTIPLE | MASK_STRING);
4294 target_flags_explicit |= (MASK_POWER | MASK_MULTIPLE | MASK_STRING);
4296 break;
4298 case OPT_mpowerpc_gpopt:
4299 case OPT_mpowerpc_gfxopt:
4300 if (value == 1)
4302 target_flags |= MASK_POWERPC;
4303 target_flags_explicit |= MASK_POWERPC;
4305 break;
4307 case OPT_maix_struct_return:
4308 case OPT_msvr4_struct_return:
4309 rs6000_explicit_options.aix_struct_ret = true;
4310 break;
4312 case OPT_mvrsave:
4313 rs6000_explicit_options.vrsave = true;
4314 TARGET_ALTIVEC_VRSAVE = value;
4315 break;
4317 case OPT_mvrsave_:
4318 rs6000_explicit_options.vrsave = true;
4319 rs6000_parse_yes_no_option ("vrsave", arg, &(TARGET_ALTIVEC_VRSAVE));
4320 break;
4322 case OPT_misel_:
4323 target_flags_explicit |= MASK_ISEL;
4324 isel = 0;
4325 rs6000_parse_yes_no_option ("isel", arg, &isel);
4326 if (isel)
4327 target_flags |= MASK_ISEL;
4328 else
4329 target_flags &= ~MASK_ISEL;
4330 break;
4332 case OPT_mspe:
4333 rs6000_explicit_options.spe = true;
4334 rs6000_spe = value;
4335 break;
4337 case OPT_mspe_:
4338 rs6000_explicit_options.spe = true;
4339 rs6000_parse_yes_no_option ("spe", arg, &(rs6000_spe));
4340 break;
4342 case OPT_mdebug_:
4343 p = ASTRDUP (arg);
4344 rs6000_debug = 0;
4346 while ((q = strtok (p, ",")) != NULL)
4348 unsigned mask = 0;
4349 bool invert;
4351 p = NULL;
4352 if (*q == '!')
4354 invert = true;
4355 q++;
4357 else
4358 invert = false;
4360 if (! strcmp (q, "all"))
4361 mask = MASK_DEBUG_ALL;
4362 else if (! strcmp (q, "stack"))
4363 mask = MASK_DEBUG_STACK;
4364 else if (! strcmp (q, "arg"))
4365 mask = MASK_DEBUG_ARG;
4366 else if (! strcmp (q, "reg"))
4367 mask = MASK_DEBUG_REG;
4368 else if (! strcmp (q, "addr"))
4369 mask = MASK_DEBUG_ADDR;
4370 else if (! strcmp (q, "cost"))
4371 mask = MASK_DEBUG_COST;
4372 else if (! strcmp (q, "target"))
4373 mask = MASK_DEBUG_TARGET;
4374 else
4375 error ("unknown -mdebug-%s switch", q);
4377 if (invert)
4378 rs6000_debug &= ~mask;
4379 else
4380 rs6000_debug |= mask;
4382 break;
4384 #ifdef TARGET_USES_SYSV4_OPT
4385 case OPT_mcall_:
4386 rs6000_abi_name = arg;
4387 break;
4389 case OPT_msdata_:
4390 rs6000_sdata_name = arg;
4391 break;
4393 case OPT_mtls_size_:
4394 if (strcmp (arg, "16") == 0)
4395 rs6000_tls_size = 16;
4396 else if (strcmp (arg, "32") == 0)
4397 rs6000_tls_size = 32;
4398 else if (strcmp (arg, "64") == 0)
4399 rs6000_tls_size = 64;
4400 else
4401 error ("bad value %qs for -mtls-size switch", arg);
4402 break;
4404 case OPT_mrelocatable:
4405 if (value == 1)
4407 target_flags |= MASK_MINIMAL_TOC;
4408 target_flags_explicit |= MASK_MINIMAL_TOC;
4409 TARGET_NO_FP_IN_TOC = 1;
4411 break;
4413 case OPT_mrelocatable_lib:
4414 if (value == 1)
4416 target_flags |= MASK_RELOCATABLE | MASK_MINIMAL_TOC;
4417 target_flags_explicit |= MASK_RELOCATABLE | MASK_MINIMAL_TOC;
4418 TARGET_NO_FP_IN_TOC = 1;
4420 else
4422 target_flags &= ~MASK_RELOCATABLE;
4423 target_flags_explicit |= MASK_RELOCATABLE;
4425 break;
4426 #endif
4428 case OPT_mabi_:
4429 if (!strcmp (arg, "altivec"))
4431 rs6000_explicit_options.altivec_abi = true;
4432 rs6000_altivec_abi = 1;
4434 /* Enabling the AltiVec ABI turns off the SPE ABI. */
4435 rs6000_spe_abi = 0;
4437 else if (! strcmp (arg, "no-altivec"))
4439 rs6000_explicit_options.altivec_abi = true;
4440 rs6000_altivec_abi = 0;
4442 else if (! strcmp (arg, "spe"))
4444 rs6000_explicit_options.spe_abi = true;
4445 rs6000_spe_abi = 1;
4446 rs6000_altivec_abi = 0;
4447 if (!TARGET_SPE_ABI)
4448 error ("not configured for ABI: '%s'", arg);
4450 else if (! strcmp (arg, "no-spe"))
4452 rs6000_explicit_options.spe_abi = true;
4453 rs6000_spe_abi = 0;
4456 /* These are here for testing during development only, do not
4457 document in the manual please. */
4458 else if (! strcmp (arg, "d64"))
4460 rs6000_darwin64_abi = 1;
4461 warning (0, "using darwin64 ABI");
4463 else if (! strcmp (arg, "d32"))
4465 rs6000_darwin64_abi = 0;
4466 warning (0, "using old darwin ABI");
4469 else if (! strcmp (arg, "ibmlongdouble"))
4471 rs6000_explicit_options.ieee = true;
4472 rs6000_ieeequad = 0;
4473 warning (0, "using IBM extended precision long double");
4475 else if (! strcmp (arg, "ieeelongdouble"))
4477 rs6000_explicit_options.ieee = true;
4478 rs6000_ieeequad = 1;
4479 warning (0, "using IEEE extended precision long double");
4482 else
4484 error ("unknown ABI specified: '%s'", arg);
4485 return false;
4487 break;
4489 case OPT_mcpu_:
4490 rs6000_select[1].string = arg;
4491 rs6000_cpu_index = rs6000_cpu_name_lookup (arg);
4492 if (rs6000_cpu_index < 0)
4493 error ("bad value (%s) for -mcpu", arg);
4494 break;
4496 case OPT_mtune_:
4497 rs6000_select[2].string = arg;
4498 rs6000_tune_index = rs6000_cpu_name_lookup (arg);
4499 if (rs6000_tune_index < 0)
4500 error ("bad value (%s) for -mtune", arg);
4501 break;
4503 case OPT_mtraceback_:
4504 if (! strncmp (arg, "full", 4))
4505 rs6000_traceback = traceback_full;
4506 else if (! strncmp (arg, "part", 4))
4507 rs6000_traceback = traceback_part;
4508 else if (! strncmp (arg, "no", 2))
4509 rs6000_traceback = traceback_none;
4510 else
4511 error ("unknown -mtraceback arg %qs; expecting %<full%>, "
4512 "%<partial%> or %<none%>", arg);
4513 break;
4515 case OPT_mfloat_gprs_:
4516 rs6000_explicit_options.float_gprs = true;
4517 if (! strcmp (arg, "yes") || ! strcmp (arg, "single"))
4518 rs6000_float_gprs = 1;
4519 else if (! strcmp (arg, "double"))
4520 rs6000_float_gprs = 2;
4521 else if (! strcmp (arg, "no"))
4522 rs6000_float_gprs = 0;
4523 else
4525 error ("invalid option for -mfloat-gprs: '%s'", arg);
4526 return false;
4528 break;
4530 case OPT_mlong_double_:
4531 rs6000_explicit_options.long_double = true;
4532 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
4533 if (value != 64 && value != 128)
4535 error ("unknown switch -mlong-double-%s", arg);
4536 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
4537 return false;
4539 else
4540 rs6000_long_double_type_size = value;
4541 break;
4543 case OPT_msched_costly_dep_:
4544 rs6000_sched_costly_dep_str = arg;
4545 break;
4547 case OPT_malign_:
4548 rs6000_explicit_options.alignment = true;
4549 if (! strcmp (arg, "power"))
4551 /* On 64-bit Darwin, power alignment is ABI-incompatible with
4552 some C library functions, so warn about it. The flag may be
4553 useful for performance studies from time to time though, so
4554 don't disable it entirely. */
4555 if (DEFAULT_ABI == ABI_DARWIN && TARGET_64BIT)
4556 warning (0, "-malign-power is not supported for 64-bit Darwin;"
4557 " it is incompatible with the installed C and C++ libraries");
4558 rs6000_alignment_flags = MASK_ALIGN_POWER;
4560 else if (! strcmp (arg, "natural"))
4561 rs6000_alignment_flags = MASK_ALIGN_NATURAL;
4562 else
4564 error ("unknown -malign-XXXXX option specified: '%s'", arg);
4565 return false;
4567 break;
4569 case OPT_msingle_float:
4570 if (!TARGET_SINGLE_FPU)
4571 warning (0, "-msingle-float option equivalent to -mhard-float");
4572 /* -msingle-float implies -mno-double-float and TARGET_HARD_FLOAT. */
4573 rs6000_double_float = 0;
4574 target_flags &= ~MASK_SOFT_FLOAT;
4575 target_flags_explicit |= MASK_SOFT_FLOAT;
4576 break;
4578 case OPT_mdouble_float:
4579 /* -mdouble-float implies -msingle-float and TARGET_HARD_FLOAT. */
4580 rs6000_single_float = 1;
4581 target_flags &= ~MASK_SOFT_FLOAT;
4582 target_flags_explicit |= MASK_SOFT_FLOAT;
4583 break;
4585 case OPT_msimple_fpu:
4586 if (!TARGET_SINGLE_FPU)
4587 warning (0, "-msimple-fpu option ignored");
4588 break;
4590 case OPT_mhard_float:
4591 /* -mhard_float implies -msingle-float and -mdouble-float. */
4592 rs6000_single_float = rs6000_double_float = 1;
4593 break;
4595 case OPT_msoft_float:
4596 /* -msoft_float implies -mnosingle-float and -mnodouble-float. */
4597 rs6000_single_float = rs6000_double_float = 0;
4598 break;
4600 case OPT_mfpu_:
4601 fpu_type = rs6000_parse_fpu_option(arg);
4602 if (fpu_type != FPU_NONE)
4603 /* If -mfpu is not none, then turn off SOFT_FLOAT, turn on HARD_FLOAT. */
4605 target_flags &= ~MASK_SOFT_FLOAT;
4606 target_flags_explicit |= MASK_SOFT_FLOAT;
4607 rs6000_xilinx_fpu = 1;
4608 if (fpu_type == FPU_SF_LITE || fpu_type == FPU_SF_FULL)
4609 rs6000_single_float = 1;
4610 if (fpu_type == FPU_DF_LITE || fpu_type == FPU_DF_FULL)
4611 rs6000_single_float = rs6000_double_float = 1;
4612 if (fpu_type == FPU_SF_LITE || fpu_type == FPU_DF_LITE)
4613 rs6000_simple_fpu = 1;
4615 else
4617 /* -mfpu=none is equivalent to -msoft-float */
4618 target_flags |= MASK_SOFT_FLOAT;
4619 target_flags_explicit |= MASK_SOFT_FLOAT;
4620 rs6000_single_float = rs6000_double_float = 0;
4623 case OPT_mrecip:
4624 rs6000_recip_name = (value) ? "default" : "none";
4625 break;
4627 case OPT_mrecip_:
4628 rs6000_recip_name = arg;
4629 break;
4631 return true;
4634 /* Do anything needed at the start of the asm file. */
4636 static void
4637 rs6000_file_start (void)
4639 size_t i;
4640 char buffer[80];
4641 const char *start = buffer;
4642 struct rs6000_cpu_select *ptr;
4643 const char *default_cpu = TARGET_CPU_DEFAULT;
4644 FILE *file = asm_out_file;
4646 default_file_start ();
4648 #ifdef TARGET_BI_ARCH
4649 if ((TARGET_DEFAULT ^ target_flags) & MASK_64BIT)
4650 default_cpu = 0;
4651 #endif
4653 if (flag_verbose_asm)
4655 sprintf (buffer, "\n%s rs6000/powerpc options:", ASM_COMMENT_START);
4656 rs6000_select[0].string = default_cpu;
4658 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
4660 ptr = &rs6000_select[i];
4661 if (ptr->string != (char *)0 && ptr->string[0] != '\0')
4663 fprintf (file, "%s %s%s", start, ptr->name, ptr->string);
4664 start = "";
4668 if (PPC405_ERRATUM77)
4670 fprintf (file, "%s PPC405CR_ERRATUM77", start);
4671 start = "";
4674 #ifdef USING_ELFOS_H
4675 switch (rs6000_sdata)
4677 case SDATA_NONE: fprintf (file, "%s -msdata=none", start); start = ""; break;
4678 case SDATA_DATA: fprintf (file, "%s -msdata=data", start); start = ""; break;
4679 case SDATA_SYSV: fprintf (file, "%s -msdata=sysv", start); start = ""; break;
4680 case SDATA_EABI: fprintf (file, "%s -msdata=eabi", start); start = ""; break;
4683 if (rs6000_sdata && g_switch_value)
4685 fprintf (file, "%s -G %d", start,
4686 g_switch_value);
4687 start = "";
4689 #endif
4691 if (*start == '\0')
4692 putc ('\n', file);
4695 #ifdef HAVE_AS_GNU_ATTRIBUTE
4696 if (TARGET_32BIT && DEFAULT_ABI == ABI_V4)
4698 fprintf (file, "\t.gnu_attribute 4, %d\n",
4699 ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT) ? 1
4700 : (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT) ? 3
4701 : 2));
4702 fprintf (file, "\t.gnu_attribute 8, %d\n",
4703 (TARGET_ALTIVEC_ABI ? 2
4704 : TARGET_SPE_ABI ? 3
4705 : 1));
4706 fprintf (file, "\t.gnu_attribute 12, %d\n",
4707 aix_struct_return ? 2 : 1);
4710 #endif
4712 if (DEFAULT_ABI == ABI_AIX || (TARGET_ELF && flag_pic == 2))
4714 switch_to_section (toc_section);
4715 switch_to_section (text_section);
4720 /* Return nonzero if this function is known to have a null epilogue. */
4723 direct_return (void)
4725 if (reload_completed)
4727 rs6000_stack_t *info = rs6000_stack_info ();
4729 if (info->first_gp_reg_save == 32
4730 && info->first_fp_reg_save == 64
4731 && info->first_altivec_reg_save == LAST_ALTIVEC_REGNO + 1
4732 && ! info->lr_save_p
4733 && ! info->cr_save_p
4734 && info->vrsave_mask == 0
4735 && ! info->push_p)
4736 return 1;
4739 return 0;
4742 /* Return the number of instructions it takes to form a constant in an
4743 integer register. */
4746 num_insns_constant_wide (HOST_WIDE_INT value)
4748 /* signed constant loadable with {cal|addi} */
4749 if ((unsigned HOST_WIDE_INT) (value + 0x8000) < 0x10000)
4750 return 1;
4752 /* constant loadable with {cau|addis} */
4753 else if ((value & 0xffff) == 0
4754 && (value >> 31 == -1 || value >> 31 == 0))
4755 return 1;
4757 #if HOST_BITS_PER_WIDE_INT == 64
4758 else if (TARGET_POWERPC64)
4760 HOST_WIDE_INT low = ((value & 0xffffffff) ^ 0x80000000) - 0x80000000;
4761 HOST_WIDE_INT high = value >> 31;
4763 if (high == 0 || high == -1)
4764 return 2;
4766 high >>= 1;
4768 if (low == 0)
4769 return num_insns_constant_wide (high) + 1;
4770 else if (high == 0)
4771 return num_insns_constant_wide (low) + 1;
4772 else
4773 return (num_insns_constant_wide (high)
4774 + num_insns_constant_wide (low) + 1);
4776 #endif
4778 else
4779 return 2;
4783 num_insns_constant (rtx op, enum machine_mode mode)
4785 HOST_WIDE_INT low, high;
4787 switch (GET_CODE (op))
4789 case CONST_INT:
4790 #if HOST_BITS_PER_WIDE_INT == 64
4791 if ((INTVAL (op) >> 31) != 0 && (INTVAL (op) >> 31) != -1
4792 && mask64_operand (op, mode))
4793 return 2;
4794 else
4795 #endif
4796 return num_insns_constant_wide (INTVAL (op));
4798 case CONST_DOUBLE:
4799 if (mode == SFmode || mode == SDmode)
4801 long l;
4802 REAL_VALUE_TYPE rv;
4804 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
4805 if (DECIMAL_FLOAT_MODE_P (mode))
4806 REAL_VALUE_TO_TARGET_DECIMAL32 (rv, l);
4807 else
4808 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
4809 return num_insns_constant_wide ((HOST_WIDE_INT) l);
4812 if (mode == VOIDmode || mode == DImode)
4814 high = CONST_DOUBLE_HIGH (op);
4815 low = CONST_DOUBLE_LOW (op);
4817 else
4819 long l[2];
4820 REAL_VALUE_TYPE rv;
4822 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
4823 if (DECIMAL_FLOAT_MODE_P (mode))
4824 REAL_VALUE_TO_TARGET_DECIMAL64 (rv, l);
4825 else
4826 REAL_VALUE_TO_TARGET_DOUBLE (rv, l);
4827 high = l[WORDS_BIG_ENDIAN == 0];
4828 low = l[WORDS_BIG_ENDIAN != 0];
4831 if (TARGET_32BIT)
4832 return (num_insns_constant_wide (low)
4833 + num_insns_constant_wide (high));
4834 else
4836 if ((high == 0 && low >= 0)
4837 || (high == -1 && low < 0))
4838 return num_insns_constant_wide (low);
4840 else if (mask64_operand (op, mode))
4841 return 2;
4843 else if (low == 0)
4844 return num_insns_constant_wide (high) + 1;
4846 else
4847 return (num_insns_constant_wide (high)
4848 + num_insns_constant_wide (low) + 1);
4851 default:
4852 gcc_unreachable ();
4856 /* Interpret element ELT of the CONST_VECTOR OP as an integer value.
4857 If the mode of OP is MODE_VECTOR_INT, this simply returns the
4858 corresponding element of the vector, but for V4SFmode and V2SFmode,
4859 the corresponding "float" is interpreted as an SImode integer. */
4861 HOST_WIDE_INT
4862 const_vector_elt_as_int (rtx op, unsigned int elt)
4864 rtx 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 = GET_MODE_NUNITS (mode);
4886 unsigned bitsize = GET_MODE_BITSIZE (inner);
4887 unsigned mask = GET_MODE_MASK (inner);
4889 HOST_WIDE_INT val = const_vector_elt_as_int (op, nunits - 1);
4890 HOST_WIDE_INT splat_val = val;
4891 HOST_WIDE_INT msb_val = val > 0 ? 0 : -1;
4893 /* Construct the value to be splatted, if possible. If not, return 0. */
4894 for (i = 2; i <= copies; i *= 2)
4896 HOST_WIDE_INT small_val;
4897 bitsize /= 2;
4898 small_val = splat_val >> bitsize;
4899 mask >>= bitsize;
4900 if (splat_val != ((small_val << bitsize) | (small_val & mask)))
4901 return false;
4902 splat_val = small_val;
4905 /* Check if SPLAT_VAL can really be the operand of a vspltis[bhw]. */
4906 if (EASY_VECTOR_15 (splat_val))
4909 /* Also check if we can splat, and then add the result to itself. Do so if
4910 the value is positive, of if the splat instruction is using OP's mode;
4911 for splat_val < 0, the splat and the add should use the same mode. */
4912 else if (EASY_VECTOR_15_ADD_SELF (splat_val)
4913 && (splat_val >= 0 || (step == 1 && copies == 1)))
4916 /* Also check if are loading up the most significant bit which can be done by
4917 loading up -1 and shifting the value left by -1. */
4918 else if (EASY_VECTOR_MSB (splat_val, inner))
4921 else
4922 return false;
4924 /* Check if VAL is present in every STEP-th element, and the
4925 other elements are filled with its most significant bit. */
4926 for (i = 0; i < nunits - 1; ++i)
4928 HOST_WIDE_INT desired_val;
4929 if (((i + 1) & (step - 1)) == 0)
4930 desired_val = val;
4931 else
4932 desired_val = msb_val;
4934 if (desired_val != const_vector_elt_as_int (op, i))
4935 return false;
4938 return true;
4942 /* Return true if OP is of the given MODE and can be synthesized
4943 with a vspltisb, vspltish or vspltisw. */
4945 bool
4946 easy_altivec_constant (rtx op, enum machine_mode mode)
4948 unsigned step, copies;
4950 if (mode == VOIDmode)
4951 mode = GET_MODE (op);
4952 else if (mode != GET_MODE (op))
4953 return false;
4955 /* Start with a vspltisw. */
4956 step = GET_MODE_NUNITS (mode) / 4;
4957 copies = 1;
4959 if (vspltis_constant (op, step, copies))
4960 return true;
4962 /* Then try with a vspltish. */
4963 if (step == 1)
4964 copies <<= 1;
4965 else
4966 step >>= 1;
4968 if (vspltis_constant (op, step, copies))
4969 return true;
4971 /* And finally a vspltisb. */
4972 if (step == 1)
4973 copies <<= 1;
4974 else
4975 step >>= 1;
4977 if (vspltis_constant (op, step, copies))
4978 return true;
4980 return false;
4983 /* Generate a VEC_DUPLICATE representing a vspltis[bhw] instruction whose
4984 result is OP. Abort if it is not possible. */
4987 gen_easy_altivec_constant (rtx op)
4989 enum machine_mode mode = GET_MODE (op);
4990 int nunits = GET_MODE_NUNITS (mode);
4991 rtx last = CONST_VECTOR_ELT (op, nunits - 1);
4992 unsigned step = nunits / 4;
4993 unsigned copies = 1;
4995 /* Start with a vspltisw. */
4996 if (vspltis_constant (op, step, copies))
4997 return gen_rtx_VEC_DUPLICATE (V4SImode, gen_lowpart (SImode, last));
4999 /* Then try with a vspltish. */
5000 if (step == 1)
5001 copies <<= 1;
5002 else
5003 step >>= 1;
5005 if (vspltis_constant (op, step, copies))
5006 return gen_rtx_VEC_DUPLICATE (V8HImode, gen_lowpart (HImode, last));
5008 /* And finally a vspltisb. */
5009 if (step == 1)
5010 copies <<= 1;
5011 else
5012 step >>= 1;
5014 if (vspltis_constant (op, step, copies))
5015 return gen_rtx_VEC_DUPLICATE (V16QImode, gen_lowpart (QImode, last));
5017 gcc_unreachable ();
5020 const char *
5021 output_vec_const_move (rtx *operands)
5023 int cst, cst2;
5024 enum machine_mode mode;
5025 rtx dest, vec;
5027 dest = operands[0];
5028 vec = operands[1];
5029 mode = GET_MODE (dest);
5031 if (TARGET_VSX && zero_constant (vec, mode))
5032 return "xxlxor %x0,%x0,%x0";
5034 if (TARGET_ALTIVEC)
5036 rtx splat_vec;
5037 if (zero_constant (vec, mode))
5038 return "vxor %0,%0,%0";
5040 splat_vec = gen_easy_altivec_constant (vec);
5041 gcc_assert (GET_CODE (splat_vec) == VEC_DUPLICATE);
5042 operands[1] = XEXP (splat_vec, 0);
5043 if (!EASY_VECTOR_15 (INTVAL (operands[1])))
5044 return "#";
5046 switch (GET_MODE (splat_vec))
5048 case V4SImode:
5049 return "vspltisw %0,%1";
5051 case V8HImode:
5052 return "vspltish %0,%1";
5054 case V16QImode:
5055 return "vspltisb %0,%1";
5057 default:
5058 gcc_unreachable ();
5062 gcc_assert (TARGET_SPE);
5064 /* Vector constant 0 is handled as a splitter of V2SI, and in the
5065 pattern of V1DI, V4HI, and V2SF.
5067 FIXME: We should probably return # and add post reload
5068 splitters for these, but this way is so easy ;-). */
5069 cst = INTVAL (CONST_VECTOR_ELT (vec, 0));
5070 cst2 = INTVAL (CONST_VECTOR_ELT (vec, 1));
5071 operands[1] = CONST_VECTOR_ELT (vec, 0);
5072 operands[2] = CONST_VECTOR_ELT (vec, 1);
5073 if (cst == cst2)
5074 return "li %0,%1\n\tevmergelo %0,%0,%0";
5075 else
5076 return "li %0,%1\n\tevmergelo %0,%0,%0\n\tli %0,%2";
5079 /* Initialize TARGET of vector PAIRED to VALS. */
5081 void
5082 paired_expand_vector_init (rtx target, rtx vals)
5084 enum machine_mode mode = GET_MODE (target);
5085 int n_elts = GET_MODE_NUNITS (mode);
5086 int n_var = 0;
5087 rtx x, new_rtx, tmp, constant_op, op1, op2;
5088 int i;
5090 for (i = 0; i < n_elts; ++i)
5092 x = XVECEXP (vals, 0, i);
5093 if (!CONSTANT_P (x))
5094 ++n_var;
5096 if (n_var == 0)
5098 /* Load from constant pool. */
5099 emit_move_insn (target, gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0)));
5100 return;
5103 if (n_var == 2)
5105 /* The vector is initialized only with non-constants. */
5106 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, XVECEXP (vals, 0, 0),
5107 XVECEXP (vals, 0, 1));
5109 emit_move_insn (target, new_rtx);
5110 return;
5113 /* One field is non-constant and the other one is a constant. Load the
5114 constant from the constant pool and use ps_merge instruction to
5115 construct the whole vector. */
5116 op1 = XVECEXP (vals, 0, 0);
5117 op2 = XVECEXP (vals, 0, 1);
5119 constant_op = (CONSTANT_P (op1)) ? op1 : op2;
5121 tmp = gen_reg_rtx (GET_MODE (constant_op));
5122 emit_move_insn (tmp, constant_op);
5124 if (CONSTANT_P (op1))
5125 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, tmp, op2);
5126 else
5127 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, op1, tmp);
5129 emit_move_insn (target, new_rtx);
5132 void
5133 paired_expand_vector_move (rtx operands[])
5135 rtx op0 = operands[0], op1 = operands[1];
5137 emit_move_insn (op0, op1);
5140 /* Emit vector compare for code RCODE. DEST is destination, OP1 and
5141 OP2 are two VEC_COND_EXPR operands, CC_OP0 and CC_OP1 are the two
5142 operands for the relation operation COND. This is a recursive
5143 function. */
5145 static void
5146 paired_emit_vector_compare (enum rtx_code rcode,
5147 rtx dest, rtx op0, rtx op1,
5148 rtx cc_op0, rtx cc_op1)
5150 rtx tmp = gen_reg_rtx (V2SFmode);
5151 rtx tmp1, max, min;
5153 gcc_assert (TARGET_PAIRED_FLOAT);
5154 gcc_assert (GET_MODE (op0) == GET_MODE (op1));
5156 switch (rcode)
5158 case LT:
5159 case LTU:
5160 paired_emit_vector_compare (GE, dest, op1, op0, cc_op0, cc_op1);
5161 return;
5162 case GE:
5163 case GEU:
5164 emit_insn (gen_subv2sf3 (tmp, cc_op0, cc_op1));
5165 emit_insn (gen_selv2sf4 (dest, tmp, op0, op1, CONST0_RTX (SFmode)));
5166 return;
5167 case LE:
5168 case LEU:
5169 paired_emit_vector_compare (GE, dest, op0, op1, cc_op1, cc_op0);
5170 return;
5171 case GT:
5172 paired_emit_vector_compare (LE, dest, op1, op0, cc_op0, cc_op1);
5173 return;
5174 case EQ:
5175 tmp1 = gen_reg_rtx (V2SFmode);
5176 max = gen_reg_rtx (V2SFmode);
5177 min = gen_reg_rtx (V2SFmode);
5178 gen_reg_rtx (V2SFmode);
5180 emit_insn (gen_subv2sf3 (tmp, cc_op0, cc_op1));
5181 emit_insn (gen_selv2sf4
5182 (max, tmp, cc_op0, cc_op1, CONST0_RTX (SFmode)));
5183 emit_insn (gen_subv2sf3 (tmp, cc_op1, cc_op0));
5184 emit_insn (gen_selv2sf4
5185 (min, tmp, cc_op0, cc_op1, CONST0_RTX (SFmode)));
5186 emit_insn (gen_subv2sf3 (tmp1, min, max));
5187 emit_insn (gen_selv2sf4 (dest, tmp1, op0, op1, CONST0_RTX (SFmode)));
5188 return;
5189 case NE:
5190 paired_emit_vector_compare (EQ, dest, op1, op0, cc_op0, cc_op1);
5191 return;
5192 case UNLE:
5193 paired_emit_vector_compare (LE, dest, op1, op0, cc_op0, cc_op1);
5194 return;
5195 case UNLT:
5196 paired_emit_vector_compare (LT, dest, op1, op0, cc_op0, cc_op1);
5197 return;
5198 case UNGE:
5199 paired_emit_vector_compare (GE, dest, op1, op0, cc_op0, cc_op1);
5200 return;
5201 case UNGT:
5202 paired_emit_vector_compare (GT, dest, op1, op0, cc_op0, cc_op1);
5203 return;
5204 default:
5205 gcc_unreachable ();
5208 return;
5211 /* Emit vector conditional expression.
5212 DEST is destination. OP1 and OP2 are two VEC_COND_EXPR operands.
5213 CC_OP0 and CC_OP1 are the two operands for the relation operation COND. */
5216 paired_emit_vector_cond_expr (rtx dest, rtx op1, rtx op2,
5217 rtx cond, rtx cc_op0, rtx cc_op1)
5219 enum rtx_code rcode = GET_CODE (cond);
5221 if (!TARGET_PAIRED_FLOAT)
5222 return 0;
5224 paired_emit_vector_compare (rcode, dest, op1, op2, cc_op0, cc_op1);
5226 return 1;
5229 /* Initialize vector TARGET to VALS. */
5231 void
5232 rs6000_expand_vector_init (rtx target, rtx vals)
5234 enum machine_mode mode = GET_MODE (target);
5235 enum machine_mode inner_mode = GET_MODE_INNER (mode);
5236 int n_elts = GET_MODE_NUNITS (mode);
5237 int n_var = 0, one_var = -1;
5238 bool all_same = true, all_const_zero = true;
5239 rtx x, mem;
5240 int i;
5242 for (i = 0; i < n_elts; ++i)
5244 x = XVECEXP (vals, 0, i);
5245 if (!CONSTANT_P (x))
5246 ++n_var, one_var = i;
5247 else if (x != CONST0_RTX (inner_mode))
5248 all_const_zero = false;
5250 if (i > 0 && !rtx_equal_p (x, XVECEXP (vals, 0, 0)))
5251 all_same = false;
5254 if (n_var == 0)
5256 rtx const_vec = gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0));
5257 bool int_vector_p = (GET_MODE_CLASS (mode) == MODE_VECTOR_INT);
5258 if ((int_vector_p || TARGET_VSX) && all_const_zero)
5260 /* Zero register. */
5261 emit_insn (gen_rtx_SET (VOIDmode, target,
5262 gen_rtx_XOR (mode, target, target)));
5263 return;
5265 else if (int_vector_p && easy_vector_constant (const_vec, mode))
5267 /* Splat immediate. */
5268 emit_insn (gen_rtx_SET (VOIDmode, target, const_vec));
5269 return;
5271 else
5273 /* Load from constant pool. */
5274 emit_move_insn (target, const_vec);
5275 return;
5279 /* Double word values on VSX can use xxpermdi or lxvdsx. */
5280 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
5282 if (all_same)
5284 rtx element = XVECEXP (vals, 0, 0);
5285 if (mode == V2DFmode)
5286 emit_insn (gen_vsx_splat_v2df (target, element));
5287 else
5288 emit_insn (gen_vsx_splat_v2di (target, element));
5290 else
5292 rtx op0 = copy_to_reg (XVECEXP (vals, 0, 0));
5293 rtx op1 = copy_to_reg (XVECEXP (vals, 0, 1));
5294 if (mode == V2DFmode)
5295 emit_insn (gen_vsx_concat_v2df (target, op0, op1));
5296 else
5297 emit_insn (gen_vsx_concat_v2di (target, op0, op1));
5299 return;
5302 /* With single precision floating point on VSX, know that internally single
5303 precision is actually represented as a double, and either make 2 V2DF
5304 vectors, and convert these vectors to single precision, or do one
5305 conversion, and splat the result to the other elements. */
5306 if (mode == V4SFmode && VECTOR_MEM_VSX_P (mode))
5308 if (all_same)
5310 rtx freg = gen_reg_rtx (V4SFmode);
5311 rtx sreg = copy_to_reg (XVECEXP (vals, 0, 0));
5313 emit_insn (gen_vsx_xscvdpsp_scalar (freg, sreg));
5314 emit_insn (gen_vsx_xxspltw_v4sf (target, freg, const0_rtx));
5316 else
5318 rtx dbl_even = gen_reg_rtx (V2DFmode);
5319 rtx dbl_odd = gen_reg_rtx (V2DFmode);
5320 rtx flt_even = gen_reg_rtx (V4SFmode);
5321 rtx flt_odd = gen_reg_rtx (V4SFmode);
5323 emit_insn (gen_vsx_concat_v2sf (dbl_even,
5324 copy_to_reg (XVECEXP (vals, 0, 0)),
5325 copy_to_reg (XVECEXP (vals, 0, 1))));
5326 emit_insn (gen_vsx_concat_v2sf (dbl_odd,
5327 copy_to_reg (XVECEXP (vals, 0, 2)),
5328 copy_to_reg (XVECEXP (vals, 0, 3))));
5329 emit_insn (gen_vsx_xvcvdpsp (flt_even, dbl_even));
5330 emit_insn (gen_vsx_xvcvdpsp (flt_odd, dbl_odd));
5331 emit_insn (gen_vec_extract_evenv4sf (target, flt_even, flt_odd));
5333 return;
5336 /* Store value to stack temp. Load vector element. Splat. However, splat
5337 of 64-bit items is not supported on Altivec. */
5338 if (all_same && GET_MODE_SIZE (mode) <= 4)
5340 mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0);
5341 emit_move_insn (adjust_address_nv (mem, inner_mode, 0),
5342 XVECEXP (vals, 0, 0));
5343 x = gen_rtx_UNSPEC (VOIDmode,
5344 gen_rtvec (1, const0_rtx), UNSPEC_LVE);
5345 emit_insn (gen_rtx_PARALLEL (VOIDmode,
5346 gen_rtvec (2,
5347 gen_rtx_SET (VOIDmode,
5348 target, mem),
5349 x)));
5350 x = gen_rtx_VEC_SELECT (inner_mode, target,
5351 gen_rtx_PARALLEL (VOIDmode,
5352 gen_rtvec (1, const0_rtx)));
5353 emit_insn (gen_rtx_SET (VOIDmode, target,
5354 gen_rtx_VEC_DUPLICATE (mode, x)));
5355 return;
5358 /* One field is non-constant. Load constant then overwrite
5359 varying field. */
5360 if (n_var == 1)
5362 rtx copy = copy_rtx (vals);
5364 /* Load constant part of vector, substitute neighboring value for
5365 varying element. */
5366 XVECEXP (copy, 0, one_var) = XVECEXP (vals, 0, (one_var + 1) % n_elts);
5367 rs6000_expand_vector_init (target, copy);
5369 /* Insert variable. */
5370 rs6000_expand_vector_set (target, XVECEXP (vals, 0, one_var), one_var);
5371 return;
5374 /* Construct the vector in memory one field at a time
5375 and load the whole vector. */
5376 mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
5377 for (i = 0; i < n_elts; i++)
5378 emit_move_insn (adjust_address_nv (mem, inner_mode,
5379 i * GET_MODE_SIZE (inner_mode)),
5380 XVECEXP (vals, 0, i));
5381 emit_move_insn (target, mem);
5384 /* Set field ELT of TARGET to VAL. */
5386 void
5387 rs6000_expand_vector_set (rtx target, rtx val, int elt)
5389 enum machine_mode mode = GET_MODE (target);
5390 enum machine_mode inner_mode = GET_MODE_INNER (mode);
5391 rtx reg = gen_reg_rtx (mode);
5392 rtx mask, mem, x;
5393 int width = GET_MODE_SIZE (inner_mode);
5394 int i;
5396 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
5398 rtx (*set_func) (rtx, rtx, rtx, rtx)
5399 = ((mode == V2DFmode) ? gen_vsx_set_v2df : gen_vsx_set_v2di);
5400 emit_insn (set_func (target, target, val, GEN_INT (elt)));
5401 return;
5404 /* Load single variable value. */
5405 mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0);
5406 emit_move_insn (adjust_address_nv (mem, inner_mode, 0), val);
5407 x = gen_rtx_UNSPEC (VOIDmode,
5408 gen_rtvec (1, const0_rtx), UNSPEC_LVE);
5409 emit_insn (gen_rtx_PARALLEL (VOIDmode,
5410 gen_rtvec (2,
5411 gen_rtx_SET (VOIDmode,
5412 reg, mem),
5413 x)));
5415 /* Linear sequence. */
5416 mask = gen_rtx_PARALLEL (V16QImode, rtvec_alloc (16));
5417 for (i = 0; i < 16; ++i)
5418 XVECEXP (mask, 0, i) = GEN_INT (i);
5420 /* Set permute mask to insert element into target. */
5421 for (i = 0; i < width; ++i)
5422 XVECEXP (mask, 0, elt*width + i)
5423 = GEN_INT (i + 0x10);
5424 x = gen_rtx_CONST_VECTOR (V16QImode, XVEC (mask, 0));
5425 x = gen_rtx_UNSPEC (mode,
5426 gen_rtvec (3, target, reg,
5427 force_reg (V16QImode, x)),
5428 UNSPEC_VPERM);
5429 emit_insn (gen_rtx_SET (VOIDmode, target, x));
5432 /* Extract field ELT from VEC into TARGET. */
5434 void
5435 rs6000_expand_vector_extract (rtx target, rtx vec, int elt)
5437 enum machine_mode mode = GET_MODE (vec);
5438 enum machine_mode inner_mode = GET_MODE_INNER (mode);
5439 rtx mem;
5441 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
5443 rtx (*extract_func) (rtx, rtx, rtx)
5444 = ((mode == V2DFmode) ? gen_vsx_extract_v2df : gen_vsx_extract_v2di);
5445 emit_insn (extract_func (target, vec, GEN_INT (elt)));
5446 return;
5449 /* Allocate mode-sized buffer. */
5450 mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
5452 emit_move_insn (mem, vec);
5454 /* Add offset to field within buffer matching vector element. */
5455 mem = adjust_address_nv (mem, inner_mode, elt * GET_MODE_SIZE (inner_mode));
5457 emit_move_insn (target, adjust_address_nv (mem, inner_mode, 0));
5460 /* Generates shifts and masks for a pair of rldicl or rldicr insns to
5461 implement ANDing by the mask IN. */
5462 void
5463 build_mask64_2_operands (rtx in, rtx *out)
5465 #if HOST_BITS_PER_WIDE_INT >= 64
5466 unsigned HOST_WIDE_INT c, lsb, m1, m2;
5467 int shift;
5469 gcc_assert (GET_CODE (in) == CONST_INT);
5471 c = INTVAL (in);
5472 if (c & 1)
5474 /* Assume c initially something like 0x00fff000000fffff. The idea
5475 is to rotate the word so that the middle ^^^^^^ group of zeros
5476 is at the MS end and can be cleared with an rldicl mask. We then
5477 rotate back and clear off the MS ^^ group of zeros with a
5478 second rldicl. */
5479 c = ~c; /* c == 0xff000ffffff00000 */
5480 lsb = c & -c; /* lsb == 0x0000000000100000 */
5481 m1 = -lsb; /* m1 == 0xfffffffffff00000 */
5482 c = ~c; /* c == 0x00fff000000fffff */
5483 c &= -lsb; /* c == 0x00fff00000000000 */
5484 lsb = c & -c; /* lsb == 0x0000100000000000 */
5485 c = ~c; /* c == 0xff000fffffffffff */
5486 c &= -lsb; /* c == 0xff00000000000000 */
5487 shift = 0;
5488 while ((lsb >>= 1) != 0)
5489 shift++; /* shift == 44 on exit from loop */
5490 m1 <<= 64 - shift; /* m1 == 0xffffff0000000000 */
5491 m1 = ~m1; /* m1 == 0x000000ffffffffff */
5492 m2 = ~c; /* m2 == 0x00ffffffffffffff */
5494 else
5496 /* Assume c initially something like 0xff000f0000000000. The idea
5497 is to rotate the word so that the ^^^ middle group of zeros
5498 is at the LS end and can be cleared with an rldicr mask. We then
5499 rotate back and clear off the LS group of ^^^^^^^^^^ zeros with
5500 a second rldicr. */
5501 lsb = c & -c; /* lsb == 0x0000010000000000 */
5502 m2 = -lsb; /* m2 == 0xffffff0000000000 */
5503 c = ~c; /* c == 0x00fff0ffffffffff */
5504 c &= -lsb; /* c == 0x00fff00000000000 */
5505 lsb = c & -c; /* lsb == 0x0000100000000000 */
5506 c = ~c; /* c == 0xff000fffffffffff */
5507 c &= -lsb; /* c == 0xff00000000000000 */
5508 shift = 0;
5509 while ((lsb >>= 1) != 0)
5510 shift++; /* shift == 44 on exit from loop */
5511 m1 = ~c; /* m1 == 0x00ffffffffffffff */
5512 m1 >>= shift; /* m1 == 0x0000000000000fff */
5513 m1 = ~m1; /* m1 == 0xfffffffffffff000 */
5516 /* Note that when we only have two 0->1 and 1->0 transitions, one of the
5517 masks will be all 1's. We are guaranteed more than one transition. */
5518 out[0] = GEN_INT (64 - shift);
5519 out[1] = GEN_INT (m1);
5520 out[2] = GEN_INT (shift);
5521 out[3] = GEN_INT (m2);
5522 #else
5523 (void)in;
5524 (void)out;
5525 gcc_unreachable ();
5526 #endif
5529 /* Return TRUE if OP is an invalid SUBREG operation on the e500. */
5531 bool
5532 invalid_e500_subreg (rtx op, enum machine_mode mode)
5534 if (TARGET_E500_DOUBLE)
5536 /* Reject (subreg:SI (reg:DF)); likewise with subreg:DI or
5537 subreg:TI and reg:TF. Decimal float modes are like integer
5538 modes (only low part of each register used) for this
5539 purpose. */
5540 if (GET_CODE (op) == SUBREG
5541 && (mode == SImode || mode == DImode || mode == TImode
5542 || mode == DDmode || mode == TDmode)
5543 && REG_P (SUBREG_REG (op))
5544 && (GET_MODE (SUBREG_REG (op)) == DFmode
5545 || GET_MODE (SUBREG_REG (op)) == TFmode))
5546 return true;
5548 /* Reject (subreg:DF (reg:DI)); likewise with subreg:TF and
5549 reg:TI. */
5550 if (GET_CODE (op) == SUBREG
5551 && (mode == DFmode || mode == TFmode)
5552 && REG_P (SUBREG_REG (op))
5553 && (GET_MODE (SUBREG_REG (op)) == DImode
5554 || GET_MODE (SUBREG_REG (op)) == TImode
5555 || GET_MODE (SUBREG_REG (op)) == DDmode
5556 || GET_MODE (SUBREG_REG (op)) == TDmode))
5557 return true;
5560 if (TARGET_SPE
5561 && GET_CODE (op) == SUBREG
5562 && mode == SImode
5563 && REG_P (SUBREG_REG (op))
5564 && SPE_VECTOR_MODE (GET_MODE (SUBREG_REG (op))))
5565 return true;
5567 return false;
5570 /* AIX increases natural record alignment to doubleword if the first
5571 field is an FP double while the FP fields remain word aligned. */
5573 unsigned int
5574 rs6000_special_round_type_align (tree type, unsigned int computed,
5575 unsigned int specified)
5577 unsigned int align = MAX (computed, specified);
5578 tree field = TYPE_FIELDS (type);
5580 /* Skip all non field decls */
5581 while (field != NULL && TREE_CODE (field) != FIELD_DECL)
5582 field = DECL_CHAIN (field);
5584 if (field != NULL && field != type)
5586 type = TREE_TYPE (field);
5587 while (TREE_CODE (type) == ARRAY_TYPE)
5588 type = TREE_TYPE (type);
5590 if (type != error_mark_node && TYPE_MODE (type) == DFmode)
5591 align = MAX (align, 64);
5594 return align;
5597 /* Darwin increases record alignment to the natural alignment of
5598 the first field. */
5600 unsigned int
5601 darwin_rs6000_special_round_type_align (tree type, unsigned int computed,
5602 unsigned int specified)
5604 unsigned int align = MAX (computed, specified);
5606 if (TYPE_PACKED (type))
5607 return align;
5609 /* Find the first field, looking down into aggregates. */
5610 do {
5611 tree field = TYPE_FIELDS (type);
5612 /* Skip all non field decls */
5613 while (field != NULL && TREE_CODE (field) != FIELD_DECL)
5614 field = DECL_CHAIN (field);
5615 if (! field)
5616 break;
5617 /* A packed field does not contribute any extra alignment. */
5618 if (DECL_PACKED (field))
5619 return align;
5620 type = TREE_TYPE (field);
5621 while (TREE_CODE (type) == ARRAY_TYPE)
5622 type = TREE_TYPE (type);
5623 } while (AGGREGATE_TYPE_P (type));
5625 if (! AGGREGATE_TYPE_P (type) && type != error_mark_node)
5626 align = MAX (align, TYPE_ALIGN (type));
5628 return align;
5631 /* Return 1 for an operand in small memory on V.4/eabi. */
5634 small_data_operand (rtx op ATTRIBUTE_UNUSED,
5635 enum machine_mode mode ATTRIBUTE_UNUSED)
5637 #if TARGET_ELF
5638 rtx sym_ref;
5640 if (rs6000_sdata == SDATA_NONE || rs6000_sdata == SDATA_DATA)
5641 return 0;
5643 if (DEFAULT_ABI != ABI_V4)
5644 return 0;
5646 /* Vector and float memory instructions have a limited offset on the
5647 SPE, so using a vector or float variable directly as an operand is
5648 not useful. */
5649 if (TARGET_SPE
5650 && (SPE_VECTOR_MODE (mode) || FLOAT_MODE_P (mode)))
5651 return 0;
5653 if (GET_CODE (op) == SYMBOL_REF)
5654 sym_ref = op;
5656 else if (GET_CODE (op) != CONST
5657 || GET_CODE (XEXP (op, 0)) != PLUS
5658 || GET_CODE (XEXP (XEXP (op, 0), 0)) != SYMBOL_REF
5659 || GET_CODE (XEXP (XEXP (op, 0), 1)) != CONST_INT)
5660 return 0;
5662 else
5664 rtx sum = XEXP (op, 0);
5665 HOST_WIDE_INT summand;
5667 /* We have to be careful here, because it is the referenced address
5668 that must be 32k from _SDA_BASE_, not just the symbol. */
5669 summand = INTVAL (XEXP (sum, 1));
5670 if (summand < 0 || summand > g_switch_value)
5671 return 0;
5673 sym_ref = XEXP (sum, 0);
5676 return SYMBOL_REF_SMALL_P (sym_ref);
5677 #else
5678 return 0;
5679 #endif
5682 /* Return true if either operand is a general purpose register. */
5684 bool
5685 gpr_or_gpr_p (rtx op0, rtx op1)
5687 return ((REG_P (op0) && INT_REGNO_P (REGNO (op0)))
5688 || (REG_P (op1) && INT_REGNO_P (REGNO (op1))));
5692 /* Subroutines of rs6000_legitimize_address and rs6000_legitimate_address_p. */
5694 static bool
5695 reg_offset_addressing_ok_p (enum machine_mode mode)
5697 switch (mode)
5699 case V16QImode:
5700 case V8HImode:
5701 case V4SFmode:
5702 case V4SImode:
5703 case V2DFmode:
5704 case V2DImode:
5705 /* AltiVec/VSX vector modes. Only reg+reg addressing is valid. */
5706 if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode))
5707 return false;
5708 break;
5710 case V4HImode:
5711 case V2SImode:
5712 case V1DImode:
5713 case V2SFmode:
5714 /* Paired vector modes. Only reg+reg addressing is valid. */
5715 if (TARGET_PAIRED_FLOAT)
5716 return false;
5717 break;
5719 default:
5720 break;
5723 return true;
5726 static bool
5727 virtual_stack_registers_memory_p (rtx op)
5729 int regnum;
5731 if (GET_CODE (op) == REG)
5732 regnum = REGNO (op);
5734 else if (GET_CODE (op) == PLUS
5735 && GET_CODE (XEXP (op, 0)) == REG
5736 && GET_CODE (XEXP (op, 1)) == CONST_INT)
5737 regnum = REGNO (XEXP (op, 0));
5739 else
5740 return false;
5742 return (regnum >= FIRST_VIRTUAL_REGISTER
5743 && regnum <= LAST_VIRTUAL_POINTER_REGISTER);
5746 static bool
5747 constant_pool_expr_p (rtx op)
5749 rtx base, offset;
5751 split_const (op, &base, &offset);
5752 return (GET_CODE (base) == SYMBOL_REF
5753 && CONSTANT_POOL_ADDRESS_P (base)
5754 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (base), Pmode));
5757 static rtx tocrel_base, tocrel_offset;
5759 bool
5760 toc_relative_expr_p (rtx op)
5762 if (GET_CODE (op) != CONST)
5763 return false;
5765 split_const (op, &tocrel_base, &tocrel_offset);
5766 return (GET_CODE (tocrel_base) == UNSPEC
5767 && XINT (tocrel_base, 1) == UNSPEC_TOCREL);
5770 bool
5771 legitimate_constant_pool_address_p (const_rtx x, bool strict)
5773 return (TARGET_TOC
5774 && (GET_CODE (x) == PLUS || GET_CODE (x) == LO_SUM)
5775 && GET_CODE (XEXP (x, 0)) == REG
5776 && (REGNO (XEXP (x, 0)) == TOC_REGISTER
5777 || ((TARGET_MINIMAL_TOC
5778 || TARGET_CMODEL != CMODEL_SMALL)
5779 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict)))
5780 && toc_relative_expr_p (XEXP (x, 1)));
5783 static bool
5784 legitimate_small_data_p (enum machine_mode mode, rtx x)
5786 return (DEFAULT_ABI == ABI_V4
5787 && !flag_pic && !TARGET_TOC
5788 && (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST)
5789 && small_data_operand (x, mode));
5792 /* SPE offset addressing is limited to 5-bits worth of double words. */
5793 #define SPE_CONST_OFFSET_OK(x) (((x) & ~0xf8) == 0)
5795 bool
5796 rs6000_legitimate_offset_address_p (enum machine_mode mode, rtx x, int strict)
5798 unsigned HOST_WIDE_INT offset, extra;
5800 if (GET_CODE (x) != PLUS)
5801 return false;
5802 if (GET_CODE (XEXP (x, 0)) != REG)
5803 return false;
5804 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
5805 return false;
5806 if (!reg_offset_addressing_ok_p (mode))
5807 return virtual_stack_registers_memory_p (x);
5808 if (legitimate_constant_pool_address_p (x, strict))
5809 return true;
5810 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5811 return false;
5813 offset = INTVAL (XEXP (x, 1));
5814 extra = 0;
5815 switch (mode)
5817 case V4HImode:
5818 case V2SImode:
5819 case V1DImode:
5820 case V2SFmode:
5821 /* SPE vector modes. */
5822 return SPE_CONST_OFFSET_OK (offset);
5824 case DFmode:
5825 if (TARGET_E500_DOUBLE)
5826 return SPE_CONST_OFFSET_OK (offset);
5828 /* If we are using VSX scalar loads, restrict ourselves to reg+reg
5829 addressing. */
5830 if (VECTOR_MEM_VSX_P (DFmode))
5831 return false;
5833 case DDmode:
5834 case DImode:
5835 /* On e500v2, we may have:
5837 (subreg:DF (mem:DI (plus (reg) (const_int))) 0).
5839 Which gets addressed with evldd instructions. */
5840 if (TARGET_E500_DOUBLE)
5841 return SPE_CONST_OFFSET_OK (offset);
5843 if (mode == DFmode || mode == DDmode || !TARGET_POWERPC64)
5844 extra = 4;
5845 else if (offset & 3)
5846 return false;
5847 break;
5849 case TFmode:
5850 if (TARGET_E500_DOUBLE)
5851 return (SPE_CONST_OFFSET_OK (offset)
5852 && SPE_CONST_OFFSET_OK (offset + 8));
5854 case TDmode:
5855 case TImode:
5856 if (mode == TFmode || mode == TDmode || !TARGET_POWERPC64)
5857 extra = 12;
5858 else if (offset & 3)
5859 return false;
5860 else
5861 extra = 8;
5862 break;
5864 default:
5865 break;
5868 offset += 0x8000;
5869 return (offset < 0x10000) && (offset + extra < 0x10000);
5872 bool
5873 legitimate_indexed_address_p (rtx x, int strict)
5875 rtx op0, op1;
5877 if (GET_CODE (x) != PLUS)
5878 return false;
5880 op0 = XEXP (x, 0);
5881 op1 = XEXP (x, 1);
5883 /* Recognize the rtl generated by reload which we know will later be
5884 replaced with proper base and index regs. */
5885 if (!strict
5886 && reload_in_progress
5887 && (REG_P (op0) || GET_CODE (op0) == PLUS)
5888 && REG_P (op1))
5889 return true;
5891 return (REG_P (op0) && REG_P (op1)
5892 && ((INT_REG_OK_FOR_BASE_P (op0, strict)
5893 && INT_REG_OK_FOR_INDEX_P (op1, strict))
5894 || (INT_REG_OK_FOR_BASE_P (op1, strict)
5895 && INT_REG_OK_FOR_INDEX_P (op0, strict))));
5898 bool
5899 avoiding_indexed_address_p (enum machine_mode mode)
5901 /* Avoid indexed addressing for modes that have non-indexed
5902 load/store instruction forms. */
5903 return (TARGET_AVOID_XFORM && VECTOR_MEM_NONE_P (mode));
5906 inline bool
5907 legitimate_indirect_address_p (rtx x, int strict)
5909 return GET_CODE (x) == REG && INT_REG_OK_FOR_BASE_P (x, strict);
5912 bool
5913 macho_lo_sum_memory_operand (rtx x, enum machine_mode mode)
5915 if (!TARGET_MACHO || !flag_pic
5916 || mode != SImode || GET_CODE (x) != MEM)
5917 return false;
5918 x = XEXP (x, 0);
5920 if (GET_CODE (x) != LO_SUM)
5921 return false;
5922 if (GET_CODE (XEXP (x, 0)) != REG)
5923 return false;
5924 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 0))
5925 return false;
5926 x = XEXP (x, 1);
5928 return CONSTANT_P (x);
5931 static bool
5932 legitimate_lo_sum_address_p (enum machine_mode mode, rtx x, int strict)
5934 if (GET_CODE (x) != LO_SUM)
5935 return false;
5936 if (GET_CODE (XEXP (x, 0)) != REG)
5937 return false;
5938 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
5939 return false;
5940 /* Restrict addressing for DI because of our SUBREG hackery. */
5941 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
5942 || mode == DDmode || mode == TDmode
5943 || mode == DImode))
5944 return false;
5945 x = XEXP (x, 1);
5947 if (TARGET_ELF || TARGET_MACHO)
5949 if (DEFAULT_ABI != ABI_AIX && DEFAULT_ABI != ABI_DARWIN && flag_pic)
5950 return false;
5951 if (TARGET_TOC)
5952 return false;
5953 if (GET_MODE_NUNITS (mode) != 1)
5954 return false;
5955 if (GET_MODE_BITSIZE (mode) > 64
5956 || (GET_MODE_BITSIZE (mode) > 32 && !TARGET_POWERPC64
5957 && !(TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5958 && (mode == DFmode || mode == DDmode))))
5959 return false;
5961 return CONSTANT_P (x);
5964 return false;
5968 /* Try machine-dependent ways of modifying an illegitimate address
5969 to be legitimate. If we find one, return the new, valid address.
5970 This is used from only one place: `memory_address' in explow.c.
5972 OLDX is the address as it was before break_out_memory_refs was
5973 called. In some cases it is useful to look at this to decide what
5974 needs to be done.
5976 It is always safe for this function to do nothing. It exists to
5977 recognize opportunities to optimize the output.
5979 On RS/6000, first check for the sum of a register with a constant
5980 integer that is out of range. If so, generate code to add the
5981 constant with the low-order 16 bits masked to the register and force
5982 this result into another register (this can be done with `cau').
5983 Then generate an address of REG+(CONST&0xffff), allowing for the
5984 possibility of bit 16 being a one.
5986 Then check for the sum of a register and something not constant, try to
5987 load the other things into a register and return the sum. */
5989 static rtx
5990 rs6000_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
5991 enum machine_mode mode)
5993 unsigned int extra = 0;
5995 if (!reg_offset_addressing_ok_p (mode))
5997 if (virtual_stack_registers_memory_p (x))
5998 return x;
6000 /* In theory we should not be seeing addresses of the form reg+0,
6001 but just in case it is generated, optimize it away. */
6002 if (GET_CODE (x) == PLUS && XEXP (x, 1) == const0_rtx)
6003 return force_reg (Pmode, XEXP (x, 0));
6005 /* Make sure both operands are registers. */
6006 else if (GET_CODE (x) == PLUS)
6007 return gen_rtx_PLUS (Pmode,
6008 force_reg (Pmode, XEXP (x, 0)),
6009 force_reg (Pmode, XEXP (x, 1)));
6010 else
6011 return force_reg (Pmode, x);
6013 if (GET_CODE (x) == SYMBOL_REF)
6015 enum tls_model model = SYMBOL_REF_TLS_MODEL (x);
6016 if (model != 0)
6017 return rs6000_legitimize_tls_address (x, model);
6020 switch (mode)
6022 case DFmode:
6023 case DDmode:
6024 extra = 4;
6025 break;
6026 case DImode:
6027 if (!TARGET_POWERPC64)
6028 extra = 4;
6029 break;
6030 case TFmode:
6031 case TDmode:
6032 extra = 12;
6033 break;
6034 case TImode:
6035 extra = TARGET_POWERPC64 ? 8 : 12;
6036 break;
6037 default:
6038 break;
6041 if (GET_CODE (x) == PLUS
6042 && GET_CODE (XEXP (x, 0)) == REG
6043 && GET_CODE (XEXP (x, 1)) == CONST_INT
6044 && ((unsigned HOST_WIDE_INT) (INTVAL (XEXP (x, 1)) + 0x8000)
6045 >= 0x10000 - extra)
6046 && !((TARGET_POWERPC64
6047 && (mode == DImode || mode == TImode)
6048 && (INTVAL (XEXP (x, 1)) & 3) != 0)
6049 || SPE_VECTOR_MODE (mode)
6050 || (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
6051 || mode == DImode || mode == DDmode
6052 || mode == TDmode))))
6054 HOST_WIDE_INT high_int, low_int;
6055 rtx sum;
6056 low_int = ((INTVAL (XEXP (x, 1)) & 0xffff) ^ 0x8000) - 0x8000;
6057 if (low_int >= 0x8000 - extra)
6058 low_int = 0;
6059 high_int = INTVAL (XEXP (x, 1)) - low_int;
6060 sum = force_operand (gen_rtx_PLUS (Pmode, XEXP (x, 0),
6061 GEN_INT (high_int)), 0);
6062 return plus_constant (sum, low_int);
6064 else if (GET_CODE (x) == PLUS
6065 && GET_CODE (XEXP (x, 0)) == REG
6066 && GET_CODE (XEXP (x, 1)) != CONST_INT
6067 && GET_MODE_NUNITS (mode) == 1
6068 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
6069 || TARGET_POWERPC64
6070 || ((mode != DImode && mode != DFmode && mode != DDmode)
6071 || (TARGET_E500_DOUBLE && mode != DDmode)))
6072 && (TARGET_POWERPC64 || mode != DImode)
6073 && !avoiding_indexed_address_p (mode)
6074 && mode != TImode
6075 && mode != TFmode
6076 && mode != TDmode)
6078 return gen_rtx_PLUS (Pmode, XEXP (x, 0),
6079 force_reg (Pmode, force_operand (XEXP (x, 1), 0)));
6081 else if (SPE_VECTOR_MODE (mode)
6082 || (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
6083 || mode == DDmode || mode == TDmode
6084 || mode == DImode)))
6086 if (mode == DImode)
6087 return x;
6088 /* We accept [reg + reg] and [reg + OFFSET]. */
6090 if (GET_CODE (x) == PLUS)
6092 rtx op1 = XEXP (x, 0);
6093 rtx op2 = XEXP (x, 1);
6094 rtx y;
6096 op1 = force_reg (Pmode, op1);
6098 if (GET_CODE (op2) != REG
6099 && (GET_CODE (op2) != CONST_INT
6100 || !SPE_CONST_OFFSET_OK (INTVAL (op2))
6101 || (GET_MODE_SIZE (mode) > 8
6102 && !SPE_CONST_OFFSET_OK (INTVAL (op2) + 8))))
6103 op2 = force_reg (Pmode, op2);
6105 /* We can't always do [reg + reg] for these, because [reg +
6106 reg + offset] is not a legitimate addressing mode. */
6107 y = gen_rtx_PLUS (Pmode, op1, op2);
6109 if ((GET_MODE_SIZE (mode) > 8 || mode == DDmode) && REG_P (op2))
6110 return force_reg (Pmode, y);
6111 else
6112 return y;
6115 return force_reg (Pmode, x);
6117 else if (TARGET_ELF
6118 && TARGET_32BIT
6119 && TARGET_NO_TOC
6120 && ! flag_pic
6121 && GET_CODE (x) != CONST_INT
6122 && GET_CODE (x) != CONST_DOUBLE
6123 && CONSTANT_P (x)
6124 && GET_MODE_NUNITS (mode) == 1
6125 && (GET_MODE_BITSIZE (mode) <= 32
6126 || ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
6127 && (mode == DFmode || mode == DDmode))))
6129 rtx reg = gen_reg_rtx (Pmode);
6130 emit_insn (gen_elf_high (reg, x));
6131 return gen_rtx_LO_SUM (Pmode, reg, x);
6133 else if (TARGET_MACHO && TARGET_32BIT && TARGET_NO_TOC
6134 && ! flag_pic
6135 #if TARGET_MACHO
6136 && ! MACHO_DYNAMIC_NO_PIC_P
6137 #endif
6138 && GET_CODE (x) != CONST_INT
6139 && GET_CODE (x) != CONST_DOUBLE
6140 && CONSTANT_P (x)
6141 && GET_MODE_NUNITS (mode) == 1
6142 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
6143 || (mode != DFmode && mode != DDmode))
6144 && mode != DImode
6145 && mode != TImode)
6147 rtx reg = gen_reg_rtx (Pmode);
6148 emit_insn (gen_macho_high (reg, x));
6149 return gen_rtx_LO_SUM (Pmode, reg, x);
6151 else if (TARGET_TOC
6152 && GET_CODE (x) == SYMBOL_REF
6153 && constant_pool_expr_p (x)
6154 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), Pmode))
6156 rtx reg = TARGET_CMODEL != CMODEL_SMALL ? gen_reg_rtx (Pmode) : NULL_RTX;
6157 return create_TOC_reference (x, reg);
6159 else
6160 return x;
6163 /* Debug version of rs6000_legitimize_address. */
6164 static rtx
6165 rs6000_debug_legitimize_address (rtx x, rtx oldx, enum machine_mode mode)
6167 rtx ret;
6168 rtx insns;
6170 start_sequence ();
6171 ret = rs6000_legitimize_address (x, oldx, mode);
6172 insns = get_insns ();
6173 end_sequence ();
6175 if (ret != x)
6177 fprintf (stderr,
6178 "\nrs6000_legitimize_address: mode %s, old code %s, "
6179 "new code %s, modified\n",
6180 GET_MODE_NAME (mode), GET_RTX_NAME (GET_CODE (x)),
6181 GET_RTX_NAME (GET_CODE (ret)));
6183 fprintf (stderr, "Original address:\n");
6184 debug_rtx (x);
6186 fprintf (stderr, "oldx:\n");
6187 debug_rtx (oldx);
6189 fprintf (stderr, "New address:\n");
6190 debug_rtx (ret);
6192 if (insns)
6194 fprintf (stderr, "Insns added:\n");
6195 debug_rtx_list (insns, 20);
6198 else
6200 fprintf (stderr,
6201 "\nrs6000_legitimize_address: mode %s, code %s, no change:\n",
6202 GET_MODE_NAME (mode), GET_RTX_NAME (GET_CODE (x)));
6204 debug_rtx (x);
6207 if (insns)
6208 emit_insn (insns);
6210 return ret;
6213 /* This is called from dwarf2out.c via TARGET_ASM_OUTPUT_DWARF_DTPREL.
6214 We need to emit DTP-relative relocations. */
6216 static void
6217 rs6000_output_dwarf_dtprel (FILE *file, int size, rtx x)
6219 switch (size)
6221 case 4:
6222 fputs ("\t.long\t", file);
6223 break;
6224 case 8:
6225 fputs (DOUBLE_INT_ASM_OP, file);
6226 break;
6227 default:
6228 gcc_unreachable ();
6230 output_addr_const (file, x);
6231 fputs ("@dtprel+0x8000", file);
6234 /* In the name of slightly smaller debug output, and to cater to
6235 general assembler lossage, recognize various UNSPEC sequences
6236 and turn them back into a direct symbol reference. */
6238 static rtx
6239 rs6000_delegitimize_address (rtx orig_x)
6241 rtx x, y;
6243 orig_x = delegitimize_mem_from_attrs (orig_x);
6244 x = orig_x;
6245 if (MEM_P (x))
6246 x = XEXP (x, 0);
6248 if ((GET_CODE (x) == PLUS
6249 || GET_CODE (x) == LO_SUM)
6250 && GET_CODE (XEXP (x, 0)) == REG
6251 && (REGNO (XEXP (x, 0)) == TOC_REGISTER
6252 || TARGET_MINIMAL_TOC
6253 || TARGET_CMODEL != CMODEL_SMALL)
6254 && GET_CODE (XEXP (x, 1)) == CONST)
6256 y = XEXP (XEXP (x, 1), 0);
6257 if (GET_CODE (y) == UNSPEC
6258 && XINT (y, 1) == UNSPEC_TOCREL)
6260 y = XVECEXP (y, 0, 0);
6261 if (!MEM_P (orig_x))
6262 return y;
6263 else
6264 return replace_equiv_address_nv (orig_x, y);
6268 if (TARGET_MACHO
6269 && GET_CODE (orig_x) == LO_SUM
6270 && GET_CODE (XEXP (x, 1)) == CONST)
6272 y = XEXP (XEXP (x, 1), 0);
6273 if (GET_CODE (y) == UNSPEC
6274 && XINT (y, 1) == UNSPEC_MACHOPIC_OFFSET)
6275 return XVECEXP (y, 0, 0);
6278 return orig_x;
6281 /* Construct the SYMBOL_REF for the tls_get_addr function. */
6283 static GTY(()) rtx rs6000_tls_symbol;
6284 static rtx
6285 rs6000_tls_get_addr (void)
6287 if (!rs6000_tls_symbol)
6288 rs6000_tls_symbol = init_one_libfunc ("__tls_get_addr");
6290 return rs6000_tls_symbol;
6293 /* Construct the SYMBOL_REF for TLS GOT references. */
6295 static GTY(()) rtx rs6000_got_symbol;
6296 static rtx
6297 rs6000_got_sym (void)
6299 if (!rs6000_got_symbol)
6301 rs6000_got_symbol = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
6302 SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_LOCAL;
6303 SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_EXTERNAL;
6306 return rs6000_got_symbol;
6309 /* ADDR contains a thread-local SYMBOL_REF. Generate code to compute
6310 this (thread-local) address. */
6312 static rtx
6313 rs6000_legitimize_tls_address (rtx addr, enum tls_model model)
6315 rtx dest, insn;
6317 dest = gen_reg_rtx (Pmode);
6318 if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 16)
6320 rtx tlsreg;
6322 if (TARGET_64BIT)
6324 tlsreg = gen_rtx_REG (Pmode, 13);
6325 insn = gen_tls_tprel_64 (dest, tlsreg, addr);
6327 else
6329 tlsreg = gen_rtx_REG (Pmode, 2);
6330 insn = gen_tls_tprel_32 (dest, tlsreg, addr);
6332 emit_insn (insn);
6334 else if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 32)
6336 rtx tlsreg, tmp;
6338 tmp = gen_reg_rtx (Pmode);
6339 if (TARGET_64BIT)
6341 tlsreg = gen_rtx_REG (Pmode, 13);
6342 insn = gen_tls_tprel_ha_64 (tmp, tlsreg, addr);
6344 else
6346 tlsreg = gen_rtx_REG (Pmode, 2);
6347 insn = gen_tls_tprel_ha_32 (tmp, tlsreg, addr);
6349 emit_insn (insn);
6350 if (TARGET_64BIT)
6351 insn = gen_tls_tprel_lo_64 (dest, tmp, addr);
6352 else
6353 insn = gen_tls_tprel_lo_32 (dest, tmp, addr);
6354 emit_insn (insn);
6356 else
6358 rtx r3, got, tga, tmp1, tmp2, call_insn;
6360 /* We currently use relocations like @got@tlsgd for tls, which
6361 means the linker will handle allocation of tls entries, placing
6362 them in the .got section. So use a pointer to the .got section,
6363 not one to secondary TOC sections used by 64-bit -mminimal-toc,
6364 or to secondary GOT sections used by 32-bit -fPIC. */
6365 if (TARGET_64BIT)
6366 got = gen_rtx_REG (Pmode, 2);
6367 else
6369 if (flag_pic == 1)
6370 got = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
6371 else
6373 rtx gsym = rs6000_got_sym ();
6374 got = gen_reg_rtx (Pmode);
6375 if (flag_pic == 0)
6376 rs6000_emit_move (got, gsym, Pmode);
6377 else
6379 rtx mem, lab, last;
6381 tmp1 = gen_reg_rtx (Pmode);
6382 tmp2 = gen_reg_rtx (Pmode);
6383 mem = gen_const_mem (Pmode, tmp1);
6384 lab = gen_label_rtx ();
6385 emit_insn (gen_load_toc_v4_PIC_1b (gsym, lab));
6386 emit_move_insn (tmp1, gen_rtx_REG (Pmode, LR_REGNO));
6387 emit_move_insn (tmp2, mem);
6388 last = emit_insn (gen_addsi3 (got, tmp1, tmp2));
6389 set_unique_reg_note (last, REG_EQUAL, gsym);
6394 if (model == TLS_MODEL_GLOBAL_DYNAMIC)
6396 r3 = gen_rtx_REG (Pmode, 3);
6397 tga = rs6000_tls_get_addr ();
6398 emit_library_call_value (tga, dest, LCT_CONST, Pmode, 1, r3, Pmode);
6400 if (DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
6401 insn = gen_tls_gd_aix64 (r3, got, addr, tga, const0_rtx);
6402 else if (DEFAULT_ABI == ABI_AIX && !TARGET_64BIT)
6403 insn = gen_tls_gd_aix32 (r3, got, addr, tga, const0_rtx);
6404 else if (DEFAULT_ABI == ABI_V4)
6405 insn = gen_tls_gd_sysvsi (r3, got, addr, tga, const0_rtx);
6406 else
6407 gcc_unreachable ();
6408 call_insn = last_call_insn ();
6409 PATTERN (call_insn) = insn;
6410 if (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
6411 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn),
6412 pic_offset_table_rtx);
6414 else if (model == TLS_MODEL_LOCAL_DYNAMIC)
6416 r3 = gen_rtx_REG (Pmode, 3);
6417 tga = rs6000_tls_get_addr ();
6418 tmp1 = gen_reg_rtx (Pmode);
6419 emit_library_call_value (tga, tmp1, LCT_CONST, Pmode, 1, r3, Pmode);
6421 if (DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
6422 insn = gen_tls_ld_aix64 (r3, got, tga, const0_rtx);
6423 else if (DEFAULT_ABI == ABI_AIX && !TARGET_64BIT)
6424 insn = gen_tls_ld_aix32 (r3, got, tga, const0_rtx);
6425 else if (DEFAULT_ABI == ABI_V4)
6426 insn = gen_tls_ld_sysvsi (r3, got, tga, const0_rtx);
6427 else
6428 gcc_unreachable ();
6429 call_insn = last_call_insn ();
6430 PATTERN (call_insn) = insn;
6431 if (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
6432 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn),
6433 pic_offset_table_rtx);
6435 if (rs6000_tls_size == 16)
6437 if (TARGET_64BIT)
6438 insn = gen_tls_dtprel_64 (dest, tmp1, addr);
6439 else
6440 insn = gen_tls_dtprel_32 (dest, tmp1, addr);
6442 else if (rs6000_tls_size == 32)
6444 tmp2 = gen_reg_rtx (Pmode);
6445 if (TARGET_64BIT)
6446 insn = gen_tls_dtprel_ha_64 (tmp2, tmp1, addr);
6447 else
6448 insn = gen_tls_dtprel_ha_32 (tmp2, tmp1, addr);
6449 emit_insn (insn);
6450 if (TARGET_64BIT)
6451 insn = gen_tls_dtprel_lo_64 (dest, tmp2, addr);
6452 else
6453 insn = gen_tls_dtprel_lo_32 (dest, tmp2, addr);
6455 else
6457 tmp2 = gen_reg_rtx (Pmode);
6458 if (TARGET_64BIT)
6459 insn = gen_tls_got_dtprel_64 (tmp2, got, addr);
6460 else
6461 insn = gen_tls_got_dtprel_32 (tmp2, got, addr);
6462 emit_insn (insn);
6463 insn = gen_rtx_SET (Pmode, dest,
6464 gen_rtx_PLUS (Pmode, tmp2, tmp1));
6466 emit_insn (insn);
6468 else
6470 /* IE, or 64-bit offset LE. */
6471 tmp2 = gen_reg_rtx (Pmode);
6472 if (TARGET_64BIT)
6473 insn = gen_tls_got_tprel_64 (tmp2, got, addr);
6474 else
6475 insn = gen_tls_got_tprel_32 (tmp2, got, addr);
6476 emit_insn (insn);
6477 if (TARGET_64BIT)
6478 insn = gen_tls_tls_64 (dest, tmp2, addr);
6479 else
6480 insn = gen_tls_tls_32 (dest, tmp2, addr);
6481 emit_insn (insn);
6485 return dest;
6488 /* Return 1 if X contains a thread-local symbol. */
6490 bool
6491 rs6000_tls_referenced_p (rtx x)
6493 if (! TARGET_HAVE_TLS)
6494 return false;
6496 return for_each_rtx (&x, &rs6000_tls_symbol_ref_1, 0);
6499 /* Return 1 if *X is a thread-local symbol. This is the same as
6500 rs6000_tls_symbol_ref except for the type of the unused argument. */
6502 static int
6503 rs6000_tls_symbol_ref_1 (rtx *x, void *data ATTRIBUTE_UNUSED)
6505 return RS6000_SYMBOL_REF_TLS_P (*x);
6508 /* Our implementation of LEGITIMIZE_RELOAD_ADDRESS. Returns a value to
6509 replace the input X, or the original X if no replacement is called for.
6510 The output parameter *WIN is 1 if the calling macro should goto WIN,
6511 0 if it should not.
6513 For RS/6000, we wish to handle large displacements off a base
6514 register by splitting the addend across an addiu/addis and the mem insn.
6515 This cuts number of extra insns needed from 3 to 1.
6517 On Darwin, we use this to generate code for floating point constants.
6518 A movsf_low is generated so we wind up with 2 instructions rather than 3.
6519 The Darwin code is inside #if TARGET_MACHO because only then are the
6520 machopic_* functions defined. */
6521 static rtx
6522 rs6000_legitimize_reload_address (rtx x, enum machine_mode mode,
6523 int opnum, int type,
6524 int ind_levels ATTRIBUTE_UNUSED, int *win)
6526 bool reg_offset_p = reg_offset_addressing_ok_p (mode);
6528 /* We must recognize output that we have already generated ourselves. */
6529 if (GET_CODE (x) == PLUS
6530 && GET_CODE (XEXP (x, 0)) == PLUS
6531 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
6532 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
6533 && GET_CODE (XEXP (x, 1)) == CONST_INT)
6535 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6536 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
6537 opnum, (enum reload_type)type);
6538 *win = 1;
6539 return x;
6542 /* Likewise for (lo_sum (high ...) ...) output we have generated. */
6543 if (GET_CODE (x) == LO_SUM
6544 && GET_CODE (XEXP (x, 0)) == HIGH)
6546 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6547 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6548 opnum, (enum reload_type)type);
6549 *win = 1;
6550 return x;
6553 #if TARGET_MACHO
6554 if (DEFAULT_ABI == ABI_DARWIN && flag_pic
6555 && GET_CODE (x) == LO_SUM
6556 && GET_CODE (XEXP (x, 0)) == PLUS
6557 && XEXP (XEXP (x, 0), 0) == pic_offset_table_rtx
6558 && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH
6559 && XEXP (XEXP (XEXP (x, 0), 1), 0) == XEXP (x, 1)
6560 && machopic_operand_p (XEXP (x, 1)))
6562 /* Result of previous invocation of this function on Darwin
6563 floating point constant. */
6564 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6565 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6566 opnum, (enum reload_type)type);
6567 *win = 1;
6568 return x;
6570 #endif
6572 if (TARGET_CMODEL != CMODEL_SMALL
6573 && GET_CODE (x) == LO_SUM
6574 && GET_CODE (XEXP (x, 0)) == PLUS
6575 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
6576 && REGNO (XEXP (XEXP (x, 0), 0)) == TOC_REGISTER
6577 && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH
6578 && GET_CODE (XEXP (x, 1)) == CONST
6579 && GET_CODE (XEXP (XEXP (x, 1), 0)) == UNSPEC
6580 && XINT (XEXP (XEXP (x, 1), 0), 1) == UNSPEC_TOCREL
6581 && rtx_equal_p (XEXP (XEXP (XEXP (x, 0), 1), 0), XEXP (x, 1)))
6583 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6584 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6585 opnum, (enum reload_type) type);
6586 *win = 1;
6587 return x;
6590 /* Force ld/std non-word aligned offset into base register by wrapping
6591 in offset 0. */
6592 if (GET_CODE (x) == PLUS
6593 && GET_CODE (XEXP (x, 0)) == REG
6594 && REGNO (XEXP (x, 0)) < 32
6595 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 1)
6596 && GET_CODE (XEXP (x, 1)) == CONST_INT
6597 && reg_offset_p
6598 && (INTVAL (XEXP (x, 1)) & 3) != 0
6599 && VECTOR_MEM_NONE_P (mode)
6600 && GET_MODE_SIZE (mode) >= UNITS_PER_WORD
6601 && TARGET_POWERPC64)
6603 x = gen_rtx_PLUS (GET_MODE (x), x, GEN_INT (0));
6604 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6605 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
6606 opnum, (enum reload_type) type);
6607 *win = 1;
6608 return x;
6611 if (GET_CODE (x) == PLUS
6612 && GET_CODE (XEXP (x, 0)) == REG
6613 && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER
6614 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 1)
6615 && GET_CODE (XEXP (x, 1)) == CONST_INT
6616 && reg_offset_p
6617 && !SPE_VECTOR_MODE (mode)
6618 && !(TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
6619 || mode == DDmode || mode == TDmode
6620 || mode == DImode))
6621 && VECTOR_MEM_NONE_P (mode))
6623 HOST_WIDE_INT val = INTVAL (XEXP (x, 1));
6624 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
6625 HOST_WIDE_INT high
6626 = (((val - low) & 0xffffffff) ^ 0x80000000) - 0x80000000;
6628 /* Check for 32-bit overflow. */
6629 if (high + low != val)
6631 *win = 0;
6632 return x;
6635 /* Reload the high part into a base reg; leave the low part
6636 in the mem directly. */
6638 x = gen_rtx_PLUS (GET_MODE (x),
6639 gen_rtx_PLUS (GET_MODE (x), XEXP (x, 0),
6640 GEN_INT (high)),
6641 GEN_INT (low));
6643 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6644 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
6645 opnum, (enum reload_type)type);
6646 *win = 1;
6647 return x;
6650 if (GET_CODE (x) == SYMBOL_REF
6651 && reg_offset_p
6652 && VECTOR_MEM_NONE_P (mode)
6653 && !SPE_VECTOR_MODE (mode)
6654 #if TARGET_MACHO
6655 && DEFAULT_ABI == ABI_DARWIN
6656 && (flag_pic || MACHO_DYNAMIC_NO_PIC_P)
6657 #else
6658 && DEFAULT_ABI == ABI_V4
6659 && !flag_pic
6660 #endif
6661 /* Don't do this for TFmode or TDmode, since the result isn't offsettable.
6662 The same goes for DImode without 64-bit gprs and DFmode and DDmode
6663 without fprs. */
6664 && mode != TFmode
6665 && mode != TDmode
6666 && (mode != DImode || TARGET_POWERPC64)
6667 && ((mode != DFmode && mode != DDmode) || TARGET_POWERPC64
6668 || (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)))
6670 #if TARGET_MACHO
6671 if (flag_pic)
6673 rtx offset = machopic_gen_offset (x);
6674 x = gen_rtx_LO_SUM (GET_MODE (x),
6675 gen_rtx_PLUS (Pmode, pic_offset_table_rtx,
6676 gen_rtx_HIGH (Pmode, offset)), offset);
6678 else
6679 #endif
6680 x = gen_rtx_LO_SUM (GET_MODE (x),
6681 gen_rtx_HIGH (Pmode, x), x);
6683 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6684 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6685 opnum, (enum reload_type)type);
6686 *win = 1;
6687 return x;
6690 /* Reload an offset address wrapped by an AND that represents the
6691 masking of the lower bits. Strip the outer AND and let reload
6692 convert the offset address into an indirect address. For VSX,
6693 force reload to create the address with an AND in a separate
6694 register, because we can't guarantee an altivec register will
6695 be used. */
6696 if (VECTOR_MEM_ALTIVEC_P (mode)
6697 && GET_CODE (x) == AND
6698 && GET_CODE (XEXP (x, 0)) == PLUS
6699 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
6700 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
6701 && GET_CODE (XEXP (x, 1)) == CONST_INT
6702 && INTVAL (XEXP (x, 1)) == -16)
6704 x = XEXP (x, 0);
6705 *win = 1;
6706 return x;
6709 if (TARGET_TOC
6710 && reg_offset_p
6711 && GET_CODE (x) == SYMBOL_REF
6712 && constant_pool_expr_p (x)
6713 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), mode))
6715 x = create_TOC_reference (x, NULL_RTX);
6716 if (TARGET_CMODEL != CMODEL_SMALL)
6717 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6718 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6719 opnum, (enum reload_type) type);
6720 *win = 1;
6721 return x;
6723 *win = 0;
6724 return x;
6727 /* Debug version of rs6000_legitimize_reload_address. */
6728 static rtx
6729 rs6000_debug_legitimize_reload_address (rtx x, enum machine_mode mode,
6730 int opnum, int type,
6731 int ind_levels, int *win)
6733 rtx ret = rs6000_legitimize_reload_address (x, mode, opnum, type,
6734 ind_levels, win);
6735 fprintf (stderr,
6736 "\nrs6000_legitimize_reload_address: mode = %s, opnum = %d, "
6737 "type = %d, ind_levels = %d, win = %d, original addr:\n",
6738 GET_MODE_NAME (mode), opnum, type, ind_levels, *win);
6739 debug_rtx (x);
6741 if (x == ret)
6742 fprintf (stderr, "Same address returned\n");
6743 else if (!ret)
6744 fprintf (stderr, "NULL returned\n");
6745 else
6747 fprintf (stderr, "New address:\n");
6748 debug_rtx (ret);
6751 return ret;
6754 /* TARGET_LEGITIMATE_ADDRESS_P recognizes an RTL expression
6755 that is a valid memory address for an instruction.
6756 The MODE argument is the machine mode for the MEM expression
6757 that wants to use this address.
6759 On the RS/6000, there are four valid address: a SYMBOL_REF that
6760 refers to a constant pool entry of an address (or the sum of it
6761 plus a constant), a short (16-bit signed) constant plus a register,
6762 the sum of two registers, or a register indirect, possibly with an
6763 auto-increment. For DFmode, DDmode and DImode with a constant plus
6764 register, we must ensure that both words are addressable or PowerPC64
6765 with offset word aligned.
6767 For modes spanning multiple registers (DFmode and DDmode in 32-bit GPRs,
6768 32-bit DImode, TImode, TFmode, TDmode), indexed addressing cannot be used
6769 because adjacent memory cells are accessed by adding word-sized offsets
6770 during assembly output. */
6771 bool
6772 rs6000_legitimate_address_p (enum machine_mode mode, rtx x, bool reg_ok_strict)
6774 bool reg_offset_p = reg_offset_addressing_ok_p (mode);
6776 /* If this is an unaligned stvx/ldvx type address, discard the outer AND. */
6777 if (VECTOR_MEM_ALTIVEC_P (mode)
6778 && GET_CODE (x) == AND
6779 && GET_CODE (XEXP (x, 1)) == CONST_INT
6780 && INTVAL (XEXP (x, 1)) == -16)
6781 x = XEXP (x, 0);
6783 if (RS6000_SYMBOL_REF_TLS_P (x))
6784 return 0;
6785 if (legitimate_indirect_address_p (x, reg_ok_strict))
6786 return 1;
6787 if ((GET_CODE (x) == PRE_INC || GET_CODE (x) == PRE_DEC)
6788 && !VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)
6789 && !SPE_VECTOR_MODE (mode)
6790 && mode != TFmode
6791 && mode != TDmode
6792 /* Restrict addressing for DI because of our SUBREG hackery. */
6793 && !(TARGET_E500_DOUBLE
6794 && (mode == DFmode || mode == DDmode || mode == DImode))
6795 && TARGET_UPDATE
6796 && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict))
6797 return 1;
6798 if (virtual_stack_registers_memory_p (x))
6799 return 1;
6800 if (reg_offset_p && legitimate_small_data_p (mode, x))
6801 return 1;
6802 if (reg_offset_p && legitimate_constant_pool_address_p (x, reg_ok_strict))
6803 return 1;
6804 /* If not REG_OK_STRICT (before reload) let pass any stack offset. */
6805 if (! reg_ok_strict
6806 && reg_offset_p
6807 && GET_CODE (x) == PLUS
6808 && GET_CODE (XEXP (x, 0)) == REG
6809 && (XEXP (x, 0) == virtual_stack_vars_rtx
6810 || XEXP (x, 0) == arg_pointer_rtx)
6811 && GET_CODE (XEXP (x, 1)) == CONST_INT)
6812 return 1;
6813 if (rs6000_legitimate_offset_address_p (mode, x, reg_ok_strict))
6814 return 1;
6815 if (mode != TImode
6816 && mode != TFmode
6817 && mode != TDmode
6818 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
6819 || TARGET_POWERPC64
6820 || (mode != DFmode && mode != DDmode)
6821 || (TARGET_E500_DOUBLE && mode != DDmode))
6822 && (TARGET_POWERPC64 || mode != DImode)
6823 && !avoiding_indexed_address_p (mode)
6824 && legitimate_indexed_address_p (x, reg_ok_strict))
6825 return 1;
6826 if (GET_CODE (x) == PRE_MODIFY
6827 && mode != TImode
6828 && mode != TFmode
6829 && mode != TDmode
6830 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
6831 || TARGET_POWERPC64
6832 || ((mode != DFmode && mode != DDmode) || TARGET_E500_DOUBLE))
6833 && (TARGET_POWERPC64 || mode != DImode)
6834 && !VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)
6835 && !SPE_VECTOR_MODE (mode)
6836 /* Restrict addressing for DI because of our SUBREG hackery. */
6837 && !(TARGET_E500_DOUBLE
6838 && (mode == DFmode || mode == DDmode || mode == DImode))
6839 && TARGET_UPDATE
6840 && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict)
6841 && (rs6000_legitimate_offset_address_p (mode, XEXP (x, 1), reg_ok_strict)
6842 || (!avoiding_indexed_address_p (mode)
6843 && legitimate_indexed_address_p (XEXP (x, 1), reg_ok_strict)))
6844 && rtx_equal_p (XEXP (XEXP (x, 1), 0), XEXP (x, 0)))
6845 return 1;
6846 if (reg_offset_p && legitimate_lo_sum_address_p (mode, x, reg_ok_strict))
6847 return 1;
6848 return 0;
6851 /* Debug version of rs6000_legitimate_address_p. */
6852 static bool
6853 rs6000_debug_legitimate_address_p (enum machine_mode mode, rtx x,
6854 bool reg_ok_strict)
6856 bool ret = rs6000_legitimate_address_p (mode, x, reg_ok_strict);
6857 fprintf (stderr,
6858 "\nrs6000_legitimate_address_p: return = %s, mode = %s, "
6859 "strict = %d, code = %s\n",
6860 ret ? "true" : "false",
6861 GET_MODE_NAME (mode),
6862 reg_ok_strict,
6863 GET_RTX_NAME (GET_CODE (x)));
6864 debug_rtx (x);
6866 return ret;
6869 /* Implement TARGET_MODE_DEPENDENT_ADDRESS_P. */
6871 static bool
6872 rs6000_mode_dependent_address_p (const_rtx addr)
6874 return rs6000_mode_dependent_address_ptr (addr);
6877 /* Go to LABEL if ADDR (a legitimate address expression)
6878 has an effect that depends on the machine mode it is used for.
6880 On the RS/6000 this is true of all integral offsets (since AltiVec
6881 and VSX modes don't allow them) or is a pre-increment or decrement.
6883 ??? Except that due to conceptual problems in offsettable_address_p
6884 we can't really report the problems of integral offsets. So leave
6885 this assuming that the adjustable offset must be valid for the
6886 sub-words of a TFmode operand, which is what we had before. */
6888 static bool
6889 rs6000_mode_dependent_address (const_rtx addr)
6891 switch (GET_CODE (addr))
6893 case PLUS:
6894 /* Any offset from virtual_stack_vars_rtx and arg_pointer_rtx
6895 is considered a legitimate address before reload, so there
6896 are no offset restrictions in that case. Note that this
6897 condition is safe in strict mode because any address involving
6898 virtual_stack_vars_rtx or arg_pointer_rtx would already have
6899 been rejected as illegitimate. */
6900 if (XEXP (addr, 0) != virtual_stack_vars_rtx
6901 && XEXP (addr, 0) != arg_pointer_rtx
6902 && GET_CODE (XEXP (addr, 1)) == CONST_INT)
6904 unsigned HOST_WIDE_INT val = INTVAL (XEXP (addr, 1));
6905 return val + 12 + 0x8000 >= 0x10000;
6907 break;
6909 case LO_SUM:
6910 /* Anything in the constant pool is sufficiently aligned that
6911 all bytes have the same high part address. */
6912 return !legitimate_constant_pool_address_p (addr, false);
6914 /* Auto-increment cases are now treated generically in recog.c. */
6915 case PRE_MODIFY:
6916 return TARGET_UPDATE;
6918 /* AND is only allowed in Altivec loads. */
6919 case AND:
6920 return true;
6922 default:
6923 break;
6926 return false;
6929 /* Debug version of rs6000_mode_dependent_address. */
6930 static bool
6931 rs6000_debug_mode_dependent_address (const_rtx addr)
6933 bool ret = rs6000_mode_dependent_address (addr);
6935 fprintf (stderr, "\nrs6000_mode_dependent_address: ret = %s\n",
6936 ret ? "true" : "false");
6937 debug_rtx (addr);
6939 return ret;
6942 /* Implement FIND_BASE_TERM. */
6945 rs6000_find_base_term (rtx op)
6947 rtx base, offset;
6949 split_const (op, &base, &offset);
6950 if (GET_CODE (base) == UNSPEC)
6951 switch (XINT (base, 1))
6953 case UNSPEC_TOCREL:
6954 case UNSPEC_MACHOPIC_OFFSET:
6955 /* OP represents SYM [+ OFFSET] - ANCHOR. SYM is the base term
6956 for aliasing purposes. */
6957 return XVECEXP (base, 0, 0);
6960 return op;
6963 /* More elaborate version of recog's offsettable_memref_p predicate
6964 that works around the ??? note of rs6000_mode_dependent_address.
6965 In particular it accepts
6967 (mem:DI (plus:SI (reg/f:SI 31 31) (const_int 32760 [0x7ff8])))
6969 in 32-bit mode, that the recog predicate rejects. */
6971 bool
6972 rs6000_offsettable_memref_p (rtx op)
6974 if (!MEM_P (op))
6975 return false;
6977 /* First mimic offsettable_memref_p. */
6978 if (offsettable_address_p (1, GET_MODE (op), XEXP (op, 0)))
6979 return true;
6981 /* offsettable_address_p invokes rs6000_mode_dependent_address, but
6982 the latter predicate knows nothing about the mode of the memory
6983 reference and, therefore, assumes that it is the largest supported
6984 mode (TFmode). As a consequence, legitimate offsettable memory
6985 references are rejected. rs6000_legitimate_offset_address_p contains
6986 the correct logic for the PLUS case of rs6000_mode_dependent_address. */
6987 return rs6000_legitimate_offset_address_p (GET_MODE (op), XEXP (op, 0), 1);
6990 /* Change register usage conditional on target flags. */
6991 static void
6992 rs6000_conditional_register_usage (void)
6994 int i;
6996 if (TARGET_DEBUG_TARGET)
6997 fprintf (stderr, "rs6000_conditional_register_usage called\n");
6999 /* Set MQ register fixed (already call_used) if not POWER
7000 architecture (RIOS1, RIOS2, RSC, and PPC601) so that it will not
7001 be allocated. */
7002 if (! TARGET_POWER)
7003 fixed_regs[64] = 1;
7005 /* 64-bit AIX and Linux reserve GPR13 for thread-private data. */
7006 if (TARGET_64BIT)
7007 fixed_regs[13] = call_used_regs[13]
7008 = call_really_used_regs[13] = 1;
7010 /* Conditionally disable FPRs. */
7011 if (TARGET_SOFT_FLOAT || !TARGET_FPRS)
7012 for (i = 32; i < 64; i++)
7013 fixed_regs[i] = call_used_regs[i]
7014 = call_really_used_regs[i] = 1;
7016 /* The TOC register is not killed across calls in a way that is
7017 visible to the compiler. */
7018 if (DEFAULT_ABI == ABI_AIX)
7019 call_really_used_regs[2] = 0;
7021 if (DEFAULT_ABI == ABI_V4
7022 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
7023 && flag_pic == 2)
7024 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
7026 if (DEFAULT_ABI == ABI_V4
7027 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
7028 && flag_pic == 1)
7029 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
7030 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
7031 = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
7033 if (DEFAULT_ABI == ABI_DARWIN
7034 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM)
7035 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
7036 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
7037 = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
7039 if (TARGET_TOC && TARGET_MINIMAL_TOC)
7040 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
7041 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
7043 if (TARGET_SPE)
7045 global_regs[SPEFSCR_REGNO] = 1;
7046 /* We used to use r14 as FIXED_SCRATCH to address SPE 64-bit
7047 registers in prologues and epilogues. We no longer use r14
7048 for FIXED_SCRATCH, but we're keeping r14 out of the allocation
7049 pool for link-compatibility with older versions of GCC. Once
7050 "old" code has died out, we can return r14 to the allocation
7051 pool. */
7052 fixed_regs[14]
7053 = call_used_regs[14]
7054 = call_really_used_regs[14] = 1;
7057 if (!TARGET_ALTIVEC && !TARGET_VSX)
7059 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
7060 fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1;
7061 call_really_used_regs[VRSAVE_REGNO] = 1;
7064 if (TARGET_ALTIVEC || TARGET_VSX)
7065 global_regs[VSCR_REGNO] = 1;
7067 if (TARGET_ALTIVEC_ABI)
7069 for (i = FIRST_ALTIVEC_REGNO; i < FIRST_ALTIVEC_REGNO + 20; ++i)
7070 call_used_regs[i] = call_really_used_regs[i] = 1;
7072 /* AIX reserves VR20:31 in non-extended ABI mode. */
7073 if (TARGET_XCOFF)
7074 for (i = FIRST_ALTIVEC_REGNO + 20; i < FIRST_ALTIVEC_REGNO + 32; ++i)
7075 fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1;
7079 /* Try to output insns to set TARGET equal to the constant C if it can
7080 be done in less than N insns. Do all computations in MODE.
7081 Returns the place where the output has been placed if it can be
7082 done and the insns have been emitted. If it would take more than N
7083 insns, zero is returned and no insns and emitted. */
7086 rs6000_emit_set_const (rtx dest, enum machine_mode mode,
7087 rtx source, int n ATTRIBUTE_UNUSED)
7089 rtx result, insn, set;
7090 HOST_WIDE_INT c0, c1;
7092 switch (mode)
7094 case QImode:
7095 case HImode:
7096 if (dest == NULL)
7097 dest = gen_reg_rtx (mode);
7098 emit_insn (gen_rtx_SET (VOIDmode, dest, source));
7099 return dest;
7101 case SImode:
7102 result = !can_create_pseudo_p () ? dest : gen_reg_rtx (SImode);
7104 emit_insn (gen_rtx_SET (VOIDmode, copy_rtx (result),
7105 GEN_INT (INTVAL (source)
7106 & (~ (HOST_WIDE_INT) 0xffff))));
7107 emit_insn (gen_rtx_SET (VOIDmode, dest,
7108 gen_rtx_IOR (SImode, copy_rtx (result),
7109 GEN_INT (INTVAL (source) & 0xffff))));
7110 result = dest;
7111 break;
7113 case DImode:
7114 switch (GET_CODE (source))
7116 case CONST_INT:
7117 c0 = INTVAL (source);
7118 c1 = -(c0 < 0);
7119 break;
7121 case CONST_DOUBLE:
7122 #if HOST_BITS_PER_WIDE_INT >= 64
7123 c0 = CONST_DOUBLE_LOW (source);
7124 c1 = -(c0 < 0);
7125 #else
7126 c0 = CONST_DOUBLE_LOW (source);
7127 c1 = CONST_DOUBLE_HIGH (source);
7128 #endif
7129 break;
7131 default:
7132 gcc_unreachable ();
7135 result = rs6000_emit_set_long_const (dest, c0, c1);
7136 break;
7138 default:
7139 gcc_unreachable ();
7142 insn = get_last_insn ();
7143 set = single_set (insn);
7144 if (! CONSTANT_P (SET_SRC (set)))
7145 set_unique_reg_note (insn, REG_EQUAL, source);
7147 return result;
7150 /* Having failed to find a 3 insn sequence in rs6000_emit_set_const,
7151 fall back to a straight forward decomposition. We do this to avoid
7152 exponential run times encountered when looking for longer sequences
7153 with rs6000_emit_set_const. */
7154 static rtx
7155 rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c1, HOST_WIDE_INT c2)
7157 if (!TARGET_POWERPC64)
7159 rtx operand1, operand2;
7161 operand1 = operand_subword_force (dest, WORDS_BIG_ENDIAN == 0,
7162 DImode);
7163 operand2 = operand_subword_force (copy_rtx (dest), WORDS_BIG_ENDIAN != 0,
7164 DImode);
7165 emit_move_insn (operand1, GEN_INT (c1));
7166 emit_move_insn (operand2, GEN_INT (c2));
7168 else
7170 HOST_WIDE_INT ud1, ud2, ud3, ud4;
7172 ud1 = c1 & 0xffff;
7173 ud2 = (c1 & 0xffff0000) >> 16;
7174 #if HOST_BITS_PER_WIDE_INT >= 64
7175 c2 = c1 >> 32;
7176 #endif
7177 ud3 = c2 & 0xffff;
7178 ud4 = (c2 & 0xffff0000) >> 16;
7180 if ((ud4 == 0xffff && ud3 == 0xffff && ud2 == 0xffff && (ud1 & 0x8000))
7181 || (ud4 == 0 && ud3 == 0 && ud2 == 0 && ! (ud1 & 0x8000)))
7183 if (ud1 & 0x8000)
7184 emit_move_insn (dest, GEN_INT (((ud1 ^ 0x8000) - 0x8000)));
7185 else
7186 emit_move_insn (dest, GEN_INT (ud1));
7189 else if ((ud4 == 0xffff && ud3 == 0xffff && (ud2 & 0x8000))
7190 || (ud4 == 0 && ud3 == 0 && ! (ud2 & 0x8000)))
7192 if (ud2 & 0x8000)
7193 emit_move_insn (dest, GEN_INT (((ud2 << 16) ^ 0x80000000)
7194 - 0x80000000));
7195 else
7196 emit_move_insn (dest, GEN_INT (ud2 << 16));
7197 if (ud1 != 0)
7198 emit_move_insn (copy_rtx (dest),
7199 gen_rtx_IOR (DImode, copy_rtx (dest),
7200 GEN_INT (ud1)));
7202 else if (ud3 == 0 && ud4 == 0)
7204 gcc_assert (ud2 & 0x8000);
7205 emit_move_insn (dest, GEN_INT (((ud2 << 16) ^ 0x80000000)
7206 - 0x80000000));
7207 if (ud1 != 0)
7208 emit_move_insn (copy_rtx (dest),
7209 gen_rtx_IOR (DImode, copy_rtx (dest),
7210 GEN_INT (ud1)));
7211 emit_move_insn (copy_rtx (dest),
7212 gen_rtx_ZERO_EXTEND (DImode,
7213 gen_lowpart (SImode,
7214 copy_rtx (dest))));
7216 else if ((ud4 == 0xffff && (ud3 & 0x8000))
7217 || (ud4 == 0 && ! (ud3 & 0x8000)))
7219 if (ud3 & 0x8000)
7220 emit_move_insn (dest, GEN_INT (((ud3 << 16) ^ 0x80000000)
7221 - 0x80000000));
7222 else
7223 emit_move_insn (dest, GEN_INT (ud3 << 16));
7225 if (ud2 != 0)
7226 emit_move_insn (copy_rtx (dest),
7227 gen_rtx_IOR (DImode, copy_rtx (dest),
7228 GEN_INT (ud2)));
7229 emit_move_insn (copy_rtx (dest),
7230 gen_rtx_ASHIFT (DImode, copy_rtx (dest),
7231 GEN_INT (16)));
7232 if (ud1 != 0)
7233 emit_move_insn (copy_rtx (dest),
7234 gen_rtx_IOR (DImode, copy_rtx (dest),
7235 GEN_INT (ud1)));
7237 else
7239 if (ud4 & 0x8000)
7240 emit_move_insn (dest, GEN_INT (((ud4 << 16) ^ 0x80000000)
7241 - 0x80000000));
7242 else
7243 emit_move_insn (dest, GEN_INT (ud4 << 16));
7245 if (ud3 != 0)
7246 emit_move_insn (copy_rtx (dest),
7247 gen_rtx_IOR (DImode, copy_rtx (dest),
7248 GEN_INT (ud3)));
7250 emit_move_insn (copy_rtx (dest),
7251 gen_rtx_ASHIFT (DImode, copy_rtx (dest),
7252 GEN_INT (32)));
7253 if (ud2 != 0)
7254 emit_move_insn (copy_rtx (dest),
7255 gen_rtx_IOR (DImode, copy_rtx (dest),
7256 GEN_INT (ud2 << 16)));
7257 if (ud1 != 0)
7258 emit_move_insn (copy_rtx (dest),
7259 gen_rtx_IOR (DImode, copy_rtx (dest), GEN_INT (ud1)));
7262 return dest;
7265 /* Helper for the following. Get rid of [r+r] memory refs
7266 in cases where it won't work (TImode, TFmode, TDmode). */
7268 static void
7269 rs6000_eliminate_indexed_memrefs (rtx operands[2])
7271 if (reload_in_progress)
7272 return;
7274 if (GET_CODE (operands[0]) == MEM
7275 && GET_CODE (XEXP (operands[0], 0)) != REG
7276 && ! legitimate_constant_pool_address_p (XEXP (operands[0], 0), false))
7277 operands[0]
7278 = replace_equiv_address (operands[0],
7279 copy_addr_to_reg (XEXP (operands[0], 0)));
7281 if (GET_CODE (operands[1]) == MEM
7282 && GET_CODE (XEXP (operands[1], 0)) != REG
7283 && ! legitimate_constant_pool_address_p (XEXP (operands[1], 0), false))
7284 operands[1]
7285 = replace_equiv_address (operands[1],
7286 copy_addr_to_reg (XEXP (operands[1], 0)));
7289 /* Return true if memory accesses to DECL are known to never straddle
7290 a 32k boundary. */
7292 static bool
7293 offsettable_ok_by_alignment (tree decl)
7295 unsigned HOST_WIDE_INT dsize, dalign;
7297 /* Presume any compiler generated symbol_ref is suitably aligned. */
7298 if (!decl)
7299 return true;
7301 if (TREE_CODE (decl) != VAR_DECL
7302 && TREE_CODE (decl) != PARM_DECL
7303 && TREE_CODE (decl) != RESULT_DECL
7304 && TREE_CODE (decl) != FIELD_DECL)
7305 return true;
7307 if (!DECL_SIZE_UNIT (decl))
7308 return false;
7310 if (!host_integerp (DECL_SIZE_UNIT (decl), 1))
7311 return false;
7313 dsize = tree_low_cst (DECL_SIZE_UNIT (decl), 1);
7314 if (dsize <= 1)
7315 return true;
7316 if (dsize > 32768)
7317 return false;
7319 dalign = DECL_ALIGN_UNIT (decl);
7320 return dalign >= dsize;
7323 /* Emit a move from SOURCE to DEST in mode MODE. */
7324 void
7325 rs6000_emit_move (rtx dest, rtx source, enum machine_mode mode)
7327 rtx operands[2];
7328 operands[0] = dest;
7329 operands[1] = source;
7331 if (TARGET_DEBUG_ADDR)
7333 fprintf (stderr,
7334 "\nrs6000_emit_move: mode = %s, reload_in_progress = %d, "
7335 "reload_completed = %d, can_create_pseudos = %d.\ndest:\n",
7336 GET_MODE_NAME (mode),
7337 reload_in_progress,
7338 reload_completed,
7339 can_create_pseudo_p ());
7340 debug_rtx (dest);
7341 fprintf (stderr, "source:\n");
7342 debug_rtx (source);
7345 /* Sanity checks. Check that we get CONST_DOUBLE only when we should. */
7346 if (GET_CODE (operands[1]) == CONST_DOUBLE
7347 && ! FLOAT_MODE_P (mode)
7348 && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
7350 /* FIXME. This should never happen. */
7351 /* Since it seems that it does, do the safe thing and convert
7352 to a CONST_INT. */
7353 operands[1] = gen_int_mode (CONST_DOUBLE_LOW (operands[1]), mode);
7355 gcc_assert (GET_CODE (operands[1]) != CONST_DOUBLE
7356 || FLOAT_MODE_P (mode)
7357 || ((CONST_DOUBLE_HIGH (operands[1]) != 0
7358 || CONST_DOUBLE_LOW (operands[1]) < 0)
7359 && (CONST_DOUBLE_HIGH (operands[1]) != -1
7360 || CONST_DOUBLE_LOW (operands[1]) >= 0)));
7362 /* Check if GCC is setting up a block move that will end up using FP
7363 registers as temporaries. We must make sure this is acceptable. */
7364 if (GET_CODE (operands[0]) == MEM
7365 && GET_CODE (operands[1]) == MEM
7366 && mode == DImode
7367 && (SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[0]))
7368 || SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[1])))
7369 && ! (SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[0]) > 32
7370 ? 32 : MEM_ALIGN (operands[0])))
7371 || SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[1]) > 32
7372 ? 32
7373 : MEM_ALIGN (operands[1]))))
7374 && ! MEM_VOLATILE_P (operands [0])
7375 && ! MEM_VOLATILE_P (operands [1]))
7377 emit_move_insn (adjust_address (operands[0], SImode, 0),
7378 adjust_address (operands[1], SImode, 0));
7379 emit_move_insn (adjust_address (copy_rtx (operands[0]), SImode, 4),
7380 adjust_address (copy_rtx (operands[1]), SImode, 4));
7381 return;
7384 if (can_create_pseudo_p () && GET_CODE (operands[0]) == MEM
7385 && !gpc_reg_operand (operands[1], mode))
7386 operands[1] = force_reg (mode, operands[1]);
7388 if (mode == SFmode && ! TARGET_POWERPC
7389 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
7390 && GET_CODE (operands[0]) == MEM)
7392 int regnum;
7394 if (reload_in_progress || reload_completed)
7395 regnum = true_regnum (operands[1]);
7396 else if (GET_CODE (operands[1]) == REG)
7397 regnum = REGNO (operands[1]);
7398 else
7399 regnum = -1;
7401 /* If operands[1] is a register, on POWER it may have
7402 double-precision data in it, so truncate it to single
7403 precision. */
7404 if (FP_REGNO_P (regnum) || regnum >= FIRST_PSEUDO_REGISTER)
7406 rtx newreg;
7407 newreg = (!can_create_pseudo_p () ? copy_rtx (operands[1])
7408 : gen_reg_rtx (mode));
7409 emit_insn (gen_aux_truncdfsf2 (newreg, operands[1]));
7410 operands[1] = newreg;
7414 /* Recognize the case where operand[1] is a reference to thread-local
7415 data and load its address to a register. */
7416 if (rs6000_tls_referenced_p (operands[1]))
7418 enum tls_model model;
7419 rtx tmp = operands[1];
7420 rtx addend = NULL;
7422 if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
7424 addend = XEXP (XEXP (tmp, 0), 1);
7425 tmp = XEXP (XEXP (tmp, 0), 0);
7428 gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
7429 model = SYMBOL_REF_TLS_MODEL (tmp);
7430 gcc_assert (model != 0);
7432 tmp = rs6000_legitimize_tls_address (tmp, model);
7433 if (addend)
7435 tmp = gen_rtx_PLUS (mode, tmp, addend);
7436 tmp = force_operand (tmp, operands[0]);
7438 operands[1] = tmp;
7441 /* Handle the case where reload calls us with an invalid address. */
7442 if (reload_in_progress && mode == Pmode
7443 && (! general_operand (operands[1], mode)
7444 || ! nonimmediate_operand (operands[0], mode)))
7445 goto emit_set;
7447 /* 128-bit constant floating-point values on Darwin should really be
7448 loaded as two parts. */
7449 if (!TARGET_IEEEQUAD && TARGET_LONG_DOUBLE_128
7450 && mode == TFmode && GET_CODE (operands[1]) == CONST_DOUBLE)
7452 /* DImode is used, not DFmode, because simplify_gen_subreg doesn't
7453 know how to get a DFmode SUBREG of a TFmode. */
7454 enum machine_mode imode = (TARGET_E500_DOUBLE ? DFmode : DImode);
7455 rs6000_emit_move (simplify_gen_subreg (imode, operands[0], mode, 0),
7456 simplify_gen_subreg (imode, operands[1], mode, 0),
7457 imode);
7458 rs6000_emit_move (simplify_gen_subreg (imode, operands[0], mode,
7459 GET_MODE_SIZE (imode)),
7460 simplify_gen_subreg (imode, operands[1], mode,
7461 GET_MODE_SIZE (imode)),
7462 imode);
7463 return;
7466 if (reload_in_progress && cfun->machine->sdmode_stack_slot != NULL_RTX)
7467 cfun->machine->sdmode_stack_slot =
7468 eliminate_regs (cfun->machine->sdmode_stack_slot, VOIDmode, NULL_RTX);
7470 if (reload_in_progress
7471 && mode == SDmode
7472 && MEM_P (operands[0])
7473 && rtx_equal_p (operands[0], cfun->machine->sdmode_stack_slot)
7474 && REG_P (operands[1]))
7476 if (FP_REGNO_P (REGNO (operands[1])))
7478 rtx mem = adjust_address_nv (operands[0], DDmode, 0);
7479 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
7480 emit_insn (gen_movsd_store (mem, operands[1]));
7482 else if (INT_REGNO_P (REGNO (operands[1])))
7484 rtx mem = adjust_address_nv (operands[0], mode, 4);
7485 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
7486 emit_insn (gen_movsd_hardfloat (mem, operands[1]));
7488 else
7489 gcc_unreachable();
7490 return;
7492 if (reload_in_progress
7493 && mode == SDmode
7494 && REG_P (operands[0])
7495 && MEM_P (operands[1])
7496 && rtx_equal_p (operands[1], cfun->machine->sdmode_stack_slot))
7498 if (FP_REGNO_P (REGNO (operands[0])))
7500 rtx mem = adjust_address_nv (operands[1], DDmode, 0);
7501 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
7502 emit_insn (gen_movsd_load (operands[0], mem));
7504 else if (INT_REGNO_P (REGNO (operands[0])))
7506 rtx mem = adjust_address_nv (operands[1], mode, 4);
7507 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
7508 emit_insn (gen_movsd_hardfloat (operands[0], mem));
7510 else
7511 gcc_unreachable();
7512 return;
7515 /* FIXME: In the long term, this switch statement should go away
7516 and be replaced by a sequence of tests based on things like
7517 mode == Pmode. */
7518 switch (mode)
7520 case HImode:
7521 case QImode:
7522 if (CONSTANT_P (operands[1])
7523 && GET_CODE (operands[1]) != CONST_INT)
7524 operands[1] = force_const_mem (mode, operands[1]);
7525 break;
7527 case TFmode:
7528 case TDmode:
7529 rs6000_eliminate_indexed_memrefs (operands);
7530 /* fall through */
7532 case DFmode:
7533 case DDmode:
7534 case SFmode:
7535 case SDmode:
7536 if (CONSTANT_P (operands[1])
7537 && ! easy_fp_constant (operands[1], mode))
7538 operands[1] = force_const_mem (mode, operands[1]);
7539 break;
7541 case V16QImode:
7542 case V8HImode:
7543 case V4SFmode:
7544 case V4SImode:
7545 case V4HImode:
7546 case V2SFmode:
7547 case V2SImode:
7548 case V1DImode:
7549 case V2DFmode:
7550 case V2DImode:
7551 if (CONSTANT_P (operands[1])
7552 && !easy_vector_constant (operands[1], mode))
7553 operands[1] = force_const_mem (mode, operands[1]);
7554 break;
7556 case SImode:
7557 case DImode:
7558 /* Use default pattern for address of ELF small data */
7559 if (TARGET_ELF
7560 && mode == Pmode
7561 && DEFAULT_ABI == ABI_V4
7562 && (GET_CODE (operands[1]) == SYMBOL_REF
7563 || GET_CODE (operands[1]) == CONST)
7564 && small_data_operand (operands[1], mode))
7566 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
7567 return;
7570 if (DEFAULT_ABI == ABI_V4
7571 && mode == Pmode && mode == SImode
7572 && flag_pic == 1 && got_operand (operands[1], mode))
7574 emit_insn (gen_movsi_got (operands[0], operands[1]));
7575 return;
7578 if ((TARGET_ELF || DEFAULT_ABI == ABI_DARWIN)
7579 && TARGET_NO_TOC
7580 && ! flag_pic
7581 && mode == Pmode
7582 && CONSTANT_P (operands[1])
7583 && GET_CODE (operands[1]) != HIGH
7584 && GET_CODE (operands[1]) != CONST_INT)
7586 rtx target = (!can_create_pseudo_p ()
7587 ? operands[0]
7588 : gen_reg_rtx (mode));
7590 /* If this is a function address on -mcall-aixdesc,
7591 convert it to the address of the descriptor. */
7592 if (DEFAULT_ABI == ABI_AIX
7593 && GET_CODE (operands[1]) == SYMBOL_REF
7594 && XSTR (operands[1], 0)[0] == '.')
7596 const char *name = XSTR (operands[1], 0);
7597 rtx new_ref;
7598 while (*name == '.')
7599 name++;
7600 new_ref = gen_rtx_SYMBOL_REF (Pmode, name);
7601 CONSTANT_POOL_ADDRESS_P (new_ref)
7602 = CONSTANT_POOL_ADDRESS_P (operands[1]);
7603 SYMBOL_REF_FLAGS (new_ref) = SYMBOL_REF_FLAGS (operands[1]);
7604 SYMBOL_REF_USED (new_ref) = SYMBOL_REF_USED (operands[1]);
7605 SYMBOL_REF_DATA (new_ref) = SYMBOL_REF_DATA (operands[1]);
7606 operands[1] = new_ref;
7609 if (DEFAULT_ABI == ABI_DARWIN)
7611 #if TARGET_MACHO
7612 if (MACHO_DYNAMIC_NO_PIC_P)
7614 /* Take care of any required data indirection. */
7615 operands[1] = rs6000_machopic_legitimize_pic_address (
7616 operands[1], mode, operands[0]);
7617 if (operands[0] != operands[1])
7618 emit_insn (gen_rtx_SET (VOIDmode,
7619 operands[0], operands[1]));
7620 return;
7622 #endif
7623 emit_insn (gen_macho_high (target, operands[1]));
7624 emit_insn (gen_macho_low (operands[0], target, operands[1]));
7625 return;
7628 emit_insn (gen_elf_high (target, operands[1]));
7629 emit_insn (gen_elf_low (operands[0], target, operands[1]));
7630 return;
7633 /* If this is a SYMBOL_REF that refers to a constant pool entry,
7634 and we have put it in the TOC, we just need to make a TOC-relative
7635 reference to it. */
7636 if ((TARGET_TOC
7637 && GET_CODE (operands[1]) == SYMBOL_REF
7638 && constant_pool_expr_p (operands[1])
7639 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (operands[1]),
7640 get_pool_mode (operands[1])))
7641 || (TARGET_CMODEL == CMODEL_MEDIUM
7642 && GET_CODE (operands[1]) == SYMBOL_REF
7643 && !CONSTANT_POOL_ADDRESS_P (operands[1])
7644 && SYMBOL_REF_LOCAL_P (operands[1])
7645 && offsettable_ok_by_alignment (SYMBOL_REF_DECL (operands[1]))))
7647 rtx reg = NULL_RTX;
7648 if (TARGET_CMODEL != CMODEL_SMALL)
7650 if (can_create_pseudo_p ())
7651 reg = gen_reg_rtx (Pmode);
7652 else
7653 reg = operands[0];
7655 operands[1] = create_TOC_reference (operands[1], reg);
7657 else if (mode == Pmode
7658 && CONSTANT_P (operands[1])
7659 && ((GET_CODE (operands[1]) != CONST_INT
7660 && ! easy_fp_constant (operands[1], mode))
7661 || (GET_CODE (operands[1]) == CONST_INT
7662 && (num_insns_constant (operands[1], mode)
7663 > (TARGET_CMODEL != CMODEL_SMALL ? 3 : 2)))
7664 || (GET_CODE (operands[0]) == REG
7665 && FP_REGNO_P (REGNO (operands[0]))))
7666 && GET_CODE (operands[1]) != HIGH
7667 && ! legitimate_constant_pool_address_p (operands[1], false)
7668 && ! toc_relative_expr_p (operands[1])
7669 && (TARGET_CMODEL == CMODEL_SMALL
7670 || can_create_pseudo_p ()
7671 || (REG_P (operands[0])
7672 && INT_REG_OK_FOR_BASE_P (operands[0], true))))
7675 #if TARGET_MACHO
7676 /* Darwin uses a special PIC legitimizer. */
7677 if (DEFAULT_ABI == ABI_DARWIN && MACHOPIC_INDIRECT)
7679 operands[1] =
7680 rs6000_machopic_legitimize_pic_address (operands[1], mode,
7681 operands[0]);
7682 if (operands[0] != operands[1])
7683 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
7684 return;
7686 #endif
7688 /* If we are to limit the number of things we put in the TOC and
7689 this is a symbol plus a constant we can add in one insn,
7690 just put the symbol in the TOC and add the constant. Don't do
7691 this if reload is in progress. */
7692 if (GET_CODE (operands[1]) == CONST
7693 && TARGET_NO_SUM_IN_TOC && ! reload_in_progress
7694 && GET_CODE (XEXP (operands[1], 0)) == PLUS
7695 && add_operand (XEXP (XEXP (operands[1], 0), 1), mode)
7696 && (GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == LABEL_REF
7697 || GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == SYMBOL_REF)
7698 && ! side_effects_p (operands[0]))
7700 rtx sym =
7701 force_const_mem (mode, XEXP (XEXP (operands[1], 0), 0));
7702 rtx other = XEXP (XEXP (operands[1], 0), 1);
7704 sym = force_reg (mode, sym);
7705 emit_insn (gen_add3_insn (operands[0], sym, other));
7706 return;
7709 operands[1] = force_const_mem (mode, operands[1]);
7711 if (TARGET_TOC
7712 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
7713 && constant_pool_expr_p (XEXP (operands[1], 0))
7714 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (
7715 get_pool_constant (XEXP (operands[1], 0)),
7716 get_pool_mode (XEXP (operands[1], 0))))
7718 rtx tocref;
7719 rtx reg = NULL_RTX;
7720 if (TARGET_CMODEL != CMODEL_SMALL)
7722 if (can_create_pseudo_p ())
7723 reg = gen_reg_rtx (Pmode);
7724 else
7725 reg = operands[0];
7727 tocref = create_TOC_reference (XEXP (operands[1], 0), reg);
7728 operands[1] = gen_const_mem (mode, tocref);
7729 set_mem_alias_set (operands[1], get_TOC_alias_set ());
7732 break;
7734 case TImode:
7735 rs6000_eliminate_indexed_memrefs (operands);
7737 if (TARGET_POWER)
7739 emit_insn (gen_rtx_PARALLEL (VOIDmode,
7740 gen_rtvec (2,
7741 gen_rtx_SET (VOIDmode,
7742 operands[0], operands[1]),
7743 gen_rtx_CLOBBER (VOIDmode,
7744 gen_rtx_SCRATCH (SImode)))));
7745 return;
7747 break;
7749 default:
7750 fatal_insn ("bad move", gen_rtx_SET (VOIDmode, dest, source));
7753 /* Above, we may have called force_const_mem which may have returned
7754 an invalid address. If we can, fix this up; otherwise, reload will
7755 have to deal with it. */
7756 if (GET_CODE (operands[1]) == MEM && ! reload_in_progress)
7757 operands[1] = validize_mem (operands[1]);
7759 emit_set:
7760 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
7763 /* Nonzero if we can use a floating-point register to pass this arg. */
7764 #define USE_FP_FOR_ARG_P(CUM,MODE,TYPE) \
7765 (SCALAR_FLOAT_MODE_P (MODE) \
7766 && (CUM)->fregno <= FP_ARG_MAX_REG \
7767 && TARGET_HARD_FLOAT && TARGET_FPRS)
7769 /* Nonzero if we can use an AltiVec register to pass this arg. */
7770 #define USE_ALTIVEC_FOR_ARG_P(CUM,MODE,TYPE,NAMED) \
7771 ((ALTIVEC_VECTOR_MODE (MODE) || VSX_VECTOR_MODE (MODE)) \
7772 && (CUM)->vregno <= ALTIVEC_ARG_MAX_REG \
7773 && TARGET_ALTIVEC_ABI \
7774 && (NAMED))
7776 /* Return a nonzero value to say to return the function value in
7777 memory, just as large structures are always returned. TYPE will be
7778 the data type of the value, and FNTYPE will be the type of the
7779 function doing the returning, or @code{NULL} for libcalls.
7781 The AIX ABI for the RS/6000 specifies that all structures are
7782 returned in memory. The Darwin ABI does the same.
7784 For the Darwin 64 Bit ABI, a function result can be returned in
7785 registers or in memory, depending on the size of the return data
7786 type. If it is returned in registers, the value occupies the same
7787 registers as it would if it were the first and only function
7788 argument. Otherwise, the function places its result in memory at
7789 the location pointed to by GPR3.
7791 The SVR4 ABI specifies that structures <= 8 bytes are returned in r3/r4,
7792 but a draft put them in memory, and GCC used to implement the draft
7793 instead of the final standard. Therefore, aix_struct_return
7794 controls this instead of DEFAULT_ABI; V.4 targets needing backward
7795 compatibility can change DRAFT_V4_STRUCT_RET to override the
7796 default, and -m switches get the final word. See
7797 rs6000_option_override_internal for more details.
7799 The PPC32 SVR4 ABI uses IEEE double extended for long double, if 128-bit
7800 long double support is enabled. These values are returned in memory.
7802 int_size_in_bytes returns -1 for variable size objects, which go in
7803 memory always. The cast to unsigned makes -1 > 8. */
7805 static bool
7806 rs6000_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
7808 /* For the Darwin64 ABI, test if we can fit the return value in regs. */
7809 if (TARGET_MACHO
7810 && rs6000_darwin64_abi
7811 && TREE_CODE (type) == RECORD_TYPE
7812 && int_size_in_bytes (type) > 0)
7814 CUMULATIVE_ARGS valcum;
7815 rtx valret;
7817 valcum.words = 0;
7818 valcum.fregno = FP_ARG_MIN_REG;
7819 valcum.vregno = ALTIVEC_ARG_MIN_REG;
7820 /* Do a trial code generation as if this were going to be passed
7821 as an argument; if any part goes in memory, we return NULL. */
7822 valret = rs6000_darwin64_record_arg (&valcum, type, true, true);
7823 if (valret)
7824 return false;
7825 /* Otherwise fall through to more conventional ABI rules. */
7828 if (AGGREGATE_TYPE_P (type)
7829 && (aix_struct_return
7830 || (unsigned HOST_WIDE_INT) int_size_in_bytes (type) > 8))
7831 return true;
7833 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
7834 modes only exist for GCC vector types if -maltivec. */
7835 if (TARGET_32BIT && !TARGET_ALTIVEC_ABI
7836 && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
7837 return false;
7839 /* Return synthetic vectors in memory. */
7840 if (TREE_CODE (type) == VECTOR_TYPE
7841 && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
7843 static bool warned_for_return_big_vectors = false;
7844 if (!warned_for_return_big_vectors)
7846 warning (0, "GCC vector returned by reference: "
7847 "non-standard ABI extension with no compatibility guarantee");
7848 warned_for_return_big_vectors = true;
7850 return true;
7853 if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && TYPE_MODE (type) == TFmode)
7854 return true;
7856 return false;
7859 /* Initialize a variable CUM of type CUMULATIVE_ARGS
7860 for a call to a function whose data type is FNTYPE.
7861 For a library call, FNTYPE is 0.
7863 For incoming args we set the number of arguments in the prototype large
7864 so we never return a PARALLEL. */
7866 void
7867 init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype,
7868 rtx libname ATTRIBUTE_UNUSED, int incoming,
7869 int libcall, int n_named_args)
7871 static CUMULATIVE_ARGS zero_cumulative;
7873 *cum = zero_cumulative;
7874 cum->words = 0;
7875 cum->fregno = FP_ARG_MIN_REG;
7876 cum->vregno = ALTIVEC_ARG_MIN_REG;
7877 cum->prototype = (fntype && TYPE_ARG_TYPES (fntype));
7878 cum->call_cookie = ((DEFAULT_ABI == ABI_V4 && libcall)
7879 ? CALL_LIBCALL : CALL_NORMAL);
7880 cum->sysv_gregno = GP_ARG_MIN_REG;
7881 cum->stdarg = stdarg_p (fntype);
7883 cum->nargs_prototype = 0;
7884 if (incoming || cum->prototype)
7885 cum->nargs_prototype = n_named_args;
7887 /* Check for a longcall attribute. */
7888 if ((!fntype && rs6000_default_long_calls)
7889 || (fntype
7890 && lookup_attribute ("longcall", TYPE_ATTRIBUTES (fntype))
7891 && !lookup_attribute ("shortcall", TYPE_ATTRIBUTES (fntype))))
7892 cum->call_cookie |= CALL_LONG;
7894 if (TARGET_DEBUG_ARG)
7896 fprintf (stderr, "\ninit_cumulative_args:");
7897 if (fntype)
7899 tree ret_type = TREE_TYPE (fntype);
7900 fprintf (stderr, " ret code = %s,",
7901 tree_code_name[ (int)TREE_CODE (ret_type) ]);
7904 if (cum->call_cookie & CALL_LONG)
7905 fprintf (stderr, " longcall,");
7907 fprintf (stderr, " proto = %d, nargs = %d\n",
7908 cum->prototype, cum->nargs_prototype);
7911 if (fntype
7912 && !TARGET_ALTIVEC
7913 && TARGET_ALTIVEC_ABI
7914 && ALTIVEC_VECTOR_MODE (TYPE_MODE (TREE_TYPE (fntype))))
7916 error ("cannot return value in vector register because"
7917 " altivec instructions are disabled, use -maltivec"
7918 " to enable them");
7922 /* Return true if TYPE must be passed on the stack and not in registers. */
7924 static bool
7925 rs6000_must_pass_in_stack (enum machine_mode mode, const_tree type)
7927 if (DEFAULT_ABI == ABI_AIX || TARGET_64BIT)
7928 return must_pass_in_stack_var_size (mode, type);
7929 else
7930 return must_pass_in_stack_var_size_or_pad (mode, type);
7933 /* If defined, a C expression which determines whether, and in which
7934 direction, to pad out an argument with extra space. The value
7935 should be of type `enum direction': either `upward' to pad above
7936 the argument, `downward' to pad below, or `none' to inhibit
7937 padding.
7939 For the AIX ABI structs are always stored left shifted in their
7940 argument slot. */
7942 enum direction
7943 function_arg_padding (enum machine_mode mode, const_tree type)
7945 #ifndef AGGREGATE_PADDING_FIXED
7946 #define AGGREGATE_PADDING_FIXED 0
7947 #endif
7948 #ifndef AGGREGATES_PAD_UPWARD_ALWAYS
7949 #define AGGREGATES_PAD_UPWARD_ALWAYS 0
7950 #endif
7952 if (!AGGREGATE_PADDING_FIXED)
7954 /* GCC used to pass structures of the same size as integer types as
7955 if they were in fact integers, ignoring FUNCTION_ARG_PADDING.
7956 i.e. Structures of size 1 or 2 (or 4 when TARGET_64BIT) were
7957 passed padded downward, except that -mstrict-align further
7958 muddied the water in that multi-component structures of 2 and 4
7959 bytes in size were passed padded upward.
7961 The following arranges for best compatibility with previous
7962 versions of gcc, but removes the -mstrict-align dependency. */
7963 if (BYTES_BIG_ENDIAN)
7965 HOST_WIDE_INT size = 0;
7967 if (mode == BLKmode)
7969 if (type && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST)
7970 size = int_size_in_bytes (type);
7972 else
7973 size = GET_MODE_SIZE (mode);
7975 if (size == 1 || size == 2 || size == 4)
7976 return downward;
7978 return upward;
7981 if (AGGREGATES_PAD_UPWARD_ALWAYS)
7983 if (type != 0 && AGGREGATE_TYPE_P (type))
7984 return upward;
7987 /* Fall back to the default. */
7988 return DEFAULT_FUNCTION_ARG_PADDING (mode, type);
7991 /* If defined, a C expression that gives the alignment boundary, in bits,
7992 of an argument with the specified mode and type. If it is not defined,
7993 PARM_BOUNDARY is used for all arguments.
7995 V.4 wants long longs and doubles to be double word aligned. Just
7996 testing the mode size is a boneheaded way to do this as it means
7997 that other types such as complex int are also double word aligned.
7998 However, we're stuck with this because changing the ABI might break
7999 existing library interfaces.
8001 Doubleword align SPE vectors.
8002 Quadword align Altivec vectors.
8003 Quadword align large synthetic vector types. */
8005 static unsigned int
8006 rs6000_function_arg_boundary (enum machine_mode mode, const_tree type)
8008 if (DEFAULT_ABI == ABI_V4
8009 && (GET_MODE_SIZE (mode) == 8
8010 || (TARGET_HARD_FLOAT
8011 && TARGET_FPRS
8012 && (mode == TFmode || mode == TDmode))))
8013 return 64;
8014 else if (SPE_VECTOR_MODE (mode)
8015 || (type && TREE_CODE (type) == VECTOR_TYPE
8016 && int_size_in_bytes (type) >= 8
8017 && int_size_in_bytes (type) < 16))
8018 return 64;
8019 else if ((ALTIVEC_VECTOR_MODE (mode) || VSX_VECTOR_MODE (mode))
8020 || (type && TREE_CODE (type) == VECTOR_TYPE
8021 && int_size_in_bytes (type) >= 16))
8022 return 128;
8023 else if (TARGET_MACHO
8024 && rs6000_darwin64_abi
8025 && mode == BLKmode
8026 && type && TYPE_ALIGN (type) > 64)
8027 return 128;
8028 else
8029 return PARM_BOUNDARY;
8032 /* For a function parm of MODE and TYPE, return the starting word in
8033 the parameter area. NWORDS of the parameter area are already used. */
8035 static unsigned int
8036 rs6000_parm_start (enum machine_mode mode, const_tree type,
8037 unsigned int nwords)
8039 unsigned int align;
8040 unsigned int parm_offset;
8042 align = rs6000_function_arg_boundary (mode, type) / PARM_BOUNDARY - 1;
8043 parm_offset = DEFAULT_ABI == ABI_V4 ? 2 : 6;
8044 return nwords + (-(parm_offset + nwords) & align);
8047 /* Compute the size (in words) of a function argument. */
8049 static unsigned long
8050 rs6000_arg_size (enum machine_mode mode, const_tree type)
8052 unsigned long size;
8054 if (mode != BLKmode)
8055 size = GET_MODE_SIZE (mode);
8056 else
8057 size = int_size_in_bytes (type);
8059 if (TARGET_32BIT)
8060 return (size + 3) >> 2;
8061 else
8062 return (size + 7) >> 3;
8065 /* Use this to flush pending int fields. */
8067 static void
8068 rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS *cum,
8069 HOST_WIDE_INT bitpos, int final)
8071 unsigned int startbit, endbit;
8072 int intregs, intoffset;
8073 enum machine_mode mode;
8075 /* Handle the situations where a float is taking up the first half
8076 of the GPR, and the other half is empty (typically due to
8077 alignment restrictions). We can detect this by a 8-byte-aligned
8078 int field, or by seeing that this is the final flush for this
8079 argument. Count the word and continue on. */
8080 if (cum->floats_in_gpr == 1
8081 && (cum->intoffset % 64 == 0
8082 || (cum->intoffset == -1 && final)))
8084 cum->words++;
8085 cum->floats_in_gpr = 0;
8088 if (cum->intoffset == -1)
8089 return;
8091 intoffset = cum->intoffset;
8092 cum->intoffset = -1;
8093 cum->floats_in_gpr = 0;
8095 if (intoffset % BITS_PER_WORD != 0)
8097 mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD,
8098 MODE_INT, 0);
8099 if (mode == BLKmode)
8101 /* We couldn't find an appropriate mode, which happens,
8102 e.g., in packed structs when there are 3 bytes to load.
8103 Back intoffset back to the beginning of the word in this
8104 case. */
8105 intoffset = intoffset & -BITS_PER_WORD;
8109 startbit = intoffset & -BITS_PER_WORD;
8110 endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD;
8111 intregs = (endbit - startbit) / BITS_PER_WORD;
8112 cum->words += intregs;
8113 /* words should be unsigned. */
8114 if ((unsigned)cum->words < (endbit/BITS_PER_WORD))
8116 int pad = (endbit/BITS_PER_WORD) - cum->words;
8117 cum->words += pad;
8121 /* The darwin64 ABI calls for us to recurse down through structs,
8122 looking for elements passed in registers. Unfortunately, we have
8123 to track int register count here also because of misalignments
8124 in powerpc alignment mode. */
8126 static void
8127 rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS *cum,
8128 const_tree type,
8129 HOST_WIDE_INT startbitpos)
8131 tree f;
8133 for (f = TYPE_FIELDS (type); f ; f = DECL_CHAIN (f))
8134 if (TREE_CODE (f) == FIELD_DECL)
8136 HOST_WIDE_INT bitpos = startbitpos;
8137 tree ftype = TREE_TYPE (f);
8138 enum machine_mode mode;
8139 if (ftype == error_mark_node)
8140 continue;
8141 mode = TYPE_MODE (ftype);
8143 if (DECL_SIZE (f) != 0
8144 && host_integerp (bit_position (f), 1))
8145 bitpos += int_bit_position (f);
8147 /* ??? FIXME: else assume zero offset. */
8149 if (TREE_CODE (ftype) == RECORD_TYPE)
8150 rs6000_darwin64_record_arg_advance_recurse (cum, ftype, bitpos);
8151 else if (USE_FP_FOR_ARG_P (cum, mode, ftype))
8153 unsigned n_fpregs = (GET_MODE_SIZE (mode) + 7) >> 3;
8154 rs6000_darwin64_record_arg_advance_flush (cum, bitpos, 0);
8155 cum->fregno += n_fpregs;
8156 /* Single-precision floats present a special problem for
8157 us, because they are smaller than an 8-byte GPR, and so
8158 the structure-packing rules combined with the standard
8159 varargs behavior mean that we want to pack float/float
8160 and float/int combinations into a single register's
8161 space. This is complicated by the arg advance flushing,
8162 which works on arbitrarily large groups of int-type
8163 fields. */
8164 if (mode == SFmode)
8166 if (cum->floats_in_gpr == 1)
8168 /* Two floats in a word; count the word and reset
8169 the float count. */
8170 cum->words++;
8171 cum->floats_in_gpr = 0;
8173 else if (bitpos % 64 == 0)
8175 /* A float at the beginning of an 8-byte word;
8176 count it and put off adjusting cum->words until
8177 we see if a arg advance flush is going to do it
8178 for us. */
8179 cum->floats_in_gpr++;
8181 else
8183 /* The float is at the end of a word, preceded
8184 by integer fields, so the arg advance flush
8185 just above has already set cum->words and
8186 everything is taken care of. */
8189 else
8190 cum->words += n_fpregs;
8192 else if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, 1))
8194 rs6000_darwin64_record_arg_advance_flush (cum, bitpos, 0);
8195 cum->vregno++;
8196 cum->words += 2;
8198 else if (cum->intoffset == -1)
8199 cum->intoffset = bitpos;
8203 /* Check for an item that needs to be considered specially under the darwin 64
8204 bit ABI. These are record types where the mode is BLK or the structure is
8205 8 bytes in size. */
8206 static int
8207 rs6000_darwin64_struct_check_p (enum machine_mode mode, const_tree type)
8209 return rs6000_darwin64_abi
8210 && ((mode == BLKmode
8211 && TREE_CODE (type) == RECORD_TYPE
8212 && int_size_in_bytes (type) > 0)
8213 || (type && TREE_CODE (type) == RECORD_TYPE
8214 && int_size_in_bytes (type) == 8)) ? 1 : 0;
8217 /* Update the data in CUM to advance over an argument
8218 of mode MODE and data type TYPE.
8219 (TYPE is null for libcalls where that information may not be available.)
8221 Note that for args passed by reference, function_arg will be called
8222 with MODE and TYPE set to that of the pointer to the arg, not the arg
8223 itself. */
8225 static void
8226 rs6000_function_arg_advance_1 (CUMULATIVE_ARGS *cum, enum machine_mode mode,
8227 const_tree type, bool named, int depth)
8230 /* Only tick off an argument if we're not recursing. */
8231 if (depth == 0)
8232 cum->nargs_prototype--;
8234 if (TARGET_ALTIVEC_ABI
8235 && (ALTIVEC_VECTOR_MODE (mode)
8236 || VSX_VECTOR_MODE (mode)
8237 || (type && TREE_CODE (type) == VECTOR_TYPE
8238 && int_size_in_bytes (type) == 16)))
8240 bool stack = false;
8242 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
8244 cum->vregno++;
8245 if (!TARGET_ALTIVEC)
8246 error ("cannot pass argument in vector register because"
8247 " altivec instructions are disabled, use -maltivec"
8248 " to enable them");
8250 /* PowerPC64 Linux and AIX allocate GPRs for a vector argument
8251 even if it is going to be passed in a vector register.
8252 Darwin does the same for variable-argument functions. */
8253 if ((DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
8254 || (cum->stdarg && DEFAULT_ABI != ABI_V4))
8255 stack = true;
8257 else
8258 stack = true;
8260 if (stack)
8262 int align;
8264 /* Vector parameters must be 16-byte aligned. This places
8265 them at 2 mod 4 in terms of words in 32-bit mode, since
8266 the parameter save area starts at offset 24 from the
8267 stack. In 64-bit mode, they just have to start on an
8268 even word, since the parameter save area is 16-byte
8269 aligned. Space for GPRs is reserved even if the argument
8270 will be passed in memory. */
8271 if (TARGET_32BIT)
8272 align = (2 - cum->words) & 3;
8273 else
8274 align = cum->words & 1;
8275 cum->words += align + rs6000_arg_size (mode, type);
8277 if (TARGET_DEBUG_ARG)
8279 fprintf (stderr, "function_adv: words = %2d, align=%d, ",
8280 cum->words, align);
8281 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s\n",
8282 cum->nargs_prototype, cum->prototype,
8283 GET_MODE_NAME (mode));
8287 else if (TARGET_SPE_ABI && TARGET_SPE && SPE_VECTOR_MODE (mode)
8288 && !cum->stdarg
8289 && cum->sysv_gregno <= GP_ARG_MAX_REG)
8290 cum->sysv_gregno++;
8292 else if (TARGET_MACHO && rs6000_darwin64_struct_check_p (mode, type))
8294 int size = int_size_in_bytes (type);
8295 /* Variable sized types have size == -1 and are
8296 treated as if consisting entirely of ints.
8297 Pad to 16 byte boundary if needed. */
8298 if (TYPE_ALIGN (type) >= 2 * BITS_PER_WORD
8299 && (cum->words % 2) != 0)
8300 cum->words++;
8301 /* For varargs, we can just go up by the size of the struct. */
8302 if (!named)
8303 cum->words += (size + 7) / 8;
8304 else
8306 /* It is tempting to say int register count just goes up by
8307 sizeof(type)/8, but this is wrong in a case such as
8308 { int; double; int; } [powerpc alignment]. We have to
8309 grovel through the fields for these too. */
8310 cum->intoffset = 0;
8311 cum->floats_in_gpr = 0;
8312 rs6000_darwin64_record_arg_advance_recurse (cum, type, 0);
8313 rs6000_darwin64_record_arg_advance_flush (cum,
8314 size * BITS_PER_UNIT, 1);
8316 if (TARGET_DEBUG_ARG)
8318 fprintf (stderr, "function_adv: words = %2d, align=%d, size=%d",
8319 cum->words, TYPE_ALIGN (type), size);
8320 fprintf (stderr,
8321 "nargs = %4d, proto = %d, mode = %4s (darwin64 abi)\n",
8322 cum->nargs_prototype, cum->prototype,
8323 GET_MODE_NAME (mode));
8326 else if (DEFAULT_ABI == ABI_V4)
8328 if (TARGET_HARD_FLOAT && TARGET_FPRS
8329 && ((TARGET_SINGLE_FLOAT && mode == SFmode)
8330 || (TARGET_DOUBLE_FLOAT && mode == DFmode)
8331 || (mode == TFmode && !TARGET_IEEEQUAD)
8332 || mode == SDmode || mode == DDmode || mode == TDmode))
8334 /* _Decimal128 must use an even/odd register pair. This assumes
8335 that the register number is odd when fregno is odd. */
8336 if (mode == TDmode && (cum->fregno % 2) == 1)
8337 cum->fregno++;
8339 if (cum->fregno + (mode == TFmode || mode == TDmode ? 1 : 0)
8340 <= FP_ARG_V4_MAX_REG)
8341 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
8342 else
8344 cum->fregno = FP_ARG_V4_MAX_REG + 1;
8345 if (mode == DFmode || mode == TFmode
8346 || mode == DDmode || mode == TDmode)
8347 cum->words += cum->words & 1;
8348 cum->words += rs6000_arg_size (mode, type);
8351 else
8353 int n_words = rs6000_arg_size (mode, type);
8354 int gregno = cum->sysv_gregno;
8356 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
8357 (r7,r8) or (r9,r10). As does any other 2 word item such
8358 as complex int due to a historical mistake. */
8359 if (n_words == 2)
8360 gregno += (1 - gregno) & 1;
8362 /* Multi-reg args are not split between registers and stack. */
8363 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
8365 /* Long long and SPE vectors are aligned on the stack.
8366 So are other 2 word items such as complex int due to
8367 a historical mistake. */
8368 if (n_words == 2)
8369 cum->words += cum->words & 1;
8370 cum->words += n_words;
8373 /* Note: continuing to accumulate gregno past when we've started
8374 spilling to the stack indicates the fact that we've started
8375 spilling to the stack to expand_builtin_saveregs. */
8376 cum->sysv_gregno = gregno + n_words;
8379 if (TARGET_DEBUG_ARG)
8381 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
8382 cum->words, cum->fregno);
8383 fprintf (stderr, "gregno = %2d, nargs = %4d, proto = %d, ",
8384 cum->sysv_gregno, cum->nargs_prototype, cum->prototype);
8385 fprintf (stderr, "mode = %4s, named = %d\n",
8386 GET_MODE_NAME (mode), named);
8389 else
8391 int n_words = rs6000_arg_size (mode, type);
8392 int start_words = cum->words;
8393 int align_words = rs6000_parm_start (mode, type, start_words);
8395 cum->words = align_words + n_words;
8397 if (SCALAR_FLOAT_MODE_P (mode)
8398 && TARGET_HARD_FLOAT && TARGET_FPRS)
8400 /* _Decimal128 must be passed in an even/odd float register pair.
8401 This assumes that the register number is odd when fregno is
8402 odd. */
8403 if (mode == TDmode && (cum->fregno % 2) == 1)
8404 cum->fregno++;
8405 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
8408 if (TARGET_DEBUG_ARG)
8410 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
8411 cum->words, cum->fregno);
8412 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s, ",
8413 cum->nargs_prototype, cum->prototype, GET_MODE_NAME (mode));
8414 fprintf (stderr, "named = %d, align = %d, depth = %d\n",
8415 named, align_words - start_words, depth);
8420 static void
8421 rs6000_function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
8422 const_tree type, bool named)
8424 rs6000_function_arg_advance_1 (cum, mode, type, named, 0);
8427 static rtx
8428 spe_build_register_parallel (enum machine_mode mode, int gregno)
8430 rtx r1, r3, r5, r7;
8432 switch (mode)
8434 case DFmode:
8435 r1 = gen_rtx_REG (DImode, gregno);
8436 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
8437 return gen_rtx_PARALLEL (mode, gen_rtvec (1, r1));
8439 case DCmode:
8440 case TFmode:
8441 r1 = gen_rtx_REG (DImode, gregno);
8442 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
8443 r3 = gen_rtx_REG (DImode, gregno + 2);
8444 r3 = gen_rtx_EXPR_LIST (VOIDmode, r3, GEN_INT (8));
8445 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r3));
8447 case TCmode:
8448 r1 = gen_rtx_REG (DImode, gregno);
8449 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
8450 r3 = gen_rtx_REG (DImode, gregno + 2);
8451 r3 = gen_rtx_EXPR_LIST (VOIDmode, r3, GEN_INT (8));
8452 r5 = gen_rtx_REG (DImode, gregno + 4);
8453 r5 = gen_rtx_EXPR_LIST (VOIDmode, r5, GEN_INT (16));
8454 r7 = gen_rtx_REG (DImode, gregno + 6);
8455 r7 = gen_rtx_EXPR_LIST (VOIDmode, r7, GEN_INT (24));
8456 return gen_rtx_PARALLEL (mode, gen_rtvec (4, r1, r3, r5, r7));
8458 default:
8459 gcc_unreachable ();
8463 /* Determine where to put a SIMD argument on the SPE. */
8464 static rtx
8465 rs6000_spe_function_arg (const CUMULATIVE_ARGS *cum, enum machine_mode mode,
8466 const_tree type)
8468 int gregno = cum->sysv_gregno;
8470 /* On E500 v2, double arithmetic is done on the full 64-bit GPR, but
8471 are passed and returned in a pair of GPRs for ABI compatibility. */
8472 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
8473 || mode == DCmode || mode == TCmode))
8475 int n_words = rs6000_arg_size (mode, type);
8477 /* Doubles go in an odd/even register pair (r5/r6, etc). */
8478 if (mode == DFmode)
8479 gregno += (1 - gregno) & 1;
8481 /* Multi-reg args are not split between registers and stack. */
8482 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
8483 return NULL_RTX;
8485 return spe_build_register_parallel (mode, gregno);
8487 if (cum->stdarg)
8489 int n_words = rs6000_arg_size (mode, type);
8491 /* SPE vectors are put in odd registers. */
8492 if (n_words == 2 && (gregno & 1) == 0)
8493 gregno += 1;
8495 if (gregno + n_words - 1 <= GP_ARG_MAX_REG)
8497 rtx r1, r2;
8498 enum machine_mode m = SImode;
8500 r1 = gen_rtx_REG (m, gregno);
8501 r1 = gen_rtx_EXPR_LIST (m, r1, const0_rtx);
8502 r2 = gen_rtx_REG (m, gregno + 1);
8503 r2 = gen_rtx_EXPR_LIST (m, r2, GEN_INT (4));
8504 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
8506 else
8507 return NULL_RTX;
8509 else
8511 if (gregno <= GP_ARG_MAX_REG)
8512 return gen_rtx_REG (mode, gregno);
8513 else
8514 return NULL_RTX;
8518 /* A subroutine of rs6000_darwin64_record_arg. Assign the bits of the
8519 structure between cum->intoffset and bitpos to integer registers. */
8521 static void
8522 rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS *cum,
8523 HOST_WIDE_INT bitpos, rtx rvec[], int *k)
8525 enum machine_mode mode;
8526 unsigned int regno;
8527 unsigned int startbit, endbit;
8528 int this_regno, intregs, intoffset;
8529 rtx reg;
8531 if (cum->intoffset == -1)
8532 return;
8534 intoffset = cum->intoffset;
8535 cum->intoffset = -1;
8537 /* If this is the trailing part of a word, try to only load that
8538 much into the register. Otherwise load the whole register. Note
8539 that in the latter case we may pick up unwanted bits. It's not a
8540 problem at the moment but may wish to revisit. */
8542 if (intoffset % BITS_PER_WORD != 0)
8544 mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD,
8545 MODE_INT, 0);
8546 if (mode == BLKmode)
8548 /* We couldn't find an appropriate mode, which happens,
8549 e.g., in packed structs when there are 3 bytes to load.
8550 Back intoffset back to the beginning of the word in this
8551 case. */
8552 intoffset = intoffset & -BITS_PER_WORD;
8553 mode = word_mode;
8556 else
8557 mode = word_mode;
8559 startbit = intoffset & -BITS_PER_WORD;
8560 endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD;
8561 intregs = (endbit - startbit) / BITS_PER_WORD;
8562 this_regno = cum->words + intoffset / BITS_PER_WORD;
8564 if (intregs > 0 && intregs > GP_ARG_NUM_REG - this_regno)
8565 cum->use_stack = 1;
8567 intregs = MIN (intregs, GP_ARG_NUM_REG - this_regno);
8568 if (intregs <= 0)
8569 return;
8571 intoffset /= BITS_PER_UNIT;
8574 regno = GP_ARG_MIN_REG + this_regno;
8575 reg = gen_rtx_REG (mode, regno);
8576 rvec[(*k)++] =
8577 gen_rtx_EXPR_LIST (VOIDmode, reg, GEN_INT (intoffset));
8579 this_regno += 1;
8580 intoffset = (intoffset | (UNITS_PER_WORD-1)) + 1;
8581 mode = word_mode;
8582 intregs -= 1;
8584 while (intregs > 0);
8587 /* Recursive workhorse for the following. */
8589 static void
8590 rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *cum, const_tree type,
8591 HOST_WIDE_INT startbitpos, rtx rvec[],
8592 int *k)
8594 tree f;
8596 for (f = TYPE_FIELDS (type); f ; f = DECL_CHAIN (f))
8597 if (TREE_CODE (f) == FIELD_DECL)
8599 HOST_WIDE_INT bitpos = startbitpos;
8600 tree ftype = TREE_TYPE (f);
8601 enum machine_mode mode;
8602 if (ftype == error_mark_node)
8603 continue;
8604 mode = TYPE_MODE (ftype);
8606 if (DECL_SIZE (f) != 0
8607 && host_integerp (bit_position (f), 1))
8608 bitpos += int_bit_position (f);
8610 /* ??? FIXME: else assume zero offset. */
8612 if (TREE_CODE (ftype) == RECORD_TYPE)
8613 rs6000_darwin64_record_arg_recurse (cum, ftype, bitpos, rvec, k);
8614 else if (cum->named && USE_FP_FOR_ARG_P (cum, mode, ftype))
8616 unsigned n_fpreg = (GET_MODE_SIZE (mode) + 7) >> 3;
8617 #if 0
8618 switch (mode)
8620 case SCmode: mode = SFmode; break;
8621 case DCmode: mode = DFmode; break;
8622 case TCmode: mode = TFmode; break;
8623 default: break;
8625 #endif
8626 rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
8627 if (cum->fregno + n_fpreg > FP_ARG_MAX_REG + 1)
8629 gcc_assert (cum->fregno == FP_ARG_MAX_REG
8630 && (mode == TFmode || mode == TDmode));
8631 /* Long double or _Decimal128 split over regs and memory. */
8632 mode = DECIMAL_FLOAT_MODE_P (mode) ? DDmode : DFmode;
8633 cum->use_stack=1;
8635 rvec[(*k)++]
8636 = gen_rtx_EXPR_LIST (VOIDmode,
8637 gen_rtx_REG (mode, cum->fregno++),
8638 GEN_INT (bitpos / BITS_PER_UNIT));
8639 if (mode == TFmode || mode == TDmode)
8640 cum->fregno++;
8642 else if (cum->named && USE_ALTIVEC_FOR_ARG_P (cum, mode, ftype, 1))
8644 rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
8645 rvec[(*k)++]
8646 = gen_rtx_EXPR_LIST (VOIDmode,
8647 gen_rtx_REG (mode, cum->vregno++),
8648 GEN_INT (bitpos / BITS_PER_UNIT));
8650 else if (cum->intoffset == -1)
8651 cum->intoffset = bitpos;
8655 /* For the darwin64 ABI, we want to construct a PARALLEL consisting of
8656 the register(s) to be used for each field and subfield of a struct
8657 being passed by value, along with the offset of where the
8658 register's value may be found in the block. FP fields go in FP
8659 register, vector fields go in vector registers, and everything
8660 else goes in int registers, packed as in memory.
8662 This code is also used for function return values. RETVAL indicates
8663 whether this is the case.
8665 Much of this is taken from the SPARC V9 port, which has a similar
8666 calling convention. */
8668 static rtx
8669 rs6000_darwin64_record_arg (CUMULATIVE_ARGS *orig_cum, const_tree type,
8670 bool named, bool retval)
8672 rtx rvec[FIRST_PSEUDO_REGISTER];
8673 int k = 1, kbase = 1;
8674 HOST_WIDE_INT typesize = int_size_in_bytes (type);
8675 /* This is a copy; modifications are not visible to our caller. */
8676 CUMULATIVE_ARGS copy_cum = *orig_cum;
8677 CUMULATIVE_ARGS *cum = &copy_cum;
8679 /* Pad to 16 byte boundary if needed. */
8680 if (!retval && TYPE_ALIGN (type) >= 2 * BITS_PER_WORD
8681 && (cum->words % 2) != 0)
8682 cum->words++;
8684 cum->intoffset = 0;
8685 cum->use_stack = 0;
8686 cum->named = named;
8688 /* Put entries into rvec[] for individual FP and vector fields, and
8689 for the chunks of memory that go in int regs. Note we start at
8690 element 1; 0 is reserved for an indication of using memory, and
8691 may or may not be filled in below. */
8692 rs6000_darwin64_record_arg_recurse (cum, type, /* startbit pos= */ 0, rvec, &k);
8693 rs6000_darwin64_record_arg_flush (cum, typesize * BITS_PER_UNIT, rvec, &k);
8695 /* If any part of the struct went on the stack put all of it there.
8696 This hack is because the generic code for
8697 FUNCTION_ARG_PARTIAL_NREGS cannot handle cases where the register
8698 parts of the struct are not at the beginning. */
8699 if (cum->use_stack)
8701 if (retval)
8702 return NULL_RTX; /* doesn't go in registers at all */
8703 kbase = 0;
8704 rvec[0] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
8706 if (k > 1 || cum->use_stack)
8707 return gen_rtx_PARALLEL (BLKmode, gen_rtvec_v (k - kbase, &rvec[kbase]));
8708 else
8709 return NULL_RTX;
8712 /* Determine where to place an argument in 64-bit mode with 32-bit ABI. */
8714 static rtx
8715 rs6000_mixed_function_arg (enum machine_mode mode, const_tree type,
8716 int align_words)
8718 int n_units;
8719 int i, k;
8720 rtx rvec[GP_ARG_NUM_REG + 1];
8722 if (align_words >= GP_ARG_NUM_REG)
8723 return NULL_RTX;
8725 n_units = rs6000_arg_size (mode, type);
8727 /* Optimize the simple case where the arg fits in one gpr, except in
8728 the case of BLKmode due to assign_parms assuming that registers are
8729 BITS_PER_WORD wide. */
8730 if (n_units == 0
8731 || (n_units == 1 && mode != BLKmode))
8732 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
8734 k = 0;
8735 if (align_words + n_units > GP_ARG_NUM_REG)
8736 /* Not all of the arg fits in gprs. Say that it goes in memory too,
8737 using a magic NULL_RTX component.
8738 This is not strictly correct. Only some of the arg belongs in
8739 memory, not all of it. However, the normal scheme using
8740 function_arg_partial_nregs can result in unusual subregs, eg.
8741 (subreg:SI (reg:DF) 4), which are not handled well. The code to
8742 store the whole arg to memory is often more efficient than code
8743 to store pieces, and we know that space is available in the right
8744 place for the whole arg. */
8745 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
8747 i = 0;
8750 rtx r = gen_rtx_REG (SImode, GP_ARG_MIN_REG + align_words);
8751 rtx off = GEN_INT (i++ * 4);
8752 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
8754 while (++align_words < GP_ARG_NUM_REG && --n_units != 0);
8756 return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
8759 /* Determine where to put an argument to a function.
8760 Value is zero to push the argument on the stack,
8761 or a hard register in which to store the argument.
8763 MODE is the argument's machine mode.
8764 TYPE is the data type of the argument (as a tree).
8765 This is null for libcalls where that information may
8766 not be available.
8767 CUM is a variable of type CUMULATIVE_ARGS which gives info about
8768 the preceding args and about the function being called. It is
8769 not modified in this routine.
8770 NAMED is nonzero if this argument is a named parameter
8771 (otherwise it is an extra parameter matching an ellipsis).
8773 On RS/6000 the first eight words of non-FP are normally in registers
8774 and the rest are pushed. Under AIX, the first 13 FP args are in registers.
8775 Under V.4, the first 8 FP args are in registers.
8777 If this is floating-point and no prototype is specified, we use
8778 both an FP and integer register (or possibly FP reg and stack). Library
8779 functions (when CALL_LIBCALL is set) always have the proper types for args,
8780 so we can pass the FP value just in one register. emit_library_function
8781 doesn't support PARALLEL anyway.
8783 Note that for args passed by reference, function_arg will be called
8784 with MODE and TYPE set to that of the pointer to the arg, not the arg
8785 itself. */
8787 static rtx
8788 rs6000_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
8789 const_tree type, bool named)
8791 enum rs6000_abi abi = DEFAULT_ABI;
8793 /* Return a marker to indicate whether CR1 needs to set or clear the
8794 bit that V.4 uses to say fp args were passed in registers.
8795 Assume that we don't need the marker for software floating point,
8796 or compiler generated library calls. */
8797 if (mode == VOIDmode)
8799 if (abi == ABI_V4
8800 && (cum->call_cookie & CALL_LIBCALL) == 0
8801 && (cum->stdarg
8802 || (cum->nargs_prototype < 0
8803 && (cum->prototype || TARGET_NO_PROTOTYPE))))
8805 /* For the SPE, we need to crxor CR6 always. */
8806 if (TARGET_SPE_ABI)
8807 return GEN_INT (cum->call_cookie | CALL_V4_SET_FP_ARGS);
8808 else if (TARGET_HARD_FLOAT && TARGET_FPRS)
8809 return GEN_INT (cum->call_cookie
8810 | ((cum->fregno == FP_ARG_MIN_REG)
8811 ? CALL_V4_SET_FP_ARGS
8812 : CALL_V4_CLEAR_FP_ARGS));
8815 return GEN_INT (cum->call_cookie);
8818 if (TARGET_MACHO && rs6000_darwin64_struct_check_p (mode, type))
8820 rtx rslt = rs6000_darwin64_record_arg (cum, type, named, /*retval= */false);
8821 if (rslt != NULL_RTX)
8822 return rslt;
8823 /* Else fall through to usual handling. */
8826 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
8827 if (TARGET_64BIT && ! cum->prototype)
8829 /* Vector parameters get passed in vector register
8830 and also in GPRs or memory, in absence of prototype. */
8831 int align_words;
8832 rtx slot;
8833 align_words = (cum->words + 1) & ~1;
8835 if (align_words >= GP_ARG_NUM_REG)
8837 slot = NULL_RTX;
8839 else
8841 slot = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
8843 return gen_rtx_PARALLEL (mode,
8844 gen_rtvec (2,
8845 gen_rtx_EXPR_LIST (VOIDmode,
8846 slot, const0_rtx),
8847 gen_rtx_EXPR_LIST (VOIDmode,
8848 gen_rtx_REG (mode, cum->vregno),
8849 const0_rtx)));
8851 else
8852 return gen_rtx_REG (mode, cum->vregno);
8853 else if (TARGET_ALTIVEC_ABI
8854 && (ALTIVEC_VECTOR_MODE (mode)
8855 || VSX_VECTOR_MODE (mode)
8856 || (type && TREE_CODE (type) == VECTOR_TYPE
8857 && int_size_in_bytes (type) == 16)))
8859 if (named || abi == ABI_V4)
8860 return NULL_RTX;
8861 else
8863 /* Vector parameters to varargs functions under AIX or Darwin
8864 get passed in memory and possibly also in GPRs. */
8865 int align, align_words, n_words;
8866 enum machine_mode part_mode;
8868 /* Vector parameters must be 16-byte aligned. This places them at
8869 2 mod 4 in terms of words in 32-bit mode, since the parameter
8870 save area starts at offset 24 from the stack. In 64-bit mode,
8871 they just have to start on an even word, since the parameter
8872 save area is 16-byte aligned. */
8873 if (TARGET_32BIT)
8874 align = (2 - cum->words) & 3;
8875 else
8876 align = cum->words & 1;
8877 align_words = cum->words + align;
8879 /* Out of registers? Memory, then. */
8880 if (align_words >= GP_ARG_NUM_REG)
8881 return NULL_RTX;
8883 if (TARGET_32BIT && TARGET_POWERPC64)
8884 return rs6000_mixed_function_arg (mode, type, align_words);
8886 /* The vector value goes in GPRs. Only the part of the
8887 value in GPRs is reported here. */
8888 part_mode = mode;
8889 n_words = rs6000_arg_size (mode, type);
8890 if (align_words + n_words > GP_ARG_NUM_REG)
8891 /* Fortunately, there are only two possibilities, the value
8892 is either wholly in GPRs or half in GPRs and half not. */
8893 part_mode = DImode;
8895 return gen_rtx_REG (part_mode, GP_ARG_MIN_REG + align_words);
8898 else if (TARGET_SPE_ABI && TARGET_SPE
8899 && (SPE_VECTOR_MODE (mode)
8900 || (TARGET_E500_DOUBLE && (mode == DFmode
8901 || mode == DCmode
8902 || mode == TFmode
8903 || mode == TCmode))))
8904 return rs6000_spe_function_arg (cum, mode, type);
8906 else if (abi == ABI_V4)
8908 if (TARGET_HARD_FLOAT && TARGET_FPRS
8909 && ((TARGET_SINGLE_FLOAT && mode == SFmode)
8910 || (TARGET_DOUBLE_FLOAT && mode == DFmode)
8911 || (mode == TFmode && !TARGET_IEEEQUAD)
8912 || mode == SDmode || mode == DDmode || mode == TDmode))
8914 /* _Decimal128 must use an even/odd register pair. This assumes
8915 that the register number is odd when fregno is odd. */
8916 if (mode == TDmode && (cum->fregno % 2) == 1)
8917 cum->fregno++;
8919 if (cum->fregno + (mode == TFmode || mode == TDmode ? 1 : 0)
8920 <= FP_ARG_V4_MAX_REG)
8921 return gen_rtx_REG (mode, cum->fregno);
8922 else
8923 return NULL_RTX;
8925 else
8927 int n_words = rs6000_arg_size (mode, type);
8928 int gregno = cum->sysv_gregno;
8930 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
8931 (r7,r8) or (r9,r10). As does any other 2 word item such
8932 as complex int due to a historical mistake. */
8933 if (n_words == 2)
8934 gregno += (1 - gregno) & 1;
8936 /* Multi-reg args are not split between registers and stack. */
8937 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
8938 return NULL_RTX;
8940 if (TARGET_32BIT && TARGET_POWERPC64)
8941 return rs6000_mixed_function_arg (mode, type,
8942 gregno - GP_ARG_MIN_REG);
8943 return gen_rtx_REG (mode, gregno);
8946 else
8948 int align_words = rs6000_parm_start (mode, type, cum->words);
8950 /* _Decimal128 must be passed in an even/odd float register pair.
8951 This assumes that the register number is odd when fregno is odd. */
8952 if (mode == TDmode && (cum->fregno % 2) == 1)
8953 cum->fregno++;
8955 if (USE_FP_FOR_ARG_P (cum, mode, type))
8957 rtx rvec[GP_ARG_NUM_REG + 1];
8958 rtx r;
8959 int k;
8960 bool needs_psave;
8961 enum machine_mode fmode = mode;
8962 unsigned long n_fpreg = (GET_MODE_SIZE (mode) + 7) >> 3;
8964 if (cum->fregno + n_fpreg > FP_ARG_MAX_REG + 1)
8966 /* Currently, we only ever need one reg here because complex
8967 doubles are split. */
8968 gcc_assert (cum->fregno == FP_ARG_MAX_REG
8969 && (fmode == TFmode || fmode == TDmode));
8971 /* Long double or _Decimal128 split over regs and memory. */
8972 fmode = DECIMAL_FLOAT_MODE_P (fmode) ? DDmode : DFmode;
8975 /* Do we also need to pass this arg in the parameter save
8976 area? */
8977 needs_psave = (type
8978 && (cum->nargs_prototype <= 0
8979 || (DEFAULT_ABI == ABI_AIX
8980 && TARGET_XL_COMPAT
8981 && align_words >= GP_ARG_NUM_REG)));
8983 if (!needs_psave && mode == fmode)
8984 return gen_rtx_REG (fmode, cum->fregno);
8986 k = 0;
8987 if (needs_psave)
8989 /* Describe the part that goes in gprs or the stack.
8990 This piece must come first, before the fprs. */
8991 if (align_words < GP_ARG_NUM_REG)
8993 unsigned long n_words = rs6000_arg_size (mode, type);
8995 if (align_words + n_words > GP_ARG_NUM_REG
8996 || (TARGET_32BIT && TARGET_POWERPC64))
8998 /* If this is partially on the stack, then we only
8999 include the portion actually in registers here. */
9000 enum machine_mode rmode = TARGET_32BIT ? SImode : DImode;
9001 rtx off;
9002 int i = 0;
9003 if (align_words + n_words > GP_ARG_NUM_REG)
9004 /* Not all of the arg fits in gprs. Say that it
9005 goes in memory too, using a magic NULL_RTX
9006 component. Also see comment in
9007 rs6000_mixed_function_arg for why the normal
9008 function_arg_partial_nregs scheme doesn't work
9009 in this case. */
9010 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX,
9011 const0_rtx);
9014 r = gen_rtx_REG (rmode,
9015 GP_ARG_MIN_REG + align_words);
9016 off = GEN_INT (i++ * GET_MODE_SIZE (rmode));
9017 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
9019 while (++align_words < GP_ARG_NUM_REG && --n_words != 0);
9021 else
9023 /* The whole arg fits in gprs. */
9024 r = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
9025 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
9028 else
9029 /* It's entirely in memory. */
9030 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
9033 /* Describe where this piece goes in the fprs. */
9034 r = gen_rtx_REG (fmode, cum->fregno);
9035 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
9037 return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
9039 else if (align_words < GP_ARG_NUM_REG)
9041 if (TARGET_32BIT && TARGET_POWERPC64)
9042 return rs6000_mixed_function_arg (mode, type, align_words);
9044 if (mode == BLKmode)
9045 mode = Pmode;
9047 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
9049 else
9050 return NULL_RTX;
9054 /* For an arg passed partly in registers and partly in memory, this is
9055 the number of bytes passed in registers. For args passed entirely in
9056 registers or entirely in memory, zero. When an arg is described by a
9057 PARALLEL, perhaps using more than one register type, this function
9058 returns the number of bytes used by the first element of the PARALLEL. */
9060 static int
9061 rs6000_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode,
9062 tree type, bool named)
9064 int ret = 0;
9065 int align_words;
9067 if (DEFAULT_ABI == ABI_V4)
9068 return 0;
9070 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named)
9071 && cum->nargs_prototype >= 0)
9072 return 0;
9074 /* In this complicated case we just disable the partial_nregs code. */
9075 if (TARGET_MACHO && rs6000_darwin64_struct_check_p (mode, type))
9076 return 0;
9078 align_words = rs6000_parm_start (mode, type, cum->words);
9080 if (USE_FP_FOR_ARG_P (cum, mode, type))
9082 /* If we are passing this arg in the fixed parameter save area
9083 (gprs or memory) as well as fprs, then this function should
9084 return the number of partial bytes passed in the parameter
9085 save area rather than partial bytes passed in fprs. */
9086 if (type
9087 && (cum->nargs_prototype <= 0
9088 || (DEFAULT_ABI == ABI_AIX
9089 && TARGET_XL_COMPAT
9090 && align_words >= GP_ARG_NUM_REG)))
9091 return 0;
9092 else if (cum->fregno + ((GET_MODE_SIZE (mode) + 7) >> 3)
9093 > FP_ARG_MAX_REG + 1)
9094 ret = (FP_ARG_MAX_REG + 1 - cum->fregno) * 8;
9095 else if (cum->nargs_prototype >= 0)
9096 return 0;
9099 if (align_words < GP_ARG_NUM_REG
9100 && GP_ARG_NUM_REG < align_words + rs6000_arg_size (mode, type))
9101 ret = (GP_ARG_NUM_REG - align_words) * (TARGET_32BIT ? 4 : 8);
9103 if (ret != 0 && TARGET_DEBUG_ARG)
9104 fprintf (stderr, "rs6000_arg_partial_bytes: %d\n", ret);
9106 return ret;
9109 /* A C expression that indicates when an argument must be passed by
9110 reference. If nonzero for an argument, a copy of that argument is
9111 made in memory and a pointer to the argument is passed instead of
9112 the argument itself. The pointer is passed in whatever way is
9113 appropriate for passing a pointer to that type.
9115 Under V.4, aggregates and long double are passed by reference.
9117 As an extension to all 32-bit ABIs, AltiVec vectors are passed by
9118 reference unless the AltiVec vector extension ABI is in force.
9120 As an extension to all ABIs, variable sized types are passed by
9121 reference. */
9123 static bool
9124 rs6000_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
9125 enum machine_mode mode, const_tree type,
9126 bool named ATTRIBUTE_UNUSED)
9128 if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && mode == TFmode)
9130 if (TARGET_DEBUG_ARG)
9131 fprintf (stderr, "function_arg_pass_by_reference: V4 long double\n");
9132 return 1;
9135 if (!type)
9136 return 0;
9138 if (DEFAULT_ABI == ABI_V4 && AGGREGATE_TYPE_P (type))
9140 if (TARGET_DEBUG_ARG)
9141 fprintf (stderr, "function_arg_pass_by_reference: V4 aggregate\n");
9142 return 1;
9145 if (int_size_in_bytes (type) < 0)
9147 if (TARGET_DEBUG_ARG)
9148 fprintf (stderr, "function_arg_pass_by_reference: variable size\n");
9149 return 1;
9152 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
9153 modes only exist for GCC vector types if -maltivec. */
9154 if (TARGET_32BIT && !TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
9156 if (TARGET_DEBUG_ARG)
9157 fprintf (stderr, "function_arg_pass_by_reference: AltiVec\n");
9158 return 1;
9161 /* Pass synthetic vectors in memory. */
9162 if (TREE_CODE (type) == VECTOR_TYPE
9163 && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
9165 static bool warned_for_pass_big_vectors = false;
9166 if (TARGET_DEBUG_ARG)
9167 fprintf (stderr, "function_arg_pass_by_reference: synthetic vector\n");
9168 if (!warned_for_pass_big_vectors)
9170 warning (0, "GCC vector passed by reference: "
9171 "non-standard ABI extension with no compatibility guarantee");
9172 warned_for_pass_big_vectors = true;
9174 return 1;
9177 return 0;
9180 static void
9181 rs6000_move_block_from_reg (int regno, rtx x, int nregs)
9183 int i;
9184 enum machine_mode reg_mode = TARGET_32BIT ? SImode : DImode;
9186 if (nregs == 0)
9187 return;
9189 for (i = 0; i < nregs; i++)
9191 rtx tem = adjust_address_nv (x, reg_mode, i * GET_MODE_SIZE (reg_mode));
9192 if (reload_completed)
9194 if (! strict_memory_address_p (reg_mode, XEXP (tem, 0)))
9195 tem = NULL_RTX;
9196 else
9197 tem = simplify_gen_subreg (reg_mode, x, BLKmode,
9198 i * GET_MODE_SIZE (reg_mode));
9200 else
9201 tem = replace_equiv_address (tem, XEXP (tem, 0));
9203 gcc_assert (tem);
9205 emit_move_insn (tem, gen_rtx_REG (reg_mode, regno + i));
9209 /* Perform any needed actions needed for a function that is receiving a
9210 variable number of arguments.
9212 CUM is as above.
9214 MODE and TYPE are the mode and type of the current parameter.
9216 PRETEND_SIZE is a variable that should be set to the amount of stack
9217 that must be pushed by the prolog to pretend that our caller pushed
9220 Normally, this macro will push all remaining incoming registers on the
9221 stack and set PRETEND_SIZE to the length of the registers pushed. */
9223 static void
9224 setup_incoming_varargs (CUMULATIVE_ARGS *cum, enum machine_mode mode,
9225 tree type, int *pretend_size ATTRIBUTE_UNUSED,
9226 int no_rtl)
9228 CUMULATIVE_ARGS next_cum;
9229 int reg_size = TARGET_32BIT ? 4 : 8;
9230 rtx save_area = NULL_RTX, mem;
9231 int first_reg_offset;
9232 alias_set_type set;
9234 /* Skip the last named argument. */
9235 next_cum = *cum;
9236 rs6000_function_arg_advance_1 (&next_cum, mode, type, true, 0);
9238 if (DEFAULT_ABI == ABI_V4)
9240 first_reg_offset = next_cum.sysv_gregno - GP_ARG_MIN_REG;
9242 if (! no_rtl)
9244 int gpr_reg_num = 0, gpr_size = 0, fpr_size = 0;
9245 HOST_WIDE_INT offset = 0;
9247 /* Try to optimize the size of the varargs save area.
9248 The ABI requires that ap.reg_save_area is doubleword
9249 aligned, but we don't need to allocate space for all
9250 the bytes, only those to which we actually will save
9251 anything. */
9252 if (cfun->va_list_gpr_size && first_reg_offset < GP_ARG_NUM_REG)
9253 gpr_reg_num = GP_ARG_NUM_REG - first_reg_offset;
9254 if (TARGET_HARD_FLOAT && TARGET_FPRS
9255 && next_cum.fregno <= FP_ARG_V4_MAX_REG
9256 && cfun->va_list_fpr_size)
9258 if (gpr_reg_num)
9259 fpr_size = (next_cum.fregno - FP_ARG_MIN_REG)
9260 * UNITS_PER_FP_WORD;
9261 if (cfun->va_list_fpr_size
9262 < FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
9263 fpr_size += cfun->va_list_fpr_size * UNITS_PER_FP_WORD;
9264 else
9265 fpr_size += (FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
9266 * UNITS_PER_FP_WORD;
9268 if (gpr_reg_num)
9270 offset = -((first_reg_offset * reg_size) & ~7);
9271 if (!fpr_size && gpr_reg_num > cfun->va_list_gpr_size)
9273 gpr_reg_num = cfun->va_list_gpr_size;
9274 if (reg_size == 4 && (first_reg_offset & 1))
9275 gpr_reg_num++;
9277 gpr_size = (gpr_reg_num * reg_size + 7) & ~7;
9279 else if (fpr_size)
9280 offset = - (int) (next_cum.fregno - FP_ARG_MIN_REG)
9281 * UNITS_PER_FP_WORD
9282 - (int) (GP_ARG_NUM_REG * reg_size);
9284 if (gpr_size + fpr_size)
9286 rtx reg_save_area
9287 = assign_stack_local (BLKmode, gpr_size + fpr_size, 64);
9288 gcc_assert (GET_CODE (reg_save_area) == MEM);
9289 reg_save_area = XEXP (reg_save_area, 0);
9290 if (GET_CODE (reg_save_area) == PLUS)
9292 gcc_assert (XEXP (reg_save_area, 0)
9293 == virtual_stack_vars_rtx);
9294 gcc_assert (GET_CODE (XEXP (reg_save_area, 1)) == CONST_INT);
9295 offset += INTVAL (XEXP (reg_save_area, 1));
9297 else
9298 gcc_assert (reg_save_area == virtual_stack_vars_rtx);
9301 cfun->machine->varargs_save_offset = offset;
9302 save_area = plus_constant (virtual_stack_vars_rtx, offset);
9305 else
9307 first_reg_offset = next_cum.words;
9308 save_area = virtual_incoming_args_rtx;
9310 if (targetm.calls.must_pass_in_stack (mode, type))
9311 first_reg_offset += rs6000_arg_size (TYPE_MODE (type), type);
9314 set = get_varargs_alias_set ();
9315 if (! no_rtl && first_reg_offset < GP_ARG_NUM_REG
9316 && cfun->va_list_gpr_size)
9318 int nregs = GP_ARG_NUM_REG - first_reg_offset;
9320 if (va_list_gpr_counter_field)
9322 /* V4 va_list_gpr_size counts number of registers needed. */
9323 if (nregs > cfun->va_list_gpr_size)
9324 nregs = cfun->va_list_gpr_size;
9326 else
9328 /* char * va_list instead counts number of bytes needed. */
9329 if (nregs > cfun->va_list_gpr_size / reg_size)
9330 nregs = cfun->va_list_gpr_size / reg_size;
9333 mem = gen_rtx_MEM (BLKmode,
9334 plus_constant (save_area,
9335 first_reg_offset * reg_size));
9336 MEM_NOTRAP_P (mem) = 1;
9337 set_mem_alias_set (mem, set);
9338 set_mem_align (mem, BITS_PER_WORD);
9340 rs6000_move_block_from_reg (GP_ARG_MIN_REG + first_reg_offset, mem,
9341 nregs);
9344 /* Save FP registers if needed. */
9345 if (DEFAULT_ABI == ABI_V4
9346 && TARGET_HARD_FLOAT && TARGET_FPRS
9347 && ! no_rtl
9348 && next_cum.fregno <= FP_ARG_V4_MAX_REG
9349 && cfun->va_list_fpr_size)
9351 int fregno = next_cum.fregno, nregs;
9352 rtx cr1 = gen_rtx_REG (CCmode, CR1_REGNO);
9353 rtx lab = gen_label_rtx ();
9354 int off = (GP_ARG_NUM_REG * reg_size) + ((fregno - FP_ARG_MIN_REG)
9355 * UNITS_PER_FP_WORD);
9357 emit_jump_insn
9358 (gen_rtx_SET (VOIDmode,
9359 pc_rtx,
9360 gen_rtx_IF_THEN_ELSE (VOIDmode,
9361 gen_rtx_NE (VOIDmode, cr1,
9362 const0_rtx),
9363 gen_rtx_LABEL_REF (VOIDmode, lab),
9364 pc_rtx)));
9366 for (nregs = 0;
9367 fregno <= FP_ARG_V4_MAX_REG && nregs < cfun->va_list_fpr_size;
9368 fregno++, off += UNITS_PER_FP_WORD, nregs++)
9370 mem = gen_rtx_MEM ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
9371 ? DFmode : SFmode,
9372 plus_constant (save_area, off));
9373 MEM_NOTRAP_P (mem) = 1;
9374 set_mem_alias_set (mem, set);
9375 set_mem_align (mem, GET_MODE_ALIGNMENT (
9376 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
9377 ? DFmode : SFmode));
9378 emit_move_insn (mem, gen_rtx_REG (
9379 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
9380 ? DFmode : SFmode, fregno));
9383 emit_label (lab);
9387 /* Create the va_list data type. */
9389 static tree
9390 rs6000_build_builtin_va_list (void)
9392 tree f_gpr, f_fpr, f_res, f_ovf, f_sav, record, type_decl;
9394 /* For AIX, prefer 'char *' because that's what the system
9395 header files like. */
9396 if (DEFAULT_ABI != ABI_V4)
9397 return build_pointer_type (char_type_node);
9399 record = (*lang_hooks.types.make_type) (RECORD_TYPE);
9400 type_decl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
9401 get_identifier ("__va_list_tag"), record);
9403 f_gpr = build_decl (BUILTINS_LOCATION, FIELD_DECL, get_identifier ("gpr"),
9404 unsigned_char_type_node);
9405 f_fpr = build_decl (BUILTINS_LOCATION, FIELD_DECL, get_identifier ("fpr"),
9406 unsigned_char_type_node);
9407 /* Give the two bytes of padding a name, so that -Wpadded won't warn on
9408 every user file. */
9409 f_res = build_decl (BUILTINS_LOCATION, FIELD_DECL,
9410 get_identifier ("reserved"), short_unsigned_type_node);
9411 f_ovf = build_decl (BUILTINS_LOCATION, FIELD_DECL,
9412 get_identifier ("overflow_arg_area"),
9413 ptr_type_node);
9414 f_sav = build_decl (BUILTINS_LOCATION, FIELD_DECL,
9415 get_identifier ("reg_save_area"),
9416 ptr_type_node);
9418 va_list_gpr_counter_field = f_gpr;
9419 va_list_fpr_counter_field = f_fpr;
9421 DECL_FIELD_CONTEXT (f_gpr) = record;
9422 DECL_FIELD_CONTEXT (f_fpr) = record;
9423 DECL_FIELD_CONTEXT (f_res) = record;
9424 DECL_FIELD_CONTEXT (f_ovf) = record;
9425 DECL_FIELD_CONTEXT (f_sav) = record;
9427 TYPE_STUB_DECL (record) = type_decl;
9428 TYPE_NAME (record) = type_decl;
9429 TYPE_FIELDS (record) = f_gpr;
9430 DECL_CHAIN (f_gpr) = f_fpr;
9431 DECL_CHAIN (f_fpr) = f_res;
9432 DECL_CHAIN (f_res) = f_ovf;
9433 DECL_CHAIN (f_ovf) = f_sav;
9435 layout_type (record);
9437 /* The correct type is an array type of one element. */
9438 return build_array_type (record, build_index_type (size_zero_node));
9441 /* Implement va_start. */
9443 static void
9444 rs6000_va_start (tree valist, rtx nextarg)
9446 HOST_WIDE_INT words, n_gpr, n_fpr;
9447 tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
9448 tree gpr, fpr, ovf, sav, t;
9450 /* Only SVR4 needs something special. */
9451 if (DEFAULT_ABI != ABI_V4)
9453 std_expand_builtin_va_start (valist, nextarg);
9454 return;
9457 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
9458 f_fpr = DECL_CHAIN (f_gpr);
9459 f_res = DECL_CHAIN (f_fpr);
9460 f_ovf = DECL_CHAIN (f_res);
9461 f_sav = DECL_CHAIN (f_ovf);
9463 valist = build_simple_mem_ref (valist);
9464 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
9465 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), unshare_expr (valist),
9466 f_fpr, NULL_TREE);
9467 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), unshare_expr (valist),
9468 f_ovf, NULL_TREE);
9469 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), unshare_expr (valist),
9470 f_sav, NULL_TREE);
9472 /* Count number of gp and fp argument registers used. */
9473 words = crtl->args.info.words;
9474 n_gpr = MIN (crtl->args.info.sysv_gregno - GP_ARG_MIN_REG,
9475 GP_ARG_NUM_REG);
9476 n_fpr = MIN (crtl->args.info.fregno - FP_ARG_MIN_REG,
9477 FP_ARG_NUM_REG);
9479 if (TARGET_DEBUG_ARG)
9480 fprintf (stderr, "va_start: words = "HOST_WIDE_INT_PRINT_DEC", n_gpr = "
9481 HOST_WIDE_INT_PRINT_DEC", n_fpr = "HOST_WIDE_INT_PRINT_DEC"\n",
9482 words, n_gpr, n_fpr);
9484 if (cfun->va_list_gpr_size)
9486 t = build2 (MODIFY_EXPR, TREE_TYPE (gpr), gpr,
9487 build_int_cst (NULL_TREE, n_gpr));
9488 TREE_SIDE_EFFECTS (t) = 1;
9489 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
9492 if (cfun->va_list_fpr_size)
9494 t = build2 (MODIFY_EXPR, TREE_TYPE (fpr), fpr,
9495 build_int_cst (NULL_TREE, n_fpr));
9496 TREE_SIDE_EFFECTS (t) = 1;
9497 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
9500 /* Find the overflow area. */
9501 t = make_tree (TREE_TYPE (ovf), virtual_incoming_args_rtx);
9502 if (words != 0)
9503 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (ovf), t,
9504 size_int (words * UNITS_PER_WORD));
9505 t = build2 (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
9506 TREE_SIDE_EFFECTS (t) = 1;
9507 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
9509 /* If there were no va_arg invocations, don't set up the register
9510 save area. */
9511 if (!cfun->va_list_gpr_size
9512 && !cfun->va_list_fpr_size
9513 && n_gpr < GP_ARG_NUM_REG
9514 && n_fpr < FP_ARG_V4_MAX_REG)
9515 return;
9517 /* Find the register save area. */
9518 t = make_tree (TREE_TYPE (sav), virtual_stack_vars_rtx);
9519 if (cfun->machine->varargs_save_offset)
9520 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (sav), t,
9521 size_int (cfun->machine->varargs_save_offset));
9522 t = build2 (MODIFY_EXPR, TREE_TYPE (sav), sav, t);
9523 TREE_SIDE_EFFECTS (t) = 1;
9524 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
9527 /* Implement va_arg. */
9529 tree
9530 rs6000_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
9531 gimple_seq *post_p)
9533 tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
9534 tree gpr, fpr, ovf, sav, reg, t, u;
9535 int size, rsize, n_reg, sav_ofs, sav_scale;
9536 tree lab_false, lab_over, addr;
9537 int align;
9538 tree ptrtype = build_pointer_type_for_mode (type, ptr_mode, true);
9539 int regalign = 0;
9540 gimple stmt;
9542 if (pass_by_reference (NULL, TYPE_MODE (type), type, false))
9544 t = rs6000_gimplify_va_arg (valist, ptrtype, pre_p, post_p);
9545 return build_va_arg_indirect_ref (t);
9548 /* We need to deal with the fact that the darwin ppc64 ABI is defined by an
9549 earlier version of gcc, with the property that it always applied alignment
9550 adjustments to the va-args (even for zero-sized types). The cheapest way
9551 to deal with this is to replicate the effect of the part of
9552 std_gimplify_va_arg_expr that carries out the align adjust, for the case
9553 of relevance.
9554 We don't need to check for pass-by-reference because of the test above.
9555 We can return a simplifed answer, since we know there's no offset to add. */
9557 if (TARGET_MACHO
9558 && rs6000_darwin64_abi
9559 && integer_zerop (TYPE_SIZE (type)))
9561 unsigned HOST_WIDE_INT align, boundary;
9562 tree valist_tmp = get_initialized_tmp_var (valist, pre_p, NULL);
9563 align = PARM_BOUNDARY / BITS_PER_UNIT;
9564 boundary = rs6000_function_arg_boundary (TYPE_MODE (type), type);
9565 if (boundary > MAX_SUPPORTED_STACK_ALIGNMENT)
9566 boundary = MAX_SUPPORTED_STACK_ALIGNMENT;
9567 boundary /= BITS_PER_UNIT;
9568 if (boundary > align)
9570 tree t ;
9571 /* This updates arg ptr by the amount that would be necessary
9572 to align the zero-sized (but not zero-alignment) item. */
9573 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
9574 fold_build2 (POINTER_PLUS_EXPR,
9575 TREE_TYPE (valist),
9576 valist_tmp, size_int (boundary - 1)));
9577 gimplify_and_add (t, pre_p);
9579 t = fold_convert (sizetype, valist_tmp);
9580 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
9581 fold_convert (TREE_TYPE (valist),
9582 fold_build2 (BIT_AND_EXPR, sizetype, t,
9583 size_int (-boundary))));
9584 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist, t);
9585 gimplify_and_add (t, pre_p);
9587 /* Since it is zero-sized there's no increment for the item itself. */
9588 valist_tmp = fold_convert (build_pointer_type (type), valist_tmp);
9589 return build_va_arg_indirect_ref (valist_tmp);
9592 if (DEFAULT_ABI != ABI_V4)
9594 if (targetm.calls.split_complex_arg && TREE_CODE (type) == COMPLEX_TYPE)
9596 tree elem_type = TREE_TYPE (type);
9597 enum machine_mode elem_mode = TYPE_MODE (elem_type);
9598 int elem_size = GET_MODE_SIZE (elem_mode);
9600 if (elem_size < UNITS_PER_WORD)
9602 tree real_part, imag_part;
9603 gimple_seq post = NULL;
9605 real_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
9606 &post);
9607 /* Copy the value into a temporary, lest the formal temporary
9608 be reused out from under us. */
9609 real_part = get_initialized_tmp_var (real_part, pre_p, &post);
9610 gimple_seq_add_seq (pre_p, post);
9612 imag_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
9613 post_p);
9615 return build2 (COMPLEX_EXPR, type, real_part, imag_part);
9619 return std_gimplify_va_arg_expr (valist, type, pre_p, post_p);
9622 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
9623 f_fpr = DECL_CHAIN (f_gpr);
9624 f_res = DECL_CHAIN (f_fpr);
9625 f_ovf = DECL_CHAIN (f_res);
9626 f_sav = DECL_CHAIN (f_ovf);
9628 valist = build_va_arg_indirect_ref (valist);
9629 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
9630 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), unshare_expr (valist),
9631 f_fpr, NULL_TREE);
9632 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), unshare_expr (valist),
9633 f_ovf, NULL_TREE);
9634 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), unshare_expr (valist),
9635 f_sav, NULL_TREE);
9637 size = int_size_in_bytes (type);
9638 rsize = (size + 3) / 4;
9639 align = 1;
9641 if (TARGET_HARD_FLOAT && TARGET_FPRS
9642 && ((TARGET_SINGLE_FLOAT && TYPE_MODE (type) == SFmode)
9643 || (TARGET_DOUBLE_FLOAT
9644 && (TYPE_MODE (type) == DFmode
9645 || TYPE_MODE (type) == TFmode
9646 || TYPE_MODE (type) == SDmode
9647 || TYPE_MODE (type) == DDmode
9648 || TYPE_MODE (type) == TDmode))))
9650 /* FP args go in FP registers, if present. */
9651 reg = fpr;
9652 n_reg = (size + 7) / 8;
9653 sav_ofs = ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? 8 : 4) * 4;
9654 sav_scale = ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? 8 : 4);
9655 if (TYPE_MODE (type) != SFmode && TYPE_MODE (type) != SDmode)
9656 align = 8;
9658 else
9660 /* Otherwise into GP registers. */
9661 reg = gpr;
9662 n_reg = rsize;
9663 sav_ofs = 0;
9664 sav_scale = 4;
9665 if (n_reg == 2)
9666 align = 8;
9669 /* Pull the value out of the saved registers.... */
9671 lab_over = NULL;
9672 addr = create_tmp_var (ptr_type_node, "addr");
9674 /* AltiVec vectors never go in registers when -mabi=altivec. */
9675 if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
9676 align = 16;
9677 else
9679 lab_false = create_artificial_label (input_location);
9680 lab_over = create_artificial_label (input_location);
9682 /* Long long and SPE vectors are aligned in the registers.
9683 As are any other 2 gpr item such as complex int due to a
9684 historical mistake. */
9685 u = reg;
9686 if (n_reg == 2 && reg == gpr)
9688 regalign = 1;
9689 u = build2 (BIT_AND_EXPR, TREE_TYPE (reg), unshare_expr (reg),
9690 build_int_cst (TREE_TYPE (reg), n_reg - 1));
9691 u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg),
9692 unshare_expr (reg), u);
9694 /* _Decimal128 is passed in even/odd fpr pairs; the stored
9695 reg number is 0 for f1, so we want to make it odd. */
9696 else if (reg == fpr && TYPE_MODE (type) == TDmode)
9698 t = build2 (BIT_IOR_EXPR, TREE_TYPE (reg), unshare_expr (reg),
9699 build_int_cst (TREE_TYPE (reg), 1));
9700 u = build2 (MODIFY_EXPR, void_type_node, unshare_expr (reg), t);
9703 t = fold_convert (TREE_TYPE (reg), size_int (8 - n_reg + 1));
9704 t = build2 (GE_EXPR, boolean_type_node, u, t);
9705 u = build1 (GOTO_EXPR, void_type_node, lab_false);
9706 t = build3 (COND_EXPR, void_type_node, t, u, NULL_TREE);
9707 gimplify_and_add (t, pre_p);
9709 t = sav;
9710 if (sav_ofs)
9711 t = build2 (POINTER_PLUS_EXPR, ptr_type_node, sav, size_int (sav_ofs));
9713 u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg), unshare_expr (reg),
9714 build_int_cst (TREE_TYPE (reg), n_reg));
9715 u = fold_convert (sizetype, u);
9716 u = build2 (MULT_EXPR, sizetype, u, size_int (sav_scale));
9717 t = build2 (POINTER_PLUS_EXPR, ptr_type_node, t, u);
9719 /* _Decimal32 varargs are located in the second word of the 64-bit
9720 FP register for 32-bit binaries. */
9721 if (!TARGET_POWERPC64
9722 && TARGET_HARD_FLOAT && TARGET_FPRS
9723 && TYPE_MODE (type) == SDmode)
9724 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (size));
9726 gimplify_assign (addr, t, pre_p);
9728 gimple_seq_add_stmt (pre_p, gimple_build_goto (lab_over));
9730 stmt = gimple_build_label (lab_false);
9731 gimple_seq_add_stmt (pre_p, stmt);
9733 if ((n_reg == 2 && !regalign) || n_reg > 2)
9735 /* Ensure that we don't find any more args in regs.
9736 Alignment has taken care of for special cases. */
9737 gimplify_assign (reg, build_int_cst (TREE_TYPE (reg), 8), pre_p);
9741 /* ... otherwise out of the overflow area. */
9743 /* Care for on-stack alignment if needed. */
9744 t = ovf;
9745 if (align != 1)
9747 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (align - 1));
9748 t = fold_convert (sizetype, t);
9749 t = build2 (BIT_AND_EXPR, TREE_TYPE (t), t,
9750 size_int (-align));
9751 t = fold_convert (TREE_TYPE (ovf), t);
9753 gimplify_expr (&t, pre_p, NULL, is_gimple_val, fb_rvalue);
9755 gimplify_assign (unshare_expr (addr), t, pre_p);
9757 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (size));
9758 gimplify_assign (unshare_expr (ovf), t, pre_p);
9760 if (lab_over)
9762 stmt = gimple_build_label (lab_over);
9763 gimple_seq_add_stmt (pre_p, stmt);
9766 if (STRICT_ALIGNMENT
9767 && (TYPE_ALIGN (type)
9768 > (unsigned) BITS_PER_UNIT * (align < 4 ? 4 : align)))
9770 /* The value (of type complex double, for example) may not be
9771 aligned in memory in the saved registers, so copy via a
9772 temporary. (This is the same code as used for SPARC.) */
9773 tree tmp = create_tmp_var (type, "va_arg_tmp");
9774 tree dest_addr = build_fold_addr_expr (tmp);
9776 tree copy = build_call_expr (implicit_built_in_decls[BUILT_IN_MEMCPY],
9777 3, dest_addr, addr, size_int (rsize * 4));
9779 gimplify_and_add (copy, pre_p);
9780 addr = dest_addr;
9783 addr = fold_convert (ptrtype, addr);
9784 return build_va_arg_indirect_ref (addr);
9787 /* Builtins. */
9789 static void
9790 def_builtin (int mask, const char *name, tree type, int code)
9792 if ((mask & target_flags) || TARGET_PAIRED_FLOAT)
9794 tree t;
9795 if (rs6000_builtin_decls[code])
9796 fatal_error ("internal error: builtin function to %s already processed",
9797 name);
9799 rs6000_builtin_decls[code] = t =
9800 add_builtin_function (name, type, code, BUILT_IN_MD,
9801 NULL, NULL_TREE);
9803 gcc_assert (code >= 0 && code < (int)RS6000_BUILTIN_COUNT);
9804 switch (builtin_classify[code])
9806 default:
9807 gcc_unreachable ();
9809 /* assume builtin can do anything. */
9810 case RS6000_BTC_MISC:
9811 break;
9813 /* const function, function only depends on the inputs. */
9814 case RS6000_BTC_CONST:
9815 TREE_READONLY (t) = 1;
9816 TREE_NOTHROW (t) = 1;
9817 break;
9819 /* pure function, function can read global memory. */
9820 case RS6000_BTC_PURE:
9821 DECL_PURE_P (t) = 1;
9822 TREE_NOTHROW (t) = 1;
9823 break;
9825 /* Function is a math function. If rounding mode is on, then treat
9826 the function as not reading global memory, but it can have
9827 arbitrary side effects. If it is off, then assume the function is
9828 a const function. This mimics the ATTR_MATHFN_FPROUNDING
9829 attribute in builtin-attribute.def that is used for the math
9830 functions. */
9831 case RS6000_BTC_FP_PURE:
9832 TREE_NOTHROW (t) = 1;
9833 if (flag_rounding_math)
9835 DECL_PURE_P (t) = 1;
9836 DECL_IS_NOVOPS (t) = 1;
9838 else
9839 TREE_READONLY (t) = 1;
9840 break;
9845 /* Simple ternary operations: VECd = foo (VECa, VECb, VECc). */
9847 static const struct builtin_description bdesc_3arg[] =
9849 { MASK_ALTIVEC, CODE_FOR_fmav4sf4, "__builtin_altivec_vmaddfp", ALTIVEC_BUILTIN_VMADDFP },
9850 { MASK_ALTIVEC, CODE_FOR_altivec_vmhaddshs, "__builtin_altivec_vmhaddshs", ALTIVEC_BUILTIN_VMHADDSHS },
9851 { MASK_ALTIVEC, CODE_FOR_altivec_vmhraddshs, "__builtin_altivec_vmhraddshs", ALTIVEC_BUILTIN_VMHRADDSHS },
9852 { MASK_ALTIVEC, CODE_FOR_altivec_vmladduhm, "__builtin_altivec_vmladduhm", ALTIVEC_BUILTIN_VMLADDUHM},
9853 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumubm, "__builtin_altivec_vmsumubm", ALTIVEC_BUILTIN_VMSUMUBM },
9854 { MASK_ALTIVEC, CODE_FOR_altivec_vmsummbm, "__builtin_altivec_vmsummbm", ALTIVEC_BUILTIN_VMSUMMBM },
9855 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhm, "__builtin_altivec_vmsumuhm", ALTIVEC_BUILTIN_VMSUMUHM },
9856 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshm, "__builtin_altivec_vmsumshm", ALTIVEC_BUILTIN_VMSUMSHM },
9857 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhs, "__builtin_altivec_vmsumuhs", ALTIVEC_BUILTIN_VMSUMUHS },
9858 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshs, "__builtin_altivec_vmsumshs", ALTIVEC_BUILTIN_VMSUMSHS },
9859 { MASK_ALTIVEC, CODE_FOR_nfmsv4sf4, "__builtin_altivec_vnmsubfp", ALTIVEC_BUILTIN_VNMSUBFP },
9860 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2df, "__builtin_altivec_vperm_2df", ALTIVEC_BUILTIN_VPERM_2DF },
9861 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2di, "__builtin_altivec_vperm_2di", ALTIVEC_BUILTIN_VPERM_2DI },
9862 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4sf, "__builtin_altivec_vperm_4sf", ALTIVEC_BUILTIN_VPERM_4SF },
9863 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4si, "__builtin_altivec_vperm_4si", ALTIVEC_BUILTIN_VPERM_4SI },
9864 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v8hi, "__builtin_altivec_vperm_8hi", ALTIVEC_BUILTIN_VPERM_8HI },
9865 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_altivec_vperm_16qi", ALTIVEC_BUILTIN_VPERM_16QI },
9866 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2di_uns, "__builtin_altivec_vperm_2di_uns", ALTIVEC_BUILTIN_VPERM_2DI_UNS },
9867 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4si_uns, "__builtin_altivec_vperm_4si_uns", ALTIVEC_BUILTIN_VPERM_4SI_UNS },
9868 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v8hi_uns, "__builtin_altivec_vperm_8hi_uns", ALTIVEC_BUILTIN_VPERM_8HI_UNS },
9869 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_altivec_vperm_16qi_uns", ALTIVEC_BUILTIN_VPERM_16QI_UNS },
9870 { MASK_ALTIVEC, CODE_FOR_vector_select_v4sf, "__builtin_altivec_vsel_4sf", ALTIVEC_BUILTIN_VSEL_4SF },
9871 { MASK_ALTIVEC, CODE_FOR_vector_select_v4si, "__builtin_altivec_vsel_4si", ALTIVEC_BUILTIN_VSEL_4SI },
9872 { MASK_ALTIVEC, CODE_FOR_vector_select_v8hi, "__builtin_altivec_vsel_8hi", ALTIVEC_BUILTIN_VSEL_8HI },
9873 { MASK_ALTIVEC, CODE_FOR_vector_select_v16qi, "__builtin_altivec_vsel_16qi", ALTIVEC_BUILTIN_VSEL_16QI },
9874 { MASK_ALTIVEC, CODE_FOR_vector_select_v2df, "__builtin_altivec_vsel_2df", ALTIVEC_BUILTIN_VSEL_2DF },
9875 { MASK_ALTIVEC, CODE_FOR_vector_select_v2di, "__builtin_altivec_vsel_2di", ALTIVEC_BUILTIN_VSEL_2DI },
9876 { MASK_ALTIVEC, CODE_FOR_vector_select_v4si_uns, "__builtin_altivec_vsel_4si_uns", ALTIVEC_BUILTIN_VSEL_4SI_UNS },
9877 { MASK_ALTIVEC, CODE_FOR_vector_select_v8hi_uns, "__builtin_altivec_vsel_8hi_uns", ALTIVEC_BUILTIN_VSEL_8HI_UNS },
9878 { MASK_ALTIVEC, CODE_FOR_vector_select_v16qi_uns, "__builtin_altivec_vsel_16qi_uns", ALTIVEC_BUILTIN_VSEL_16QI_UNS },
9879 { MASK_ALTIVEC, CODE_FOR_vector_select_v2di_uns, "__builtin_altivec_vsel_2di_uns", ALTIVEC_BUILTIN_VSEL_2DI_UNS },
9880 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v16qi, "__builtin_altivec_vsldoi_16qi", ALTIVEC_BUILTIN_VSLDOI_16QI },
9881 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v8hi, "__builtin_altivec_vsldoi_8hi", ALTIVEC_BUILTIN_VSLDOI_8HI },
9882 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v4si, "__builtin_altivec_vsldoi_4si", ALTIVEC_BUILTIN_VSLDOI_4SI },
9883 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v4sf, "__builtin_altivec_vsldoi_4sf", ALTIVEC_BUILTIN_VSLDOI_4SF },
9885 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_madd", ALTIVEC_BUILTIN_VEC_MADD },
9886 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_madds", ALTIVEC_BUILTIN_VEC_MADDS },
9887 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mladd", ALTIVEC_BUILTIN_VEC_MLADD },
9888 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mradds", ALTIVEC_BUILTIN_VEC_MRADDS },
9889 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msum", ALTIVEC_BUILTIN_VEC_MSUM },
9890 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumshm", ALTIVEC_BUILTIN_VEC_VMSUMSHM },
9891 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumuhm", ALTIVEC_BUILTIN_VEC_VMSUMUHM },
9892 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsummbm", ALTIVEC_BUILTIN_VEC_VMSUMMBM },
9893 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumubm", ALTIVEC_BUILTIN_VEC_VMSUMUBM },
9894 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msums", ALTIVEC_BUILTIN_VEC_MSUMS },
9895 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumshs", ALTIVEC_BUILTIN_VEC_VMSUMSHS },
9896 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumuhs", ALTIVEC_BUILTIN_VEC_VMSUMUHS },
9897 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nmsub", ALTIVEC_BUILTIN_VEC_NMSUB },
9898 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_perm", ALTIVEC_BUILTIN_VEC_PERM },
9899 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sel", ALTIVEC_BUILTIN_VEC_SEL },
9901 { MASK_VSX, CODE_FOR_fmav2df4, "__builtin_vsx_xvmadddp", VSX_BUILTIN_XVMADDDP },
9902 { MASK_VSX, CODE_FOR_fmsv2df4, "__builtin_vsx_xvmsubdp", VSX_BUILTIN_XVMSUBDP },
9903 { MASK_VSX, CODE_FOR_nfmav2df4, "__builtin_vsx_xvnmadddp", VSX_BUILTIN_XVNMADDDP },
9904 { MASK_VSX, CODE_FOR_nfmsv2df4, "__builtin_vsx_xvnmsubdp", VSX_BUILTIN_XVNMSUBDP },
9906 { MASK_VSX, CODE_FOR_fmav4sf4, "__builtin_vsx_xvmaddsp", VSX_BUILTIN_XVMADDSP },
9907 { MASK_VSX, CODE_FOR_fmsv4sf4, "__builtin_vsx_xvmsubsp", VSX_BUILTIN_XVMSUBSP },
9908 { MASK_VSX, CODE_FOR_nfmav4sf4, "__builtin_vsx_xvnmaddsp", VSX_BUILTIN_XVNMADDSP },
9909 { MASK_VSX, CODE_FOR_nfmsv4sf4, "__builtin_vsx_xvnmsubsp", VSX_BUILTIN_XVNMSUBSP },
9911 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msub", VSX_BUILTIN_VEC_MSUB },
9912 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nmadd", VSX_BUILTIN_VEC_NMADD },
9914 { MASK_VSX, CODE_FOR_vector_select_v2di, "__builtin_vsx_xxsel_2di", VSX_BUILTIN_XXSEL_2DI },
9915 { MASK_VSX, CODE_FOR_vector_select_v2df, "__builtin_vsx_xxsel_2df", VSX_BUILTIN_XXSEL_2DF },
9916 { MASK_VSX, CODE_FOR_vector_select_v4sf, "__builtin_vsx_xxsel_4sf", VSX_BUILTIN_XXSEL_4SF },
9917 { MASK_VSX, CODE_FOR_vector_select_v4si, "__builtin_vsx_xxsel_4si", VSX_BUILTIN_XXSEL_4SI },
9918 { MASK_VSX, CODE_FOR_vector_select_v8hi, "__builtin_vsx_xxsel_8hi", VSX_BUILTIN_XXSEL_8HI },
9919 { MASK_VSX, CODE_FOR_vector_select_v16qi, "__builtin_vsx_xxsel_16qi", VSX_BUILTIN_XXSEL_16QI },
9920 { MASK_VSX, CODE_FOR_vector_select_v2di_uns, "__builtin_vsx_xxsel_2di_uns", VSX_BUILTIN_XXSEL_2DI_UNS },
9921 { MASK_VSX, CODE_FOR_vector_select_v4si_uns, "__builtin_vsx_xxsel_4si_uns", VSX_BUILTIN_XXSEL_4SI_UNS },
9922 { MASK_VSX, CODE_FOR_vector_select_v8hi_uns, "__builtin_vsx_xxsel_8hi_uns", VSX_BUILTIN_XXSEL_8HI_UNS },
9923 { MASK_VSX, CODE_FOR_vector_select_v16qi_uns, "__builtin_vsx_xxsel_16qi_uns", VSX_BUILTIN_XXSEL_16QI_UNS },
9925 { MASK_VSX, CODE_FOR_altivec_vperm_v2di, "__builtin_vsx_vperm_2di", VSX_BUILTIN_VPERM_2DI },
9926 { MASK_VSX, CODE_FOR_altivec_vperm_v2df, "__builtin_vsx_vperm_2df", VSX_BUILTIN_VPERM_2DF },
9927 { MASK_VSX, CODE_FOR_altivec_vperm_v4sf, "__builtin_vsx_vperm_4sf", VSX_BUILTIN_VPERM_4SF },
9928 { MASK_VSX, CODE_FOR_altivec_vperm_v4si, "__builtin_vsx_vperm_4si", VSX_BUILTIN_VPERM_4SI },
9929 { MASK_VSX, CODE_FOR_altivec_vperm_v8hi, "__builtin_vsx_vperm_8hi", VSX_BUILTIN_VPERM_8HI },
9930 { MASK_VSX, CODE_FOR_altivec_vperm_v16qi, "__builtin_vsx_vperm_16qi", VSX_BUILTIN_VPERM_16QI },
9931 { MASK_VSX, CODE_FOR_altivec_vperm_v2di_uns, "__builtin_vsx_vperm_2di_uns", VSX_BUILTIN_VPERM_2DI_UNS },
9932 { MASK_VSX, CODE_FOR_altivec_vperm_v4si_uns, "__builtin_vsx_vperm_4si_uns", VSX_BUILTIN_VPERM_4SI_UNS },
9933 { MASK_VSX, CODE_FOR_altivec_vperm_v8hi_uns, "__builtin_vsx_vperm_8hi_uns", VSX_BUILTIN_VPERM_8HI_UNS },
9934 { MASK_VSX, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_vsx_vperm_16qi_uns", VSX_BUILTIN_VPERM_16QI_UNS },
9936 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v2df, "__builtin_vsx_xxpermdi_2df", VSX_BUILTIN_XXPERMDI_2DF },
9937 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v2di, "__builtin_vsx_xxpermdi_2di", VSX_BUILTIN_XXPERMDI_2DI },
9938 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v4sf, "__builtin_vsx_xxpermdi_4sf", VSX_BUILTIN_XXPERMDI_4SF },
9939 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v4si, "__builtin_vsx_xxpermdi_4si", VSX_BUILTIN_XXPERMDI_4SI },
9940 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v8hi, "__builtin_vsx_xxpermdi_8hi", VSX_BUILTIN_XXPERMDI_8HI },
9941 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v16qi, "__builtin_vsx_xxpermdi_16qi", VSX_BUILTIN_XXPERMDI_16QI },
9942 { MASK_VSX, CODE_FOR_nothing, "__builtin_vsx_xxpermdi", VSX_BUILTIN_VEC_XXPERMDI },
9943 { MASK_VSX, CODE_FOR_vsx_set_v2df, "__builtin_vsx_set_2df", VSX_BUILTIN_SET_2DF },
9944 { MASK_VSX, CODE_FOR_vsx_set_v2di, "__builtin_vsx_set_2di", VSX_BUILTIN_SET_2DI },
9946 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v2di, "__builtin_vsx_xxsldwi_2di", VSX_BUILTIN_XXSLDWI_2DI },
9947 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v2df, "__builtin_vsx_xxsldwi_2df", VSX_BUILTIN_XXSLDWI_2DF },
9948 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v4sf, "__builtin_vsx_xxsldwi_4sf", VSX_BUILTIN_XXSLDWI_4SF },
9949 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v4si, "__builtin_vsx_xxsldwi_4si", VSX_BUILTIN_XXSLDWI_4SI },
9950 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v8hi, "__builtin_vsx_xxsldwi_8hi", VSX_BUILTIN_XXSLDWI_8HI },
9951 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v16qi, "__builtin_vsx_xxsldwi_16qi", VSX_BUILTIN_XXSLDWI_16QI },
9952 { MASK_VSX, CODE_FOR_nothing, "__builtin_vsx_xxsldwi", VSX_BUILTIN_VEC_XXSLDWI },
9954 { 0, CODE_FOR_fmsv2sf4, "__builtin_paired_msub", PAIRED_BUILTIN_MSUB },
9955 { 0, CODE_FOR_fmav2sf4, "__builtin_paired_madd", PAIRED_BUILTIN_MADD },
9956 { 0, CODE_FOR_paired_madds0, "__builtin_paired_madds0", PAIRED_BUILTIN_MADDS0 },
9957 { 0, CODE_FOR_paired_madds1, "__builtin_paired_madds1", PAIRED_BUILTIN_MADDS1 },
9958 { 0, CODE_FOR_nfmsv2sf4, "__builtin_paired_nmsub", PAIRED_BUILTIN_NMSUB },
9959 { 0, CODE_FOR_nfmav2sf4, "__builtin_paired_nmadd", PAIRED_BUILTIN_NMADD },
9960 { 0, CODE_FOR_paired_sum0, "__builtin_paired_sum0", PAIRED_BUILTIN_SUM0 },
9961 { 0, CODE_FOR_paired_sum1, "__builtin_paired_sum1", PAIRED_BUILTIN_SUM1 },
9962 { 0, CODE_FOR_selv2sf4, "__builtin_paired_selv2sf4", PAIRED_BUILTIN_SELV2SF4 },
9965 /* DST operations: void foo (void *, const int, const char). */
9967 static const struct builtin_description bdesc_dst[] =
9969 { MASK_ALTIVEC, CODE_FOR_altivec_dst, "__builtin_altivec_dst", ALTIVEC_BUILTIN_DST },
9970 { MASK_ALTIVEC, CODE_FOR_altivec_dstt, "__builtin_altivec_dstt", ALTIVEC_BUILTIN_DSTT },
9971 { MASK_ALTIVEC, CODE_FOR_altivec_dstst, "__builtin_altivec_dstst", ALTIVEC_BUILTIN_DSTST },
9972 { MASK_ALTIVEC, CODE_FOR_altivec_dststt, "__builtin_altivec_dststt", ALTIVEC_BUILTIN_DSTSTT },
9974 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dst", ALTIVEC_BUILTIN_VEC_DST },
9975 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dstt", ALTIVEC_BUILTIN_VEC_DSTT },
9976 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dstst", ALTIVEC_BUILTIN_VEC_DSTST },
9977 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dststt", ALTIVEC_BUILTIN_VEC_DSTSTT }
9980 /* Simple binary operations: VECc = foo (VECa, VECb). */
9982 static struct builtin_description bdesc_2arg[] =
9984 { MASK_ALTIVEC, CODE_FOR_addv16qi3, "__builtin_altivec_vaddubm", ALTIVEC_BUILTIN_VADDUBM },
9985 { MASK_ALTIVEC, CODE_FOR_addv8hi3, "__builtin_altivec_vadduhm", ALTIVEC_BUILTIN_VADDUHM },
9986 { MASK_ALTIVEC, CODE_FOR_addv4si3, "__builtin_altivec_vadduwm", ALTIVEC_BUILTIN_VADDUWM },
9987 { MASK_ALTIVEC, CODE_FOR_addv4sf3, "__builtin_altivec_vaddfp", ALTIVEC_BUILTIN_VADDFP },
9988 { MASK_ALTIVEC, CODE_FOR_altivec_vaddcuw, "__builtin_altivec_vaddcuw", ALTIVEC_BUILTIN_VADDCUW },
9989 { MASK_ALTIVEC, CODE_FOR_altivec_vaddubs, "__builtin_altivec_vaddubs", ALTIVEC_BUILTIN_VADDUBS },
9990 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsbs, "__builtin_altivec_vaddsbs", ALTIVEC_BUILTIN_VADDSBS },
9991 { MASK_ALTIVEC, CODE_FOR_altivec_vadduhs, "__builtin_altivec_vadduhs", ALTIVEC_BUILTIN_VADDUHS },
9992 { MASK_ALTIVEC, CODE_FOR_altivec_vaddshs, "__builtin_altivec_vaddshs", ALTIVEC_BUILTIN_VADDSHS },
9993 { MASK_ALTIVEC, CODE_FOR_altivec_vadduws, "__builtin_altivec_vadduws", ALTIVEC_BUILTIN_VADDUWS },
9994 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsws, "__builtin_altivec_vaddsws", ALTIVEC_BUILTIN_VADDSWS },
9995 { MASK_ALTIVEC, CODE_FOR_andv4si3, "__builtin_altivec_vand", ALTIVEC_BUILTIN_VAND },
9996 { MASK_ALTIVEC, CODE_FOR_andcv4si3, "__builtin_altivec_vandc", ALTIVEC_BUILTIN_VANDC },
9997 { MASK_ALTIVEC, CODE_FOR_altivec_vavgub, "__builtin_altivec_vavgub", ALTIVEC_BUILTIN_VAVGUB },
9998 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsb, "__builtin_altivec_vavgsb", ALTIVEC_BUILTIN_VAVGSB },
9999 { MASK_ALTIVEC, CODE_FOR_altivec_vavguh, "__builtin_altivec_vavguh", ALTIVEC_BUILTIN_VAVGUH },
10000 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsh, "__builtin_altivec_vavgsh", ALTIVEC_BUILTIN_VAVGSH },
10001 { MASK_ALTIVEC, CODE_FOR_altivec_vavguw, "__builtin_altivec_vavguw", ALTIVEC_BUILTIN_VAVGUW },
10002 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsw, "__builtin_altivec_vavgsw", ALTIVEC_BUILTIN_VAVGSW },
10003 { MASK_ALTIVEC, CODE_FOR_altivec_vcfux, "__builtin_altivec_vcfux", ALTIVEC_BUILTIN_VCFUX },
10004 { MASK_ALTIVEC, CODE_FOR_altivec_vcfsx, "__builtin_altivec_vcfsx", ALTIVEC_BUILTIN_VCFSX },
10005 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpbfp, "__builtin_altivec_vcmpbfp", ALTIVEC_BUILTIN_VCMPBFP },
10006 { MASK_ALTIVEC, CODE_FOR_vector_eqv16qi, "__builtin_altivec_vcmpequb", ALTIVEC_BUILTIN_VCMPEQUB },
10007 { MASK_ALTIVEC, CODE_FOR_vector_eqv8hi, "__builtin_altivec_vcmpequh", ALTIVEC_BUILTIN_VCMPEQUH },
10008 { MASK_ALTIVEC, CODE_FOR_vector_eqv4si, "__builtin_altivec_vcmpequw", ALTIVEC_BUILTIN_VCMPEQUW },
10009 { MASK_ALTIVEC, CODE_FOR_vector_eqv4sf, "__builtin_altivec_vcmpeqfp", ALTIVEC_BUILTIN_VCMPEQFP },
10010 { MASK_ALTIVEC, CODE_FOR_vector_gev4sf, "__builtin_altivec_vcmpgefp", ALTIVEC_BUILTIN_VCMPGEFP },
10011 { MASK_ALTIVEC, CODE_FOR_vector_gtuv16qi, "__builtin_altivec_vcmpgtub", ALTIVEC_BUILTIN_VCMPGTUB },
10012 { MASK_ALTIVEC, CODE_FOR_vector_gtv16qi, "__builtin_altivec_vcmpgtsb", ALTIVEC_BUILTIN_VCMPGTSB },
10013 { MASK_ALTIVEC, CODE_FOR_vector_gtuv8hi, "__builtin_altivec_vcmpgtuh", ALTIVEC_BUILTIN_VCMPGTUH },
10014 { MASK_ALTIVEC, CODE_FOR_vector_gtv8hi, "__builtin_altivec_vcmpgtsh", ALTIVEC_BUILTIN_VCMPGTSH },
10015 { MASK_ALTIVEC, CODE_FOR_vector_gtuv4si, "__builtin_altivec_vcmpgtuw", ALTIVEC_BUILTIN_VCMPGTUW },
10016 { MASK_ALTIVEC, CODE_FOR_vector_gtv4si, "__builtin_altivec_vcmpgtsw", ALTIVEC_BUILTIN_VCMPGTSW },
10017 { MASK_ALTIVEC, CODE_FOR_vector_gtv4sf, "__builtin_altivec_vcmpgtfp", ALTIVEC_BUILTIN_VCMPGTFP },
10018 { MASK_ALTIVEC, CODE_FOR_altivec_vctsxs, "__builtin_altivec_vctsxs", ALTIVEC_BUILTIN_VCTSXS },
10019 { MASK_ALTIVEC, CODE_FOR_altivec_vctuxs, "__builtin_altivec_vctuxs", ALTIVEC_BUILTIN_VCTUXS },
10020 { MASK_ALTIVEC, CODE_FOR_umaxv16qi3, "__builtin_altivec_vmaxub", ALTIVEC_BUILTIN_VMAXUB },
10021 { MASK_ALTIVEC, CODE_FOR_smaxv16qi3, "__builtin_altivec_vmaxsb", ALTIVEC_BUILTIN_VMAXSB },
10022 { MASK_ALTIVEC, CODE_FOR_umaxv8hi3, "__builtin_altivec_vmaxuh", ALTIVEC_BUILTIN_VMAXUH },
10023 { MASK_ALTIVEC, CODE_FOR_smaxv8hi3, "__builtin_altivec_vmaxsh", ALTIVEC_BUILTIN_VMAXSH },
10024 { MASK_ALTIVEC, CODE_FOR_umaxv4si3, "__builtin_altivec_vmaxuw", ALTIVEC_BUILTIN_VMAXUW },
10025 { MASK_ALTIVEC, CODE_FOR_smaxv4si3, "__builtin_altivec_vmaxsw", ALTIVEC_BUILTIN_VMAXSW },
10026 { MASK_ALTIVEC, CODE_FOR_smaxv4sf3, "__builtin_altivec_vmaxfp", ALTIVEC_BUILTIN_VMAXFP },
10027 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghb, "__builtin_altivec_vmrghb", ALTIVEC_BUILTIN_VMRGHB },
10028 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghh, "__builtin_altivec_vmrghh", ALTIVEC_BUILTIN_VMRGHH },
10029 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghw, "__builtin_altivec_vmrghw", ALTIVEC_BUILTIN_VMRGHW },
10030 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglb, "__builtin_altivec_vmrglb", ALTIVEC_BUILTIN_VMRGLB },
10031 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglh, "__builtin_altivec_vmrglh", ALTIVEC_BUILTIN_VMRGLH },
10032 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglw, "__builtin_altivec_vmrglw", ALTIVEC_BUILTIN_VMRGLW },
10033 { MASK_ALTIVEC, CODE_FOR_uminv16qi3, "__builtin_altivec_vminub", ALTIVEC_BUILTIN_VMINUB },
10034 { MASK_ALTIVEC, CODE_FOR_sminv16qi3, "__builtin_altivec_vminsb", ALTIVEC_BUILTIN_VMINSB },
10035 { MASK_ALTIVEC, CODE_FOR_uminv8hi3, "__builtin_altivec_vminuh", ALTIVEC_BUILTIN_VMINUH },
10036 { MASK_ALTIVEC, CODE_FOR_sminv8hi3, "__builtin_altivec_vminsh", ALTIVEC_BUILTIN_VMINSH },
10037 { MASK_ALTIVEC, CODE_FOR_uminv4si3, "__builtin_altivec_vminuw", ALTIVEC_BUILTIN_VMINUW },
10038 { MASK_ALTIVEC, CODE_FOR_sminv4si3, "__builtin_altivec_vminsw", ALTIVEC_BUILTIN_VMINSW },
10039 { MASK_ALTIVEC, CODE_FOR_sminv4sf3, "__builtin_altivec_vminfp", ALTIVEC_BUILTIN_VMINFP },
10040 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleub, "__builtin_altivec_vmuleub", ALTIVEC_BUILTIN_VMULEUB },
10041 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleub, "__builtin_altivec_vmuleub_uns", ALTIVEC_BUILTIN_VMULEUB_UNS },
10042 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesb, "__builtin_altivec_vmulesb", ALTIVEC_BUILTIN_VMULESB },
10043 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleuh, "__builtin_altivec_vmuleuh", ALTIVEC_BUILTIN_VMULEUH },
10044 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleuh, "__builtin_altivec_vmuleuh_uns", ALTIVEC_BUILTIN_VMULEUH_UNS },
10045 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesh, "__builtin_altivec_vmulesh", ALTIVEC_BUILTIN_VMULESH },
10046 { MASK_ALTIVEC, CODE_FOR_altivec_vmuloub, "__builtin_altivec_vmuloub", ALTIVEC_BUILTIN_VMULOUB },
10047 { MASK_ALTIVEC, CODE_FOR_altivec_vmuloub, "__builtin_altivec_vmuloub_uns", ALTIVEC_BUILTIN_VMULOUB_UNS },
10048 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosb, "__builtin_altivec_vmulosb", ALTIVEC_BUILTIN_VMULOSB },
10049 { MASK_ALTIVEC, CODE_FOR_altivec_vmulouh, "__builtin_altivec_vmulouh", ALTIVEC_BUILTIN_VMULOUH },
10050 { MASK_ALTIVEC, CODE_FOR_altivec_vmulouh, "__builtin_altivec_vmulouh_uns", ALTIVEC_BUILTIN_VMULOUH_UNS },
10051 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosh, "__builtin_altivec_vmulosh", ALTIVEC_BUILTIN_VMULOSH },
10052 { MASK_ALTIVEC, CODE_FOR_norv4si3, "__builtin_altivec_vnor", ALTIVEC_BUILTIN_VNOR },
10053 { MASK_ALTIVEC, CODE_FOR_iorv4si3, "__builtin_altivec_vor", ALTIVEC_BUILTIN_VOR },
10054 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhum, "__builtin_altivec_vpkuhum", ALTIVEC_BUILTIN_VPKUHUM },
10055 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwum, "__builtin_altivec_vpkuwum", ALTIVEC_BUILTIN_VPKUWUM },
10056 { MASK_ALTIVEC, CODE_FOR_altivec_vpkpx, "__builtin_altivec_vpkpx", ALTIVEC_BUILTIN_VPKPX },
10057 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshss, "__builtin_altivec_vpkshss", ALTIVEC_BUILTIN_VPKSHSS },
10058 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswss, "__builtin_altivec_vpkswss", ALTIVEC_BUILTIN_VPKSWSS },
10059 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhus, "__builtin_altivec_vpkuhus", ALTIVEC_BUILTIN_VPKUHUS },
10060 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshus, "__builtin_altivec_vpkshus", ALTIVEC_BUILTIN_VPKSHUS },
10061 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwus, "__builtin_altivec_vpkuwus", ALTIVEC_BUILTIN_VPKUWUS },
10062 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswus, "__builtin_altivec_vpkswus", ALTIVEC_BUILTIN_VPKSWUS },
10063 { MASK_ALTIVEC, CODE_FOR_recipv4sf3, "__builtin_altivec_vrecipdivfp", ALTIVEC_BUILTIN_VRECIPFP },
10064 { MASK_ALTIVEC, CODE_FOR_vrotlv16qi3, "__builtin_altivec_vrlb", ALTIVEC_BUILTIN_VRLB },
10065 { MASK_ALTIVEC, CODE_FOR_vrotlv8hi3, "__builtin_altivec_vrlh", ALTIVEC_BUILTIN_VRLH },
10066 { MASK_ALTIVEC, CODE_FOR_vrotlv4si3, "__builtin_altivec_vrlw", ALTIVEC_BUILTIN_VRLW },
10067 { MASK_ALTIVEC, CODE_FOR_vashlv16qi3, "__builtin_altivec_vslb", ALTIVEC_BUILTIN_VSLB },
10068 { MASK_ALTIVEC, CODE_FOR_vashlv8hi3, "__builtin_altivec_vslh", ALTIVEC_BUILTIN_VSLH },
10069 { MASK_ALTIVEC, CODE_FOR_vashlv4si3, "__builtin_altivec_vslw", ALTIVEC_BUILTIN_VSLW },
10070 { MASK_ALTIVEC, CODE_FOR_altivec_vsl, "__builtin_altivec_vsl", ALTIVEC_BUILTIN_VSL },
10071 { MASK_ALTIVEC, CODE_FOR_altivec_vslo, "__builtin_altivec_vslo", ALTIVEC_BUILTIN_VSLO },
10072 { MASK_ALTIVEC, CODE_FOR_altivec_vspltb, "__builtin_altivec_vspltb", ALTIVEC_BUILTIN_VSPLTB },
10073 { MASK_ALTIVEC, CODE_FOR_altivec_vsplth, "__builtin_altivec_vsplth", ALTIVEC_BUILTIN_VSPLTH },
10074 { MASK_ALTIVEC, CODE_FOR_altivec_vspltw, "__builtin_altivec_vspltw", ALTIVEC_BUILTIN_VSPLTW },
10075 { MASK_ALTIVEC, CODE_FOR_vlshrv16qi3, "__builtin_altivec_vsrb", ALTIVEC_BUILTIN_VSRB },
10076 { MASK_ALTIVEC, CODE_FOR_vlshrv8hi3, "__builtin_altivec_vsrh", ALTIVEC_BUILTIN_VSRH },
10077 { MASK_ALTIVEC, CODE_FOR_vlshrv4si3, "__builtin_altivec_vsrw", ALTIVEC_BUILTIN_VSRW },
10078 { MASK_ALTIVEC, CODE_FOR_vashrv16qi3, "__builtin_altivec_vsrab", ALTIVEC_BUILTIN_VSRAB },
10079 { MASK_ALTIVEC, CODE_FOR_vashrv8hi3, "__builtin_altivec_vsrah", ALTIVEC_BUILTIN_VSRAH },
10080 { MASK_ALTIVEC, CODE_FOR_vashrv4si3, "__builtin_altivec_vsraw", ALTIVEC_BUILTIN_VSRAW },
10081 { MASK_ALTIVEC, CODE_FOR_altivec_vsr, "__builtin_altivec_vsr", ALTIVEC_BUILTIN_VSR },
10082 { MASK_ALTIVEC, CODE_FOR_altivec_vsro, "__builtin_altivec_vsro", ALTIVEC_BUILTIN_VSRO },
10083 { MASK_ALTIVEC, CODE_FOR_subv16qi3, "__builtin_altivec_vsububm", ALTIVEC_BUILTIN_VSUBUBM },
10084 { MASK_ALTIVEC, CODE_FOR_subv8hi3, "__builtin_altivec_vsubuhm", ALTIVEC_BUILTIN_VSUBUHM },
10085 { MASK_ALTIVEC, CODE_FOR_subv4si3, "__builtin_altivec_vsubuwm", ALTIVEC_BUILTIN_VSUBUWM },
10086 { MASK_ALTIVEC, CODE_FOR_subv4sf3, "__builtin_altivec_vsubfp", ALTIVEC_BUILTIN_VSUBFP },
10087 { MASK_ALTIVEC, CODE_FOR_altivec_vsubcuw, "__builtin_altivec_vsubcuw", ALTIVEC_BUILTIN_VSUBCUW },
10088 { MASK_ALTIVEC, CODE_FOR_altivec_vsububs, "__builtin_altivec_vsububs", ALTIVEC_BUILTIN_VSUBUBS },
10089 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsbs, "__builtin_altivec_vsubsbs", ALTIVEC_BUILTIN_VSUBSBS },
10090 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuhs, "__builtin_altivec_vsubuhs", ALTIVEC_BUILTIN_VSUBUHS },
10091 { MASK_ALTIVEC, CODE_FOR_altivec_vsubshs, "__builtin_altivec_vsubshs", ALTIVEC_BUILTIN_VSUBSHS },
10092 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuws, "__builtin_altivec_vsubuws", ALTIVEC_BUILTIN_VSUBUWS },
10093 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsws, "__builtin_altivec_vsubsws", ALTIVEC_BUILTIN_VSUBSWS },
10094 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4ubs, "__builtin_altivec_vsum4ubs", ALTIVEC_BUILTIN_VSUM4UBS },
10095 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4sbs, "__builtin_altivec_vsum4sbs", ALTIVEC_BUILTIN_VSUM4SBS },
10096 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4shs, "__builtin_altivec_vsum4shs", ALTIVEC_BUILTIN_VSUM4SHS },
10097 { MASK_ALTIVEC, CODE_FOR_altivec_vsum2sws, "__builtin_altivec_vsum2sws", ALTIVEC_BUILTIN_VSUM2SWS },
10098 { MASK_ALTIVEC, CODE_FOR_altivec_vsumsws, "__builtin_altivec_vsumsws", ALTIVEC_BUILTIN_VSUMSWS },
10099 { MASK_ALTIVEC, CODE_FOR_xorv4si3, "__builtin_altivec_vxor", ALTIVEC_BUILTIN_VXOR },
10100 { MASK_ALTIVEC, CODE_FOR_vector_copysignv4sf3, "__builtin_altivec_copysignfp", ALTIVEC_BUILTIN_COPYSIGN_V4SF },
10102 { MASK_VSX, CODE_FOR_addv2df3, "__builtin_vsx_xvadddp", VSX_BUILTIN_XVADDDP },
10103 { MASK_VSX, CODE_FOR_subv2df3, "__builtin_vsx_xvsubdp", VSX_BUILTIN_XVSUBDP },
10104 { MASK_VSX, CODE_FOR_mulv2df3, "__builtin_vsx_xvmuldp", VSX_BUILTIN_XVMULDP },
10105 { MASK_VSX, CODE_FOR_divv2df3, "__builtin_vsx_xvdivdp", VSX_BUILTIN_XVDIVDP },
10106 { MASK_VSX, CODE_FOR_recipv2df3, "__builtin_vsx_xvrecipdivdp", VSX_BUILTIN_RECIP_V2DF },
10107 { MASK_VSX, CODE_FOR_sminv2df3, "__builtin_vsx_xvmindp", VSX_BUILTIN_XVMINDP },
10108 { MASK_VSX, CODE_FOR_smaxv2df3, "__builtin_vsx_xvmaxdp", VSX_BUILTIN_XVMAXDP },
10109 { MASK_VSX, CODE_FOR_vsx_tdivv2df3_fe, "__builtin_vsx_xvtdivdp_fe", VSX_BUILTIN_XVTDIVDP_FE },
10110 { MASK_VSX, CODE_FOR_vsx_tdivv2df3_fg, "__builtin_vsx_xvtdivdp_fg", VSX_BUILTIN_XVTDIVDP_FG },
10111 { MASK_VSX, CODE_FOR_vector_eqv2df, "__builtin_vsx_xvcmpeqdp", VSX_BUILTIN_XVCMPEQDP },
10112 { MASK_VSX, CODE_FOR_vector_gtv2df, "__builtin_vsx_xvcmpgtdp", VSX_BUILTIN_XVCMPGTDP },
10113 { MASK_VSX, CODE_FOR_vector_gev2df, "__builtin_vsx_xvcmpgedp", VSX_BUILTIN_XVCMPGEDP },
10115 { MASK_VSX, CODE_FOR_addv4sf3, "__builtin_vsx_xvaddsp", VSX_BUILTIN_XVADDSP },
10116 { MASK_VSX, CODE_FOR_subv4sf3, "__builtin_vsx_xvsubsp", VSX_BUILTIN_XVSUBSP },
10117 { MASK_VSX, CODE_FOR_mulv4sf3, "__builtin_vsx_xvmulsp", VSX_BUILTIN_XVMULSP },
10118 { MASK_VSX, CODE_FOR_divv4sf3, "__builtin_vsx_xvdivsp", VSX_BUILTIN_XVDIVSP },
10119 { MASK_VSX, CODE_FOR_recipv4sf3, "__builtin_vsx_xvrecipdivsp", VSX_BUILTIN_RECIP_V4SF },
10120 { MASK_VSX, CODE_FOR_sminv4sf3, "__builtin_vsx_xvminsp", VSX_BUILTIN_XVMINSP },
10121 { MASK_VSX, CODE_FOR_smaxv4sf3, "__builtin_vsx_xvmaxsp", VSX_BUILTIN_XVMAXSP },
10122 { MASK_VSX, CODE_FOR_vsx_tdivv4sf3_fe, "__builtin_vsx_xvtdivsp_fe", VSX_BUILTIN_XVTDIVSP_FE },
10123 { MASK_VSX, CODE_FOR_vsx_tdivv4sf3_fg, "__builtin_vsx_xvtdivsp_fg", VSX_BUILTIN_XVTDIVSP_FG },
10124 { MASK_VSX, CODE_FOR_vector_eqv4sf, "__builtin_vsx_xvcmpeqsp", VSX_BUILTIN_XVCMPEQSP },
10125 { MASK_VSX, CODE_FOR_vector_gtv4sf, "__builtin_vsx_xvcmpgtsp", VSX_BUILTIN_XVCMPGTSP },
10126 { MASK_VSX, CODE_FOR_vector_gev4sf, "__builtin_vsx_xvcmpgesp", VSX_BUILTIN_XVCMPGESP },
10128 { MASK_VSX, CODE_FOR_smindf3, "__builtin_vsx_xsmindp", VSX_BUILTIN_XSMINDP },
10129 { MASK_VSX, CODE_FOR_smaxdf3, "__builtin_vsx_xsmaxdp", VSX_BUILTIN_XSMAXDP },
10130 { MASK_VSX, CODE_FOR_vsx_tdivdf3_fe, "__builtin_vsx_xstdivdp_fe", VSX_BUILTIN_XSTDIVDP_FE },
10131 { MASK_VSX, CODE_FOR_vsx_tdivdf3_fg, "__builtin_vsx_xstdivdp_fg", VSX_BUILTIN_XSTDIVDP_FG },
10132 { MASK_VSX, CODE_FOR_vector_copysignv2df3, "__builtin_vsx_cpsgndp", VSX_BUILTIN_CPSGNDP },
10133 { MASK_VSX, CODE_FOR_vector_copysignv4sf3, "__builtin_vsx_cpsgnsp", VSX_BUILTIN_CPSGNSP },
10135 { MASK_VSX, CODE_FOR_vsx_concat_v2df, "__builtin_vsx_concat_2df", VSX_BUILTIN_CONCAT_2DF },
10136 { MASK_VSX, CODE_FOR_vsx_concat_v2di, "__builtin_vsx_concat_2di", VSX_BUILTIN_CONCAT_2DI },
10137 { MASK_VSX, CODE_FOR_vsx_splat_v2df, "__builtin_vsx_splat_2df", VSX_BUILTIN_SPLAT_2DF },
10138 { MASK_VSX, CODE_FOR_vsx_splat_v2di, "__builtin_vsx_splat_2di", VSX_BUILTIN_SPLAT_2DI },
10139 { MASK_VSX, CODE_FOR_vsx_xxmrghw_v4sf, "__builtin_vsx_xxmrghw", VSX_BUILTIN_XXMRGHW_4SF },
10140 { MASK_VSX, CODE_FOR_vsx_xxmrghw_v4si, "__builtin_vsx_xxmrghw_4si", VSX_BUILTIN_XXMRGHW_4SI },
10141 { MASK_VSX, CODE_FOR_vsx_xxmrglw_v4sf, "__builtin_vsx_xxmrglw", VSX_BUILTIN_XXMRGLW_4SF },
10142 { MASK_VSX, CODE_FOR_vsx_xxmrglw_v4si, "__builtin_vsx_xxmrglw_4si", VSX_BUILTIN_XXMRGLW_4SI },
10143 { MASK_VSX, CODE_FOR_vec_interleave_lowv2df, "__builtin_vsx_mergel_2df", VSX_BUILTIN_VEC_MERGEL_V2DF },
10144 { MASK_VSX, CODE_FOR_vec_interleave_lowv2di, "__builtin_vsx_mergel_2di", VSX_BUILTIN_VEC_MERGEL_V2DI },
10145 { MASK_VSX, CODE_FOR_vec_interleave_highv2df, "__builtin_vsx_mergeh_2df", VSX_BUILTIN_VEC_MERGEH_V2DF },
10146 { MASK_VSX, CODE_FOR_vec_interleave_highv2di, "__builtin_vsx_mergeh_2di", VSX_BUILTIN_VEC_MERGEH_V2DI },
10148 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_add", ALTIVEC_BUILTIN_VEC_ADD },
10149 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vaddfp", ALTIVEC_BUILTIN_VEC_VADDFP },
10150 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduwm", ALTIVEC_BUILTIN_VEC_VADDUWM },
10151 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhm", ALTIVEC_BUILTIN_VEC_VADDUHM },
10152 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubm", ALTIVEC_BUILTIN_VEC_VADDUBM },
10153 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_addc", ALTIVEC_BUILTIN_VEC_ADDC },
10154 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_adds", ALTIVEC_BUILTIN_VEC_ADDS },
10155 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddsws", ALTIVEC_BUILTIN_VEC_VADDSWS },
10156 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduws", ALTIVEC_BUILTIN_VEC_VADDUWS },
10157 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddshs", ALTIVEC_BUILTIN_VEC_VADDSHS },
10158 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhs", ALTIVEC_BUILTIN_VEC_VADDUHS },
10159 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddsbs", ALTIVEC_BUILTIN_VEC_VADDSBS },
10160 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubs", ALTIVEC_BUILTIN_VEC_VADDUBS },
10161 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_and", ALTIVEC_BUILTIN_VEC_AND },
10162 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_andc", ALTIVEC_BUILTIN_VEC_ANDC },
10163 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_avg", ALTIVEC_BUILTIN_VEC_AVG },
10164 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsw", ALTIVEC_BUILTIN_VEC_VAVGSW },
10165 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavguw", ALTIVEC_BUILTIN_VEC_VAVGUW },
10166 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsh", ALTIVEC_BUILTIN_VEC_VAVGSH },
10167 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavguh", ALTIVEC_BUILTIN_VEC_VAVGUH },
10168 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsb", ALTIVEC_BUILTIN_VEC_VAVGSB },
10169 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgub", ALTIVEC_BUILTIN_VEC_VAVGUB },
10170 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpb", ALTIVEC_BUILTIN_VEC_CMPB },
10171 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpeq", ALTIVEC_BUILTIN_VEC_CMPEQ },
10172 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpeqfp", ALTIVEC_BUILTIN_VEC_VCMPEQFP },
10173 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequw", ALTIVEC_BUILTIN_VEC_VCMPEQUW },
10174 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequh", ALTIVEC_BUILTIN_VEC_VCMPEQUH },
10175 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequb", ALTIVEC_BUILTIN_VEC_VCMPEQUB },
10176 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpge", ALTIVEC_BUILTIN_VEC_CMPGE },
10177 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpgt", ALTIVEC_BUILTIN_VEC_CMPGT },
10178 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtfp", ALTIVEC_BUILTIN_VEC_VCMPGTFP },
10179 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsw", ALTIVEC_BUILTIN_VEC_VCMPGTSW },
10180 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtuw", ALTIVEC_BUILTIN_VEC_VCMPGTUW },
10181 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsh", ALTIVEC_BUILTIN_VEC_VCMPGTSH },
10182 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtuh", ALTIVEC_BUILTIN_VEC_VCMPGTUH },
10183 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsb", ALTIVEC_BUILTIN_VEC_VCMPGTSB },
10184 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtub", ALTIVEC_BUILTIN_VEC_VCMPGTUB },
10185 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmple", ALTIVEC_BUILTIN_VEC_CMPLE },
10186 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmplt", ALTIVEC_BUILTIN_VEC_CMPLT },
10187 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_copysign", ALTIVEC_BUILTIN_VEC_COPYSIGN },
10188 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_max", ALTIVEC_BUILTIN_VEC_MAX },
10189 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vmaxfp", ALTIVEC_BUILTIN_VEC_VMAXFP },
10190 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsw", ALTIVEC_BUILTIN_VEC_VMAXSW },
10191 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxuw", ALTIVEC_BUILTIN_VEC_VMAXUW },
10192 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsh", ALTIVEC_BUILTIN_VEC_VMAXSH },
10193 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxuh", ALTIVEC_BUILTIN_VEC_VMAXUH },
10194 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsb", ALTIVEC_BUILTIN_VEC_VMAXSB },
10195 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxub", ALTIVEC_BUILTIN_VEC_VMAXUB },
10196 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mergeh", ALTIVEC_BUILTIN_VEC_MERGEH },
10197 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghw", ALTIVEC_BUILTIN_VEC_VMRGHW },
10198 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghh", ALTIVEC_BUILTIN_VEC_VMRGHH },
10199 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghb", ALTIVEC_BUILTIN_VEC_VMRGHB },
10200 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mergel", ALTIVEC_BUILTIN_VEC_MERGEL },
10201 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglw", ALTIVEC_BUILTIN_VEC_VMRGLW },
10202 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglh", ALTIVEC_BUILTIN_VEC_VMRGLH },
10203 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglb", ALTIVEC_BUILTIN_VEC_VMRGLB },
10204 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_min", ALTIVEC_BUILTIN_VEC_MIN },
10205 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vminfp", ALTIVEC_BUILTIN_VEC_VMINFP },
10206 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsw", ALTIVEC_BUILTIN_VEC_VMINSW },
10207 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminuw", ALTIVEC_BUILTIN_VEC_VMINUW },
10208 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsh", ALTIVEC_BUILTIN_VEC_VMINSH },
10209 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminuh", ALTIVEC_BUILTIN_VEC_VMINUH },
10210 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsb", ALTIVEC_BUILTIN_VEC_VMINSB },
10211 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminub", ALTIVEC_BUILTIN_VEC_VMINUB },
10212 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mule", ALTIVEC_BUILTIN_VEC_MULE },
10213 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuleub", ALTIVEC_BUILTIN_VEC_VMULEUB },
10214 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulesb", ALTIVEC_BUILTIN_VEC_VMULESB },
10215 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuleuh", ALTIVEC_BUILTIN_VEC_VMULEUH },
10216 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulesh", ALTIVEC_BUILTIN_VEC_VMULESH },
10217 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mulo", ALTIVEC_BUILTIN_VEC_MULO },
10218 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulosh", ALTIVEC_BUILTIN_VEC_VMULOSH },
10219 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulouh", ALTIVEC_BUILTIN_VEC_VMULOUH },
10220 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulosb", ALTIVEC_BUILTIN_VEC_VMULOSB },
10221 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuloub", ALTIVEC_BUILTIN_VEC_VMULOUB },
10222 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_nor", ALTIVEC_BUILTIN_VEC_NOR },
10223 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_or", ALTIVEC_BUILTIN_VEC_OR },
10224 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_pack", ALTIVEC_BUILTIN_VEC_PACK },
10225 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuwum", ALTIVEC_BUILTIN_VEC_VPKUWUM },
10226 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuhum", ALTIVEC_BUILTIN_VEC_VPKUHUM },
10227 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packpx", ALTIVEC_BUILTIN_VEC_PACKPX },
10228 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packs", ALTIVEC_BUILTIN_VEC_PACKS },
10229 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkswss", ALTIVEC_BUILTIN_VEC_VPKSWSS },
10230 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuwus", ALTIVEC_BUILTIN_VEC_VPKUWUS },
10231 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkshss", ALTIVEC_BUILTIN_VEC_VPKSHSS },
10232 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuhus", ALTIVEC_BUILTIN_VEC_VPKUHUS },
10233 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packsu", ALTIVEC_BUILTIN_VEC_PACKSU },
10234 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkswus", ALTIVEC_BUILTIN_VEC_VPKSWUS },
10235 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkshus", ALTIVEC_BUILTIN_VEC_VPKSHUS },
10236 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_recipdiv", ALTIVEC_BUILTIN_VEC_RECIP },
10237 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rl", ALTIVEC_BUILTIN_VEC_RL },
10238 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlw", ALTIVEC_BUILTIN_VEC_VRLW },
10239 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlh", ALTIVEC_BUILTIN_VEC_VRLH },
10240 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlb", ALTIVEC_BUILTIN_VEC_VRLB },
10241 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sl", ALTIVEC_BUILTIN_VEC_SL },
10242 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslw", ALTIVEC_BUILTIN_VEC_VSLW },
10243 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslh", ALTIVEC_BUILTIN_VEC_VSLH },
10244 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslb", ALTIVEC_BUILTIN_VEC_VSLB },
10245 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sll", ALTIVEC_BUILTIN_VEC_SLL },
10246 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_slo", ALTIVEC_BUILTIN_VEC_SLO },
10247 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sr", ALTIVEC_BUILTIN_VEC_SR },
10248 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrw", ALTIVEC_BUILTIN_VEC_VSRW },
10249 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrh", ALTIVEC_BUILTIN_VEC_VSRH },
10250 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrb", ALTIVEC_BUILTIN_VEC_VSRB },
10251 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sra", ALTIVEC_BUILTIN_VEC_SRA },
10252 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsraw", ALTIVEC_BUILTIN_VEC_VSRAW },
10253 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrah", ALTIVEC_BUILTIN_VEC_VSRAH },
10254 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrab", ALTIVEC_BUILTIN_VEC_VSRAB },
10255 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_srl", ALTIVEC_BUILTIN_VEC_SRL },
10256 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sro", ALTIVEC_BUILTIN_VEC_SRO },
10257 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_sub", ALTIVEC_BUILTIN_VEC_SUB },
10258 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vsubfp", ALTIVEC_BUILTIN_VEC_VSUBFP },
10259 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuwm", ALTIVEC_BUILTIN_VEC_VSUBUWM },
10260 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuhm", ALTIVEC_BUILTIN_VEC_VSUBUHM },
10261 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsububm", ALTIVEC_BUILTIN_VEC_VSUBUBM },
10262 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_subc", ALTIVEC_BUILTIN_VEC_SUBC },
10263 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_subs", ALTIVEC_BUILTIN_VEC_SUBS },
10264 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubsws", ALTIVEC_BUILTIN_VEC_VSUBSWS },
10265 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuws", ALTIVEC_BUILTIN_VEC_VSUBUWS },
10266 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubshs", ALTIVEC_BUILTIN_VEC_VSUBSHS },
10267 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuhs", ALTIVEC_BUILTIN_VEC_VSUBUHS },
10268 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubsbs", ALTIVEC_BUILTIN_VEC_VSUBSBS },
10269 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsububs", ALTIVEC_BUILTIN_VEC_VSUBUBS },
10270 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sum4s", ALTIVEC_BUILTIN_VEC_SUM4S },
10271 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4shs", ALTIVEC_BUILTIN_VEC_VSUM4SHS },
10272 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4sbs", ALTIVEC_BUILTIN_VEC_VSUM4SBS },
10273 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4ubs", ALTIVEC_BUILTIN_VEC_VSUM4UBS },
10274 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sum2s", ALTIVEC_BUILTIN_VEC_SUM2S },
10275 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sums", ALTIVEC_BUILTIN_VEC_SUMS },
10276 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_xor", ALTIVEC_BUILTIN_VEC_XOR },
10278 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_mul", VSX_BUILTIN_VEC_MUL },
10279 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_div", VSX_BUILTIN_VEC_DIV },
10281 { 0, CODE_FOR_paired_divv2sf3, "__builtin_paired_divv2sf3", PAIRED_BUILTIN_DIVV2SF3 },
10282 { 0, CODE_FOR_paired_addv2sf3, "__builtin_paired_addv2sf3", PAIRED_BUILTIN_ADDV2SF3 },
10283 { 0, CODE_FOR_paired_subv2sf3, "__builtin_paired_subv2sf3", PAIRED_BUILTIN_SUBV2SF3 },
10284 { 0, CODE_FOR_paired_mulv2sf3, "__builtin_paired_mulv2sf3", PAIRED_BUILTIN_MULV2SF3 },
10285 { 0, CODE_FOR_paired_muls0, "__builtin_paired_muls0", PAIRED_BUILTIN_MULS0 },
10286 { 0, CODE_FOR_paired_muls1, "__builtin_paired_muls1", PAIRED_BUILTIN_MULS1 },
10287 { 0, CODE_FOR_paired_merge00, "__builtin_paired_merge00", PAIRED_BUILTIN_MERGE00 },
10288 { 0, CODE_FOR_paired_merge01, "__builtin_paired_merge01", PAIRED_BUILTIN_MERGE01 },
10289 { 0, CODE_FOR_paired_merge10, "__builtin_paired_merge10", PAIRED_BUILTIN_MERGE10 },
10290 { 0, CODE_FOR_paired_merge11, "__builtin_paired_merge11", PAIRED_BUILTIN_MERGE11 },
10292 /* Place holder, leave as first spe builtin. */
10293 { 0, CODE_FOR_addv2si3, "__builtin_spe_evaddw", SPE_BUILTIN_EVADDW },
10294 { 0, CODE_FOR_andv2si3, "__builtin_spe_evand", SPE_BUILTIN_EVAND },
10295 { 0, CODE_FOR_spe_evandc, "__builtin_spe_evandc", SPE_BUILTIN_EVANDC },
10296 { 0, CODE_FOR_divv2si3, "__builtin_spe_evdivws", SPE_BUILTIN_EVDIVWS },
10297 { 0, CODE_FOR_spe_evdivwu, "__builtin_spe_evdivwu", SPE_BUILTIN_EVDIVWU },
10298 { 0, CODE_FOR_spe_eveqv, "__builtin_spe_eveqv", SPE_BUILTIN_EVEQV },
10299 { 0, CODE_FOR_spe_evfsadd, "__builtin_spe_evfsadd", SPE_BUILTIN_EVFSADD },
10300 { 0, CODE_FOR_spe_evfsdiv, "__builtin_spe_evfsdiv", SPE_BUILTIN_EVFSDIV },
10301 { 0, CODE_FOR_spe_evfsmul, "__builtin_spe_evfsmul", SPE_BUILTIN_EVFSMUL },
10302 { 0, CODE_FOR_spe_evfssub, "__builtin_spe_evfssub", SPE_BUILTIN_EVFSSUB },
10303 { 0, CODE_FOR_spe_evmergehi, "__builtin_spe_evmergehi", SPE_BUILTIN_EVMERGEHI },
10304 { 0, CODE_FOR_spe_evmergehilo, "__builtin_spe_evmergehilo", SPE_BUILTIN_EVMERGEHILO },
10305 { 0, CODE_FOR_spe_evmergelo, "__builtin_spe_evmergelo", SPE_BUILTIN_EVMERGELO },
10306 { 0, CODE_FOR_spe_evmergelohi, "__builtin_spe_evmergelohi", SPE_BUILTIN_EVMERGELOHI },
10307 { 0, CODE_FOR_spe_evmhegsmfaa, "__builtin_spe_evmhegsmfaa", SPE_BUILTIN_EVMHEGSMFAA },
10308 { 0, CODE_FOR_spe_evmhegsmfan, "__builtin_spe_evmhegsmfan", SPE_BUILTIN_EVMHEGSMFAN },
10309 { 0, CODE_FOR_spe_evmhegsmiaa, "__builtin_spe_evmhegsmiaa", SPE_BUILTIN_EVMHEGSMIAA },
10310 { 0, CODE_FOR_spe_evmhegsmian, "__builtin_spe_evmhegsmian", SPE_BUILTIN_EVMHEGSMIAN },
10311 { 0, CODE_FOR_spe_evmhegumiaa, "__builtin_spe_evmhegumiaa", SPE_BUILTIN_EVMHEGUMIAA },
10312 { 0, CODE_FOR_spe_evmhegumian, "__builtin_spe_evmhegumian", SPE_BUILTIN_EVMHEGUMIAN },
10313 { 0, CODE_FOR_spe_evmhesmf, "__builtin_spe_evmhesmf", SPE_BUILTIN_EVMHESMF },
10314 { 0, CODE_FOR_spe_evmhesmfa, "__builtin_spe_evmhesmfa", SPE_BUILTIN_EVMHESMFA },
10315 { 0, CODE_FOR_spe_evmhesmfaaw, "__builtin_spe_evmhesmfaaw", SPE_BUILTIN_EVMHESMFAAW },
10316 { 0, CODE_FOR_spe_evmhesmfanw, "__builtin_spe_evmhesmfanw", SPE_BUILTIN_EVMHESMFANW },
10317 { 0, CODE_FOR_spe_evmhesmi, "__builtin_spe_evmhesmi", SPE_BUILTIN_EVMHESMI },
10318 { 0, CODE_FOR_spe_evmhesmia, "__builtin_spe_evmhesmia", SPE_BUILTIN_EVMHESMIA },
10319 { 0, CODE_FOR_spe_evmhesmiaaw, "__builtin_spe_evmhesmiaaw", SPE_BUILTIN_EVMHESMIAAW },
10320 { 0, CODE_FOR_spe_evmhesmianw, "__builtin_spe_evmhesmianw", SPE_BUILTIN_EVMHESMIANW },
10321 { 0, CODE_FOR_spe_evmhessf, "__builtin_spe_evmhessf", SPE_BUILTIN_EVMHESSF },
10322 { 0, CODE_FOR_spe_evmhessfa, "__builtin_spe_evmhessfa", SPE_BUILTIN_EVMHESSFA },
10323 { 0, CODE_FOR_spe_evmhessfaaw, "__builtin_spe_evmhessfaaw", SPE_BUILTIN_EVMHESSFAAW },
10324 { 0, CODE_FOR_spe_evmhessfanw, "__builtin_spe_evmhessfanw", SPE_BUILTIN_EVMHESSFANW },
10325 { 0, CODE_FOR_spe_evmhessiaaw, "__builtin_spe_evmhessiaaw", SPE_BUILTIN_EVMHESSIAAW },
10326 { 0, CODE_FOR_spe_evmhessianw, "__builtin_spe_evmhessianw", SPE_BUILTIN_EVMHESSIANW },
10327 { 0, CODE_FOR_spe_evmheumi, "__builtin_spe_evmheumi", SPE_BUILTIN_EVMHEUMI },
10328 { 0, CODE_FOR_spe_evmheumia, "__builtin_spe_evmheumia", SPE_BUILTIN_EVMHEUMIA },
10329 { 0, CODE_FOR_spe_evmheumiaaw, "__builtin_spe_evmheumiaaw", SPE_BUILTIN_EVMHEUMIAAW },
10330 { 0, CODE_FOR_spe_evmheumianw, "__builtin_spe_evmheumianw", SPE_BUILTIN_EVMHEUMIANW },
10331 { 0, CODE_FOR_spe_evmheusiaaw, "__builtin_spe_evmheusiaaw", SPE_BUILTIN_EVMHEUSIAAW },
10332 { 0, CODE_FOR_spe_evmheusianw, "__builtin_spe_evmheusianw", SPE_BUILTIN_EVMHEUSIANW },
10333 { 0, CODE_FOR_spe_evmhogsmfaa, "__builtin_spe_evmhogsmfaa", SPE_BUILTIN_EVMHOGSMFAA },
10334 { 0, CODE_FOR_spe_evmhogsmfan, "__builtin_spe_evmhogsmfan", SPE_BUILTIN_EVMHOGSMFAN },
10335 { 0, CODE_FOR_spe_evmhogsmiaa, "__builtin_spe_evmhogsmiaa", SPE_BUILTIN_EVMHOGSMIAA },
10336 { 0, CODE_FOR_spe_evmhogsmian, "__builtin_spe_evmhogsmian", SPE_BUILTIN_EVMHOGSMIAN },
10337 { 0, CODE_FOR_spe_evmhogumiaa, "__builtin_spe_evmhogumiaa", SPE_BUILTIN_EVMHOGUMIAA },
10338 { 0, CODE_FOR_spe_evmhogumian, "__builtin_spe_evmhogumian", SPE_BUILTIN_EVMHOGUMIAN },
10339 { 0, CODE_FOR_spe_evmhosmf, "__builtin_spe_evmhosmf", SPE_BUILTIN_EVMHOSMF },
10340 { 0, CODE_FOR_spe_evmhosmfa, "__builtin_spe_evmhosmfa", SPE_BUILTIN_EVMHOSMFA },
10341 { 0, CODE_FOR_spe_evmhosmfaaw, "__builtin_spe_evmhosmfaaw", SPE_BUILTIN_EVMHOSMFAAW },
10342 { 0, CODE_FOR_spe_evmhosmfanw, "__builtin_spe_evmhosmfanw", SPE_BUILTIN_EVMHOSMFANW },
10343 { 0, CODE_FOR_spe_evmhosmi, "__builtin_spe_evmhosmi", SPE_BUILTIN_EVMHOSMI },
10344 { 0, CODE_FOR_spe_evmhosmia, "__builtin_spe_evmhosmia", SPE_BUILTIN_EVMHOSMIA },
10345 { 0, CODE_FOR_spe_evmhosmiaaw, "__builtin_spe_evmhosmiaaw", SPE_BUILTIN_EVMHOSMIAAW },
10346 { 0, CODE_FOR_spe_evmhosmianw, "__builtin_spe_evmhosmianw", SPE_BUILTIN_EVMHOSMIANW },
10347 { 0, CODE_FOR_spe_evmhossf, "__builtin_spe_evmhossf", SPE_BUILTIN_EVMHOSSF },
10348 { 0, CODE_FOR_spe_evmhossfa, "__builtin_spe_evmhossfa", SPE_BUILTIN_EVMHOSSFA },
10349 { 0, CODE_FOR_spe_evmhossfaaw, "__builtin_spe_evmhossfaaw", SPE_BUILTIN_EVMHOSSFAAW },
10350 { 0, CODE_FOR_spe_evmhossfanw, "__builtin_spe_evmhossfanw", SPE_BUILTIN_EVMHOSSFANW },
10351 { 0, CODE_FOR_spe_evmhossiaaw, "__builtin_spe_evmhossiaaw", SPE_BUILTIN_EVMHOSSIAAW },
10352 { 0, CODE_FOR_spe_evmhossianw, "__builtin_spe_evmhossianw", SPE_BUILTIN_EVMHOSSIANW },
10353 { 0, CODE_FOR_spe_evmhoumi, "__builtin_spe_evmhoumi", SPE_BUILTIN_EVMHOUMI },
10354 { 0, CODE_FOR_spe_evmhoumia, "__builtin_spe_evmhoumia", SPE_BUILTIN_EVMHOUMIA },
10355 { 0, CODE_FOR_spe_evmhoumiaaw, "__builtin_spe_evmhoumiaaw", SPE_BUILTIN_EVMHOUMIAAW },
10356 { 0, CODE_FOR_spe_evmhoumianw, "__builtin_spe_evmhoumianw", SPE_BUILTIN_EVMHOUMIANW },
10357 { 0, CODE_FOR_spe_evmhousiaaw, "__builtin_spe_evmhousiaaw", SPE_BUILTIN_EVMHOUSIAAW },
10358 { 0, CODE_FOR_spe_evmhousianw, "__builtin_spe_evmhousianw", SPE_BUILTIN_EVMHOUSIANW },
10359 { 0, CODE_FOR_spe_evmwhsmf, "__builtin_spe_evmwhsmf", SPE_BUILTIN_EVMWHSMF },
10360 { 0, CODE_FOR_spe_evmwhsmfa, "__builtin_spe_evmwhsmfa", SPE_BUILTIN_EVMWHSMFA },
10361 { 0, CODE_FOR_spe_evmwhsmi, "__builtin_spe_evmwhsmi", SPE_BUILTIN_EVMWHSMI },
10362 { 0, CODE_FOR_spe_evmwhsmia, "__builtin_spe_evmwhsmia", SPE_BUILTIN_EVMWHSMIA },
10363 { 0, CODE_FOR_spe_evmwhssf, "__builtin_spe_evmwhssf", SPE_BUILTIN_EVMWHSSF },
10364 { 0, CODE_FOR_spe_evmwhssfa, "__builtin_spe_evmwhssfa", SPE_BUILTIN_EVMWHSSFA },
10365 { 0, CODE_FOR_spe_evmwhumi, "__builtin_spe_evmwhumi", SPE_BUILTIN_EVMWHUMI },
10366 { 0, CODE_FOR_spe_evmwhumia, "__builtin_spe_evmwhumia", SPE_BUILTIN_EVMWHUMIA },
10367 { 0, CODE_FOR_spe_evmwlsmiaaw, "__builtin_spe_evmwlsmiaaw", SPE_BUILTIN_EVMWLSMIAAW },
10368 { 0, CODE_FOR_spe_evmwlsmianw, "__builtin_spe_evmwlsmianw", SPE_BUILTIN_EVMWLSMIANW },
10369 { 0, CODE_FOR_spe_evmwlssiaaw, "__builtin_spe_evmwlssiaaw", SPE_BUILTIN_EVMWLSSIAAW },
10370 { 0, CODE_FOR_spe_evmwlssianw, "__builtin_spe_evmwlssianw", SPE_BUILTIN_EVMWLSSIANW },
10371 { 0, CODE_FOR_spe_evmwlumi, "__builtin_spe_evmwlumi", SPE_BUILTIN_EVMWLUMI },
10372 { 0, CODE_FOR_spe_evmwlumia, "__builtin_spe_evmwlumia", SPE_BUILTIN_EVMWLUMIA },
10373 { 0, CODE_FOR_spe_evmwlumiaaw, "__builtin_spe_evmwlumiaaw", SPE_BUILTIN_EVMWLUMIAAW },
10374 { 0, CODE_FOR_spe_evmwlumianw, "__builtin_spe_evmwlumianw", SPE_BUILTIN_EVMWLUMIANW },
10375 { 0, CODE_FOR_spe_evmwlusiaaw, "__builtin_spe_evmwlusiaaw", SPE_BUILTIN_EVMWLUSIAAW },
10376 { 0, CODE_FOR_spe_evmwlusianw, "__builtin_spe_evmwlusianw", SPE_BUILTIN_EVMWLUSIANW },
10377 { 0, CODE_FOR_spe_evmwsmf, "__builtin_spe_evmwsmf", SPE_BUILTIN_EVMWSMF },
10378 { 0, CODE_FOR_spe_evmwsmfa, "__builtin_spe_evmwsmfa", SPE_BUILTIN_EVMWSMFA },
10379 { 0, CODE_FOR_spe_evmwsmfaa, "__builtin_spe_evmwsmfaa", SPE_BUILTIN_EVMWSMFAA },
10380 { 0, CODE_FOR_spe_evmwsmfan, "__builtin_spe_evmwsmfan", SPE_BUILTIN_EVMWSMFAN },
10381 { 0, CODE_FOR_spe_evmwsmi, "__builtin_spe_evmwsmi", SPE_BUILTIN_EVMWSMI },
10382 { 0, CODE_FOR_spe_evmwsmia, "__builtin_spe_evmwsmia", SPE_BUILTIN_EVMWSMIA },
10383 { 0, CODE_FOR_spe_evmwsmiaa, "__builtin_spe_evmwsmiaa", SPE_BUILTIN_EVMWSMIAA },
10384 { 0, CODE_FOR_spe_evmwsmian, "__builtin_spe_evmwsmian", SPE_BUILTIN_EVMWSMIAN },
10385 { 0, CODE_FOR_spe_evmwssf, "__builtin_spe_evmwssf", SPE_BUILTIN_EVMWSSF },
10386 { 0, CODE_FOR_spe_evmwssfa, "__builtin_spe_evmwssfa", SPE_BUILTIN_EVMWSSFA },
10387 { 0, CODE_FOR_spe_evmwssfaa, "__builtin_spe_evmwssfaa", SPE_BUILTIN_EVMWSSFAA },
10388 { 0, CODE_FOR_spe_evmwssfan, "__builtin_spe_evmwssfan", SPE_BUILTIN_EVMWSSFAN },
10389 { 0, CODE_FOR_spe_evmwumi, "__builtin_spe_evmwumi", SPE_BUILTIN_EVMWUMI },
10390 { 0, CODE_FOR_spe_evmwumia, "__builtin_spe_evmwumia", SPE_BUILTIN_EVMWUMIA },
10391 { 0, CODE_FOR_spe_evmwumiaa, "__builtin_spe_evmwumiaa", SPE_BUILTIN_EVMWUMIAA },
10392 { 0, CODE_FOR_spe_evmwumian, "__builtin_spe_evmwumian", SPE_BUILTIN_EVMWUMIAN },
10393 { 0, CODE_FOR_spe_evnand, "__builtin_spe_evnand", SPE_BUILTIN_EVNAND },
10394 { 0, CODE_FOR_spe_evnor, "__builtin_spe_evnor", SPE_BUILTIN_EVNOR },
10395 { 0, CODE_FOR_spe_evor, "__builtin_spe_evor", SPE_BUILTIN_EVOR },
10396 { 0, CODE_FOR_spe_evorc, "__builtin_spe_evorc", SPE_BUILTIN_EVORC },
10397 { 0, CODE_FOR_spe_evrlw, "__builtin_spe_evrlw", SPE_BUILTIN_EVRLW },
10398 { 0, CODE_FOR_spe_evslw, "__builtin_spe_evslw", SPE_BUILTIN_EVSLW },
10399 { 0, CODE_FOR_spe_evsrws, "__builtin_spe_evsrws", SPE_BUILTIN_EVSRWS },
10400 { 0, CODE_FOR_spe_evsrwu, "__builtin_spe_evsrwu", SPE_BUILTIN_EVSRWU },
10401 { 0, CODE_FOR_subv2si3, "__builtin_spe_evsubfw", SPE_BUILTIN_EVSUBFW },
10403 /* SPE binary operations expecting a 5-bit unsigned literal. */
10404 { 0, CODE_FOR_spe_evaddiw, "__builtin_spe_evaddiw", SPE_BUILTIN_EVADDIW },
10406 { 0, CODE_FOR_spe_evrlwi, "__builtin_spe_evrlwi", SPE_BUILTIN_EVRLWI },
10407 { 0, CODE_FOR_spe_evslwi, "__builtin_spe_evslwi", SPE_BUILTIN_EVSLWI },
10408 { 0, CODE_FOR_spe_evsrwis, "__builtin_spe_evsrwis", SPE_BUILTIN_EVSRWIS },
10409 { 0, CODE_FOR_spe_evsrwiu, "__builtin_spe_evsrwiu", SPE_BUILTIN_EVSRWIU },
10410 { 0, CODE_FOR_spe_evsubifw, "__builtin_spe_evsubifw", SPE_BUILTIN_EVSUBIFW },
10411 { 0, CODE_FOR_spe_evmwhssfaa, "__builtin_spe_evmwhssfaa", SPE_BUILTIN_EVMWHSSFAA },
10412 { 0, CODE_FOR_spe_evmwhssmaa, "__builtin_spe_evmwhssmaa", SPE_BUILTIN_EVMWHSSMAA },
10413 { 0, CODE_FOR_spe_evmwhsmfaa, "__builtin_spe_evmwhsmfaa", SPE_BUILTIN_EVMWHSMFAA },
10414 { 0, CODE_FOR_spe_evmwhsmiaa, "__builtin_spe_evmwhsmiaa", SPE_BUILTIN_EVMWHSMIAA },
10415 { 0, CODE_FOR_spe_evmwhusiaa, "__builtin_spe_evmwhusiaa", SPE_BUILTIN_EVMWHUSIAA },
10416 { 0, CODE_FOR_spe_evmwhumiaa, "__builtin_spe_evmwhumiaa", SPE_BUILTIN_EVMWHUMIAA },
10417 { 0, CODE_FOR_spe_evmwhssfan, "__builtin_spe_evmwhssfan", SPE_BUILTIN_EVMWHSSFAN },
10418 { 0, CODE_FOR_spe_evmwhssian, "__builtin_spe_evmwhssian", SPE_BUILTIN_EVMWHSSIAN },
10419 { 0, CODE_FOR_spe_evmwhsmfan, "__builtin_spe_evmwhsmfan", SPE_BUILTIN_EVMWHSMFAN },
10420 { 0, CODE_FOR_spe_evmwhsmian, "__builtin_spe_evmwhsmian", SPE_BUILTIN_EVMWHSMIAN },
10421 { 0, CODE_FOR_spe_evmwhusian, "__builtin_spe_evmwhusian", SPE_BUILTIN_EVMWHUSIAN },
10422 { 0, CODE_FOR_spe_evmwhumian, "__builtin_spe_evmwhumian", SPE_BUILTIN_EVMWHUMIAN },
10423 { 0, CODE_FOR_spe_evmwhgssfaa, "__builtin_spe_evmwhgssfaa", SPE_BUILTIN_EVMWHGSSFAA },
10424 { 0, CODE_FOR_spe_evmwhgsmfaa, "__builtin_spe_evmwhgsmfaa", SPE_BUILTIN_EVMWHGSMFAA },
10425 { 0, CODE_FOR_spe_evmwhgsmiaa, "__builtin_spe_evmwhgsmiaa", SPE_BUILTIN_EVMWHGSMIAA },
10426 { 0, CODE_FOR_spe_evmwhgumiaa, "__builtin_spe_evmwhgumiaa", SPE_BUILTIN_EVMWHGUMIAA },
10427 { 0, CODE_FOR_spe_evmwhgssfan, "__builtin_spe_evmwhgssfan", SPE_BUILTIN_EVMWHGSSFAN },
10428 { 0, CODE_FOR_spe_evmwhgsmfan, "__builtin_spe_evmwhgsmfan", SPE_BUILTIN_EVMWHGSMFAN },
10429 { 0, CODE_FOR_spe_evmwhgsmian, "__builtin_spe_evmwhgsmian", SPE_BUILTIN_EVMWHGSMIAN },
10430 { 0, CODE_FOR_spe_evmwhgumian, "__builtin_spe_evmwhgumian", SPE_BUILTIN_EVMWHGUMIAN },
10431 { 0, CODE_FOR_spe_brinc, "__builtin_spe_brinc", SPE_BUILTIN_BRINC },
10433 /* Place-holder. Leave as last binary SPE builtin. */
10434 { 0, CODE_FOR_xorv2si3, "__builtin_spe_evxor", SPE_BUILTIN_EVXOR }
10437 /* AltiVec predicates. */
10439 struct builtin_description_predicates
10441 const unsigned int mask;
10442 const enum insn_code icode;
10443 const char *const name;
10444 const enum rs6000_builtins code;
10447 static const struct builtin_description_predicates bdesc_altivec_preds[] =
10449 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpbfp_p, "__builtin_altivec_vcmpbfp_p",
10450 ALTIVEC_BUILTIN_VCMPBFP_P },
10451 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_eq_v4sf_p,
10452 "__builtin_altivec_vcmpeqfp_p", ALTIVEC_BUILTIN_VCMPEQFP_P },
10453 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_ge_v4sf_p,
10454 "__builtin_altivec_vcmpgefp_p", ALTIVEC_BUILTIN_VCMPGEFP_P },
10455 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_gt_v4sf_p,
10456 "__builtin_altivec_vcmpgtfp_p", ALTIVEC_BUILTIN_VCMPGTFP_P },
10457 { MASK_ALTIVEC, CODE_FOR_vector_eq_v4si_p, "__builtin_altivec_vcmpequw_p",
10458 ALTIVEC_BUILTIN_VCMPEQUW_P },
10459 { MASK_ALTIVEC, CODE_FOR_vector_gt_v4si_p, "__builtin_altivec_vcmpgtsw_p",
10460 ALTIVEC_BUILTIN_VCMPGTSW_P },
10461 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v4si_p, "__builtin_altivec_vcmpgtuw_p",
10462 ALTIVEC_BUILTIN_VCMPGTUW_P },
10463 { MASK_ALTIVEC, CODE_FOR_vector_eq_v8hi_p, "__builtin_altivec_vcmpequh_p",
10464 ALTIVEC_BUILTIN_VCMPEQUH_P },
10465 { MASK_ALTIVEC, CODE_FOR_vector_gt_v8hi_p, "__builtin_altivec_vcmpgtsh_p",
10466 ALTIVEC_BUILTIN_VCMPGTSH_P },
10467 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v8hi_p, "__builtin_altivec_vcmpgtuh_p",
10468 ALTIVEC_BUILTIN_VCMPGTUH_P },
10469 { MASK_ALTIVEC, CODE_FOR_vector_eq_v16qi_p, "__builtin_altivec_vcmpequb_p",
10470 ALTIVEC_BUILTIN_VCMPEQUB_P },
10471 { MASK_ALTIVEC, CODE_FOR_vector_gt_v16qi_p, "__builtin_altivec_vcmpgtsb_p",
10472 ALTIVEC_BUILTIN_VCMPGTSB_P },
10473 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v16qi_p, "__builtin_altivec_vcmpgtub_p",
10474 ALTIVEC_BUILTIN_VCMPGTUB_P },
10476 { MASK_VSX, CODE_FOR_vector_eq_v4sf_p, "__builtin_vsx_xvcmpeqsp_p",
10477 VSX_BUILTIN_XVCMPEQSP_P },
10478 { MASK_VSX, CODE_FOR_vector_ge_v4sf_p, "__builtin_vsx_xvcmpgesp_p",
10479 VSX_BUILTIN_XVCMPGESP_P },
10480 { MASK_VSX, CODE_FOR_vector_gt_v4sf_p, "__builtin_vsx_xvcmpgtsp_p",
10481 VSX_BUILTIN_XVCMPGTSP_P },
10482 { MASK_VSX, CODE_FOR_vector_eq_v2df_p, "__builtin_vsx_xvcmpeqdp_p",
10483 VSX_BUILTIN_XVCMPEQDP_P },
10484 { MASK_VSX, CODE_FOR_vector_ge_v2df_p, "__builtin_vsx_xvcmpgedp_p",
10485 VSX_BUILTIN_XVCMPGEDP_P },
10486 { MASK_VSX, CODE_FOR_vector_gt_v2df_p, "__builtin_vsx_xvcmpgtdp_p",
10487 VSX_BUILTIN_XVCMPGTDP_P },
10489 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpeq_p",
10490 ALTIVEC_BUILTIN_VCMPEQ_P },
10491 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpgt_p",
10492 ALTIVEC_BUILTIN_VCMPGT_P },
10493 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpge_p",
10494 ALTIVEC_BUILTIN_VCMPGE_P }
10497 /* SPE predicates. */
10498 static struct builtin_description bdesc_spe_predicates[] =
10500 /* Place-holder. Leave as first. */
10501 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evcmpeq", SPE_BUILTIN_EVCMPEQ },
10502 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evcmpgts", SPE_BUILTIN_EVCMPGTS },
10503 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evcmpgtu", SPE_BUILTIN_EVCMPGTU },
10504 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evcmplts", SPE_BUILTIN_EVCMPLTS },
10505 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evcmpltu", SPE_BUILTIN_EVCMPLTU },
10506 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evfscmpeq", SPE_BUILTIN_EVFSCMPEQ },
10507 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evfscmpgt", SPE_BUILTIN_EVFSCMPGT },
10508 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evfscmplt", SPE_BUILTIN_EVFSCMPLT },
10509 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evfststeq", SPE_BUILTIN_EVFSTSTEQ },
10510 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evfststgt", SPE_BUILTIN_EVFSTSTGT },
10511 /* Place-holder. Leave as last. */
10512 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evfststlt", SPE_BUILTIN_EVFSTSTLT },
10515 /* SPE evsel predicates. */
10516 static struct builtin_description bdesc_spe_evsel[] =
10518 /* Place-holder. Leave as first. */
10519 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evsel_gts", SPE_BUILTIN_EVSEL_CMPGTS },
10520 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evsel_gtu", SPE_BUILTIN_EVSEL_CMPGTU },
10521 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evsel_lts", SPE_BUILTIN_EVSEL_CMPLTS },
10522 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evsel_ltu", SPE_BUILTIN_EVSEL_CMPLTU },
10523 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evsel_eq", SPE_BUILTIN_EVSEL_CMPEQ },
10524 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evsel_fsgt", SPE_BUILTIN_EVSEL_FSCMPGT },
10525 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evsel_fslt", SPE_BUILTIN_EVSEL_FSCMPLT },
10526 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evsel_fseq", SPE_BUILTIN_EVSEL_FSCMPEQ },
10527 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evsel_fststgt", SPE_BUILTIN_EVSEL_FSTSTGT },
10528 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evsel_fststlt", SPE_BUILTIN_EVSEL_FSTSTLT },
10529 /* Place-holder. Leave as last. */
10530 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evsel_fststeq", SPE_BUILTIN_EVSEL_FSTSTEQ },
10533 /* PAIRED predicates. */
10534 static const struct builtin_description bdesc_paired_preds[] =
10536 /* Place-holder. Leave as first. */
10537 { 0, CODE_FOR_paired_cmpu0, "__builtin_paired_cmpu0", PAIRED_BUILTIN_CMPU0 },
10538 /* Place-holder. Leave as last. */
10539 { 0, CODE_FOR_paired_cmpu1, "__builtin_paired_cmpu1", PAIRED_BUILTIN_CMPU1 },
10542 /* ABS* operations. */
10544 static const struct builtin_description bdesc_abs[] =
10546 { MASK_ALTIVEC, CODE_FOR_absv4si2, "__builtin_altivec_abs_v4si", ALTIVEC_BUILTIN_ABS_V4SI },
10547 { MASK_ALTIVEC, CODE_FOR_absv8hi2, "__builtin_altivec_abs_v8hi", ALTIVEC_BUILTIN_ABS_V8HI },
10548 { MASK_ALTIVEC, CODE_FOR_absv4sf2, "__builtin_altivec_abs_v4sf", ALTIVEC_BUILTIN_ABS_V4SF },
10549 { MASK_ALTIVEC, CODE_FOR_absv16qi2, "__builtin_altivec_abs_v16qi", ALTIVEC_BUILTIN_ABS_V16QI },
10550 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v4si, "__builtin_altivec_abss_v4si", ALTIVEC_BUILTIN_ABSS_V4SI },
10551 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v8hi, "__builtin_altivec_abss_v8hi", ALTIVEC_BUILTIN_ABSS_V8HI },
10552 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v16qi, "__builtin_altivec_abss_v16qi", ALTIVEC_BUILTIN_ABSS_V16QI },
10553 { MASK_VSX, CODE_FOR_absv2df2, "__builtin_vsx_xvabsdp", VSX_BUILTIN_XVABSDP },
10554 { MASK_VSX, CODE_FOR_vsx_nabsv2df2, "__builtin_vsx_xvnabsdp", VSX_BUILTIN_XVNABSDP },
10555 { MASK_VSX, CODE_FOR_absv4sf2, "__builtin_vsx_xvabssp", VSX_BUILTIN_XVABSSP },
10556 { MASK_VSX, CODE_FOR_vsx_nabsv4sf2, "__builtin_vsx_xvnabssp", VSX_BUILTIN_XVNABSSP },
10559 /* Simple unary operations: VECb = foo (unsigned literal) or VECb =
10560 foo (VECa). */
10562 static struct builtin_description bdesc_1arg[] =
10564 { MASK_ALTIVEC, CODE_FOR_altivec_vexptefp, "__builtin_altivec_vexptefp", ALTIVEC_BUILTIN_VEXPTEFP },
10565 { MASK_ALTIVEC, CODE_FOR_altivec_vlogefp, "__builtin_altivec_vlogefp", ALTIVEC_BUILTIN_VLOGEFP },
10566 { MASK_ALTIVEC, CODE_FOR_rev4sf2, "__builtin_altivec_vrefp", ALTIVEC_BUILTIN_VREFP },
10567 { MASK_ALTIVEC, CODE_FOR_vector_floorv4sf2, "__builtin_altivec_vrfim", ALTIVEC_BUILTIN_VRFIM },
10568 { MASK_ALTIVEC, CODE_FOR_altivec_vrfin, "__builtin_altivec_vrfin", ALTIVEC_BUILTIN_VRFIN },
10569 { MASK_ALTIVEC, CODE_FOR_vector_ceilv4sf2, "__builtin_altivec_vrfip", ALTIVEC_BUILTIN_VRFIP },
10570 { MASK_ALTIVEC, CODE_FOR_vector_btruncv4sf2, "__builtin_altivec_vrfiz", ALTIVEC_BUILTIN_VRFIZ },
10571 { MASK_ALTIVEC, CODE_FOR_rsqrtv4sf2, "__builtin_altivec_vrsqrtfp", ALTIVEC_BUILTIN_VRSQRTFP },
10572 { MASK_ALTIVEC, CODE_FOR_rsqrtev4sf2, "__builtin_altivec_vrsqrtefp", ALTIVEC_BUILTIN_VRSQRTEFP },
10573 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisb, "__builtin_altivec_vspltisb", ALTIVEC_BUILTIN_VSPLTISB },
10574 { MASK_ALTIVEC, CODE_FOR_altivec_vspltish, "__builtin_altivec_vspltish", ALTIVEC_BUILTIN_VSPLTISH },
10575 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisw, "__builtin_altivec_vspltisw", ALTIVEC_BUILTIN_VSPLTISW },
10576 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsb, "__builtin_altivec_vupkhsb", ALTIVEC_BUILTIN_VUPKHSB },
10577 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhpx, "__builtin_altivec_vupkhpx", ALTIVEC_BUILTIN_VUPKHPX },
10578 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsh, "__builtin_altivec_vupkhsh", ALTIVEC_BUILTIN_VUPKHSH },
10579 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsb, "__builtin_altivec_vupklsb", ALTIVEC_BUILTIN_VUPKLSB },
10580 { MASK_ALTIVEC, CODE_FOR_altivec_vupklpx, "__builtin_altivec_vupklpx", ALTIVEC_BUILTIN_VUPKLPX },
10581 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsh, "__builtin_altivec_vupklsh", ALTIVEC_BUILTIN_VUPKLSH },
10583 { MASK_VSX, CODE_FOR_negv2df2, "__builtin_vsx_xvnegdp", VSX_BUILTIN_XVNEGDP },
10584 { MASK_VSX, CODE_FOR_sqrtv2df2, "__builtin_vsx_xvsqrtdp", VSX_BUILTIN_XVSQRTDP },
10585 { MASK_VSX, CODE_FOR_rsqrtv2df2, "__builtin_vsx_xvrsqrtdp", VSX_BUILTIN_VEC_RSQRT_V2DF },
10586 { MASK_VSX, CODE_FOR_rsqrtev2df2, "__builtin_vsx_xvrsqrtedp", VSX_BUILTIN_XVRSQRTEDP },
10587 { MASK_VSX, CODE_FOR_vsx_tsqrtv2df2_fe, "__builtin_vsx_xvtsqrtdp_fe", VSX_BUILTIN_XVTSQRTDP_FE },
10588 { MASK_VSX, CODE_FOR_vsx_tsqrtv2df2_fg, "__builtin_vsx_xvtsqrtdp_fg", VSX_BUILTIN_XVTSQRTDP_FG },
10589 { MASK_VSX, CODE_FOR_vsx_frev2df2, "__builtin_vsx_xvredp", VSX_BUILTIN_XVREDP },
10591 { MASK_VSX, CODE_FOR_negv4sf2, "__builtin_vsx_xvnegsp", VSX_BUILTIN_XVNEGSP },
10592 { MASK_VSX, CODE_FOR_sqrtv4sf2, "__builtin_vsx_xvsqrtsp", VSX_BUILTIN_XVSQRTSP },
10593 { MASK_VSX, CODE_FOR_rsqrtv4sf2, "__builtin_vsx_xvrsqrtsp", VSX_BUILTIN_VEC_RSQRT_V4SF },
10594 { MASK_VSX, CODE_FOR_rsqrtev4sf2, "__builtin_vsx_xvrsqrtesp", VSX_BUILTIN_XVRSQRTESP },
10595 { MASK_VSX, CODE_FOR_vsx_tsqrtv4sf2_fe, "__builtin_vsx_xvtsqrtsp_fe", VSX_BUILTIN_XVTSQRTSP_FE },
10596 { MASK_VSX, CODE_FOR_vsx_tsqrtv4sf2_fg, "__builtin_vsx_xvtsqrtsp_fg", VSX_BUILTIN_XVTSQRTSP_FG },
10597 { MASK_VSX, CODE_FOR_vsx_frev4sf2, "__builtin_vsx_xvresp", VSX_BUILTIN_XVRESP },
10599 { MASK_VSX, CODE_FOR_vsx_xscvdpsp, "__builtin_vsx_xscvdpsp", VSX_BUILTIN_XSCVDPSP },
10600 { MASK_VSX, CODE_FOR_vsx_xscvdpsp, "__builtin_vsx_xscvspdp", VSX_BUILTIN_XSCVSPDP },
10601 { MASK_VSX, CODE_FOR_vsx_xvcvdpsp, "__builtin_vsx_xvcvdpsp", VSX_BUILTIN_XVCVDPSP },
10602 { MASK_VSX, CODE_FOR_vsx_xvcvspdp, "__builtin_vsx_xvcvspdp", VSX_BUILTIN_XVCVSPDP },
10603 { MASK_VSX, CODE_FOR_vsx_tsqrtdf2_fe, "__builtin_vsx_xstsqrtdp_fe", VSX_BUILTIN_XSTSQRTDP_FE },
10604 { MASK_VSX, CODE_FOR_vsx_tsqrtdf2_fg, "__builtin_vsx_xstsqrtdp_fg", VSX_BUILTIN_XSTSQRTDP_FG },
10606 { MASK_VSX, CODE_FOR_vsx_fix_truncv2dfv2di2, "__builtin_vsx_xvcvdpsxds", VSX_BUILTIN_XVCVDPSXDS },
10607 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv2dfv2di2, "__builtin_vsx_xvcvdpuxds", VSX_BUILTIN_XVCVDPUXDS },
10608 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv2dfv2di2, "__builtin_vsx_xvcvdpuxds_uns", VSX_BUILTIN_XVCVDPUXDS_UNS },
10609 { MASK_VSX, CODE_FOR_vsx_floatv2div2df2, "__builtin_vsx_xvcvsxddp", VSX_BUILTIN_XVCVSXDDP },
10610 { MASK_VSX, CODE_FOR_vsx_floatunsv2div2df2, "__builtin_vsx_xvcvuxddp", VSX_BUILTIN_XVCVUXDDP },
10611 { MASK_VSX, CODE_FOR_vsx_floatunsv2div2df2, "__builtin_vsx_xvcvuxddp_uns", VSX_BUILTIN_XVCVUXDDP_UNS },
10613 { MASK_VSX, CODE_FOR_vsx_fix_truncv4sfv4si2, "__builtin_vsx_xvcvspsxws", VSX_BUILTIN_XVCVSPSXWS },
10614 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv4sfv4si2, "__builtin_vsx_xvcvspuxws", VSX_BUILTIN_XVCVSPUXWS },
10615 { MASK_VSX, CODE_FOR_vsx_floatv4siv4sf2, "__builtin_vsx_xvcvsxwsp", VSX_BUILTIN_XVCVSXWSP },
10616 { MASK_VSX, CODE_FOR_vsx_floatunsv4siv4sf2, "__builtin_vsx_xvcvuxwsp", VSX_BUILTIN_XVCVUXWSP },
10618 { MASK_VSX, CODE_FOR_vsx_xvcvdpsxws, "__builtin_vsx_xvcvdpsxws", VSX_BUILTIN_XVCVDPSXWS },
10619 { MASK_VSX, CODE_FOR_vsx_xvcvdpuxws, "__builtin_vsx_xvcvdpuxws", VSX_BUILTIN_XVCVDPUXWS },
10620 { MASK_VSX, CODE_FOR_vsx_xvcvsxwdp, "__builtin_vsx_xvcvsxwdp", VSX_BUILTIN_XVCVSXWDP },
10621 { MASK_VSX, CODE_FOR_vsx_xvcvuxwdp, "__builtin_vsx_xvcvuxwdp", VSX_BUILTIN_XVCVUXWDP },
10622 { MASK_VSX, CODE_FOR_vsx_xvrdpi, "__builtin_vsx_xvrdpi", VSX_BUILTIN_XVRDPI },
10623 { MASK_VSX, CODE_FOR_vsx_xvrdpic, "__builtin_vsx_xvrdpic", VSX_BUILTIN_XVRDPIC },
10624 { MASK_VSX, CODE_FOR_vsx_floorv2df2, "__builtin_vsx_xvrdpim", VSX_BUILTIN_XVRDPIM },
10625 { MASK_VSX, CODE_FOR_vsx_ceilv2df2, "__builtin_vsx_xvrdpip", VSX_BUILTIN_XVRDPIP },
10626 { MASK_VSX, CODE_FOR_vsx_btruncv2df2, "__builtin_vsx_xvrdpiz", VSX_BUILTIN_XVRDPIZ },
10628 { MASK_VSX, CODE_FOR_vsx_xvcvspsxds, "__builtin_vsx_xvcvspsxds", VSX_BUILTIN_XVCVSPSXDS },
10629 { MASK_VSX, CODE_FOR_vsx_xvcvspuxds, "__builtin_vsx_xvcvspuxds", VSX_BUILTIN_XVCVSPUXDS },
10630 { MASK_VSX, CODE_FOR_vsx_xvcvsxdsp, "__builtin_vsx_xvcvsxdsp", VSX_BUILTIN_XVCVSXDSP },
10631 { MASK_VSX, CODE_FOR_vsx_xvcvuxdsp, "__builtin_vsx_xvcvuxdsp", VSX_BUILTIN_XVCVUXDSP },
10632 { MASK_VSX, CODE_FOR_vsx_xvrspi, "__builtin_vsx_xvrspi", VSX_BUILTIN_XVRSPI },
10633 { MASK_VSX, CODE_FOR_vsx_xvrspic, "__builtin_vsx_xvrspic", VSX_BUILTIN_XVRSPIC },
10634 { MASK_VSX, CODE_FOR_vsx_floorv4sf2, "__builtin_vsx_xvrspim", VSX_BUILTIN_XVRSPIM },
10635 { MASK_VSX, CODE_FOR_vsx_ceilv4sf2, "__builtin_vsx_xvrspip", VSX_BUILTIN_XVRSPIP },
10636 { MASK_VSX, CODE_FOR_vsx_btruncv4sf2, "__builtin_vsx_xvrspiz", VSX_BUILTIN_XVRSPIZ },
10638 { MASK_VSX, CODE_FOR_vsx_xsrdpi, "__builtin_vsx_xsrdpi", VSX_BUILTIN_XSRDPI },
10639 { MASK_VSX, CODE_FOR_vsx_xsrdpic, "__builtin_vsx_xsrdpic", VSX_BUILTIN_XSRDPIC },
10640 { MASK_VSX, CODE_FOR_vsx_floordf2, "__builtin_vsx_xsrdpim", VSX_BUILTIN_XSRDPIM },
10641 { MASK_VSX, CODE_FOR_vsx_ceildf2, "__builtin_vsx_xsrdpip", VSX_BUILTIN_XSRDPIP },
10642 { MASK_VSX, CODE_FOR_vsx_btruncdf2, "__builtin_vsx_xsrdpiz", VSX_BUILTIN_XSRDPIZ },
10644 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abs", ALTIVEC_BUILTIN_VEC_ABS },
10645 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abss", ALTIVEC_BUILTIN_VEC_ABSS },
10646 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_ceil", ALTIVEC_BUILTIN_VEC_CEIL },
10647 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_expte", ALTIVEC_BUILTIN_VEC_EXPTE },
10648 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_floor", ALTIVEC_BUILTIN_VEC_FLOOR },
10649 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_loge", ALTIVEC_BUILTIN_VEC_LOGE },
10650 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mtvscr", ALTIVEC_BUILTIN_VEC_MTVSCR },
10651 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_re", ALTIVEC_BUILTIN_VEC_RE },
10652 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_round", ALTIVEC_BUILTIN_VEC_ROUND },
10653 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rsqrt", ALTIVEC_BUILTIN_VEC_RSQRT },
10654 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rsqrte", ALTIVEC_BUILTIN_VEC_RSQRTE },
10655 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_trunc", ALTIVEC_BUILTIN_VEC_TRUNC },
10656 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_unpackh", ALTIVEC_BUILTIN_VEC_UNPACKH },
10657 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhsh", ALTIVEC_BUILTIN_VEC_VUPKHSH },
10658 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhpx", ALTIVEC_BUILTIN_VEC_VUPKHPX },
10659 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhsb", ALTIVEC_BUILTIN_VEC_VUPKHSB },
10660 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_unpackl", ALTIVEC_BUILTIN_VEC_UNPACKL },
10661 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklpx", ALTIVEC_BUILTIN_VEC_VUPKLPX },
10662 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsh", ALTIVEC_BUILTIN_VEC_VUPKLSH },
10663 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsb", ALTIVEC_BUILTIN_VEC_VUPKLSB },
10665 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_nearbyint", ALTIVEC_BUILTIN_VEC_NEARBYINT },
10666 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_rint", ALTIVEC_BUILTIN_VEC_RINT },
10667 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_sqrt", ALTIVEC_BUILTIN_VEC_SQRT },
10669 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_floatv4siv4sf2, "__builtin_vec_float_sisf", VECTOR_BUILTIN_FLOAT_V4SI_V4SF },
10670 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_unsigned_floatv4siv4sf2, "__builtin_vec_uns_float_sisf", VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF },
10671 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_fix_truncv4sfv4si2, "__builtin_vec_fix_sfsi", VECTOR_BUILTIN_FIX_V4SF_V4SI },
10672 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_fixuns_truncv4sfv4si2, "__builtin_vec_fixuns_sfsi", VECTOR_BUILTIN_FIXUNS_V4SF_V4SI },
10674 /* The SPE unary builtins must start with SPE_BUILTIN_EVABS and
10675 end with SPE_BUILTIN_EVSUBFUSIAAW. */
10676 { 0, CODE_FOR_absv2si2, "__builtin_spe_evabs", SPE_BUILTIN_EVABS },
10677 { 0, CODE_FOR_spe_evaddsmiaaw, "__builtin_spe_evaddsmiaaw", SPE_BUILTIN_EVADDSMIAAW },
10678 { 0, CODE_FOR_spe_evaddssiaaw, "__builtin_spe_evaddssiaaw", SPE_BUILTIN_EVADDSSIAAW },
10679 { 0, CODE_FOR_spe_evaddumiaaw, "__builtin_spe_evaddumiaaw", SPE_BUILTIN_EVADDUMIAAW },
10680 { 0, CODE_FOR_spe_evaddusiaaw, "__builtin_spe_evaddusiaaw", SPE_BUILTIN_EVADDUSIAAW },
10681 { 0, CODE_FOR_spe_evcntlsw, "__builtin_spe_evcntlsw", SPE_BUILTIN_EVCNTLSW },
10682 { 0, CODE_FOR_spe_evcntlzw, "__builtin_spe_evcntlzw", SPE_BUILTIN_EVCNTLZW },
10683 { 0, CODE_FOR_spe_evextsb, "__builtin_spe_evextsb", SPE_BUILTIN_EVEXTSB },
10684 { 0, CODE_FOR_spe_evextsh, "__builtin_spe_evextsh", SPE_BUILTIN_EVEXTSH },
10685 { 0, CODE_FOR_spe_evfsabs, "__builtin_spe_evfsabs", SPE_BUILTIN_EVFSABS },
10686 { 0, CODE_FOR_spe_evfscfsf, "__builtin_spe_evfscfsf", SPE_BUILTIN_EVFSCFSF },
10687 { 0, CODE_FOR_spe_evfscfsi, "__builtin_spe_evfscfsi", SPE_BUILTIN_EVFSCFSI },
10688 { 0, CODE_FOR_spe_evfscfuf, "__builtin_spe_evfscfuf", SPE_BUILTIN_EVFSCFUF },
10689 { 0, CODE_FOR_spe_evfscfui, "__builtin_spe_evfscfui", SPE_BUILTIN_EVFSCFUI },
10690 { 0, CODE_FOR_spe_evfsctsf, "__builtin_spe_evfsctsf", SPE_BUILTIN_EVFSCTSF },
10691 { 0, CODE_FOR_spe_evfsctsi, "__builtin_spe_evfsctsi", SPE_BUILTIN_EVFSCTSI },
10692 { 0, CODE_FOR_spe_evfsctsiz, "__builtin_spe_evfsctsiz", SPE_BUILTIN_EVFSCTSIZ },
10693 { 0, CODE_FOR_spe_evfsctuf, "__builtin_spe_evfsctuf", SPE_BUILTIN_EVFSCTUF },
10694 { 0, CODE_FOR_spe_evfsctui, "__builtin_spe_evfsctui", SPE_BUILTIN_EVFSCTUI },
10695 { 0, CODE_FOR_spe_evfsctuiz, "__builtin_spe_evfsctuiz", SPE_BUILTIN_EVFSCTUIZ },
10696 { 0, CODE_FOR_spe_evfsnabs, "__builtin_spe_evfsnabs", SPE_BUILTIN_EVFSNABS },
10697 { 0, CODE_FOR_spe_evfsneg, "__builtin_spe_evfsneg", SPE_BUILTIN_EVFSNEG },
10698 { 0, CODE_FOR_spe_evmra, "__builtin_spe_evmra", SPE_BUILTIN_EVMRA },
10699 { 0, CODE_FOR_negv2si2, "__builtin_spe_evneg", SPE_BUILTIN_EVNEG },
10700 { 0, CODE_FOR_spe_evrndw, "__builtin_spe_evrndw", SPE_BUILTIN_EVRNDW },
10701 { 0, CODE_FOR_spe_evsubfsmiaaw, "__builtin_spe_evsubfsmiaaw", SPE_BUILTIN_EVSUBFSMIAAW },
10702 { 0, CODE_FOR_spe_evsubfssiaaw, "__builtin_spe_evsubfssiaaw", SPE_BUILTIN_EVSUBFSSIAAW },
10703 { 0, CODE_FOR_spe_evsubfumiaaw, "__builtin_spe_evsubfumiaaw", SPE_BUILTIN_EVSUBFUMIAAW },
10705 /* Place-holder. Leave as last unary SPE builtin. */
10706 { 0, CODE_FOR_spe_evsubfusiaaw, "__builtin_spe_evsubfusiaaw", SPE_BUILTIN_EVSUBFUSIAAW },
10708 { 0, CODE_FOR_paired_absv2sf2, "__builtin_paired_absv2sf2", PAIRED_BUILTIN_ABSV2SF2 },
10709 { 0, CODE_FOR_nabsv2sf2, "__builtin_paired_nabsv2sf2", PAIRED_BUILTIN_NABSV2SF2 },
10710 { 0, CODE_FOR_paired_negv2sf2, "__builtin_paired_negv2sf2", PAIRED_BUILTIN_NEGV2SF2 },
10711 { 0, CODE_FOR_sqrtv2sf2, "__builtin_paired_sqrtv2sf2", PAIRED_BUILTIN_SQRTV2SF2 },
10712 { 0, CODE_FOR_resv2sf2, "__builtin_paired_resv2sf2", PAIRED_BUILTIN_RESV2SF2 }
10715 static rtx
10716 rs6000_expand_unop_builtin (enum insn_code icode, tree exp, rtx target)
10718 rtx pat;
10719 tree arg0 = CALL_EXPR_ARG (exp, 0);
10720 rtx op0 = expand_normal (arg0);
10721 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10722 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10724 if (icode == CODE_FOR_nothing)
10725 /* Builtin not supported on this processor. */
10726 return 0;
10728 /* If we got invalid arguments bail out before generating bad rtl. */
10729 if (arg0 == error_mark_node)
10730 return const0_rtx;
10732 if (icode == CODE_FOR_altivec_vspltisb
10733 || icode == CODE_FOR_altivec_vspltish
10734 || icode == CODE_FOR_altivec_vspltisw
10735 || icode == CODE_FOR_spe_evsplatfi
10736 || icode == CODE_FOR_spe_evsplati)
10738 /* Only allow 5-bit *signed* literals. */
10739 if (GET_CODE (op0) != CONST_INT
10740 || INTVAL (op0) > 15
10741 || INTVAL (op0) < -16)
10743 error ("argument 1 must be a 5-bit signed literal");
10744 return const0_rtx;
10748 if (target == 0
10749 || GET_MODE (target) != tmode
10750 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10751 target = gen_reg_rtx (tmode);
10753 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10754 op0 = copy_to_mode_reg (mode0, op0);
10756 pat = GEN_FCN (icode) (target, op0);
10757 if (! pat)
10758 return 0;
10759 emit_insn (pat);
10761 return target;
10764 static rtx
10765 altivec_expand_abs_builtin (enum insn_code icode, tree exp, rtx target)
10767 rtx pat, scratch1, scratch2;
10768 tree arg0 = CALL_EXPR_ARG (exp, 0);
10769 rtx op0 = expand_normal (arg0);
10770 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10771 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10773 /* If we have invalid arguments, bail out before generating bad rtl. */
10774 if (arg0 == error_mark_node)
10775 return const0_rtx;
10777 if (target == 0
10778 || GET_MODE (target) != tmode
10779 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10780 target = gen_reg_rtx (tmode);
10782 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10783 op0 = copy_to_mode_reg (mode0, op0);
10785 scratch1 = gen_reg_rtx (mode0);
10786 scratch2 = gen_reg_rtx (mode0);
10788 pat = GEN_FCN (icode) (target, op0, scratch1, scratch2);
10789 if (! pat)
10790 return 0;
10791 emit_insn (pat);
10793 return target;
10796 static rtx
10797 rs6000_expand_binop_builtin (enum insn_code icode, tree exp, rtx target)
10799 rtx pat;
10800 tree arg0 = CALL_EXPR_ARG (exp, 0);
10801 tree arg1 = CALL_EXPR_ARG (exp, 1);
10802 rtx op0 = expand_normal (arg0);
10803 rtx op1 = expand_normal (arg1);
10804 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10805 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10806 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
10808 if (icode == CODE_FOR_nothing)
10809 /* Builtin not supported on this processor. */
10810 return 0;
10812 /* If we got invalid arguments bail out before generating bad rtl. */
10813 if (arg0 == error_mark_node || arg1 == error_mark_node)
10814 return const0_rtx;
10816 if (icode == CODE_FOR_altivec_vcfux
10817 || icode == CODE_FOR_altivec_vcfsx
10818 || icode == CODE_FOR_altivec_vctsxs
10819 || icode == CODE_FOR_altivec_vctuxs
10820 || icode == CODE_FOR_altivec_vspltb
10821 || icode == CODE_FOR_altivec_vsplth
10822 || icode == CODE_FOR_altivec_vspltw
10823 || icode == CODE_FOR_spe_evaddiw
10824 || icode == CODE_FOR_spe_evldd
10825 || icode == CODE_FOR_spe_evldh
10826 || icode == CODE_FOR_spe_evldw
10827 || icode == CODE_FOR_spe_evlhhesplat
10828 || icode == CODE_FOR_spe_evlhhossplat
10829 || icode == CODE_FOR_spe_evlhhousplat
10830 || icode == CODE_FOR_spe_evlwhe
10831 || icode == CODE_FOR_spe_evlwhos
10832 || icode == CODE_FOR_spe_evlwhou
10833 || icode == CODE_FOR_spe_evlwhsplat
10834 || icode == CODE_FOR_spe_evlwwsplat
10835 || icode == CODE_FOR_spe_evrlwi
10836 || icode == CODE_FOR_spe_evslwi
10837 || icode == CODE_FOR_spe_evsrwis
10838 || icode == CODE_FOR_spe_evsubifw
10839 || icode == CODE_FOR_spe_evsrwiu)
10841 /* Only allow 5-bit unsigned literals. */
10842 STRIP_NOPS (arg1);
10843 if (TREE_CODE (arg1) != INTEGER_CST
10844 || TREE_INT_CST_LOW (arg1) & ~0x1f)
10846 error ("argument 2 must be a 5-bit unsigned literal");
10847 return const0_rtx;
10851 if (target == 0
10852 || GET_MODE (target) != tmode
10853 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10854 target = gen_reg_rtx (tmode);
10856 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10857 op0 = copy_to_mode_reg (mode0, op0);
10858 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
10859 op1 = copy_to_mode_reg (mode1, op1);
10861 pat = GEN_FCN (icode) (target, op0, op1);
10862 if (! pat)
10863 return 0;
10864 emit_insn (pat);
10866 return target;
10869 static rtx
10870 altivec_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
10872 rtx pat, scratch;
10873 tree cr6_form = CALL_EXPR_ARG (exp, 0);
10874 tree arg0 = CALL_EXPR_ARG (exp, 1);
10875 tree arg1 = CALL_EXPR_ARG (exp, 2);
10876 rtx op0 = expand_normal (arg0);
10877 rtx op1 = expand_normal (arg1);
10878 enum machine_mode tmode = SImode;
10879 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10880 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
10881 int cr6_form_int;
10883 if (TREE_CODE (cr6_form) != INTEGER_CST)
10885 error ("argument 1 of __builtin_altivec_predicate must be a constant");
10886 return const0_rtx;
10888 else
10889 cr6_form_int = TREE_INT_CST_LOW (cr6_form);
10891 gcc_assert (mode0 == mode1);
10893 /* If we have invalid arguments, bail out before generating bad rtl. */
10894 if (arg0 == error_mark_node || arg1 == error_mark_node)
10895 return const0_rtx;
10897 if (target == 0
10898 || GET_MODE (target) != tmode
10899 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10900 target = gen_reg_rtx (tmode);
10902 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10903 op0 = copy_to_mode_reg (mode0, op0);
10904 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
10905 op1 = copy_to_mode_reg (mode1, op1);
10907 scratch = gen_reg_rtx (mode0);
10909 pat = GEN_FCN (icode) (scratch, op0, op1);
10910 if (! pat)
10911 return 0;
10912 emit_insn (pat);
10914 /* The vec_any* and vec_all* predicates use the same opcodes for two
10915 different operations, but the bits in CR6 will be different
10916 depending on what information we want. So we have to play tricks
10917 with CR6 to get the right bits out.
10919 If you think this is disgusting, look at the specs for the
10920 AltiVec predicates. */
10922 switch (cr6_form_int)
10924 case 0:
10925 emit_insn (gen_cr6_test_for_zero (target));
10926 break;
10927 case 1:
10928 emit_insn (gen_cr6_test_for_zero_reverse (target));
10929 break;
10930 case 2:
10931 emit_insn (gen_cr6_test_for_lt (target));
10932 break;
10933 case 3:
10934 emit_insn (gen_cr6_test_for_lt_reverse (target));
10935 break;
10936 default:
10937 error ("argument 1 of __builtin_altivec_predicate is out of range");
10938 break;
10941 return target;
10944 static rtx
10945 paired_expand_lv_builtin (enum insn_code icode, tree exp, rtx target)
10947 rtx pat, addr;
10948 tree arg0 = CALL_EXPR_ARG (exp, 0);
10949 tree arg1 = CALL_EXPR_ARG (exp, 1);
10950 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10951 enum machine_mode mode0 = Pmode;
10952 enum machine_mode mode1 = Pmode;
10953 rtx op0 = expand_normal (arg0);
10954 rtx op1 = expand_normal (arg1);
10956 if (icode == CODE_FOR_nothing)
10957 /* Builtin not supported on this processor. */
10958 return 0;
10960 /* If we got invalid arguments bail out before generating bad rtl. */
10961 if (arg0 == error_mark_node || arg1 == error_mark_node)
10962 return const0_rtx;
10964 if (target == 0
10965 || GET_MODE (target) != tmode
10966 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10967 target = gen_reg_rtx (tmode);
10969 op1 = copy_to_mode_reg (mode1, op1);
10971 if (op0 == const0_rtx)
10973 addr = gen_rtx_MEM (tmode, op1);
10975 else
10977 op0 = copy_to_mode_reg (mode0, op0);
10978 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op0, op1));
10981 pat = GEN_FCN (icode) (target, addr);
10983 if (! pat)
10984 return 0;
10985 emit_insn (pat);
10987 return target;
10990 static rtx
10991 altivec_expand_lv_builtin (enum insn_code icode, tree exp, rtx target, bool blk)
10993 rtx pat, addr;
10994 tree arg0 = CALL_EXPR_ARG (exp, 0);
10995 tree arg1 = CALL_EXPR_ARG (exp, 1);
10996 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10997 enum machine_mode mode0 = Pmode;
10998 enum machine_mode mode1 = Pmode;
10999 rtx op0 = expand_normal (arg0);
11000 rtx op1 = expand_normal (arg1);
11002 if (icode == CODE_FOR_nothing)
11003 /* Builtin not supported on this processor. */
11004 return 0;
11006 /* If we got invalid arguments bail out before generating bad rtl. */
11007 if (arg0 == error_mark_node || arg1 == error_mark_node)
11008 return const0_rtx;
11010 if (target == 0
11011 || GET_MODE (target) != tmode
11012 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11013 target = gen_reg_rtx (tmode);
11015 op1 = copy_to_mode_reg (mode1, op1);
11017 if (op0 == const0_rtx)
11019 addr = gen_rtx_MEM (blk ? BLKmode : tmode, op1);
11021 else
11023 op0 = copy_to_mode_reg (mode0, op0);
11024 addr = gen_rtx_MEM (blk ? BLKmode : tmode, gen_rtx_PLUS (Pmode, op0, op1));
11027 pat = GEN_FCN (icode) (target, addr);
11029 if (! pat)
11030 return 0;
11031 emit_insn (pat);
11033 return target;
11036 static rtx
11037 spe_expand_stv_builtin (enum insn_code icode, tree exp)
11039 tree arg0 = CALL_EXPR_ARG (exp, 0);
11040 tree arg1 = CALL_EXPR_ARG (exp, 1);
11041 tree arg2 = CALL_EXPR_ARG (exp, 2);
11042 rtx op0 = expand_normal (arg0);
11043 rtx op1 = expand_normal (arg1);
11044 rtx op2 = expand_normal (arg2);
11045 rtx pat;
11046 enum machine_mode mode0 = insn_data[icode].operand[0].mode;
11047 enum machine_mode mode1 = insn_data[icode].operand[1].mode;
11048 enum machine_mode mode2 = insn_data[icode].operand[2].mode;
11050 /* Invalid arguments. Bail before doing anything stoopid! */
11051 if (arg0 == error_mark_node
11052 || arg1 == error_mark_node
11053 || arg2 == error_mark_node)
11054 return const0_rtx;
11056 if (! (*insn_data[icode].operand[2].predicate) (op0, mode2))
11057 op0 = copy_to_mode_reg (mode2, op0);
11058 if (! (*insn_data[icode].operand[0].predicate) (op1, mode0))
11059 op1 = copy_to_mode_reg (mode0, op1);
11060 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
11061 op2 = copy_to_mode_reg (mode1, op2);
11063 pat = GEN_FCN (icode) (op1, op2, op0);
11064 if (pat)
11065 emit_insn (pat);
11066 return NULL_RTX;
11069 static rtx
11070 paired_expand_stv_builtin (enum insn_code icode, tree exp)
11072 tree arg0 = CALL_EXPR_ARG (exp, 0);
11073 tree arg1 = CALL_EXPR_ARG (exp, 1);
11074 tree arg2 = CALL_EXPR_ARG (exp, 2);
11075 rtx op0 = expand_normal (arg0);
11076 rtx op1 = expand_normal (arg1);
11077 rtx op2 = expand_normal (arg2);
11078 rtx pat, addr;
11079 enum machine_mode tmode = insn_data[icode].operand[0].mode;
11080 enum machine_mode mode1 = Pmode;
11081 enum machine_mode mode2 = Pmode;
11083 /* Invalid arguments. Bail before doing anything stoopid! */
11084 if (arg0 == error_mark_node
11085 || arg1 == error_mark_node
11086 || arg2 == error_mark_node)
11087 return const0_rtx;
11089 if (! (*insn_data[icode].operand[1].predicate) (op0, tmode))
11090 op0 = copy_to_mode_reg (tmode, op0);
11092 op2 = copy_to_mode_reg (mode2, op2);
11094 if (op1 == const0_rtx)
11096 addr = gen_rtx_MEM (tmode, op2);
11098 else
11100 op1 = copy_to_mode_reg (mode1, op1);
11101 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op1, op2));
11104 pat = GEN_FCN (icode) (addr, op0);
11105 if (pat)
11106 emit_insn (pat);
11107 return NULL_RTX;
11110 static rtx
11111 altivec_expand_stv_builtin (enum insn_code icode, tree exp)
11113 tree arg0 = CALL_EXPR_ARG (exp, 0);
11114 tree arg1 = CALL_EXPR_ARG (exp, 1);
11115 tree arg2 = CALL_EXPR_ARG (exp, 2);
11116 rtx op0 = expand_normal (arg0);
11117 rtx op1 = expand_normal (arg1);
11118 rtx op2 = expand_normal (arg2);
11119 rtx pat, addr;
11120 enum machine_mode tmode = insn_data[icode].operand[0].mode;
11121 enum machine_mode smode = insn_data[icode].operand[1].mode;
11122 enum machine_mode mode1 = Pmode;
11123 enum machine_mode mode2 = Pmode;
11125 /* Invalid arguments. Bail before doing anything stoopid! */
11126 if (arg0 == error_mark_node
11127 || arg1 == error_mark_node
11128 || arg2 == error_mark_node)
11129 return const0_rtx;
11131 if (! (*insn_data[icode].operand[1].predicate) (op0, smode))
11132 op0 = copy_to_mode_reg (smode, op0);
11134 op2 = copy_to_mode_reg (mode2, op2);
11136 if (op1 == const0_rtx)
11138 addr = gen_rtx_MEM (tmode, op2);
11140 else
11142 op1 = copy_to_mode_reg (mode1, op1);
11143 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op1, op2));
11146 pat = GEN_FCN (icode) (addr, op0);
11147 if (pat)
11148 emit_insn (pat);
11149 return NULL_RTX;
11152 static rtx
11153 rs6000_expand_ternop_builtin (enum insn_code icode, tree exp, rtx target)
11155 rtx pat;
11156 tree arg0 = CALL_EXPR_ARG (exp, 0);
11157 tree arg1 = CALL_EXPR_ARG (exp, 1);
11158 tree arg2 = CALL_EXPR_ARG (exp, 2);
11159 rtx op0 = expand_normal (arg0);
11160 rtx op1 = expand_normal (arg1);
11161 rtx op2 = expand_normal (arg2);
11162 enum machine_mode tmode = insn_data[icode].operand[0].mode;
11163 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
11164 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
11165 enum machine_mode mode2 = insn_data[icode].operand[3].mode;
11167 if (icode == CODE_FOR_nothing)
11168 /* Builtin not supported on this processor. */
11169 return 0;
11171 /* If we got invalid arguments bail out before generating bad rtl. */
11172 if (arg0 == error_mark_node
11173 || arg1 == error_mark_node
11174 || arg2 == error_mark_node)
11175 return const0_rtx;
11177 /* Check and prepare argument depending on the instruction code.
11179 Note that a switch statement instead of the sequence of tests
11180 would be incorrect as many of the CODE_FOR values could be
11181 CODE_FOR_nothing and that would yield multiple alternatives
11182 with identical values. We'd never reach here at runtime in
11183 this case. */
11184 if (icode == CODE_FOR_altivec_vsldoi_v4sf
11185 || icode == CODE_FOR_altivec_vsldoi_v4si
11186 || icode == CODE_FOR_altivec_vsldoi_v8hi
11187 || icode == CODE_FOR_altivec_vsldoi_v16qi)
11189 /* Only allow 4-bit unsigned literals. */
11190 STRIP_NOPS (arg2);
11191 if (TREE_CODE (arg2) != INTEGER_CST
11192 || TREE_INT_CST_LOW (arg2) & ~0xf)
11194 error ("argument 3 must be a 4-bit unsigned literal");
11195 return const0_rtx;
11198 else if (icode == CODE_FOR_vsx_xxpermdi_v2df
11199 || icode == CODE_FOR_vsx_xxpermdi_v2di
11200 || icode == CODE_FOR_vsx_xxsldwi_v16qi
11201 || icode == CODE_FOR_vsx_xxsldwi_v8hi
11202 || icode == CODE_FOR_vsx_xxsldwi_v4si
11203 || icode == CODE_FOR_vsx_xxsldwi_v4sf
11204 || icode == CODE_FOR_vsx_xxsldwi_v2di
11205 || icode == CODE_FOR_vsx_xxsldwi_v2df)
11207 /* Only allow 2-bit unsigned literals. */
11208 STRIP_NOPS (arg2);
11209 if (TREE_CODE (arg2) != INTEGER_CST
11210 || TREE_INT_CST_LOW (arg2) & ~0x3)
11212 error ("argument 3 must be a 2-bit unsigned literal");
11213 return const0_rtx;
11216 else if (icode == CODE_FOR_vsx_set_v2df
11217 || icode == CODE_FOR_vsx_set_v2di)
11219 /* Only allow 1-bit unsigned literals. */
11220 STRIP_NOPS (arg2);
11221 if (TREE_CODE (arg2) != INTEGER_CST
11222 || TREE_INT_CST_LOW (arg2) & ~0x1)
11224 error ("argument 3 must be a 1-bit unsigned literal");
11225 return const0_rtx;
11229 if (target == 0
11230 || GET_MODE (target) != tmode
11231 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11232 target = gen_reg_rtx (tmode);
11234 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
11235 op0 = copy_to_mode_reg (mode0, op0);
11236 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
11237 op1 = copy_to_mode_reg (mode1, op1);
11238 if (! (*insn_data[icode].operand[3].predicate) (op2, mode2))
11239 op2 = copy_to_mode_reg (mode2, op2);
11241 if (TARGET_PAIRED_FLOAT && icode == CODE_FOR_selv2sf4)
11242 pat = GEN_FCN (icode) (target, op0, op1, op2, CONST0_RTX (SFmode));
11243 else
11244 pat = GEN_FCN (icode) (target, op0, op1, op2);
11245 if (! pat)
11246 return 0;
11247 emit_insn (pat);
11249 return target;
11252 /* Expand the lvx builtins. */
11253 static rtx
11254 altivec_expand_ld_builtin (tree exp, rtx target, bool *expandedp)
11256 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11257 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11258 tree arg0;
11259 enum machine_mode tmode, mode0;
11260 rtx pat, op0;
11261 enum insn_code icode;
11263 switch (fcode)
11265 case ALTIVEC_BUILTIN_LD_INTERNAL_16qi:
11266 icode = CODE_FOR_vector_load_v16qi;
11267 break;
11268 case ALTIVEC_BUILTIN_LD_INTERNAL_8hi:
11269 icode = CODE_FOR_vector_load_v8hi;
11270 break;
11271 case ALTIVEC_BUILTIN_LD_INTERNAL_4si:
11272 icode = CODE_FOR_vector_load_v4si;
11273 break;
11274 case ALTIVEC_BUILTIN_LD_INTERNAL_4sf:
11275 icode = CODE_FOR_vector_load_v4sf;
11276 break;
11277 default:
11278 *expandedp = false;
11279 return NULL_RTX;
11282 *expandedp = true;
11284 arg0 = CALL_EXPR_ARG (exp, 0);
11285 op0 = expand_normal (arg0);
11286 tmode = insn_data[icode].operand[0].mode;
11287 mode0 = insn_data[icode].operand[1].mode;
11289 if (target == 0
11290 || GET_MODE (target) != tmode
11291 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11292 target = gen_reg_rtx (tmode);
11294 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
11295 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
11297 pat = GEN_FCN (icode) (target, op0);
11298 if (! pat)
11299 return 0;
11300 emit_insn (pat);
11301 return target;
11304 /* Expand the stvx builtins. */
11305 static rtx
11306 altivec_expand_st_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
11307 bool *expandedp)
11309 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11310 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11311 tree arg0, arg1;
11312 enum machine_mode mode0, mode1;
11313 rtx pat, op0, op1;
11314 enum insn_code icode;
11316 switch (fcode)
11318 case ALTIVEC_BUILTIN_ST_INTERNAL_16qi:
11319 icode = CODE_FOR_vector_store_v16qi;
11320 break;
11321 case ALTIVEC_BUILTIN_ST_INTERNAL_8hi:
11322 icode = CODE_FOR_vector_store_v8hi;
11323 break;
11324 case ALTIVEC_BUILTIN_ST_INTERNAL_4si:
11325 icode = CODE_FOR_vector_store_v4si;
11326 break;
11327 case ALTIVEC_BUILTIN_ST_INTERNAL_4sf:
11328 icode = CODE_FOR_vector_store_v4sf;
11329 break;
11330 default:
11331 *expandedp = false;
11332 return NULL_RTX;
11335 arg0 = CALL_EXPR_ARG (exp, 0);
11336 arg1 = CALL_EXPR_ARG (exp, 1);
11337 op0 = expand_normal (arg0);
11338 op1 = expand_normal (arg1);
11339 mode0 = insn_data[icode].operand[0].mode;
11340 mode1 = insn_data[icode].operand[1].mode;
11342 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
11343 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
11344 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
11345 op1 = copy_to_mode_reg (mode1, op1);
11347 pat = GEN_FCN (icode) (op0, op1);
11348 if (pat)
11349 emit_insn (pat);
11351 *expandedp = true;
11352 return NULL_RTX;
11355 /* Expand the dst builtins. */
11356 static rtx
11357 altivec_expand_dst_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
11358 bool *expandedp)
11360 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11361 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11362 tree arg0, arg1, arg2;
11363 enum machine_mode mode0, mode1;
11364 rtx pat, op0, op1, op2;
11365 const struct builtin_description *d;
11366 size_t i;
11368 *expandedp = false;
11370 /* Handle DST variants. */
11371 d = bdesc_dst;
11372 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
11373 if (d->code == fcode)
11375 arg0 = CALL_EXPR_ARG (exp, 0);
11376 arg1 = CALL_EXPR_ARG (exp, 1);
11377 arg2 = CALL_EXPR_ARG (exp, 2);
11378 op0 = expand_normal (arg0);
11379 op1 = expand_normal (arg1);
11380 op2 = expand_normal (arg2);
11381 mode0 = insn_data[d->icode].operand[0].mode;
11382 mode1 = insn_data[d->icode].operand[1].mode;
11384 /* Invalid arguments, bail out before generating bad rtl. */
11385 if (arg0 == error_mark_node
11386 || arg1 == error_mark_node
11387 || arg2 == error_mark_node)
11388 return const0_rtx;
11390 *expandedp = true;
11391 STRIP_NOPS (arg2);
11392 if (TREE_CODE (arg2) != INTEGER_CST
11393 || TREE_INT_CST_LOW (arg2) & ~0x3)
11395 error ("argument to %qs must be a 2-bit unsigned literal", d->name);
11396 return const0_rtx;
11399 if (! (*insn_data[d->icode].operand[0].predicate) (op0, mode0))
11400 op0 = copy_to_mode_reg (Pmode, op0);
11401 if (! (*insn_data[d->icode].operand[1].predicate) (op1, mode1))
11402 op1 = copy_to_mode_reg (mode1, op1);
11404 pat = GEN_FCN (d->icode) (op0, op1, op2);
11405 if (pat != 0)
11406 emit_insn (pat);
11408 return NULL_RTX;
11411 return NULL_RTX;
11414 /* Expand vec_init builtin. */
11415 static rtx
11416 altivec_expand_vec_init_builtin (tree type, tree exp, rtx target)
11418 enum machine_mode tmode = TYPE_MODE (type);
11419 enum machine_mode inner_mode = GET_MODE_INNER (tmode);
11420 int i, n_elt = GET_MODE_NUNITS (tmode);
11421 rtvec v = rtvec_alloc (n_elt);
11423 gcc_assert (VECTOR_MODE_P (tmode));
11424 gcc_assert (n_elt == call_expr_nargs (exp));
11426 for (i = 0; i < n_elt; ++i)
11428 rtx x = expand_normal (CALL_EXPR_ARG (exp, i));
11429 RTVEC_ELT (v, i) = gen_lowpart (inner_mode, x);
11432 if (!target || !register_operand (target, tmode))
11433 target = gen_reg_rtx (tmode);
11435 rs6000_expand_vector_init (target, gen_rtx_PARALLEL (tmode, v));
11436 return target;
11439 /* Return the integer constant in ARG. Constrain it to be in the range
11440 of the subparts of VEC_TYPE; issue an error if not. */
11442 static int
11443 get_element_number (tree vec_type, tree arg)
11445 unsigned HOST_WIDE_INT elt, max = TYPE_VECTOR_SUBPARTS (vec_type) - 1;
11447 if (!host_integerp (arg, 1)
11448 || (elt = tree_low_cst (arg, 1), elt > max))
11450 error ("selector must be an integer constant in the range 0..%wi", max);
11451 return 0;
11454 return elt;
11457 /* Expand vec_set builtin. */
11458 static rtx
11459 altivec_expand_vec_set_builtin (tree exp)
11461 enum machine_mode tmode, mode1;
11462 tree arg0, arg1, arg2;
11463 int elt;
11464 rtx op0, op1;
11466 arg0 = CALL_EXPR_ARG (exp, 0);
11467 arg1 = CALL_EXPR_ARG (exp, 1);
11468 arg2 = CALL_EXPR_ARG (exp, 2);
11470 tmode = TYPE_MODE (TREE_TYPE (arg0));
11471 mode1 = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
11472 gcc_assert (VECTOR_MODE_P (tmode));
11474 op0 = expand_expr (arg0, NULL_RTX, tmode, EXPAND_NORMAL);
11475 op1 = expand_expr (arg1, NULL_RTX, mode1, EXPAND_NORMAL);
11476 elt = get_element_number (TREE_TYPE (arg0), arg2);
11478 if (GET_MODE (op1) != mode1 && GET_MODE (op1) != VOIDmode)
11479 op1 = convert_modes (mode1, GET_MODE (op1), op1, true);
11481 op0 = force_reg (tmode, op0);
11482 op1 = force_reg (mode1, op1);
11484 rs6000_expand_vector_set (op0, op1, elt);
11486 return op0;
11489 /* Expand vec_ext builtin. */
11490 static rtx
11491 altivec_expand_vec_ext_builtin (tree exp, rtx target)
11493 enum machine_mode tmode, mode0;
11494 tree arg0, arg1;
11495 int elt;
11496 rtx op0;
11498 arg0 = CALL_EXPR_ARG (exp, 0);
11499 arg1 = CALL_EXPR_ARG (exp, 1);
11501 op0 = expand_normal (arg0);
11502 elt = get_element_number (TREE_TYPE (arg0), arg1);
11504 tmode = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
11505 mode0 = TYPE_MODE (TREE_TYPE (arg0));
11506 gcc_assert (VECTOR_MODE_P (mode0));
11508 op0 = force_reg (mode0, op0);
11510 if (optimize || !target || !register_operand (target, tmode))
11511 target = gen_reg_rtx (tmode);
11513 rs6000_expand_vector_extract (target, op0, elt);
11515 return target;
11518 /* Expand the builtin in EXP and store the result in TARGET. Store
11519 true in *EXPANDEDP if we found a builtin to expand. */
11520 static rtx
11521 altivec_expand_builtin (tree exp, rtx target, bool *expandedp)
11523 const struct builtin_description *d;
11524 const struct builtin_description_predicates *dp;
11525 size_t i;
11526 enum insn_code icode;
11527 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11528 tree arg0;
11529 rtx op0, pat;
11530 enum machine_mode tmode, mode0;
11531 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11533 if ((fcode >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
11534 && fcode <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
11535 || (fcode >= VSX_BUILTIN_OVERLOADED_FIRST
11536 && fcode <= VSX_BUILTIN_OVERLOADED_LAST))
11538 *expandedp = true;
11539 error ("unresolved overload for Altivec builtin %qF", fndecl);
11540 return const0_rtx;
11543 target = altivec_expand_ld_builtin (exp, target, expandedp);
11544 if (*expandedp)
11545 return target;
11547 target = altivec_expand_st_builtin (exp, target, expandedp);
11548 if (*expandedp)
11549 return target;
11551 target = altivec_expand_dst_builtin (exp, target, expandedp);
11552 if (*expandedp)
11553 return target;
11555 *expandedp = true;
11557 switch (fcode)
11559 case ALTIVEC_BUILTIN_STVX:
11560 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx, exp);
11561 case ALTIVEC_BUILTIN_STVEBX:
11562 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvebx, exp);
11563 case ALTIVEC_BUILTIN_STVEHX:
11564 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvehx, exp);
11565 case ALTIVEC_BUILTIN_STVEWX:
11566 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvewx, exp);
11567 case ALTIVEC_BUILTIN_STVXL:
11568 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvxl, exp);
11570 case ALTIVEC_BUILTIN_STVLX:
11571 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlx, exp);
11572 case ALTIVEC_BUILTIN_STVLXL:
11573 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlxl, exp);
11574 case ALTIVEC_BUILTIN_STVRX:
11575 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrx, exp);
11576 case ALTIVEC_BUILTIN_STVRXL:
11577 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrxl, exp);
11579 case ALTIVEC_BUILTIN_MFVSCR:
11580 icode = CODE_FOR_altivec_mfvscr;
11581 tmode = insn_data[icode].operand[0].mode;
11583 if (target == 0
11584 || GET_MODE (target) != tmode
11585 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11586 target = gen_reg_rtx (tmode);
11588 pat = GEN_FCN (icode) (target);
11589 if (! pat)
11590 return 0;
11591 emit_insn (pat);
11592 return target;
11594 case ALTIVEC_BUILTIN_MTVSCR:
11595 icode = CODE_FOR_altivec_mtvscr;
11596 arg0 = CALL_EXPR_ARG (exp, 0);
11597 op0 = expand_normal (arg0);
11598 mode0 = insn_data[icode].operand[0].mode;
11600 /* If we got invalid arguments bail out before generating bad rtl. */
11601 if (arg0 == error_mark_node)
11602 return const0_rtx;
11604 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
11605 op0 = copy_to_mode_reg (mode0, op0);
11607 pat = GEN_FCN (icode) (op0);
11608 if (pat)
11609 emit_insn (pat);
11610 return NULL_RTX;
11612 case ALTIVEC_BUILTIN_DSSALL:
11613 emit_insn (gen_altivec_dssall ());
11614 return NULL_RTX;
11616 case ALTIVEC_BUILTIN_DSS:
11617 icode = CODE_FOR_altivec_dss;
11618 arg0 = CALL_EXPR_ARG (exp, 0);
11619 STRIP_NOPS (arg0);
11620 op0 = expand_normal (arg0);
11621 mode0 = insn_data[icode].operand[0].mode;
11623 /* If we got invalid arguments bail out before generating bad rtl. */
11624 if (arg0 == error_mark_node)
11625 return const0_rtx;
11627 if (TREE_CODE (arg0) != INTEGER_CST
11628 || TREE_INT_CST_LOW (arg0) & ~0x3)
11630 error ("argument to dss must be a 2-bit unsigned literal");
11631 return const0_rtx;
11634 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
11635 op0 = copy_to_mode_reg (mode0, op0);
11637 emit_insn (gen_altivec_dss (op0));
11638 return NULL_RTX;
11640 case ALTIVEC_BUILTIN_VEC_INIT_V4SI:
11641 case ALTIVEC_BUILTIN_VEC_INIT_V8HI:
11642 case ALTIVEC_BUILTIN_VEC_INIT_V16QI:
11643 case ALTIVEC_BUILTIN_VEC_INIT_V4SF:
11644 case VSX_BUILTIN_VEC_INIT_V2DF:
11645 case VSX_BUILTIN_VEC_INIT_V2DI:
11646 return altivec_expand_vec_init_builtin (TREE_TYPE (exp), exp, target);
11648 case ALTIVEC_BUILTIN_VEC_SET_V4SI:
11649 case ALTIVEC_BUILTIN_VEC_SET_V8HI:
11650 case ALTIVEC_BUILTIN_VEC_SET_V16QI:
11651 case ALTIVEC_BUILTIN_VEC_SET_V4SF:
11652 case VSX_BUILTIN_VEC_SET_V2DF:
11653 case VSX_BUILTIN_VEC_SET_V2DI:
11654 return altivec_expand_vec_set_builtin (exp);
11656 case ALTIVEC_BUILTIN_VEC_EXT_V4SI:
11657 case ALTIVEC_BUILTIN_VEC_EXT_V8HI:
11658 case ALTIVEC_BUILTIN_VEC_EXT_V16QI:
11659 case ALTIVEC_BUILTIN_VEC_EXT_V4SF:
11660 case VSX_BUILTIN_VEC_EXT_V2DF:
11661 case VSX_BUILTIN_VEC_EXT_V2DI:
11662 return altivec_expand_vec_ext_builtin (exp, target);
11664 default:
11665 break;
11666 /* Fall through. */
11669 /* Expand abs* operations. */
11670 d = bdesc_abs;
11671 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
11672 if (d->code == fcode)
11673 return altivec_expand_abs_builtin (d->icode, exp, target);
11675 /* Expand the AltiVec predicates. */
11676 dp = bdesc_altivec_preds;
11677 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
11678 if (dp->code == fcode)
11679 return altivec_expand_predicate_builtin (dp->icode, exp, target);
11681 /* LV* are funky. We initialized them differently. */
11682 switch (fcode)
11684 case ALTIVEC_BUILTIN_LVSL:
11685 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsl,
11686 exp, target, false);
11687 case ALTIVEC_BUILTIN_LVSR:
11688 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsr,
11689 exp, target, false);
11690 case ALTIVEC_BUILTIN_LVEBX:
11691 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvebx,
11692 exp, target, false);
11693 case ALTIVEC_BUILTIN_LVEHX:
11694 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvehx,
11695 exp, target, false);
11696 case ALTIVEC_BUILTIN_LVEWX:
11697 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvewx,
11698 exp, target, false);
11699 case ALTIVEC_BUILTIN_LVXL:
11700 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvxl,
11701 exp, target, false);
11702 case ALTIVEC_BUILTIN_LVX:
11703 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx,
11704 exp, target, false);
11705 case ALTIVEC_BUILTIN_LVLX:
11706 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlx,
11707 exp, target, true);
11708 case ALTIVEC_BUILTIN_LVLXL:
11709 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlxl,
11710 exp, target, true);
11711 case ALTIVEC_BUILTIN_LVRX:
11712 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrx,
11713 exp, target, true);
11714 case ALTIVEC_BUILTIN_LVRXL:
11715 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrxl,
11716 exp, target, true);
11717 default:
11718 break;
11719 /* Fall through. */
11722 *expandedp = false;
11723 return NULL_RTX;
11726 /* Expand the builtin in EXP and store the result in TARGET. Store
11727 true in *EXPANDEDP if we found a builtin to expand. */
11728 static rtx
11729 paired_expand_builtin (tree exp, rtx target, bool * expandedp)
11731 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11732 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11733 const struct builtin_description *d;
11734 size_t i;
11736 *expandedp = true;
11738 switch (fcode)
11740 case PAIRED_BUILTIN_STX:
11741 return paired_expand_stv_builtin (CODE_FOR_paired_stx, exp);
11742 case PAIRED_BUILTIN_LX:
11743 return paired_expand_lv_builtin (CODE_FOR_paired_lx, exp, target);
11744 default:
11745 break;
11746 /* Fall through. */
11749 /* Expand the paired predicates. */
11750 d = bdesc_paired_preds;
11751 for (i = 0; i < ARRAY_SIZE (bdesc_paired_preds); i++, d++)
11752 if (d->code == fcode)
11753 return paired_expand_predicate_builtin (d->icode, exp, target);
11755 *expandedp = false;
11756 return NULL_RTX;
11759 /* Binops that need to be initialized manually, but can be expanded
11760 automagically by rs6000_expand_binop_builtin. */
11761 static struct builtin_description bdesc_2arg_spe[] =
11763 { 0, CODE_FOR_spe_evlddx, "__builtin_spe_evlddx", SPE_BUILTIN_EVLDDX },
11764 { 0, CODE_FOR_spe_evldwx, "__builtin_spe_evldwx", SPE_BUILTIN_EVLDWX },
11765 { 0, CODE_FOR_spe_evldhx, "__builtin_spe_evldhx", SPE_BUILTIN_EVLDHX },
11766 { 0, CODE_FOR_spe_evlwhex, "__builtin_spe_evlwhex", SPE_BUILTIN_EVLWHEX },
11767 { 0, CODE_FOR_spe_evlwhoux, "__builtin_spe_evlwhoux", SPE_BUILTIN_EVLWHOUX },
11768 { 0, CODE_FOR_spe_evlwhosx, "__builtin_spe_evlwhosx", SPE_BUILTIN_EVLWHOSX },
11769 { 0, CODE_FOR_spe_evlwwsplatx, "__builtin_spe_evlwwsplatx", SPE_BUILTIN_EVLWWSPLATX },
11770 { 0, CODE_FOR_spe_evlwhsplatx, "__builtin_spe_evlwhsplatx", SPE_BUILTIN_EVLWHSPLATX },
11771 { 0, CODE_FOR_spe_evlhhesplatx, "__builtin_spe_evlhhesplatx", SPE_BUILTIN_EVLHHESPLATX },
11772 { 0, CODE_FOR_spe_evlhhousplatx, "__builtin_spe_evlhhousplatx", SPE_BUILTIN_EVLHHOUSPLATX },
11773 { 0, CODE_FOR_spe_evlhhossplatx, "__builtin_spe_evlhhossplatx", SPE_BUILTIN_EVLHHOSSPLATX },
11774 { 0, CODE_FOR_spe_evldd, "__builtin_spe_evldd", SPE_BUILTIN_EVLDD },
11775 { 0, CODE_FOR_spe_evldw, "__builtin_spe_evldw", SPE_BUILTIN_EVLDW },
11776 { 0, CODE_FOR_spe_evldh, "__builtin_spe_evldh", SPE_BUILTIN_EVLDH },
11777 { 0, CODE_FOR_spe_evlwhe, "__builtin_spe_evlwhe", SPE_BUILTIN_EVLWHE },
11778 { 0, CODE_FOR_spe_evlwhou, "__builtin_spe_evlwhou", SPE_BUILTIN_EVLWHOU },
11779 { 0, CODE_FOR_spe_evlwhos, "__builtin_spe_evlwhos", SPE_BUILTIN_EVLWHOS },
11780 { 0, CODE_FOR_spe_evlwwsplat, "__builtin_spe_evlwwsplat", SPE_BUILTIN_EVLWWSPLAT },
11781 { 0, CODE_FOR_spe_evlwhsplat, "__builtin_spe_evlwhsplat", SPE_BUILTIN_EVLWHSPLAT },
11782 { 0, CODE_FOR_spe_evlhhesplat, "__builtin_spe_evlhhesplat", SPE_BUILTIN_EVLHHESPLAT },
11783 { 0, CODE_FOR_spe_evlhhousplat, "__builtin_spe_evlhhousplat", SPE_BUILTIN_EVLHHOUSPLAT },
11784 { 0, CODE_FOR_spe_evlhhossplat, "__builtin_spe_evlhhossplat", SPE_BUILTIN_EVLHHOSSPLAT }
11787 /* Expand the builtin in EXP and store the result in TARGET. Store
11788 true in *EXPANDEDP if we found a builtin to expand.
11790 This expands the SPE builtins that are not simple unary and binary
11791 operations. */
11792 static rtx
11793 spe_expand_builtin (tree exp, rtx target, bool *expandedp)
11795 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11796 tree arg1, arg0;
11797 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11798 enum insn_code icode;
11799 enum machine_mode tmode, mode0;
11800 rtx pat, op0;
11801 struct builtin_description *d;
11802 size_t i;
11804 *expandedp = true;
11806 /* Syntax check for a 5-bit unsigned immediate. */
11807 switch (fcode)
11809 case SPE_BUILTIN_EVSTDD:
11810 case SPE_BUILTIN_EVSTDH:
11811 case SPE_BUILTIN_EVSTDW:
11812 case SPE_BUILTIN_EVSTWHE:
11813 case SPE_BUILTIN_EVSTWHO:
11814 case SPE_BUILTIN_EVSTWWE:
11815 case SPE_BUILTIN_EVSTWWO:
11816 arg1 = CALL_EXPR_ARG (exp, 2);
11817 if (TREE_CODE (arg1) != INTEGER_CST
11818 || TREE_INT_CST_LOW (arg1) & ~0x1f)
11820 error ("argument 2 must be a 5-bit unsigned literal");
11821 return const0_rtx;
11823 break;
11824 default:
11825 break;
11828 /* The evsplat*i instructions are not quite generic. */
11829 switch (fcode)
11831 case SPE_BUILTIN_EVSPLATFI:
11832 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplatfi,
11833 exp, target);
11834 case SPE_BUILTIN_EVSPLATI:
11835 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplati,
11836 exp, target);
11837 default:
11838 break;
11841 d = (struct builtin_description *) bdesc_2arg_spe;
11842 for (i = 0; i < ARRAY_SIZE (bdesc_2arg_spe); ++i, ++d)
11843 if (d->code == fcode)
11844 return rs6000_expand_binop_builtin (d->icode, exp, target);
11846 d = (struct builtin_description *) bdesc_spe_predicates;
11847 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, ++d)
11848 if (d->code == fcode)
11849 return spe_expand_predicate_builtin (d->icode, exp, target);
11851 d = (struct builtin_description *) bdesc_spe_evsel;
11852 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, ++d)
11853 if (d->code == fcode)
11854 return spe_expand_evsel_builtin (d->icode, exp, target);
11856 switch (fcode)
11858 case SPE_BUILTIN_EVSTDDX:
11859 return spe_expand_stv_builtin (CODE_FOR_spe_evstddx, exp);
11860 case SPE_BUILTIN_EVSTDHX:
11861 return spe_expand_stv_builtin (CODE_FOR_spe_evstdhx, exp);
11862 case SPE_BUILTIN_EVSTDWX:
11863 return spe_expand_stv_builtin (CODE_FOR_spe_evstdwx, exp);
11864 case SPE_BUILTIN_EVSTWHEX:
11865 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhex, exp);
11866 case SPE_BUILTIN_EVSTWHOX:
11867 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhox, exp);
11868 case SPE_BUILTIN_EVSTWWEX:
11869 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwex, exp);
11870 case SPE_BUILTIN_EVSTWWOX:
11871 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwox, exp);
11872 case SPE_BUILTIN_EVSTDD:
11873 return spe_expand_stv_builtin (CODE_FOR_spe_evstdd, exp);
11874 case SPE_BUILTIN_EVSTDH:
11875 return spe_expand_stv_builtin (CODE_FOR_spe_evstdh, exp);
11876 case SPE_BUILTIN_EVSTDW:
11877 return spe_expand_stv_builtin (CODE_FOR_spe_evstdw, exp);
11878 case SPE_BUILTIN_EVSTWHE:
11879 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhe, exp);
11880 case SPE_BUILTIN_EVSTWHO:
11881 return spe_expand_stv_builtin (CODE_FOR_spe_evstwho, exp);
11882 case SPE_BUILTIN_EVSTWWE:
11883 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwe, exp);
11884 case SPE_BUILTIN_EVSTWWO:
11885 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwo, exp);
11886 case SPE_BUILTIN_MFSPEFSCR:
11887 icode = CODE_FOR_spe_mfspefscr;
11888 tmode = insn_data[icode].operand[0].mode;
11890 if (target == 0
11891 || GET_MODE (target) != tmode
11892 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11893 target = gen_reg_rtx (tmode);
11895 pat = GEN_FCN (icode) (target);
11896 if (! pat)
11897 return 0;
11898 emit_insn (pat);
11899 return target;
11900 case SPE_BUILTIN_MTSPEFSCR:
11901 icode = CODE_FOR_spe_mtspefscr;
11902 arg0 = CALL_EXPR_ARG (exp, 0);
11903 op0 = expand_normal (arg0);
11904 mode0 = insn_data[icode].operand[0].mode;
11906 if (arg0 == error_mark_node)
11907 return const0_rtx;
11909 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
11910 op0 = copy_to_mode_reg (mode0, op0);
11912 pat = GEN_FCN (icode) (op0);
11913 if (pat)
11914 emit_insn (pat);
11915 return NULL_RTX;
11916 default:
11917 break;
11920 *expandedp = false;
11921 return NULL_RTX;
11924 static rtx
11925 paired_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
11927 rtx pat, scratch, tmp;
11928 tree form = CALL_EXPR_ARG (exp, 0);
11929 tree arg0 = CALL_EXPR_ARG (exp, 1);
11930 tree arg1 = CALL_EXPR_ARG (exp, 2);
11931 rtx op0 = expand_normal (arg0);
11932 rtx op1 = expand_normal (arg1);
11933 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
11934 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
11935 int form_int;
11936 enum rtx_code code;
11938 if (TREE_CODE (form) != INTEGER_CST)
11940 error ("argument 1 of __builtin_paired_predicate must be a constant");
11941 return const0_rtx;
11943 else
11944 form_int = TREE_INT_CST_LOW (form);
11946 gcc_assert (mode0 == mode1);
11948 if (arg0 == error_mark_node || arg1 == error_mark_node)
11949 return const0_rtx;
11951 if (target == 0
11952 || GET_MODE (target) != SImode
11953 || !(*insn_data[icode].operand[0].predicate) (target, SImode))
11954 target = gen_reg_rtx (SImode);
11955 if (!(*insn_data[icode].operand[1].predicate) (op0, mode0))
11956 op0 = copy_to_mode_reg (mode0, op0);
11957 if (!(*insn_data[icode].operand[2].predicate) (op1, mode1))
11958 op1 = copy_to_mode_reg (mode1, op1);
11960 scratch = gen_reg_rtx (CCFPmode);
11962 pat = GEN_FCN (icode) (scratch, op0, op1);
11963 if (!pat)
11964 return const0_rtx;
11966 emit_insn (pat);
11968 switch (form_int)
11970 /* LT bit. */
11971 case 0:
11972 code = LT;
11973 break;
11974 /* GT bit. */
11975 case 1:
11976 code = GT;
11977 break;
11978 /* EQ bit. */
11979 case 2:
11980 code = EQ;
11981 break;
11982 /* UN bit. */
11983 case 3:
11984 emit_insn (gen_move_from_CR_ov_bit (target, scratch));
11985 return target;
11986 default:
11987 error ("argument 1 of __builtin_paired_predicate is out of range");
11988 return const0_rtx;
11991 tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx);
11992 emit_move_insn (target, tmp);
11993 return target;
11996 static rtx
11997 spe_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
11999 rtx pat, scratch, tmp;
12000 tree form = CALL_EXPR_ARG (exp, 0);
12001 tree arg0 = CALL_EXPR_ARG (exp, 1);
12002 tree arg1 = CALL_EXPR_ARG (exp, 2);
12003 rtx op0 = expand_normal (arg0);
12004 rtx op1 = expand_normal (arg1);
12005 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
12006 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
12007 int form_int;
12008 enum rtx_code code;
12010 if (TREE_CODE (form) != INTEGER_CST)
12012 error ("argument 1 of __builtin_spe_predicate must be a constant");
12013 return const0_rtx;
12015 else
12016 form_int = TREE_INT_CST_LOW (form);
12018 gcc_assert (mode0 == mode1);
12020 if (arg0 == error_mark_node || arg1 == error_mark_node)
12021 return const0_rtx;
12023 if (target == 0
12024 || GET_MODE (target) != SImode
12025 || ! (*insn_data[icode].operand[0].predicate) (target, SImode))
12026 target = gen_reg_rtx (SImode);
12028 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
12029 op0 = copy_to_mode_reg (mode0, op0);
12030 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
12031 op1 = copy_to_mode_reg (mode1, op1);
12033 scratch = gen_reg_rtx (CCmode);
12035 pat = GEN_FCN (icode) (scratch, op0, op1);
12036 if (! pat)
12037 return const0_rtx;
12038 emit_insn (pat);
12040 /* There are 4 variants for each predicate: _any_, _all_, _upper_,
12041 _lower_. We use one compare, but look in different bits of the
12042 CR for each variant.
12044 There are 2 elements in each SPE simd type (upper/lower). The CR
12045 bits are set as follows:
12047 BIT0 | BIT 1 | BIT 2 | BIT 3
12048 U | L | (U | L) | (U & L)
12050 So, for an "all" relationship, BIT 3 would be set.
12051 For an "any" relationship, BIT 2 would be set. Etc.
12053 Following traditional nomenclature, these bits map to:
12055 BIT0 | BIT 1 | BIT 2 | BIT 3
12056 LT | GT | EQ | OV
12058 Later, we will generate rtl to look in the LT/EQ/EQ/OV bits.
12061 switch (form_int)
12063 /* All variant. OV bit. */
12064 case 0:
12065 /* We need to get to the OV bit, which is the ORDERED bit. We
12066 could generate (ordered:SI (reg:CC xx) (const_int 0)), but
12067 that's ugly and will make validate_condition_mode die.
12068 So let's just use another pattern. */
12069 emit_insn (gen_move_from_CR_ov_bit (target, scratch));
12070 return target;
12071 /* Any variant. EQ bit. */
12072 case 1:
12073 code = EQ;
12074 break;
12075 /* Upper variant. LT bit. */
12076 case 2:
12077 code = LT;
12078 break;
12079 /* Lower variant. GT bit. */
12080 case 3:
12081 code = GT;
12082 break;
12083 default:
12084 error ("argument 1 of __builtin_spe_predicate is out of range");
12085 return const0_rtx;
12088 tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx);
12089 emit_move_insn (target, tmp);
12091 return target;
12094 /* The evsel builtins look like this:
12096 e = __builtin_spe_evsel_OP (a, b, c, d);
12098 and work like this:
12100 e[upper] = a[upper] *OP* b[upper] ? c[upper] : d[upper];
12101 e[lower] = a[lower] *OP* b[lower] ? c[lower] : d[lower];
12104 static rtx
12105 spe_expand_evsel_builtin (enum insn_code icode, tree exp, rtx target)
12107 rtx pat, scratch;
12108 tree arg0 = CALL_EXPR_ARG (exp, 0);
12109 tree arg1 = CALL_EXPR_ARG (exp, 1);
12110 tree arg2 = CALL_EXPR_ARG (exp, 2);
12111 tree arg3 = CALL_EXPR_ARG (exp, 3);
12112 rtx op0 = expand_normal (arg0);
12113 rtx op1 = expand_normal (arg1);
12114 rtx op2 = expand_normal (arg2);
12115 rtx op3 = expand_normal (arg3);
12116 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
12117 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
12119 gcc_assert (mode0 == mode1);
12121 if (arg0 == error_mark_node || arg1 == error_mark_node
12122 || arg2 == error_mark_node || arg3 == error_mark_node)
12123 return const0_rtx;
12125 if (target == 0
12126 || GET_MODE (target) != mode0
12127 || ! (*insn_data[icode].operand[0].predicate) (target, mode0))
12128 target = gen_reg_rtx (mode0);
12130 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
12131 op0 = copy_to_mode_reg (mode0, op0);
12132 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
12133 op1 = copy_to_mode_reg (mode0, op1);
12134 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
12135 op2 = copy_to_mode_reg (mode0, op2);
12136 if (! (*insn_data[icode].operand[1].predicate) (op3, mode1))
12137 op3 = copy_to_mode_reg (mode0, op3);
12139 /* Generate the compare. */
12140 scratch = gen_reg_rtx (CCmode);
12141 pat = GEN_FCN (icode) (scratch, op0, op1);
12142 if (! pat)
12143 return const0_rtx;
12144 emit_insn (pat);
12146 if (mode0 == V2SImode)
12147 emit_insn (gen_spe_evsel (target, op2, op3, scratch));
12148 else
12149 emit_insn (gen_spe_evsel_fs (target, op2, op3, scratch));
12151 return target;
12154 /* Expand an expression EXP that calls a built-in function,
12155 with result going to TARGET if that's convenient
12156 (and in mode MODE if that's convenient).
12157 SUBTARGET may be used as the target for computing one of EXP's operands.
12158 IGNORE is nonzero if the value is to be ignored. */
12160 static rtx
12161 rs6000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
12162 enum machine_mode mode ATTRIBUTE_UNUSED,
12163 int ignore ATTRIBUTE_UNUSED)
12165 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
12166 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
12167 const struct builtin_description *d;
12168 size_t i;
12169 rtx ret;
12170 bool success;
12172 switch (fcode)
12174 case RS6000_BUILTIN_RECIP:
12175 return rs6000_expand_binop_builtin (CODE_FOR_recipdf3, exp, target);
12177 case RS6000_BUILTIN_RECIPF:
12178 return rs6000_expand_binop_builtin (CODE_FOR_recipsf3, exp, target);
12180 case RS6000_BUILTIN_RSQRTF:
12181 return rs6000_expand_unop_builtin (CODE_FOR_rsqrtsf2, exp, target);
12183 case RS6000_BUILTIN_RSQRT:
12184 return rs6000_expand_unop_builtin (CODE_FOR_rsqrtdf2, exp, target);
12186 case RS6000_BUILTIN_BSWAP_HI:
12187 return rs6000_expand_unop_builtin (CODE_FOR_bswaphi2, exp, target);
12189 case POWER7_BUILTIN_BPERMD:
12190 return rs6000_expand_binop_builtin (((TARGET_64BIT)
12191 ? CODE_FOR_bpermd_di
12192 : CODE_FOR_bpermd_si), exp, target);
12194 case ALTIVEC_BUILTIN_MASK_FOR_LOAD:
12195 case ALTIVEC_BUILTIN_MASK_FOR_STORE:
12197 int icode = (int) CODE_FOR_altivec_lvsr;
12198 enum machine_mode tmode = insn_data[icode].operand[0].mode;
12199 enum machine_mode mode = insn_data[icode].operand[1].mode;
12200 tree arg;
12201 rtx op, addr, pat;
12203 gcc_assert (TARGET_ALTIVEC);
12205 arg = CALL_EXPR_ARG (exp, 0);
12206 gcc_assert (POINTER_TYPE_P (TREE_TYPE (arg)));
12207 op = expand_expr (arg, NULL_RTX, Pmode, EXPAND_NORMAL);
12208 addr = memory_address (mode, op);
12209 if (fcode == ALTIVEC_BUILTIN_MASK_FOR_STORE)
12210 op = addr;
12211 else
12213 /* For the load case need to negate the address. */
12214 op = gen_reg_rtx (GET_MODE (addr));
12215 emit_insn (gen_rtx_SET (VOIDmode, op,
12216 gen_rtx_NEG (GET_MODE (addr), addr)));
12218 op = gen_rtx_MEM (mode, op);
12220 if (target == 0
12221 || GET_MODE (target) != tmode
12222 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
12223 target = gen_reg_rtx (tmode);
12225 /*pat = gen_altivec_lvsr (target, op);*/
12226 pat = GEN_FCN (icode) (target, op);
12227 if (!pat)
12228 return 0;
12229 emit_insn (pat);
12231 return target;
12234 case ALTIVEC_BUILTIN_VCFUX:
12235 case ALTIVEC_BUILTIN_VCFSX:
12236 case ALTIVEC_BUILTIN_VCTUXS:
12237 case ALTIVEC_BUILTIN_VCTSXS:
12238 /* FIXME: There's got to be a nicer way to handle this case than
12239 constructing a new CALL_EXPR. */
12240 if (call_expr_nargs (exp) == 1)
12242 exp = build_call_nary (TREE_TYPE (exp), CALL_EXPR_FN (exp),
12243 2, CALL_EXPR_ARG (exp, 0), integer_zero_node);
12245 break;
12247 default:
12248 break;
12251 if (TARGET_ALTIVEC)
12253 ret = altivec_expand_builtin (exp, target, &success);
12255 if (success)
12256 return ret;
12258 if (TARGET_SPE)
12260 ret = spe_expand_builtin (exp, target, &success);
12262 if (success)
12263 return ret;
12265 if (TARGET_PAIRED_FLOAT)
12267 ret = paired_expand_builtin (exp, target, &success);
12269 if (success)
12270 return ret;
12273 gcc_assert (TARGET_ALTIVEC || TARGET_VSX || TARGET_SPE || TARGET_PAIRED_FLOAT);
12275 /* Handle simple unary operations. */
12276 d = (struct builtin_description *) bdesc_1arg;
12277 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
12278 if (d->code == fcode)
12279 return rs6000_expand_unop_builtin (d->icode, exp, target);
12281 /* Handle simple binary operations. */
12282 d = (struct builtin_description *) bdesc_2arg;
12283 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
12284 if (d->code == fcode)
12285 return rs6000_expand_binop_builtin (d->icode, exp, target);
12287 /* Handle simple ternary operations. */
12288 d = bdesc_3arg;
12289 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
12290 if (d->code == fcode)
12291 return rs6000_expand_ternop_builtin (d->icode, exp, target);
12293 gcc_unreachable ();
12296 static void
12297 rs6000_init_builtins (void)
12299 tree tdecl;
12300 tree ftype;
12302 V2SI_type_node = build_vector_type (intSI_type_node, 2);
12303 V2SF_type_node = build_vector_type (float_type_node, 2);
12304 V2DI_type_node = build_vector_type (intDI_type_node, 2);
12305 V2DF_type_node = build_vector_type (double_type_node, 2);
12306 V4HI_type_node = build_vector_type (intHI_type_node, 4);
12307 V4SI_type_node = build_vector_type (intSI_type_node, 4);
12308 V4SF_type_node = build_vector_type (float_type_node, 4);
12309 V8HI_type_node = build_vector_type (intHI_type_node, 8);
12310 V16QI_type_node = build_vector_type (intQI_type_node, 16);
12312 unsigned_V16QI_type_node = build_vector_type (unsigned_intQI_type_node, 16);
12313 unsigned_V8HI_type_node = build_vector_type (unsigned_intHI_type_node, 8);
12314 unsigned_V4SI_type_node = build_vector_type (unsigned_intSI_type_node, 4);
12315 unsigned_V2DI_type_node = build_vector_type (unsigned_intDI_type_node, 2);
12317 opaque_V2SF_type_node = build_opaque_vector_type (float_type_node, 2);
12318 opaque_V2SI_type_node = build_opaque_vector_type (intSI_type_node, 2);
12319 opaque_p_V2SI_type_node = build_pointer_type (opaque_V2SI_type_node);
12320 opaque_V4SI_type_node = build_opaque_vector_type (intSI_type_node, 4);
12322 /* The 'vector bool ...' types must be kept distinct from 'vector unsigned ...'
12323 types, especially in C++ land. Similarly, 'vector pixel' is distinct from
12324 'vector unsigned short'. */
12326 bool_char_type_node = build_distinct_type_copy (unsigned_intQI_type_node);
12327 bool_short_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
12328 bool_int_type_node = build_distinct_type_copy (unsigned_intSI_type_node);
12329 bool_long_type_node = build_distinct_type_copy (unsigned_intDI_type_node);
12330 pixel_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
12332 long_integer_type_internal_node = long_integer_type_node;
12333 long_unsigned_type_internal_node = long_unsigned_type_node;
12334 intQI_type_internal_node = intQI_type_node;
12335 uintQI_type_internal_node = unsigned_intQI_type_node;
12336 intHI_type_internal_node = intHI_type_node;
12337 uintHI_type_internal_node = unsigned_intHI_type_node;
12338 intSI_type_internal_node = intSI_type_node;
12339 uintSI_type_internal_node = unsigned_intSI_type_node;
12340 intDI_type_internal_node = intDI_type_node;
12341 uintDI_type_internal_node = unsigned_intDI_type_node;
12342 float_type_internal_node = float_type_node;
12343 double_type_internal_node = float_type_node;
12344 void_type_internal_node = void_type_node;
12346 /* Initialize the modes for builtin_function_type, mapping a machine mode to
12347 tree type node. */
12348 builtin_mode_to_type[QImode][0] = integer_type_node;
12349 builtin_mode_to_type[HImode][0] = integer_type_node;
12350 builtin_mode_to_type[SImode][0] = intSI_type_node;
12351 builtin_mode_to_type[SImode][1] = unsigned_intSI_type_node;
12352 builtin_mode_to_type[DImode][0] = intDI_type_node;
12353 builtin_mode_to_type[DImode][1] = unsigned_intDI_type_node;
12354 builtin_mode_to_type[SFmode][0] = float_type_node;
12355 builtin_mode_to_type[DFmode][0] = double_type_node;
12356 builtin_mode_to_type[V2SImode][0] = V2SI_type_node;
12357 builtin_mode_to_type[V2SFmode][0] = V2SF_type_node;
12358 builtin_mode_to_type[V2DImode][0] = V2DI_type_node;
12359 builtin_mode_to_type[V2DImode][1] = unsigned_V2DI_type_node;
12360 builtin_mode_to_type[V2DFmode][0] = V2DF_type_node;
12361 builtin_mode_to_type[V4HImode][0] = V4HI_type_node;
12362 builtin_mode_to_type[V4SImode][0] = V4SI_type_node;
12363 builtin_mode_to_type[V4SImode][1] = unsigned_V4SI_type_node;
12364 builtin_mode_to_type[V4SFmode][0] = V4SF_type_node;
12365 builtin_mode_to_type[V8HImode][0] = V8HI_type_node;
12366 builtin_mode_to_type[V8HImode][1] = unsigned_V8HI_type_node;
12367 builtin_mode_to_type[V16QImode][0] = V16QI_type_node;
12368 builtin_mode_to_type[V16QImode][1] = unsigned_V16QI_type_node;
12370 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12371 get_identifier ("__bool char"),
12372 bool_char_type_node);
12373 TYPE_NAME (bool_char_type_node) = tdecl;
12374 (*lang_hooks.decls.pushdecl) (tdecl);
12375 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12376 get_identifier ("__bool short"),
12377 bool_short_type_node);
12378 TYPE_NAME (bool_short_type_node) = tdecl;
12379 (*lang_hooks.decls.pushdecl) (tdecl);
12380 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12381 get_identifier ("__bool int"),
12382 bool_int_type_node);
12383 TYPE_NAME (bool_int_type_node) = tdecl;
12384 (*lang_hooks.decls.pushdecl) (tdecl);
12385 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL, get_identifier ("__pixel"),
12386 pixel_type_node);
12387 TYPE_NAME (pixel_type_node) = tdecl;
12388 (*lang_hooks.decls.pushdecl) (tdecl);
12390 bool_V16QI_type_node = build_vector_type (bool_char_type_node, 16);
12391 bool_V8HI_type_node = build_vector_type (bool_short_type_node, 8);
12392 bool_V4SI_type_node = build_vector_type (bool_int_type_node, 4);
12393 bool_V2DI_type_node = build_vector_type (bool_long_type_node, 2);
12394 pixel_V8HI_type_node = build_vector_type (pixel_type_node, 8);
12396 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12397 get_identifier ("__vector unsigned char"),
12398 unsigned_V16QI_type_node);
12399 TYPE_NAME (unsigned_V16QI_type_node) = tdecl;
12400 (*lang_hooks.decls.pushdecl) (tdecl);
12401 tdecl = build_decl (BUILTINS_LOCATION,
12402 TYPE_DECL, get_identifier ("__vector signed char"),
12403 V16QI_type_node);
12404 TYPE_NAME (V16QI_type_node) = tdecl;
12405 (*lang_hooks.decls.pushdecl) (tdecl);
12406 tdecl = build_decl (BUILTINS_LOCATION,
12407 TYPE_DECL, get_identifier ("__vector __bool char"),
12408 bool_V16QI_type_node);
12409 TYPE_NAME ( bool_V16QI_type_node) = tdecl;
12410 (*lang_hooks.decls.pushdecl) (tdecl);
12412 tdecl = build_decl (BUILTINS_LOCATION,
12413 TYPE_DECL, get_identifier ("__vector unsigned short"),
12414 unsigned_V8HI_type_node);
12415 TYPE_NAME (unsigned_V8HI_type_node) = tdecl;
12416 (*lang_hooks.decls.pushdecl) (tdecl);
12417 tdecl = build_decl (BUILTINS_LOCATION,
12418 TYPE_DECL, get_identifier ("__vector signed short"),
12419 V8HI_type_node);
12420 TYPE_NAME (V8HI_type_node) = tdecl;
12421 (*lang_hooks.decls.pushdecl) (tdecl);
12422 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12423 get_identifier ("__vector __bool short"),
12424 bool_V8HI_type_node);
12425 TYPE_NAME (bool_V8HI_type_node) = tdecl;
12426 (*lang_hooks.decls.pushdecl) (tdecl);
12428 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12429 get_identifier ("__vector unsigned int"),
12430 unsigned_V4SI_type_node);
12431 TYPE_NAME (unsigned_V4SI_type_node) = tdecl;
12432 (*lang_hooks.decls.pushdecl) (tdecl);
12433 tdecl = build_decl (BUILTINS_LOCATION,
12434 TYPE_DECL, get_identifier ("__vector signed int"),
12435 V4SI_type_node);
12436 TYPE_NAME (V4SI_type_node) = tdecl;
12437 (*lang_hooks.decls.pushdecl) (tdecl);
12438 tdecl = build_decl (BUILTINS_LOCATION,
12439 TYPE_DECL, get_identifier ("__vector __bool int"),
12440 bool_V4SI_type_node);
12441 TYPE_NAME (bool_V4SI_type_node) = tdecl;
12442 (*lang_hooks.decls.pushdecl) (tdecl);
12444 tdecl = build_decl (BUILTINS_LOCATION,
12445 TYPE_DECL, get_identifier ("__vector float"),
12446 V4SF_type_node);
12447 TYPE_NAME (V4SF_type_node) = tdecl;
12448 (*lang_hooks.decls.pushdecl) (tdecl);
12449 tdecl = build_decl (BUILTINS_LOCATION,
12450 TYPE_DECL, get_identifier ("__vector __pixel"),
12451 pixel_V8HI_type_node);
12452 TYPE_NAME (pixel_V8HI_type_node) = tdecl;
12453 (*lang_hooks.decls.pushdecl) (tdecl);
12455 if (TARGET_VSX)
12457 tdecl = build_decl (BUILTINS_LOCATION,
12458 TYPE_DECL, get_identifier ("__vector double"),
12459 V2DF_type_node);
12460 TYPE_NAME (V2DF_type_node) = tdecl;
12461 (*lang_hooks.decls.pushdecl) (tdecl);
12463 tdecl = build_decl (BUILTINS_LOCATION,
12464 TYPE_DECL, get_identifier ("__vector long"),
12465 V2DI_type_node);
12466 TYPE_NAME (V2DI_type_node) = tdecl;
12467 (*lang_hooks.decls.pushdecl) (tdecl);
12469 tdecl = build_decl (BUILTINS_LOCATION,
12470 TYPE_DECL, get_identifier ("__vector unsigned long"),
12471 unsigned_V2DI_type_node);
12472 TYPE_NAME (unsigned_V2DI_type_node) = tdecl;
12473 (*lang_hooks.decls.pushdecl) (tdecl);
12475 tdecl = build_decl (BUILTINS_LOCATION,
12476 TYPE_DECL, get_identifier ("__vector __bool long"),
12477 bool_V2DI_type_node);
12478 TYPE_NAME (bool_V2DI_type_node) = tdecl;
12479 (*lang_hooks.decls.pushdecl) (tdecl);
12482 if (TARGET_PAIRED_FLOAT)
12483 paired_init_builtins ();
12484 if (TARGET_SPE)
12485 spe_init_builtins ();
12486 if (TARGET_ALTIVEC)
12487 altivec_init_builtins ();
12488 if (TARGET_ALTIVEC || TARGET_SPE || TARGET_PAIRED_FLOAT || TARGET_VSX)
12489 rs6000_common_init_builtins ();
12490 if (TARGET_FRE)
12492 ftype = builtin_function_type (DFmode, DFmode, DFmode, VOIDmode,
12493 RS6000_BUILTIN_RECIP,
12494 "__builtin_recipdiv");
12495 def_builtin (MASK_POPCNTB, "__builtin_recipdiv", ftype,
12496 RS6000_BUILTIN_RECIP);
12498 if (TARGET_FRES)
12500 ftype = builtin_function_type (SFmode, SFmode, SFmode, VOIDmode,
12501 RS6000_BUILTIN_RECIPF,
12502 "__builtin_recipdivf");
12503 def_builtin (MASK_PPC_GFXOPT, "__builtin_recipdivf", ftype,
12504 RS6000_BUILTIN_RECIPF);
12506 if (TARGET_FRSQRTE)
12508 ftype = builtin_function_type (DFmode, DFmode, VOIDmode, VOIDmode,
12509 RS6000_BUILTIN_RSQRT,
12510 "__builtin_rsqrt");
12511 def_builtin (MASK_PPC_GFXOPT, "__builtin_rsqrt", ftype,
12512 RS6000_BUILTIN_RSQRT);
12514 if (TARGET_FRSQRTES)
12516 ftype = builtin_function_type (SFmode, SFmode, VOIDmode, VOIDmode,
12517 RS6000_BUILTIN_RSQRTF,
12518 "__builtin_rsqrtf");
12519 def_builtin (MASK_PPC_GFXOPT, "__builtin_rsqrtf", ftype,
12520 RS6000_BUILTIN_RSQRTF);
12522 if (TARGET_POPCNTD)
12524 enum machine_mode mode = (TARGET_64BIT) ? DImode : SImode;
12525 tree ftype = builtin_function_type (mode, mode, mode, VOIDmode,
12526 POWER7_BUILTIN_BPERMD,
12527 "__builtin_bpermd");
12528 def_builtin (MASK_POPCNTD, "__builtin_bpermd", ftype,
12529 POWER7_BUILTIN_BPERMD);
12531 if (TARGET_POWERPC)
12533 /* Don't use builtin_function_type here, as it maps HI/QI to SI. */
12534 tree ftype = build_function_type_list (unsigned_intHI_type_node,
12535 unsigned_intHI_type_node,
12536 NULL_TREE);
12537 def_builtin (MASK_POWERPC, "__builtin_bswap16", ftype,
12538 RS6000_BUILTIN_BSWAP_HI);
12541 #if TARGET_XCOFF
12542 /* AIX libm provides clog as __clog. */
12543 if (built_in_decls [BUILT_IN_CLOG])
12544 set_user_assembler_name (built_in_decls [BUILT_IN_CLOG], "__clog");
12545 #endif
12547 #ifdef SUBTARGET_INIT_BUILTINS
12548 SUBTARGET_INIT_BUILTINS;
12549 #endif
12552 /* Returns the rs6000 builtin decl for CODE. */
12554 static tree
12555 rs6000_builtin_decl (unsigned code, bool initialize_p ATTRIBUTE_UNUSED)
12557 if (code >= RS6000_BUILTIN_COUNT)
12558 return error_mark_node;
12560 return rs6000_builtin_decls[code];
12563 /* Search through a set of builtins and enable the mask bits.
12564 DESC is an array of builtins.
12565 SIZE is the total number of builtins.
12566 START is the builtin enum at which to start.
12567 END is the builtin enum at which to end. */
12568 static void
12569 enable_mask_for_builtins (struct builtin_description *desc, int size,
12570 enum rs6000_builtins start,
12571 enum rs6000_builtins end)
12573 int i;
12575 for (i = 0; i < size; ++i)
12576 if (desc[i].code == start)
12577 break;
12579 if (i == size)
12580 return;
12582 for (; i < size; ++i)
12584 /* Flip all the bits on. */
12585 desc[i].mask = target_flags;
12586 if (desc[i].code == end)
12587 break;
12591 static void
12592 spe_init_builtins (void)
12594 tree endlink = void_list_node;
12595 tree puint_type_node = build_pointer_type (unsigned_type_node);
12596 tree pushort_type_node = build_pointer_type (short_unsigned_type_node);
12597 struct builtin_description *d;
12598 size_t i;
12600 tree v2si_ftype_4_v2si
12601 = build_function_type
12602 (opaque_V2SI_type_node,
12603 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12604 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12605 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12606 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12607 endlink)))));
12609 tree v2sf_ftype_4_v2sf
12610 = build_function_type
12611 (opaque_V2SF_type_node,
12612 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12613 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12614 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12615 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12616 endlink)))));
12618 tree int_ftype_int_v2si_v2si
12619 = build_function_type
12620 (integer_type_node,
12621 tree_cons (NULL_TREE, integer_type_node,
12622 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12623 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12624 endlink))));
12626 tree int_ftype_int_v2sf_v2sf
12627 = build_function_type
12628 (integer_type_node,
12629 tree_cons (NULL_TREE, integer_type_node,
12630 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12631 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12632 endlink))));
12634 tree void_ftype_v2si_puint_int
12635 = build_function_type (void_type_node,
12636 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12637 tree_cons (NULL_TREE, puint_type_node,
12638 tree_cons (NULL_TREE,
12639 integer_type_node,
12640 endlink))));
12642 tree void_ftype_v2si_puint_char
12643 = build_function_type (void_type_node,
12644 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12645 tree_cons (NULL_TREE, puint_type_node,
12646 tree_cons (NULL_TREE,
12647 char_type_node,
12648 endlink))));
12650 tree void_ftype_v2si_pv2si_int
12651 = build_function_type (void_type_node,
12652 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12653 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
12654 tree_cons (NULL_TREE,
12655 integer_type_node,
12656 endlink))));
12658 tree void_ftype_v2si_pv2si_char
12659 = build_function_type (void_type_node,
12660 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12661 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
12662 tree_cons (NULL_TREE,
12663 char_type_node,
12664 endlink))));
12666 tree void_ftype_int
12667 = build_function_type (void_type_node,
12668 tree_cons (NULL_TREE, integer_type_node, endlink));
12670 tree int_ftype_void
12671 = build_function_type (integer_type_node, endlink);
12673 tree v2si_ftype_pv2si_int
12674 = build_function_type (opaque_V2SI_type_node,
12675 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
12676 tree_cons (NULL_TREE, integer_type_node,
12677 endlink)));
12679 tree v2si_ftype_puint_int
12680 = build_function_type (opaque_V2SI_type_node,
12681 tree_cons (NULL_TREE, puint_type_node,
12682 tree_cons (NULL_TREE, integer_type_node,
12683 endlink)));
12685 tree v2si_ftype_pushort_int
12686 = build_function_type (opaque_V2SI_type_node,
12687 tree_cons (NULL_TREE, pushort_type_node,
12688 tree_cons (NULL_TREE, integer_type_node,
12689 endlink)));
12691 tree v2si_ftype_signed_char
12692 = build_function_type (opaque_V2SI_type_node,
12693 tree_cons (NULL_TREE, signed_char_type_node,
12694 endlink));
12696 /* The initialization of the simple binary and unary builtins is
12697 done in rs6000_common_init_builtins, but we have to enable the
12698 mask bits here manually because we have run out of `target_flags'
12699 bits. We really need to redesign this mask business. */
12701 enable_mask_for_builtins ((struct builtin_description *) bdesc_2arg,
12702 ARRAY_SIZE (bdesc_2arg),
12703 SPE_BUILTIN_EVADDW,
12704 SPE_BUILTIN_EVXOR);
12705 enable_mask_for_builtins ((struct builtin_description *) bdesc_1arg,
12706 ARRAY_SIZE (bdesc_1arg),
12707 SPE_BUILTIN_EVABS,
12708 SPE_BUILTIN_EVSUBFUSIAAW);
12709 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_predicates,
12710 ARRAY_SIZE (bdesc_spe_predicates),
12711 SPE_BUILTIN_EVCMPEQ,
12712 SPE_BUILTIN_EVFSTSTLT);
12713 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_evsel,
12714 ARRAY_SIZE (bdesc_spe_evsel),
12715 SPE_BUILTIN_EVSEL_CMPGTS,
12716 SPE_BUILTIN_EVSEL_FSTSTEQ);
12718 (*lang_hooks.decls.pushdecl)
12719 (build_decl (BUILTINS_LOCATION, TYPE_DECL,
12720 get_identifier ("__ev64_opaque__"),
12721 opaque_V2SI_type_node));
12723 /* Initialize irregular SPE builtins. */
12725 def_builtin (target_flags, "__builtin_spe_mtspefscr", void_ftype_int, SPE_BUILTIN_MTSPEFSCR);
12726 def_builtin (target_flags, "__builtin_spe_mfspefscr", int_ftype_void, SPE_BUILTIN_MFSPEFSCR);
12727 def_builtin (target_flags, "__builtin_spe_evstddx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDDX);
12728 def_builtin (target_flags, "__builtin_spe_evstdhx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDHX);
12729 def_builtin (target_flags, "__builtin_spe_evstdwx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDWX);
12730 def_builtin (target_flags, "__builtin_spe_evstwhex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHEX);
12731 def_builtin (target_flags, "__builtin_spe_evstwhox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHOX);
12732 def_builtin (target_flags, "__builtin_spe_evstwwex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWEX);
12733 def_builtin (target_flags, "__builtin_spe_evstwwox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWOX);
12734 def_builtin (target_flags, "__builtin_spe_evstdd", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDD);
12735 def_builtin (target_flags, "__builtin_spe_evstdh", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDH);
12736 def_builtin (target_flags, "__builtin_spe_evstdw", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDW);
12737 def_builtin (target_flags, "__builtin_spe_evstwhe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHE);
12738 def_builtin (target_flags, "__builtin_spe_evstwho", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHO);
12739 def_builtin (target_flags, "__builtin_spe_evstwwe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWE);
12740 def_builtin (target_flags, "__builtin_spe_evstwwo", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWO);
12741 def_builtin (target_flags, "__builtin_spe_evsplatfi", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATFI);
12742 def_builtin (target_flags, "__builtin_spe_evsplati", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATI);
12744 /* Loads. */
12745 def_builtin (target_flags, "__builtin_spe_evlddx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDDX);
12746 def_builtin (target_flags, "__builtin_spe_evldwx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDWX);
12747 def_builtin (target_flags, "__builtin_spe_evldhx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDHX);
12748 def_builtin (target_flags, "__builtin_spe_evlwhex", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHEX);
12749 def_builtin (target_flags, "__builtin_spe_evlwhoux", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOUX);
12750 def_builtin (target_flags, "__builtin_spe_evlwhosx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOSX);
12751 def_builtin (target_flags, "__builtin_spe_evlwwsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLATX);
12752 def_builtin (target_flags, "__builtin_spe_evlwhsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLATX);
12753 def_builtin (target_flags, "__builtin_spe_evlhhesplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLATX);
12754 def_builtin (target_flags, "__builtin_spe_evlhhousplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLATX);
12755 def_builtin (target_flags, "__builtin_spe_evlhhossplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLATX);
12756 def_builtin (target_flags, "__builtin_spe_evldd", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDD);
12757 def_builtin (target_flags, "__builtin_spe_evldw", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDW);
12758 def_builtin (target_flags, "__builtin_spe_evldh", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDH);
12759 def_builtin (target_flags, "__builtin_spe_evlhhesplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLAT);
12760 def_builtin (target_flags, "__builtin_spe_evlhhossplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLAT);
12761 def_builtin (target_flags, "__builtin_spe_evlhhousplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLAT);
12762 def_builtin (target_flags, "__builtin_spe_evlwhe", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHE);
12763 def_builtin (target_flags, "__builtin_spe_evlwhos", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOS);
12764 def_builtin (target_flags, "__builtin_spe_evlwhou", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOU);
12765 def_builtin (target_flags, "__builtin_spe_evlwhsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLAT);
12766 def_builtin (target_flags, "__builtin_spe_evlwwsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLAT);
12768 /* Predicates. */
12769 d = (struct builtin_description *) bdesc_spe_predicates;
12770 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, d++)
12772 tree type;
12774 switch (insn_data[d->icode].operand[1].mode)
12776 case V2SImode:
12777 type = int_ftype_int_v2si_v2si;
12778 break;
12779 case V2SFmode:
12780 type = int_ftype_int_v2sf_v2sf;
12781 break;
12782 default:
12783 gcc_unreachable ();
12786 def_builtin (d->mask, d->name, type, d->code);
12789 /* Evsel predicates. */
12790 d = (struct builtin_description *) bdesc_spe_evsel;
12791 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, d++)
12793 tree type;
12795 switch (insn_data[d->icode].operand[1].mode)
12797 case V2SImode:
12798 type = v2si_ftype_4_v2si;
12799 break;
12800 case V2SFmode:
12801 type = v2sf_ftype_4_v2sf;
12802 break;
12803 default:
12804 gcc_unreachable ();
12807 def_builtin (d->mask, d->name, type, d->code);
12811 static void
12812 paired_init_builtins (void)
12814 const struct builtin_description *d;
12815 size_t i;
12816 tree endlink = void_list_node;
12818 tree int_ftype_int_v2sf_v2sf
12819 = build_function_type
12820 (integer_type_node,
12821 tree_cons (NULL_TREE, integer_type_node,
12822 tree_cons (NULL_TREE, V2SF_type_node,
12823 tree_cons (NULL_TREE, V2SF_type_node,
12824 endlink))));
12825 tree pcfloat_type_node =
12826 build_pointer_type (build_qualified_type
12827 (float_type_node, TYPE_QUAL_CONST));
12829 tree v2sf_ftype_long_pcfloat = build_function_type_list (V2SF_type_node,
12830 long_integer_type_node,
12831 pcfloat_type_node,
12832 NULL_TREE);
12833 tree void_ftype_v2sf_long_pcfloat =
12834 build_function_type_list (void_type_node,
12835 V2SF_type_node,
12836 long_integer_type_node,
12837 pcfloat_type_node,
12838 NULL_TREE);
12841 def_builtin (0, "__builtin_paired_lx", v2sf_ftype_long_pcfloat,
12842 PAIRED_BUILTIN_LX);
12845 def_builtin (0, "__builtin_paired_stx", void_ftype_v2sf_long_pcfloat,
12846 PAIRED_BUILTIN_STX);
12848 /* Predicates. */
12849 d = bdesc_paired_preds;
12850 for (i = 0; i < ARRAY_SIZE (bdesc_paired_preds); ++i, d++)
12852 tree type;
12854 switch (insn_data[d->icode].operand[1].mode)
12856 case V2SFmode:
12857 type = int_ftype_int_v2sf_v2sf;
12858 break;
12859 default:
12860 gcc_unreachable ();
12863 def_builtin (d->mask, d->name, type, d->code);
12867 static void
12868 altivec_init_builtins (void)
12870 const struct builtin_description *d;
12871 const struct builtin_description_predicates *dp;
12872 size_t i;
12873 tree ftype;
12875 tree pfloat_type_node = build_pointer_type (float_type_node);
12876 tree pint_type_node = build_pointer_type (integer_type_node);
12877 tree pshort_type_node = build_pointer_type (short_integer_type_node);
12878 tree pchar_type_node = build_pointer_type (char_type_node);
12880 tree pvoid_type_node = build_pointer_type (void_type_node);
12882 tree pcfloat_type_node = build_pointer_type (build_qualified_type (float_type_node, TYPE_QUAL_CONST));
12883 tree pcint_type_node = build_pointer_type (build_qualified_type (integer_type_node, TYPE_QUAL_CONST));
12884 tree pcshort_type_node = build_pointer_type (build_qualified_type (short_integer_type_node, TYPE_QUAL_CONST));
12885 tree pcchar_type_node = build_pointer_type (build_qualified_type (char_type_node, TYPE_QUAL_CONST));
12887 tree pcvoid_type_node = build_pointer_type (build_qualified_type (void_type_node, TYPE_QUAL_CONST));
12889 tree int_ftype_opaque
12890 = build_function_type_list (integer_type_node,
12891 opaque_V4SI_type_node, NULL_TREE);
12892 tree opaque_ftype_opaque
12893 = build_function_type (integer_type_node,
12894 NULL_TREE);
12895 tree opaque_ftype_opaque_int
12896 = build_function_type_list (opaque_V4SI_type_node,
12897 opaque_V4SI_type_node, integer_type_node, NULL_TREE);
12898 tree opaque_ftype_opaque_opaque_int
12899 = build_function_type_list (opaque_V4SI_type_node,
12900 opaque_V4SI_type_node, opaque_V4SI_type_node,
12901 integer_type_node, NULL_TREE);
12902 tree int_ftype_int_opaque_opaque
12903 = build_function_type_list (integer_type_node,
12904 integer_type_node, opaque_V4SI_type_node,
12905 opaque_V4SI_type_node, NULL_TREE);
12906 tree int_ftype_int_v4si_v4si
12907 = build_function_type_list (integer_type_node,
12908 integer_type_node, V4SI_type_node,
12909 V4SI_type_node, NULL_TREE);
12910 tree v4sf_ftype_pcfloat
12911 = build_function_type_list (V4SF_type_node, pcfloat_type_node, NULL_TREE);
12912 tree void_ftype_pfloat_v4sf
12913 = build_function_type_list (void_type_node,
12914 pfloat_type_node, V4SF_type_node, NULL_TREE);
12915 tree v4si_ftype_pcint
12916 = build_function_type_list (V4SI_type_node, pcint_type_node, NULL_TREE);
12917 tree void_ftype_pint_v4si
12918 = build_function_type_list (void_type_node,
12919 pint_type_node, V4SI_type_node, NULL_TREE);
12920 tree v8hi_ftype_pcshort
12921 = build_function_type_list (V8HI_type_node, pcshort_type_node, NULL_TREE);
12922 tree void_ftype_pshort_v8hi
12923 = build_function_type_list (void_type_node,
12924 pshort_type_node, V8HI_type_node, NULL_TREE);
12925 tree v16qi_ftype_pcchar
12926 = build_function_type_list (V16QI_type_node, pcchar_type_node, NULL_TREE);
12927 tree void_ftype_pchar_v16qi
12928 = build_function_type_list (void_type_node,
12929 pchar_type_node, V16QI_type_node, NULL_TREE);
12930 tree void_ftype_v4si
12931 = build_function_type_list (void_type_node, V4SI_type_node, NULL_TREE);
12932 tree v8hi_ftype_void
12933 = build_function_type (V8HI_type_node, void_list_node);
12934 tree void_ftype_void
12935 = build_function_type (void_type_node, void_list_node);
12936 tree void_ftype_int
12937 = build_function_type_list (void_type_node, integer_type_node, NULL_TREE);
12939 tree opaque_ftype_long_pcvoid
12940 = build_function_type_list (opaque_V4SI_type_node,
12941 long_integer_type_node, pcvoid_type_node, NULL_TREE);
12942 tree v16qi_ftype_long_pcvoid
12943 = build_function_type_list (V16QI_type_node,
12944 long_integer_type_node, pcvoid_type_node, NULL_TREE);
12945 tree v8hi_ftype_long_pcvoid
12946 = build_function_type_list (V8HI_type_node,
12947 long_integer_type_node, pcvoid_type_node, NULL_TREE);
12948 tree v4si_ftype_long_pcvoid
12949 = build_function_type_list (V4SI_type_node,
12950 long_integer_type_node, pcvoid_type_node, NULL_TREE);
12952 tree void_ftype_opaque_long_pvoid
12953 = build_function_type_list (void_type_node,
12954 opaque_V4SI_type_node, long_integer_type_node,
12955 pvoid_type_node, NULL_TREE);
12956 tree void_ftype_v4si_long_pvoid
12957 = build_function_type_list (void_type_node,
12958 V4SI_type_node, long_integer_type_node,
12959 pvoid_type_node, NULL_TREE);
12960 tree void_ftype_v16qi_long_pvoid
12961 = build_function_type_list (void_type_node,
12962 V16QI_type_node, long_integer_type_node,
12963 pvoid_type_node, NULL_TREE);
12964 tree void_ftype_v8hi_long_pvoid
12965 = build_function_type_list (void_type_node,
12966 V8HI_type_node, long_integer_type_node,
12967 pvoid_type_node, NULL_TREE);
12968 tree int_ftype_int_v8hi_v8hi
12969 = build_function_type_list (integer_type_node,
12970 integer_type_node, V8HI_type_node,
12971 V8HI_type_node, NULL_TREE);
12972 tree int_ftype_int_v16qi_v16qi
12973 = build_function_type_list (integer_type_node,
12974 integer_type_node, V16QI_type_node,
12975 V16QI_type_node, NULL_TREE);
12976 tree int_ftype_int_v4sf_v4sf
12977 = build_function_type_list (integer_type_node,
12978 integer_type_node, V4SF_type_node,
12979 V4SF_type_node, NULL_TREE);
12980 tree int_ftype_int_v2df_v2df
12981 = build_function_type_list (integer_type_node,
12982 integer_type_node, V2DF_type_node,
12983 V2DF_type_node, NULL_TREE);
12984 tree v4si_ftype_v4si
12985 = build_function_type_list (V4SI_type_node, V4SI_type_node, NULL_TREE);
12986 tree v8hi_ftype_v8hi
12987 = build_function_type_list (V8HI_type_node, V8HI_type_node, NULL_TREE);
12988 tree v16qi_ftype_v16qi
12989 = build_function_type_list (V16QI_type_node, V16QI_type_node, NULL_TREE);
12990 tree v4sf_ftype_v4sf
12991 = build_function_type_list (V4SF_type_node, V4SF_type_node, NULL_TREE);
12992 tree v2df_ftype_v2df
12993 = build_function_type_list (V2DF_type_node, V2DF_type_node, NULL_TREE);
12994 tree void_ftype_pcvoid_int_int
12995 = build_function_type_list (void_type_node,
12996 pcvoid_type_node, integer_type_node,
12997 integer_type_node, NULL_TREE);
12999 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_4sf", v4sf_ftype_pcfloat,
13000 ALTIVEC_BUILTIN_LD_INTERNAL_4sf);
13001 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_4sf", void_ftype_pfloat_v4sf,
13002 ALTIVEC_BUILTIN_ST_INTERNAL_4sf);
13003 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_4si", v4si_ftype_pcint,
13004 ALTIVEC_BUILTIN_LD_INTERNAL_4si);
13005 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_4si", void_ftype_pint_v4si,
13006 ALTIVEC_BUILTIN_ST_INTERNAL_4si);
13007 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_8hi", v8hi_ftype_pcshort,
13008 ALTIVEC_BUILTIN_LD_INTERNAL_8hi);
13009 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_8hi", void_ftype_pshort_v8hi,
13010 ALTIVEC_BUILTIN_ST_INTERNAL_8hi);
13011 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_16qi", v16qi_ftype_pcchar,
13012 ALTIVEC_BUILTIN_LD_INTERNAL_16qi);
13013 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_16qi", void_ftype_pchar_v16qi,
13014 ALTIVEC_BUILTIN_ST_INTERNAL_16qi);
13015 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mtvscr", void_ftype_v4si, ALTIVEC_BUILTIN_MTVSCR);
13016 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mfvscr", v8hi_ftype_void, ALTIVEC_BUILTIN_MFVSCR);
13017 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dssall", void_ftype_void, ALTIVEC_BUILTIN_DSSALL);
13018 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dss", void_ftype_int, ALTIVEC_BUILTIN_DSS);
13019 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSL);
13020 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSR);
13021 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEBX);
13022 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEHX);
13023 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEWX);
13024 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvxl", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVXL);
13025 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVX);
13026 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVX);
13027 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvewx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVEWX);
13028 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvxl", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVXL);
13029 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvebx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVEBX);
13030 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvehx", void_ftype_v8hi_long_pvoid, ALTIVEC_BUILTIN_STVEHX);
13031 def_builtin (MASK_ALTIVEC, "__builtin_vec_ld", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LD);
13032 def_builtin (MASK_ALTIVEC, "__builtin_vec_lde", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDE);
13033 def_builtin (MASK_ALTIVEC, "__builtin_vec_ldl", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDL);
13034 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSL);
13035 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSR);
13036 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEBX);
13037 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEHX);
13038 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEWX);
13039 def_builtin (MASK_ALTIVEC, "__builtin_vec_st", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_ST);
13040 def_builtin (MASK_ALTIVEC, "__builtin_vec_ste", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STE);
13041 def_builtin (MASK_ALTIVEC, "__builtin_vec_stl", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STL);
13042 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvewx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEWX);
13043 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvebx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEBX);
13044 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvehx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEHX);
13046 if (rs6000_cpu == PROCESSOR_CELL)
13048 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvlx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVLX);
13049 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvlxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVLXL);
13050 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvrx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVRX);
13051 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvrxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVRXL);
13053 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvlx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVLX);
13054 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvlxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVLXL);
13055 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvrx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVRX);
13056 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvrxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVRXL);
13058 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvlx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVLX);
13059 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvlxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVLXL);
13060 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvrx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVRX);
13061 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvrxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVRXL);
13063 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvlx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVLX);
13064 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvlxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVLXL);
13065 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvrx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVRX);
13066 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvrxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVRXL);
13068 def_builtin (MASK_ALTIVEC, "__builtin_vec_step", int_ftype_opaque, ALTIVEC_BUILTIN_VEC_STEP);
13069 def_builtin (MASK_ALTIVEC, "__builtin_vec_splats", opaque_ftype_opaque, ALTIVEC_BUILTIN_VEC_SPLATS);
13070 def_builtin (MASK_ALTIVEC, "__builtin_vec_promote", opaque_ftype_opaque, ALTIVEC_BUILTIN_VEC_PROMOTE);
13072 def_builtin (MASK_ALTIVEC, "__builtin_vec_sld", opaque_ftype_opaque_opaque_int, ALTIVEC_BUILTIN_VEC_SLD);
13073 def_builtin (MASK_ALTIVEC, "__builtin_vec_splat", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_SPLAT);
13074 def_builtin (MASK_ALTIVEC, "__builtin_vec_extract", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_EXTRACT);
13075 def_builtin (MASK_ALTIVEC, "__builtin_vec_insert", opaque_ftype_opaque_opaque_int, ALTIVEC_BUILTIN_VEC_INSERT);
13076 def_builtin (MASK_ALTIVEC, "__builtin_vec_vspltw", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTW);
13077 def_builtin (MASK_ALTIVEC, "__builtin_vec_vsplth", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTH);
13078 def_builtin (MASK_ALTIVEC, "__builtin_vec_vspltb", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTB);
13079 def_builtin (MASK_ALTIVEC, "__builtin_vec_ctf", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTF);
13080 def_builtin (MASK_ALTIVEC, "__builtin_vec_vcfsx", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFSX);
13081 def_builtin (MASK_ALTIVEC, "__builtin_vec_vcfux", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFUX);
13082 def_builtin (MASK_ALTIVEC, "__builtin_vec_cts", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTS);
13083 def_builtin (MASK_ALTIVEC, "__builtin_vec_ctu", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTU);
13085 /* Add the DST variants. */
13086 d = bdesc_dst;
13087 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
13088 def_builtin (d->mask, d->name, void_ftype_pcvoid_int_int, d->code);
13090 /* Initialize the predicates. */
13091 dp = bdesc_altivec_preds;
13092 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
13094 enum machine_mode mode1;
13095 tree type;
13096 bool is_overloaded = ((dp->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
13097 && dp->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
13098 || (dp->code >= VSX_BUILTIN_OVERLOADED_FIRST
13099 && dp->code <= VSX_BUILTIN_OVERLOADED_LAST));
13101 if (is_overloaded)
13102 mode1 = VOIDmode;
13103 else
13104 mode1 = insn_data[dp->icode].operand[1].mode;
13106 switch (mode1)
13108 case VOIDmode:
13109 type = int_ftype_int_opaque_opaque;
13110 break;
13111 case V4SImode:
13112 type = int_ftype_int_v4si_v4si;
13113 break;
13114 case V8HImode:
13115 type = int_ftype_int_v8hi_v8hi;
13116 break;
13117 case V16QImode:
13118 type = int_ftype_int_v16qi_v16qi;
13119 break;
13120 case V4SFmode:
13121 type = int_ftype_int_v4sf_v4sf;
13122 break;
13123 case V2DFmode:
13124 type = int_ftype_int_v2df_v2df;
13125 break;
13126 default:
13127 gcc_unreachable ();
13130 def_builtin (dp->mask, dp->name, type, dp->code);
13133 /* Initialize the abs* operators. */
13134 d = bdesc_abs;
13135 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
13137 enum machine_mode mode0;
13138 tree type;
13140 mode0 = insn_data[d->icode].operand[0].mode;
13142 switch (mode0)
13144 case V4SImode:
13145 type = v4si_ftype_v4si;
13146 break;
13147 case V8HImode:
13148 type = v8hi_ftype_v8hi;
13149 break;
13150 case V16QImode:
13151 type = v16qi_ftype_v16qi;
13152 break;
13153 case V4SFmode:
13154 type = v4sf_ftype_v4sf;
13155 break;
13156 case V2DFmode:
13157 type = v2df_ftype_v2df;
13158 break;
13159 default:
13160 gcc_unreachable ();
13163 def_builtin (d->mask, d->name, type, d->code);
13166 if (TARGET_ALTIVEC)
13168 tree decl;
13170 /* Initialize target builtin that implements
13171 targetm.vectorize.builtin_mask_for_load. */
13173 decl = add_builtin_function ("__builtin_altivec_mask_for_load",
13174 v16qi_ftype_long_pcvoid,
13175 ALTIVEC_BUILTIN_MASK_FOR_LOAD,
13176 BUILT_IN_MD, NULL, NULL_TREE);
13177 TREE_READONLY (decl) = 1;
13178 /* Record the decl. Will be used by rs6000_builtin_mask_for_load. */
13179 altivec_builtin_mask_for_load = decl;
13182 /* Access to the vec_init patterns. */
13183 ftype = build_function_type_list (V4SI_type_node, integer_type_node,
13184 integer_type_node, integer_type_node,
13185 integer_type_node, NULL_TREE);
13186 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v4si", ftype,
13187 ALTIVEC_BUILTIN_VEC_INIT_V4SI);
13189 ftype = build_function_type_list (V8HI_type_node, short_integer_type_node,
13190 short_integer_type_node,
13191 short_integer_type_node,
13192 short_integer_type_node,
13193 short_integer_type_node,
13194 short_integer_type_node,
13195 short_integer_type_node,
13196 short_integer_type_node, NULL_TREE);
13197 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v8hi", ftype,
13198 ALTIVEC_BUILTIN_VEC_INIT_V8HI);
13200 ftype = build_function_type_list (V16QI_type_node, char_type_node,
13201 char_type_node, char_type_node,
13202 char_type_node, char_type_node,
13203 char_type_node, char_type_node,
13204 char_type_node, char_type_node,
13205 char_type_node, char_type_node,
13206 char_type_node, char_type_node,
13207 char_type_node, char_type_node,
13208 char_type_node, NULL_TREE);
13209 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v16qi", ftype,
13210 ALTIVEC_BUILTIN_VEC_INIT_V16QI);
13212 ftype = build_function_type_list (V4SF_type_node, float_type_node,
13213 float_type_node, float_type_node,
13214 float_type_node, NULL_TREE);
13215 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v4sf", ftype,
13216 ALTIVEC_BUILTIN_VEC_INIT_V4SF);
13218 if (TARGET_VSX)
13220 ftype = build_function_type_list (V2DF_type_node, double_type_node,
13221 double_type_node, NULL_TREE);
13222 def_builtin (MASK_VSX, "__builtin_vec_init_v2df", ftype,
13223 VSX_BUILTIN_VEC_INIT_V2DF);
13225 ftype = build_function_type_list (V2DI_type_node, intDI_type_node,
13226 intDI_type_node, NULL_TREE);
13227 def_builtin (MASK_VSX, "__builtin_vec_init_v2di", ftype,
13228 VSX_BUILTIN_VEC_INIT_V2DI);
13231 /* Access to the vec_set patterns. */
13232 ftype = build_function_type_list (V4SI_type_node, V4SI_type_node,
13233 intSI_type_node,
13234 integer_type_node, NULL_TREE);
13235 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v4si", ftype,
13236 ALTIVEC_BUILTIN_VEC_SET_V4SI);
13238 ftype = build_function_type_list (V8HI_type_node, V8HI_type_node,
13239 intHI_type_node,
13240 integer_type_node, NULL_TREE);
13241 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v8hi", ftype,
13242 ALTIVEC_BUILTIN_VEC_SET_V8HI);
13244 ftype = build_function_type_list (V16QI_type_node, V16QI_type_node,
13245 intQI_type_node,
13246 integer_type_node, NULL_TREE);
13247 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v16qi", ftype,
13248 ALTIVEC_BUILTIN_VEC_SET_V16QI);
13250 ftype = build_function_type_list (V4SF_type_node, V4SF_type_node,
13251 float_type_node,
13252 integer_type_node, NULL_TREE);
13253 def_builtin (MASK_ALTIVEC|MASK_VSX, "__builtin_vec_set_v4sf", ftype,
13254 ALTIVEC_BUILTIN_VEC_SET_V4SF);
13256 if (TARGET_VSX)
13258 ftype = build_function_type_list (V2DF_type_node, V2DF_type_node,
13259 double_type_node,
13260 integer_type_node, NULL_TREE);
13261 def_builtin (MASK_VSX, "__builtin_vec_set_v2df", ftype,
13262 VSX_BUILTIN_VEC_SET_V2DF);
13264 ftype = build_function_type_list (V2DI_type_node, V2DI_type_node,
13265 intDI_type_node,
13266 integer_type_node, NULL_TREE);
13267 def_builtin (MASK_VSX, "__builtin_vec_set_v2di", ftype,
13268 VSX_BUILTIN_VEC_SET_V2DI);
13271 /* Access to the vec_extract patterns. */
13272 ftype = build_function_type_list (intSI_type_node, V4SI_type_node,
13273 integer_type_node, NULL_TREE);
13274 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v4si", ftype,
13275 ALTIVEC_BUILTIN_VEC_EXT_V4SI);
13277 ftype = build_function_type_list (intHI_type_node, V8HI_type_node,
13278 integer_type_node, NULL_TREE);
13279 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v8hi", ftype,
13280 ALTIVEC_BUILTIN_VEC_EXT_V8HI);
13282 ftype = build_function_type_list (intQI_type_node, V16QI_type_node,
13283 integer_type_node, NULL_TREE);
13284 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v16qi", ftype,
13285 ALTIVEC_BUILTIN_VEC_EXT_V16QI);
13287 ftype = build_function_type_list (float_type_node, V4SF_type_node,
13288 integer_type_node, NULL_TREE);
13289 def_builtin (MASK_ALTIVEC|MASK_VSX, "__builtin_vec_ext_v4sf", ftype,
13290 ALTIVEC_BUILTIN_VEC_EXT_V4SF);
13292 if (TARGET_VSX)
13294 ftype = build_function_type_list (double_type_node, V2DF_type_node,
13295 integer_type_node, NULL_TREE);
13296 def_builtin (MASK_VSX, "__builtin_vec_ext_v2df", ftype,
13297 VSX_BUILTIN_VEC_EXT_V2DF);
13299 ftype = build_function_type_list (intDI_type_node, V2DI_type_node,
13300 integer_type_node, NULL_TREE);
13301 def_builtin (MASK_VSX, "__builtin_vec_ext_v2di", ftype,
13302 VSX_BUILTIN_VEC_EXT_V2DI);
13306 /* Hash function for builtin functions with up to 3 arguments and a return
13307 type. */
13308 static unsigned
13309 builtin_hash_function (const void *hash_entry)
13311 unsigned ret = 0;
13312 int i;
13313 const struct builtin_hash_struct *bh =
13314 (const struct builtin_hash_struct *) hash_entry;
13316 for (i = 0; i < 4; i++)
13318 ret = (ret * (unsigned)MAX_MACHINE_MODE) + ((unsigned)bh->mode[i]);
13319 ret = (ret * 2) + bh->uns_p[i];
13322 return ret;
13325 /* Compare builtin hash entries H1 and H2 for equivalence. */
13326 static int
13327 builtin_hash_eq (const void *h1, const void *h2)
13329 const struct builtin_hash_struct *p1 = (const struct builtin_hash_struct *) h1;
13330 const struct builtin_hash_struct *p2 = (const struct builtin_hash_struct *) h2;
13332 return ((p1->mode[0] == p2->mode[0])
13333 && (p1->mode[1] == p2->mode[1])
13334 && (p1->mode[2] == p2->mode[2])
13335 && (p1->mode[3] == p2->mode[3])
13336 && (p1->uns_p[0] == p2->uns_p[0])
13337 && (p1->uns_p[1] == p2->uns_p[1])
13338 && (p1->uns_p[2] == p2->uns_p[2])
13339 && (p1->uns_p[3] == p2->uns_p[3]));
13342 /* Map types for builtin functions with an explicit return type and up to 3
13343 arguments. Functions with fewer than 3 arguments use VOIDmode as the type
13344 of the argument. */
13345 static tree
13346 builtin_function_type (enum machine_mode mode_ret, enum machine_mode mode_arg0,
13347 enum machine_mode mode_arg1, enum machine_mode mode_arg2,
13348 enum rs6000_builtins builtin, const char *name)
13350 struct builtin_hash_struct h;
13351 struct builtin_hash_struct *h2;
13352 void **found;
13353 int num_args = 3;
13354 int i;
13355 tree ret_type = NULL_TREE;
13356 tree arg_type[3] = { NULL_TREE, NULL_TREE, NULL_TREE };
13357 tree args;
13359 /* Create builtin_hash_table. */
13360 if (builtin_hash_table == NULL)
13361 builtin_hash_table = htab_create_ggc (1500, builtin_hash_function,
13362 builtin_hash_eq, NULL);
13364 h.type = NULL_TREE;
13365 h.mode[0] = mode_ret;
13366 h.mode[1] = mode_arg0;
13367 h.mode[2] = mode_arg1;
13368 h.mode[3] = mode_arg2;
13369 h.uns_p[0] = 0;
13370 h.uns_p[1] = 0;
13371 h.uns_p[2] = 0;
13372 h.uns_p[3] = 0;
13374 /* If the builtin is a type that produces unsigned results or takes unsigned
13375 arguments, and it is returned as a decl for the vectorizer (such as
13376 widening multiplies, permute), make sure the arguments and return value
13377 are type correct. */
13378 switch (builtin)
13380 /* unsigned 2 argument functions. */
13381 case ALTIVEC_BUILTIN_VMULEUB_UNS:
13382 case ALTIVEC_BUILTIN_VMULEUH_UNS:
13383 case ALTIVEC_BUILTIN_VMULOUB_UNS:
13384 case ALTIVEC_BUILTIN_VMULOUH_UNS:
13385 h.uns_p[0] = 1;
13386 h.uns_p[1] = 1;
13387 h.uns_p[2] = 1;
13388 break;
13390 /* unsigned 3 argument functions. */
13391 case ALTIVEC_BUILTIN_VPERM_16QI_UNS:
13392 case ALTIVEC_BUILTIN_VPERM_8HI_UNS:
13393 case ALTIVEC_BUILTIN_VPERM_4SI_UNS:
13394 case ALTIVEC_BUILTIN_VPERM_2DI_UNS:
13395 case ALTIVEC_BUILTIN_VSEL_16QI_UNS:
13396 case ALTIVEC_BUILTIN_VSEL_8HI_UNS:
13397 case ALTIVEC_BUILTIN_VSEL_4SI_UNS:
13398 case ALTIVEC_BUILTIN_VSEL_2DI_UNS:
13399 case VSX_BUILTIN_VPERM_16QI_UNS:
13400 case VSX_BUILTIN_VPERM_8HI_UNS:
13401 case VSX_BUILTIN_VPERM_4SI_UNS:
13402 case VSX_BUILTIN_VPERM_2DI_UNS:
13403 case VSX_BUILTIN_XXSEL_16QI_UNS:
13404 case VSX_BUILTIN_XXSEL_8HI_UNS:
13405 case VSX_BUILTIN_XXSEL_4SI_UNS:
13406 case VSX_BUILTIN_XXSEL_2DI_UNS:
13407 h.uns_p[0] = 1;
13408 h.uns_p[1] = 1;
13409 h.uns_p[2] = 1;
13410 h.uns_p[3] = 1;
13411 break;
13413 /* signed permute functions with unsigned char mask. */
13414 case ALTIVEC_BUILTIN_VPERM_16QI:
13415 case ALTIVEC_BUILTIN_VPERM_8HI:
13416 case ALTIVEC_BUILTIN_VPERM_4SI:
13417 case ALTIVEC_BUILTIN_VPERM_4SF:
13418 case ALTIVEC_BUILTIN_VPERM_2DI:
13419 case ALTIVEC_BUILTIN_VPERM_2DF:
13420 case VSX_BUILTIN_VPERM_16QI:
13421 case VSX_BUILTIN_VPERM_8HI:
13422 case VSX_BUILTIN_VPERM_4SI:
13423 case VSX_BUILTIN_VPERM_4SF:
13424 case VSX_BUILTIN_VPERM_2DI:
13425 case VSX_BUILTIN_VPERM_2DF:
13426 h.uns_p[3] = 1;
13427 break;
13429 /* unsigned args, signed return. */
13430 case VSX_BUILTIN_XVCVUXDDP_UNS:
13431 case VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF:
13432 h.uns_p[1] = 1;
13433 break;
13435 /* signed args, unsigned return. */
13436 case VSX_BUILTIN_XVCVDPUXDS_UNS:
13437 case VECTOR_BUILTIN_FIXUNS_V4SF_V4SI:
13438 h.uns_p[0] = 1;
13439 break;
13441 default:
13442 break;
13445 /* Figure out how many args are present. */
13446 while (num_args > 0 && h.mode[num_args] == VOIDmode)
13447 num_args--;
13449 if (num_args == 0)
13450 fatal_error ("internal error: builtin function %s had no type", name);
13452 ret_type = builtin_mode_to_type[h.mode[0]][h.uns_p[0]];
13453 if (!ret_type && h.uns_p[0])
13454 ret_type = builtin_mode_to_type[h.mode[0]][0];
13456 if (!ret_type)
13457 fatal_error ("internal error: builtin function %s had an unexpected "
13458 "return type %s", name, GET_MODE_NAME (h.mode[0]));
13460 for (i = 0; i < num_args; i++)
13462 int m = (int) h.mode[i+1];
13463 int uns_p = h.uns_p[i+1];
13465 arg_type[i] = builtin_mode_to_type[m][uns_p];
13466 if (!arg_type[i] && uns_p)
13467 arg_type[i] = builtin_mode_to_type[m][0];
13469 if (!arg_type[i])
13470 fatal_error ("internal error: builtin function %s, argument %d "
13471 "had unexpected argument type %s", name, i,
13472 GET_MODE_NAME (m));
13475 found = htab_find_slot (builtin_hash_table, &h, INSERT);
13476 if (*found == NULL)
13478 h2 = ggc_alloc_builtin_hash_struct ();
13479 *h2 = h;
13480 *found = (void *)h2;
13481 args = void_list_node;
13483 for (i = num_args - 1; i >= 0; i--)
13484 args = tree_cons (NULL_TREE, arg_type[i], args);
13486 h2->type = build_function_type (ret_type, args);
13489 return ((struct builtin_hash_struct *)(*found))->type;
13492 static void
13493 rs6000_common_init_builtins (void)
13495 const struct builtin_description *d;
13496 size_t i;
13498 tree opaque_ftype_opaque = NULL_TREE;
13499 tree opaque_ftype_opaque_opaque = NULL_TREE;
13500 tree opaque_ftype_opaque_opaque_opaque = NULL_TREE;
13501 tree v2si_ftype_qi = NULL_TREE;
13502 tree v2si_ftype_v2si_qi = NULL_TREE;
13503 tree v2si_ftype_int_qi = NULL_TREE;
13505 if (!TARGET_PAIRED_FLOAT)
13507 builtin_mode_to_type[V2SImode][0] = opaque_V2SI_type_node;
13508 builtin_mode_to_type[V2SFmode][0] = opaque_V2SF_type_node;
13511 /* Add the ternary operators. */
13512 d = bdesc_3arg;
13513 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
13515 tree type;
13516 int mask = d->mask;
13518 if ((mask != 0 && (mask & target_flags) == 0)
13519 || (mask == 0 && !TARGET_PAIRED_FLOAT))
13520 continue;
13522 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
13523 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
13524 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
13525 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
13527 if (! (type = opaque_ftype_opaque_opaque_opaque))
13528 type = opaque_ftype_opaque_opaque_opaque
13529 = build_function_type_list (opaque_V4SI_type_node,
13530 opaque_V4SI_type_node,
13531 opaque_V4SI_type_node,
13532 opaque_V4SI_type_node,
13533 NULL_TREE);
13535 else
13537 enum insn_code icode = d->icode;
13538 if (d->name == 0 || icode == CODE_FOR_nothing)
13539 continue;
13541 type = builtin_function_type (insn_data[icode].operand[0].mode,
13542 insn_data[icode].operand[1].mode,
13543 insn_data[icode].operand[2].mode,
13544 insn_data[icode].operand[3].mode,
13545 d->code, d->name);
13548 def_builtin (d->mask, d->name, type, d->code);
13551 /* Add the binary operators. */
13552 d = bdesc_2arg;
13553 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
13555 enum machine_mode mode0, mode1, mode2;
13556 tree type;
13557 int mask = d->mask;
13559 if ((mask != 0 && (mask & target_flags) == 0)
13560 || (mask == 0 && !TARGET_PAIRED_FLOAT))
13561 continue;
13563 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
13564 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
13565 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
13566 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
13568 if (! (type = opaque_ftype_opaque_opaque))
13569 type = opaque_ftype_opaque_opaque
13570 = build_function_type_list (opaque_V4SI_type_node,
13571 opaque_V4SI_type_node,
13572 opaque_V4SI_type_node,
13573 NULL_TREE);
13575 else
13577 enum insn_code icode = d->icode;
13578 if (d->name == 0 || icode == CODE_FOR_nothing)
13579 continue;
13581 mode0 = insn_data[icode].operand[0].mode;
13582 mode1 = insn_data[icode].operand[1].mode;
13583 mode2 = insn_data[icode].operand[2].mode;
13585 if (mode0 == V2SImode && mode1 == V2SImode && mode2 == QImode)
13587 if (! (type = v2si_ftype_v2si_qi))
13588 type = v2si_ftype_v2si_qi
13589 = build_function_type_list (opaque_V2SI_type_node,
13590 opaque_V2SI_type_node,
13591 char_type_node,
13592 NULL_TREE);
13595 else if (mode0 == V2SImode && GET_MODE_CLASS (mode1) == MODE_INT
13596 && mode2 == QImode)
13598 if (! (type = v2si_ftype_int_qi))
13599 type = v2si_ftype_int_qi
13600 = build_function_type_list (opaque_V2SI_type_node,
13601 integer_type_node,
13602 char_type_node,
13603 NULL_TREE);
13606 else
13607 type = builtin_function_type (mode0, mode1, mode2, VOIDmode,
13608 d->code, d->name);
13611 def_builtin (d->mask, d->name, type, d->code);
13614 /* Add the simple unary operators. */
13615 d = (struct builtin_description *) bdesc_1arg;
13616 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
13618 enum machine_mode mode0, mode1;
13619 tree type;
13620 int mask = d->mask;
13622 if ((mask != 0 && (mask & target_flags) == 0)
13623 || (mask == 0 && !TARGET_PAIRED_FLOAT))
13624 continue;
13626 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
13627 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
13628 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
13629 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
13631 if (! (type = opaque_ftype_opaque))
13632 type = opaque_ftype_opaque
13633 = build_function_type_list (opaque_V4SI_type_node,
13634 opaque_V4SI_type_node,
13635 NULL_TREE);
13637 else
13639 enum insn_code icode = d->icode;
13640 if (d->name == 0 || icode == CODE_FOR_nothing)
13641 continue;
13643 mode0 = insn_data[icode].operand[0].mode;
13644 mode1 = insn_data[icode].operand[1].mode;
13646 if (mode0 == V2SImode && mode1 == QImode)
13648 if (! (type = v2si_ftype_qi))
13649 type = v2si_ftype_qi
13650 = build_function_type_list (opaque_V2SI_type_node,
13651 char_type_node,
13652 NULL_TREE);
13655 else
13656 type = builtin_function_type (mode0, mode1, VOIDmode, VOIDmode,
13657 d->code, d->name);
13660 def_builtin (d->mask, d->name, type, d->code);
13664 static void
13665 rs6000_init_libfuncs (void)
13667 if (DEFAULT_ABI != ABI_V4 && TARGET_XCOFF
13668 && !TARGET_POWER2 && !TARGET_POWERPC)
13670 /* AIX library routines for float->int conversion. */
13671 set_conv_libfunc (sfix_optab, SImode, DFmode, "__itrunc");
13672 set_conv_libfunc (ufix_optab, SImode, DFmode, "__uitrunc");
13673 set_conv_libfunc (sfix_optab, SImode, TFmode, "_qitrunc");
13674 set_conv_libfunc (ufix_optab, SImode, TFmode, "_quitrunc");
13677 if (!TARGET_IEEEQUAD)
13678 /* AIX/Darwin/64-bit Linux quad floating point routines. */
13679 if (!TARGET_XL_COMPAT)
13681 set_optab_libfunc (add_optab, TFmode, "__gcc_qadd");
13682 set_optab_libfunc (sub_optab, TFmode, "__gcc_qsub");
13683 set_optab_libfunc (smul_optab, TFmode, "__gcc_qmul");
13684 set_optab_libfunc (sdiv_optab, TFmode, "__gcc_qdiv");
13686 if (!(TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)))
13688 set_optab_libfunc (neg_optab, TFmode, "__gcc_qneg");
13689 set_optab_libfunc (eq_optab, TFmode, "__gcc_qeq");
13690 set_optab_libfunc (ne_optab, TFmode, "__gcc_qne");
13691 set_optab_libfunc (gt_optab, TFmode, "__gcc_qgt");
13692 set_optab_libfunc (ge_optab, TFmode, "__gcc_qge");
13693 set_optab_libfunc (lt_optab, TFmode, "__gcc_qlt");
13694 set_optab_libfunc (le_optab, TFmode, "__gcc_qle");
13696 set_conv_libfunc (sext_optab, TFmode, SFmode, "__gcc_stoq");
13697 set_conv_libfunc (sext_optab, TFmode, DFmode, "__gcc_dtoq");
13698 set_conv_libfunc (trunc_optab, SFmode, TFmode, "__gcc_qtos");
13699 set_conv_libfunc (trunc_optab, DFmode, TFmode, "__gcc_qtod");
13700 set_conv_libfunc (sfix_optab, SImode, TFmode, "__gcc_qtoi");
13701 set_conv_libfunc (ufix_optab, SImode, TFmode, "__gcc_qtou");
13702 set_conv_libfunc (sfloat_optab, TFmode, SImode, "__gcc_itoq");
13703 set_conv_libfunc (ufloat_optab, TFmode, SImode, "__gcc_utoq");
13706 if (!(TARGET_HARD_FLOAT && TARGET_FPRS))
13707 set_optab_libfunc (unord_optab, TFmode, "__gcc_qunord");
13709 else
13711 set_optab_libfunc (add_optab, TFmode, "_xlqadd");
13712 set_optab_libfunc (sub_optab, TFmode, "_xlqsub");
13713 set_optab_libfunc (smul_optab, TFmode, "_xlqmul");
13714 set_optab_libfunc (sdiv_optab, TFmode, "_xlqdiv");
13716 else
13718 /* 32-bit SVR4 quad floating point routines. */
13720 set_optab_libfunc (add_optab, TFmode, "_q_add");
13721 set_optab_libfunc (sub_optab, TFmode, "_q_sub");
13722 set_optab_libfunc (neg_optab, TFmode, "_q_neg");
13723 set_optab_libfunc (smul_optab, TFmode, "_q_mul");
13724 set_optab_libfunc (sdiv_optab, TFmode, "_q_div");
13725 if (TARGET_PPC_GPOPT || TARGET_POWER2)
13726 set_optab_libfunc (sqrt_optab, TFmode, "_q_sqrt");
13728 set_optab_libfunc (eq_optab, TFmode, "_q_feq");
13729 set_optab_libfunc (ne_optab, TFmode, "_q_fne");
13730 set_optab_libfunc (gt_optab, TFmode, "_q_fgt");
13731 set_optab_libfunc (ge_optab, TFmode, "_q_fge");
13732 set_optab_libfunc (lt_optab, TFmode, "_q_flt");
13733 set_optab_libfunc (le_optab, TFmode, "_q_fle");
13735 set_conv_libfunc (sext_optab, TFmode, SFmode, "_q_stoq");
13736 set_conv_libfunc (sext_optab, TFmode, DFmode, "_q_dtoq");
13737 set_conv_libfunc (trunc_optab, SFmode, TFmode, "_q_qtos");
13738 set_conv_libfunc (trunc_optab, DFmode, TFmode, "_q_qtod");
13739 set_conv_libfunc (sfix_optab, SImode, TFmode, "_q_qtoi");
13740 set_conv_libfunc (ufix_optab, SImode, TFmode, "_q_qtou");
13741 set_conv_libfunc (sfloat_optab, TFmode, SImode, "_q_itoq");
13742 set_conv_libfunc (ufloat_optab, TFmode, SImode, "_q_utoq");
13747 /* Expand a block clear operation, and return 1 if successful. Return 0
13748 if we should let the compiler generate normal code.
13750 operands[0] is the destination
13751 operands[1] is the length
13752 operands[3] is the alignment */
13755 expand_block_clear (rtx operands[])
13757 rtx orig_dest = operands[0];
13758 rtx bytes_rtx = operands[1];
13759 rtx align_rtx = operands[3];
13760 bool constp = (GET_CODE (bytes_rtx) == CONST_INT);
13761 HOST_WIDE_INT align;
13762 HOST_WIDE_INT bytes;
13763 int offset;
13764 int clear_bytes;
13765 int clear_step;
13767 /* If this is not a fixed size move, just call memcpy */
13768 if (! constp)
13769 return 0;
13771 /* This must be a fixed size alignment */
13772 gcc_assert (GET_CODE (align_rtx) == CONST_INT);
13773 align = INTVAL (align_rtx) * BITS_PER_UNIT;
13775 /* Anything to clear? */
13776 bytes = INTVAL (bytes_rtx);
13777 if (bytes <= 0)
13778 return 1;
13780 /* Use the builtin memset after a point, to avoid huge code bloat.
13781 When optimize_size, avoid any significant code bloat; calling
13782 memset is about 4 instructions, so allow for one instruction to
13783 load zero and three to do clearing. */
13784 if (TARGET_ALTIVEC && align >= 128)
13785 clear_step = 16;
13786 else if (TARGET_POWERPC64 && align >= 32)
13787 clear_step = 8;
13788 else if (TARGET_SPE && align >= 64)
13789 clear_step = 8;
13790 else
13791 clear_step = 4;
13793 if (optimize_size && bytes > 3 * clear_step)
13794 return 0;
13795 if (! optimize_size && bytes > 8 * clear_step)
13796 return 0;
13798 for (offset = 0; bytes > 0; offset += clear_bytes, bytes -= clear_bytes)
13800 enum machine_mode mode = BLKmode;
13801 rtx dest;
13803 if (bytes >= 16 && TARGET_ALTIVEC && align >= 128)
13805 clear_bytes = 16;
13806 mode = V4SImode;
13808 else if (bytes >= 8 && TARGET_SPE && align >= 64)
13810 clear_bytes = 8;
13811 mode = V2SImode;
13813 else if (bytes >= 8 && TARGET_POWERPC64
13814 /* 64-bit loads and stores require word-aligned
13815 displacements. */
13816 && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
13818 clear_bytes = 8;
13819 mode = DImode;
13821 else if (bytes >= 4 && (align >= 32 || !STRICT_ALIGNMENT))
13822 { /* move 4 bytes */
13823 clear_bytes = 4;
13824 mode = SImode;
13826 else if (bytes >= 2 && (align >= 16 || !STRICT_ALIGNMENT))
13827 { /* move 2 bytes */
13828 clear_bytes = 2;
13829 mode = HImode;
13831 else /* move 1 byte at a time */
13833 clear_bytes = 1;
13834 mode = QImode;
13837 dest = adjust_address (orig_dest, mode, offset);
13839 emit_move_insn (dest, CONST0_RTX (mode));
13842 return 1;
13846 /* Expand a block move operation, and return 1 if successful. Return 0
13847 if we should let the compiler generate normal code.
13849 operands[0] is the destination
13850 operands[1] is the source
13851 operands[2] is the length
13852 operands[3] is the alignment */
13854 #define MAX_MOVE_REG 4
13857 expand_block_move (rtx operands[])
13859 rtx orig_dest = operands[0];
13860 rtx orig_src = operands[1];
13861 rtx bytes_rtx = operands[2];
13862 rtx align_rtx = operands[3];
13863 int constp = (GET_CODE (bytes_rtx) == CONST_INT);
13864 int align;
13865 int bytes;
13866 int offset;
13867 int move_bytes;
13868 rtx stores[MAX_MOVE_REG];
13869 int num_reg = 0;
13871 /* If this is not a fixed size move, just call memcpy */
13872 if (! constp)
13873 return 0;
13875 /* This must be a fixed size alignment */
13876 gcc_assert (GET_CODE (align_rtx) == CONST_INT);
13877 align = INTVAL (align_rtx) * BITS_PER_UNIT;
13879 /* Anything to move? */
13880 bytes = INTVAL (bytes_rtx);
13881 if (bytes <= 0)
13882 return 1;
13884 if (bytes > rs6000_block_move_inline_limit)
13885 return 0;
13887 for (offset = 0; bytes > 0; offset += move_bytes, bytes -= move_bytes)
13889 union {
13890 rtx (*movmemsi) (rtx, rtx, rtx, rtx);
13891 rtx (*mov) (rtx, rtx);
13892 } gen_func;
13893 enum machine_mode mode = BLKmode;
13894 rtx src, dest;
13896 /* Altivec first, since it will be faster than a string move
13897 when it applies, and usually not significantly larger. */
13898 if (TARGET_ALTIVEC && bytes >= 16 && align >= 128)
13900 move_bytes = 16;
13901 mode = V4SImode;
13902 gen_func.mov = gen_movv4si;
13904 else if (TARGET_SPE && bytes >= 8 && align >= 64)
13906 move_bytes = 8;
13907 mode = V2SImode;
13908 gen_func.mov = gen_movv2si;
13910 else if (TARGET_STRING
13911 && bytes > 24 /* move up to 32 bytes at a time */
13912 && ! fixed_regs[5]
13913 && ! fixed_regs[6]
13914 && ! fixed_regs[7]
13915 && ! fixed_regs[8]
13916 && ! fixed_regs[9]
13917 && ! fixed_regs[10]
13918 && ! fixed_regs[11]
13919 && ! fixed_regs[12])
13921 move_bytes = (bytes > 32) ? 32 : bytes;
13922 gen_func.movmemsi = gen_movmemsi_8reg;
13924 else if (TARGET_STRING
13925 && bytes > 16 /* move up to 24 bytes at a time */
13926 && ! fixed_regs[5]
13927 && ! fixed_regs[6]
13928 && ! fixed_regs[7]
13929 && ! fixed_regs[8]
13930 && ! fixed_regs[9]
13931 && ! fixed_regs[10])
13933 move_bytes = (bytes > 24) ? 24 : bytes;
13934 gen_func.movmemsi = gen_movmemsi_6reg;
13936 else if (TARGET_STRING
13937 && bytes > 8 /* move up to 16 bytes at a time */
13938 && ! fixed_regs[5]
13939 && ! fixed_regs[6]
13940 && ! fixed_regs[7]
13941 && ! fixed_regs[8])
13943 move_bytes = (bytes > 16) ? 16 : bytes;
13944 gen_func.movmemsi = gen_movmemsi_4reg;
13946 else if (bytes >= 8 && TARGET_POWERPC64
13947 /* 64-bit loads and stores require word-aligned
13948 displacements. */
13949 && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
13951 move_bytes = 8;
13952 mode = DImode;
13953 gen_func.mov = gen_movdi;
13955 else if (TARGET_STRING && bytes > 4 && !TARGET_POWERPC64)
13956 { /* move up to 8 bytes at a time */
13957 move_bytes = (bytes > 8) ? 8 : bytes;
13958 gen_func.movmemsi = gen_movmemsi_2reg;
13960 else if (bytes >= 4 && (align >= 32 || !STRICT_ALIGNMENT))
13961 { /* move 4 bytes */
13962 move_bytes = 4;
13963 mode = SImode;
13964 gen_func.mov = gen_movsi;
13966 else if (bytes >= 2 && (align >= 16 || !STRICT_ALIGNMENT))
13967 { /* move 2 bytes */
13968 move_bytes = 2;
13969 mode = HImode;
13970 gen_func.mov = gen_movhi;
13972 else if (TARGET_STRING && bytes > 1)
13973 { /* move up to 4 bytes at a time */
13974 move_bytes = (bytes > 4) ? 4 : bytes;
13975 gen_func.movmemsi = gen_movmemsi_1reg;
13977 else /* move 1 byte at a time */
13979 move_bytes = 1;
13980 mode = QImode;
13981 gen_func.mov = gen_movqi;
13984 src = adjust_address (orig_src, mode, offset);
13985 dest = adjust_address (orig_dest, mode, offset);
13987 if (mode != BLKmode)
13989 rtx tmp_reg = gen_reg_rtx (mode);
13991 emit_insn ((*gen_func.mov) (tmp_reg, src));
13992 stores[num_reg++] = (*gen_func.mov) (dest, tmp_reg);
13995 if (mode == BLKmode || num_reg >= MAX_MOVE_REG || bytes == move_bytes)
13997 int i;
13998 for (i = 0; i < num_reg; i++)
13999 emit_insn (stores[i]);
14000 num_reg = 0;
14003 if (mode == BLKmode)
14005 /* Move the address into scratch registers. The movmemsi
14006 patterns require zero offset. */
14007 if (!REG_P (XEXP (src, 0)))
14009 rtx src_reg = copy_addr_to_reg (XEXP (src, 0));
14010 src = replace_equiv_address (src, src_reg);
14012 set_mem_size (src, GEN_INT (move_bytes));
14014 if (!REG_P (XEXP (dest, 0)))
14016 rtx dest_reg = copy_addr_to_reg (XEXP (dest, 0));
14017 dest = replace_equiv_address (dest, dest_reg);
14019 set_mem_size (dest, GEN_INT (move_bytes));
14021 emit_insn ((*gen_func.movmemsi) (dest, src,
14022 GEN_INT (move_bytes & 31),
14023 align_rtx));
14027 return 1;
14031 /* Return a string to perform a load_multiple operation.
14032 operands[0] is the vector.
14033 operands[1] is the source address.
14034 operands[2] is the first destination register. */
14036 const char *
14037 rs6000_output_load_multiple (rtx operands[3])
14039 /* We have to handle the case where the pseudo used to contain the address
14040 is assigned to one of the output registers. */
14041 int i, j;
14042 int words = XVECLEN (operands[0], 0);
14043 rtx xop[10];
14045 if (XVECLEN (operands[0], 0) == 1)
14046 return "{l|lwz} %2,0(%1)";
14048 for (i = 0; i < words; i++)
14049 if (refers_to_regno_p (REGNO (operands[2]) + i,
14050 REGNO (operands[2]) + i + 1, operands[1], 0))
14052 if (i == words-1)
14054 xop[0] = GEN_INT (4 * (words-1));
14055 xop[1] = operands[1];
14056 xop[2] = operands[2];
14057 output_asm_insn ("{lsi|lswi} %2,%1,%0\n\t{l|lwz} %1,%0(%1)", xop);
14058 return "";
14060 else if (i == 0)
14062 xop[0] = GEN_INT (4 * (words-1));
14063 xop[1] = operands[1];
14064 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + 1);
14065 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);
14066 return "";
14068 else
14070 for (j = 0; j < words; j++)
14071 if (j != i)
14073 xop[0] = GEN_INT (j * 4);
14074 xop[1] = operands[1];
14075 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + j);
14076 output_asm_insn ("{l|lwz} %2,%0(%1)", xop);
14078 xop[0] = GEN_INT (i * 4);
14079 xop[1] = operands[1];
14080 output_asm_insn ("{l|lwz} %1,%0(%1)", xop);
14081 return "";
14085 return "{lsi|lswi} %2,%1,%N0";
14089 /* A validation routine: say whether CODE, a condition code, and MODE
14090 match. The other alternatives either don't make sense or should
14091 never be generated. */
14093 void
14094 validate_condition_mode (enum rtx_code code, enum machine_mode mode)
14096 gcc_assert ((GET_RTX_CLASS (code) == RTX_COMPARE
14097 || GET_RTX_CLASS (code) == RTX_COMM_COMPARE)
14098 && GET_MODE_CLASS (mode) == MODE_CC);
14100 /* These don't make sense. */
14101 gcc_assert ((code != GT && code != LT && code != GE && code != LE)
14102 || mode != CCUNSmode);
14104 gcc_assert ((code != GTU && code != LTU && code != GEU && code != LEU)
14105 || mode == CCUNSmode);
14107 gcc_assert (mode == CCFPmode
14108 || (code != ORDERED && code != UNORDERED
14109 && code != UNEQ && code != LTGT
14110 && code != UNGT && code != UNLT
14111 && code != UNGE && code != UNLE));
14113 /* These should never be generated except for
14114 flag_finite_math_only. */
14115 gcc_assert (mode != CCFPmode
14116 || flag_finite_math_only
14117 || (code != LE && code != GE
14118 && code != UNEQ && code != LTGT
14119 && code != UNGT && code != UNLT));
14121 /* These are invalid; the information is not there. */
14122 gcc_assert (mode != CCEQmode || code == EQ || code == NE);
14126 /* Return 1 if ANDOP is a mask that has no bits on that are not in the
14127 mask required to convert the result of a rotate insn into a shift
14128 left insn of SHIFTOP bits. Both are known to be SImode CONST_INT. */
14131 includes_lshift_p (rtx shiftop, rtx andop)
14133 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
14135 shift_mask <<= INTVAL (shiftop);
14137 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
14140 /* Similar, but for right shift. */
14143 includes_rshift_p (rtx shiftop, rtx andop)
14145 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
14147 shift_mask >>= INTVAL (shiftop);
14149 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
14152 /* Return 1 if ANDOP is a mask suitable for use with an rldic insn
14153 to perform a left shift. It must have exactly SHIFTOP least
14154 significant 0's, then one or more 1's, then zero or more 0's. */
14157 includes_rldic_lshift_p (rtx shiftop, rtx andop)
14159 if (GET_CODE (andop) == CONST_INT)
14161 HOST_WIDE_INT c, lsb, shift_mask;
14163 c = INTVAL (andop);
14164 if (c == 0 || c == ~0)
14165 return 0;
14167 shift_mask = ~0;
14168 shift_mask <<= INTVAL (shiftop);
14170 /* Find the least significant one bit. */
14171 lsb = c & -c;
14173 /* It must coincide with the LSB of the shift mask. */
14174 if (-lsb != shift_mask)
14175 return 0;
14177 /* Invert to look for the next transition (if any). */
14178 c = ~c;
14180 /* Remove the low group of ones (originally low group of zeros). */
14181 c &= -lsb;
14183 /* Again find the lsb, and check we have all 1's above. */
14184 lsb = c & -c;
14185 return c == -lsb;
14187 else if (GET_CODE (andop) == CONST_DOUBLE
14188 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
14190 HOST_WIDE_INT low, high, lsb;
14191 HOST_WIDE_INT shift_mask_low, shift_mask_high;
14193 low = CONST_DOUBLE_LOW (andop);
14194 if (HOST_BITS_PER_WIDE_INT < 64)
14195 high = CONST_DOUBLE_HIGH (andop);
14197 if ((low == 0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == 0))
14198 || (low == ~0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0)))
14199 return 0;
14201 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
14203 shift_mask_high = ~0;
14204 if (INTVAL (shiftop) > 32)
14205 shift_mask_high <<= INTVAL (shiftop) - 32;
14207 lsb = high & -high;
14209 if (-lsb != shift_mask_high || INTVAL (shiftop) < 32)
14210 return 0;
14212 high = ~high;
14213 high &= -lsb;
14215 lsb = high & -high;
14216 return high == -lsb;
14219 shift_mask_low = ~0;
14220 shift_mask_low <<= INTVAL (shiftop);
14222 lsb = low & -low;
14224 if (-lsb != shift_mask_low)
14225 return 0;
14227 if (HOST_BITS_PER_WIDE_INT < 64)
14228 high = ~high;
14229 low = ~low;
14230 low &= -lsb;
14232 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
14234 lsb = high & -high;
14235 return high == -lsb;
14238 lsb = low & -low;
14239 return low == -lsb && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0);
14241 else
14242 return 0;
14245 /* Return 1 if ANDOP is a mask suitable for use with an rldicr insn
14246 to perform a left shift. It must have SHIFTOP or more least
14247 significant 0's, with the remainder of the word 1's. */
14250 includes_rldicr_lshift_p (rtx shiftop, rtx andop)
14252 if (GET_CODE (andop) == CONST_INT)
14254 HOST_WIDE_INT c, lsb, shift_mask;
14256 shift_mask = ~0;
14257 shift_mask <<= INTVAL (shiftop);
14258 c = INTVAL (andop);
14260 /* Find the least significant one bit. */
14261 lsb = c & -c;
14263 /* It must be covered by the shift mask.
14264 This test also rejects c == 0. */
14265 if ((lsb & shift_mask) == 0)
14266 return 0;
14268 /* Check we have all 1's above the transition, and reject all 1's. */
14269 return c == -lsb && lsb != 1;
14271 else if (GET_CODE (andop) == CONST_DOUBLE
14272 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
14274 HOST_WIDE_INT low, lsb, shift_mask_low;
14276 low = CONST_DOUBLE_LOW (andop);
14278 if (HOST_BITS_PER_WIDE_INT < 64)
14280 HOST_WIDE_INT high, shift_mask_high;
14282 high = CONST_DOUBLE_HIGH (andop);
14284 if (low == 0)
14286 shift_mask_high = ~0;
14287 if (INTVAL (shiftop) > 32)
14288 shift_mask_high <<= INTVAL (shiftop) - 32;
14290 lsb = high & -high;
14292 if ((lsb & shift_mask_high) == 0)
14293 return 0;
14295 return high == -lsb;
14297 if (high != ~0)
14298 return 0;
14301 shift_mask_low = ~0;
14302 shift_mask_low <<= INTVAL (shiftop);
14304 lsb = low & -low;
14306 if ((lsb & shift_mask_low) == 0)
14307 return 0;
14309 return low == -lsb && lsb != 1;
14311 else
14312 return 0;
14315 /* Return 1 if operands will generate a valid arguments to rlwimi
14316 instruction for insert with right shift in 64-bit mode. The mask may
14317 not start on the first bit or stop on the last bit because wrap-around
14318 effects of instruction do not correspond to semantics of RTL insn. */
14321 insvdi_rshift_rlwimi_p (rtx sizeop, rtx startop, rtx shiftop)
14323 if (INTVAL (startop) > 32
14324 && INTVAL (startop) < 64
14325 && INTVAL (sizeop) > 1
14326 && INTVAL (sizeop) + INTVAL (startop) < 64
14327 && INTVAL (shiftop) > 0
14328 && INTVAL (sizeop) + INTVAL (shiftop) < 32
14329 && (64 - (INTVAL (shiftop) & 63)) >= INTVAL (sizeop))
14330 return 1;
14332 return 0;
14335 /* Return 1 if REGNO (reg1) == REGNO (reg2) - 1 making them candidates
14336 for lfq and stfq insns iff the registers are hard registers. */
14339 registers_ok_for_quad_peep (rtx reg1, rtx reg2)
14341 /* We might have been passed a SUBREG. */
14342 if (GET_CODE (reg1) != REG || GET_CODE (reg2) != REG)
14343 return 0;
14345 /* We might have been passed non floating point registers. */
14346 if (!FP_REGNO_P (REGNO (reg1))
14347 || !FP_REGNO_P (REGNO (reg2)))
14348 return 0;
14350 return (REGNO (reg1) == REGNO (reg2) - 1);
14353 /* Return 1 if addr1 and addr2 are suitable for lfq or stfq insn.
14354 addr1 and addr2 must be in consecutive memory locations
14355 (addr2 == addr1 + 8). */
14358 mems_ok_for_quad_peep (rtx mem1, rtx mem2)
14360 rtx addr1, addr2;
14361 unsigned int reg1, reg2;
14362 int offset1, offset2;
14364 /* The mems cannot be volatile. */
14365 if (MEM_VOLATILE_P (mem1) || MEM_VOLATILE_P (mem2))
14366 return 0;
14368 addr1 = XEXP (mem1, 0);
14369 addr2 = XEXP (mem2, 0);
14371 /* Extract an offset (if used) from the first addr. */
14372 if (GET_CODE (addr1) == PLUS)
14374 /* If not a REG, return zero. */
14375 if (GET_CODE (XEXP (addr1, 0)) != REG)
14376 return 0;
14377 else
14379 reg1 = REGNO (XEXP (addr1, 0));
14380 /* The offset must be constant! */
14381 if (GET_CODE (XEXP (addr1, 1)) != CONST_INT)
14382 return 0;
14383 offset1 = INTVAL (XEXP (addr1, 1));
14386 else if (GET_CODE (addr1) != REG)
14387 return 0;
14388 else
14390 reg1 = REGNO (addr1);
14391 /* This was a simple (mem (reg)) expression. Offset is 0. */
14392 offset1 = 0;
14395 /* And now for the second addr. */
14396 if (GET_CODE (addr2) == PLUS)
14398 /* If not a REG, return zero. */
14399 if (GET_CODE (XEXP (addr2, 0)) != REG)
14400 return 0;
14401 else
14403 reg2 = REGNO (XEXP (addr2, 0));
14404 /* The offset must be constant. */
14405 if (GET_CODE (XEXP (addr2, 1)) != CONST_INT)
14406 return 0;
14407 offset2 = INTVAL (XEXP (addr2, 1));
14410 else if (GET_CODE (addr2) != REG)
14411 return 0;
14412 else
14414 reg2 = REGNO (addr2);
14415 /* This was a simple (mem (reg)) expression. Offset is 0. */
14416 offset2 = 0;
14419 /* Both of these must have the same base register. */
14420 if (reg1 != reg2)
14421 return 0;
14423 /* The offset for the second addr must be 8 more than the first addr. */
14424 if (offset2 != offset1 + 8)
14425 return 0;
14427 /* All the tests passed. addr1 and addr2 are valid for lfq or stfq
14428 instructions. */
14429 return 1;
14434 rs6000_secondary_memory_needed_rtx (enum machine_mode mode)
14436 static bool eliminated = false;
14437 rtx ret;
14439 if (mode != SDmode)
14440 ret = assign_stack_local (mode, GET_MODE_SIZE (mode), 0);
14441 else
14443 rtx mem = cfun->machine->sdmode_stack_slot;
14444 gcc_assert (mem != NULL_RTX);
14446 if (!eliminated)
14448 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
14449 cfun->machine->sdmode_stack_slot = mem;
14450 eliminated = true;
14452 ret = mem;
14455 if (TARGET_DEBUG_ADDR)
14457 fprintf (stderr, "\nrs6000_secondary_memory_needed_rtx, mode %s, rtx:\n",
14458 GET_MODE_NAME (mode));
14459 if (!ret)
14460 fprintf (stderr, "\tNULL_RTX\n");
14461 else
14462 debug_rtx (ret);
14465 return ret;
14468 static tree
14469 rs6000_check_sdmode (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
14471 /* Don't walk into types. */
14472 if (*tp == NULL_TREE || *tp == error_mark_node || TYPE_P (*tp))
14474 *walk_subtrees = 0;
14475 return NULL_TREE;
14478 switch (TREE_CODE (*tp))
14480 case VAR_DECL:
14481 case PARM_DECL:
14482 case FIELD_DECL:
14483 case RESULT_DECL:
14484 case SSA_NAME:
14485 case REAL_CST:
14486 case MEM_REF:
14487 case VIEW_CONVERT_EXPR:
14488 if (TYPE_MODE (TREE_TYPE (*tp)) == SDmode)
14489 return *tp;
14490 break;
14491 default:
14492 break;
14495 return NULL_TREE;
14498 enum reload_reg_type {
14499 GPR_REGISTER_TYPE,
14500 VECTOR_REGISTER_TYPE,
14501 OTHER_REGISTER_TYPE
14504 static enum reload_reg_type
14505 rs6000_reload_register_type (enum reg_class rclass)
14507 switch (rclass)
14509 case GENERAL_REGS:
14510 case BASE_REGS:
14511 return GPR_REGISTER_TYPE;
14513 case FLOAT_REGS:
14514 case ALTIVEC_REGS:
14515 case VSX_REGS:
14516 return VECTOR_REGISTER_TYPE;
14518 default:
14519 return OTHER_REGISTER_TYPE;
14523 /* Inform reload about cases where moving X with a mode MODE to a register in
14524 RCLASS requires an extra scratch or immediate register. Return the class
14525 needed for the immediate register.
14527 For VSX and Altivec, we may need a register to convert sp+offset into
14528 reg+sp. */
14530 static reg_class_t
14531 rs6000_secondary_reload (bool in_p,
14532 rtx x,
14533 reg_class_t rclass_i,
14534 enum machine_mode mode,
14535 secondary_reload_info *sri)
14537 enum reg_class rclass = (enum reg_class) rclass_i;
14538 reg_class_t ret = ALL_REGS;
14539 enum insn_code icode;
14540 bool default_p = false;
14542 sri->icode = CODE_FOR_nothing;
14544 /* Convert vector loads and stores into gprs to use an additional base
14545 register. */
14546 icode = rs6000_vector_reload[mode][in_p != false];
14547 if (icode != CODE_FOR_nothing)
14549 ret = NO_REGS;
14550 sri->icode = CODE_FOR_nothing;
14551 sri->extra_cost = 0;
14553 if (GET_CODE (x) == MEM)
14555 rtx addr = XEXP (x, 0);
14557 /* Loads to and stores from gprs can do reg+offset, and wouldn't need
14558 an extra register in that case, but it would need an extra
14559 register if the addressing is reg+reg or (reg+reg)&(-16). */
14560 if (rclass == GENERAL_REGS || rclass == BASE_REGS)
14562 if (!legitimate_indirect_address_p (addr, false)
14563 && !rs6000_legitimate_offset_address_p (TImode, addr, false))
14565 sri->icode = icode;
14566 /* account for splitting the loads, and converting the
14567 address from reg+reg to reg. */
14568 sri->extra_cost = (((TARGET_64BIT) ? 3 : 5)
14569 + ((GET_CODE (addr) == AND) ? 1 : 0));
14572 /* Loads to and stores from vector registers can only do reg+reg
14573 addressing. Altivec registers can also do (reg+reg)&(-16). */
14574 else if (rclass == VSX_REGS || rclass == ALTIVEC_REGS
14575 || rclass == FLOAT_REGS || rclass == NO_REGS)
14577 if (!VECTOR_MEM_ALTIVEC_P (mode)
14578 && GET_CODE (addr) == AND
14579 && GET_CODE (XEXP (addr, 1)) == CONST_INT
14580 && INTVAL (XEXP (addr, 1)) == -16
14581 && (legitimate_indirect_address_p (XEXP (addr, 0), false)
14582 || legitimate_indexed_address_p (XEXP (addr, 0), false)))
14584 sri->icode = icode;
14585 sri->extra_cost = ((GET_CODE (XEXP (addr, 0)) == PLUS)
14586 ? 2 : 1);
14588 else if (!legitimate_indirect_address_p (addr, false)
14589 && (rclass == NO_REGS
14590 || !legitimate_indexed_address_p (addr, false)))
14592 sri->icode = icode;
14593 sri->extra_cost = 1;
14595 else
14596 icode = CODE_FOR_nothing;
14598 /* Any other loads, including to pseudo registers which haven't been
14599 assigned to a register yet, default to require a scratch
14600 register. */
14601 else
14603 sri->icode = icode;
14604 sri->extra_cost = 2;
14607 else if (REG_P (x))
14609 int regno = true_regnum (x);
14611 icode = CODE_FOR_nothing;
14612 if (regno < 0 || regno >= FIRST_PSEUDO_REGISTER)
14613 default_p = true;
14614 else
14616 enum reg_class xclass = REGNO_REG_CLASS (regno);
14617 enum reload_reg_type rtype1 = rs6000_reload_register_type (rclass);
14618 enum reload_reg_type rtype2 = rs6000_reload_register_type (xclass);
14620 /* If memory is needed, use default_secondary_reload to create the
14621 stack slot. */
14622 if (rtype1 != rtype2 || rtype1 == OTHER_REGISTER_TYPE)
14623 default_p = true;
14624 else
14625 ret = NO_REGS;
14628 else
14629 default_p = true;
14631 else
14632 default_p = true;
14634 if (default_p)
14635 ret = default_secondary_reload (in_p, x, rclass, mode, sri);
14637 gcc_assert (ret != ALL_REGS);
14639 if (TARGET_DEBUG_ADDR)
14641 fprintf (stderr,
14642 "\nrs6000_secondary_reload, return %s, in_p = %s, rclass = %s, "
14643 "mode = %s",
14644 reg_class_names[ret],
14645 in_p ? "true" : "false",
14646 reg_class_names[rclass],
14647 GET_MODE_NAME (mode));
14649 if (default_p)
14650 fprintf (stderr, ", default secondary reload");
14652 if (sri->icode != CODE_FOR_nothing)
14653 fprintf (stderr, ", reload func = %s, extra cost = %d\n",
14654 insn_data[sri->icode].name, sri->extra_cost);
14655 else
14656 fprintf (stderr, "\n");
14658 debug_rtx (x);
14661 return ret;
14664 /* Fixup reload addresses for Altivec or VSX loads/stores to change SP+offset
14665 to SP+reg addressing. */
14667 void
14668 rs6000_secondary_reload_inner (rtx reg, rtx mem, rtx scratch, bool store_p)
14670 int regno = true_regnum (reg);
14671 enum machine_mode mode = GET_MODE (reg);
14672 enum reg_class rclass;
14673 rtx addr;
14674 rtx and_op2 = NULL_RTX;
14675 rtx addr_op1;
14676 rtx addr_op2;
14677 rtx scratch_or_premodify = scratch;
14678 rtx and_rtx;
14679 rtx cc_clobber;
14681 if (TARGET_DEBUG_ADDR)
14683 fprintf (stderr, "\nrs6000_secondary_reload_inner, type = %s\n",
14684 store_p ? "store" : "load");
14685 fprintf (stderr, "reg:\n");
14686 debug_rtx (reg);
14687 fprintf (stderr, "mem:\n");
14688 debug_rtx (mem);
14689 fprintf (stderr, "scratch:\n");
14690 debug_rtx (scratch);
14693 gcc_assert (regno >= 0 && regno < FIRST_PSEUDO_REGISTER);
14694 gcc_assert (GET_CODE (mem) == MEM);
14695 rclass = REGNO_REG_CLASS (regno);
14696 addr = XEXP (mem, 0);
14698 switch (rclass)
14700 /* GPRs can handle reg + small constant, all other addresses need to use
14701 the scratch register. */
14702 case GENERAL_REGS:
14703 case BASE_REGS:
14704 if (GET_CODE (addr) == AND)
14706 and_op2 = XEXP (addr, 1);
14707 addr = XEXP (addr, 0);
14710 if (GET_CODE (addr) == PRE_MODIFY)
14712 scratch_or_premodify = XEXP (addr, 0);
14713 gcc_assert (REG_P (scratch_or_premodify));
14714 gcc_assert (GET_CODE (XEXP (addr, 1)) == PLUS);
14715 addr = XEXP (addr, 1);
14718 if (GET_CODE (addr) == PLUS
14719 && (!rs6000_legitimate_offset_address_p (TImode, addr, false)
14720 || and_op2 != NULL_RTX))
14722 addr_op1 = XEXP (addr, 0);
14723 addr_op2 = XEXP (addr, 1);
14724 gcc_assert (legitimate_indirect_address_p (addr_op1, false));
14726 if (!REG_P (addr_op2)
14727 && (GET_CODE (addr_op2) != CONST_INT
14728 || !satisfies_constraint_I (addr_op2)))
14730 if (TARGET_DEBUG_ADDR)
14732 fprintf (stderr,
14733 "\nMove plus addr to register %s, mode = %s: ",
14734 rs6000_reg_names[REGNO (scratch)],
14735 GET_MODE_NAME (mode));
14736 debug_rtx (addr_op2);
14738 rs6000_emit_move (scratch, addr_op2, Pmode);
14739 addr_op2 = scratch;
14742 emit_insn (gen_rtx_SET (VOIDmode,
14743 scratch_or_premodify,
14744 gen_rtx_PLUS (Pmode,
14745 addr_op1,
14746 addr_op2)));
14748 addr = scratch_or_premodify;
14749 scratch_or_premodify = scratch;
14751 else if (!legitimate_indirect_address_p (addr, false)
14752 && !rs6000_legitimate_offset_address_p (TImode, addr, false))
14754 if (TARGET_DEBUG_ADDR)
14756 fprintf (stderr, "\nMove addr to register %s, mode = %s: ",
14757 rs6000_reg_names[REGNO (scratch_or_premodify)],
14758 GET_MODE_NAME (mode));
14759 debug_rtx (addr);
14761 rs6000_emit_move (scratch_or_premodify, addr, Pmode);
14762 addr = scratch_or_premodify;
14763 scratch_or_premodify = scratch;
14765 break;
14767 /* Float/Altivec registers can only handle reg+reg addressing. Move
14768 other addresses into a scratch register. */
14769 case FLOAT_REGS:
14770 case VSX_REGS:
14771 case ALTIVEC_REGS:
14773 /* With float regs, we need to handle the AND ourselves, since we can't
14774 use the Altivec instruction with an implicit AND -16. Allow scalar
14775 loads to float registers to use reg+offset even if VSX. */
14776 if (GET_CODE (addr) == AND
14777 && (rclass != ALTIVEC_REGS || GET_MODE_SIZE (mode) != 16
14778 || GET_CODE (XEXP (addr, 1)) != CONST_INT
14779 || INTVAL (XEXP (addr, 1)) != -16
14780 || !VECTOR_MEM_ALTIVEC_P (mode)))
14782 and_op2 = XEXP (addr, 1);
14783 addr = XEXP (addr, 0);
14786 /* If we aren't using a VSX load, save the PRE_MODIFY register and use it
14787 as the address later. */
14788 if (GET_CODE (addr) == PRE_MODIFY
14789 && (!VECTOR_MEM_VSX_P (mode)
14790 || and_op2 != NULL_RTX
14791 || !legitimate_indexed_address_p (XEXP (addr, 1), false)))
14793 scratch_or_premodify = XEXP (addr, 0);
14794 gcc_assert (legitimate_indirect_address_p (scratch_or_premodify,
14795 false));
14796 gcc_assert (GET_CODE (XEXP (addr, 1)) == PLUS);
14797 addr = XEXP (addr, 1);
14800 if (legitimate_indirect_address_p (addr, false) /* reg */
14801 || legitimate_indexed_address_p (addr, false) /* reg+reg */
14802 || GET_CODE (addr) == PRE_MODIFY /* VSX pre-modify */
14803 || (GET_CODE (addr) == AND /* Altivec memory */
14804 && GET_CODE (XEXP (addr, 1)) == CONST_INT
14805 && INTVAL (XEXP (addr, 1)) == -16
14806 && VECTOR_MEM_ALTIVEC_P (mode))
14807 || (rclass == FLOAT_REGS /* legacy float mem */
14808 && GET_MODE_SIZE (mode) == 8
14809 && and_op2 == NULL_RTX
14810 && scratch_or_premodify == scratch
14811 && rs6000_legitimate_offset_address_p (mode, addr, false)))
14814 else if (GET_CODE (addr) == PLUS)
14816 addr_op1 = XEXP (addr, 0);
14817 addr_op2 = XEXP (addr, 1);
14818 gcc_assert (REG_P (addr_op1));
14820 if (TARGET_DEBUG_ADDR)
14822 fprintf (stderr, "\nMove plus addr to register %s, mode = %s: ",
14823 rs6000_reg_names[REGNO (scratch)], GET_MODE_NAME (mode));
14824 debug_rtx (addr_op2);
14826 rs6000_emit_move (scratch, addr_op2, Pmode);
14827 emit_insn (gen_rtx_SET (VOIDmode,
14828 scratch_or_premodify,
14829 gen_rtx_PLUS (Pmode,
14830 addr_op1,
14831 scratch)));
14832 addr = scratch_or_premodify;
14833 scratch_or_premodify = scratch;
14836 else if (GET_CODE (addr) == SYMBOL_REF || GET_CODE (addr) == CONST
14837 || GET_CODE (addr) == CONST_INT || REG_P (addr))
14839 if (TARGET_DEBUG_ADDR)
14841 fprintf (stderr, "\nMove addr to register %s, mode = %s: ",
14842 rs6000_reg_names[REGNO (scratch_or_premodify)],
14843 GET_MODE_NAME (mode));
14844 debug_rtx (addr);
14847 rs6000_emit_move (scratch_or_premodify, addr, Pmode);
14848 addr = scratch_or_premodify;
14849 scratch_or_premodify = scratch;
14852 else
14853 gcc_unreachable ();
14855 break;
14857 default:
14858 gcc_unreachable ();
14861 /* If the original address involved a pre-modify that we couldn't use the VSX
14862 memory instruction with update, and we haven't taken care of already,
14863 store the address in the pre-modify register and use that as the
14864 address. */
14865 if (scratch_or_premodify != scratch && scratch_or_premodify != addr)
14867 emit_insn (gen_rtx_SET (VOIDmode, scratch_or_premodify, addr));
14868 addr = scratch_or_premodify;
14871 /* If the original address involved an AND -16 and we couldn't use an ALTIVEC
14872 memory instruction, recreate the AND now, including the clobber which is
14873 generated by the general ANDSI3/ANDDI3 patterns for the
14874 andi. instruction. */
14875 if (and_op2 != NULL_RTX)
14877 if (! legitimate_indirect_address_p (addr, false))
14879 emit_insn (gen_rtx_SET (VOIDmode, scratch, addr));
14880 addr = scratch;
14883 if (TARGET_DEBUG_ADDR)
14885 fprintf (stderr, "\nAnd addr to register %s, mode = %s: ",
14886 rs6000_reg_names[REGNO (scratch)], GET_MODE_NAME (mode));
14887 debug_rtx (and_op2);
14890 and_rtx = gen_rtx_SET (VOIDmode,
14891 scratch,
14892 gen_rtx_AND (Pmode,
14893 addr,
14894 and_op2));
14896 cc_clobber = gen_rtx_CLOBBER (CCmode, gen_rtx_SCRATCH (CCmode));
14897 emit_insn (gen_rtx_PARALLEL (VOIDmode,
14898 gen_rtvec (2, and_rtx, cc_clobber)));
14899 addr = scratch;
14902 /* Adjust the address if it changed. */
14903 if (addr != XEXP (mem, 0))
14905 mem = change_address (mem, mode, addr);
14906 if (TARGET_DEBUG_ADDR)
14907 fprintf (stderr, "\nrs6000_secondary_reload_inner, mem adjusted.\n");
14910 /* Now create the move. */
14911 if (store_p)
14912 emit_insn (gen_rtx_SET (VOIDmode, mem, reg));
14913 else
14914 emit_insn (gen_rtx_SET (VOIDmode, reg, mem));
14916 return;
14919 /* Target hook to return the cover classes for Integrated Register Allocator.
14920 Cover classes is a set of non-intersected register classes covering all hard
14921 registers used for register allocation purpose. Any move between two
14922 registers of a cover class should be cheaper than load or store of the
14923 registers. The value is array of register classes with LIM_REG_CLASSES used
14924 as the end marker.
14926 We need two IRA_COVER_CLASSES, one for pre-VSX, and the other for VSX to
14927 account for the Altivec and Floating registers being subsets of the VSX
14928 register set under VSX, but distinct register sets on pre-VSX machines. */
14930 static const reg_class_t *
14931 rs6000_ira_cover_classes (void)
14933 static const reg_class_t cover_pre_vsx[] = IRA_COVER_CLASSES_PRE_VSX;
14934 static const reg_class_t cover_vsx[] = IRA_COVER_CLASSES_VSX;
14936 return (TARGET_VSX) ? cover_vsx : cover_pre_vsx;
14939 /* Allocate a 64-bit stack slot to be used for copying SDmode
14940 values through if this function has any SDmode references. */
14942 static void
14943 rs6000_alloc_sdmode_stack_slot (void)
14945 tree t;
14946 basic_block bb;
14947 gimple_stmt_iterator gsi;
14949 gcc_assert (cfun->machine->sdmode_stack_slot == NULL_RTX);
14951 FOR_EACH_BB (bb)
14952 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
14954 tree ret = walk_gimple_op (gsi_stmt (gsi), rs6000_check_sdmode, NULL);
14955 if (ret)
14957 rtx stack = assign_stack_local (DDmode, GET_MODE_SIZE (DDmode), 0);
14958 cfun->machine->sdmode_stack_slot = adjust_address_nv (stack,
14959 SDmode, 0);
14960 return;
14964 /* Check for any SDmode parameters of the function. */
14965 for (t = DECL_ARGUMENTS (cfun->decl); t; t = DECL_CHAIN (t))
14967 if (TREE_TYPE (t) == error_mark_node)
14968 continue;
14970 if (TYPE_MODE (TREE_TYPE (t)) == SDmode
14971 || TYPE_MODE (DECL_ARG_TYPE (t)) == SDmode)
14973 rtx stack = assign_stack_local (DDmode, GET_MODE_SIZE (DDmode), 0);
14974 cfun->machine->sdmode_stack_slot = adjust_address_nv (stack,
14975 SDmode, 0);
14976 return;
14981 static void
14982 rs6000_instantiate_decls (void)
14984 if (cfun->machine->sdmode_stack_slot != NULL_RTX)
14985 instantiate_decl_rtl (cfun->machine->sdmode_stack_slot);
14988 /* Given an rtx X being reloaded into a reg required to be
14989 in class CLASS, return the class of reg to actually use.
14990 In general this is just CLASS; but on some machines
14991 in some cases it is preferable to use a more restrictive class.
14993 On the RS/6000, we have to return NO_REGS when we want to reload a
14994 floating-point CONST_DOUBLE to force it to be copied to memory.
14996 We also don't want to reload integer values into floating-point
14997 registers if we can at all help it. In fact, this can
14998 cause reload to die, if it tries to generate a reload of CTR
14999 into a FP register and discovers it doesn't have the memory location
15000 required.
15002 ??? Would it be a good idea to have reload do the converse, that is
15003 try to reload floating modes into FP registers if possible?
15006 static enum reg_class
15007 rs6000_preferred_reload_class (rtx x, enum reg_class rclass)
15009 enum machine_mode mode = GET_MODE (x);
15011 if (VECTOR_UNIT_VSX_P (mode)
15012 && x == CONST0_RTX (mode) && VSX_REG_CLASS_P (rclass))
15013 return rclass;
15015 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode)
15016 && (rclass == ALTIVEC_REGS || rclass == VSX_REGS)
15017 && easy_vector_constant (x, mode))
15018 return ALTIVEC_REGS;
15020 if (CONSTANT_P (x) && reg_classes_intersect_p (rclass, FLOAT_REGS))
15021 return NO_REGS;
15023 if (GET_MODE_CLASS (mode) == MODE_INT && rclass == NON_SPECIAL_REGS)
15024 return GENERAL_REGS;
15026 /* For VSX, prefer the traditional registers for 64-bit values because we can
15027 use the non-VSX loads. Prefer the Altivec registers if Altivec is
15028 handling the vector operations (i.e. V16QI, V8HI, and V4SI), or if we
15029 prefer Altivec loads.. */
15030 if (rclass == VSX_REGS)
15032 if (GET_MODE_SIZE (mode) <= 8)
15033 return FLOAT_REGS;
15035 if (VECTOR_UNIT_ALTIVEC_P (mode) || VECTOR_MEM_ALTIVEC_P (mode))
15036 return ALTIVEC_REGS;
15038 return rclass;
15041 return rclass;
15044 /* Debug version of rs6000_preferred_reload_class. */
15045 static enum reg_class
15046 rs6000_debug_preferred_reload_class (rtx x, enum reg_class rclass)
15048 enum reg_class ret = rs6000_preferred_reload_class (x, rclass);
15050 fprintf (stderr,
15051 "\nrs6000_preferred_reload_class, return %s, rclass = %s, "
15052 "mode = %s, x:\n",
15053 reg_class_names[ret], reg_class_names[rclass],
15054 GET_MODE_NAME (GET_MODE (x)));
15055 debug_rtx (x);
15057 return ret;
15060 /* If we are copying between FP or AltiVec registers and anything else, we need
15061 a memory location. The exception is when we are targeting ppc64 and the
15062 move to/from fpr to gpr instructions are available. Also, under VSX, you
15063 can copy vector registers from the FP register set to the Altivec register
15064 set and vice versa. */
15066 static bool
15067 rs6000_secondary_memory_needed (enum reg_class class1,
15068 enum reg_class class2,
15069 enum machine_mode mode)
15071 if (class1 == class2)
15072 return false;
15074 /* Under VSX, there are 3 register classes that values could be in (VSX_REGS,
15075 ALTIVEC_REGS, and FLOAT_REGS). We don't need to use memory to copy
15076 between these classes. But we need memory for other things that can go in
15077 FLOAT_REGS like SFmode. */
15078 if (TARGET_VSX
15079 && (VECTOR_MEM_VSX_P (mode) || VECTOR_UNIT_VSX_P (mode))
15080 && (class1 == VSX_REGS || class1 == ALTIVEC_REGS
15081 || class1 == FLOAT_REGS))
15082 return (class2 != VSX_REGS && class2 != ALTIVEC_REGS
15083 && class2 != FLOAT_REGS);
15085 if (class1 == VSX_REGS || class2 == VSX_REGS)
15086 return true;
15088 if (class1 == FLOAT_REGS
15089 && (!TARGET_MFPGPR || !TARGET_POWERPC64
15090 || ((mode != DFmode)
15091 && (mode != DDmode)
15092 && (mode != DImode))))
15093 return true;
15095 if (class2 == FLOAT_REGS
15096 && (!TARGET_MFPGPR || !TARGET_POWERPC64
15097 || ((mode != DFmode)
15098 && (mode != DDmode)
15099 && (mode != DImode))))
15100 return true;
15102 if (class1 == ALTIVEC_REGS || class2 == ALTIVEC_REGS)
15103 return true;
15105 return false;
15108 /* Debug version of rs6000_secondary_memory_needed. */
15109 static bool
15110 rs6000_debug_secondary_memory_needed (enum reg_class class1,
15111 enum reg_class class2,
15112 enum machine_mode mode)
15114 bool ret = rs6000_secondary_memory_needed (class1, class2, mode);
15116 fprintf (stderr,
15117 "rs6000_secondary_memory_needed, return: %s, class1 = %s, "
15118 "class2 = %s, mode = %s\n",
15119 ret ? "true" : "false", reg_class_names[class1],
15120 reg_class_names[class2], GET_MODE_NAME (mode));
15122 return ret;
15125 /* Return the register class of a scratch register needed to copy IN into
15126 or out of a register in RCLASS in MODE. If it can be done directly,
15127 NO_REGS is returned. */
15129 static enum reg_class
15130 rs6000_secondary_reload_class (enum reg_class rclass, enum machine_mode mode,
15131 rtx in)
15133 int regno;
15135 if (TARGET_ELF || (DEFAULT_ABI == ABI_DARWIN
15136 #if TARGET_MACHO
15137 && MACHOPIC_INDIRECT
15138 #endif
15141 /* We cannot copy a symbolic operand directly into anything
15142 other than BASE_REGS for TARGET_ELF. So indicate that a
15143 register from BASE_REGS is needed as an intermediate
15144 register.
15146 On Darwin, pic addresses require a load from memory, which
15147 needs a base register. */
15148 if (rclass != BASE_REGS
15149 && (GET_CODE (in) == SYMBOL_REF
15150 || GET_CODE (in) == HIGH
15151 || GET_CODE (in) == LABEL_REF
15152 || GET_CODE (in) == CONST))
15153 return BASE_REGS;
15156 if (GET_CODE (in) == REG)
15158 regno = REGNO (in);
15159 if (regno >= FIRST_PSEUDO_REGISTER)
15161 regno = true_regnum (in);
15162 if (regno >= FIRST_PSEUDO_REGISTER)
15163 regno = -1;
15166 else if (GET_CODE (in) == SUBREG)
15168 regno = true_regnum (in);
15169 if (regno >= FIRST_PSEUDO_REGISTER)
15170 regno = -1;
15172 else
15173 regno = -1;
15175 /* We can place anything into GENERAL_REGS and can put GENERAL_REGS
15176 into anything. */
15177 if (rclass == GENERAL_REGS || rclass == BASE_REGS
15178 || (regno >= 0 && INT_REGNO_P (regno)))
15179 return NO_REGS;
15181 /* Constants, memory, and FP registers can go into FP registers. */
15182 if ((regno == -1 || FP_REGNO_P (regno))
15183 && (rclass == FLOAT_REGS || rclass == NON_SPECIAL_REGS))
15184 return (mode != SDmode) ? NO_REGS : GENERAL_REGS;
15186 /* Memory, and FP/altivec registers can go into fp/altivec registers under
15187 VSX. */
15188 if (TARGET_VSX
15189 && (regno == -1 || VSX_REGNO_P (regno))
15190 && VSX_REG_CLASS_P (rclass))
15191 return NO_REGS;
15193 /* Memory, and AltiVec registers can go into AltiVec registers. */
15194 if ((regno == -1 || ALTIVEC_REGNO_P (regno))
15195 && rclass == ALTIVEC_REGS)
15196 return NO_REGS;
15198 /* We can copy among the CR registers. */
15199 if ((rclass == CR_REGS || rclass == CR0_REGS)
15200 && regno >= 0 && CR_REGNO_P (regno))
15201 return NO_REGS;
15203 /* Otherwise, we need GENERAL_REGS. */
15204 return GENERAL_REGS;
15207 /* Debug version of rs6000_secondary_reload_class. */
15208 static enum reg_class
15209 rs6000_debug_secondary_reload_class (enum reg_class rclass,
15210 enum machine_mode mode, rtx in)
15212 enum reg_class ret = rs6000_secondary_reload_class (rclass, mode, in);
15213 fprintf (stderr,
15214 "\nrs6000_secondary_reload_class, return %s, rclass = %s, "
15215 "mode = %s, input rtx:\n",
15216 reg_class_names[ret], reg_class_names[rclass],
15217 GET_MODE_NAME (mode));
15218 debug_rtx (in);
15220 return ret;
15223 /* Return nonzero if for CLASS a mode change from FROM to TO is invalid. */
15225 static bool
15226 rs6000_cannot_change_mode_class (enum machine_mode from,
15227 enum machine_mode to,
15228 enum reg_class rclass)
15230 unsigned from_size = GET_MODE_SIZE (from);
15231 unsigned to_size = GET_MODE_SIZE (to);
15233 if (from_size != to_size)
15235 enum reg_class xclass = (TARGET_VSX) ? VSX_REGS : FLOAT_REGS;
15236 return ((from_size < 8 || to_size < 8 || TARGET_IEEEQUAD)
15237 && reg_classes_intersect_p (xclass, rclass));
15240 if (TARGET_E500_DOUBLE
15241 && ((((to) == DFmode) + ((from) == DFmode)) == 1
15242 || (((to) == TFmode) + ((from) == TFmode)) == 1
15243 || (((to) == DDmode) + ((from) == DDmode)) == 1
15244 || (((to) == TDmode) + ((from) == TDmode)) == 1
15245 || (((to) == DImode) + ((from) == DImode)) == 1))
15246 return true;
15248 /* Since the VSX register set includes traditional floating point registers
15249 and altivec registers, just check for the size being different instead of
15250 trying to check whether the modes are vector modes. Otherwise it won't
15251 allow say DF and DI to change classes. */
15252 if (TARGET_VSX && VSX_REG_CLASS_P (rclass))
15253 return (from_size != 8 && from_size != 16);
15255 if (TARGET_ALTIVEC && rclass == ALTIVEC_REGS
15256 && (ALTIVEC_VECTOR_MODE (from) + ALTIVEC_VECTOR_MODE (to)) == 1)
15257 return true;
15259 if (TARGET_SPE && (SPE_VECTOR_MODE (from) + SPE_VECTOR_MODE (to)) == 1
15260 && reg_classes_intersect_p (GENERAL_REGS, rclass))
15261 return true;
15263 return false;
15266 /* Debug version of rs6000_cannot_change_mode_class. */
15267 static bool
15268 rs6000_debug_cannot_change_mode_class (enum machine_mode from,
15269 enum machine_mode to,
15270 enum reg_class rclass)
15272 bool ret = rs6000_cannot_change_mode_class (from, to, rclass);
15274 fprintf (stderr,
15275 "rs6000_cannot_change_mode_class, return %s, from = %s, "
15276 "to = %s, rclass = %s\n",
15277 ret ? "true" : "false",
15278 GET_MODE_NAME (from), GET_MODE_NAME (to),
15279 reg_class_names[rclass]);
15281 return ret;
15284 /* Given a comparison operation, return the bit number in CCR to test. We
15285 know this is a valid comparison.
15287 SCC_P is 1 if this is for an scc. That means that %D will have been
15288 used instead of %C, so the bits will be in different places.
15290 Return -1 if OP isn't a valid comparison for some reason. */
15293 ccr_bit (rtx op, int scc_p)
15295 enum rtx_code code = GET_CODE (op);
15296 enum machine_mode cc_mode;
15297 int cc_regnum;
15298 int base_bit;
15299 rtx reg;
15301 if (!COMPARISON_P (op))
15302 return -1;
15304 reg = XEXP (op, 0);
15306 gcc_assert (GET_CODE (reg) == REG && CR_REGNO_P (REGNO (reg)));
15308 cc_mode = GET_MODE (reg);
15309 cc_regnum = REGNO (reg);
15310 base_bit = 4 * (cc_regnum - CR0_REGNO);
15312 validate_condition_mode (code, cc_mode);
15314 /* When generating a sCOND operation, only positive conditions are
15315 allowed. */
15316 gcc_assert (!scc_p
15317 || code == EQ || code == GT || code == LT || code == UNORDERED
15318 || code == GTU || code == LTU);
15320 switch (code)
15322 case NE:
15323 return scc_p ? base_bit + 3 : base_bit + 2;
15324 case EQ:
15325 return base_bit + 2;
15326 case GT: case GTU: case UNLE:
15327 return base_bit + 1;
15328 case LT: case LTU: case UNGE:
15329 return base_bit;
15330 case ORDERED: case UNORDERED:
15331 return base_bit + 3;
15333 case GE: case GEU:
15334 /* If scc, we will have done a cror to put the bit in the
15335 unordered position. So test that bit. For integer, this is ! LT
15336 unless this is an scc insn. */
15337 return scc_p ? base_bit + 3 : base_bit;
15339 case LE: case LEU:
15340 return scc_p ? base_bit + 3 : base_bit + 1;
15342 default:
15343 gcc_unreachable ();
15347 /* Return the GOT register. */
15350 rs6000_got_register (rtx value ATTRIBUTE_UNUSED)
15352 /* The second flow pass currently (June 1999) can't update
15353 regs_ever_live without disturbing other parts of the compiler, so
15354 update it here to make the prolog/epilogue code happy. */
15355 if (!can_create_pseudo_p ()
15356 && !df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM))
15357 df_set_regs_ever_live (RS6000_PIC_OFFSET_TABLE_REGNUM, true);
15359 crtl->uses_pic_offset_table = 1;
15361 return pic_offset_table_rtx;
15364 static rs6000_stack_t stack_info;
15366 /* Function to init struct machine_function.
15367 This will be called, via a pointer variable,
15368 from push_function_context. */
15370 static struct machine_function *
15371 rs6000_init_machine_status (void)
15373 stack_info.reload_completed = 0;
15374 return ggc_alloc_cleared_machine_function ();
15377 /* These macros test for integers and extract the low-order bits. */
15378 #define INT_P(X) \
15379 ((GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST_DOUBLE) \
15380 && GET_MODE (X) == VOIDmode)
15382 #define INT_LOWPART(X) \
15383 (GET_CODE (X) == CONST_INT ? INTVAL (X) : CONST_DOUBLE_LOW (X))
15386 extract_MB (rtx op)
15388 int i;
15389 unsigned long val = INT_LOWPART (op);
15391 /* If the high bit is zero, the value is the first 1 bit we find
15392 from the left. */
15393 if ((val & 0x80000000) == 0)
15395 gcc_assert (val & 0xffffffff);
15397 i = 1;
15398 while (((val <<= 1) & 0x80000000) == 0)
15399 ++i;
15400 return i;
15403 /* If the high bit is set and the low bit is not, or the mask is all
15404 1's, the value is zero. */
15405 if ((val & 1) == 0 || (val & 0xffffffff) == 0xffffffff)
15406 return 0;
15408 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
15409 from the right. */
15410 i = 31;
15411 while (((val >>= 1) & 1) != 0)
15412 --i;
15414 return i;
15418 extract_ME (rtx op)
15420 int i;
15421 unsigned long val = INT_LOWPART (op);
15423 /* If the low bit is zero, the value is the first 1 bit we find from
15424 the right. */
15425 if ((val & 1) == 0)
15427 gcc_assert (val & 0xffffffff);
15429 i = 30;
15430 while (((val >>= 1) & 1) == 0)
15431 --i;
15433 return i;
15436 /* If the low bit is set and the high bit is not, or the mask is all
15437 1's, the value is 31. */
15438 if ((val & 0x80000000) == 0 || (val & 0xffffffff) == 0xffffffff)
15439 return 31;
15441 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
15442 from the left. */
15443 i = 0;
15444 while (((val <<= 1) & 0x80000000) != 0)
15445 ++i;
15447 return i;
15450 /* Locate some local-dynamic symbol still in use by this function
15451 so that we can print its name in some tls_ld pattern. */
15453 static const char *
15454 rs6000_get_some_local_dynamic_name (void)
15456 rtx insn;
15458 if (cfun->machine->some_ld_name)
15459 return cfun->machine->some_ld_name;
15461 for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
15462 if (INSN_P (insn)
15463 && for_each_rtx (&PATTERN (insn),
15464 rs6000_get_some_local_dynamic_name_1, 0))
15465 return cfun->machine->some_ld_name;
15467 gcc_unreachable ();
15470 /* Helper function for rs6000_get_some_local_dynamic_name. */
15472 static int
15473 rs6000_get_some_local_dynamic_name_1 (rtx *px, void *data ATTRIBUTE_UNUSED)
15475 rtx x = *px;
15477 if (GET_CODE (x) == SYMBOL_REF)
15479 const char *str = XSTR (x, 0);
15480 if (SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_DYNAMIC)
15482 cfun->machine->some_ld_name = str;
15483 return 1;
15487 return 0;
15490 /* Write out a function code label. */
15492 void
15493 rs6000_output_function_entry (FILE *file, const char *fname)
15495 if (fname[0] != '.')
15497 switch (DEFAULT_ABI)
15499 default:
15500 gcc_unreachable ();
15502 case ABI_AIX:
15503 if (DOT_SYMBOLS)
15504 putc ('.', file);
15505 else
15506 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "L.");
15507 break;
15509 case ABI_V4:
15510 case ABI_DARWIN:
15511 break;
15515 RS6000_OUTPUT_BASENAME (file, fname);
15518 /* Print an operand. Recognize special options, documented below. */
15520 #if TARGET_ELF
15521 #define SMALL_DATA_RELOC ((rs6000_sdata == SDATA_EABI) ? "sda21" : "sdarel")
15522 #define SMALL_DATA_REG ((rs6000_sdata == SDATA_EABI) ? 0 : 13)
15523 #else
15524 #define SMALL_DATA_RELOC "sda21"
15525 #define SMALL_DATA_REG 0
15526 #endif
15528 void
15529 print_operand (FILE *file, rtx x, int code)
15531 int i;
15532 HOST_WIDE_INT val;
15533 unsigned HOST_WIDE_INT uval;
15535 switch (code)
15537 case '.':
15538 /* Write out an instruction after the call which may be replaced
15539 with glue code by the loader. This depends on the AIX version. */
15540 asm_fprintf (file, RS6000_CALL_GLUE);
15541 return;
15543 /* %a is output_address. */
15545 case 'A':
15546 /* If X is a constant integer whose low-order 5 bits are zero,
15547 write 'l'. Otherwise, write 'r'. This is a kludge to fix a bug
15548 in the AIX assembler where "sri" with a zero shift count
15549 writes a trash instruction. */
15550 if (GET_CODE (x) == CONST_INT && (INTVAL (x) & 31) == 0)
15551 putc ('l', file);
15552 else
15553 putc ('r', file);
15554 return;
15556 case 'b':
15557 /* If constant, low-order 16 bits of constant, unsigned.
15558 Otherwise, write normally. */
15559 if (INT_P (x))
15560 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 0xffff);
15561 else
15562 print_operand (file, x, 0);
15563 return;
15565 case 'B':
15566 /* If the low-order bit is zero, write 'r'; otherwise, write 'l'
15567 for 64-bit mask direction. */
15568 putc (((INT_LOWPART (x) & 1) == 0 ? 'r' : 'l'), file);
15569 return;
15571 /* %c is output_addr_const if a CONSTANT_ADDRESS_P, otherwise
15572 output_operand. */
15574 case 'c':
15575 /* X is a CR register. Print the number of the GT bit of the CR. */
15576 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15577 output_operand_lossage ("invalid %%c value");
15578 else
15579 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 1);
15580 return;
15582 case 'D':
15583 /* Like 'J' but get to the GT bit only. */
15584 gcc_assert (GET_CODE (x) == REG);
15586 /* Bit 1 is GT bit. */
15587 i = 4 * (REGNO (x) - CR0_REGNO) + 1;
15589 /* Add one for shift count in rlinm for scc. */
15590 fprintf (file, "%d", i + 1);
15591 return;
15593 case 'E':
15594 /* X is a CR register. Print the number of the EQ bit of the CR */
15595 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15596 output_operand_lossage ("invalid %%E value");
15597 else
15598 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 2);
15599 return;
15601 case 'f':
15602 /* X is a CR register. Print the shift count needed to move it
15603 to the high-order four bits. */
15604 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15605 output_operand_lossage ("invalid %%f value");
15606 else
15607 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO));
15608 return;
15610 case 'F':
15611 /* Similar, but print the count for the rotate in the opposite
15612 direction. */
15613 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15614 output_operand_lossage ("invalid %%F value");
15615 else
15616 fprintf (file, "%d", 32 - 4 * (REGNO (x) - CR0_REGNO));
15617 return;
15619 case 'G':
15620 /* X is a constant integer. If it is negative, print "m",
15621 otherwise print "z". This is to make an aze or ame insn. */
15622 if (GET_CODE (x) != CONST_INT)
15623 output_operand_lossage ("invalid %%G value");
15624 else if (INTVAL (x) >= 0)
15625 putc ('z', file);
15626 else
15627 putc ('m', file);
15628 return;
15630 case 'h':
15631 /* If constant, output low-order five bits. Otherwise, write
15632 normally. */
15633 if (INT_P (x))
15634 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 31);
15635 else
15636 print_operand (file, x, 0);
15637 return;
15639 case 'H':
15640 /* If constant, output low-order six bits. Otherwise, write
15641 normally. */
15642 if (INT_P (x))
15643 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 63);
15644 else
15645 print_operand (file, x, 0);
15646 return;
15648 case 'I':
15649 /* Print `i' if this is a constant, else nothing. */
15650 if (INT_P (x))
15651 putc ('i', file);
15652 return;
15654 case 'j':
15655 /* Write the bit number in CCR for jump. */
15656 i = ccr_bit (x, 0);
15657 if (i == -1)
15658 output_operand_lossage ("invalid %%j code");
15659 else
15660 fprintf (file, "%d", i);
15661 return;
15663 case 'J':
15664 /* Similar, but add one for shift count in rlinm for scc and pass
15665 scc flag to `ccr_bit'. */
15666 i = ccr_bit (x, 1);
15667 if (i == -1)
15668 output_operand_lossage ("invalid %%J code");
15669 else
15670 /* If we want bit 31, write a shift count of zero, not 32. */
15671 fprintf (file, "%d", i == 31 ? 0 : i + 1);
15672 return;
15674 case 'k':
15675 /* X must be a constant. Write the 1's complement of the
15676 constant. */
15677 if (! INT_P (x))
15678 output_operand_lossage ("invalid %%k value");
15679 else
15680 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ~ INT_LOWPART (x));
15681 return;
15683 case 'K':
15684 /* X must be a symbolic constant on ELF. Write an
15685 expression suitable for an 'addi' that adds in the low 16
15686 bits of the MEM. */
15687 if (GET_CODE (x) == CONST)
15689 if (GET_CODE (XEXP (x, 0)) != PLUS
15690 || (GET_CODE (XEXP (XEXP (x, 0), 0)) != SYMBOL_REF
15691 && GET_CODE (XEXP (XEXP (x, 0), 0)) != LABEL_REF)
15692 || GET_CODE (XEXP (XEXP (x, 0), 1)) != CONST_INT)
15693 output_operand_lossage ("invalid %%K value");
15695 print_operand_address (file, x);
15696 fputs ("@l", file);
15697 return;
15699 /* %l is output_asm_label. */
15701 case 'L':
15702 /* Write second word of DImode or DFmode reference. Works on register
15703 or non-indexed memory only. */
15704 if (GET_CODE (x) == REG)
15705 fputs (reg_names[REGNO (x) + 1], file);
15706 else if (GET_CODE (x) == MEM)
15708 /* Handle possible auto-increment. Since it is pre-increment and
15709 we have already done it, we can just use an offset of word. */
15710 if (GET_CODE (XEXP (x, 0)) == PRE_INC
15711 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
15712 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
15713 UNITS_PER_WORD));
15714 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
15715 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
15716 UNITS_PER_WORD));
15717 else
15718 output_address (XEXP (adjust_address_nv (x, SImode,
15719 UNITS_PER_WORD),
15720 0));
15722 if (small_data_operand (x, GET_MODE (x)))
15723 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
15724 reg_names[SMALL_DATA_REG]);
15726 return;
15728 case 'm':
15729 /* MB value for a mask operand. */
15730 if (! mask_operand (x, SImode))
15731 output_operand_lossage ("invalid %%m value");
15733 fprintf (file, "%d", extract_MB (x));
15734 return;
15736 case 'M':
15737 /* ME value for a mask operand. */
15738 if (! mask_operand (x, SImode))
15739 output_operand_lossage ("invalid %%M value");
15741 fprintf (file, "%d", extract_ME (x));
15742 return;
15744 /* %n outputs the negative of its operand. */
15746 case 'N':
15747 /* Write the number of elements in the vector times 4. */
15748 if (GET_CODE (x) != PARALLEL)
15749 output_operand_lossage ("invalid %%N value");
15750 else
15751 fprintf (file, "%d", XVECLEN (x, 0) * 4);
15752 return;
15754 case 'O':
15755 /* Similar, but subtract 1 first. */
15756 if (GET_CODE (x) != PARALLEL)
15757 output_operand_lossage ("invalid %%O value");
15758 else
15759 fprintf (file, "%d", (XVECLEN (x, 0) - 1) * 4);
15760 return;
15762 case 'p':
15763 /* X is a CONST_INT that is a power of two. Output the logarithm. */
15764 if (! INT_P (x)
15765 || INT_LOWPART (x) < 0
15766 || (i = exact_log2 (INT_LOWPART (x))) < 0)
15767 output_operand_lossage ("invalid %%p value");
15768 else
15769 fprintf (file, "%d", i);
15770 return;
15772 case 'P':
15773 /* The operand must be an indirect memory reference. The result
15774 is the register name. */
15775 if (GET_CODE (x) != MEM || GET_CODE (XEXP (x, 0)) != REG
15776 || REGNO (XEXP (x, 0)) >= 32)
15777 output_operand_lossage ("invalid %%P value");
15778 else
15779 fputs (reg_names[REGNO (XEXP (x, 0))], file);
15780 return;
15782 case 'q':
15783 /* This outputs the logical code corresponding to a boolean
15784 expression. The expression may have one or both operands
15785 negated (if one, only the first one). For condition register
15786 logical operations, it will also treat the negated
15787 CR codes as NOTs, but not handle NOTs of them. */
15789 const char *const *t = 0;
15790 const char *s;
15791 enum rtx_code code = GET_CODE (x);
15792 static const char * const tbl[3][3] = {
15793 { "and", "andc", "nor" },
15794 { "or", "orc", "nand" },
15795 { "xor", "eqv", "xor" } };
15797 if (code == AND)
15798 t = tbl[0];
15799 else if (code == IOR)
15800 t = tbl[1];
15801 else if (code == XOR)
15802 t = tbl[2];
15803 else
15804 output_operand_lossage ("invalid %%q value");
15806 if (GET_CODE (XEXP (x, 0)) != NOT)
15807 s = t[0];
15808 else
15810 if (GET_CODE (XEXP (x, 1)) == NOT)
15811 s = t[2];
15812 else
15813 s = t[1];
15816 fputs (s, file);
15818 return;
15820 case 'Q':
15821 if (TARGET_MFCRF)
15822 fputc (',', file);
15823 /* FALLTHRU */
15824 else
15825 return;
15827 case 'R':
15828 /* X is a CR register. Print the mask for `mtcrf'. */
15829 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15830 output_operand_lossage ("invalid %%R value");
15831 else
15832 fprintf (file, "%d", 128 >> (REGNO (x) - CR0_REGNO));
15833 return;
15835 case 's':
15836 /* Low 5 bits of 32 - value */
15837 if (! INT_P (x))
15838 output_operand_lossage ("invalid %%s value");
15839 else
15840 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (32 - INT_LOWPART (x)) & 31);
15841 return;
15843 case 'S':
15844 /* PowerPC64 mask position. All 0's is excluded.
15845 CONST_INT 32-bit mask is considered sign-extended so any
15846 transition must occur within the CONST_INT, not on the boundary. */
15847 if (! mask64_operand (x, DImode))
15848 output_operand_lossage ("invalid %%S value");
15850 uval = INT_LOWPART (x);
15852 if (uval & 1) /* Clear Left */
15854 #if HOST_BITS_PER_WIDE_INT > 64
15855 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
15856 #endif
15857 i = 64;
15859 else /* Clear Right */
15861 uval = ~uval;
15862 #if HOST_BITS_PER_WIDE_INT > 64
15863 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
15864 #endif
15865 i = 63;
15867 while (uval != 0)
15868 --i, uval >>= 1;
15869 gcc_assert (i >= 0);
15870 fprintf (file, "%d", i);
15871 return;
15873 case 't':
15874 /* Like 'J' but get to the OVERFLOW/UNORDERED bit. */
15875 gcc_assert (GET_CODE (x) == REG && GET_MODE (x) == CCmode);
15877 /* Bit 3 is OV bit. */
15878 i = 4 * (REGNO (x) - CR0_REGNO) + 3;
15880 /* If we want bit 31, write a shift count of zero, not 32. */
15881 fprintf (file, "%d", i == 31 ? 0 : i + 1);
15882 return;
15884 case 'T':
15885 /* Print the symbolic name of a branch target register. */
15886 if (GET_CODE (x) != REG || (REGNO (x) != LR_REGNO
15887 && REGNO (x) != CTR_REGNO))
15888 output_operand_lossage ("invalid %%T value");
15889 else if (REGNO (x) == LR_REGNO)
15890 fputs (TARGET_NEW_MNEMONICS ? "lr" : "r", file);
15891 else
15892 fputs ("ctr", file);
15893 return;
15895 case 'u':
15896 /* High-order 16 bits of constant for use in unsigned operand. */
15897 if (! INT_P (x))
15898 output_operand_lossage ("invalid %%u value");
15899 else
15900 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
15901 (INT_LOWPART (x) >> 16) & 0xffff);
15902 return;
15904 case 'v':
15905 /* High-order 16 bits of constant for use in signed operand. */
15906 if (! INT_P (x))
15907 output_operand_lossage ("invalid %%v value");
15908 else
15909 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
15910 (INT_LOWPART (x) >> 16) & 0xffff);
15911 return;
15913 case 'U':
15914 /* Print `u' if this has an auto-increment or auto-decrement. */
15915 if (GET_CODE (x) == MEM
15916 && (GET_CODE (XEXP (x, 0)) == PRE_INC
15917 || GET_CODE (XEXP (x, 0)) == PRE_DEC
15918 || GET_CODE (XEXP (x, 0)) == PRE_MODIFY))
15919 putc ('u', file);
15920 return;
15922 case 'V':
15923 /* Print the trap code for this operand. */
15924 switch (GET_CODE (x))
15926 case EQ:
15927 fputs ("eq", file); /* 4 */
15928 break;
15929 case NE:
15930 fputs ("ne", file); /* 24 */
15931 break;
15932 case LT:
15933 fputs ("lt", file); /* 16 */
15934 break;
15935 case LE:
15936 fputs ("le", file); /* 20 */
15937 break;
15938 case GT:
15939 fputs ("gt", file); /* 8 */
15940 break;
15941 case GE:
15942 fputs ("ge", file); /* 12 */
15943 break;
15944 case LTU:
15945 fputs ("llt", file); /* 2 */
15946 break;
15947 case LEU:
15948 fputs ("lle", file); /* 6 */
15949 break;
15950 case GTU:
15951 fputs ("lgt", file); /* 1 */
15952 break;
15953 case GEU:
15954 fputs ("lge", file); /* 5 */
15955 break;
15956 default:
15957 gcc_unreachable ();
15959 break;
15961 case 'w':
15962 /* If constant, low-order 16 bits of constant, signed. Otherwise, write
15963 normally. */
15964 if (INT_P (x))
15965 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
15966 ((INT_LOWPART (x) & 0xffff) ^ 0x8000) - 0x8000);
15967 else
15968 print_operand (file, x, 0);
15969 return;
15971 case 'W':
15972 /* MB value for a PowerPC64 rldic operand. */
15973 val = (GET_CODE (x) == CONST_INT
15974 ? INTVAL (x) : CONST_DOUBLE_HIGH (x));
15976 if (val < 0)
15977 i = -1;
15978 else
15979 for (i = 0; i < HOST_BITS_PER_WIDE_INT; i++)
15980 if ((val <<= 1) < 0)
15981 break;
15983 #if HOST_BITS_PER_WIDE_INT == 32
15984 if (GET_CODE (x) == CONST_INT && i >= 0)
15985 i += 32; /* zero-extend high-part was all 0's */
15986 else if (GET_CODE (x) == CONST_DOUBLE && i == 32)
15988 val = CONST_DOUBLE_LOW (x);
15990 gcc_assert (val);
15991 if (val < 0)
15992 --i;
15993 else
15994 for ( ; i < 64; i++)
15995 if ((val <<= 1) < 0)
15996 break;
15998 #endif
16000 fprintf (file, "%d", i + 1);
16001 return;
16003 case 'x':
16004 /* X is a FPR or Altivec register used in a VSX context. */
16005 if (GET_CODE (x) != REG || !VSX_REGNO_P (REGNO (x)))
16006 output_operand_lossage ("invalid %%x value");
16007 else
16009 int reg = REGNO (x);
16010 int vsx_reg = (FP_REGNO_P (reg)
16011 ? reg - 32
16012 : reg - FIRST_ALTIVEC_REGNO + 32);
16014 #ifdef TARGET_REGNAMES
16015 if (TARGET_REGNAMES)
16016 fprintf (file, "%%vs%d", vsx_reg);
16017 else
16018 #endif
16019 fprintf (file, "%d", vsx_reg);
16021 return;
16023 case 'X':
16024 if (GET_CODE (x) == MEM
16025 && (legitimate_indexed_address_p (XEXP (x, 0), 0)
16026 || (GET_CODE (XEXP (x, 0)) == PRE_MODIFY
16027 && legitimate_indexed_address_p (XEXP (XEXP (x, 0), 1), 0))))
16028 putc ('x', file);
16029 return;
16031 case 'Y':
16032 /* Like 'L', for third word of TImode */
16033 if (GET_CODE (x) == REG)
16034 fputs (reg_names[REGNO (x) + 2], file);
16035 else if (GET_CODE (x) == MEM)
16037 if (GET_CODE (XEXP (x, 0)) == PRE_INC
16038 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
16039 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
16040 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
16041 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
16042 else
16043 output_address (XEXP (adjust_address_nv (x, SImode, 8), 0));
16044 if (small_data_operand (x, GET_MODE (x)))
16045 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
16046 reg_names[SMALL_DATA_REG]);
16048 return;
16050 case 'z':
16051 /* X is a SYMBOL_REF. Write out the name preceded by a
16052 period and without any trailing data in brackets. Used for function
16053 names. If we are configured for System V (or the embedded ABI) on
16054 the PowerPC, do not emit the period, since those systems do not use
16055 TOCs and the like. */
16056 gcc_assert (GET_CODE (x) == SYMBOL_REF);
16058 /* Mark the decl as referenced so that cgraph will output the
16059 function. */
16060 if (SYMBOL_REF_DECL (x))
16061 mark_decl_referenced (SYMBOL_REF_DECL (x));
16063 /* For macho, check to see if we need a stub. */
16064 if (TARGET_MACHO)
16066 const char *name = XSTR (x, 0);
16067 #if TARGET_MACHO
16068 if (darwin_emit_branch_islands
16069 && MACHOPIC_INDIRECT
16070 && machopic_classify_symbol (x) == MACHOPIC_UNDEFINED_FUNCTION)
16071 name = machopic_indirection_name (x, /*stub_p=*/true);
16072 #endif
16073 assemble_name (file, name);
16075 else if (!DOT_SYMBOLS)
16076 assemble_name (file, XSTR (x, 0));
16077 else
16078 rs6000_output_function_entry (file, XSTR (x, 0));
16079 return;
16081 case 'Z':
16082 /* Like 'L', for last word of TImode. */
16083 if (GET_CODE (x) == REG)
16084 fputs (reg_names[REGNO (x) + 3], file);
16085 else if (GET_CODE (x) == MEM)
16087 if (GET_CODE (XEXP (x, 0)) == PRE_INC
16088 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
16089 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
16090 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
16091 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
16092 else
16093 output_address (XEXP (adjust_address_nv (x, SImode, 12), 0));
16094 if (small_data_operand (x, GET_MODE (x)))
16095 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
16096 reg_names[SMALL_DATA_REG]);
16098 return;
16100 /* Print AltiVec or SPE memory operand. */
16101 case 'y':
16103 rtx tmp;
16105 gcc_assert (GET_CODE (x) == MEM);
16107 tmp = XEXP (x, 0);
16109 /* Ugly hack because %y is overloaded. */
16110 if ((TARGET_SPE || TARGET_E500_DOUBLE)
16111 && (GET_MODE_SIZE (GET_MODE (x)) == 8
16112 || GET_MODE (x) == TFmode
16113 || GET_MODE (x) == TImode))
16115 /* Handle [reg]. */
16116 if (GET_CODE (tmp) == REG)
16118 fprintf (file, "0(%s)", reg_names[REGNO (tmp)]);
16119 break;
16121 /* Handle [reg+UIMM]. */
16122 else if (GET_CODE (tmp) == PLUS &&
16123 GET_CODE (XEXP (tmp, 1)) == CONST_INT)
16125 int x;
16127 gcc_assert (GET_CODE (XEXP (tmp, 0)) == REG);
16129 x = INTVAL (XEXP (tmp, 1));
16130 fprintf (file, "%d(%s)", x, reg_names[REGNO (XEXP (tmp, 0))]);
16131 break;
16134 /* Fall through. Must be [reg+reg]. */
16136 if (VECTOR_MEM_ALTIVEC_P (GET_MODE (x))
16137 && GET_CODE (tmp) == AND
16138 && GET_CODE (XEXP (tmp, 1)) == CONST_INT
16139 && INTVAL (XEXP (tmp, 1)) == -16)
16140 tmp = XEXP (tmp, 0);
16141 else if (VECTOR_MEM_VSX_P (GET_MODE (x))
16142 && GET_CODE (tmp) == PRE_MODIFY)
16143 tmp = XEXP (tmp, 1);
16144 if (GET_CODE (tmp) == REG)
16145 fprintf (file, "0,%s", reg_names[REGNO (tmp)]);
16146 else
16148 if (!GET_CODE (tmp) == PLUS
16149 || !REG_P (XEXP (tmp, 0))
16150 || !REG_P (XEXP (tmp, 1)))
16152 output_operand_lossage ("invalid %%y value, try using the 'Z' constraint");
16153 break;
16156 if (REGNO (XEXP (tmp, 0)) == 0)
16157 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 1)) ],
16158 reg_names[ REGNO (XEXP (tmp, 0)) ]);
16159 else
16160 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 0)) ],
16161 reg_names[ REGNO (XEXP (tmp, 1)) ]);
16163 break;
16166 case 0:
16167 if (GET_CODE (x) == REG)
16168 fprintf (file, "%s", reg_names[REGNO (x)]);
16169 else if (GET_CODE (x) == MEM)
16171 /* We need to handle PRE_INC and PRE_DEC here, since we need to
16172 know the width from the mode. */
16173 if (GET_CODE (XEXP (x, 0)) == PRE_INC)
16174 fprintf (file, "%d(%s)", GET_MODE_SIZE (GET_MODE (x)),
16175 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
16176 else if (GET_CODE (XEXP (x, 0)) == PRE_DEC)
16177 fprintf (file, "%d(%s)", - GET_MODE_SIZE (GET_MODE (x)),
16178 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
16179 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
16180 output_address (XEXP (XEXP (x, 0), 1));
16181 else
16182 output_address (XEXP (x, 0));
16184 else
16185 output_addr_const (file, x);
16186 return;
16188 case '&':
16189 assemble_name (file, rs6000_get_some_local_dynamic_name ());
16190 return;
16192 default:
16193 output_operand_lossage ("invalid %%xn code");
16197 /* Print the address of an operand. */
16199 void
16200 print_operand_address (FILE *file, rtx x)
16202 if (GET_CODE (x) == REG)
16203 fprintf (file, "0(%s)", reg_names[ REGNO (x) ]);
16204 else if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST
16205 || GET_CODE (x) == LABEL_REF)
16207 output_addr_const (file, x);
16208 if (small_data_operand (x, GET_MODE (x)))
16209 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
16210 reg_names[SMALL_DATA_REG]);
16211 else
16212 gcc_assert (!TARGET_TOC);
16214 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == REG)
16216 gcc_assert (REG_P (XEXP (x, 0)));
16217 if (REGNO (XEXP (x, 0)) == 0)
16218 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 1)) ],
16219 reg_names[ REGNO (XEXP (x, 0)) ]);
16220 else
16221 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 0)) ],
16222 reg_names[ REGNO (XEXP (x, 1)) ]);
16224 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == CONST_INT)
16225 fprintf (file, HOST_WIDE_INT_PRINT_DEC "(%s)",
16226 INTVAL (XEXP (x, 1)), reg_names[ REGNO (XEXP (x, 0)) ]);
16227 #if TARGET_MACHO
16228 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
16229 && CONSTANT_P (XEXP (x, 1)))
16231 fprintf (file, "lo16(");
16232 output_addr_const (file, XEXP (x, 1));
16233 fprintf (file, ")(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
16235 #endif
16236 else if (legitimate_constant_pool_address_p (x, true))
16238 /* This hack along with a corresponding hack in
16239 rs6000_output_addr_const_extra arranges to output addends
16240 where the assembler expects to find them. eg.
16241 (lo_sum (reg 9)
16242 . (const (plus (unspec [symbol_ref ("x") tocrel]) 8)))
16243 without this hack would be output as "x@toc+8@l(9)". We
16244 want "x+8@toc@l(9)". */
16245 output_addr_const (file, tocrel_base);
16246 if (GET_CODE (x) == LO_SUM)
16247 fprintf (file, "@l(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
16248 else
16249 fprintf (file, "(%s)", reg_names[REGNO (XEXP (x, 0))]);
16251 #if TARGET_ELF
16252 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
16253 && CONSTANT_P (XEXP (x, 1)))
16255 output_addr_const (file, XEXP (x, 1));
16256 fprintf (file, "@l(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
16258 #endif
16259 else
16260 gcc_unreachable ();
16263 /* Implement TARGET_OUTPUT_ADDR_CONST_EXTRA. */
16265 static bool
16266 rs6000_output_addr_const_extra (FILE *file, rtx x)
16268 if (GET_CODE (x) == UNSPEC)
16269 switch (XINT (x, 1))
16271 case UNSPEC_TOCREL:
16272 gcc_assert (GET_CODE (XVECEXP (x, 0, 0)) == SYMBOL_REF);
16273 output_addr_const (file, XVECEXP (x, 0, 0));
16274 if (x == tocrel_base && tocrel_offset != const0_rtx)
16276 if (INTVAL (tocrel_offset) >= 0)
16277 fprintf (file, "+");
16278 output_addr_const (file, tocrel_offset);
16280 if (!TARGET_AIX || (TARGET_ELF && TARGET_MINIMAL_TOC))
16282 putc ('-', file);
16283 assemble_name (file, toc_label_name);
16285 else if (TARGET_ELF)
16286 fputs ("@toc", file);
16287 return true;
16289 #if TARGET_MACHO
16290 case UNSPEC_MACHOPIC_OFFSET:
16291 output_addr_const (file, XVECEXP (x, 0, 0));
16292 putc ('-', file);
16293 machopic_output_function_base_name (file);
16294 return true;
16295 #endif
16297 return false;
16300 /* Target hook for assembling integer objects. The PowerPC version has
16301 to handle fixup entries for relocatable code if RELOCATABLE_NEEDS_FIXUP
16302 is defined. It also needs to handle DI-mode objects on 64-bit
16303 targets. */
16305 static bool
16306 rs6000_assemble_integer (rtx x, unsigned int size, int aligned_p)
16308 #ifdef RELOCATABLE_NEEDS_FIXUP
16309 /* Special handling for SI values. */
16310 if (RELOCATABLE_NEEDS_FIXUP && size == 4 && aligned_p)
16312 static int recurse = 0;
16314 /* For -mrelocatable, we mark all addresses that need to be fixed up
16315 in the .fixup section. */
16316 if (TARGET_RELOCATABLE
16317 && in_section != toc_section
16318 && in_section != text_section
16319 && !unlikely_text_section_p (in_section)
16320 && !recurse
16321 && GET_CODE (x) != CONST_INT
16322 && GET_CODE (x) != CONST_DOUBLE
16323 && CONSTANT_P (x))
16325 char buf[256];
16327 recurse = 1;
16328 ASM_GENERATE_INTERNAL_LABEL (buf, "LCP", fixuplabelno);
16329 fixuplabelno++;
16330 ASM_OUTPUT_LABEL (asm_out_file, buf);
16331 fprintf (asm_out_file, "\t.long\t(");
16332 output_addr_const (asm_out_file, x);
16333 fprintf (asm_out_file, ")@fixup\n");
16334 fprintf (asm_out_file, "\t.section\t\".fixup\",\"aw\"\n");
16335 ASM_OUTPUT_ALIGN (asm_out_file, 2);
16336 fprintf (asm_out_file, "\t.long\t");
16337 assemble_name (asm_out_file, buf);
16338 fprintf (asm_out_file, "\n\t.previous\n");
16339 recurse = 0;
16340 return true;
16342 /* Remove initial .'s to turn a -mcall-aixdesc function
16343 address into the address of the descriptor, not the function
16344 itself. */
16345 else if (GET_CODE (x) == SYMBOL_REF
16346 && XSTR (x, 0)[0] == '.'
16347 && DEFAULT_ABI == ABI_AIX)
16349 const char *name = XSTR (x, 0);
16350 while (*name == '.')
16351 name++;
16353 fprintf (asm_out_file, "\t.long\t%s\n", name);
16354 return true;
16357 #endif /* RELOCATABLE_NEEDS_FIXUP */
16358 return default_assemble_integer (x, size, aligned_p);
16361 #ifdef HAVE_GAS_HIDDEN
16362 /* Emit an assembler directive to set symbol visibility for DECL to
16363 VISIBILITY_TYPE. */
16365 static void
16366 rs6000_assemble_visibility (tree decl, int vis)
16368 /* Functions need to have their entry point symbol visibility set as
16369 well as their descriptor symbol visibility. */
16370 if (DEFAULT_ABI == ABI_AIX
16371 && DOT_SYMBOLS
16372 && TREE_CODE (decl) == FUNCTION_DECL)
16374 static const char * const visibility_types[] = {
16375 NULL, "internal", "hidden", "protected"
16378 const char *name, *type;
16380 name = ((* targetm.strip_name_encoding)
16381 (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))));
16382 type = visibility_types[vis];
16384 fprintf (asm_out_file, "\t.%s\t%s\n", type, name);
16385 fprintf (asm_out_file, "\t.%s\t.%s\n", type, name);
16387 else
16388 default_assemble_visibility (decl, vis);
16390 #endif
16392 enum rtx_code
16393 rs6000_reverse_condition (enum machine_mode mode, enum rtx_code code)
16395 /* Reversal of FP compares takes care -- an ordered compare
16396 becomes an unordered compare and vice versa. */
16397 if (mode == CCFPmode
16398 && (!flag_finite_math_only
16399 || code == UNLT || code == UNLE || code == UNGT || code == UNGE
16400 || code == UNEQ || code == LTGT))
16401 return reverse_condition_maybe_unordered (code);
16402 else
16403 return reverse_condition (code);
16406 /* Generate a compare for CODE. Return a brand-new rtx that
16407 represents the result of the compare. */
16409 static rtx
16410 rs6000_generate_compare (rtx cmp, enum machine_mode mode)
16412 enum machine_mode comp_mode;
16413 rtx compare_result;
16414 enum rtx_code code = GET_CODE (cmp);
16415 rtx op0 = XEXP (cmp, 0);
16416 rtx op1 = XEXP (cmp, 1);
16418 if (FLOAT_MODE_P (mode))
16419 comp_mode = CCFPmode;
16420 else if (code == GTU || code == LTU
16421 || code == GEU || code == LEU)
16422 comp_mode = CCUNSmode;
16423 else if ((code == EQ || code == NE)
16424 && GET_CODE (op0) == SUBREG
16425 && GET_CODE (op1) == SUBREG
16426 && SUBREG_PROMOTED_UNSIGNED_P (op0)
16427 && SUBREG_PROMOTED_UNSIGNED_P (op1))
16428 /* These are unsigned values, perhaps there will be a later
16429 ordering compare that can be shared with this one.
16430 Unfortunately we cannot detect the signedness of the operands
16431 for non-subregs. */
16432 comp_mode = CCUNSmode;
16433 else
16434 comp_mode = CCmode;
16436 /* First, the compare. */
16437 compare_result = gen_reg_rtx (comp_mode);
16439 /* E500 FP compare instructions on the GPRs. Yuck! */
16440 if ((!TARGET_FPRS && TARGET_HARD_FLOAT)
16441 && FLOAT_MODE_P (mode))
16443 rtx cmp, or_result, compare_result2;
16444 enum machine_mode op_mode = GET_MODE (op0);
16446 if (op_mode == VOIDmode)
16447 op_mode = GET_MODE (op1);
16449 /* The E500 FP compare instructions toggle the GT bit (CR bit 1) only.
16450 This explains the following mess. */
16452 switch (code)
16454 case EQ: case UNEQ: case NE: case LTGT:
16455 switch (op_mode)
16457 case SFmode:
16458 cmp = (flag_finite_math_only && !flag_trapping_math)
16459 ? gen_tstsfeq_gpr (compare_result, op0, op1)
16460 : gen_cmpsfeq_gpr (compare_result, op0, op1);
16461 break;
16463 case DFmode:
16464 cmp = (flag_finite_math_only && !flag_trapping_math)
16465 ? gen_tstdfeq_gpr (compare_result, op0, op1)
16466 : gen_cmpdfeq_gpr (compare_result, op0, op1);
16467 break;
16469 case TFmode:
16470 cmp = (flag_finite_math_only && !flag_trapping_math)
16471 ? gen_tsttfeq_gpr (compare_result, op0, op1)
16472 : gen_cmptfeq_gpr (compare_result, op0, op1);
16473 break;
16475 default:
16476 gcc_unreachable ();
16478 break;
16480 case GT: case GTU: case UNGT: case UNGE: case GE: case GEU:
16481 switch (op_mode)
16483 case SFmode:
16484 cmp = (flag_finite_math_only && !flag_trapping_math)
16485 ? gen_tstsfgt_gpr (compare_result, op0, op1)
16486 : gen_cmpsfgt_gpr (compare_result, op0, op1);
16487 break;
16489 case DFmode:
16490 cmp = (flag_finite_math_only && !flag_trapping_math)
16491 ? gen_tstdfgt_gpr (compare_result, op0, op1)
16492 : gen_cmpdfgt_gpr (compare_result, op0, op1);
16493 break;
16495 case TFmode:
16496 cmp = (flag_finite_math_only && !flag_trapping_math)
16497 ? gen_tsttfgt_gpr (compare_result, op0, op1)
16498 : gen_cmptfgt_gpr (compare_result, op0, op1);
16499 break;
16501 default:
16502 gcc_unreachable ();
16504 break;
16506 case LT: case LTU: case UNLT: case UNLE: case LE: case LEU:
16507 switch (op_mode)
16509 case SFmode:
16510 cmp = (flag_finite_math_only && !flag_trapping_math)
16511 ? gen_tstsflt_gpr (compare_result, op0, op1)
16512 : gen_cmpsflt_gpr (compare_result, op0, op1);
16513 break;
16515 case DFmode:
16516 cmp = (flag_finite_math_only && !flag_trapping_math)
16517 ? gen_tstdflt_gpr (compare_result, op0, op1)
16518 : gen_cmpdflt_gpr (compare_result, op0, op1);
16519 break;
16521 case TFmode:
16522 cmp = (flag_finite_math_only && !flag_trapping_math)
16523 ? gen_tsttflt_gpr (compare_result, op0, op1)
16524 : gen_cmptflt_gpr (compare_result, op0, op1);
16525 break;
16527 default:
16528 gcc_unreachable ();
16530 break;
16531 default:
16532 gcc_unreachable ();
16535 /* Synthesize LE and GE from LT/GT || EQ. */
16536 if (code == LE || code == GE || code == LEU || code == GEU)
16538 emit_insn (cmp);
16540 switch (code)
16542 case LE: code = LT; break;
16543 case GE: code = GT; break;
16544 case LEU: code = LT; break;
16545 case GEU: code = GT; break;
16546 default: gcc_unreachable ();
16549 compare_result2 = gen_reg_rtx (CCFPmode);
16551 /* Do the EQ. */
16552 switch (op_mode)
16554 case SFmode:
16555 cmp = (flag_finite_math_only && !flag_trapping_math)
16556 ? gen_tstsfeq_gpr (compare_result2, op0, op1)
16557 : gen_cmpsfeq_gpr (compare_result2, op0, op1);
16558 break;
16560 case DFmode:
16561 cmp = (flag_finite_math_only && !flag_trapping_math)
16562 ? gen_tstdfeq_gpr (compare_result2, op0, op1)
16563 : gen_cmpdfeq_gpr (compare_result2, op0, op1);
16564 break;
16566 case TFmode:
16567 cmp = (flag_finite_math_only && !flag_trapping_math)
16568 ? gen_tsttfeq_gpr (compare_result2, op0, op1)
16569 : gen_cmptfeq_gpr (compare_result2, op0, op1);
16570 break;
16572 default:
16573 gcc_unreachable ();
16575 emit_insn (cmp);
16577 /* OR them together. */
16578 or_result = gen_reg_rtx (CCFPmode);
16579 cmp = gen_e500_cr_ior_compare (or_result, compare_result,
16580 compare_result2);
16581 compare_result = or_result;
16582 code = EQ;
16584 else
16586 if (code == NE || code == LTGT)
16587 code = NE;
16588 else
16589 code = EQ;
16592 emit_insn (cmp);
16594 else
16596 /* Generate XLC-compatible TFmode compare as PARALLEL with extra
16597 CLOBBERs to match cmptf_internal2 pattern. */
16598 if (comp_mode == CCFPmode && TARGET_XL_COMPAT
16599 && GET_MODE (op0) == TFmode
16600 && !TARGET_IEEEQUAD
16601 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128)
16602 emit_insn (gen_rtx_PARALLEL (VOIDmode,
16603 gen_rtvec (10,
16604 gen_rtx_SET (VOIDmode,
16605 compare_result,
16606 gen_rtx_COMPARE (comp_mode, op0, op1)),
16607 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16608 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16609 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16610 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16611 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16612 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16613 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16614 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16615 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (Pmode)))));
16616 else if (GET_CODE (op1) == UNSPEC
16617 && XINT (op1, 1) == UNSPEC_SP_TEST)
16619 rtx op1b = XVECEXP (op1, 0, 0);
16620 comp_mode = CCEQmode;
16621 compare_result = gen_reg_rtx (CCEQmode);
16622 if (TARGET_64BIT)
16623 emit_insn (gen_stack_protect_testdi (compare_result, op0, op1b));
16624 else
16625 emit_insn (gen_stack_protect_testsi (compare_result, op0, op1b));
16627 else
16628 emit_insn (gen_rtx_SET (VOIDmode, compare_result,
16629 gen_rtx_COMPARE (comp_mode, op0, op1)));
16632 /* Some kinds of FP comparisons need an OR operation;
16633 under flag_finite_math_only we don't bother. */
16634 if (FLOAT_MODE_P (mode)
16635 && !flag_finite_math_only
16636 && !(TARGET_HARD_FLOAT && !TARGET_FPRS)
16637 && (code == LE || code == GE
16638 || code == UNEQ || code == LTGT
16639 || code == UNGT || code == UNLT))
16641 enum rtx_code or1, or2;
16642 rtx or1_rtx, or2_rtx, compare2_rtx;
16643 rtx or_result = gen_reg_rtx (CCEQmode);
16645 switch (code)
16647 case LE: or1 = LT; or2 = EQ; break;
16648 case GE: or1 = GT; or2 = EQ; break;
16649 case UNEQ: or1 = UNORDERED; or2 = EQ; break;
16650 case LTGT: or1 = LT; or2 = GT; break;
16651 case UNGT: or1 = UNORDERED; or2 = GT; break;
16652 case UNLT: or1 = UNORDERED; or2 = LT; break;
16653 default: gcc_unreachable ();
16655 validate_condition_mode (or1, comp_mode);
16656 validate_condition_mode (or2, comp_mode);
16657 or1_rtx = gen_rtx_fmt_ee (or1, SImode, compare_result, const0_rtx);
16658 or2_rtx = gen_rtx_fmt_ee (or2, SImode, compare_result, const0_rtx);
16659 compare2_rtx = gen_rtx_COMPARE (CCEQmode,
16660 gen_rtx_IOR (SImode, or1_rtx, or2_rtx),
16661 const_true_rtx);
16662 emit_insn (gen_rtx_SET (VOIDmode, or_result, compare2_rtx));
16664 compare_result = or_result;
16665 code = EQ;
16668 validate_condition_mode (code, GET_MODE (compare_result));
16670 return gen_rtx_fmt_ee (code, VOIDmode, compare_result, const0_rtx);
16674 /* Emit the RTL for an sISEL pattern. */
16676 void
16677 rs6000_emit_sISEL (enum machine_mode mode ATTRIBUTE_UNUSED, rtx operands[])
16679 rs6000_emit_int_cmove (operands[0], operands[1], const1_rtx, const0_rtx);
16682 void
16683 rs6000_emit_sCOND (enum machine_mode mode, rtx operands[])
16685 rtx condition_rtx;
16686 enum machine_mode op_mode;
16687 enum rtx_code cond_code;
16688 rtx result = operands[0];
16690 if (TARGET_ISEL && (mode == SImode || mode == DImode))
16692 rs6000_emit_sISEL (mode, operands);
16693 return;
16696 condition_rtx = rs6000_generate_compare (operands[1], mode);
16697 cond_code = GET_CODE (condition_rtx);
16699 if (FLOAT_MODE_P (mode)
16700 && !TARGET_FPRS && TARGET_HARD_FLOAT)
16702 rtx t;
16704 PUT_MODE (condition_rtx, SImode);
16705 t = XEXP (condition_rtx, 0);
16707 gcc_assert (cond_code == NE || cond_code == EQ);
16709 if (cond_code == NE)
16710 emit_insn (gen_e500_flip_gt_bit (t, t));
16712 emit_insn (gen_move_from_CR_gt_bit (result, t));
16713 return;
16716 if (cond_code == NE
16717 || cond_code == GE || cond_code == LE
16718 || cond_code == GEU || cond_code == LEU
16719 || cond_code == ORDERED || cond_code == UNGE || cond_code == UNLE)
16721 rtx not_result = gen_reg_rtx (CCEQmode);
16722 rtx not_op, rev_cond_rtx;
16723 enum machine_mode cc_mode;
16725 cc_mode = GET_MODE (XEXP (condition_rtx, 0));
16727 rev_cond_rtx = gen_rtx_fmt_ee (rs6000_reverse_condition (cc_mode, cond_code),
16728 SImode, XEXP (condition_rtx, 0), const0_rtx);
16729 not_op = gen_rtx_COMPARE (CCEQmode, rev_cond_rtx, const0_rtx);
16730 emit_insn (gen_rtx_SET (VOIDmode, not_result, not_op));
16731 condition_rtx = gen_rtx_EQ (VOIDmode, not_result, const0_rtx);
16734 op_mode = GET_MODE (XEXP (operands[1], 0));
16735 if (op_mode == VOIDmode)
16736 op_mode = GET_MODE (XEXP (operands[1], 1));
16738 if (TARGET_POWERPC64 && (op_mode == DImode || FLOAT_MODE_P (mode)))
16740 PUT_MODE (condition_rtx, DImode);
16741 convert_move (result, condition_rtx, 0);
16743 else
16745 PUT_MODE (condition_rtx, SImode);
16746 emit_insn (gen_rtx_SET (VOIDmode, result, condition_rtx));
16750 /* Emit a branch of kind CODE to location LOC. */
16752 void
16753 rs6000_emit_cbranch (enum machine_mode mode, rtx operands[])
16755 rtx condition_rtx, loc_ref;
16757 condition_rtx = rs6000_generate_compare (operands[0], mode);
16758 loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands[3]);
16759 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
16760 gen_rtx_IF_THEN_ELSE (VOIDmode, condition_rtx,
16761 loc_ref, pc_rtx)));
16764 /* Return the string to output a conditional branch to LABEL, which is
16765 the operand number of the label, or -1 if the branch is really a
16766 conditional return.
16768 OP is the conditional expression. XEXP (OP, 0) is assumed to be a
16769 condition code register and its mode specifies what kind of
16770 comparison we made.
16772 REVERSED is nonzero if we should reverse the sense of the comparison.
16774 INSN is the insn. */
16776 char *
16777 output_cbranch (rtx op, const char *label, int reversed, rtx insn)
16779 static char string[64];
16780 enum rtx_code code = GET_CODE (op);
16781 rtx cc_reg = XEXP (op, 0);
16782 enum machine_mode mode = GET_MODE (cc_reg);
16783 int cc_regno = REGNO (cc_reg) - CR0_REGNO;
16784 int need_longbranch = label != NULL && get_attr_length (insn) == 8;
16785 int really_reversed = reversed ^ need_longbranch;
16786 char *s = string;
16787 const char *ccode;
16788 const char *pred;
16789 rtx note;
16791 validate_condition_mode (code, mode);
16793 /* Work out which way this really branches. We could use
16794 reverse_condition_maybe_unordered here always but this
16795 makes the resulting assembler clearer. */
16796 if (really_reversed)
16798 /* Reversal of FP compares takes care -- an ordered compare
16799 becomes an unordered compare and vice versa. */
16800 if (mode == CCFPmode)
16801 code = reverse_condition_maybe_unordered (code);
16802 else
16803 code = reverse_condition (code);
16806 if ((!TARGET_FPRS && TARGET_HARD_FLOAT) && mode == CCFPmode)
16808 /* The efscmp/tst* instructions twiddle bit 2, which maps nicely
16809 to the GT bit. */
16810 switch (code)
16812 case EQ:
16813 /* Opposite of GT. */
16814 code = GT;
16815 break;
16817 case NE:
16818 code = UNLE;
16819 break;
16821 default:
16822 gcc_unreachable ();
16826 switch (code)
16828 /* Not all of these are actually distinct opcodes, but
16829 we distinguish them for clarity of the resulting assembler. */
16830 case NE: case LTGT:
16831 ccode = "ne"; break;
16832 case EQ: case UNEQ:
16833 ccode = "eq"; break;
16834 case GE: case GEU:
16835 ccode = "ge"; break;
16836 case GT: case GTU: case UNGT:
16837 ccode = "gt"; break;
16838 case LE: case LEU:
16839 ccode = "le"; break;
16840 case LT: case LTU: case UNLT:
16841 ccode = "lt"; break;
16842 case UNORDERED: ccode = "un"; break;
16843 case ORDERED: ccode = "nu"; break;
16844 case UNGE: ccode = "nl"; break;
16845 case UNLE: ccode = "ng"; break;
16846 default:
16847 gcc_unreachable ();
16850 /* Maybe we have a guess as to how likely the branch is.
16851 The old mnemonics don't have a way to specify this information. */
16852 pred = "";
16853 note = find_reg_note (insn, REG_BR_PROB, NULL_RTX);
16854 if (note != NULL_RTX)
16856 /* PROB is the difference from 50%. */
16857 int prob = INTVAL (XEXP (note, 0)) - REG_BR_PROB_BASE / 2;
16859 /* Only hint for highly probable/improbable branches on newer
16860 cpus as static prediction overrides processor dynamic
16861 prediction. For older cpus we may as well always hint, but
16862 assume not taken for branches that are very close to 50% as a
16863 mispredicted taken branch is more expensive than a
16864 mispredicted not-taken branch. */
16865 if (rs6000_always_hint
16866 || (abs (prob) > REG_BR_PROB_BASE / 100 * 48
16867 && br_prob_note_reliable_p (note)))
16869 if (abs (prob) > REG_BR_PROB_BASE / 20
16870 && ((prob > 0) ^ need_longbranch))
16871 pred = "+";
16872 else
16873 pred = "-";
16877 if (label == NULL)
16878 s += sprintf (s, "{b%sr|b%slr%s} ", ccode, ccode, pred);
16879 else
16880 s += sprintf (s, "{b%s|b%s%s} ", ccode, ccode, pred);
16882 /* We need to escape any '%' characters in the reg_names string.
16883 Assume they'd only be the first character.... */
16884 if (reg_names[cc_regno + CR0_REGNO][0] == '%')
16885 *s++ = '%';
16886 s += sprintf (s, "%s", reg_names[cc_regno + CR0_REGNO]);
16888 if (label != NULL)
16890 /* If the branch distance was too far, we may have to use an
16891 unconditional branch to go the distance. */
16892 if (need_longbranch)
16893 s += sprintf (s, ",$+8\n\tb %s", label);
16894 else
16895 s += sprintf (s, ",%s", label);
16898 return string;
16901 /* Return the string to flip the GT bit on a CR. */
16902 char *
16903 output_e500_flip_gt_bit (rtx dst, rtx src)
16905 static char string[64];
16906 int a, b;
16908 gcc_assert (GET_CODE (dst) == REG && CR_REGNO_P (REGNO (dst))
16909 && GET_CODE (src) == REG && CR_REGNO_P (REGNO (src)));
16911 /* GT bit. */
16912 a = 4 * (REGNO (dst) - CR0_REGNO) + 1;
16913 b = 4 * (REGNO (src) - CR0_REGNO) + 1;
16915 sprintf (string, "crnot %d,%d", a, b);
16916 return string;
16919 /* Return insn for VSX or Altivec comparisons. */
16921 static rtx
16922 rs6000_emit_vector_compare_inner (enum rtx_code code, rtx op0, rtx op1)
16924 rtx mask;
16925 enum machine_mode mode = GET_MODE (op0);
16927 switch (code)
16929 default:
16930 break;
16932 case GE:
16933 if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
16934 return NULL_RTX;
16936 case EQ:
16937 case GT:
16938 case GTU:
16939 mask = gen_reg_rtx (mode);
16940 emit_insn (gen_rtx_SET (VOIDmode,
16941 mask,
16942 gen_rtx_fmt_ee (code, mode, op0, op1)));
16943 return mask;
16946 return NULL_RTX;
16949 /* Emit vector compare for operands OP0 and OP1 using code RCODE.
16950 DMODE is expected destination mode. This is a recursive function. */
16952 static rtx
16953 rs6000_emit_vector_compare (enum rtx_code rcode,
16954 rtx op0, rtx op1,
16955 enum machine_mode dmode)
16957 rtx mask;
16958 bool swap_operands = false;
16959 bool try_again = false;
16961 gcc_assert (VECTOR_UNIT_ALTIVEC_OR_VSX_P (dmode));
16962 gcc_assert (GET_MODE (op0) == GET_MODE (op1));
16964 /* See if the comparison works as is. */
16965 mask = rs6000_emit_vector_compare_inner (rcode, op0, op1);
16966 if (mask)
16967 return mask;
16969 switch (rcode)
16971 case LT:
16972 rcode = GT;
16973 swap_operands = true;
16974 try_again = true;
16975 break;
16976 case LTU:
16977 rcode = GTU;
16978 swap_operands = true;
16979 try_again = true;
16980 break;
16981 case NE:
16982 case UNLE:
16983 case UNLT:
16984 case UNGE:
16985 case UNGT:
16986 /* Invert condition and try again.
16987 e.g., A != B becomes ~(A==B). */
16989 enum rtx_code rev_code;
16990 enum insn_code nor_code;
16991 rtx mask2;
16993 rev_code = reverse_condition_maybe_unordered (rcode);
16994 if (rev_code == UNKNOWN)
16995 return NULL_RTX;
16997 nor_code = optab_handler (one_cmpl_optab, dmode);
16998 if (nor_code == CODE_FOR_nothing)
16999 return NULL_RTX;
17001 mask2 = rs6000_emit_vector_compare (rev_code, op0, op1, dmode);
17002 if (!mask2)
17003 return NULL_RTX;
17005 mask = gen_reg_rtx (dmode);
17006 emit_insn (GEN_FCN (nor_code) (mask, mask2));
17007 return mask;
17009 break;
17010 case GE:
17011 case GEU:
17012 case LE:
17013 case LEU:
17014 /* Try GT/GTU/LT/LTU OR EQ */
17016 rtx c_rtx, eq_rtx;
17017 enum insn_code ior_code;
17018 enum rtx_code new_code;
17020 switch (rcode)
17022 case GE:
17023 new_code = GT;
17024 break;
17026 case GEU:
17027 new_code = GTU;
17028 break;
17030 case LE:
17031 new_code = LT;
17032 break;
17034 case LEU:
17035 new_code = LTU;
17036 break;
17038 default:
17039 gcc_unreachable ();
17042 ior_code = optab_handler (ior_optab, dmode);
17043 if (ior_code == CODE_FOR_nothing)
17044 return NULL_RTX;
17046 c_rtx = rs6000_emit_vector_compare (new_code, op0, op1, dmode);
17047 if (!c_rtx)
17048 return NULL_RTX;
17050 eq_rtx = rs6000_emit_vector_compare (EQ, op0, op1, dmode);
17051 if (!eq_rtx)
17052 return NULL_RTX;
17054 mask = gen_reg_rtx (dmode);
17055 emit_insn (GEN_FCN (ior_code) (mask, c_rtx, eq_rtx));
17056 return mask;
17058 break;
17059 default:
17060 return NULL_RTX;
17063 if (try_again)
17065 if (swap_operands)
17067 rtx tmp;
17068 tmp = op0;
17069 op0 = op1;
17070 op1 = tmp;
17073 mask = rs6000_emit_vector_compare_inner (rcode, op0, op1);
17074 if (mask)
17075 return mask;
17078 /* You only get two chances. */
17079 return NULL_RTX;
17082 /* Emit vector conditional expression. DEST is destination. OP_TRUE and
17083 OP_FALSE are two VEC_COND_EXPR operands. CC_OP0 and CC_OP1 are the two
17084 operands for the relation operation COND. */
17087 rs6000_emit_vector_cond_expr (rtx dest, rtx op_true, rtx op_false,
17088 rtx cond, rtx cc_op0, rtx cc_op1)
17090 enum machine_mode dest_mode = GET_MODE (dest);
17091 enum rtx_code rcode = GET_CODE (cond);
17092 enum machine_mode cc_mode = CCmode;
17093 rtx mask;
17094 rtx cond2;
17095 rtx tmp;
17096 bool invert_move = false;
17098 if (VECTOR_UNIT_NONE_P (dest_mode))
17099 return 0;
17101 switch (rcode)
17103 /* Swap operands if we can, and fall back to doing the operation as
17104 specified, and doing a NOR to invert the test. */
17105 case NE:
17106 case UNLE:
17107 case UNLT:
17108 case UNGE:
17109 case UNGT:
17110 /* Invert condition and try again.
17111 e.g., A = (B != C) ? D : E becomes A = (B == C) ? E : D. */
17112 invert_move = true;
17113 rcode = reverse_condition_maybe_unordered (rcode);
17114 if (rcode == UNKNOWN)
17115 return 0;
17116 break;
17118 /* Mark unsigned tests with CCUNSmode. */
17119 case GTU:
17120 case GEU:
17121 case LTU:
17122 case LEU:
17123 cc_mode = CCUNSmode;
17124 break;
17126 default:
17127 break;
17130 /* Get the vector mask for the given relational operations. */
17131 mask = rs6000_emit_vector_compare (rcode, cc_op0, cc_op1, dest_mode);
17133 if (!mask)
17134 return 0;
17136 if (invert_move)
17138 tmp = op_true;
17139 op_true = op_false;
17140 op_false = tmp;
17143 cond2 = gen_rtx_fmt_ee (NE, cc_mode, mask, const0_rtx);
17144 emit_insn (gen_rtx_SET (VOIDmode,
17145 dest,
17146 gen_rtx_IF_THEN_ELSE (dest_mode,
17147 cond2,
17148 op_true,
17149 op_false)));
17150 return 1;
17153 /* Emit a conditional move: move TRUE_COND to DEST if OP of the
17154 operands of the last comparison is nonzero/true, FALSE_COND if it
17155 is zero/false. Return 0 if the hardware has no such operation. */
17158 rs6000_emit_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
17160 enum rtx_code code = GET_CODE (op);
17161 rtx op0 = XEXP (op, 0);
17162 rtx op1 = XEXP (op, 1);
17163 REAL_VALUE_TYPE c1;
17164 enum machine_mode compare_mode = GET_MODE (op0);
17165 enum machine_mode result_mode = GET_MODE (dest);
17166 rtx temp;
17167 bool is_against_zero;
17169 /* These modes should always match. */
17170 if (GET_MODE (op1) != compare_mode
17171 /* In the isel case however, we can use a compare immediate, so
17172 op1 may be a small constant. */
17173 && (!TARGET_ISEL || !short_cint_operand (op1, VOIDmode)))
17174 return 0;
17175 if (GET_MODE (true_cond) != result_mode)
17176 return 0;
17177 if (GET_MODE (false_cond) != result_mode)
17178 return 0;
17180 /* First, work out if the hardware can do this at all, or
17181 if it's too slow.... */
17182 if (!FLOAT_MODE_P (compare_mode))
17184 if (TARGET_ISEL)
17185 return rs6000_emit_int_cmove (dest, op, true_cond, false_cond);
17186 return 0;
17188 else if (TARGET_HARD_FLOAT && !TARGET_FPRS
17189 && SCALAR_FLOAT_MODE_P (compare_mode))
17190 return 0;
17192 is_against_zero = op1 == CONST0_RTX (compare_mode);
17194 /* A floating-point subtract might overflow, underflow, or produce
17195 an inexact result, thus changing the floating-point flags, so it
17196 can't be generated if we care about that. It's safe if one side
17197 of the construct is zero, since then no subtract will be
17198 generated. */
17199 if (SCALAR_FLOAT_MODE_P (compare_mode)
17200 && flag_trapping_math && ! is_against_zero)
17201 return 0;
17203 /* Eliminate half of the comparisons by switching operands, this
17204 makes the remaining code simpler. */
17205 if (code == UNLT || code == UNGT || code == UNORDERED || code == NE
17206 || code == LTGT || code == LT || code == UNLE)
17208 code = reverse_condition_maybe_unordered (code);
17209 temp = true_cond;
17210 true_cond = false_cond;
17211 false_cond = temp;
17214 /* UNEQ and LTGT take four instructions for a comparison with zero,
17215 it'll probably be faster to use a branch here too. */
17216 if (code == UNEQ && HONOR_NANS (compare_mode))
17217 return 0;
17219 if (GET_CODE (op1) == CONST_DOUBLE)
17220 REAL_VALUE_FROM_CONST_DOUBLE (c1, op1);
17222 /* We're going to try to implement comparisons by performing
17223 a subtract, then comparing against zero. Unfortunately,
17224 Inf - Inf is NaN which is not zero, and so if we don't
17225 know that the operand is finite and the comparison
17226 would treat EQ different to UNORDERED, we can't do it. */
17227 if (HONOR_INFINITIES (compare_mode)
17228 && code != GT && code != UNGE
17229 && (GET_CODE (op1) != CONST_DOUBLE || real_isinf (&c1))
17230 /* Constructs of the form (a OP b ? a : b) are safe. */
17231 && ((! rtx_equal_p (op0, false_cond) && ! rtx_equal_p (op1, false_cond))
17232 || (! rtx_equal_p (op0, true_cond)
17233 && ! rtx_equal_p (op1, true_cond))))
17234 return 0;
17236 /* At this point we know we can use fsel. */
17238 /* Reduce the comparison to a comparison against zero. */
17239 if (! is_against_zero)
17241 temp = gen_reg_rtx (compare_mode);
17242 emit_insn (gen_rtx_SET (VOIDmode, temp,
17243 gen_rtx_MINUS (compare_mode, op0, op1)));
17244 op0 = temp;
17245 op1 = CONST0_RTX (compare_mode);
17248 /* If we don't care about NaNs we can reduce some of the comparisons
17249 down to faster ones. */
17250 if (! HONOR_NANS (compare_mode))
17251 switch (code)
17253 case GT:
17254 code = LE;
17255 temp = true_cond;
17256 true_cond = false_cond;
17257 false_cond = temp;
17258 break;
17259 case UNGE:
17260 code = GE;
17261 break;
17262 case UNEQ:
17263 code = EQ;
17264 break;
17265 default:
17266 break;
17269 /* Now, reduce everything down to a GE. */
17270 switch (code)
17272 case GE:
17273 break;
17275 case LE:
17276 temp = gen_reg_rtx (compare_mode);
17277 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
17278 op0 = temp;
17279 break;
17281 case ORDERED:
17282 temp = gen_reg_rtx (compare_mode);
17283 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_ABS (compare_mode, op0)));
17284 op0 = temp;
17285 break;
17287 case EQ:
17288 temp = gen_reg_rtx (compare_mode);
17289 emit_insn (gen_rtx_SET (VOIDmode, temp,
17290 gen_rtx_NEG (compare_mode,
17291 gen_rtx_ABS (compare_mode, op0))));
17292 op0 = temp;
17293 break;
17295 case UNGE:
17296 /* a UNGE 0 <-> (a GE 0 || -a UNLT 0) */
17297 temp = gen_reg_rtx (result_mode);
17298 emit_insn (gen_rtx_SET (VOIDmode, temp,
17299 gen_rtx_IF_THEN_ELSE (result_mode,
17300 gen_rtx_GE (VOIDmode,
17301 op0, op1),
17302 true_cond, false_cond)));
17303 false_cond = true_cond;
17304 true_cond = temp;
17306 temp = gen_reg_rtx (compare_mode);
17307 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
17308 op0 = temp;
17309 break;
17311 case GT:
17312 /* a GT 0 <-> (a GE 0 && -a UNLT 0) */
17313 temp = gen_reg_rtx (result_mode);
17314 emit_insn (gen_rtx_SET (VOIDmode, temp,
17315 gen_rtx_IF_THEN_ELSE (result_mode,
17316 gen_rtx_GE (VOIDmode,
17317 op0, op1),
17318 true_cond, false_cond)));
17319 true_cond = false_cond;
17320 false_cond = temp;
17322 temp = gen_reg_rtx (compare_mode);
17323 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
17324 op0 = temp;
17325 break;
17327 default:
17328 gcc_unreachable ();
17331 emit_insn (gen_rtx_SET (VOIDmode, dest,
17332 gen_rtx_IF_THEN_ELSE (result_mode,
17333 gen_rtx_GE (VOIDmode,
17334 op0, op1),
17335 true_cond, false_cond)));
17336 return 1;
17339 /* Same as above, but for ints (isel). */
17341 static int
17342 rs6000_emit_int_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
17344 rtx condition_rtx, cr;
17345 enum machine_mode mode = GET_MODE (dest);
17346 enum rtx_code cond_code;
17347 rtx (*isel_func) (rtx, rtx, rtx, rtx, rtx);
17348 bool signedp;
17350 if (mode != SImode && (!TARGET_POWERPC64 || mode != DImode))
17351 return 0;
17353 /* We still have to do the compare, because isel doesn't do a
17354 compare, it just looks at the CRx bits set by a previous compare
17355 instruction. */
17356 condition_rtx = rs6000_generate_compare (op, mode);
17357 cond_code = GET_CODE (condition_rtx);
17358 cr = XEXP (condition_rtx, 0);
17359 signedp = GET_MODE (cr) == CCmode;
17361 isel_func = (mode == SImode
17362 ? (signedp ? gen_isel_signed_si : gen_isel_unsigned_si)
17363 : (signedp ? gen_isel_signed_di : gen_isel_unsigned_di));
17365 switch (cond_code)
17367 case LT: case GT: case LTU: case GTU: case EQ:
17368 /* isel handles these directly. */
17369 break;
17371 default:
17372 /* We need to swap the sense of the comparison. */
17374 rtx t = true_cond;
17375 true_cond = false_cond;
17376 false_cond = t;
17377 PUT_CODE (condition_rtx, reverse_condition (cond_code));
17379 break;
17382 false_cond = force_reg (mode, false_cond);
17383 if (true_cond != const0_rtx)
17384 true_cond = force_reg (mode, true_cond);
17386 emit_insn (isel_func (dest, condition_rtx, true_cond, false_cond, cr));
17388 return 1;
17391 const char *
17392 output_isel (rtx *operands)
17394 enum rtx_code code;
17396 code = GET_CODE (operands[1]);
17398 if (code == GE || code == GEU || code == LE || code == LEU || code == NE)
17400 gcc_assert (GET_CODE (operands[2]) == REG
17401 && GET_CODE (operands[3]) == REG);
17402 PUT_CODE (operands[1], reverse_condition (code));
17403 return "isel %0,%3,%2,%j1";
17406 return "isel %0,%2,%3,%j1";
17409 void
17410 rs6000_emit_minmax (rtx dest, enum rtx_code code, rtx op0, rtx op1)
17412 enum machine_mode mode = GET_MODE (op0);
17413 enum rtx_code c;
17414 rtx target;
17416 /* VSX/altivec have direct min/max insns. */
17417 if ((code == SMAX || code == SMIN)
17418 && (VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode)
17419 || (mode == SFmode && VECTOR_UNIT_VSX_P (DFmode))))
17421 emit_insn (gen_rtx_SET (VOIDmode,
17422 dest,
17423 gen_rtx_fmt_ee (code, mode, op0, op1)));
17424 return;
17427 if (code == SMAX || code == SMIN)
17428 c = GE;
17429 else
17430 c = GEU;
17432 if (code == SMAX || code == UMAX)
17433 target = emit_conditional_move (dest, c, op0, op1, mode,
17434 op0, op1, mode, 0);
17435 else
17436 target = emit_conditional_move (dest, c, op0, op1, mode,
17437 op1, op0, mode, 0);
17438 gcc_assert (target);
17439 if (target != dest)
17440 emit_move_insn (dest, target);
17443 /* Emit instructions to perform a load-reserved/store-conditional operation.
17444 The operation performed is an atomic
17445 (set M (CODE:MODE M OP))
17446 If not NULL, BEFORE is atomically set to M before the operation, and
17447 AFTER is set to M after the operation (that is, (CODE:MODE M OP)).
17448 If SYNC_P then a memory barrier is emitted before the operation.
17449 Either OP or M may be wrapped in a NOT operation. */
17451 void
17452 rs6000_emit_sync (enum rtx_code code, enum machine_mode mode,
17453 rtx m, rtx op, rtx before_param, rtx after_param,
17454 bool sync_p)
17456 enum machine_mode used_mode;
17457 rtx the_op, set_before, set_after, set_atomic, cc_scratch, before, after;
17458 rtx used_m;
17459 rtvec vec;
17460 HOST_WIDE_INT imask = GET_MODE_MASK (mode);
17461 rtx shift = NULL_RTX;
17463 if (sync_p)
17464 emit_insn (gen_lwsync ());
17466 used_m = m;
17468 /* If this is smaller than SImode, we'll have to use SImode with
17469 adjustments. */
17470 if (mode == QImode || mode == HImode)
17472 rtx newop, oldop;
17474 if (MEM_ALIGN (used_m) >= 32)
17476 int ishift = 0;
17477 if (BYTES_BIG_ENDIAN)
17478 ishift = GET_MODE_BITSIZE (SImode) - GET_MODE_BITSIZE (mode);
17480 shift = GEN_INT (ishift);
17481 used_m = change_address (used_m, SImode, 0);
17483 else
17485 rtx addrSI, aligned_addr;
17486 int shift_mask = mode == QImode ? 0x18 : 0x10;
17488 addrSI = gen_lowpart_common (SImode,
17489 force_reg (Pmode, XEXP (used_m, 0)));
17490 addrSI = force_reg (SImode, addrSI);
17491 shift = gen_reg_rtx (SImode);
17493 emit_insn (gen_rlwinm (shift, addrSI, GEN_INT (3),
17494 GEN_INT (shift_mask)));
17495 emit_insn (gen_xorsi3 (shift, shift, GEN_INT (shift_mask)));
17497 aligned_addr = expand_binop (Pmode, and_optab,
17498 XEXP (used_m, 0),
17499 GEN_INT (-4), NULL_RTX,
17500 1, OPTAB_LIB_WIDEN);
17501 used_m = change_address (used_m, SImode, aligned_addr);
17502 set_mem_align (used_m, 32);
17504 /* It's safe to keep the old alias set of USED_M, because
17505 the operation is atomic and only affects the original
17506 USED_M. */
17507 m = used_m;
17509 if (GET_CODE (op) == NOT)
17511 oldop = lowpart_subreg (SImode, XEXP (op, 0), mode);
17512 oldop = gen_rtx_NOT (SImode, oldop);
17514 else
17515 oldop = lowpart_subreg (SImode, op, mode);
17517 switch (code)
17519 case IOR:
17520 case XOR:
17521 newop = expand_binop (SImode, and_optab,
17522 oldop, GEN_INT (imask), NULL_RTX,
17523 1, OPTAB_LIB_WIDEN);
17524 emit_insn (gen_ashlsi3 (newop, newop, shift));
17525 break;
17527 case NOT: /* NAND */
17528 newop = expand_binop (SImode, ior_optab,
17529 oldop, GEN_INT (~imask), NULL_RTX,
17530 1, OPTAB_LIB_WIDEN);
17531 emit_insn (gen_rotlsi3 (newop, newop, shift));
17532 break;
17534 case AND:
17535 newop = expand_binop (SImode, ior_optab,
17536 oldop, GEN_INT (~imask), NULL_RTX,
17537 1, OPTAB_LIB_WIDEN);
17538 emit_insn (gen_rotlsi3 (newop, newop, shift));
17539 break;
17541 case PLUS:
17542 case MINUS:
17544 rtx mask;
17546 newop = expand_binop (SImode, and_optab,
17547 oldop, GEN_INT (imask), NULL_RTX,
17548 1, OPTAB_LIB_WIDEN);
17549 emit_insn (gen_ashlsi3 (newop, newop, shift));
17551 mask = gen_reg_rtx (SImode);
17552 emit_move_insn (mask, GEN_INT (imask));
17553 emit_insn (gen_ashlsi3 (mask, mask, shift));
17555 if (code == PLUS)
17556 newop = gen_rtx_PLUS (SImode, m, newop);
17557 else
17558 newop = gen_rtx_MINUS (SImode, m, newop);
17559 newop = gen_rtx_AND (SImode, newop, mask);
17560 newop = gen_rtx_IOR (SImode, newop,
17561 gen_rtx_AND (SImode,
17562 gen_rtx_NOT (SImode, mask),
17563 m));
17564 break;
17567 default:
17568 gcc_unreachable ();
17571 op = newop;
17572 used_mode = SImode;
17573 before = gen_reg_rtx (used_mode);
17574 after = gen_reg_rtx (used_mode);
17576 else
17578 used_mode = mode;
17579 before = before_param;
17580 after = after_param;
17582 if (before == NULL_RTX)
17583 before = gen_reg_rtx (used_mode);
17584 if (after == NULL_RTX)
17585 after = gen_reg_rtx (used_mode);
17588 if ((code == PLUS || code == MINUS)
17589 && used_mode != mode)
17590 the_op = op; /* Computed above. */
17591 else if (GET_CODE (op) == NOT && GET_CODE (m) != NOT)
17592 the_op = gen_rtx_fmt_ee (code, used_mode, op, m);
17593 else if (code == NOT)
17594 the_op = gen_rtx_fmt_ee (IOR, used_mode,
17595 gen_rtx_NOT (used_mode, m),
17596 gen_rtx_NOT (used_mode, op));
17597 else
17598 the_op = gen_rtx_fmt_ee (code, used_mode, m, op);
17600 set_after = gen_rtx_SET (VOIDmode, after, the_op);
17601 set_before = gen_rtx_SET (VOIDmode, before, used_m);
17602 set_atomic = gen_rtx_SET (VOIDmode, used_m,
17603 gen_rtx_UNSPEC (used_mode,
17604 gen_rtvec (1, the_op),
17605 UNSPEC_SYNC_OP));
17606 cc_scratch = gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (CCmode));
17608 if ((code == PLUS || code == MINUS) && used_mode != mode)
17609 vec = gen_rtvec (5, set_after, set_before, set_atomic, cc_scratch,
17610 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (SImode)));
17611 else
17612 vec = gen_rtvec (4, set_after, set_before, set_atomic, cc_scratch);
17613 emit_insn (gen_rtx_PARALLEL (VOIDmode, vec));
17615 /* Shift and mask the return values properly. */
17616 if (used_mode != mode && before_param)
17618 emit_insn (gen_lshrsi3 (before, before, shift));
17619 convert_move (before_param, before, 1);
17622 if (used_mode != mode && after_param)
17624 emit_insn (gen_lshrsi3 (after, after, shift));
17625 convert_move (after_param, after, 1);
17628 /* The previous sequence will end with a branch that's dependent on
17629 the conditional store, so placing an isync will ensure that no
17630 other instructions (especially, no load or store instructions)
17631 can start before the atomic operation completes. */
17632 if (sync_p)
17633 emit_insn (gen_isync ());
17636 /* A subroutine of the atomic operation splitters. Jump to LABEL if
17637 COND is true. Mark the jump as unlikely to be taken. */
17639 static void
17640 emit_unlikely_jump (rtx cond, rtx label)
17642 rtx very_unlikely = GEN_INT (REG_BR_PROB_BASE / 100 - 1);
17643 rtx x;
17645 x = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, label, pc_rtx);
17646 x = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, x));
17647 add_reg_note (x, REG_BR_PROB, very_unlikely);
17650 /* A subroutine of the atomic operation splitters. Emit a load-locked
17651 instruction in MODE. */
17653 static void
17654 emit_load_locked (enum machine_mode mode, rtx reg, rtx mem)
17656 rtx (*fn) (rtx, rtx) = NULL;
17657 if (mode == SImode)
17658 fn = gen_load_locked_si;
17659 else if (mode == DImode)
17660 fn = gen_load_locked_di;
17661 emit_insn (fn (reg, mem));
17664 /* A subroutine of the atomic operation splitters. Emit a store-conditional
17665 instruction in MODE. */
17667 static void
17668 emit_store_conditional (enum machine_mode mode, rtx res, rtx mem, rtx val)
17670 rtx (*fn) (rtx, rtx, rtx) = NULL;
17671 if (mode == SImode)
17672 fn = gen_store_conditional_si;
17673 else if (mode == DImode)
17674 fn = gen_store_conditional_di;
17676 /* Emit sync before stwcx. to address PPC405 Erratum. */
17677 if (PPC405_ERRATUM77)
17678 emit_insn (gen_memory_barrier ());
17680 emit_insn (fn (res, mem, val));
17683 /* Expand an atomic fetch-and-operate pattern. CODE is the binary operation
17684 to perform. MEM is the memory on which to operate. VAL is the second
17685 operand of the binary operator. BEFORE and AFTER are optional locations to
17686 return the value of MEM either before of after the operation. SCRATCH is
17687 a scratch register. */
17689 void
17690 rs6000_split_atomic_op (enum rtx_code code, rtx mem, rtx val,
17691 rtx before, rtx after, rtx scratch)
17693 enum machine_mode mode = GET_MODE (mem);
17694 rtx label, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
17696 emit_insn (gen_lwsync ());
17698 label = gen_label_rtx ();
17699 emit_label (label);
17700 label = gen_rtx_LABEL_REF (VOIDmode, label);
17702 if (before == NULL_RTX)
17703 before = scratch;
17704 emit_load_locked (mode, before, mem);
17706 if (code == NOT)
17707 x = gen_rtx_IOR (mode,
17708 gen_rtx_NOT (mode, before),
17709 gen_rtx_NOT (mode, val));
17710 else if (code == AND)
17711 x = gen_rtx_UNSPEC (mode, gen_rtvec (2, before, val), UNSPEC_AND);
17712 else
17713 x = gen_rtx_fmt_ee (code, mode, before, val);
17715 if (after != NULL_RTX)
17716 emit_insn (gen_rtx_SET (VOIDmode, after, copy_rtx (x)));
17717 emit_insn (gen_rtx_SET (VOIDmode, scratch, x));
17719 emit_store_conditional (mode, cond, mem, scratch);
17721 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17722 emit_unlikely_jump (x, label);
17724 emit_insn (gen_isync ());
17727 /* Expand an atomic compare and swap operation. MEM is the memory on which
17728 to operate. OLDVAL is the old value to be compared. NEWVAL is the new
17729 value to be stored. SCRATCH is a scratch GPR. */
17731 void
17732 rs6000_split_compare_and_swap (rtx retval, rtx mem, rtx oldval, rtx newval,
17733 rtx scratch)
17735 enum machine_mode mode = GET_MODE (mem);
17736 rtx label1, label2, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
17738 emit_insn (gen_lwsync ());
17740 label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
17741 label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
17742 emit_label (XEXP (label1, 0));
17744 emit_load_locked (mode, retval, mem);
17746 x = gen_rtx_COMPARE (CCmode, retval, oldval);
17747 emit_insn (gen_rtx_SET (VOIDmode, cond, x));
17749 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17750 emit_unlikely_jump (x, label2);
17752 emit_move_insn (scratch, newval);
17753 emit_store_conditional (mode, cond, mem, scratch);
17755 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17756 emit_unlikely_jump (x, label1);
17758 emit_insn (gen_isync ());
17759 emit_label (XEXP (label2, 0));
17762 /* Expand an atomic test and set operation. MEM is the memory on which
17763 to operate. VAL is the value set. SCRATCH is a scratch GPR. */
17765 void
17766 rs6000_split_lock_test_and_set (rtx retval, rtx mem, rtx val, rtx scratch)
17768 enum machine_mode mode = GET_MODE (mem);
17769 rtx label, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
17771 label = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
17772 emit_label (XEXP (label, 0));
17774 emit_load_locked (mode, retval, mem);
17775 emit_move_insn (scratch, val);
17776 emit_store_conditional (mode, cond, mem, scratch);
17778 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17779 emit_unlikely_jump (x, label);
17781 emit_insn (gen_isync ());
17784 void
17785 rs6000_expand_compare_and_swapqhi (rtx dst, rtx mem, rtx oldval, rtx newval)
17787 enum machine_mode mode = GET_MODE (mem);
17788 rtx addrSI, align, wdst, shift, mask;
17789 HOST_WIDE_INT shift_mask = mode == QImode ? 0x18 : 0x10;
17790 HOST_WIDE_INT imask = GET_MODE_MASK (mode);
17792 /* Shift amount for subword relative to aligned word. */
17793 addrSI = force_reg (GET_MODE (XEXP (mem, 0)), XEXP (mem, 0));
17794 addrSI = force_reg (SImode, gen_lowpart_common (SImode, addrSI));
17795 shift = gen_reg_rtx (SImode);
17796 emit_insn (gen_rlwinm (shift, addrSI, GEN_INT (3),
17797 GEN_INT (shift_mask)));
17798 emit_insn (gen_xorsi3 (shift, shift, GEN_INT (shift_mask)));
17800 /* Shift and mask old value into position within word. */
17801 oldval = convert_modes (SImode, mode, oldval, 1);
17802 oldval = expand_binop (SImode, and_optab,
17803 oldval, GEN_INT (imask), NULL_RTX,
17804 1, OPTAB_LIB_WIDEN);
17805 emit_insn (gen_ashlsi3 (oldval, oldval, shift));
17807 /* Shift and mask new value into position within word. */
17808 newval = convert_modes (SImode, mode, newval, 1);
17809 newval = expand_binop (SImode, and_optab,
17810 newval, GEN_INT (imask), NULL_RTX,
17811 1, OPTAB_LIB_WIDEN);
17812 emit_insn (gen_ashlsi3 (newval, newval, shift));
17814 /* Mask for insertion. */
17815 mask = gen_reg_rtx (SImode);
17816 emit_move_insn (mask, GEN_INT (imask));
17817 emit_insn (gen_ashlsi3 (mask, mask, shift));
17819 /* Address of aligned word containing subword. */
17820 align = expand_binop (Pmode, and_optab, XEXP (mem, 0), GEN_INT (-4),
17821 NULL_RTX, 1, OPTAB_LIB_WIDEN);
17822 mem = change_address (mem, SImode, align);
17823 set_mem_align (mem, 32);
17824 MEM_VOLATILE_P (mem) = 1;
17826 wdst = gen_reg_rtx (SImode);
17827 emit_insn (gen_sync_compare_and_swapqhi_internal (wdst, mask,
17828 oldval, newval, mem));
17830 /* Shift the result back. */
17831 emit_insn (gen_lshrsi3 (wdst, wdst, shift));
17833 emit_move_insn (dst, gen_lowpart (mode, wdst));
17836 void
17837 rs6000_split_compare_and_swapqhi (rtx dest, rtx mask,
17838 rtx oldval, rtx newval, rtx mem,
17839 rtx scratch)
17841 rtx label1, label2, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
17843 emit_insn (gen_lwsync ());
17844 label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
17845 label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
17846 emit_label (XEXP (label1, 0));
17848 emit_load_locked (SImode, scratch, mem);
17850 /* Mask subword within loaded value for comparison with oldval.
17851 Use UNSPEC_AND to avoid clobber.*/
17852 emit_insn (gen_rtx_SET (SImode, dest,
17853 gen_rtx_UNSPEC (SImode,
17854 gen_rtvec (2, scratch, mask),
17855 UNSPEC_AND)));
17857 x = gen_rtx_COMPARE (CCmode, dest, oldval);
17858 emit_insn (gen_rtx_SET (VOIDmode, cond, x));
17860 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17861 emit_unlikely_jump (x, label2);
17863 /* Clear subword within loaded value for insertion of new value. */
17864 emit_insn (gen_rtx_SET (SImode, scratch,
17865 gen_rtx_AND (SImode,
17866 gen_rtx_NOT (SImode, mask), scratch)));
17867 emit_insn (gen_iorsi3 (scratch, scratch, newval));
17868 emit_store_conditional (SImode, cond, mem, scratch);
17870 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17871 emit_unlikely_jump (x, label1);
17873 emit_insn (gen_isync ());
17874 emit_label (XEXP (label2, 0));
17878 /* Emit instructions to move SRC to DST. Called by splitters for
17879 multi-register moves. It will emit at most one instruction for
17880 each register that is accessed; that is, it won't emit li/lis pairs
17881 (or equivalent for 64-bit code). One of SRC or DST must be a hard
17882 register. */
17884 void
17885 rs6000_split_multireg_move (rtx dst, rtx src)
17887 /* The register number of the first register being moved. */
17888 int reg;
17889 /* The mode that is to be moved. */
17890 enum machine_mode mode;
17891 /* The mode that the move is being done in, and its size. */
17892 enum machine_mode reg_mode;
17893 int reg_mode_size;
17894 /* The number of registers that will be moved. */
17895 int nregs;
17897 reg = REG_P (dst) ? REGNO (dst) : REGNO (src);
17898 mode = GET_MODE (dst);
17899 nregs = hard_regno_nregs[reg][mode];
17900 if (FP_REGNO_P (reg))
17901 reg_mode = DECIMAL_FLOAT_MODE_P (mode) ? DDmode :
17902 ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? DFmode : SFmode);
17903 else if (ALTIVEC_REGNO_P (reg))
17904 reg_mode = V16QImode;
17905 else if (TARGET_E500_DOUBLE && mode == TFmode)
17906 reg_mode = DFmode;
17907 else
17908 reg_mode = word_mode;
17909 reg_mode_size = GET_MODE_SIZE (reg_mode);
17911 gcc_assert (reg_mode_size * nregs == GET_MODE_SIZE (mode));
17913 if (REG_P (src) && REG_P (dst) && (REGNO (src) < REGNO (dst)))
17915 /* Move register range backwards, if we might have destructive
17916 overlap. */
17917 int i;
17918 for (i = nregs - 1; i >= 0; i--)
17919 emit_insn (gen_rtx_SET (VOIDmode,
17920 simplify_gen_subreg (reg_mode, dst, mode,
17921 i * reg_mode_size),
17922 simplify_gen_subreg (reg_mode, src, mode,
17923 i * reg_mode_size)));
17925 else
17927 int i;
17928 int j = -1;
17929 bool used_update = false;
17930 rtx restore_basereg = NULL_RTX;
17932 if (MEM_P (src) && INT_REGNO_P (reg))
17934 rtx breg;
17936 if (GET_CODE (XEXP (src, 0)) == PRE_INC
17937 || GET_CODE (XEXP (src, 0)) == PRE_DEC)
17939 rtx delta_rtx;
17940 breg = XEXP (XEXP (src, 0), 0);
17941 delta_rtx = (GET_CODE (XEXP (src, 0)) == PRE_INC
17942 ? GEN_INT (GET_MODE_SIZE (GET_MODE (src)))
17943 : GEN_INT (-GET_MODE_SIZE (GET_MODE (src))));
17944 emit_insn (gen_add3_insn (breg, breg, delta_rtx));
17945 src = replace_equiv_address (src, breg);
17947 else if (! rs6000_offsettable_memref_p (src))
17949 if (GET_CODE (XEXP (src, 0)) == PRE_MODIFY)
17951 rtx basereg = XEXP (XEXP (src, 0), 0);
17952 if (TARGET_UPDATE)
17954 rtx ndst = simplify_gen_subreg (reg_mode, dst, mode, 0);
17955 emit_insn (gen_rtx_SET (VOIDmode, ndst,
17956 gen_rtx_MEM (reg_mode, XEXP (src, 0))));
17957 used_update = true;
17959 else
17960 emit_insn (gen_rtx_SET (VOIDmode, basereg,
17961 XEXP (XEXP (src, 0), 1)));
17962 src = replace_equiv_address (src, basereg);
17964 else
17966 rtx basereg = gen_rtx_REG (Pmode, reg);
17967 emit_insn (gen_rtx_SET (VOIDmode, basereg, XEXP (src, 0)));
17968 src = replace_equiv_address (src, basereg);
17972 breg = XEXP (src, 0);
17973 if (GET_CODE (breg) == PLUS || GET_CODE (breg) == LO_SUM)
17974 breg = XEXP (breg, 0);
17976 /* If the base register we are using to address memory is
17977 also a destination reg, then change that register last. */
17978 if (REG_P (breg)
17979 && REGNO (breg) >= REGNO (dst)
17980 && REGNO (breg) < REGNO (dst) + nregs)
17981 j = REGNO (breg) - REGNO (dst);
17983 else if (MEM_P (dst) && INT_REGNO_P (reg))
17985 rtx breg;
17987 if (GET_CODE (XEXP (dst, 0)) == PRE_INC
17988 || GET_CODE (XEXP (dst, 0)) == PRE_DEC)
17990 rtx delta_rtx;
17991 breg = XEXP (XEXP (dst, 0), 0);
17992 delta_rtx = (GET_CODE (XEXP (dst, 0)) == PRE_INC
17993 ? GEN_INT (GET_MODE_SIZE (GET_MODE (dst)))
17994 : GEN_INT (-GET_MODE_SIZE (GET_MODE (dst))));
17996 /* We have to update the breg before doing the store.
17997 Use store with update, if available. */
17999 if (TARGET_UPDATE)
18001 rtx nsrc = simplify_gen_subreg (reg_mode, src, mode, 0);
18002 emit_insn (TARGET_32BIT
18003 ? (TARGET_POWERPC64
18004 ? gen_movdi_si_update (breg, breg, delta_rtx, nsrc)
18005 : gen_movsi_update (breg, breg, delta_rtx, nsrc))
18006 : gen_movdi_di_update (breg, breg, delta_rtx, nsrc));
18007 used_update = true;
18009 else
18010 emit_insn (gen_add3_insn (breg, breg, delta_rtx));
18011 dst = replace_equiv_address (dst, breg);
18013 else if (!rs6000_offsettable_memref_p (dst)
18014 && GET_CODE (XEXP (dst, 0)) != LO_SUM)
18016 if (GET_CODE (XEXP (dst, 0)) == PRE_MODIFY)
18018 rtx basereg = XEXP (XEXP (dst, 0), 0);
18019 if (TARGET_UPDATE)
18021 rtx nsrc = simplify_gen_subreg (reg_mode, src, mode, 0);
18022 emit_insn (gen_rtx_SET (VOIDmode,
18023 gen_rtx_MEM (reg_mode, XEXP (dst, 0)), nsrc));
18024 used_update = true;
18026 else
18027 emit_insn (gen_rtx_SET (VOIDmode, basereg,
18028 XEXP (XEXP (dst, 0), 1)));
18029 dst = replace_equiv_address (dst, basereg);
18031 else
18033 rtx basereg = XEXP (XEXP (dst, 0), 0);
18034 rtx offsetreg = XEXP (XEXP (dst, 0), 1);
18035 gcc_assert (GET_CODE (XEXP (dst, 0)) == PLUS
18036 && REG_P (basereg)
18037 && REG_P (offsetreg)
18038 && REGNO (basereg) != REGNO (offsetreg));
18039 if (REGNO (basereg) == 0)
18041 rtx tmp = offsetreg;
18042 offsetreg = basereg;
18043 basereg = tmp;
18045 emit_insn (gen_add3_insn (basereg, basereg, offsetreg));
18046 restore_basereg = gen_sub3_insn (basereg, basereg, offsetreg);
18047 dst = replace_equiv_address (dst, basereg);
18050 else if (GET_CODE (XEXP (dst, 0)) != LO_SUM)
18051 gcc_assert (rs6000_offsettable_memref_p (dst));
18054 for (i = 0; i < nregs; i++)
18056 /* Calculate index to next subword. */
18057 ++j;
18058 if (j == nregs)
18059 j = 0;
18061 /* If compiler already emitted move of first word by
18062 store with update, no need to do anything. */
18063 if (j == 0 && used_update)
18064 continue;
18066 emit_insn (gen_rtx_SET (VOIDmode,
18067 simplify_gen_subreg (reg_mode, dst, mode,
18068 j * reg_mode_size),
18069 simplify_gen_subreg (reg_mode, src, mode,
18070 j * reg_mode_size)));
18072 if (restore_basereg != NULL_RTX)
18073 emit_insn (restore_basereg);
18078 /* This page contains routines that are used to determine what the
18079 function prologue and epilogue code will do and write them out. */
18081 /* Return the first fixed-point register that is required to be
18082 saved. 32 if none. */
18085 first_reg_to_save (void)
18087 int first_reg;
18089 /* Find lowest numbered live register. */
18090 for (first_reg = 13; first_reg <= 31; first_reg++)
18091 if (df_regs_ever_live_p (first_reg)
18092 && (! call_used_regs[first_reg]
18093 || (first_reg == RS6000_PIC_OFFSET_TABLE_REGNUM
18094 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
18095 || (DEFAULT_ABI == ABI_DARWIN && flag_pic)
18096 || (TARGET_TOC && TARGET_MINIMAL_TOC)))))
18097 break;
18099 #if TARGET_MACHO
18100 if (flag_pic
18101 && crtl->uses_pic_offset_table
18102 && first_reg > RS6000_PIC_OFFSET_TABLE_REGNUM)
18103 return RS6000_PIC_OFFSET_TABLE_REGNUM;
18104 #endif
18106 return first_reg;
18109 /* Similar, for FP regs. */
18112 first_fp_reg_to_save (void)
18114 int first_reg;
18116 /* Find lowest numbered live register. */
18117 for (first_reg = 14 + 32; first_reg <= 63; first_reg++)
18118 if (df_regs_ever_live_p (first_reg))
18119 break;
18121 return first_reg;
18124 /* Similar, for AltiVec regs. */
18126 static int
18127 first_altivec_reg_to_save (void)
18129 int i;
18131 /* Stack frame remains as is unless we are in AltiVec ABI. */
18132 if (! TARGET_ALTIVEC_ABI)
18133 return LAST_ALTIVEC_REGNO + 1;
18135 /* On Darwin, the unwind routines are compiled without
18136 TARGET_ALTIVEC, and use save_world to save/restore the
18137 altivec registers when necessary. */
18138 if (DEFAULT_ABI == ABI_DARWIN && crtl->calls_eh_return
18139 && ! TARGET_ALTIVEC)
18140 return FIRST_ALTIVEC_REGNO + 20;
18142 /* Find lowest numbered live register. */
18143 for (i = FIRST_ALTIVEC_REGNO + 20; i <= LAST_ALTIVEC_REGNO; ++i)
18144 if (df_regs_ever_live_p (i))
18145 break;
18147 return i;
18150 /* Return a 32-bit mask of the AltiVec registers we need to set in
18151 VRSAVE. Bit n of the return value is 1 if Vn is live. The MSB in
18152 the 32-bit word is 0. */
18154 static unsigned int
18155 compute_vrsave_mask (void)
18157 unsigned int i, mask = 0;
18159 /* On Darwin, the unwind routines are compiled without
18160 TARGET_ALTIVEC, and use save_world to save/restore the
18161 call-saved altivec registers when necessary. */
18162 if (DEFAULT_ABI == ABI_DARWIN && crtl->calls_eh_return
18163 && ! TARGET_ALTIVEC)
18164 mask |= 0xFFF;
18166 /* First, find out if we use _any_ altivec registers. */
18167 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
18168 if (df_regs_ever_live_p (i))
18169 mask |= ALTIVEC_REG_BIT (i);
18171 if (mask == 0)
18172 return mask;
18174 /* Next, remove the argument registers from the set. These must
18175 be in the VRSAVE mask set by the caller, so we don't need to add
18176 them in again. More importantly, the mask we compute here is
18177 used to generate CLOBBERs in the set_vrsave insn, and we do not
18178 wish the argument registers to die. */
18179 for (i = crtl->args.info.vregno - 1; i >= ALTIVEC_ARG_MIN_REG; --i)
18180 mask &= ~ALTIVEC_REG_BIT (i);
18182 /* Similarly, remove the return value from the set. */
18184 bool yes = false;
18185 diddle_return_value (is_altivec_return_reg, &yes);
18186 if (yes)
18187 mask &= ~ALTIVEC_REG_BIT (ALTIVEC_ARG_RETURN);
18190 return mask;
18193 /* For a very restricted set of circumstances, we can cut down the
18194 size of prologues/epilogues by calling our own save/restore-the-world
18195 routines. */
18197 static void
18198 compute_save_world_info (rs6000_stack_t *info_ptr)
18200 info_ptr->world_save_p = 1;
18201 info_ptr->world_save_p
18202 = (WORLD_SAVE_P (info_ptr)
18203 && DEFAULT_ABI == ABI_DARWIN
18204 && ! (cfun->calls_setjmp && flag_exceptions)
18205 && info_ptr->first_fp_reg_save == FIRST_SAVED_FP_REGNO
18206 && info_ptr->first_gp_reg_save == FIRST_SAVED_GP_REGNO
18207 && info_ptr->first_altivec_reg_save == FIRST_SAVED_ALTIVEC_REGNO
18208 && info_ptr->cr_save_p);
18210 /* This will not work in conjunction with sibcalls. Make sure there
18211 are none. (This check is expensive, but seldom executed.) */
18212 if (WORLD_SAVE_P (info_ptr))
18214 rtx insn;
18215 for ( insn = get_last_insn_anywhere (); insn; insn = PREV_INSN (insn))
18216 if ( GET_CODE (insn) == CALL_INSN
18217 && SIBLING_CALL_P (insn))
18219 info_ptr->world_save_p = 0;
18220 break;
18224 if (WORLD_SAVE_P (info_ptr))
18226 /* Even if we're not touching VRsave, make sure there's room on the
18227 stack for it, if it looks like we're calling SAVE_WORLD, which
18228 will attempt to save it. */
18229 info_ptr->vrsave_size = 4;
18231 /* If we are going to save the world, we need to save the link register too. */
18232 info_ptr->lr_save_p = 1;
18234 /* "Save" the VRsave register too if we're saving the world. */
18235 if (info_ptr->vrsave_mask == 0)
18236 info_ptr->vrsave_mask = compute_vrsave_mask ();
18238 /* Because the Darwin register save/restore routines only handle
18239 F14 .. F31 and V20 .. V31 as per the ABI, perform a consistency
18240 check. */
18241 gcc_assert (info_ptr->first_fp_reg_save >= FIRST_SAVED_FP_REGNO
18242 && (info_ptr->first_altivec_reg_save
18243 >= FIRST_SAVED_ALTIVEC_REGNO));
18245 return;
18249 static void
18250 is_altivec_return_reg (rtx reg, void *xyes)
18252 bool *yes = (bool *) xyes;
18253 if (REGNO (reg) == ALTIVEC_ARG_RETURN)
18254 *yes = true;
18258 /* Determine the strategy for savings/restoring registers. */
18260 enum {
18261 SAVRES_MULTIPLE = 0x1,
18262 SAVE_INLINE_FPRS = 0x2,
18263 SAVE_INLINE_GPRS = 0x4,
18264 REST_INLINE_FPRS = 0x8,
18265 REST_INLINE_GPRS = 0x10,
18266 SAVE_NOINLINE_GPRS_SAVES_LR = 0x20,
18267 SAVE_NOINLINE_FPRS_SAVES_LR = 0x40,
18268 REST_NOINLINE_FPRS_DOESNT_RESTORE_LR = 0x80
18271 static int
18272 rs6000_savres_strategy (rs6000_stack_t *info,
18273 bool using_static_chain_p)
18275 int strategy = 0;
18277 if (TARGET_MULTIPLE
18278 && !TARGET_POWERPC64
18279 && !(TARGET_SPE_ABI && info->spe_64bit_regs_used)
18280 && info->first_gp_reg_save < 31
18281 && no_global_regs_above (info->first_gp_reg_save, /*gpr=*/true))
18282 strategy |= SAVRES_MULTIPLE;
18284 if (crtl->calls_eh_return
18285 || cfun->machine->ra_need_lr
18286 || info->total_size > 32767)
18287 strategy |= (SAVE_INLINE_FPRS | REST_INLINE_FPRS
18288 | SAVE_INLINE_GPRS | REST_INLINE_GPRS);
18290 if (info->first_fp_reg_save == 64
18291 || FP_SAVE_INLINE (info->first_fp_reg_save)
18292 /* The out-of-line FP routines use double-precision stores;
18293 we can't use those routines if we don't have such stores. */
18294 || (TARGET_HARD_FLOAT && !TARGET_DOUBLE_FLOAT)
18295 || !no_global_regs_above (info->first_fp_reg_save, /*gpr=*/false))
18296 strategy |= SAVE_INLINE_FPRS | REST_INLINE_FPRS;
18298 if (info->first_gp_reg_save == 32
18299 || GP_SAVE_INLINE (info->first_gp_reg_save)
18300 || !((strategy & SAVRES_MULTIPLE)
18301 || no_global_regs_above (info->first_gp_reg_save, /*gpr=*/true)))
18302 strategy |= SAVE_INLINE_GPRS | REST_INLINE_GPRS;
18304 /* Don't bother to try to save things out-of-line if r11 is occupied
18305 by the static chain. It would require too much fiddling and the
18306 static chain is rarely used anyway. */
18307 if (using_static_chain_p)
18308 strategy |= SAVE_INLINE_FPRS | SAVE_INLINE_GPRS;
18310 /* If we are going to use store multiple, then don't even bother
18311 with the out-of-line routines, since the store-multiple
18312 instruction will always be smaller. */
18313 if ((strategy & SAVRES_MULTIPLE))
18314 strategy |= SAVE_INLINE_GPRS;
18316 /* The situation is more complicated with load multiple. We'd
18317 prefer to use the out-of-line routines for restores, since the
18318 "exit" out-of-line routines can handle the restore of LR and the
18319 frame teardown. However if doesn't make sense to use the
18320 out-of-line routine if that is the only reason we'd need to save
18321 LR, and we can't use the "exit" out-of-line gpr restore if we
18322 have saved some fprs; In those cases it is advantageous to use
18323 load multiple when available. */
18324 if ((strategy & SAVRES_MULTIPLE)
18325 && (!info->lr_save_p
18326 || info->first_fp_reg_save != 64))
18327 strategy |= REST_INLINE_GPRS;
18329 /* We can only use load multiple or the out-of-line routines to
18330 restore if we've used store multiple or out-of-line routines
18331 in the prologue, i.e. if we've saved all the registers from
18332 first_gp_reg_save. Otherwise, we risk loading garbage. */
18333 if ((strategy & (SAVE_INLINE_GPRS | SAVRES_MULTIPLE)) == SAVE_INLINE_GPRS)
18334 strategy |= REST_INLINE_GPRS;
18336 /* Saving CR interferes with the exit routines used on the SPE, so
18337 just punt here. */
18338 if (TARGET_SPE_ABI
18339 && info->spe_64bit_regs_used
18340 && info->cr_save_p)
18341 strategy |= REST_INLINE_GPRS;
18343 #ifdef POWERPC_LINUX
18344 if (TARGET_64BIT)
18346 if (!(strategy & SAVE_INLINE_FPRS))
18347 strategy |= SAVE_NOINLINE_FPRS_SAVES_LR;
18348 else if (!(strategy & SAVE_INLINE_GPRS)
18349 && info->first_fp_reg_save == 64)
18350 strategy |= SAVE_NOINLINE_GPRS_SAVES_LR;
18352 #else
18353 if (TARGET_AIX && !(strategy & REST_INLINE_FPRS))
18354 strategy |= REST_NOINLINE_FPRS_DOESNT_RESTORE_LR;
18355 #endif
18356 return strategy;
18359 /* Calculate the stack information for the current function. This is
18360 complicated by having two separate calling sequences, the AIX calling
18361 sequence and the V.4 calling sequence.
18363 AIX (and Darwin/Mac OS X) stack frames look like:
18364 32-bit 64-bit
18365 SP----> +---------------------------------------+
18366 | back chain to caller | 0 0
18367 +---------------------------------------+
18368 | saved CR | 4 8 (8-11)
18369 +---------------------------------------+
18370 | saved LR | 8 16
18371 +---------------------------------------+
18372 | reserved for compilers | 12 24
18373 +---------------------------------------+
18374 | reserved for binders | 16 32
18375 +---------------------------------------+
18376 | saved TOC pointer | 20 40
18377 +---------------------------------------+
18378 | Parameter save area (P) | 24 48
18379 +---------------------------------------+
18380 | Alloca space (A) | 24+P etc.
18381 +---------------------------------------+
18382 | Local variable space (L) | 24+P+A
18383 +---------------------------------------+
18384 | Float/int conversion temporary (X) | 24+P+A+L
18385 +---------------------------------------+
18386 | Save area for AltiVec registers (W) | 24+P+A+L+X
18387 +---------------------------------------+
18388 | AltiVec alignment padding (Y) | 24+P+A+L+X+W
18389 +---------------------------------------+
18390 | Save area for VRSAVE register (Z) | 24+P+A+L+X+W+Y
18391 +---------------------------------------+
18392 | Save area for GP registers (G) | 24+P+A+X+L+X+W+Y+Z
18393 +---------------------------------------+
18394 | Save area for FP registers (F) | 24+P+A+X+L+X+W+Y+Z+G
18395 +---------------------------------------+
18396 old SP->| back chain to caller's caller |
18397 +---------------------------------------+
18399 The required alignment for AIX configurations is two words (i.e., 8
18400 or 16 bytes).
18403 V.4 stack frames look like:
18405 SP----> +---------------------------------------+
18406 | back chain to caller | 0
18407 +---------------------------------------+
18408 | caller's saved LR | 4
18409 +---------------------------------------+
18410 | Parameter save area (P) | 8
18411 +---------------------------------------+
18412 | Alloca space (A) | 8+P
18413 +---------------------------------------+
18414 | Varargs save area (V) | 8+P+A
18415 +---------------------------------------+
18416 | Local variable space (L) | 8+P+A+V
18417 +---------------------------------------+
18418 | Float/int conversion temporary (X) | 8+P+A+V+L
18419 +---------------------------------------+
18420 | Save area for AltiVec registers (W) | 8+P+A+V+L+X
18421 +---------------------------------------+
18422 | AltiVec alignment padding (Y) | 8+P+A+V+L+X+W
18423 +---------------------------------------+
18424 | Save area for VRSAVE register (Z) | 8+P+A+V+L+X+W+Y
18425 +---------------------------------------+
18426 | SPE: area for 64-bit GP registers |
18427 +---------------------------------------+
18428 | SPE alignment padding |
18429 +---------------------------------------+
18430 | saved CR (C) | 8+P+A+V+L+X+W+Y+Z
18431 +---------------------------------------+
18432 | Save area for GP registers (G) | 8+P+A+V+L+X+W+Y+Z+C
18433 +---------------------------------------+
18434 | Save area for FP registers (F) | 8+P+A+V+L+X+W+Y+Z+C+G
18435 +---------------------------------------+
18436 old SP->| back chain to caller's caller |
18437 +---------------------------------------+
18439 The required alignment for V.4 is 16 bytes, or 8 bytes if -meabi is
18440 given. (But note below and in sysv4.h that we require only 8 and
18441 may round up the size of our stack frame anyways. The historical
18442 reason is early versions of powerpc-linux which didn't properly
18443 align the stack at program startup. A happy side-effect is that
18444 -mno-eabi libraries can be used with -meabi programs.)
18446 The EABI configuration defaults to the V.4 layout. However,
18447 the stack alignment requirements may differ. If -mno-eabi is not
18448 given, the required stack alignment is 8 bytes; if -mno-eabi is
18449 given, the required alignment is 16 bytes. (But see V.4 comment
18450 above.) */
18452 #ifndef ABI_STACK_BOUNDARY
18453 #define ABI_STACK_BOUNDARY STACK_BOUNDARY
18454 #endif
18456 static rs6000_stack_t *
18457 rs6000_stack_info (void)
18459 #ifdef ENABLE_CHECKING
18460 static rs6000_stack_t info_save;
18461 #endif
18462 rs6000_stack_t *info_ptr = &stack_info;
18463 int reg_size = TARGET_32BIT ? 4 : 8;
18464 int ehrd_size;
18465 int save_align;
18466 int first_gp;
18467 HOST_WIDE_INT non_fixed_size;
18468 bool using_static_chain_p;
18470 #ifdef ENABLE_CHECKING
18471 memcpy (&info_save, &stack_info, sizeof stack_info);
18472 #else
18473 if (reload_completed && info_ptr->reload_completed)
18474 return info_ptr;
18475 #endif
18477 memset (&stack_info, 0, sizeof (stack_info));
18478 info_ptr->reload_completed = reload_completed;
18480 if (TARGET_SPE)
18482 /* Cache value so we don't rescan instruction chain over and over. */
18483 if (cfun->machine->insn_chain_scanned_p == 0)
18484 cfun->machine->insn_chain_scanned_p
18485 = spe_func_has_64bit_regs_p () + 1;
18486 info_ptr->spe_64bit_regs_used = cfun->machine->insn_chain_scanned_p - 1;
18489 /* Select which calling sequence. */
18490 info_ptr->abi = DEFAULT_ABI;
18492 /* Calculate which registers need to be saved & save area size. */
18493 info_ptr->first_gp_reg_save = first_reg_to_save ();
18494 /* Assume that we will have to save RS6000_PIC_OFFSET_TABLE_REGNUM,
18495 even if it currently looks like we won't. Reload may need it to
18496 get at a constant; if so, it will have already created a constant
18497 pool entry for it. */
18498 if (((TARGET_TOC && TARGET_MINIMAL_TOC)
18499 || (flag_pic == 1 && DEFAULT_ABI == ABI_V4)
18500 || (flag_pic && DEFAULT_ABI == ABI_DARWIN))
18501 && crtl->uses_const_pool
18502 && info_ptr->first_gp_reg_save > RS6000_PIC_OFFSET_TABLE_REGNUM)
18503 first_gp = RS6000_PIC_OFFSET_TABLE_REGNUM;
18504 else
18505 first_gp = info_ptr->first_gp_reg_save;
18507 info_ptr->gp_size = reg_size * (32 - first_gp);
18509 /* For the SPE, we have an additional upper 32-bits on each GPR.
18510 Ideally we should save the entire 64-bits only when the upper
18511 half is used in SIMD instructions. Since we only record
18512 registers live (not the size they are used in), this proves
18513 difficult because we'd have to traverse the instruction chain at
18514 the right time, taking reload into account. This is a real pain,
18515 so we opt to save the GPRs in 64-bits always if but one register
18516 gets used in 64-bits. Otherwise, all the registers in the frame
18517 get saved in 32-bits.
18519 So... since when we save all GPRs (except the SP) in 64-bits, the
18520 traditional GP save area will be empty. */
18521 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
18522 info_ptr->gp_size = 0;
18524 info_ptr->first_fp_reg_save = first_fp_reg_to_save ();
18525 info_ptr->fp_size = 8 * (64 - info_ptr->first_fp_reg_save);
18527 info_ptr->first_altivec_reg_save = first_altivec_reg_to_save ();
18528 info_ptr->altivec_size = 16 * (LAST_ALTIVEC_REGNO + 1
18529 - info_ptr->first_altivec_reg_save);
18531 /* Does this function call anything? */
18532 info_ptr->calls_p = (! current_function_is_leaf
18533 || cfun->machine->ra_needs_full_frame);
18535 /* Determine if we need to save the condition code registers. */
18536 if (df_regs_ever_live_p (CR2_REGNO)
18537 || df_regs_ever_live_p (CR3_REGNO)
18538 || df_regs_ever_live_p (CR4_REGNO))
18540 info_ptr->cr_save_p = 1;
18541 if (DEFAULT_ABI == ABI_V4)
18542 info_ptr->cr_size = reg_size;
18545 /* If the current function calls __builtin_eh_return, then we need
18546 to allocate stack space for registers that will hold data for
18547 the exception handler. */
18548 if (crtl->calls_eh_return)
18550 unsigned int i;
18551 for (i = 0; EH_RETURN_DATA_REGNO (i) != INVALID_REGNUM; ++i)
18552 continue;
18554 /* SPE saves EH registers in 64-bits. */
18555 ehrd_size = i * (TARGET_SPE_ABI
18556 && info_ptr->spe_64bit_regs_used != 0
18557 ? UNITS_PER_SPE_WORD : UNITS_PER_WORD);
18559 else
18560 ehrd_size = 0;
18562 /* Determine various sizes. */
18563 info_ptr->reg_size = reg_size;
18564 info_ptr->fixed_size = RS6000_SAVE_AREA;
18565 info_ptr->vars_size = RS6000_ALIGN (get_frame_size (), 8);
18566 info_ptr->parm_size = RS6000_ALIGN (crtl->outgoing_args_size,
18567 TARGET_ALTIVEC ? 16 : 8);
18568 if (FRAME_GROWS_DOWNWARD)
18569 info_ptr->vars_size
18570 += RS6000_ALIGN (info_ptr->fixed_size + info_ptr->vars_size
18571 + info_ptr->parm_size,
18572 ABI_STACK_BOUNDARY / BITS_PER_UNIT)
18573 - (info_ptr->fixed_size + info_ptr->vars_size
18574 + info_ptr->parm_size);
18576 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
18577 info_ptr->spe_gp_size = 8 * (32 - first_gp);
18578 else
18579 info_ptr->spe_gp_size = 0;
18581 if (TARGET_ALTIVEC_ABI)
18582 info_ptr->vrsave_mask = compute_vrsave_mask ();
18583 else
18584 info_ptr->vrsave_mask = 0;
18586 if (TARGET_ALTIVEC_VRSAVE && info_ptr->vrsave_mask)
18587 info_ptr->vrsave_size = 4;
18588 else
18589 info_ptr->vrsave_size = 0;
18591 compute_save_world_info (info_ptr);
18593 /* Calculate the offsets. */
18594 switch (DEFAULT_ABI)
18596 case ABI_NONE:
18597 default:
18598 gcc_unreachable ();
18600 case ABI_AIX:
18601 case ABI_DARWIN:
18602 info_ptr->fp_save_offset = - info_ptr->fp_size;
18603 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
18605 if (TARGET_ALTIVEC_ABI)
18607 info_ptr->vrsave_save_offset
18608 = info_ptr->gp_save_offset - info_ptr->vrsave_size;
18610 /* Align stack so vector save area is on a quadword boundary.
18611 The padding goes above the vectors. */
18612 if (info_ptr->altivec_size != 0)
18613 info_ptr->altivec_padding_size
18614 = info_ptr->vrsave_save_offset & 0xF;
18615 else
18616 info_ptr->altivec_padding_size = 0;
18618 info_ptr->altivec_save_offset
18619 = info_ptr->vrsave_save_offset
18620 - info_ptr->altivec_padding_size
18621 - info_ptr->altivec_size;
18622 gcc_assert (info_ptr->altivec_size == 0
18623 || info_ptr->altivec_save_offset % 16 == 0);
18625 /* Adjust for AltiVec case. */
18626 info_ptr->ehrd_offset = info_ptr->altivec_save_offset - ehrd_size;
18628 else
18629 info_ptr->ehrd_offset = info_ptr->gp_save_offset - ehrd_size;
18630 info_ptr->cr_save_offset = reg_size; /* first word when 64-bit. */
18631 info_ptr->lr_save_offset = 2*reg_size;
18632 break;
18634 case ABI_V4:
18635 info_ptr->fp_save_offset = - info_ptr->fp_size;
18636 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
18637 info_ptr->cr_save_offset = info_ptr->gp_save_offset - info_ptr->cr_size;
18639 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
18641 /* Align stack so SPE GPR save area is aligned on a
18642 double-word boundary. */
18643 if (info_ptr->spe_gp_size != 0 && info_ptr->cr_save_offset != 0)
18644 info_ptr->spe_padding_size
18645 = 8 - (-info_ptr->cr_save_offset % 8);
18646 else
18647 info_ptr->spe_padding_size = 0;
18649 info_ptr->spe_gp_save_offset
18650 = info_ptr->cr_save_offset
18651 - info_ptr->spe_padding_size
18652 - info_ptr->spe_gp_size;
18654 /* Adjust for SPE case. */
18655 info_ptr->ehrd_offset = info_ptr->spe_gp_save_offset;
18657 else if (TARGET_ALTIVEC_ABI)
18659 info_ptr->vrsave_save_offset
18660 = info_ptr->cr_save_offset - info_ptr->vrsave_size;
18662 /* Align stack so vector save area is on a quadword boundary. */
18663 if (info_ptr->altivec_size != 0)
18664 info_ptr->altivec_padding_size
18665 = 16 - (-info_ptr->vrsave_save_offset % 16);
18666 else
18667 info_ptr->altivec_padding_size = 0;
18669 info_ptr->altivec_save_offset
18670 = info_ptr->vrsave_save_offset
18671 - info_ptr->altivec_padding_size
18672 - info_ptr->altivec_size;
18674 /* Adjust for AltiVec case. */
18675 info_ptr->ehrd_offset = info_ptr->altivec_save_offset;
18677 else
18678 info_ptr->ehrd_offset = info_ptr->cr_save_offset;
18679 info_ptr->ehrd_offset -= ehrd_size;
18680 info_ptr->lr_save_offset = reg_size;
18681 break;
18684 save_align = (TARGET_ALTIVEC_ABI || DEFAULT_ABI == ABI_DARWIN) ? 16 : 8;
18685 info_ptr->save_size = RS6000_ALIGN (info_ptr->fp_size
18686 + info_ptr->gp_size
18687 + info_ptr->altivec_size
18688 + info_ptr->altivec_padding_size
18689 + info_ptr->spe_gp_size
18690 + info_ptr->spe_padding_size
18691 + ehrd_size
18692 + info_ptr->cr_size
18693 + info_ptr->vrsave_size,
18694 save_align);
18696 non_fixed_size = (info_ptr->vars_size
18697 + info_ptr->parm_size
18698 + info_ptr->save_size);
18700 info_ptr->total_size = RS6000_ALIGN (non_fixed_size + info_ptr->fixed_size,
18701 ABI_STACK_BOUNDARY / BITS_PER_UNIT);
18703 /* Determine if we need to save the link register. */
18704 if (info_ptr->calls_p
18705 || (DEFAULT_ABI == ABI_AIX
18706 && crtl->profile
18707 && !TARGET_PROFILE_KERNEL)
18708 || (DEFAULT_ABI == ABI_V4 && cfun->calls_alloca)
18709 #ifdef TARGET_RELOCATABLE
18710 || (TARGET_RELOCATABLE && (get_pool_size () != 0))
18711 #endif
18712 || rs6000_ra_ever_killed ())
18713 info_ptr->lr_save_p = 1;
18715 using_static_chain_p = (cfun->static_chain_decl != NULL_TREE
18716 && df_regs_ever_live_p (STATIC_CHAIN_REGNUM)
18717 && call_used_regs[STATIC_CHAIN_REGNUM]);
18718 info_ptr->savres_strategy = rs6000_savres_strategy (info_ptr,
18719 using_static_chain_p);
18721 if (!(info_ptr->savres_strategy & SAVE_INLINE_GPRS)
18722 || !(info_ptr->savres_strategy & SAVE_INLINE_FPRS)
18723 || !(info_ptr->savres_strategy & REST_INLINE_GPRS)
18724 || !(info_ptr->savres_strategy & REST_INLINE_FPRS))
18725 info_ptr->lr_save_p = 1;
18727 if (info_ptr->lr_save_p)
18728 df_set_regs_ever_live (LR_REGNO, true);
18730 /* Determine if we need to allocate any stack frame:
18732 For AIX we need to push the stack if a frame pointer is needed
18733 (because the stack might be dynamically adjusted), if we are
18734 debugging, if we make calls, or if the sum of fp_save, gp_save,
18735 and local variables are more than the space needed to save all
18736 non-volatile registers: 32-bit: 18*8 + 19*4 = 220 or 64-bit: 18*8
18737 + 18*8 = 288 (GPR13 reserved).
18739 For V.4 we don't have the stack cushion that AIX uses, but assume
18740 that the debugger can handle stackless frames. */
18742 if (info_ptr->calls_p)
18743 info_ptr->push_p = 1;
18745 else if (DEFAULT_ABI == ABI_V4)
18746 info_ptr->push_p = non_fixed_size != 0;
18748 else if (frame_pointer_needed)
18749 info_ptr->push_p = 1;
18751 else if (TARGET_XCOFF && write_symbols != NO_DEBUG)
18752 info_ptr->push_p = 1;
18754 else
18755 info_ptr->push_p = non_fixed_size > (TARGET_32BIT ? 220 : 288);
18757 /* Zero offsets if we're not saving those registers. */
18758 if (info_ptr->fp_size == 0)
18759 info_ptr->fp_save_offset = 0;
18761 if (info_ptr->gp_size == 0)
18762 info_ptr->gp_save_offset = 0;
18764 if (! TARGET_ALTIVEC_ABI || info_ptr->altivec_size == 0)
18765 info_ptr->altivec_save_offset = 0;
18767 if (! TARGET_ALTIVEC_ABI || info_ptr->vrsave_mask == 0)
18768 info_ptr->vrsave_save_offset = 0;
18770 if (! TARGET_SPE_ABI
18771 || info_ptr->spe_64bit_regs_used == 0
18772 || info_ptr->spe_gp_size == 0)
18773 info_ptr->spe_gp_save_offset = 0;
18775 if (! info_ptr->lr_save_p)
18776 info_ptr->lr_save_offset = 0;
18778 if (! info_ptr->cr_save_p)
18779 info_ptr->cr_save_offset = 0;
18781 #ifdef ENABLE_CHECKING
18782 gcc_assert (!(reload_completed && info_save.reload_completed)
18783 || memcmp (&info_save, &stack_info, sizeof stack_info) == 0);
18784 #endif
18785 return info_ptr;
18788 /* Return true if the current function uses any GPRs in 64-bit SIMD
18789 mode. */
18791 static bool
18792 spe_func_has_64bit_regs_p (void)
18794 rtx insns, insn;
18796 /* Functions that save and restore all the call-saved registers will
18797 need to save/restore the registers in 64-bits. */
18798 if (crtl->calls_eh_return
18799 || cfun->calls_setjmp
18800 || crtl->has_nonlocal_goto)
18801 return true;
18803 insns = get_insns ();
18805 for (insn = NEXT_INSN (insns); insn != NULL_RTX; insn = NEXT_INSN (insn))
18807 if (INSN_P (insn))
18809 rtx i;
18811 /* FIXME: This should be implemented with attributes...
18813 (set_attr "spe64" "true")....then,
18814 if (get_spe64(insn)) return true;
18816 It's the only reliable way to do the stuff below. */
18818 i = PATTERN (insn);
18819 if (GET_CODE (i) == SET)
18821 enum machine_mode mode = GET_MODE (SET_SRC (i));
18823 if (SPE_VECTOR_MODE (mode))
18824 return true;
18825 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode))
18826 return true;
18831 return false;
18834 static void
18835 debug_stack_info (rs6000_stack_t *info)
18837 const char *abi_string;
18839 if (! info)
18840 info = rs6000_stack_info ();
18842 fprintf (stderr, "\nStack information for function %s:\n",
18843 ((current_function_decl && DECL_NAME (current_function_decl))
18844 ? IDENTIFIER_POINTER (DECL_NAME (current_function_decl))
18845 : "<unknown>"));
18847 switch (info->abi)
18849 default: abi_string = "Unknown"; break;
18850 case ABI_NONE: abi_string = "NONE"; break;
18851 case ABI_AIX: abi_string = "AIX"; break;
18852 case ABI_DARWIN: abi_string = "Darwin"; break;
18853 case ABI_V4: abi_string = "V.4"; break;
18856 fprintf (stderr, "\tABI = %5s\n", abi_string);
18858 if (TARGET_ALTIVEC_ABI)
18859 fprintf (stderr, "\tALTIVEC ABI extensions enabled.\n");
18861 if (TARGET_SPE_ABI)
18862 fprintf (stderr, "\tSPE ABI extensions enabled.\n");
18864 if (info->first_gp_reg_save != 32)
18865 fprintf (stderr, "\tfirst_gp_reg_save = %5d\n", info->first_gp_reg_save);
18867 if (info->first_fp_reg_save != 64)
18868 fprintf (stderr, "\tfirst_fp_reg_save = %5d\n", info->first_fp_reg_save);
18870 if (info->first_altivec_reg_save <= LAST_ALTIVEC_REGNO)
18871 fprintf (stderr, "\tfirst_altivec_reg_save = %5d\n",
18872 info->first_altivec_reg_save);
18874 if (info->lr_save_p)
18875 fprintf (stderr, "\tlr_save_p = %5d\n", info->lr_save_p);
18877 if (info->cr_save_p)
18878 fprintf (stderr, "\tcr_save_p = %5d\n", info->cr_save_p);
18880 if (info->vrsave_mask)
18881 fprintf (stderr, "\tvrsave_mask = 0x%x\n", info->vrsave_mask);
18883 if (info->push_p)
18884 fprintf (stderr, "\tpush_p = %5d\n", info->push_p);
18886 if (info->calls_p)
18887 fprintf (stderr, "\tcalls_p = %5d\n", info->calls_p);
18889 if (info->gp_save_offset)
18890 fprintf (stderr, "\tgp_save_offset = %5d\n", info->gp_save_offset);
18892 if (info->fp_save_offset)
18893 fprintf (stderr, "\tfp_save_offset = %5d\n", info->fp_save_offset);
18895 if (info->altivec_save_offset)
18896 fprintf (stderr, "\taltivec_save_offset = %5d\n",
18897 info->altivec_save_offset);
18899 if (info->spe_gp_save_offset)
18900 fprintf (stderr, "\tspe_gp_save_offset = %5d\n",
18901 info->spe_gp_save_offset);
18903 if (info->vrsave_save_offset)
18904 fprintf (stderr, "\tvrsave_save_offset = %5d\n",
18905 info->vrsave_save_offset);
18907 if (info->lr_save_offset)
18908 fprintf (stderr, "\tlr_save_offset = %5d\n", info->lr_save_offset);
18910 if (info->cr_save_offset)
18911 fprintf (stderr, "\tcr_save_offset = %5d\n", info->cr_save_offset);
18913 if (info->varargs_save_offset)
18914 fprintf (stderr, "\tvarargs_save_offset = %5d\n", info->varargs_save_offset);
18916 if (info->total_size)
18917 fprintf (stderr, "\ttotal_size = "HOST_WIDE_INT_PRINT_DEC"\n",
18918 info->total_size);
18920 if (info->vars_size)
18921 fprintf (stderr, "\tvars_size = "HOST_WIDE_INT_PRINT_DEC"\n",
18922 info->vars_size);
18924 if (info->parm_size)
18925 fprintf (stderr, "\tparm_size = %5d\n", info->parm_size);
18927 if (info->fixed_size)
18928 fprintf (stderr, "\tfixed_size = %5d\n", info->fixed_size);
18930 if (info->gp_size)
18931 fprintf (stderr, "\tgp_size = %5d\n", info->gp_size);
18933 if (info->spe_gp_size)
18934 fprintf (stderr, "\tspe_gp_size = %5d\n", info->spe_gp_size);
18936 if (info->fp_size)
18937 fprintf (stderr, "\tfp_size = %5d\n", info->fp_size);
18939 if (info->altivec_size)
18940 fprintf (stderr, "\taltivec_size = %5d\n", info->altivec_size);
18942 if (info->vrsave_size)
18943 fprintf (stderr, "\tvrsave_size = %5d\n", info->vrsave_size);
18945 if (info->altivec_padding_size)
18946 fprintf (stderr, "\taltivec_padding_size= %5d\n",
18947 info->altivec_padding_size);
18949 if (info->spe_padding_size)
18950 fprintf (stderr, "\tspe_padding_size = %5d\n",
18951 info->spe_padding_size);
18953 if (info->cr_size)
18954 fprintf (stderr, "\tcr_size = %5d\n", info->cr_size);
18956 if (info->save_size)
18957 fprintf (stderr, "\tsave_size = %5d\n", info->save_size);
18959 if (info->reg_size != 4)
18960 fprintf (stderr, "\treg_size = %5d\n", info->reg_size);
18962 fprintf (stderr, "\n");
18966 rs6000_return_addr (int count, rtx frame)
18968 /* Currently we don't optimize very well between prolog and body
18969 code and for PIC code the code can be actually quite bad, so
18970 don't try to be too clever here. */
18971 if (count != 0 || (DEFAULT_ABI != ABI_AIX && flag_pic))
18973 cfun->machine->ra_needs_full_frame = 1;
18975 return
18976 gen_rtx_MEM
18977 (Pmode,
18978 memory_address
18979 (Pmode,
18980 plus_constant (copy_to_reg
18981 (gen_rtx_MEM (Pmode,
18982 memory_address (Pmode, frame))),
18983 RETURN_ADDRESS_OFFSET)));
18986 cfun->machine->ra_need_lr = 1;
18987 return get_hard_reg_initial_val (Pmode, LR_REGNO);
18990 /* Say whether a function is a candidate for sibcall handling or not.
18991 We do not allow indirect calls to be optimized into sibling calls.
18992 Also, we can't do it if there are any vector parameters; there's
18993 nowhere to put the VRsave code so it works; note that functions with
18994 vector parameters are required to have a prototype, so the argument
18995 type info must be available here. (The tail recursion case can work
18996 with vector parameters, but there's no way to distinguish here.) */
18997 static bool
18998 rs6000_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED)
19000 tree type;
19001 if (decl)
19003 if (TARGET_ALTIVEC_VRSAVE)
19005 for (type = TYPE_ARG_TYPES (TREE_TYPE (decl));
19006 type; type = TREE_CHAIN (type))
19008 if (TREE_CODE (TREE_VALUE (type)) == VECTOR_TYPE)
19009 return false;
19012 if (DEFAULT_ABI == ABI_DARWIN
19013 || ((*targetm.binds_local_p) (decl)
19014 && (DEFAULT_ABI != ABI_AIX || !DECL_EXTERNAL (decl))))
19016 tree attr_list = TYPE_ATTRIBUTES (TREE_TYPE (decl));
19018 if (!lookup_attribute ("longcall", attr_list)
19019 || lookup_attribute ("shortcall", attr_list))
19020 return true;
19023 return false;
19026 /* NULL if INSN insn is valid within a low-overhead loop.
19027 Otherwise return why doloop cannot be applied.
19028 PowerPC uses the COUNT register for branch on table instructions. */
19030 static const char *
19031 rs6000_invalid_within_doloop (const_rtx insn)
19033 if (CALL_P (insn))
19034 return "Function call in the loop.";
19036 if (JUMP_P (insn)
19037 && (GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC
19038 || GET_CODE (PATTERN (insn)) == ADDR_VEC))
19039 return "Computed branch in the loop.";
19041 return NULL;
19044 static int
19045 rs6000_ra_ever_killed (void)
19047 rtx top;
19048 rtx reg;
19049 rtx insn;
19051 if (cfun->is_thunk)
19052 return 0;
19054 if (cfun->machine->lr_save_state)
19055 return cfun->machine->lr_save_state - 1;
19057 /* regs_ever_live has LR marked as used if any sibcalls are present,
19058 but this should not force saving and restoring in the
19059 pro/epilogue. Likewise, reg_set_between_p thinks a sibcall
19060 clobbers LR, so that is inappropriate. */
19062 /* Also, the prologue can generate a store into LR that
19063 doesn't really count, like this:
19065 move LR->R0
19066 bcl to set PIC register
19067 move LR->R31
19068 move R0->LR
19070 When we're called from the epilogue, we need to avoid counting
19071 this as a store. */
19073 push_topmost_sequence ();
19074 top = get_insns ();
19075 pop_topmost_sequence ();
19076 reg = gen_rtx_REG (Pmode, LR_REGNO);
19078 for (insn = NEXT_INSN (top); insn != NULL_RTX; insn = NEXT_INSN (insn))
19080 if (INSN_P (insn))
19082 if (CALL_P (insn))
19084 if (!SIBLING_CALL_P (insn))
19085 return 1;
19087 else if (find_regno_note (insn, REG_INC, LR_REGNO))
19088 return 1;
19089 else if (set_of (reg, insn) != NULL_RTX
19090 && !prologue_epilogue_contains (insn))
19091 return 1;
19094 return 0;
19097 /* Emit instructions needed to load the TOC register.
19098 This is only needed when TARGET_TOC, TARGET_MINIMAL_TOC, and there is
19099 a constant pool; or for SVR4 -fpic. */
19101 void
19102 rs6000_emit_load_toc_table (int fromprolog)
19104 rtx dest;
19105 dest = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
19107 if (TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI != ABI_AIX && flag_pic)
19109 char buf[30];
19110 rtx lab, tmp1, tmp2, got;
19112 lab = gen_label_rtx ();
19113 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (lab));
19114 lab = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
19115 if (flag_pic == 2)
19116 got = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
19117 else
19118 got = rs6000_got_sym ();
19119 tmp1 = tmp2 = dest;
19120 if (!fromprolog)
19122 tmp1 = gen_reg_rtx (Pmode);
19123 tmp2 = gen_reg_rtx (Pmode);
19125 emit_insn (gen_load_toc_v4_PIC_1 (lab));
19126 emit_move_insn (tmp1, gen_rtx_REG (Pmode, LR_REGNO));
19127 emit_insn (gen_load_toc_v4_PIC_3b (tmp2, tmp1, got, lab));
19128 emit_insn (gen_load_toc_v4_PIC_3c (dest, tmp2, got, lab));
19130 else if (TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 1)
19132 emit_insn (gen_load_toc_v4_pic_si ());
19133 emit_move_insn (dest, gen_rtx_REG (Pmode, LR_REGNO));
19135 else if (TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2)
19137 char buf[30];
19138 rtx temp0 = (fromprolog
19139 ? gen_rtx_REG (Pmode, 0)
19140 : gen_reg_rtx (Pmode));
19142 if (fromprolog)
19144 rtx symF, symL;
19146 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
19147 symF = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
19149 ASM_GENERATE_INTERNAL_LABEL (buf, "LCL", rs6000_pic_labelno);
19150 symL = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
19152 emit_insn (gen_load_toc_v4_PIC_1 (symF));
19153 emit_move_insn (dest, gen_rtx_REG (Pmode, LR_REGNO));
19154 emit_insn (gen_load_toc_v4_PIC_2 (temp0, dest, symL, symF));
19156 else
19158 rtx tocsym, lab;
19160 tocsym = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
19161 lab = gen_label_rtx ();
19162 emit_insn (gen_load_toc_v4_PIC_1b (tocsym, lab));
19163 emit_move_insn (dest, gen_rtx_REG (Pmode, LR_REGNO));
19164 emit_move_insn (temp0, gen_rtx_MEM (Pmode, dest));
19166 emit_insn (gen_addsi3 (dest, temp0, dest));
19168 else if (TARGET_ELF && !TARGET_AIX && flag_pic == 0 && TARGET_MINIMAL_TOC)
19170 /* This is for AIX code running in non-PIC ELF32. */
19171 char buf[30];
19172 rtx realsym;
19173 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
19174 realsym = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
19176 emit_insn (gen_elf_high (dest, realsym));
19177 emit_insn (gen_elf_low (dest, dest, realsym));
19179 else
19181 gcc_assert (DEFAULT_ABI == ABI_AIX);
19183 if (TARGET_32BIT)
19184 emit_insn (gen_load_toc_aix_si (dest));
19185 else
19186 emit_insn (gen_load_toc_aix_di (dest));
19190 /* Emit instructions to restore the link register after determining where
19191 its value has been stored. */
19193 void
19194 rs6000_emit_eh_reg_restore (rtx source, rtx scratch)
19196 rs6000_stack_t *info = rs6000_stack_info ();
19197 rtx operands[2];
19199 operands[0] = source;
19200 operands[1] = scratch;
19202 if (info->lr_save_p)
19204 rtx frame_rtx = stack_pointer_rtx;
19205 HOST_WIDE_INT sp_offset = 0;
19206 rtx tmp;
19208 if (frame_pointer_needed
19209 || cfun->calls_alloca
19210 || info->total_size > 32767)
19212 tmp = gen_frame_mem (Pmode, frame_rtx);
19213 emit_move_insn (operands[1], tmp);
19214 frame_rtx = operands[1];
19216 else if (info->push_p)
19217 sp_offset = info->total_size;
19219 tmp = plus_constant (frame_rtx, info->lr_save_offset + sp_offset);
19220 tmp = gen_frame_mem (Pmode, tmp);
19221 emit_move_insn (tmp, operands[0]);
19223 else
19224 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO), operands[0]);
19226 /* Freeze lr_save_p. We've just emitted rtl that depends on the
19227 state of lr_save_p so any change from here on would be a bug. In
19228 particular, stop rs6000_ra_ever_killed from considering the SET
19229 of lr we may have added just above. */
19230 cfun->machine->lr_save_state = info->lr_save_p + 1;
19233 static GTY(()) alias_set_type set = -1;
19235 alias_set_type
19236 get_TOC_alias_set (void)
19238 if (set == -1)
19239 set = new_alias_set ();
19240 return set;
19243 /* This returns nonzero if the current function uses the TOC. This is
19244 determined by the presence of (use (unspec ... UNSPEC_TOC)), which
19245 is generated by the ABI_V4 load_toc_* patterns. */
19246 #if TARGET_ELF
19247 static int
19248 uses_TOC (void)
19250 rtx insn;
19252 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
19253 if (INSN_P (insn))
19255 rtx pat = PATTERN (insn);
19256 int i;
19258 if (GET_CODE (pat) == PARALLEL)
19259 for (i = 0; i < XVECLEN (pat, 0); i++)
19261 rtx sub = XVECEXP (pat, 0, i);
19262 if (GET_CODE (sub) == USE)
19264 sub = XEXP (sub, 0);
19265 if (GET_CODE (sub) == UNSPEC
19266 && XINT (sub, 1) == UNSPEC_TOC)
19267 return 1;
19271 return 0;
19273 #endif
19276 create_TOC_reference (rtx symbol, rtx largetoc_reg)
19278 rtx tocrel, tocreg;
19280 if (TARGET_DEBUG_ADDR)
19282 if (GET_CODE (symbol) == SYMBOL_REF)
19283 fprintf (stderr, "\ncreate_TOC_reference, (symbol_ref %s)\n",
19284 XSTR (symbol, 0));
19285 else
19287 fprintf (stderr, "\ncreate_TOC_reference, code %s:\n",
19288 GET_RTX_NAME (GET_CODE (symbol)));
19289 debug_rtx (symbol);
19293 if (!can_create_pseudo_p ())
19294 df_set_regs_ever_live (TOC_REGISTER, true);
19296 tocrel = gen_rtx_CONST (Pmode,
19297 gen_rtx_UNSPEC (Pmode, gen_rtvec (1, symbol),
19298 UNSPEC_TOCREL));
19299 tocreg = gen_rtx_REG (Pmode, TOC_REGISTER);
19300 if (TARGET_CMODEL != CMODEL_SMALL)
19302 rtx hi = gen_rtx_PLUS (Pmode, tocreg, gen_rtx_HIGH (Pmode, tocrel));
19303 if (largetoc_reg != NULL)
19305 emit_move_insn (largetoc_reg, hi);
19306 hi = largetoc_reg;
19308 return gen_rtx_LO_SUM (Pmode, hi, copy_rtx (tocrel));
19310 else
19311 return gen_rtx_PLUS (Pmode, tocreg, tocrel);
19314 /* Issue assembly directives that create a reference to the given DWARF
19315 FRAME_TABLE_LABEL from the current function section. */
19316 void
19317 rs6000_aix_asm_output_dwarf_table_ref (char * frame_table_label)
19319 fprintf (asm_out_file, "\t.ref %s\n",
19320 TARGET_STRIP_NAME_ENCODING (frame_table_label));
19323 /* This ties together stack memory (MEM with an alias set of frame_alias_set)
19324 and the change to the stack pointer. */
19326 static void
19327 rs6000_emit_stack_tie (void)
19329 rtx mem = gen_frame_mem (BLKmode,
19330 gen_rtx_REG (Pmode, STACK_POINTER_REGNUM));
19332 emit_insn (gen_stack_tie (mem));
19335 /* Emit the correct code for allocating stack space, as insns.
19336 If COPY_REG, make sure a copy of the old frame is left there.
19337 The generated code may use hard register 0 as a temporary. */
19339 static void
19340 rs6000_emit_allocate_stack (HOST_WIDE_INT size, rtx copy_reg)
19342 rtx insn;
19343 rtx stack_reg = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
19344 rtx tmp_reg = gen_rtx_REG (Pmode, 0);
19345 rtx todec = gen_int_mode (-size, Pmode);
19346 rtx par, set, mem;
19348 if (INTVAL (todec) != -size)
19350 warning (0, "stack frame too large");
19351 emit_insn (gen_trap ());
19352 return;
19355 if (crtl->limit_stack)
19357 if (REG_P (stack_limit_rtx)
19358 && REGNO (stack_limit_rtx) > 1
19359 && REGNO (stack_limit_rtx) <= 31)
19361 emit_insn (gen_add3_insn (tmp_reg, stack_limit_rtx, GEN_INT (size)));
19362 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
19363 const0_rtx));
19365 else if (GET_CODE (stack_limit_rtx) == SYMBOL_REF
19366 && TARGET_32BIT
19367 && DEFAULT_ABI == ABI_V4)
19369 rtx toload = gen_rtx_CONST (VOIDmode,
19370 gen_rtx_PLUS (Pmode,
19371 stack_limit_rtx,
19372 GEN_INT (size)));
19374 emit_insn (gen_elf_high (tmp_reg, toload));
19375 emit_insn (gen_elf_low (tmp_reg, tmp_reg, toload));
19376 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
19377 const0_rtx));
19379 else
19380 warning (0, "stack limit expression is not supported");
19383 if (copy_reg)
19384 emit_move_insn (copy_reg, stack_reg);
19386 if (size > 32767)
19388 /* Need a note here so that try_split doesn't get confused. */
19389 if (get_last_insn () == NULL_RTX)
19390 emit_note (NOTE_INSN_DELETED);
19391 insn = emit_move_insn (tmp_reg, todec);
19392 try_split (PATTERN (insn), insn, 0);
19393 todec = tmp_reg;
19396 insn = emit_insn (TARGET_32BIT
19397 ? gen_movsi_update_stack (stack_reg, stack_reg,
19398 todec, stack_reg)
19399 : gen_movdi_di_update_stack (stack_reg, stack_reg,
19400 todec, stack_reg));
19401 /* Since we didn't use gen_frame_mem to generate the MEM, grab
19402 it now and set the alias set/attributes. The above gen_*_update
19403 calls will generate a PARALLEL with the MEM set being the first
19404 operation. */
19405 par = PATTERN (insn);
19406 gcc_assert (GET_CODE (par) == PARALLEL);
19407 set = XVECEXP (par, 0, 0);
19408 gcc_assert (GET_CODE (set) == SET);
19409 mem = SET_DEST (set);
19410 gcc_assert (MEM_P (mem));
19411 MEM_NOTRAP_P (mem) = 1;
19412 set_mem_alias_set (mem, get_frame_alias_set ());
19414 RTX_FRAME_RELATED_P (insn) = 1;
19415 add_reg_note (insn, REG_FRAME_RELATED_EXPR,
19416 gen_rtx_SET (VOIDmode, stack_reg,
19417 gen_rtx_PLUS (Pmode, stack_reg,
19418 GEN_INT (-size))));
19421 #define PROBE_INTERVAL (1 << STACK_CHECK_PROBE_INTERVAL_EXP)
19423 #if PROBE_INTERVAL > 32768
19424 #error Cannot use indexed addressing mode for stack probing
19425 #endif
19427 /* Emit code to probe a range of stack addresses from FIRST to FIRST+SIZE,
19428 inclusive. These are offsets from the current stack pointer. */
19430 static void
19431 rs6000_emit_probe_stack_range (HOST_WIDE_INT first, HOST_WIDE_INT size)
19433 /* See if we have a constant small number of probes to generate. If so,
19434 that's the easy case. */
19435 if (first + size <= 32768)
19437 HOST_WIDE_INT i;
19439 /* Probe at FIRST + N * PROBE_INTERVAL for values of N from 1 until
19440 it exceeds SIZE. If only one probe is needed, this will not
19441 generate any code. Then probe at FIRST + SIZE. */
19442 for (i = PROBE_INTERVAL; i < size; i += PROBE_INTERVAL)
19443 emit_stack_probe (plus_constant (stack_pointer_rtx, -(first + i)));
19445 emit_stack_probe (plus_constant (stack_pointer_rtx, -(first + size)));
19448 /* Otherwise, do the same as above, but in a loop. Note that we must be
19449 extra careful with variables wrapping around because we might be at
19450 the very top (or the very bottom) of the address space and we have
19451 to be able to handle this case properly; in particular, we use an
19452 equality test for the loop condition. */
19453 else
19455 HOST_WIDE_INT rounded_size;
19456 rtx r12 = gen_rtx_REG (Pmode, 12);
19457 rtx r0 = gen_rtx_REG (Pmode, 0);
19459 /* Sanity check for the addressing mode we're going to use. */
19460 gcc_assert (first <= 32768);
19462 /* Step 1: round SIZE to the previous multiple of the interval. */
19464 rounded_size = size & -PROBE_INTERVAL;
19467 /* Step 2: compute initial and final value of the loop counter. */
19469 /* TEST_ADDR = SP + FIRST. */
19470 emit_insn (gen_rtx_SET (VOIDmode, r12,
19471 plus_constant (stack_pointer_rtx, -first)));
19473 /* LAST_ADDR = SP + FIRST + ROUNDED_SIZE. */
19474 if (rounded_size > 32768)
19476 emit_move_insn (r0, GEN_INT (-rounded_size));
19477 emit_insn (gen_rtx_SET (VOIDmode, r0,
19478 gen_rtx_PLUS (Pmode, r12, r0)));
19480 else
19481 emit_insn (gen_rtx_SET (VOIDmode, r0,
19482 plus_constant (r12, -rounded_size)));
19485 /* Step 3: the loop
19487 while (TEST_ADDR != LAST_ADDR)
19489 TEST_ADDR = TEST_ADDR + PROBE_INTERVAL
19490 probe at TEST_ADDR
19493 probes at FIRST + N * PROBE_INTERVAL for values of N from 1
19494 until it is equal to ROUNDED_SIZE. */
19496 if (TARGET_64BIT)
19497 emit_insn (gen_probe_stack_rangedi (r12, r12, r0));
19498 else
19499 emit_insn (gen_probe_stack_rangesi (r12, r12, r0));
19502 /* Step 4: probe at FIRST + SIZE if we cannot assert at compile-time
19503 that SIZE is equal to ROUNDED_SIZE. */
19505 if (size != rounded_size)
19506 emit_stack_probe (plus_constant (r12, rounded_size - size));
19510 /* Probe a range of stack addresses from REG1 to REG2 inclusive. These are
19511 absolute addresses. */
19513 const char *
19514 output_probe_stack_range (rtx reg1, rtx reg2)
19516 static int labelno = 0;
19517 char loop_lab[32], end_lab[32];
19518 rtx xops[2];
19520 ASM_GENERATE_INTERNAL_LABEL (loop_lab, "LPSRL", labelno);
19521 ASM_GENERATE_INTERNAL_LABEL (end_lab, "LPSRE", labelno++);
19523 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, loop_lab);
19525 /* Jump to END_LAB if TEST_ADDR == LAST_ADDR. */
19526 xops[0] = reg1;
19527 xops[1] = reg2;
19528 if (TARGET_64BIT)
19529 output_asm_insn ("{cmp|cmpd} 0,%0,%1", xops);
19530 else
19531 output_asm_insn ("{cmp|cmpw} 0,%0,%1", xops);
19533 fputs ("\tbeq 0,", asm_out_file);
19534 assemble_name_raw (asm_out_file, end_lab);
19535 fputc ('\n', asm_out_file);
19537 /* TEST_ADDR = TEST_ADDR + PROBE_INTERVAL. */
19538 xops[1] = GEN_INT (-PROBE_INTERVAL);
19539 output_asm_insn ("{cal %0,%1(%0)|addi %0,%0,%1}", xops);
19541 /* Probe at TEST_ADDR and branch. */
19542 output_asm_insn ("{st|stw} 0,0(%0)", xops);
19543 fprintf (asm_out_file, "\tb ");
19544 assemble_name_raw (asm_out_file, loop_lab);
19545 fputc ('\n', asm_out_file);
19547 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, end_lab);
19549 return "";
19552 /* Add to 'insn' a note which is PATTERN (INSN) but with REG replaced
19553 with (plus:P (reg 1) VAL), and with REG2 replaced with RREG if REG2
19554 is not NULL. It would be nice if dwarf2out_frame_debug_expr could
19555 deduce these equivalences by itself so it wasn't necessary to hold
19556 its hand so much. */
19558 static void
19559 rs6000_frame_related (rtx insn, rtx reg, HOST_WIDE_INT val,
19560 rtx reg2, rtx rreg)
19562 rtx real, temp;
19564 /* copy_rtx will not make unique copies of registers, so we need to
19565 ensure we don't have unwanted sharing here. */
19566 if (reg == reg2)
19567 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
19569 if (reg == rreg)
19570 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
19572 real = copy_rtx (PATTERN (insn));
19574 if (reg2 != NULL_RTX)
19575 real = replace_rtx (real, reg2, rreg);
19577 real = replace_rtx (real, reg,
19578 gen_rtx_PLUS (Pmode, gen_rtx_REG (Pmode,
19579 STACK_POINTER_REGNUM),
19580 GEN_INT (val)));
19582 /* We expect that 'real' is either a SET or a PARALLEL containing
19583 SETs (and possibly other stuff). In a PARALLEL, all the SETs
19584 are important so they all have to be marked RTX_FRAME_RELATED_P. */
19586 if (GET_CODE (real) == SET)
19588 rtx set = real;
19590 temp = simplify_rtx (SET_SRC (set));
19591 if (temp)
19592 SET_SRC (set) = temp;
19593 temp = simplify_rtx (SET_DEST (set));
19594 if (temp)
19595 SET_DEST (set) = temp;
19596 if (GET_CODE (SET_DEST (set)) == MEM)
19598 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
19599 if (temp)
19600 XEXP (SET_DEST (set), 0) = temp;
19603 else
19605 int i;
19607 gcc_assert (GET_CODE (real) == PARALLEL);
19608 for (i = 0; i < XVECLEN (real, 0); i++)
19609 if (GET_CODE (XVECEXP (real, 0, i)) == SET)
19611 rtx set = XVECEXP (real, 0, i);
19613 temp = simplify_rtx (SET_SRC (set));
19614 if (temp)
19615 SET_SRC (set) = temp;
19616 temp = simplify_rtx (SET_DEST (set));
19617 if (temp)
19618 SET_DEST (set) = temp;
19619 if (GET_CODE (SET_DEST (set)) == MEM)
19621 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
19622 if (temp)
19623 XEXP (SET_DEST (set), 0) = temp;
19625 RTX_FRAME_RELATED_P (set) = 1;
19629 RTX_FRAME_RELATED_P (insn) = 1;
19630 add_reg_note (insn, REG_FRAME_RELATED_EXPR, real);
19633 /* Returns an insn that has a vrsave set operation with the
19634 appropriate CLOBBERs. */
19636 static rtx
19637 generate_set_vrsave (rtx reg, rs6000_stack_t *info, int epiloguep)
19639 int nclobs, i;
19640 rtx insn, clobs[TOTAL_ALTIVEC_REGS + 1];
19641 rtx vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
19643 clobs[0]
19644 = gen_rtx_SET (VOIDmode,
19645 vrsave,
19646 gen_rtx_UNSPEC_VOLATILE (SImode,
19647 gen_rtvec (2, reg, vrsave),
19648 UNSPECV_SET_VRSAVE));
19650 nclobs = 1;
19652 /* We need to clobber the registers in the mask so the scheduler
19653 does not move sets to VRSAVE before sets of AltiVec registers.
19655 However, if the function receives nonlocal gotos, reload will set
19656 all call saved registers live. We will end up with:
19658 (set (reg 999) (mem))
19659 (parallel [ (set (reg vrsave) (unspec blah))
19660 (clobber (reg 999))])
19662 The clobber will cause the store into reg 999 to be dead, and
19663 flow will attempt to delete an epilogue insn. In this case, we
19664 need an unspec use/set of the register. */
19666 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
19667 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
19669 if (!epiloguep || call_used_regs [i])
19670 clobs[nclobs++] = gen_rtx_CLOBBER (VOIDmode,
19671 gen_rtx_REG (V4SImode, i));
19672 else
19674 rtx reg = gen_rtx_REG (V4SImode, i);
19676 clobs[nclobs++]
19677 = gen_rtx_SET (VOIDmode,
19678 reg,
19679 gen_rtx_UNSPEC (V4SImode,
19680 gen_rtvec (1, reg), 27));
19684 insn = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (nclobs));
19686 for (i = 0; i < nclobs; ++i)
19687 XVECEXP (insn, 0, i) = clobs[i];
19689 return insn;
19692 /* Save a register into the frame, and emit RTX_FRAME_RELATED_P notes.
19693 Save REGNO into [FRAME_REG + OFFSET] in mode MODE. */
19695 static void
19696 emit_frame_save (rtx frame_reg, rtx frame_ptr, enum machine_mode mode,
19697 unsigned int regno, int offset, HOST_WIDE_INT total_size)
19699 rtx reg, offset_rtx, insn, mem, addr, int_rtx;
19700 rtx replacea, replaceb;
19702 int_rtx = GEN_INT (offset);
19704 /* Some cases that need register indexed addressing. */
19705 if ((TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
19706 || (TARGET_VSX && VSX_VECTOR_MODE (mode))
19707 || (TARGET_E500_DOUBLE && mode == DFmode)
19708 || (TARGET_SPE_ABI
19709 && SPE_VECTOR_MODE (mode)
19710 && !SPE_CONST_OFFSET_OK (offset)))
19712 /* Whomever calls us must make sure r11 is available in the
19713 flow path of instructions in the prologue. */
19714 offset_rtx = gen_rtx_REG (Pmode, 11);
19715 emit_move_insn (offset_rtx, int_rtx);
19717 replacea = offset_rtx;
19718 replaceb = int_rtx;
19720 else
19722 offset_rtx = int_rtx;
19723 replacea = NULL_RTX;
19724 replaceb = NULL_RTX;
19727 reg = gen_rtx_REG (mode, regno);
19728 addr = gen_rtx_PLUS (Pmode, frame_reg, offset_rtx);
19729 mem = gen_frame_mem (mode, addr);
19731 insn = emit_move_insn (mem, reg);
19733 rs6000_frame_related (insn, frame_ptr, total_size, replacea, replaceb);
19736 /* Emit an offset memory reference suitable for a frame store, while
19737 converting to a valid addressing mode. */
19739 static rtx
19740 gen_frame_mem_offset (enum machine_mode mode, rtx reg, int offset)
19742 rtx int_rtx, offset_rtx;
19744 int_rtx = GEN_INT (offset);
19746 if ((TARGET_SPE_ABI && SPE_VECTOR_MODE (mode))
19747 || (TARGET_E500_DOUBLE && mode == DFmode))
19749 offset_rtx = gen_rtx_REG (Pmode, FIXED_SCRATCH);
19750 emit_move_insn (offset_rtx, int_rtx);
19752 else
19753 offset_rtx = int_rtx;
19755 return gen_frame_mem (mode, gen_rtx_PLUS (Pmode, reg, offset_rtx));
19758 /* Look for user-defined global regs. We should not save and restore these,
19759 and cannot use stmw/lmw if there are any in its range. */
19761 static bool
19762 no_global_regs_above (int first, bool gpr)
19764 int i;
19765 int last = gpr ? 32 : 64;
19766 for (i = first; i < last; i++)
19767 if (global_regs[i])
19768 return false;
19769 return true;
19772 #ifndef TARGET_FIX_AND_CONTINUE
19773 #define TARGET_FIX_AND_CONTINUE 0
19774 #endif
19776 /* It's really GPR 13 and FPR 14, but we need the smaller of the two. */
19777 #define FIRST_SAVRES_REGISTER FIRST_SAVED_GP_REGNO
19778 #define LAST_SAVRES_REGISTER 31
19779 #define N_SAVRES_REGISTERS (LAST_SAVRES_REGISTER - FIRST_SAVRES_REGISTER + 1)
19781 static GTY(()) rtx savres_routine_syms[N_SAVRES_REGISTERS][8];
19783 /* Temporary holding space for an out-of-line register save/restore
19784 routine name. */
19785 static char savres_routine_name[30];
19787 /* Return the name for an out-of-line register save/restore routine.
19788 We are saving/restoring GPRs if GPR is true. */
19790 static char *
19791 rs6000_savres_routine_name (rs6000_stack_t *info, int regno,
19792 bool savep, bool gpr, bool lr)
19794 const char *prefix = "";
19795 const char *suffix = "";
19797 /* Different targets are supposed to define
19798 {SAVE,RESTORE}_FP_{PREFIX,SUFFIX} with the idea that the needed
19799 routine name could be defined with:
19801 sprintf (name, "%s%d%s", SAVE_FP_PREFIX, regno, SAVE_FP_SUFFIX)
19803 This is a nice idea in practice, but in reality, things are
19804 complicated in several ways:
19806 - ELF targets have save/restore routines for GPRs.
19808 - SPE targets use different prefixes for 32/64-bit registers, and
19809 neither of them fit neatly in the FOO_{PREFIX,SUFFIX} regimen.
19811 - PPC64 ELF targets have routines for save/restore of GPRs that
19812 differ in what they do with the link register, so having a set
19813 prefix doesn't work. (We only use one of the save routines at
19814 the moment, though.)
19816 - PPC32 elf targets have "exit" versions of the restore routines
19817 that restore the link register and can save some extra space.
19818 These require an extra suffix. (There are also "tail" versions
19819 of the restore routines and "GOT" versions of the save routines,
19820 but we don't generate those at present. Same problems apply,
19821 though.)
19823 We deal with all this by synthesizing our own prefix/suffix and
19824 using that for the simple sprintf call shown above. */
19825 if (TARGET_SPE)
19827 /* No floating point saves on the SPE. */
19828 gcc_assert (gpr);
19830 if (savep)
19831 prefix = info->spe_64bit_regs_used ? "_save64gpr_" : "_save32gpr_";
19832 else
19833 prefix = info->spe_64bit_regs_used ? "_rest64gpr_" : "_rest32gpr_";
19835 if (lr)
19836 suffix = "_x";
19838 else if (DEFAULT_ABI == ABI_V4)
19840 if (TARGET_64BIT)
19841 goto aix_names;
19843 if (gpr)
19844 prefix = savep ? "_savegpr_" : "_restgpr_";
19845 else
19846 prefix = savep ? "_savefpr_" : "_restfpr_";
19848 if (lr)
19849 suffix = "_x";
19851 else if (DEFAULT_ABI == ABI_AIX)
19853 #ifndef POWERPC_LINUX
19854 /* No out-of-line save/restore routines for GPRs on AIX. */
19855 gcc_assert (!TARGET_AIX || !gpr);
19856 #endif
19858 aix_names:
19859 if (gpr)
19860 prefix = (savep
19861 ? (lr ? "_savegpr0_" : "_savegpr1_")
19862 : (lr ? "_restgpr0_" : "_restgpr1_"));
19863 #ifdef POWERPC_LINUX
19864 else if (lr)
19865 prefix = (savep ? "_savefpr_" : "_restfpr_");
19866 #endif
19867 else
19869 prefix = savep ? SAVE_FP_PREFIX : RESTORE_FP_PREFIX;
19870 suffix = savep ? SAVE_FP_SUFFIX : RESTORE_FP_SUFFIX;
19873 else if (DEFAULT_ABI == ABI_DARWIN)
19874 sorry ("out-of-line save/restore routines not supported on Darwin");
19876 sprintf (savres_routine_name, "%s%d%s", prefix, regno, suffix);
19878 return savres_routine_name;
19881 /* Return an RTL SYMBOL_REF for an out-of-line register save/restore routine.
19882 We are saving/restoring GPRs if GPR is true. */
19884 static rtx
19885 rs6000_savres_routine_sym (rs6000_stack_t *info, bool savep,
19886 bool gpr, bool lr)
19888 int regno = gpr ? info->first_gp_reg_save : (info->first_fp_reg_save - 32);
19889 rtx sym;
19890 int select = ((savep ? 1 : 0) << 2
19891 | ((TARGET_SPE_ABI
19892 /* On the SPE, we never have any FPRs, but we do have
19893 32/64-bit versions of the routines. */
19894 ? (info->spe_64bit_regs_used ? 1 : 0)
19895 : (gpr ? 1 : 0)) << 1)
19896 | (lr ? 1: 0));
19898 /* Don't generate bogus routine names. */
19899 gcc_assert (FIRST_SAVRES_REGISTER <= regno
19900 && regno <= LAST_SAVRES_REGISTER);
19902 sym = savres_routine_syms[regno-FIRST_SAVRES_REGISTER][select];
19904 if (sym == NULL)
19906 char *name;
19908 name = rs6000_savres_routine_name (info, regno, savep, gpr, lr);
19910 sym = savres_routine_syms[regno-FIRST_SAVRES_REGISTER][select]
19911 = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (name));
19912 SYMBOL_REF_FLAGS (sym) |= SYMBOL_FLAG_FUNCTION;
19915 return sym;
19918 /* Emit a sequence of insns, including a stack tie if needed, for
19919 resetting the stack pointer. If SAVRES is true, then don't reset the
19920 stack pointer, but move the base of the frame into r11 for use by
19921 out-of-line register restore routines. */
19923 static rtx
19924 rs6000_emit_stack_reset (rs6000_stack_t *info,
19925 rtx sp_reg_rtx, rtx frame_reg_rtx,
19926 int sp_offset, bool savres)
19928 /* This blockage is needed so that sched doesn't decide to move
19929 the sp change before the register restores. */
19930 if (frame_reg_rtx != sp_reg_rtx
19931 || (TARGET_SPE_ABI
19932 && info->spe_64bit_regs_used != 0
19933 && info->first_gp_reg_save != 32))
19934 rs6000_emit_stack_tie ();
19936 if (frame_reg_rtx != sp_reg_rtx)
19938 if (sp_offset != 0)
19940 rtx dest_reg = savres ? gen_rtx_REG (Pmode, 11) : sp_reg_rtx;
19941 return emit_insn (gen_add3_insn (dest_reg, frame_reg_rtx,
19942 GEN_INT (sp_offset)));
19944 else if (!savres)
19945 return emit_move_insn (sp_reg_rtx, frame_reg_rtx);
19947 else if (sp_offset != 0)
19949 /* If we are restoring registers out-of-line, we will be using the
19950 "exit" variants of the restore routines, which will reset the
19951 stack for us. But we do need to point r11 into the right place
19952 for those routines. */
19953 rtx dest_reg = (savres
19954 ? gen_rtx_REG (Pmode, 11)
19955 : sp_reg_rtx);
19957 rtx insn = emit_insn (gen_add3_insn (dest_reg, sp_reg_rtx,
19958 GEN_INT (sp_offset)));
19959 if (!savres)
19960 return insn;
19962 return NULL_RTX;
19965 /* Construct a parallel rtx describing the effect of a call to an
19966 out-of-line register save/restore routine. */
19968 static rtx
19969 rs6000_make_savres_rtx (rs6000_stack_t *info,
19970 rtx frame_reg_rtx, int save_area_offset,
19971 enum machine_mode reg_mode,
19972 bool savep, bool gpr, bool lr)
19974 int i;
19975 int offset, start_reg, end_reg, n_regs;
19976 int reg_size = GET_MODE_SIZE (reg_mode);
19977 rtx sym;
19978 rtvec p;
19980 offset = 0;
19981 start_reg = (gpr
19982 ? info->first_gp_reg_save
19983 : info->first_fp_reg_save);
19984 end_reg = gpr ? 32 : 64;
19985 n_regs = end_reg - start_reg;
19986 p = rtvec_alloc ((lr ? 4 : 3) + n_regs);
19988 if (!savep && lr)
19989 RTVEC_ELT (p, offset++) = gen_rtx_RETURN (VOIDmode);
19991 RTVEC_ELT (p, offset++)
19992 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 65));
19994 sym = rs6000_savres_routine_sym (info, savep, gpr, lr);
19995 RTVEC_ELT (p, offset++) = gen_rtx_USE (VOIDmode, sym);
19996 RTVEC_ELT (p, offset++)
19997 = gen_rtx_USE (VOIDmode,
19998 gen_rtx_REG (Pmode, DEFAULT_ABI != ABI_AIX ? 11
19999 : gpr && !lr ? 12
20000 : 1));
20002 for (i = 0; i < end_reg - start_reg; i++)
20004 rtx addr, reg, mem;
20005 reg = gen_rtx_REG (reg_mode, start_reg + i);
20006 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20007 GEN_INT (save_area_offset + reg_size*i));
20008 mem = gen_frame_mem (reg_mode, addr);
20010 RTVEC_ELT (p, i + offset) = gen_rtx_SET (VOIDmode,
20011 savep ? mem : reg,
20012 savep ? reg : mem);
20015 if (savep && lr)
20017 rtx addr, reg, mem;
20018 reg = gen_rtx_REG (Pmode, 0);
20019 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20020 GEN_INT (info->lr_save_offset));
20021 mem = gen_frame_mem (Pmode, addr);
20022 RTVEC_ELT (p, i + offset) = gen_rtx_SET (VOIDmode, mem, reg);
20025 return gen_rtx_PARALLEL (VOIDmode, p);
20028 /* Determine whether the gp REG is really used. */
20030 static bool
20031 rs6000_reg_live_or_pic_offset_p (int reg)
20033 /* If the function calls eh_return, claim used all the registers that would
20034 be checked for liveness otherwise. This is required for the PIC offset
20035 register with -mminimal-toc on AIX, as it is advertised as "fixed" for
20036 register allocation purposes in this case. */
20038 return (((crtl->calls_eh_return || df_regs_ever_live_p (reg))
20039 && (!call_used_regs[reg]
20040 || (reg == RS6000_PIC_OFFSET_TABLE_REGNUM
20041 && !TARGET_SINGLE_PIC_BASE
20042 && TARGET_TOC && TARGET_MINIMAL_TOC)))
20043 || (reg == RS6000_PIC_OFFSET_TABLE_REGNUM
20044 && !TARGET_SINGLE_PIC_BASE
20045 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
20046 || (DEFAULT_ABI == ABI_DARWIN && flag_pic))));
20049 /* Emit function prologue as insns. */
20051 void
20052 rs6000_emit_prologue (void)
20054 rs6000_stack_t *info = rs6000_stack_info ();
20055 enum machine_mode reg_mode = Pmode;
20056 int reg_size = TARGET_32BIT ? 4 : 8;
20057 rtx sp_reg_rtx = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
20058 rtx frame_ptr_rtx = gen_rtx_REG (Pmode, 12);
20059 rtx frame_reg_rtx = sp_reg_rtx;
20060 rtx cr_save_rtx = NULL_RTX;
20061 rtx insn;
20062 int strategy;
20063 int saving_FPRs_inline;
20064 int saving_GPRs_inline;
20065 int using_store_multiple;
20066 int using_static_chain_p = (cfun->static_chain_decl != NULL_TREE
20067 && df_regs_ever_live_p (STATIC_CHAIN_REGNUM)
20068 && call_used_regs[STATIC_CHAIN_REGNUM]);
20069 HOST_WIDE_INT sp_offset = 0;
20071 if (flag_stack_usage)
20072 current_function_static_stack_size = info->total_size;
20074 if (flag_stack_check == STATIC_BUILTIN_STACK_CHECK && info->total_size)
20075 rs6000_emit_probe_stack_range (STACK_CHECK_PROTECT, info->total_size);
20077 if (TARGET_FIX_AND_CONTINUE)
20079 /* gdb on darwin arranges to forward a function from the old
20080 address by modifying the first 5 instructions of the function
20081 to branch to the overriding function. This is necessary to
20082 permit function pointers that point to the old function to
20083 actually forward to the new function. */
20084 emit_insn (gen_nop ());
20085 emit_insn (gen_nop ());
20086 emit_insn (gen_nop ());
20087 emit_insn (gen_nop ());
20088 emit_insn (gen_nop ());
20091 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
20093 reg_mode = V2SImode;
20094 reg_size = 8;
20097 strategy = info->savres_strategy;
20098 using_store_multiple = strategy & SAVRES_MULTIPLE;
20099 saving_FPRs_inline = strategy & SAVE_INLINE_FPRS;
20100 saving_GPRs_inline = strategy & SAVE_INLINE_GPRS;
20102 /* For V.4, update stack before we do any saving and set back pointer. */
20103 if (! WORLD_SAVE_P (info)
20104 && info->push_p
20105 && (DEFAULT_ABI == ABI_V4
20106 || crtl->calls_eh_return))
20108 bool need_r11 = (TARGET_SPE
20109 ? (!saving_GPRs_inline
20110 && info->spe_64bit_regs_used == 0)
20111 : (!saving_FPRs_inline || !saving_GPRs_inline));
20112 rtx copy_reg = need_r11 ? gen_rtx_REG (Pmode, 11) : NULL;
20114 if (info->total_size < 32767)
20115 sp_offset = info->total_size;
20116 else if (need_r11)
20117 frame_reg_rtx = copy_reg;
20118 else if (info->cr_save_p
20119 || info->lr_save_p
20120 || info->first_fp_reg_save < 64
20121 || info->first_gp_reg_save < 32
20122 || info->altivec_size != 0
20123 || info->vrsave_mask != 0
20124 || crtl->calls_eh_return)
20126 copy_reg = frame_ptr_rtx;
20127 frame_reg_rtx = copy_reg;
20129 else
20131 /* The prologue won't be saving any regs so there is no need
20132 to set up a frame register to access any frame save area.
20133 We also won't be using sp_offset anywhere below, but set
20134 the correct value anyway to protect against future
20135 changes to this function. */
20136 sp_offset = info->total_size;
20138 rs6000_emit_allocate_stack (info->total_size, copy_reg);
20139 if (frame_reg_rtx != sp_reg_rtx)
20140 rs6000_emit_stack_tie ();
20143 /* Handle world saves specially here. */
20144 if (WORLD_SAVE_P (info))
20146 int i, j, sz;
20147 rtx treg;
20148 rtvec p;
20149 rtx reg0;
20151 /* save_world expects lr in r0. */
20152 reg0 = gen_rtx_REG (Pmode, 0);
20153 if (info->lr_save_p)
20155 insn = emit_move_insn (reg0,
20156 gen_rtx_REG (Pmode, LR_REGNO));
20157 RTX_FRAME_RELATED_P (insn) = 1;
20160 /* The SAVE_WORLD and RESTORE_WORLD routines make a number of
20161 assumptions about the offsets of various bits of the stack
20162 frame. */
20163 gcc_assert (info->gp_save_offset == -220
20164 && info->fp_save_offset == -144
20165 && info->lr_save_offset == 8
20166 && info->cr_save_offset == 4
20167 && info->push_p
20168 && info->lr_save_p
20169 && (!crtl->calls_eh_return
20170 || info->ehrd_offset == -432)
20171 && info->vrsave_save_offset == -224
20172 && info->altivec_save_offset == -416);
20174 treg = gen_rtx_REG (SImode, 11);
20175 emit_move_insn (treg, GEN_INT (-info->total_size));
20177 /* SAVE_WORLD takes the caller's LR in R0 and the frame size
20178 in R11. It also clobbers R12, so beware! */
20180 /* Preserve CR2 for save_world prologues */
20181 sz = 5;
20182 sz += 32 - info->first_gp_reg_save;
20183 sz += 64 - info->first_fp_reg_save;
20184 sz += LAST_ALTIVEC_REGNO - info->first_altivec_reg_save + 1;
20185 p = rtvec_alloc (sz);
20186 j = 0;
20187 RTVEC_ELT (p, j++) = gen_rtx_CLOBBER (VOIDmode,
20188 gen_rtx_REG (SImode,
20189 LR_REGNO));
20190 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
20191 gen_rtx_SYMBOL_REF (Pmode,
20192 "*save_world"));
20193 /* We do floats first so that the instruction pattern matches
20194 properly. */
20195 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
20197 rtx reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20198 ? DFmode : SFmode),
20199 info->first_fp_reg_save + i);
20200 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20201 GEN_INT (info->fp_save_offset
20202 + sp_offset + 8 * i));
20203 rtx mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20204 ? DFmode : SFmode), addr);
20206 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
20208 for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++)
20210 rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i);
20211 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20212 GEN_INT (info->altivec_save_offset
20213 + sp_offset + 16 * i));
20214 rtx mem = gen_frame_mem (V4SImode, addr);
20216 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
20218 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20220 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20221 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20222 GEN_INT (info->gp_save_offset
20223 + sp_offset + reg_size * i));
20224 rtx mem = gen_frame_mem (reg_mode, addr);
20226 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
20230 /* CR register traditionally saved as CR2. */
20231 rtx reg = gen_rtx_REG (reg_mode, CR2_REGNO);
20232 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20233 GEN_INT (info->cr_save_offset
20234 + sp_offset));
20235 rtx mem = gen_frame_mem (reg_mode, addr);
20237 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
20239 /* Explain about use of R0. */
20240 if (info->lr_save_p)
20242 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20243 GEN_INT (info->lr_save_offset
20244 + sp_offset));
20245 rtx mem = gen_frame_mem (reg_mode, addr);
20247 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg0);
20249 /* Explain what happens to the stack pointer. */
20251 rtx newval = gen_rtx_PLUS (Pmode, sp_reg_rtx, treg);
20252 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, sp_reg_rtx, newval);
20255 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
20256 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20257 treg, GEN_INT (-info->total_size));
20258 sp_offset = info->total_size;
20261 /* If we use the link register, get it into r0. */
20262 if (!WORLD_SAVE_P (info) && info->lr_save_p)
20264 rtx addr, reg, mem;
20266 insn = emit_move_insn (gen_rtx_REG (Pmode, 0),
20267 gen_rtx_REG (Pmode, LR_REGNO));
20268 RTX_FRAME_RELATED_P (insn) = 1;
20270 if (!(strategy & (SAVE_NOINLINE_GPRS_SAVES_LR
20271 | SAVE_NOINLINE_FPRS_SAVES_LR)))
20273 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20274 GEN_INT (info->lr_save_offset + sp_offset));
20275 reg = gen_rtx_REG (Pmode, 0);
20276 mem = gen_rtx_MEM (Pmode, addr);
20277 /* This should not be of rs6000_sr_alias_set, because of
20278 __builtin_return_address. */
20280 insn = emit_move_insn (mem, reg);
20281 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20282 NULL_RTX, NULL_RTX);
20286 /* If we need to save CR, put it into r12 or r11. */
20287 if (!WORLD_SAVE_P (info) && info->cr_save_p && frame_reg_rtx != frame_ptr_rtx)
20289 rtx set;
20291 cr_save_rtx
20292 = gen_rtx_REG (SImode, DEFAULT_ABI == ABI_AIX && !saving_GPRs_inline
20293 ? 11 : 12);
20294 insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
20295 RTX_FRAME_RELATED_P (insn) = 1;
20296 /* Now, there's no way that dwarf2out_frame_debug_expr is going
20297 to understand '(unspec:SI [(reg:CC 68) ...] UNSPEC_MOVESI_FROM_CR)'.
20298 But that's OK. All we have to do is specify that _one_ condition
20299 code register is saved in this stack slot. The thrower's epilogue
20300 will then restore all the call-saved registers.
20301 We use CR2_REGNO (70) to be compatible with gcc-2.95 on Linux. */
20302 set = gen_rtx_SET (VOIDmode, cr_save_rtx,
20303 gen_rtx_REG (SImode, CR2_REGNO));
20304 add_reg_note (insn, REG_FRAME_RELATED_EXPR, set);
20307 /* Do any required saving of fpr's. If only one or two to save, do
20308 it ourselves. Otherwise, call function. */
20309 if (!WORLD_SAVE_P (info) && saving_FPRs_inline)
20311 int i;
20312 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
20313 if ((df_regs_ever_live_p (info->first_fp_reg_save+i)
20314 && ! call_used_regs[info->first_fp_reg_save+i]))
20315 emit_frame_save (frame_reg_rtx, frame_ptr_rtx,
20316 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20317 ? DFmode : SFmode,
20318 info->first_fp_reg_save + i,
20319 info->fp_save_offset + sp_offset + 8 * i,
20320 info->total_size);
20322 else if (!WORLD_SAVE_P (info) && info->first_fp_reg_save != 64)
20324 rtx par;
20326 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
20327 info->fp_save_offset + sp_offset,
20328 DFmode,
20329 /*savep=*/true, /*gpr=*/false,
20330 /*lr=*/(strategy
20331 & SAVE_NOINLINE_FPRS_SAVES_LR)
20332 != 0);
20333 insn = emit_insn (par);
20334 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20335 NULL_RTX, NULL_RTX);
20338 /* Save GPRs. This is done as a PARALLEL if we are using
20339 the store-multiple instructions. */
20340 if (!WORLD_SAVE_P (info)
20341 && TARGET_SPE_ABI
20342 && info->spe_64bit_regs_used != 0
20343 && info->first_gp_reg_save != 32)
20345 int i;
20346 rtx spe_save_area_ptr;
20348 /* Determine whether we can address all of the registers that need
20349 to be saved with an offset from the stack pointer that fits in
20350 the small const field for SPE memory instructions. */
20351 int spe_regs_addressable_via_sp
20352 = (SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset
20353 + (32 - info->first_gp_reg_save - 1) * reg_size)
20354 && saving_GPRs_inline);
20355 int spe_offset;
20357 if (spe_regs_addressable_via_sp)
20359 spe_save_area_ptr = frame_reg_rtx;
20360 spe_offset = info->spe_gp_save_offset + sp_offset;
20362 else
20364 /* Make r11 point to the start of the SPE save area. We need
20365 to be careful here if r11 is holding the static chain. If
20366 it is, then temporarily save it in r0. We would use r0 as
20367 our base register here, but using r0 as a base register in
20368 loads and stores means something different from what we
20369 would like. */
20370 int ool_adjust = (saving_GPRs_inline
20372 : (info->first_gp_reg_save
20373 - (FIRST_SAVRES_REGISTER+1))*8);
20374 HOST_WIDE_INT offset = (info->spe_gp_save_offset
20375 + sp_offset - ool_adjust);
20377 if (using_static_chain_p)
20379 rtx r0 = gen_rtx_REG (Pmode, 0);
20380 gcc_assert (info->first_gp_reg_save > 11);
20382 emit_move_insn (r0, gen_rtx_REG (Pmode, 11));
20385 spe_save_area_ptr = gen_rtx_REG (Pmode, 11);
20386 insn = emit_insn (gen_addsi3 (spe_save_area_ptr,
20387 frame_reg_rtx,
20388 GEN_INT (offset)));
20389 /* We need to make sure the move to r11 gets noted for
20390 properly outputting unwind information. */
20391 if (!saving_GPRs_inline)
20392 rs6000_frame_related (insn, frame_reg_rtx, offset,
20393 NULL_RTX, NULL_RTX);
20394 spe_offset = 0;
20397 if (saving_GPRs_inline)
20399 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20400 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
20402 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20403 rtx offset, addr, mem;
20405 /* We're doing all this to ensure that the offset fits into
20406 the immediate offset of 'evstdd'. */
20407 gcc_assert (SPE_CONST_OFFSET_OK (reg_size * i + spe_offset));
20409 offset = GEN_INT (reg_size * i + spe_offset);
20410 addr = gen_rtx_PLUS (Pmode, spe_save_area_ptr, offset);
20411 mem = gen_rtx_MEM (V2SImode, addr);
20413 insn = emit_move_insn (mem, reg);
20415 rs6000_frame_related (insn, spe_save_area_ptr,
20416 info->spe_gp_save_offset
20417 + sp_offset + reg_size * i,
20418 offset, const0_rtx);
20421 else
20423 rtx par;
20425 par = rs6000_make_savres_rtx (info, gen_rtx_REG (Pmode, 11),
20426 0, reg_mode,
20427 /*savep=*/true, /*gpr=*/true,
20428 /*lr=*/false);
20429 insn = emit_insn (par);
20430 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20431 NULL_RTX, NULL_RTX);
20435 /* Move the static chain pointer back. */
20436 if (using_static_chain_p && !spe_regs_addressable_via_sp)
20437 emit_move_insn (gen_rtx_REG (Pmode, 11), gen_rtx_REG (Pmode, 0));
20439 else if (!WORLD_SAVE_P (info) && !saving_GPRs_inline)
20441 rtx par;
20443 /* Need to adjust r11 (r12) if we saved any FPRs. */
20444 if (info->first_fp_reg_save != 64)
20446 rtx dest_reg = gen_rtx_REG (reg_mode, DEFAULT_ABI == ABI_AIX
20447 ? 12 : 11);
20448 rtx offset = GEN_INT (sp_offset
20449 + (-8 * (64-info->first_fp_reg_save)));
20450 emit_insn (gen_add3_insn (dest_reg, frame_reg_rtx, offset));
20453 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
20454 info->gp_save_offset + sp_offset,
20455 reg_mode,
20456 /*savep=*/true, /*gpr=*/true,
20457 /*lr=*/(strategy
20458 & SAVE_NOINLINE_GPRS_SAVES_LR)
20459 != 0);
20460 insn = emit_insn (par);
20461 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20462 NULL_RTX, NULL_RTX);
20464 else if (!WORLD_SAVE_P (info) && using_store_multiple)
20466 rtvec p;
20467 int i;
20468 p = rtvec_alloc (32 - info->first_gp_reg_save);
20469 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20471 rtx addr, reg, mem;
20472 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20473 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20474 GEN_INT (info->gp_save_offset
20475 + sp_offset
20476 + reg_size * i));
20477 mem = gen_frame_mem (reg_mode, addr);
20479 RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, mem, reg);
20481 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
20482 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20483 NULL_RTX, NULL_RTX);
20485 else if (!WORLD_SAVE_P (info))
20487 int i;
20488 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20489 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
20491 rtx addr, reg, mem;
20492 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20494 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20495 GEN_INT (info->gp_save_offset
20496 + sp_offset
20497 + reg_size * i));
20498 mem = gen_frame_mem (reg_mode, addr);
20500 insn = emit_move_insn (mem, reg);
20501 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20502 NULL_RTX, NULL_RTX);
20506 /* ??? There's no need to emit actual instructions here, but it's the
20507 easiest way to get the frame unwind information emitted. */
20508 if (crtl->calls_eh_return)
20510 unsigned int i, regno;
20512 for (i = 0; ; ++i)
20514 regno = EH_RETURN_DATA_REGNO (i);
20515 if (regno == INVALID_REGNUM)
20516 break;
20518 emit_frame_save (frame_reg_rtx, frame_ptr_rtx, reg_mode, regno,
20519 info->ehrd_offset + sp_offset
20520 + reg_size * (int) i,
20521 info->total_size);
20525 /* In AIX ABI we need to make sure r2 is really saved. */
20526 if (TARGET_AIX && crtl->calls_eh_return)
20528 rtx tmp_reg, tmp_reg_si, hi, lo, compare_result, toc_save_done, jump;
20529 long toc_restore_insn;
20531 gcc_assert (frame_reg_rtx == frame_ptr_rtx
20532 || frame_reg_rtx == sp_reg_rtx);
20533 tmp_reg = gen_rtx_REG (Pmode, 11);
20534 tmp_reg_si = gen_rtx_REG (SImode, 11);
20535 if (using_static_chain_p)
20536 emit_move_insn (gen_rtx_REG (Pmode, 0), tmp_reg);
20537 gcc_assert (saving_GPRs_inline && saving_FPRs_inline);
20538 emit_move_insn (tmp_reg, gen_rtx_REG (Pmode, LR_REGNO));
20539 /* Peek at instruction to which this function returns. If it's
20540 restoring r2, then we know we've already saved r2. We can't
20541 unconditionally save r2 because the value we have will already
20542 be updated if we arrived at this function via a plt call or
20543 toc adjusting stub. */
20544 emit_move_insn (tmp_reg_si, gen_rtx_MEM (SImode, tmp_reg));
20545 toc_restore_insn = TARGET_32BIT ? 0x80410014 : 0xE8410028;
20546 hi = gen_int_mode (toc_restore_insn & ~0xffff, SImode);
20547 emit_insn (gen_xorsi3 (tmp_reg_si, tmp_reg_si, hi));
20548 compare_result = gen_rtx_REG (CCUNSmode, CR0_REGNO);
20549 validate_condition_mode (EQ, CCUNSmode);
20550 lo = gen_int_mode (toc_restore_insn & 0xffff, SImode);
20551 emit_insn (gen_rtx_SET (VOIDmode, compare_result,
20552 gen_rtx_COMPARE (CCUNSmode, tmp_reg_si, lo)));
20553 toc_save_done = gen_label_rtx ();
20554 jump = gen_rtx_IF_THEN_ELSE (VOIDmode,
20555 gen_rtx_EQ (VOIDmode, compare_result,
20556 const0_rtx),
20557 gen_rtx_LABEL_REF (VOIDmode, toc_save_done),
20558 pc_rtx);
20559 jump = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, jump));
20560 JUMP_LABEL (jump) = toc_save_done;
20561 LABEL_NUSES (toc_save_done) += 1;
20563 emit_frame_save (frame_reg_rtx, frame_ptr_rtx, reg_mode, 2,
20564 sp_offset + 5 * reg_size, info->total_size);
20565 emit_label (toc_save_done);
20566 if (using_static_chain_p)
20567 emit_move_insn (tmp_reg, gen_rtx_REG (Pmode, 0));
20570 /* Save CR if we use any that must be preserved. */
20571 if (!WORLD_SAVE_P (info) && info->cr_save_p)
20573 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20574 GEN_INT (info->cr_save_offset + sp_offset));
20575 rtx mem = gen_frame_mem (SImode, addr);
20576 /* See the large comment above about why CR2_REGNO is used. */
20577 rtx magic_eh_cr_reg = gen_rtx_REG (SImode, CR2_REGNO);
20579 /* If r12 was used to hold the original sp, copy cr into r0 now
20580 that it's free. */
20581 if (REGNO (frame_reg_rtx) == 12)
20583 rtx set;
20585 cr_save_rtx = gen_rtx_REG (SImode, 0);
20586 insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
20587 RTX_FRAME_RELATED_P (insn) = 1;
20588 set = gen_rtx_SET (VOIDmode, cr_save_rtx, magic_eh_cr_reg);
20589 add_reg_note (insn, REG_FRAME_RELATED_EXPR, set);
20591 insn = emit_move_insn (mem, cr_save_rtx);
20593 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20594 NULL_RTX, NULL_RTX);
20597 /* Update stack and set back pointer unless this is V.4,
20598 for which it was done previously. */
20599 if (!WORLD_SAVE_P (info) && info->push_p
20600 && !(DEFAULT_ABI == ABI_V4 || crtl->calls_eh_return))
20602 rtx copy_reg = NULL;
20604 if (info->total_size < 32767)
20605 sp_offset = info->total_size;
20606 else if (info->altivec_size != 0
20607 || info->vrsave_mask != 0)
20609 copy_reg = frame_ptr_rtx;
20610 frame_reg_rtx = copy_reg;
20612 else
20613 sp_offset = info->total_size;
20614 rs6000_emit_allocate_stack (info->total_size, copy_reg);
20615 if (frame_reg_rtx != sp_reg_rtx)
20616 rs6000_emit_stack_tie ();
20619 /* Set frame pointer, if needed. */
20620 if (frame_pointer_needed)
20622 insn = emit_move_insn (gen_rtx_REG (Pmode, HARD_FRAME_POINTER_REGNUM),
20623 sp_reg_rtx);
20624 RTX_FRAME_RELATED_P (insn) = 1;
20627 /* Save AltiVec registers if needed. Save here because the red zone does
20628 not include AltiVec registers. */
20629 if (!WORLD_SAVE_P (info) && TARGET_ALTIVEC_ABI && info->altivec_size != 0)
20631 int i;
20633 /* There should be a non inline version of this, for when we
20634 are saving lots of vector registers. */
20635 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
20636 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
20638 rtx areg, savereg, mem;
20639 int offset;
20641 offset = info->altivec_save_offset + sp_offset
20642 + 16 * (i - info->first_altivec_reg_save);
20644 savereg = gen_rtx_REG (V4SImode, i);
20646 areg = gen_rtx_REG (Pmode, 0);
20647 emit_move_insn (areg, GEN_INT (offset));
20649 /* AltiVec addressing mode is [reg+reg]. */
20650 mem = gen_frame_mem (V4SImode,
20651 gen_rtx_PLUS (Pmode, frame_reg_rtx, areg));
20653 insn = emit_move_insn (mem, savereg);
20655 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20656 areg, GEN_INT (offset));
20660 /* VRSAVE is a bit vector representing which AltiVec registers
20661 are used. The OS uses this to determine which vector
20662 registers to save on a context switch. We need to save
20663 VRSAVE on the stack frame, add whatever AltiVec registers we
20664 used in this function, and do the corresponding magic in the
20665 epilogue. */
20667 if (TARGET_ALTIVEC && TARGET_ALTIVEC_VRSAVE
20668 && info->vrsave_mask != 0)
20670 rtx reg, mem, vrsave;
20671 int offset;
20673 /* Get VRSAVE onto a GPR. Note that ABI_V4 might be using r12
20674 as frame_reg_rtx and r11 as the static chain pointer for
20675 nested functions. */
20676 reg = gen_rtx_REG (SImode, 0);
20677 vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
20678 if (TARGET_MACHO)
20679 emit_insn (gen_get_vrsave_internal (reg));
20680 else
20681 emit_insn (gen_rtx_SET (VOIDmode, reg, vrsave));
20683 if (!WORLD_SAVE_P (info))
20685 /* Save VRSAVE. */
20686 offset = info->vrsave_save_offset + sp_offset;
20687 mem = gen_frame_mem (SImode,
20688 gen_rtx_PLUS (Pmode, frame_reg_rtx,
20689 GEN_INT (offset)));
20690 insn = emit_move_insn (mem, reg);
20693 /* Include the registers in the mask. */
20694 emit_insn (gen_iorsi3 (reg, reg, GEN_INT ((int) info->vrsave_mask)));
20696 insn = emit_insn (generate_set_vrsave (reg, info, 0));
20699 if (TARGET_SINGLE_PIC_BASE)
20700 return; /* Do not set PIC register */
20702 /* If we are using RS6000_PIC_OFFSET_TABLE_REGNUM, we need to set it up. */
20703 if ((TARGET_TOC && TARGET_MINIMAL_TOC && get_pool_size () != 0)
20704 || (DEFAULT_ABI == ABI_V4
20705 && (flag_pic == 1 || (flag_pic && TARGET_SECURE_PLT))
20706 && df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM)))
20708 /* If emit_load_toc_table will use the link register, we need to save
20709 it. We use R12 for this purpose because emit_load_toc_table
20710 can use register 0. This allows us to use a plain 'blr' to return
20711 from the procedure more often. */
20712 int save_LR_around_toc_setup = (TARGET_ELF
20713 && DEFAULT_ABI != ABI_AIX
20714 && flag_pic
20715 && ! info->lr_save_p
20716 && EDGE_COUNT (EXIT_BLOCK_PTR->preds) > 0);
20717 if (save_LR_around_toc_setup)
20719 rtx lr = gen_rtx_REG (Pmode, LR_REGNO);
20721 insn = emit_move_insn (frame_ptr_rtx, lr);
20722 RTX_FRAME_RELATED_P (insn) = 1;
20724 rs6000_emit_load_toc_table (TRUE);
20726 insn = emit_move_insn (lr, frame_ptr_rtx);
20727 RTX_FRAME_RELATED_P (insn) = 1;
20729 else
20730 rs6000_emit_load_toc_table (TRUE);
20733 #if TARGET_MACHO
20734 if (DEFAULT_ABI == ABI_DARWIN
20735 && flag_pic && crtl->uses_pic_offset_table)
20737 rtx lr = gen_rtx_REG (Pmode, LR_REGNO);
20738 rtx src = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
20740 /* Save and restore LR locally around this call (in R0). */
20741 if (!info->lr_save_p)
20742 emit_move_insn (gen_rtx_REG (Pmode, 0), lr);
20744 emit_insn (gen_load_macho_picbase (src));
20746 emit_move_insn (gen_rtx_REG (Pmode,
20747 RS6000_PIC_OFFSET_TABLE_REGNUM),
20748 lr);
20750 if (!info->lr_save_p)
20751 emit_move_insn (lr, gen_rtx_REG (Pmode, 0));
20753 #endif
20756 /* Write function prologue. */
20758 static void
20759 rs6000_output_function_prologue (FILE *file,
20760 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
20762 rs6000_stack_t *info = rs6000_stack_info ();
20764 if (TARGET_DEBUG_STACK)
20765 debug_stack_info (info);
20767 /* Write .extern for any function we will call to save and restore
20768 fp values. */
20769 if (info->first_fp_reg_save < 64)
20771 char *name;
20772 int regno = info->first_fp_reg_save - 32;
20774 if ((info->savres_strategy & SAVE_INLINE_FPRS) == 0)
20776 name = rs6000_savres_routine_name (info, regno, /*savep=*/true,
20777 /*gpr=*/false, /*lr=*/false);
20778 fprintf (file, "\t.extern %s\n", name);
20780 if ((info->savres_strategy & REST_INLINE_FPRS) == 0)
20782 name = rs6000_savres_routine_name (info, regno, /*savep=*/false,
20783 /*gpr=*/false, /*lr=*/true);
20784 fprintf (file, "\t.extern %s\n", name);
20788 /* Write .extern for AIX common mode routines, if needed. */
20789 if (! TARGET_POWER && ! TARGET_POWERPC && ! common_mode_defined)
20791 fputs ("\t.extern __mulh\n", file);
20792 fputs ("\t.extern __mull\n", file);
20793 fputs ("\t.extern __divss\n", file);
20794 fputs ("\t.extern __divus\n", file);
20795 fputs ("\t.extern __quoss\n", file);
20796 fputs ("\t.extern __quous\n", file);
20797 common_mode_defined = 1;
20800 if (! HAVE_prologue)
20802 rtx prologue;
20804 start_sequence ();
20806 /* A NOTE_INSN_DELETED is supposed to be at the start and end of
20807 the "toplevel" insn chain. */
20808 emit_note (NOTE_INSN_DELETED);
20809 rs6000_emit_prologue ();
20810 emit_note (NOTE_INSN_DELETED);
20812 /* Expand INSN_ADDRESSES so final() doesn't crash. */
20814 rtx insn;
20815 unsigned addr = 0;
20816 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
20818 INSN_ADDRESSES_NEW (insn, addr);
20819 addr += 4;
20823 prologue = get_insns ();
20824 end_sequence ();
20826 if (TARGET_DEBUG_STACK)
20827 debug_rtx_list (prologue, 100);
20829 emit_insn_before_noloc (prologue, BB_HEAD (ENTRY_BLOCK_PTR->next_bb),
20830 ENTRY_BLOCK_PTR);
20833 rs6000_pic_labelno++;
20836 /* Non-zero if vmx regs are restored before the frame pop, zero if
20837 we restore after the pop when possible. */
20838 #define ALWAYS_RESTORE_ALTIVEC_BEFORE_POP 0
20840 /* Reload CR from REG. */
20842 static void
20843 rs6000_restore_saved_cr (rtx reg, int using_mfcr_multiple)
20845 int count = 0;
20846 int i;
20848 if (using_mfcr_multiple)
20850 for (i = 0; i < 8; i++)
20851 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
20852 count++;
20853 gcc_assert (count);
20856 if (using_mfcr_multiple && count > 1)
20858 rtvec p;
20859 int ndx;
20861 p = rtvec_alloc (count);
20863 ndx = 0;
20864 for (i = 0; i < 8; i++)
20865 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
20867 rtvec r = rtvec_alloc (2);
20868 RTVEC_ELT (r, 0) = reg;
20869 RTVEC_ELT (r, 1) = GEN_INT (1 << (7-i));
20870 RTVEC_ELT (p, ndx) =
20871 gen_rtx_SET (VOIDmode, gen_rtx_REG (CCmode, CR0_REGNO+i),
20872 gen_rtx_UNSPEC (CCmode, r, UNSPEC_MOVESI_TO_CR));
20873 ndx++;
20875 emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
20876 gcc_assert (ndx == count);
20878 else
20879 for (i = 0; i < 8; i++)
20880 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
20882 emit_insn (gen_movsi_to_cr_one (gen_rtx_REG (CCmode,
20883 CR0_REGNO+i),
20884 reg));
20888 /* Return true if OFFSET from stack pointer can be clobbered by signals.
20889 V.4 doesn't have any stack cushion, AIX ABIs have 220 or 288 bytes
20890 below stack pointer not cloberred by signals. */
20892 static inline bool
20893 offset_below_red_zone_p (HOST_WIDE_INT offset)
20895 return offset < (DEFAULT_ABI == ABI_V4
20897 : TARGET_32BIT ? -220 : -288);
20900 /* Emit function epilogue as insns. */
20902 void
20903 rs6000_emit_epilogue (int sibcall)
20905 rs6000_stack_t *info;
20906 int restoring_GPRs_inline;
20907 int restoring_FPRs_inline;
20908 int using_load_multiple;
20909 int using_mtcr_multiple;
20910 int use_backchain_to_restore_sp;
20911 int restore_lr;
20912 int strategy;
20913 int sp_offset = 0;
20914 rtx sp_reg_rtx = gen_rtx_REG (Pmode, 1);
20915 rtx frame_reg_rtx = sp_reg_rtx;
20916 rtx cfa_restores = NULL_RTX;
20917 rtx insn;
20918 rtx cr_save_reg = NULL_RTX;
20919 enum machine_mode reg_mode = Pmode;
20920 int reg_size = TARGET_32BIT ? 4 : 8;
20921 int i;
20923 info = rs6000_stack_info ();
20925 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
20927 reg_mode = V2SImode;
20928 reg_size = 8;
20931 strategy = info->savres_strategy;
20932 using_load_multiple = strategy & SAVRES_MULTIPLE;
20933 restoring_FPRs_inline = sibcall || (strategy & REST_INLINE_FPRS);
20934 restoring_GPRs_inline = sibcall || (strategy & REST_INLINE_GPRS);
20935 using_mtcr_multiple = (rs6000_cpu == PROCESSOR_PPC601
20936 || rs6000_cpu == PROCESSOR_PPC603
20937 || rs6000_cpu == PROCESSOR_PPC750
20938 || optimize_size);
20939 /* Restore via the backchain when we have a large frame, since this
20940 is more efficient than an addis, addi pair. The second condition
20941 here will not trigger at the moment; We don't actually need a
20942 frame pointer for alloca, but the generic parts of the compiler
20943 give us one anyway. */
20944 use_backchain_to_restore_sp = (info->total_size > 32767
20945 || info->total_size
20946 + (info->lr_save_p ? info->lr_save_offset : 0)
20947 > 32767
20948 || (cfun->calls_alloca
20949 && !frame_pointer_needed));
20950 restore_lr = (info->lr_save_p
20951 && (restoring_FPRs_inline
20952 || (strategy & REST_NOINLINE_FPRS_DOESNT_RESTORE_LR))
20953 && (restoring_GPRs_inline
20954 || info->first_fp_reg_save < 64));
20956 if (WORLD_SAVE_P (info))
20958 int i, j;
20959 char rname[30];
20960 const char *alloc_rname;
20961 rtvec p;
20963 /* eh_rest_world_r10 will return to the location saved in the LR
20964 stack slot (which is not likely to be our caller.)
20965 Input: R10 -- stack adjustment. Clobbers R0, R11, R12, R7, R8.
20966 rest_world is similar, except any R10 parameter is ignored.
20967 The exception-handling stuff that was here in 2.95 is no
20968 longer necessary. */
20970 p = rtvec_alloc (9
20972 + 32 - info->first_gp_reg_save
20973 + LAST_ALTIVEC_REGNO + 1 - info->first_altivec_reg_save
20974 + 63 + 1 - info->first_fp_reg_save);
20976 strcpy (rname, ((crtl->calls_eh_return) ?
20977 "*eh_rest_world_r10" : "*rest_world"));
20978 alloc_rname = ggc_strdup (rname);
20980 j = 0;
20981 RTVEC_ELT (p, j++) = gen_rtx_RETURN (VOIDmode);
20982 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
20983 gen_rtx_REG (Pmode,
20984 LR_REGNO));
20985 RTVEC_ELT (p, j++)
20986 = gen_rtx_USE (VOIDmode, gen_rtx_SYMBOL_REF (Pmode, alloc_rname));
20987 /* The instruction pattern requires a clobber here;
20988 it is shared with the restVEC helper. */
20989 RTVEC_ELT (p, j++)
20990 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 11));
20993 /* CR register traditionally saved as CR2. */
20994 rtx reg = gen_rtx_REG (reg_mode, CR2_REGNO);
20995 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20996 GEN_INT (info->cr_save_offset));
20997 rtx mem = gen_frame_mem (reg_mode, addr);
20999 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
21002 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
21004 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
21005 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21006 GEN_INT (info->gp_save_offset
21007 + reg_size * i));
21008 rtx mem = gen_frame_mem (reg_mode, addr);
21010 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
21012 for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++)
21014 rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i);
21015 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21016 GEN_INT (info->altivec_save_offset
21017 + 16 * i));
21018 rtx mem = gen_frame_mem (V4SImode, addr);
21020 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
21022 for (i = 0; info->first_fp_reg_save + i <= 63; i++)
21024 rtx reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
21025 ? DFmode : SFmode),
21026 info->first_fp_reg_save + i);
21027 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21028 GEN_INT (info->fp_save_offset
21029 + 8 * i));
21030 rtx mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
21031 ? DFmode : SFmode), addr);
21033 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
21035 RTVEC_ELT (p, j++)
21036 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 0));
21037 RTVEC_ELT (p, j++)
21038 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 12));
21039 RTVEC_ELT (p, j++)
21040 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 7));
21041 RTVEC_ELT (p, j++)
21042 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 8));
21043 RTVEC_ELT (p, j++)
21044 = gen_rtx_USE (VOIDmode, gen_rtx_REG (SImode, 10));
21045 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
21047 return;
21050 /* frame_reg_rtx + sp_offset points to the top of this stack frame. */
21051 if (info->push_p)
21052 sp_offset = info->total_size;
21054 /* Restore AltiVec registers if we must do so before adjusting the
21055 stack. */
21056 if (TARGET_ALTIVEC_ABI
21057 && info->altivec_size != 0
21058 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
21059 || (DEFAULT_ABI != ABI_V4
21060 && offset_below_red_zone_p (info->altivec_save_offset))))
21062 int i;
21064 if (use_backchain_to_restore_sp)
21066 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
21067 emit_move_insn (frame_reg_rtx,
21068 gen_rtx_MEM (Pmode, sp_reg_rtx));
21069 sp_offset = 0;
21071 else if (frame_pointer_needed)
21072 frame_reg_rtx = hard_frame_pointer_rtx;
21074 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
21075 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
21077 rtx addr, areg, mem, reg;
21079 areg = gen_rtx_REG (Pmode, 0);
21080 emit_move_insn
21081 (areg, GEN_INT (info->altivec_save_offset
21082 + sp_offset
21083 + 16 * (i - info->first_altivec_reg_save)));
21085 /* AltiVec addressing mode is [reg+reg]. */
21086 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
21087 mem = gen_frame_mem (V4SImode, addr);
21089 reg = gen_rtx_REG (V4SImode, i);
21090 emit_move_insn (reg, mem);
21091 if (offset_below_red_zone_p (info->altivec_save_offset
21092 + (i - info->first_altivec_reg_save)
21093 * 16))
21094 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21095 cfa_restores);
21099 /* Restore VRSAVE if we must do so before adjusting the stack. */
21100 if (TARGET_ALTIVEC
21101 && TARGET_ALTIVEC_VRSAVE
21102 && info->vrsave_mask != 0
21103 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
21104 || (DEFAULT_ABI != ABI_V4
21105 && offset_below_red_zone_p (info->vrsave_save_offset))))
21107 rtx addr, mem, reg;
21109 if (frame_reg_rtx == sp_reg_rtx)
21111 if (use_backchain_to_restore_sp)
21113 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
21114 emit_move_insn (frame_reg_rtx,
21115 gen_rtx_MEM (Pmode, sp_reg_rtx));
21116 sp_offset = 0;
21118 else if (frame_pointer_needed)
21119 frame_reg_rtx = hard_frame_pointer_rtx;
21122 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21123 GEN_INT (info->vrsave_save_offset + sp_offset));
21124 mem = gen_frame_mem (SImode, addr);
21125 reg = gen_rtx_REG (SImode, 12);
21126 emit_move_insn (reg, mem);
21128 emit_insn (generate_set_vrsave (reg, info, 1));
21131 insn = NULL_RTX;
21132 /* If we have a large stack frame, restore the old stack pointer
21133 using the backchain. */
21134 if (use_backchain_to_restore_sp)
21136 if (frame_reg_rtx == sp_reg_rtx)
21138 /* Under V.4, don't reset the stack pointer until after we're done
21139 loading the saved registers. */
21140 if (DEFAULT_ABI == ABI_V4)
21141 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
21143 insn = emit_move_insn (frame_reg_rtx,
21144 gen_rtx_MEM (Pmode, sp_reg_rtx));
21145 sp_offset = 0;
21147 else if (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
21148 && DEFAULT_ABI == ABI_V4)
21149 /* frame_reg_rtx has been set up by the altivec restore. */
21151 else
21153 insn = emit_move_insn (sp_reg_rtx, frame_reg_rtx);
21154 frame_reg_rtx = sp_reg_rtx;
21157 /* If we have a frame pointer, we can restore the old stack pointer
21158 from it. */
21159 else if (frame_pointer_needed)
21161 frame_reg_rtx = sp_reg_rtx;
21162 if (DEFAULT_ABI == ABI_V4)
21163 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
21164 /* Prevent reordering memory accesses against stack pointer restore. */
21165 else if (cfun->calls_alloca
21166 || offset_below_red_zone_p (-info->total_size))
21168 rtx mem1 = gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx);
21169 rtx mem2 = gen_rtx_MEM (BLKmode, sp_reg_rtx);
21170 MEM_NOTRAP_P (mem1) = 1;
21171 MEM_NOTRAP_P (mem2) = 1;
21172 emit_insn (gen_frame_tie (mem1, mem2));
21175 insn = emit_insn (gen_add3_insn (frame_reg_rtx, hard_frame_pointer_rtx,
21176 GEN_INT (info->total_size)));
21177 sp_offset = 0;
21179 else if (info->push_p
21180 && DEFAULT_ABI != ABI_V4
21181 && !crtl->calls_eh_return)
21183 /* Prevent reordering memory accesses against stack pointer restore. */
21184 if (cfun->calls_alloca
21185 || offset_below_red_zone_p (-info->total_size))
21187 rtx mem = gen_rtx_MEM (BLKmode, sp_reg_rtx);
21188 MEM_NOTRAP_P (mem) = 1;
21189 emit_insn (gen_stack_tie (mem));
21191 insn = emit_insn (gen_add3_insn (sp_reg_rtx, sp_reg_rtx,
21192 GEN_INT (info->total_size)));
21193 sp_offset = 0;
21195 if (insn && frame_reg_rtx == sp_reg_rtx)
21197 if (cfa_restores)
21199 REG_NOTES (insn) = cfa_restores;
21200 cfa_restores = NULL_RTX;
21202 add_reg_note (insn, REG_CFA_DEF_CFA, sp_reg_rtx);
21203 RTX_FRAME_RELATED_P (insn) = 1;
21206 /* Restore AltiVec registers if we have not done so already. */
21207 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
21208 && TARGET_ALTIVEC_ABI
21209 && info->altivec_size != 0
21210 && (DEFAULT_ABI == ABI_V4
21211 || !offset_below_red_zone_p (info->altivec_save_offset)))
21213 int i;
21215 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
21216 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
21218 rtx addr, areg, mem, reg;
21220 areg = gen_rtx_REG (Pmode, 0);
21221 emit_move_insn
21222 (areg, GEN_INT (info->altivec_save_offset
21223 + sp_offset
21224 + 16 * (i - info->first_altivec_reg_save)));
21226 /* AltiVec addressing mode is [reg+reg]. */
21227 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
21228 mem = gen_frame_mem (V4SImode, addr);
21230 reg = gen_rtx_REG (V4SImode, i);
21231 emit_move_insn (reg, mem);
21232 if (DEFAULT_ABI == ABI_V4)
21233 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21234 cfa_restores);
21238 /* Restore VRSAVE if we have not done so already. */
21239 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
21240 && TARGET_ALTIVEC
21241 && TARGET_ALTIVEC_VRSAVE
21242 && info->vrsave_mask != 0
21243 && (DEFAULT_ABI == ABI_V4
21244 || !offset_below_red_zone_p (info->vrsave_save_offset)))
21246 rtx addr, mem, reg;
21248 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21249 GEN_INT (info->vrsave_save_offset + sp_offset));
21250 mem = gen_frame_mem (SImode, addr);
21251 reg = gen_rtx_REG (SImode, 12);
21252 emit_move_insn (reg, mem);
21254 emit_insn (generate_set_vrsave (reg, info, 1));
21257 /* Get the old lr if we saved it. If we are restoring registers
21258 out-of-line, then the out-of-line routines can do this for us. */
21259 if (restore_lr && restoring_GPRs_inline)
21261 rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
21262 info->lr_save_offset + sp_offset);
21264 emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
21267 /* Get the old cr if we saved it. */
21268 if (info->cr_save_p)
21270 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21271 GEN_INT (info->cr_save_offset + sp_offset));
21272 rtx mem = gen_frame_mem (SImode, addr);
21274 cr_save_reg = gen_rtx_REG (SImode,
21275 DEFAULT_ABI == ABI_AIX
21276 && !restoring_GPRs_inline
21277 && info->first_fp_reg_save < 64
21278 ? 11 : 12);
21279 emit_move_insn (cr_save_reg, mem);
21282 /* Set LR here to try to overlap restores below. LR is always saved
21283 above incoming stack, so it never needs REG_CFA_RESTORE. */
21284 if (restore_lr && restoring_GPRs_inline)
21285 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO),
21286 gen_rtx_REG (Pmode, 0));
21288 /* Load exception handler data registers, if needed. */
21289 if (crtl->calls_eh_return)
21291 unsigned int i, regno;
21293 if (TARGET_AIX)
21295 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21296 GEN_INT (sp_offset + 5 * reg_size));
21297 rtx mem = gen_frame_mem (reg_mode, addr);
21299 emit_move_insn (gen_rtx_REG (reg_mode, 2), mem);
21302 for (i = 0; ; ++i)
21304 rtx mem;
21306 regno = EH_RETURN_DATA_REGNO (i);
21307 if (regno == INVALID_REGNUM)
21308 break;
21310 mem = gen_frame_mem_offset (reg_mode, frame_reg_rtx,
21311 info->ehrd_offset + sp_offset
21312 + reg_size * (int) i);
21314 emit_move_insn (gen_rtx_REG (reg_mode, regno), mem);
21318 /* Restore GPRs. This is done as a PARALLEL if we are using
21319 the load-multiple instructions. */
21320 if (TARGET_SPE_ABI
21321 && info->spe_64bit_regs_used != 0
21322 && info->first_gp_reg_save != 32)
21324 /* Determine whether we can address all of the registers that need
21325 to be saved with an offset from the stack pointer that fits in
21326 the small const field for SPE memory instructions. */
21327 int spe_regs_addressable_via_sp
21328 = (SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset
21329 + (32 - info->first_gp_reg_save - 1) * reg_size)
21330 && restoring_GPRs_inline);
21331 int spe_offset;
21333 if (spe_regs_addressable_via_sp)
21334 spe_offset = info->spe_gp_save_offset + sp_offset;
21335 else
21337 rtx old_frame_reg_rtx = frame_reg_rtx;
21338 /* Make r11 point to the start of the SPE save area. We worried about
21339 not clobbering it when we were saving registers in the prologue.
21340 There's no need to worry here because the static chain is passed
21341 anew to every function. */
21342 int ool_adjust = (restoring_GPRs_inline
21344 : (info->first_gp_reg_save
21345 - (FIRST_SAVRES_REGISTER+1))*8);
21347 if (frame_reg_rtx == sp_reg_rtx)
21348 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
21349 emit_insn (gen_addsi3 (frame_reg_rtx, old_frame_reg_rtx,
21350 GEN_INT (info->spe_gp_save_offset
21351 + sp_offset
21352 - ool_adjust)));
21353 /* Keep the invariant that frame_reg_rtx + sp_offset points
21354 at the top of the stack frame. */
21355 sp_offset = -info->spe_gp_save_offset;
21357 spe_offset = 0;
21360 if (restoring_GPRs_inline)
21362 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
21363 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
21365 rtx offset, addr, mem, reg;
21367 /* We're doing all this to ensure that the immediate offset
21368 fits into the immediate field of 'evldd'. */
21369 gcc_assert (SPE_CONST_OFFSET_OK (spe_offset + reg_size * i));
21371 offset = GEN_INT (spe_offset + reg_size * i);
21372 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, offset);
21373 mem = gen_rtx_MEM (V2SImode, addr);
21374 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
21376 insn = emit_move_insn (reg, mem);
21377 if (DEFAULT_ABI == ABI_V4)
21379 if (frame_pointer_needed
21380 && info->first_gp_reg_save + i
21381 == HARD_FRAME_POINTER_REGNUM)
21383 add_reg_note (insn, REG_CFA_DEF_CFA,
21384 plus_constant (frame_reg_rtx,
21385 sp_offset));
21386 RTX_FRAME_RELATED_P (insn) = 1;
21389 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21390 cfa_restores);
21394 else
21396 rtx par;
21398 par = rs6000_make_savres_rtx (info, gen_rtx_REG (Pmode, 11),
21399 0, reg_mode,
21400 /*savep=*/false, /*gpr=*/true,
21401 /*lr=*/true);
21402 emit_jump_insn (par);
21403 /* We don't want anybody else emitting things after we jumped
21404 back. */
21405 return;
21408 else if (!restoring_GPRs_inline)
21410 /* We are jumping to an out-of-line function. */
21411 bool can_use_exit = info->first_fp_reg_save == 64;
21412 rtx par;
21414 /* Emit stack reset code if we need it. */
21415 if (can_use_exit)
21416 rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx,
21417 sp_offset, can_use_exit);
21418 else
21420 emit_insn (gen_add3_insn (gen_rtx_REG (Pmode, DEFAULT_ABI == ABI_AIX
21421 ? 12 : 11),
21422 frame_reg_rtx,
21423 GEN_INT (sp_offset - info->fp_size)));
21424 if (REGNO (frame_reg_rtx) == 11)
21425 sp_offset += info->fp_size;
21428 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
21429 info->gp_save_offset, reg_mode,
21430 /*savep=*/false, /*gpr=*/true,
21431 /*lr=*/can_use_exit);
21433 if (can_use_exit)
21435 if (info->cr_save_p)
21437 rs6000_restore_saved_cr (cr_save_reg, using_mtcr_multiple);
21438 if (DEFAULT_ABI == ABI_V4)
21439 cfa_restores
21440 = alloc_reg_note (REG_CFA_RESTORE,
21441 gen_rtx_REG (SImode, CR2_REGNO),
21442 cfa_restores);
21445 emit_jump_insn (par);
21447 /* We don't want anybody else emitting things after we jumped
21448 back. */
21449 return;
21452 insn = emit_insn (par);
21453 if (DEFAULT_ABI == ABI_V4)
21455 if (frame_pointer_needed)
21457 add_reg_note (insn, REG_CFA_DEF_CFA,
21458 plus_constant (frame_reg_rtx, sp_offset));
21459 RTX_FRAME_RELATED_P (insn) = 1;
21462 for (i = info->first_gp_reg_save; i < 32; i++)
21463 cfa_restores
21464 = alloc_reg_note (REG_CFA_RESTORE,
21465 gen_rtx_REG (reg_mode, i), cfa_restores);
21468 else if (using_load_multiple)
21470 rtvec p;
21471 p = rtvec_alloc (32 - info->first_gp_reg_save);
21472 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
21474 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21475 GEN_INT (info->gp_save_offset
21476 + sp_offset
21477 + reg_size * i));
21478 rtx mem = gen_frame_mem (reg_mode, addr);
21479 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
21481 RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, reg, mem);
21482 if (DEFAULT_ABI == ABI_V4)
21483 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21484 cfa_restores);
21486 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
21487 if (DEFAULT_ABI == ABI_V4 && frame_pointer_needed)
21489 add_reg_note (insn, REG_CFA_DEF_CFA,
21490 plus_constant (frame_reg_rtx, sp_offset));
21491 RTX_FRAME_RELATED_P (insn) = 1;
21494 else
21496 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
21497 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
21499 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21500 GEN_INT (info->gp_save_offset
21501 + sp_offset
21502 + reg_size * i));
21503 rtx mem = gen_frame_mem (reg_mode, addr);
21504 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
21506 insn = emit_move_insn (reg, mem);
21507 if (DEFAULT_ABI == ABI_V4)
21509 if (frame_pointer_needed
21510 && info->first_gp_reg_save + i
21511 == HARD_FRAME_POINTER_REGNUM)
21513 add_reg_note (insn, REG_CFA_DEF_CFA,
21514 plus_constant (frame_reg_rtx, sp_offset));
21515 RTX_FRAME_RELATED_P (insn) = 1;
21518 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21519 cfa_restores);
21524 if (restore_lr && !restoring_GPRs_inline)
21526 rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
21527 info->lr_save_offset + sp_offset);
21529 emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
21530 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO),
21531 gen_rtx_REG (Pmode, 0));
21534 /* Restore fpr's if we need to do it without calling a function. */
21535 if (restoring_FPRs_inline)
21536 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
21537 if ((df_regs_ever_live_p (info->first_fp_reg_save+i)
21538 && ! call_used_regs[info->first_fp_reg_save+i]))
21540 rtx addr, mem, reg;
21541 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21542 GEN_INT (info->fp_save_offset
21543 + sp_offset
21544 + 8 * i));
21545 mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
21546 ? DFmode : SFmode), addr);
21547 reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
21548 ? DFmode : SFmode),
21549 info->first_fp_reg_save + i);
21551 emit_move_insn (reg, mem);
21552 if (DEFAULT_ABI == ABI_V4)
21553 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21554 cfa_restores);
21557 /* If we saved cr, restore it here. Just those that were used. */
21558 if (info->cr_save_p)
21560 rs6000_restore_saved_cr (cr_save_reg, using_mtcr_multiple);
21561 if (DEFAULT_ABI == ABI_V4)
21562 cfa_restores
21563 = alloc_reg_note (REG_CFA_RESTORE, gen_rtx_REG (SImode, CR2_REGNO),
21564 cfa_restores);
21567 /* If this is V.4, unwind the stack pointer after all of the loads
21568 have been done. */
21569 insn = rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx,
21570 sp_offset, !restoring_FPRs_inline);
21571 if (insn)
21573 if (cfa_restores)
21575 REG_NOTES (insn) = cfa_restores;
21576 cfa_restores = NULL_RTX;
21578 add_reg_note (insn, REG_CFA_DEF_CFA, sp_reg_rtx);
21579 RTX_FRAME_RELATED_P (insn) = 1;
21582 if (crtl->calls_eh_return)
21584 rtx sa = EH_RETURN_STACKADJ_RTX;
21585 emit_insn (gen_add3_insn (sp_reg_rtx, sp_reg_rtx, sa));
21588 if (!sibcall)
21590 rtvec p;
21591 bool lr = (strategy & REST_NOINLINE_FPRS_DOESNT_RESTORE_LR) == 0;
21592 if (! restoring_FPRs_inline)
21593 p = rtvec_alloc (4 + 64 - info->first_fp_reg_save);
21594 else
21595 p = rtvec_alloc (2);
21597 RTVEC_ELT (p, 0) = gen_rtx_RETURN (VOIDmode);
21598 RTVEC_ELT (p, 1) = ((restoring_FPRs_inline || !lr)
21599 ? gen_rtx_USE (VOIDmode, gen_rtx_REG (Pmode, 65))
21600 : gen_rtx_CLOBBER (VOIDmode,
21601 gen_rtx_REG (Pmode, 65)));
21603 /* If we have to restore more than two FP registers, branch to the
21604 restore function. It will return to our caller. */
21605 if (! restoring_FPRs_inline)
21607 int i;
21608 rtx sym;
21610 sym = rs6000_savres_routine_sym (info,
21611 /*savep=*/false,
21612 /*gpr=*/false,
21613 /*lr=*/lr);
21614 RTVEC_ELT (p, 2) = gen_rtx_USE (VOIDmode, sym);
21615 RTVEC_ELT (p, 3) = gen_rtx_USE (VOIDmode,
21616 gen_rtx_REG (Pmode,
21617 DEFAULT_ABI == ABI_AIX
21618 ? 1 : 11));
21619 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
21621 rtx addr, mem;
21622 addr = gen_rtx_PLUS (Pmode, sp_reg_rtx,
21623 GEN_INT (info->fp_save_offset + 8*i));
21624 mem = gen_frame_mem (DFmode, addr);
21626 RTVEC_ELT (p, i+4) =
21627 gen_rtx_SET (VOIDmode,
21628 gen_rtx_REG (DFmode, info->first_fp_reg_save + i),
21629 mem);
21633 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
21637 /* Write function epilogue. */
21639 static void
21640 rs6000_output_function_epilogue (FILE *file,
21641 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
21643 if (! HAVE_epilogue)
21645 rtx insn = get_last_insn ();
21646 /* If the last insn was a BARRIER, we don't have to write anything except
21647 the trace table. */
21648 if (GET_CODE (insn) == NOTE)
21649 insn = prev_nonnote_insn (insn);
21650 if (insn == 0 || GET_CODE (insn) != BARRIER)
21652 /* This is slightly ugly, but at least we don't have two
21653 copies of the epilogue-emitting code. */
21654 start_sequence ();
21656 /* A NOTE_INSN_DELETED is supposed to be at the start
21657 and end of the "toplevel" insn chain. */
21658 emit_note (NOTE_INSN_DELETED);
21659 rs6000_emit_epilogue (FALSE);
21660 emit_note (NOTE_INSN_DELETED);
21662 /* Expand INSN_ADDRESSES so final() doesn't crash. */
21664 rtx insn;
21665 unsigned addr = 0;
21666 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
21668 INSN_ADDRESSES_NEW (insn, addr);
21669 addr += 4;
21673 if (TARGET_DEBUG_STACK)
21674 debug_rtx_list (get_insns (), 100);
21675 final (get_insns (), file, FALSE);
21676 end_sequence ();
21680 #if TARGET_MACHO
21681 macho_branch_islands ();
21682 /* Mach-O doesn't support labels at the end of objects, so if
21683 it looks like we might want one, insert a NOP. */
21685 rtx insn = get_last_insn ();
21686 while (insn
21687 && NOTE_P (insn)
21688 && NOTE_KIND (insn) != NOTE_INSN_DELETED_LABEL)
21689 insn = PREV_INSN (insn);
21690 if (insn
21691 && (LABEL_P (insn)
21692 || (NOTE_P (insn)
21693 && NOTE_KIND (insn) == NOTE_INSN_DELETED_LABEL)))
21694 fputs ("\tnop\n", file);
21696 #endif
21698 /* Output a traceback table here. See /usr/include/sys/debug.h for info
21699 on its format.
21701 We don't output a traceback table if -finhibit-size-directive was
21702 used. The documentation for -finhibit-size-directive reads
21703 ``don't output a @code{.size} assembler directive, or anything
21704 else that would cause trouble if the function is split in the
21705 middle, and the two halves are placed at locations far apart in
21706 memory.'' The traceback table has this property, since it
21707 includes the offset from the start of the function to the
21708 traceback table itself.
21710 System V.4 Powerpc's (and the embedded ABI derived from it) use a
21711 different traceback table. */
21712 if (DEFAULT_ABI == ABI_AIX && ! flag_inhibit_size_directive
21713 && rs6000_traceback != traceback_none && !cfun->is_thunk)
21715 const char *fname = NULL;
21716 const char *language_string = lang_hooks.name;
21717 int fixed_parms = 0, float_parms = 0, parm_info = 0;
21718 int i;
21719 int optional_tbtab;
21720 rs6000_stack_t *info = rs6000_stack_info ();
21722 if (rs6000_traceback == traceback_full)
21723 optional_tbtab = 1;
21724 else if (rs6000_traceback == traceback_part)
21725 optional_tbtab = 0;
21726 else
21727 optional_tbtab = !optimize_size && !TARGET_ELF;
21729 if (optional_tbtab)
21731 fname = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0);
21732 while (*fname == '.') /* V.4 encodes . in the name */
21733 fname++;
21735 /* Need label immediately before tbtab, so we can compute
21736 its offset from the function start. */
21737 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
21738 ASM_OUTPUT_LABEL (file, fname);
21741 /* The .tbtab pseudo-op can only be used for the first eight
21742 expressions, since it can't handle the possibly variable
21743 length fields that follow. However, if you omit the optional
21744 fields, the assembler outputs zeros for all optional fields
21745 anyways, giving each variable length field is minimum length
21746 (as defined in sys/debug.h). Thus we can not use the .tbtab
21747 pseudo-op at all. */
21749 /* An all-zero word flags the start of the tbtab, for debuggers
21750 that have to find it by searching forward from the entry
21751 point or from the current pc. */
21752 fputs ("\t.long 0\n", file);
21754 /* Tbtab format type. Use format type 0. */
21755 fputs ("\t.byte 0,", file);
21757 /* Language type. Unfortunately, there does not seem to be any
21758 official way to discover the language being compiled, so we
21759 use language_string.
21760 C is 0. Fortran is 1. Pascal is 2. Ada is 3. C++ is 9.
21761 Java is 13. Objective-C is 14. Objective-C++ isn't assigned
21762 a number, so for now use 9. LTO isn't assigned a number either,
21763 so for now use 0. */
21764 if (! strcmp (language_string, "GNU C")
21765 || ! strcmp (language_string, "GNU GIMPLE"))
21766 i = 0;
21767 else if (! strcmp (language_string, "GNU F77")
21768 || ! strcmp (language_string, "GNU Fortran"))
21769 i = 1;
21770 else if (! strcmp (language_string, "GNU Pascal"))
21771 i = 2;
21772 else if (! strcmp (language_string, "GNU Ada"))
21773 i = 3;
21774 else if (! strcmp (language_string, "GNU C++")
21775 || ! strcmp (language_string, "GNU Objective-C++"))
21776 i = 9;
21777 else if (! strcmp (language_string, "GNU Java"))
21778 i = 13;
21779 else if (! strcmp (language_string, "GNU Objective-C"))
21780 i = 14;
21781 else
21782 gcc_unreachable ();
21783 fprintf (file, "%d,", i);
21785 /* 8 single bit fields: global linkage (not set for C extern linkage,
21786 apparently a PL/I convention?), out-of-line epilogue/prologue, offset
21787 from start of procedure stored in tbtab, internal function, function
21788 has controlled storage, function has no toc, function uses fp,
21789 function logs/aborts fp operations. */
21790 /* Assume that fp operations are used if any fp reg must be saved. */
21791 fprintf (file, "%d,",
21792 (optional_tbtab << 5) | ((info->first_fp_reg_save != 64) << 1));
21794 /* 6 bitfields: function is interrupt handler, name present in
21795 proc table, function calls alloca, on condition directives
21796 (controls stack walks, 3 bits), saves condition reg, saves
21797 link reg. */
21798 /* The `function calls alloca' bit seems to be set whenever reg 31 is
21799 set up as a frame pointer, even when there is no alloca call. */
21800 fprintf (file, "%d,",
21801 ((optional_tbtab << 6)
21802 | ((optional_tbtab & frame_pointer_needed) << 5)
21803 | (info->cr_save_p << 1)
21804 | (info->lr_save_p)));
21806 /* 3 bitfields: saves backchain, fixup code, number of fpr saved
21807 (6 bits). */
21808 fprintf (file, "%d,",
21809 (info->push_p << 7) | (64 - info->first_fp_reg_save));
21811 /* 2 bitfields: spare bits (2 bits), number of gpr saved (6 bits). */
21812 fprintf (file, "%d,", (32 - first_reg_to_save ()));
21814 if (optional_tbtab)
21816 /* Compute the parameter info from the function decl argument
21817 list. */
21818 tree decl;
21819 int next_parm_info_bit = 31;
21821 for (decl = DECL_ARGUMENTS (current_function_decl);
21822 decl; decl = DECL_CHAIN (decl))
21824 rtx parameter = DECL_INCOMING_RTL (decl);
21825 enum machine_mode mode = GET_MODE (parameter);
21827 if (GET_CODE (parameter) == REG)
21829 if (SCALAR_FLOAT_MODE_P (mode))
21831 int bits;
21833 float_parms++;
21835 switch (mode)
21837 case SFmode:
21838 case SDmode:
21839 bits = 0x2;
21840 break;
21842 case DFmode:
21843 case DDmode:
21844 case TFmode:
21845 case TDmode:
21846 bits = 0x3;
21847 break;
21849 default:
21850 gcc_unreachable ();
21853 /* If only one bit will fit, don't or in this entry. */
21854 if (next_parm_info_bit > 0)
21855 parm_info |= (bits << (next_parm_info_bit - 1));
21856 next_parm_info_bit -= 2;
21858 else
21860 fixed_parms += ((GET_MODE_SIZE (mode)
21861 + (UNITS_PER_WORD - 1))
21862 / UNITS_PER_WORD);
21863 next_parm_info_bit -= 1;
21869 /* Number of fixed point parameters. */
21870 /* This is actually the number of words of fixed point parameters; thus
21871 an 8 byte struct counts as 2; and thus the maximum value is 8. */
21872 fprintf (file, "%d,", fixed_parms);
21874 /* 2 bitfields: number of floating point parameters (7 bits), parameters
21875 all on stack. */
21876 /* This is actually the number of fp registers that hold parameters;
21877 and thus the maximum value is 13. */
21878 /* Set parameters on stack bit if parameters are not in their original
21879 registers, regardless of whether they are on the stack? Xlc
21880 seems to set the bit when not optimizing. */
21881 fprintf (file, "%d\n", ((float_parms << 1) | (! optimize)));
21883 if (! optional_tbtab)
21884 return;
21886 /* Optional fields follow. Some are variable length. */
21888 /* Parameter types, left adjusted bit fields: 0 fixed, 10 single float,
21889 11 double float. */
21890 /* There is an entry for each parameter in a register, in the order that
21891 they occur in the parameter list. Any intervening arguments on the
21892 stack are ignored. If the list overflows a long (max possible length
21893 34 bits) then completely leave off all elements that don't fit. */
21894 /* Only emit this long if there was at least one parameter. */
21895 if (fixed_parms || float_parms)
21896 fprintf (file, "\t.long %d\n", parm_info);
21898 /* Offset from start of code to tb table. */
21899 fputs ("\t.long ", file);
21900 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
21901 RS6000_OUTPUT_BASENAME (file, fname);
21902 putc ('-', file);
21903 rs6000_output_function_entry (file, fname);
21904 putc ('\n', file);
21906 /* Interrupt handler mask. */
21907 /* Omit this long, since we never set the interrupt handler bit
21908 above. */
21910 /* Number of CTL (controlled storage) anchors. */
21911 /* Omit this long, since the has_ctl bit is never set above. */
21913 /* Displacement into stack of each CTL anchor. */
21914 /* Omit this list of longs, because there are no CTL anchors. */
21916 /* Length of function name. */
21917 if (*fname == '*')
21918 ++fname;
21919 fprintf (file, "\t.short %d\n", (int) strlen (fname));
21921 /* Function name. */
21922 assemble_string (fname, strlen (fname));
21924 /* Register for alloca automatic storage; this is always reg 31.
21925 Only emit this if the alloca bit was set above. */
21926 if (frame_pointer_needed)
21927 fputs ("\t.byte 31\n", file);
21929 fputs ("\t.align 2\n", file);
21933 /* A C compound statement that outputs the assembler code for a thunk
21934 function, used to implement C++ virtual function calls with
21935 multiple inheritance. The thunk acts as a wrapper around a virtual
21936 function, adjusting the implicit object parameter before handing
21937 control off to the real function.
21939 First, emit code to add the integer DELTA to the location that
21940 contains the incoming first argument. Assume that this argument
21941 contains a pointer, and is the one used to pass the `this' pointer
21942 in C++. This is the incoming argument *before* the function
21943 prologue, e.g. `%o0' on a sparc. The addition must preserve the
21944 values of all other incoming arguments.
21946 After the addition, emit code to jump to FUNCTION, which is a
21947 `FUNCTION_DECL'. This is a direct pure jump, not a call, and does
21948 not touch the return address. Hence returning from FUNCTION will
21949 return to whoever called the current `thunk'.
21951 The effect must be as if FUNCTION had been called directly with the
21952 adjusted first argument. This macro is responsible for emitting
21953 all of the code for a thunk function; output_function_prologue()
21954 and output_function_epilogue() are not invoked.
21956 The THUNK_FNDECL is redundant. (DELTA and FUNCTION have already
21957 been extracted from it.) It might possibly be useful on some
21958 targets, but probably not.
21960 If you do not define this macro, the target-independent code in the
21961 C++ frontend will generate a less efficient heavyweight thunk that
21962 calls FUNCTION instead of jumping to it. The generic approach does
21963 not support varargs. */
21965 static void
21966 rs6000_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
21967 HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
21968 tree function)
21970 rtx this_rtx, insn, funexp;
21972 reload_completed = 1;
21973 epilogue_completed = 1;
21975 /* Mark the end of the (empty) prologue. */
21976 emit_note (NOTE_INSN_PROLOGUE_END);
21978 /* Find the "this" pointer. If the function returns a structure,
21979 the structure return pointer is in r3. */
21980 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function))
21981 this_rtx = gen_rtx_REG (Pmode, 4);
21982 else
21983 this_rtx = gen_rtx_REG (Pmode, 3);
21985 /* Apply the constant offset, if required. */
21986 if (delta)
21987 emit_insn (gen_add3_insn (this_rtx, this_rtx, GEN_INT (delta)));
21989 /* Apply the offset from the vtable, if required. */
21990 if (vcall_offset)
21992 rtx vcall_offset_rtx = GEN_INT (vcall_offset);
21993 rtx tmp = gen_rtx_REG (Pmode, 12);
21995 emit_move_insn (tmp, gen_rtx_MEM (Pmode, this_rtx));
21996 if (((unsigned HOST_WIDE_INT) vcall_offset) + 0x8000 >= 0x10000)
21998 emit_insn (gen_add3_insn (tmp, tmp, vcall_offset_rtx));
21999 emit_move_insn (tmp, gen_rtx_MEM (Pmode, tmp));
22001 else
22003 rtx loc = gen_rtx_PLUS (Pmode, tmp, vcall_offset_rtx);
22005 emit_move_insn (tmp, gen_rtx_MEM (Pmode, loc));
22007 emit_insn (gen_add3_insn (this_rtx, this_rtx, tmp));
22010 /* Generate a tail call to the target function. */
22011 if (!TREE_USED (function))
22013 assemble_external (function);
22014 TREE_USED (function) = 1;
22016 funexp = XEXP (DECL_RTL (function), 0);
22017 funexp = gen_rtx_MEM (FUNCTION_MODE, funexp);
22019 #if TARGET_MACHO
22020 if (MACHOPIC_INDIRECT)
22021 funexp = machopic_indirect_call_target (funexp);
22022 #endif
22024 /* gen_sibcall expects reload to convert scratch pseudo to LR so we must
22025 generate sibcall RTL explicitly. */
22026 insn = emit_call_insn (
22027 gen_rtx_PARALLEL (VOIDmode,
22028 gen_rtvec (4,
22029 gen_rtx_CALL (VOIDmode,
22030 funexp, const0_rtx),
22031 gen_rtx_USE (VOIDmode, const0_rtx),
22032 gen_rtx_USE (VOIDmode,
22033 gen_rtx_REG (SImode,
22034 LR_REGNO)),
22035 gen_rtx_RETURN (VOIDmode))));
22036 SIBLING_CALL_P (insn) = 1;
22037 emit_barrier ();
22039 /* Run just enough of rest_of_compilation to get the insns emitted.
22040 There's not really enough bulk here to make other passes such as
22041 instruction scheduling worth while. Note that use_thunk calls
22042 assemble_start_function and assemble_end_function. */
22043 insn = get_insns ();
22044 insn_locators_alloc ();
22045 shorten_branches (insn);
22046 final_start_function (insn, file, 1);
22047 final (insn, file, 1);
22048 final_end_function ();
22050 reload_completed = 0;
22051 epilogue_completed = 0;
22054 /* A quick summary of the various types of 'constant-pool tables'
22055 under PowerPC:
22057 Target Flags Name One table per
22058 AIX (none) AIX TOC object file
22059 AIX -mfull-toc AIX TOC object file
22060 AIX -mminimal-toc AIX minimal TOC translation unit
22061 SVR4/EABI (none) SVR4 SDATA object file
22062 SVR4/EABI -fpic SVR4 pic object file
22063 SVR4/EABI -fPIC SVR4 PIC translation unit
22064 SVR4/EABI -mrelocatable EABI TOC function
22065 SVR4/EABI -maix AIX TOC object file
22066 SVR4/EABI -maix -mminimal-toc
22067 AIX minimal TOC translation unit
22069 Name Reg. Set by entries contains:
22070 made by addrs? fp? sum?
22072 AIX TOC 2 crt0 as Y option option
22073 AIX minimal TOC 30 prolog gcc Y Y option
22074 SVR4 SDATA 13 crt0 gcc N Y N
22075 SVR4 pic 30 prolog ld Y not yet N
22076 SVR4 PIC 30 prolog gcc Y option option
22077 EABI TOC 30 prolog gcc Y option option
22081 /* Hash functions for the hash table. */
22083 static unsigned
22084 rs6000_hash_constant (rtx k)
22086 enum rtx_code code = GET_CODE (k);
22087 enum machine_mode mode = GET_MODE (k);
22088 unsigned result = (code << 3) ^ mode;
22089 const char *format;
22090 int flen, fidx;
22092 format = GET_RTX_FORMAT (code);
22093 flen = strlen (format);
22094 fidx = 0;
22096 switch (code)
22098 case LABEL_REF:
22099 return result * 1231 + (unsigned) INSN_UID (XEXP (k, 0));
22101 case CONST_DOUBLE:
22102 if (mode != VOIDmode)
22103 return real_hash (CONST_DOUBLE_REAL_VALUE (k)) * result;
22104 flen = 2;
22105 break;
22107 case CODE_LABEL:
22108 fidx = 3;
22109 break;
22111 default:
22112 break;
22115 for (; fidx < flen; fidx++)
22116 switch (format[fidx])
22118 case 's':
22120 unsigned i, len;
22121 const char *str = XSTR (k, fidx);
22122 len = strlen (str);
22123 result = result * 613 + len;
22124 for (i = 0; i < len; i++)
22125 result = result * 613 + (unsigned) str[i];
22126 break;
22128 case 'u':
22129 case 'e':
22130 result = result * 1231 + rs6000_hash_constant (XEXP (k, fidx));
22131 break;
22132 case 'i':
22133 case 'n':
22134 result = result * 613 + (unsigned) XINT (k, fidx);
22135 break;
22136 case 'w':
22137 if (sizeof (unsigned) >= sizeof (HOST_WIDE_INT))
22138 result = result * 613 + (unsigned) XWINT (k, fidx);
22139 else
22141 size_t i;
22142 for (i = 0; i < sizeof (HOST_WIDE_INT) / sizeof (unsigned); i++)
22143 result = result * 613 + (unsigned) (XWINT (k, fidx)
22144 >> CHAR_BIT * i);
22146 break;
22147 case '0':
22148 break;
22149 default:
22150 gcc_unreachable ();
22153 return result;
22156 static unsigned
22157 toc_hash_function (const void *hash_entry)
22159 const struct toc_hash_struct *thc =
22160 (const struct toc_hash_struct *) hash_entry;
22161 return rs6000_hash_constant (thc->key) ^ thc->key_mode;
22164 /* Compare H1 and H2 for equivalence. */
22166 static int
22167 toc_hash_eq (const void *h1, const void *h2)
22169 rtx r1 = ((const struct toc_hash_struct *) h1)->key;
22170 rtx r2 = ((const struct toc_hash_struct *) h2)->key;
22172 if (((const struct toc_hash_struct *) h1)->key_mode
22173 != ((const struct toc_hash_struct *) h2)->key_mode)
22174 return 0;
22176 return rtx_equal_p (r1, r2);
22179 /* These are the names given by the C++ front-end to vtables, and
22180 vtable-like objects. Ideally, this logic should not be here;
22181 instead, there should be some programmatic way of inquiring as
22182 to whether or not an object is a vtable. */
22184 #define VTABLE_NAME_P(NAME) \
22185 (strncmp ("_vt.", name, strlen ("_vt.")) == 0 \
22186 || strncmp ("_ZTV", name, strlen ("_ZTV")) == 0 \
22187 || strncmp ("_ZTT", name, strlen ("_ZTT")) == 0 \
22188 || strncmp ("_ZTI", name, strlen ("_ZTI")) == 0 \
22189 || strncmp ("_ZTC", name, strlen ("_ZTC")) == 0)
22191 #ifdef NO_DOLLAR_IN_LABEL
22192 /* Return a GGC-allocated character string translating dollar signs in
22193 input NAME to underscores. Used by XCOFF ASM_OUTPUT_LABELREF. */
22195 const char *
22196 rs6000_xcoff_strip_dollar (const char *name)
22198 char *strip, *p;
22199 int len;
22201 p = strchr (name, '$');
22203 if (p == 0 || p == name)
22204 return name;
22206 len = strlen (name);
22207 strip = (char *) alloca (len + 1);
22208 strcpy (strip, name);
22209 p = strchr (strip, '$');
22210 while (p)
22212 *p = '_';
22213 p = strchr (p + 1, '$');
22216 return ggc_alloc_string (strip, len);
22218 #endif
22220 void
22221 rs6000_output_symbol_ref (FILE *file, rtx x)
22223 /* Currently C++ toc references to vtables can be emitted before it
22224 is decided whether the vtable is public or private. If this is
22225 the case, then the linker will eventually complain that there is
22226 a reference to an unknown section. Thus, for vtables only,
22227 we emit the TOC reference to reference the symbol and not the
22228 section. */
22229 const char *name = XSTR (x, 0);
22231 if (VTABLE_NAME_P (name))
22233 RS6000_OUTPUT_BASENAME (file, name);
22235 else
22236 assemble_name (file, name);
22239 /* Output a TOC entry. We derive the entry name from what is being
22240 written. */
22242 void
22243 output_toc (FILE *file, rtx x, int labelno, enum machine_mode mode)
22245 char buf[256];
22246 const char *name = buf;
22247 rtx base = x;
22248 HOST_WIDE_INT offset = 0;
22250 gcc_assert (!TARGET_NO_TOC);
22252 /* When the linker won't eliminate them, don't output duplicate
22253 TOC entries (this happens on AIX if there is any kind of TOC,
22254 and on SVR4 under -fPIC or -mrelocatable). Don't do this for
22255 CODE_LABELs. */
22256 if (TARGET_TOC && GET_CODE (x) != LABEL_REF)
22258 struct toc_hash_struct *h;
22259 void * * found;
22261 /* Create toc_hash_table. This can't be done at TARGET_OPTION_OVERRIDE
22262 time because GGC is not initialized at that point. */
22263 if (toc_hash_table == NULL)
22264 toc_hash_table = htab_create_ggc (1021, toc_hash_function,
22265 toc_hash_eq, NULL);
22267 h = ggc_alloc_toc_hash_struct ();
22268 h->key = x;
22269 h->key_mode = mode;
22270 h->labelno = labelno;
22272 found = htab_find_slot (toc_hash_table, h, INSERT);
22273 if (*found == NULL)
22274 *found = h;
22275 else /* This is indeed a duplicate.
22276 Set this label equal to that label. */
22278 fputs ("\t.set ", file);
22279 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
22280 fprintf (file, "%d,", labelno);
22281 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
22282 fprintf (file, "%d\n", ((*(const struct toc_hash_struct **)
22283 found)->labelno));
22284 return;
22288 /* If we're going to put a double constant in the TOC, make sure it's
22289 aligned properly when strict alignment is on. */
22290 if (GET_CODE (x) == CONST_DOUBLE
22291 && STRICT_ALIGNMENT
22292 && GET_MODE_BITSIZE (mode) >= 64
22293 && ! (TARGET_NO_FP_IN_TOC && ! TARGET_MINIMAL_TOC)) {
22294 ASM_OUTPUT_ALIGN (file, 3);
22297 (*targetm.asm_out.internal_label) (file, "LC", labelno);
22299 /* Handle FP constants specially. Note that if we have a minimal
22300 TOC, things we put here aren't actually in the TOC, so we can allow
22301 FP constants. */
22302 if (GET_CODE (x) == CONST_DOUBLE &&
22303 (GET_MODE (x) == TFmode || GET_MODE (x) == TDmode))
22305 REAL_VALUE_TYPE rv;
22306 long k[4];
22308 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
22309 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
22310 REAL_VALUE_TO_TARGET_DECIMAL128 (rv, k);
22311 else
22312 REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv, k);
22314 if (TARGET_64BIT)
22316 if (TARGET_MINIMAL_TOC)
22317 fputs (DOUBLE_INT_ASM_OP, file);
22318 else
22319 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
22320 k[0] & 0xffffffff, k[1] & 0xffffffff,
22321 k[2] & 0xffffffff, k[3] & 0xffffffff);
22322 fprintf (file, "0x%lx%08lx,0x%lx%08lx\n",
22323 k[0] & 0xffffffff, k[1] & 0xffffffff,
22324 k[2] & 0xffffffff, k[3] & 0xffffffff);
22325 return;
22327 else
22329 if (TARGET_MINIMAL_TOC)
22330 fputs ("\t.long ", file);
22331 else
22332 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
22333 k[0] & 0xffffffff, k[1] & 0xffffffff,
22334 k[2] & 0xffffffff, k[3] & 0xffffffff);
22335 fprintf (file, "0x%lx,0x%lx,0x%lx,0x%lx\n",
22336 k[0] & 0xffffffff, k[1] & 0xffffffff,
22337 k[2] & 0xffffffff, k[3] & 0xffffffff);
22338 return;
22341 else if (GET_CODE (x) == CONST_DOUBLE &&
22342 (GET_MODE (x) == DFmode || GET_MODE (x) == DDmode))
22344 REAL_VALUE_TYPE rv;
22345 long k[2];
22347 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
22349 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
22350 REAL_VALUE_TO_TARGET_DECIMAL64 (rv, k);
22351 else
22352 REAL_VALUE_TO_TARGET_DOUBLE (rv, k);
22354 if (TARGET_64BIT)
22356 if (TARGET_MINIMAL_TOC)
22357 fputs (DOUBLE_INT_ASM_OP, file);
22358 else
22359 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
22360 k[0] & 0xffffffff, k[1] & 0xffffffff);
22361 fprintf (file, "0x%lx%08lx\n",
22362 k[0] & 0xffffffff, k[1] & 0xffffffff);
22363 return;
22365 else
22367 if (TARGET_MINIMAL_TOC)
22368 fputs ("\t.long ", file);
22369 else
22370 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
22371 k[0] & 0xffffffff, k[1] & 0xffffffff);
22372 fprintf (file, "0x%lx,0x%lx\n",
22373 k[0] & 0xffffffff, k[1] & 0xffffffff);
22374 return;
22377 else if (GET_CODE (x) == CONST_DOUBLE &&
22378 (GET_MODE (x) == SFmode || GET_MODE (x) == SDmode))
22380 REAL_VALUE_TYPE rv;
22381 long l;
22383 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
22384 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
22385 REAL_VALUE_TO_TARGET_DECIMAL32 (rv, l);
22386 else
22387 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
22389 if (TARGET_64BIT)
22391 if (TARGET_MINIMAL_TOC)
22392 fputs (DOUBLE_INT_ASM_OP, file);
22393 else
22394 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
22395 fprintf (file, "0x%lx00000000\n", l & 0xffffffff);
22396 return;
22398 else
22400 if (TARGET_MINIMAL_TOC)
22401 fputs ("\t.long ", file);
22402 else
22403 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
22404 fprintf (file, "0x%lx\n", l & 0xffffffff);
22405 return;
22408 else if (GET_MODE (x) == VOIDmode
22409 && (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE))
22411 unsigned HOST_WIDE_INT low;
22412 HOST_WIDE_INT high;
22414 if (GET_CODE (x) == CONST_DOUBLE)
22416 low = CONST_DOUBLE_LOW (x);
22417 high = CONST_DOUBLE_HIGH (x);
22419 else
22420 #if HOST_BITS_PER_WIDE_INT == 32
22422 low = INTVAL (x);
22423 high = (low & 0x80000000) ? ~0 : 0;
22425 #else
22427 low = INTVAL (x) & 0xffffffff;
22428 high = (HOST_WIDE_INT) INTVAL (x) >> 32;
22430 #endif
22432 /* TOC entries are always Pmode-sized, but since this
22433 is a bigendian machine then if we're putting smaller
22434 integer constants in the TOC we have to pad them.
22435 (This is still a win over putting the constants in
22436 a separate constant pool, because then we'd have
22437 to have both a TOC entry _and_ the actual constant.)
22439 For a 32-bit target, CONST_INT values are loaded and shifted
22440 entirely within `low' and can be stored in one TOC entry. */
22442 /* It would be easy to make this work, but it doesn't now. */
22443 gcc_assert (!TARGET_64BIT || POINTER_SIZE >= GET_MODE_BITSIZE (mode));
22445 if (POINTER_SIZE > GET_MODE_BITSIZE (mode))
22447 #if HOST_BITS_PER_WIDE_INT == 32
22448 lshift_double (low, high, POINTER_SIZE - GET_MODE_BITSIZE (mode),
22449 POINTER_SIZE, &low, &high, 0);
22450 #else
22451 low |= high << 32;
22452 low <<= POINTER_SIZE - GET_MODE_BITSIZE (mode);
22453 high = (HOST_WIDE_INT) low >> 32;
22454 low &= 0xffffffff;
22455 #endif
22458 if (TARGET_64BIT)
22460 if (TARGET_MINIMAL_TOC)
22461 fputs (DOUBLE_INT_ASM_OP, file);
22462 else
22463 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
22464 (long) high & 0xffffffff, (long) low & 0xffffffff);
22465 fprintf (file, "0x%lx%08lx\n",
22466 (long) high & 0xffffffff, (long) low & 0xffffffff);
22467 return;
22469 else
22471 if (POINTER_SIZE < GET_MODE_BITSIZE (mode))
22473 if (TARGET_MINIMAL_TOC)
22474 fputs ("\t.long ", file);
22475 else
22476 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
22477 (long) high & 0xffffffff, (long) low & 0xffffffff);
22478 fprintf (file, "0x%lx,0x%lx\n",
22479 (long) high & 0xffffffff, (long) low & 0xffffffff);
22481 else
22483 if (TARGET_MINIMAL_TOC)
22484 fputs ("\t.long ", file);
22485 else
22486 fprintf (file, "\t.tc IS_%lx[TC],", (long) low & 0xffffffff);
22487 fprintf (file, "0x%lx\n", (long) low & 0xffffffff);
22489 return;
22493 if (GET_CODE (x) == CONST)
22495 gcc_assert (GET_CODE (XEXP (x, 0)) == PLUS
22496 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT);
22498 base = XEXP (XEXP (x, 0), 0);
22499 offset = INTVAL (XEXP (XEXP (x, 0), 1));
22502 switch (GET_CODE (base))
22504 case SYMBOL_REF:
22505 name = XSTR (base, 0);
22506 break;
22508 case LABEL_REF:
22509 ASM_GENERATE_INTERNAL_LABEL (buf, "L",
22510 CODE_LABEL_NUMBER (XEXP (base, 0)));
22511 break;
22513 case CODE_LABEL:
22514 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (base));
22515 break;
22517 default:
22518 gcc_unreachable ();
22521 if (TARGET_MINIMAL_TOC)
22522 fputs (TARGET_32BIT ? "\t.long " : DOUBLE_INT_ASM_OP, file);
22523 else
22525 fputs ("\t.tc ", file);
22526 RS6000_OUTPUT_BASENAME (file, name);
22528 if (offset < 0)
22529 fprintf (file, ".N" HOST_WIDE_INT_PRINT_UNSIGNED, - offset);
22530 else if (offset)
22531 fprintf (file, ".P" HOST_WIDE_INT_PRINT_UNSIGNED, offset);
22533 fputs ("[TC],", file);
22536 /* Currently C++ toc references to vtables can be emitted before it
22537 is decided whether the vtable is public or private. If this is
22538 the case, then the linker will eventually complain that there is
22539 a TOC reference to an unknown section. Thus, for vtables only,
22540 we emit the TOC reference to reference the symbol and not the
22541 section. */
22542 if (VTABLE_NAME_P (name))
22544 RS6000_OUTPUT_BASENAME (file, name);
22545 if (offset < 0)
22546 fprintf (file, HOST_WIDE_INT_PRINT_DEC, offset);
22547 else if (offset > 0)
22548 fprintf (file, "+" HOST_WIDE_INT_PRINT_DEC, offset);
22550 else
22551 output_addr_const (file, x);
22552 putc ('\n', file);
22555 /* Output an assembler pseudo-op to write an ASCII string of N characters
22556 starting at P to FILE.
22558 On the RS/6000, we have to do this using the .byte operation and
22559 write out special characters outside the quoted string.
22560 Also, the assembler is broken; very long strings are truncated,
22561 so we must artificially break them up early. */
22563 void
22564 output_ascii (FILE *file, const char *p, int n)
22566 char c;
22567 int i, count_string;
22568 const char *for_string = "\t.byte \"";
22569 const char *for_decimal = "\t.byte ";
22570 const char *to_close = NULL;
22572 count_string = 0;
22573 for (i = 0; i < n; i++)
22575 c = *p++;
22576 if (c >= ' ' && c < 0177)
22578 if (for_string)
22579 fputs (for_string, file);
22580 putc (c, file);
22582 /* Write two quotes to get one. */
22583 if (c == '"')
22585 putc (c, file);
22586 ++count_string;
22589 for_string = NULL;
22590 for_decimal = "\"\n\t.byte ";
22591 to_close = "\"\n";
22592 ++count_string;
22594 if (count_string >= 512)
22596 fputs (to_close, file);
22598 for_string = "\t.byte \"";
22599 for_decimal = "\t.byte ";
22600 to_close = NULL;
22601 count_string = 0;
22604 else
22606 if (for_decimal)
22607 fputs (for_decimal, file);
22608 fprintf (file, "%d", c);
22610 for_string = "\n\t.byte \"";
22611 for_decimal = ", ";
22612 to_close = "\n";
22613 count_string = 0;
22617 /* Now close the string if we have written one. Then end the line. */
22618 if (to_close)
22619 fputs (to_close, file);
22622 /* Generate a unique section name for FILENAME for a section type
22623 represented by SECTION_DESC. Output goes into BUF.
22625 SECTION_DESC can be any string, as long as it is different for each
22626 possible section type.
22628 We name the section in the same manner as xlc. The name begins with an
22629 underscore followed by the filename (after stripping any leading directory
22630 names) with the last period replaced by the string SECTION_DESC. If
22631 FILENAME does not contain a period, SECTION_DESC is appended to the end of
22632 the name. */
22634 void
22635 rs6000_gen_section_name (char **buf, const char *filename,
22636 const char *section_desc)
22638 const char *q, *after_last_slash, *last_period = 0;
22639 char *p;
22640 int len;
22642 after_last_slash = filename;
22643 for (q = filename; *q; q++)
22645 if (*q == '/')
22646 after_last_slash = q + 1;
22647 else if (*q == '.')
22648 last_period = q;
22651 len = strlen (after_last_slash) + strlen (section_desc) + 2;
22652 *buf = (char *) xmalloc (len);
22654 p = *buf;
22655 *p++ = '_';
22657 for (q = after_last_slash; *q; q++)
22659 if (q == last_period)
22661 strcpy (p, section_desc);
22662 p += strlen (section_desc);
22663 break;
22666 else if (ISALNUM (*q))
22667 *p++ = *q;
22670 if (last_period == 0)
22671 strcpy (p, section_desc);
22672 else
22673 *p = '\0';
22676 /* Emit profile function. */
22678 void
22679 output_profile_hook (int labelno ATTRIBUTE_UNUSED)
22681 /* Non-standard profiling for kernels, which just saves LR then calls
22682 _mcount without worrying about arg saves. The idea is to change
22683 the function prologue as little as possible as it isn't easy to
22684 account for arg save/restore code added just for _mcount. */
22685 if (TARGET_PROFILE_KERNEL)
22686 return;
22688 if (DEFAULT_ABI == ABI_AIX)
22690 #ifndef NO_PROFILE_COUNTERS
22691 # define NO_PROFILE_COUNTERS 0
22692 #endif
22693 if (NO_PROFILE_COUNTERS)
22694 emit_library_call (init_one_libfunc (RS6000_MCOUNT),
22695 LCT_NORMAL, VOIDmode, 0);
22696 else
22698 char buf[30];
22699 const char *label_name;
22700 rtx fun;
22702 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
22703 label_name = (*targetm.strip_name_encoding) (ggc_strdup (buf));
22704 fun = gen_rtx_SYMBOL_REF (Pmode, label_name);
22706 emit_library_call (init_one_libfunc (RS6000_MCOUNT),
22707 LCT_NORMAL, VOIDmode, 1, fun, Pmode);
22710 else if (DEFAULT_ABI == ABI_DARWIN)
22712 const char *mcount_name = RS6000_MCOUNT;
22713 int caller_addr_regno = LR_REGNO;
22715 /* Be conservative and always set this, at least for now. */
22716 crtl->uses_pic_offset_table = 1;
22718 #if TARGET_MACHO
22719 /* For PIC code, set up a stub and collect the caller's address
22720 from r0, which is where the prologue puts it. */
22721 if (MACHOPIC_INDIRECT
22722 && crtl->uses_pic_offset_table)
22723 caller_addr_regno = 0;
22724 #endif
22725 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, mcount_name),
22726 LCT_NORMAL, VOIDmode, 1,
22727 gen_rtx_REG (Pmode, caller_addr_regno), Pmode);
22731 /* Write function profiler code. */
22733 void
22734 output_function_profiler (FILE *file, int labelno)
22736 char buf[100];
22738 switch (DEFAULT_ABI)
22740 default:
22741 gcc_unreachable ();
22743 case ABI_V4:
22744 if (!TARGET_32BIT)
22746 warning (0, "no profiling of 64-bit code for this ABI");
22747 return;
22749 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
22750 fprintf (file, "\tmflr %s\n", reg_names[0]);
22751 if (NO_PROFILE_COUNTERS)
22753 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
22754 reg_names[0], reg_names[1]);
22756 else if (TARGET_SECURE_PLT && flag_pic)
22758 asm_fprintf (file, "\tbcl 20,31,1f\n1:\n\t{st|stw} %s,4(%s)\n",
22759 reg_names[0], reg_names[1]);
22760 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
22761 asm_fprintf (file, "\t{cau|addis} %s,%s,",
22762 reg_names[12], reg_names[12]);
22763 assemble_name (file, buf);
22764 asm_fprintf (file, "-1b@ha\n\t{cal|la} %s,", reg_names[0]);
22765 assemble_name (file, buf);
22766 asm_fprintf (file, "-1b@l(%s)\n", reg_names[12]);
22768 else if (flag_pic == 1)
22770 fputs ("\tbl _GLOBAL_OFFSET_TABLE_@local-4\n", file);
22771 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
22772 reg_names[0], reg_names[1]);
22773 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
22774 asm_fprintf (file, "\t{l|lwz} %s,", reg_names[0]);
22775 assemble_name (file, buf);
22776 asm_fprintf (file, "@got(%s)\n", reg_names[12]);
22778 else if (flag_pic > 1)
22780 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
22781 reg_names[0], reg_names[1]);
22782 /* Now, we need to get the address of the label. */
22783 fputs ("\tbcl 20,31,1f\n\t.long ", file);
22784 assemble_name (file, buf);
22785 fputs ("-.\n1:", file);
22786 asm_fprintf (file, "\tmflr %s\n", reg_names[11]);
22787 asm_fprintf (file, "\t{l|lwz} %s,0(%s)\n",
22788 reg_names[0], reg_names[11]);
22789 asm_fprintf (file, "\t{cax|add} %s,%s,%s\n",
22790 reg_names[0], reg_names[0], reg_names[11]);
22792 else
22794 asm_fprintf (file, "\t{liu|lis} %s,", reg_names[12]);
22795 assemble_name (file, buf);
22796 fputs ("@ha\n", file);
22797 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
22798 reg_names[0], reg_names[1]);
22799 asm_fprintf (file, "\t{cal|la} %s,", reg_names[0]);
22800 assemble_name (file, buf);
22801 asm_fprintf (file, "@l(%s)\n", reg_names[12]);
22804 /* ABI_V4 saves the static chain reg with ASM_OUTPUT_REG_PUSH. */
22805 fprintf (file, "\tbl %s%s\n",
22806 RS6000_MCOUNT, flag_pic ? "@plt" : "");
22807 break;
22809 case ABI_AIX:
22810 case ABI_DARWIN:
22811 if (!TARGET_PROFILE_KERNEL)
22813 /* Don't do anything, done in output_profile_hook (). */
22815 else
22817 gcc_assert (!TARGET_32BIT);
22819 asm_fprintf (file, "\tmflr %s\n", reg_names[0]);
22820 asm_fprintf (file, "\tstd %s,16(%s)\n", reg_names[0], reg_names[1]);
22822 if (cfun->static_chain_decl != NULL)
22824 asm_fprintf (file, "\tstd %s,24(%s)\n",
22825 reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
22826 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
22827 asm_fprintf (file, "\tld %s,24(%s)\n",
22828 reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
22830 else
22831 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
22833 break;
22839 /* The following variable value is the last issued insn. */
22841 static rtx last_scheduled_insn;
22843 /* The following variable helps to balance issuing of load and
22844 store instructions */
22846 static int load_store_pendulum;
22848 /* Power4 load update and store update instructions are cracked into a
22849 load or store and an integer insn which are executed in the same cycle.
22850 Branches have their own dispatch slot which does not count against the
22851 GCC issue rate, but it changes the program flow so there are no other
22852 instructions to issue in this cycle. */
22854 static int
22855 rs6000_variable_issue_1 (rtx insn, int more)
22857 last_scheduled_insn = insn;
22858 if (GET_CODE (PATTERN (insn)) == USE
22859 || GET_CODE (PATTERN (insn)) == CLOBBER)
22861 cached_can_issue_more = more;
22862 return cached_can_issue_more;
22865 if (insn_terminates_group_p (insn, current_group))
22867 cached_can_issue_more = 0;
22868 return cached_can_issue_more;
22871 /* If no reservation, but reach here */
22872 if (recog_memoized (insn) < 0)
22873 return more;
22875 if (rs6000_sched_groups)
22877 if (is_microcoded_insn (insn))
22878 cached_can_issue_more = 0;
22879 else if (is_cracked_insn (insn))
22880 cached_can_issue_more = more > 2 ? more - 2 : 0;
22881 else
22882 cached_can_issue_more = more - 1;
22884 return cached_can_issue_more;
22887 if (rs6000_cpu_attr == CPU_CELL && is_nonpipeline_insn (insn))
22888 return 0;
22890 cached_can_issue_more = more - 1;
22891 return cached_can_issue_more;
22894 static int
22895 rs6000_variable_issue (FILE *stream, int verbose, rtx insn, int more)
22897 int r = rs6000_variable_issue_1 (insn, more);
22898 if (verbose)
22899 fprintf (stream, "// rs6000_variable_issue (more = %d) = %d\n", more, r);
22900 return r;
22903 /* Adjust the cost of a scheduling dependency. Return the new cost of
22904 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
22906 static int
22907 rs6000_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
22909 enum attr_type attr_type;
22911 if (! recog_memoized (insn))
22912 return 0;
22914 switch (REG_NOTE_KIND (link))
22916 case REG_DEP_TRUE:
22918 /* Data dependency; DEP_INSN writes a register that INSN reads
22919 some cycles later. */
22921 /* Separate a load from a narrower, dependent store. */
22922 if (rs6000_sched_groups
22923 && GET_CODE (PATTERN (insn)) == SET
22924 && GET_CODE (PATTERN (dep_insn)) == SET
22925 && GET_CODE (XEXP (PATTERN (insn), 1)) == MEM
22926 && GET_CODE (XEXP (PATTERN (dep_insn), 0)) == MEM
22927 && (GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (insn), 1)))
22928 > GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (dep_insn), 0)))))
22929 return cost + 14;
22931 attr_type = get_attr_type (insn);
22933 switch (attr_type)
22935 case TYPE_JMPREG:
22936 /* Tell the first scheduling pass about the latency between
22937 a mtctr and bctr (and mtlr and br/blr). The first
22938 scheduling pass will not know about this latency since
22939 the mtctr instruction, which has the latency associated
22940 to it, will be generated by reload. */
22941 return TARGET_POWER ? 5 : 4;
22942 case TYPE_BRANCH:
22943 /* Leave some extra cycles between a compare and its
22944 dependent branch, to inhibit expensive mispredicts. */
22945 if ((rs6000_cpu_attr == CPU_PPC603
22946 || rs6000_cpu_attr == CPU_PPC604
22947 || rs6000_cpu_attr == CPU_PPC604E
22948 || rs6000_cpu_attr == CPU_PPC620
22949 || rs6000_cpu_attr == CPU_PPC630
22950 || rs6000_cpu_attr == CPU_PPC750
22951 || rs6000_cpu_attr == CPU_PPC7400
22952 || rs6000_cpu_attr == CPU_PPC7450
22953 || rs6000_cpu_attr == CPU_POWER4
22954 || rs6000_cpu_attr == CPU_POWER5
22955 || rs6000_cpu_attr == CPU_POWER7
22956 || rs6000_cpu_attr == CPU_CELL)
22957 && recog_memoized (dep_insn)
22958 && (INSN_CODE (dep_insn) >= 0))
22960 switch (get_attr_type (dep_insn))
22962 case TYPE_CMP:
22963 case TYPE_COMPARE:
22964 case TYPE_DELAYED_COMPARE:
22965 case TYPE_IMUL_COMPARE:
22966 case TYPE_LMUL_COMPARE:
22967 case TYPE_FPCOMPARE:
22968 case TYPE_CR_LOGICAL:
22969 case TYPE_DELAYED_CR:
22970 return cost + 2;
22971 default:
22972 break;
22974 break;
22976 case TYPE_STORE:
22977 case TYPE_STORE_U:
22978 case TYPE_STORE_UX:
22979 case TYPE_FPSTORE:
22980 case TYPE_FPSTORE_U:
22981 case TYPE_FPSTORE_UX:
22982 if ((rs6000_cpu == PROCESSOR_POWER6)
22983 && recog_memoized (dep_insn)
22984 && (INSN_CODE (dep_insn) >= 0))
22987 if (GET_CODE (PATTERN (insn)) != SET)
22988 /* If this happens, we have to extend this to schedule
22989 optimally. Return default for now. */
22990 return cost;
22992 /* Adjust the cost for the case where the value written
22993 by a fixed point operation is used as the address
22994 gen value on a store. */
22995 switch (get_attr_type (dep_insn))
22997 case TYPE_LOAD:
22998 case TYPE_LOAD_U:
22999 case TYPE_LOAD_UX:
23000 case TYPE_CNTLZ:
23002 if (! store_data_bypass_p (dep_insn, insn))
23003 return 4;
23004 break;
23006 case TYPE_LOAD_EXT:
23007 case TYPE_LOAD_EXT_U:
23008 case TYPE_LOAD_EXT_UX:
23009 case TYPE_VAR_SHIFT_ROTATE:
23010 case TYPE_VAR_DELAYED_COMPARE:
23012 if (! store_data_bypass_p (dep_insn, insn))
23013 return 6;
23014 break;
23016 case TYPE_INTEGER:
23017 case TYPE_COMPARE:
23018 case TYPE_FAST_COMPARE:
23019 case TYPE_EXTS:
23020 case TYPE_SHIFT:
23021 case TYPE_INSERT_WORD:
23022 case TYPE_INSERT_DWORD:
23023 case TYPE_FPLOAD_U:
23024 case TYPE_FPLOAD_UX:
23025 case TYPE_STORE_U:
23026 case TYPE_STORE_UX:
23027 case TYPE_FPSTORE_U:
23028 case TYPE_FPSTORE_UX:
23030 if (! store_data_bypass_p (dep_insn, insn))
23031 return 3;
23032 break;
23034 case TYPE_IMUL:
23035 case TYPE_IMUL2:
23036 case TYPE_IMUL3:
23037 case TYPE_LMUL:
23038 case TYPE_IMUL_COMPARE:
23039 case TYPE_LMUL_COMPARE:
23041 if (! store_data_bypass_p (dep_insn, insn))
23042 return 17;
23043 break;
23045 case TYPE_IDIV:
23047 if (! store_data_bypass_p (dep_insn, insn))
23048 return 45;
23049 break;
23051 case TYPE_LDIV:
23053 if (! store_data_bypass_p (dep_insn, insn))
23054 return 57;
23055 break;
23057 default:
23058 break;
23061 break;
23063 case TYPE_LOAD:
23064 case TYPE_LOAD_U:
23065 case TYPE_LOAD_UX:
23066 case TYPE_LOAD_EXT:
23067 case TYPE_LOAD_EXT_U:
23068 case TYPE_LOAD_EXT_UX:
23069 if ((rs6000_cpu == PROCESSOR_POWER6)
23070 && recog_memoized (dep_insn)
23071 && (INSN_CODE (dep_insn) >= 0))
23074 /* Adjust the cost for the case where the value written
23075 by a fixed point instruction is used within the address
23076 gen portion of a subsequent load(u)(x) */
23077 switch (get_attr_type (dep_insn))
23079 case TYPE_LOAD:
23080 case TYPE_LOAD_U:
23081 case TYPE_LOAD_UX:
23082 case TYPE_CNTLZ:
23084 if (set_to_load_agen (dep_insn, insn))
23085 return 4;
23086 break;
23088 case TYPE_LOAD_EXT:
23089 case TYPE_LOAD_EXT_U:
23090 case TYPE_LOAD_EXT_UX:
23091 case TYPE_VAR_SHIFT_ROTATE:
23092 case TYPE_VAR_DELAYED_COMPARE:
23094 if (set_to_load_agen (dep_insn, insn))
23095 return 6;
23096 break;
23098 case TYPE_INTEGER:
23099 case TYPE_COMPARE:
23100 case TYPE_FAST_COMPARE:
23101 case TYPE_EXTS:
23102 case TYPE_SHIFT:
23103 case TYPE_INSERT_WORD:
23104 case TYPE_INSERT_DWORD:
23105 case TYPE_FPLOAD_U:
23106 case TYPE_FPLOAD_UX:
23107 case TYPE_STORE_U:
23108 case TYPE_STORE_UX:
23109 case TYPE_FPSTORE_U:
23110 case TYPE_FPSTORE_UX:
23112 if (set_to_load_agen (dep_insn, insn))
23113 return 3;
23114 break;
23116 case TYPE_IMUL:
23117 case TYPE_IMUL2:
23118 case TYPE_IMUL3:
23119 case TYPE_LMUL:
23120 case TYPE_IMUL_COMPARE:
23121 case TYPE_LMUL_COMPARE:
23123 if (set_to_load_agen (dep_insn, insn))
23124 return 17;
23125 break;
23127 case TYPE_IDIV:
23129 if (set_to_load_agen (dep_insn, insn))
23130 return 45;
23131 break;
23133 case TYPE_LDIV:
23135 if (set_to_load_agen (dep_insn, insn))
23136 return 57;
23137 break;
23139 default:
23140 break;
23143 break;
23145 case TYPE_FPLOAD:
23146 if ((rs6000_cpu == PROCESSOR_POWER6)
23147 && recog_memoized (dep_insn)
23148 && (INSN_CODE (dep_insn) >= 0)
23149 && (get_attr_type (dep_insn) == TYPE_MFFGPR))
23150 return 2;
23152 default:
23153 break;
23156 /* Fall out to return default cost. */
23158 break;
23160 case REG_DEP_OUTPUT:
23161 /* Output dependency; DEP_INSN writes a register that INSN writes some
23162 cycles later. */
23163 if ((rs6000_cpu == PROCESSOR_POWER6)
23164 && recog_memoized (dep_insn)
23165 && (INSN_CODE (dep_insn) >= 0))
23167 attr_type = get_attr_type (insn);
23169 switch (attr_type)
23171 case TYPE_FP:
23172 if (get_attr_type (dep_insn) == TYPE_FP)
23173 return 1;
23174 break;
23175 case TYPE_FPLOAD:
23176 if (get_attr_type (dep_insn) == TYPE_MFFGPR)
23177 return 2;
23178 break;
23179 default:
23180 break;
23183 case REG_DEP_ANTI:
23184 /* Anti dependency; DEP_INSN reads a register that INSN writes some
23185 cycles later. */
23186 return 0;
23188 default:
23189 gcc_unreachable ();
23192 return cost;
23195 /* Debug version of rs6000_adjust_cost. */
23197 static int
23198 rs6000_debug_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
23200 int ret = rs6000_adjust_cost (insn, link, dep_insn, cost);
23202 if (ret != cost)
23204 const char *dep;
23206 switch (REG_NOTE_KIND (link))
23208 default: dep = "unknown depencency"; break;
23209 case REG_DEP_TRUE: dep = "data dependency"; break;
23210 case REG_DEP_OUTPUT: dep = "output dependency"; break;
23211 case REG_DEP_ANTI: dep = "anti depencency"; break;
23214 fprintf (stderr,
23215 "\nrs6000_adjust_cost, final cost = %d, orig cost = %d, "
23216 "%s, insn:\n", ret, cost, dep);
23218 debug_rtx (insn);
23221 return ret;
23224 /* The function returns a true if INSN is microcoded.
23225 Return false otherwise. */
23227 static bool
23228 is_microcoded_insn (rtx insn)
23230 if (!insn || !NONDEBUG_INSN_P (insn)
23231 || GET_CODE (PATTERN (insn)) == USE
23232 || GET_CODE (PATTERN (insn)) == CLOBBER)
23233 return false;
23235 if (rs6000_cpu_attr == CPU_CELL)
23236 return get_attr_cell_micro (insn) == CELL_MICRO_ALWAYS;
23238 if (rs6000_sched_groups)
23240 enum attr_type type = get_attr_type (insn);
23241 if (type == TYPE_LOAD_EXT_U
23242 || type == TYPE_LOAD_EXT_UX
23243 || type == TYPE_LOAD_UX
23244 || type == TYPE_STORE_UX
23245 || type == TYPE_MFCR)
23246 return true;
23249 return false;
23252 /* The function returns true if INSN is cracked into 2 instructions
23253 by the processor (and therefore occupies 2 issue slots). */
23255 static bool
23256 is_cracked_insn (rtx insn)
23258 if (!insn || !NONDEBUG_INSN_P (insn)
23259 || GET_CODE (PATTERN (insn)) == USE
23260 || GET_CODE (PATTERN (insn)) == CLOBBER)
23261 return false;
23263 if (rs6000_sched_groups)
23265 enum attr_type type = get_attr_type (insn);
23266 if (type == TYPE_LOAD_U || type == TYPE_STORE_U
23267 || type == TYPE_FPLOAD_U || type == TYPE_FPSTORE_U
23268 || type == TYPE_FPLOAD_UX || type == TYPE_FPSTORE_UX
23269 || type == TYPE_LOAD_EXT || type == TYPE_DELAYED_CR
23270 || type == TYPE_COMPARE || type == TYPE_DELAYED_COMPARE
23271 || type == TYPE_IMUL_COMPARE || type == TYPE_LMUL_COMPARE
23272 || type == TYPE_IDIV || type == TYPE_LDIV
23273 || type == TYPE_INSERT_WORD)
23274 return true;
23277 return false;
23280 /* The function returns true if INSN can be issued only from
23281 the branch slot. */
23283 static bool
23284 is_branch_slot_insn (rtx insn)
23286 if (!insn || !NONDEBUG_INSN_P (insn)
23287 || GET_CODE (PATTERN (insn)) == USE
23288 || GET_CODE (PATTERN (insn)) == CLOBBER)
23289 return false;
23291 if (rs6000_sched_groups)
23293 enum attr_type type = get_attr_type (insn);
23294 if (type == TYPE_BRANCH || type == TYPE_JMPREG)
23295 return true;
23296 return false;
23299 return false;
23302 /* The function returns true if out_inst sets a value that is
23303 used in the address generation computation of in_insn */
23304 static bool
23305 set_to_load_agen (rtx out_insn, rtx in_insn)
23307 rtx out_set, in_set;
23309 /* For performance reasons, only handle the simple case where
23310 both loads are a single_set. */
23311 out_set = single_set (out_insn);
23312 if (out_set)
23314 in_set = single_set (in_insn);
23315 if (in_set)
23316 return reg_mentioned_p (SET_DEST (out_set), SET_SRC (in_set));
23319 return false;
23322 /* The function returns true if the target storage location of
23323 out_insn is adjacent to the target storage location of in_insn */
23324 /* Return 1 if memory locations are adjacent. */
23326 static bool
23327 adjacent_mem_locations (rtx insn1, rtx insn2)
23330 rtx a = get_store_dest (PATTERN (insn1));
23331 rtx b = get_store_dest (PATTERN (insn2));
23333 if ((GET_CODE (XEXP (a, 0)) == REG
23334 || (GET_CODE (XEXP (a, 0)) == PLUS
23335 && GET_CODE (XEXP (XEXP (a, 0), 1)) == CONST_INT))
23336 && (GET_CODE (XEXP (b, 0)) == REG
23337 || (GET_CODE (XEXP (b, 0)) == PLUS
23338 && GET_CODE (XEXP (XEXP (b, 0), 1)) == CONST_INT)))
23340 HOST_WIDE_INT val0 = 0, val1 = 0, val_diff;
23341 rtx reg0, reg1;
23343 if (GET_CODE (XEXP (a, 0)) == PLUS)
23345 reg0 = XEXP (XEXP (a, 0), 0);
23346 val0 = INTVAL (XEXP (XEXP (a, 0), 1));
23348 else
23349 reg0 = XEXP (a, 0);
23351 if (GET_CODE (XEXP (b, 0)) == PLUS)
23353 reg1 = XEXP (XEXP (b, 0), 0);
23354 val1 = INTVAL (XEXP (XEXP (b, 0), 1));
23356 else
23357 reg1 = XEXP (b, 0);
23359 val_diff = val1 - val0;
23361 return ((REGNO (reg0) == REGNO (reg1))
23362 && ((MEM_SIZE (a) && val_diff == INTVAL (MEM_SIZE (a)))
23363 || (MEM_SIZE (b) && val_diff == -INTVAL (MEM_SIZE (b)))));
23366 return false;
23369 /* A C statement (sans semicolon) to update the integer scheduling
23370 priority INSN_PRIORITY (INSN). Increase the priority to execute the
23371 INSN earlier, reduce the priority to execute INSN later. Do not
23372 define this macro if you do not need to adjust the scheduling
23373 priorities of insns. */
23375 static int
23376 rs6000_adjust_priority (rtx insn ATTRIBUTE_UNUSED, int priority)
23378 /* On machines (like the 750) which have asymmetric integer units,
23379 where one integer unit can do multiply and divides and the other
23380 can't, reduce the priority of multiply/divide so it is scheduled
23381 before other integer operations. */
23383 #if 0
23384 if (! INSN_P (insn))
23385 return priority;
23387 if (GET_CODE (PATTERN (insn)) == USE)
23388 return priority;
23390 switch (rs6000_cpu_attr) {
23391 case CPU_PPC750:
23392 switch (get_attr_type (insn))
23394 default:
23395 break;
23397 case TYPE_IMUL:
23398 case TYPE_IDIV:
23399 fprintf (stderr, "priority was %#x (%d) before adjustment\n",
23400 priority, priority);
23401 if (priority >= 0 && priority < 0x01000000)
23402 priority >>= 3;
23403 break;
23406 #endif
23408 if (insn_must_be_first_in_group (insn)
23409 && reload_completed
23410 && current_sched_info->sched_max_insns_priority
23411 && rs6000_sched_restricted_insns_priority)
23414 /* Prioritize insns that can be dispatched only in the first
23415 dispatch slot. */
23416 if (rs6000_sched_restricted_insns_priority == 1)
23417 /* Attach highest priority to insn. This means that in
23418 haifa-sched.c:ready_sort(), dispatch-slot restriction considerations
23419 precede 'priority' (critical path) considerations. */
23420 return current_sched_info->sched_max_insns_priority;
23421 else if (rs6000_sched_restricted_insns_priority == 2)
23422 /* Increase priority of insn by a minimal amount. This means that in
23423 haifa-sched.c:ready_sort(), only 'priority' (critical path)
23424 considerations precede dispatch-slot restriction considerations. */
23425 return (priority + 1);
23428 if (rs6000_cpu == PROCESSOR_POWER6
23429 && ((load_store_pendulum == -2 && is_load_insn (insn))
23430 || (load_store_pendulum == 2 && is_store_insn (insn))))
23431 /* Attach highest priority to insn if the scheduler has just issued two
23432 stores and this instruction is a load, or two loads and this instruction
23433 is a store. Power6 wants loads and stores scheduled alternately
23434 when possible */
23435 return current_sched_info->sched_max_insns_priority;
23437 return priority;
23440 /* Return true if the instruction is nonpipelined on the Cell. */
23441 static bool
23442 is_nonpipeline_insn (rtx insn)
23444 enum attr_type type;
23445 if (!insn || !NONDEBUG_INSN_P (insn)
23446 || GET_CODE (PATTERN (insn)) == USE
23447 || GET_CODE (PATTERN (insn)) == CLOBBER)
23448 return false;
23450 type = get_attr_type (insn);
23451 if (type == TYPE_IMUL
23452 || type == TYPE_IMUL2
23453 || type == TYPE_IMUL3
23454 || type == TYPE_LMUL
23455 || type == TYPE_IDIV
23456 || type == TYPE_LDIV
23457 || type == TYPE_SDIV
23458 || type == TYPE_DDIV
23459 || type == TYPE_SSQRT
23460 || type == TYPE_DSQRT
23461 || type == TYPE_MFCR
23462 || type == TYPE_MFCRF
23463 || type == TYPE_MFJMPR)
23465 return true;
23467 return false;
23471 /* Return how many instructions the machine can issue per cycle. */
23473 static int
23474 rs6000_issue_rate (void)
23476 /* Unless scheduling for register pressure, use issue rate of 1 for
23477 first scheduling pass to decrease degradation. */
23478 if (!reload_completed && !flag_sched_pressure)
23479 return 1;
23481 switch (rs6000_cpu_attr) {
23482 case CPU_RIOS1: /* ? */
23483 case CPU_RS64A:
23484 case CPU_PPC601: /* ? */
23485 case CPU_PPC7450:
23486 return 3;
23487 case CPU_PPC440:
23488 case CPU_PPC603:
23489 case CPU_PPC750:
23490 case CPU_PPC7400:
23491 case CPU_PPC8540:
23492 case CPU_CELL:
23493 case CPU_PPCE300C2:
23494 case CPU_PPCE300C3:
23495 case CPU_PPCE500MC:
23496 case CPU_PPCE500MC64:
23497 case CPU_TITAN:
23498 return 2;
23499 case CPU_RIOS2:
23500 case CPU_PPC476:
23501 case CPU_PPC604:
23502 case CPU_PPC604E:
23503 case CPU_PPC620:
23504 case CPU_PPC630:
23505 return 4;
23506 case CPU_POWER4:
23507 case CPU_POWER5:
23508 case CPU_POWER6:
23509 case CPU_POWER7:
23510 return 5;
23511 default:
23512 return 1;
23516 /* Return how many instructions to look ahead for better insn
23517 scheduling. */
23519 static int
23520 rs6000_use_sched_lookahead (void)
23522 if (rs6000_cpu_attr == CPU_PPC8540)
23523 return 4;
23524 if (rs6000_cpu_attr == CPU_CELL)
23525 return (reload_completed ? 8 : 0);
23526 return 0;
23529 /* We are choosing insn from the ready queue. Return nonzero if INSN can be chosen. */
23530 static int
23531 rs6000_use_sched_lookahead_guard (rtx insn)
23533 if (rs6000_cpu_attr != CPU_CELL)
23534 return 1;
23536 if (insn == NULL_RTX || !INSN_P (insn))
23537 abort ();
23539 if (!reload_completed
23540 || is_nonpipeline_insn (insn)
23541 || is_microcoded_insn (insn))
23542 return 0;
23544 return 1;
23547 /* Determine is PAT refers to memory. */
23549 static bool
23550 is_mem_ref (rtx pat)
23552 const char * fmt;
23553 int i, j;
23554 bool ret = false;
23556 /* stack_tie does not produce any real memory traffic. */
23557 if (GET_CODE (pat) == UNSPEC
23558 && XINT (pat, 1) == UNSPEC_TIE)
23559 return false;
23561 if (GET_CODE (pat) == MEM)
23562 return true;
23564 /* Recursively process the pattern. */
23565 fmt = GET_RTX_FORMAT (GET_CODE (pat));
23567 for (i = GET_RTX_LENGTH (GET_CODE (pat)) - 1; i >= 0 && !ret; i--)
23569 if (fmt[i] == 'e')
23570 ret |= is_mem_ref (XEXP (pat, i));
23571 else if (fmt[i] == 'E')
23572 for (j = XVECLEN (pat, i) - 1; j >= 0; j--)
23573 ret |= is_mem_ref (XVECEXP (pat, i, j));
23576 return ret;
23579 /* Determine if PAT is a PATTERN of a load insn. */
23581 static bool
23582 is_load_insn1 (rtx pat)
23584 if (!pat || pat == NULL_RTX)
23585 return false;
23587 if (GET_CODE (pat) == SET)
23588 return is_mem_ref (SET_SRC (pat));
23590 if (GET_CODE (pat) == PARALLEL)
23592 int i;
23594 for (i = 0; i < XVECLEN (pat, 0); i++)
23595 if (is_load_insn1 (XVECEXP (pat, 0, i)))
23596 return true;
23599 return false;
23602 /* Determine if INSN loads from memory. */
23604 static bool
23605 is_load_insn (rtx insn)
23607 if (!insn || !INSN_P (insn))
23608 return false;
23610 if (GET_CODE (insn) == CALL_INSN)
23611 return false;
23613 return is_load_insn1 (PATTERN (insn));
23616 /* Determine if PAT is a PATTERN of a store insn. */
23618 static bool
23619 is_store_insn1 (rtx pat)
23621 if (!pat || pat == NULL_RTX)
23622 return false;
23624 if (GET_CODE (pat) == SET)
23625 return is_mem_ref (SET_DEST (pat));
23627 if (GET_CODE (pat) == PARALLEL)
23629 int i;
23631 for (i = 0; i < XVECLEN (pat, 0); i++)
23632 if (is_store_insn1 (XVECEXP (pat, 0, i)))
23633 return true;
23636 return false;
23639 /* Determine if INSN stores to memory. */
23641 static bool
23642 is_store_insn (rtx insn)
23644 if (!insn || !INSN_P (insn))
23645 return false;
23647 return is_store_insn1 (PATTERN (insn));
23650 /* Return the dest of a store insn. */
23652 static rtx
23653 get_store_dest (rtx pat)
23655 gcc_assert (is_store_insn1 (pat));
23657 if (GET_CODE (pat) == SET)
23658 return SET_DEST (pat);
23659 else if (GET_CODE (pat) == PARALLEL)
23661 int i;
23663 for (i = 0; i < XVECLEN (pat, 0); i++)
23665 rtx inner_pat = XVECEXP (pat, 0, i);
23666 if (GET_CODE (inner_pat) == SET
23667 && is_mem_ref (SET_DEST (inner_pat)))
23668 return inner_pat;
23671 /* We shouldn't get here, because we should have either a simple
23672 store insn or a store with update which are covered above. */
23673 gcc_unreachable();
23676 /* Returns whether the dependence between INSN and NEXT is considered
23677 costly by the given target. */
23679 static bool
23680 rs6000_is_costly_dependence (dep_t dep, int cost, int distance)
23682 rtx insn;
23683 rtx next;
23685 /* If the flag is not enabled - no dependence is considered costly;
23686 allow all dependent insns in the same group.
23687 This is the most aggressive option. */
23688 if (rs6000_sched_costly_dep == no_dep_costly)
23689 return false;
23691 /* If the flag is set to 1 - a dependence is always considered costly;
23692 do not allow dependent instructions in the same group.
23693 This is the most conservative option. */
23694 if (rs6000_sched_costly_dep == all_deps_costly)
23695 return true;
23697 insn = DEP_PRO (dep);
23698 next = DEP_CON (dep);
23700 if (rs6000_sched_costly_dep == store_to_load_dep_costly
23701 && is_load_insn (next)
23702 && is_store_insn (insn))
23703 /* Prevent load after store in the same group. */
23704 return true;
23706 if (rs6000_sched_costly_dep == true_store_to_load_dep_costly
23707 && is_load_insn (next)
23708 && is_store_insn (insn)
23709 && DEP_TYPE (dep) == REG_DEP_TRUE)
23710 /* Prevent load after store in the same group if it is a true
23711 dependence. */
23712 return true;
23714 /* The flag is set to X; dependences with latency >= X are considered costly,
23715 and will not be scheduled in the same group. */
23716 if (rs6000_sched_costly_dep <= max_dep_latency
23717 && ((cost - distance) >= (int)rs6000_sched_costly_dep))
23718 return true;
23720 return false;
23723 /* Return the next insn after INSN that is found before TAIL is reached,
23724 skipping any "non-active" insns - insns that will not actually occupy
23725 an issue slot. Return NULL_RTX if such an insn is not found. */
23727 static rtx
23728 get_next_active_insn (rtx insn, rtx tail)
23730 if (insn == NULL_RTX || insn == tail)
23731 return NULL_RTX;
23733 while (1)
23735 insn = NEXT_INSN (insn);
23736 if (insn == NULL_RTX || insn == tail)
23737 return NULL_RTX;
23739 if (CALL_P (insn)
23740 || JUMP_P (insn)
23741 || (NONJUMP_INSN_P (insn)
23742 && GET_CODE (PATTERN (insn)) != USE
23743 && GET_CODE (PATTERN (insn)) != CLOBBER
23744 && INSN_CODE (insn) != CODE_FOR_stack_tie))
23745 break;
23747 return insn;
23750 /* We are about to begin issuing insns for this clock cycle. */
23752 static int
23753 rs6000_sched_reorder (FILE *dump ATTRIBUTE_UNUSED, int sched_verbose,
23754 rtx *ready ATTRIBUTE_UNUSED,
23755 int *pn_ready ATTRIBUTE_UNUSED,
23756 int clock_var ATTRIBUTE_UNUSED)
23758 int n_ready = *pn_ready;
23760 if (sched_verbose)
23761 fprintf (dump, "// rs6000_sched_reorder :\n");
23763 /* Reorder the ready list, if the second to last ready insn
23764 is a nonepipeline insn. */
23765 if (rs6000_cpu_attr == CPU_CELL && n_ready > 1)
23767 if (is_nonpipeline_insn (ready[n_ready - 1])
23768 && (recog_memoized (ready[n_ready - 2]) > 0))
23769 /* Simply swap first two insns. */
23771 rtx tmp = ready[n_ready - 1];
23772 ready[n_ready - 1] = ready[n_ready - 2];
23773 ready[n_ready - 2] = tmp;
23777 if (rs6000_cpu == PROCESSOR_POWER6)
23778 load_store_pendulum = 0;
23780 return rs6000_issue_rate ();
23783 /* Like rs6000_sched_reorder, but called after issuing each insn. */
23785 static int
23786 rs6000_sched_reorder2 (FILE *dump, int sched_verbose, rtx *ready,
23787 int *pn_ready, int clock_var ATTRIBUTE_UNUSED)
23789 if (sched_verbose)
23790 fprintf (dump, "// rs6000_sched_reorder2 :\n");
23792 /* For Power6, we need to handle some special cases to try and keep the
23793 store queue from overflowing and triggering expensive flushes.
23795 This code monitors how load and store instructions are being issued
23796 and skews the ready list one way or the other to increase the likelihood
23797 that a desired instruction is issued at the proper time.
23799 A couple of things are done. First, we maintain a "load_store_pendulum"
23800 to track the current state of load/store issue.
23802 - If the pendulum is at zero, then no loads or stores have been
23803 issued in the current cycle so we do nothing.
23805 - If the pendulum is 1, then a single load has been issued in this
23806 cycle and we attempt to locate another load in the ready list to
23807 issue with it.
23809 - If the pendulum is -2, then two stores have already been
23810 issued in this cycle, so we increase the priority of the first load
23811 in the ready list to increase it's likelihood of being chosen first
23812 in the next cycle.
23814 - If the pendulum is -1, then a single store has been issued in this
23815 cycle and we attempt to locate another store in the ready list to
23816 issue with it, preferring a store to an adjacent memory location to
23817 facilitate store pairing in the store queue.
23819 - If the pendulum is 2, then two loads have already been
23820 issued in this cycle, so we increase the priority of the first store
23821 in the ready list to increase it's likelihood of being chosen first
23822 in the next cycle.
23824 - If the pendulum < -2 or > 2, then do nothing.
23826 Note: This code covers the most common scenarios. There exist non
23827 load/store instructions which make use of the LSU and which
23828 would need to be accounted for to strictly model the behavior
23829 of the machine. Those instructions are currently unaccounted
23830 for to help minimize compile time overhead of this code.
23832 if (rs6000_cpu == PROCESSOR_POWER6 && last_scheduled_insn)
23834 int pos;
23835 int i;
23836 rtx tmp;
23838 if (is_store_insn (last_scheduled_insn))
23839 /* Issuing a store, swing the load_store_pendulum to the left */
23840 load_store_pendulum--;
23841 else if (is_load_insn (last_scheduled_insn))
23842 /* Issuing a load, swing the load_store_pendulum to the right */
23843 load_store_pendulum++;
23844 else
23845 return cached_can_issue_more;
23847 /* If the pendulum is balanced, or there is only one instruction on
23848 the ready list, then all is well, so return. */
23849 if ((load_store_pendulum == 0) || (*pn_ready <= 1))
23850 return cached_can_issue_more;
23852 if (load_store_pendulum == 1)
23854 /* A load has been issued in this cycle. Scan the ready list
23855 for another load to issue with it */
23856 pos = *pn_ready-1;
23858 while (pos >= 0)
23860 if (is_load_insn (ready[pos]))
23862 /* Found a load. Move it to the head of the ready list,
23863 and adjust it's priority so that it is more likely to
23864 stay there */
23865 tmp = ready[pos];
23866 for (i=pos; i<*pn_ready-1; i++)
23867 ready[i] = ready[i + 1];
23868 ready[*pn_ready-1] = tmp;
23870 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
23871 INSN_PRIORITY (tmp)++;
23872 break;
23874 pos--;
23877 else if (load_store_pendulum == -2)
23879 /* Two stores have been issued in this cycle. Increase the
23880 priority of the first load in the ready list to favor it for
23881 issuing in the next cycle. */
23882 pos = *pn_ready-1;
23884 while (pos >= 0)
23886 if (is_load_insn (ready[pos])
23887 && !sel_sched_p ()
23888 && INSN_PRIORITY_KNOWN (ready[pos]))
23890 INSN_PRIORITY (ready[pos])++;
23892 /* Adjust the pendulum to account for the fact that a load
23893 was found and increased in priority. This is to prevent
23894 increasing the priority of multiple loads */
23895 load_store_pendulum--;
23897 break;
23899 pos--;
23902 else if (load_store_pendulum == -1)
23904 /* A store has been issued in this cycle. Scan the ready list for
23905 another store to issue with it, preferring a store to an adjacent
23906 memory location */
23907 int first_store_pos = -1;
23909 pos = *pn_ready-1;
23911 while (pos >= 0)
23913 if (is_store_insn (ready[pos]))
23915 /* Maintain the index of the first store found on the
23916 list */
23917 if (first_store_pos == -1)
23918 first_store_pos = pos;
23920 if (is_store_insn (last_scheduled_insn)
23921 && adjacent_mem_locations (last_scheduled_insn,ready[pos]))
23923 /* Found an adjacent store. Move it to the head of the
23924 ready list, and adjust it's priority so that it is
23925 more likely to stay there */
23926 tmp = ready[pos];
23927 for (i=pos; i<*pn_ready-1; i++)
23928 ready[i] = ready[i + 1];
23929 ready[*pn_ready-1] = tmp;
23931 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
23932 INSN_PRIORITY (tmp)++;
23934 first_store_pos = -1;
23936 break;
23939 pos--;
23942 if (first_store_pos >= 0)
23944 /* An adjacent store wasn't found, but a non-adjacent store was,
23945 so move the non-adjacent store to the front of the ready
23946 list, and adjust its priority so that it is more likely to
23947 stay there. */
23948 tmp = ready[first_store_pos];
23949 for (i=first_store_pos; i<*pn_ready-1; i++)
23950 ready[i] = ready[i + 1];
23951 ready[*pn_ready-1] = tmp;
23952 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
23953 INSN_PRIORITY (tmp)++;
23956 else if (load_store_pendulum == 2)
23958 /* Two loads have been issued in this cycle. Increase the priority
23959 of the first store in the ready list to favor it for issuing in
23960 the next cycle. */
23961 pos = *pn_ready-1;
23963 while (pos >= 0)
23965 if (is_store_insn (ready[pos])
23966 && !sel_sched_p ()
23967 && INSN_PRIORITY_KNOWN (ready[pos]))
23969 INSN_PRIORITY (ready[pos])++;
23971 /* Adjust the pendulum to account for the fact that a store
23972 was found and increased in priority. This is to prevent
23973 increasing the priority of multiple stores */
23974 load_store_pendulum++;
23976 break;
23978 pos--;
23983 return cached_can_issue_more;
23986 /* Return whether the presence of INSN causes a dispatch group termination
23987 of group WHICH_GROUP.
23989 If WHICH_GROUP == current_group, this function will return true if INSN
23990 causes the termination of the current group (i.e, the dispatch group to
23991 which INSN belongs). This means that INSN will be the last insn in the
23992 group it belongs to.
23994 If WHICH_GROUP == previous_group, this function will return true if INSN
23995 causes the termination of the previous group (i.e, the dispatch group that
23996 precedes the group to which INSN belongs). This means that INSN will be
23997 the first insn in the group it belongs to). */
23999 static bool
24000 insn_terminates_group_p (rtx insn, enum group_termination which_group)
24002 bool first, last;
24004 if (! insn)
24005 return false;
24007 first = insn_must_be_first_in_group (insn);
24008 last = insn_must_be_last_in_group (insn);
24010 if (first && last)
24011 return true;
24013 if (which_group == current_group)
24014 return last;
24015 else if (which_group == previous_group)
24016 return first;
24018 return false;
24022 static bool
24023 insn_must_be_first_in_group (rtx insn)
24025 enum attr_type type;
24027 if (!insn
24028 || GET_CODE (insn) == NOTE
24029 || DEBUG_INSN_P (insn)
24030 || GET_CODE (PATTERN (insn)) == USE
24031 || GET_CODE (PATTERN (insn)) == CLOBBER)
24032 return false;
24034 switch (rs6000_cpu)
24036 case PROCESSOR_POWER5:
24037 if (is_cracked_insn (insn))
24038 return true;
24039 case PROCESSOR_POWER4:
24040 if (is_microcoded_insn (insn))
24041 return true;
24043 if (!rs6000_sched_groups)
24044 return false;
24046 type = get_attr_type (insn);
24048 switch (type)
24050 case TYPE_MFCR:
24051 case TYPE_MFCRF:
24052 case TYPE_MTCR:
24053 case TYPE_DELAYED_CR:
24054 case TYPE_CR_LOGICAL:
24055 case TYPE_MTJMPR:
24056 case TYPE_MFJMPR:
24057 case TYPE_IDIV:
24058 case TYPE_LDIV:
24059 case TYPE_LOAD_L:
24060 case TYPE_STORE_C:
24061 case TYPE_ISYNC:
24062 case TYPE_SYNC:
24063 return true;
24064 default:
24065 break;
24067 break;
24068 case PROCESSOR_POWER6:
24069 type = get_attr_type (insn);
24071 switch (type)
24073 case TYPE_INSERT_DWORD:
24074 case TYPE_EXTS:
24075 case TYPE_CNTLZ:
24076 case TYPE_SHIFT:
24077 case TYPE_VAR_SHIFT_ROTATE:
24078 case TYPE_TRAP:
24079 case TYPE_IMUL:
24080 case TYPE_IMUL2:
24081 case TYPE_IMUL3:
24082 case TYPE_LMUL:
24083 case TYPE_IDIV:
24084 case TYPE_INSERT_WORD:
24085 case TYPE_DELAYED_COMPARE:
24086 case TYPE_IMUL_COMPARE:
24087 case TYPE_LMUL_COMPARE:
24088 case TYPE_FPCOMPARE:
24089 case TYPE_MFCR:
24090 case TYPE_MTCR:
24091 case TYPE_MFJMPR:
24092 case TYPE_MTJMPR:
24093 case TYPE_ISYNC:
24094 case TYPE_SYNC:
24095 case TYPE_LOAD_L:
24096 case TYPE_STORE_C:
24097 case TYPE_LOAD_U:
24098 case TYPE_LOAD_UX:
24099 case TYPE_LOAD_EXT_UX:
24100 case TYPE_STORE_U:
24101 case TYPE_STORE_UX:
24102 case TYPE_FPLOAD_U:
24103 case TYPE_FPLOAD_UX:
24104 case TYPE_FPSTORE_U:
24105 case TYPE_FPSTORE_UX:
24106 return true;
24107 default:
24108 break;
24110 break;
24111 case PROCESSOR_POWER7:
24112 type = get_attr_type (insn);
24114 switch (type)
24116 case TYPE_CR_LOGICAL:
24117 case TYPE_MFCR:
24118 case TYPE_MFCRF:
24119 case TYPE_MTCR:
24120 case TYPE_IDIV:
24121 case TYPE_LDIV:
24122 case TYPE_COMPARE:
24123 case TYPE_DELAYED_COMPARE:
24124 case TYPE_VAR_DELAYED_COMPARE:
24125 case TYPE_ISYNC:
24126 case TYPE_LOAD_L:
24127 case TYPE_STORE_C:
24128 case TYPE_LOAD_U:
24129 case TYPE_LOAD_UX:
24130 case TYPE_LOAD_EXT:
24131 case TYPE_LOAD_EXT_U:
24132 case TYPE_LOAD_EXT_UX:
24133 case TYPE_STORE_U:
24134 case TYPE_STORE_UX:
24135 case TYPE_FPLOAD_U:
24136 case TYPE_FPLOAD_UX:
24137 case TYPE_FPSTORE_U:
24138 case TYPE_FPSTORE_UX:
24139 case TYPE_MFJMPR:
24140 case TYPE_MTJMPR:
24141 return true;
24142 default:
24143 break;
24145 break;
24146 default:
24147 break;
24150 return false;
24153 static bool
24154 insn_must_be_last_in_group (rtx insn)
24156 enum attr_type type;
24158 if (!insn
24159 || GET_CODE (insn) == NOTE
24160 || DEBUG_INSN_P (insn)
24161 || GET_CODE (PATTERN (insn)) == USE
24162 || GET_CODE (PATTERN (insn)) == CLOBBER)
24163 return false;
24165 switch (rs6000_cpu) {
24166 case PROCESSOR_POWER4:
24167 case PROCESSOR_POWER5:
24168 if (is_microcoded_insn (insn))
24169 return true;
24171 if (is_branch_slot_insn (insn))
24172 return true;
24174 break;
24175 case PROCESSOR_POWER6:
24176 type = get_attr_type (insn);
24178 switch (type)
24180 case TYPE_EXTS:
24181 case TYPE_CNTLZ:
24182 case TYPE_SHIFT:
24183 case TYPE_VAR_SHIFT_ROTATE:
24184 case TYPE_TRAP:
24185 case TYPE_IMUL:
24186 case TYPE_IMUL2:
24187 case TYPE_IMUL3:
24188 case TYPE_LMUL:
24189 case TYPE_IDIV:
24190 case TYPE_DELAYED_COMPARE:
24191 case TYPE_IMUL_COMPARE:
24192 case TYPE_LMUL_COMPARE:
24193 case TYPE_FPCOMPARE:
24194 case TYPE_MFCR:
24195 case TYPE_MTCR:
24196 case TYPE_MFJMPR:
24197 case TYPE_MTJMPR:
24198 case TYPE_ISYNC:
24199 case TYPE_SYNC:
24200 case TYPE_LOAD_L:
24201 case TYPE_STORE_C:
24202 return true;
24203 default:
24204 break;
24206 break;
24207 case PROCESSOR_POWER7:
24208 type = get_attr_type (insn);
24210 switch (type)
24212 case TYPE_ISYNC:
24213 case TYPE_SYNC:
24214 case TYPE_LOAD_L:
24215 case TYPE_STORE_C:
24216 case TYPE_LOAD_EXT_U:
24217 case TYPE_LOAD_EXT_UX:
24218 case TYPE_STORE_UX:
24219 return true;
24220 default:
24221 break;
24223 break;
24224 default:
24225 break;
24228 return false;
24231 /* Return true if it is recommended to keep NEXT_INSN "far" (in a separate
24232 dispatch group) from the insns in GROUP_INSNS. Return false otherwise. */
24234 static bool
24235 is_costly_group (rtx *group_insns, rtx next_insn)
24237 int i;
24238 int issue_rate = rs6000_issue_rate ();
24240 for (i = 0; i < issue_rate; i++)
24242 sd_iterator_def sd_it;
24243 dep_t dep;
24244 rtx insn = group_insns[i];
24246 if (!insn)
24247 continue;
24249 FOR_EACH_DEP (insn, SD_LIST_FORW, sd_it, dep)
24251 rtx next = DEP_CON (dep);
24253 if (next == next_insn
24254 && rs6000_is_costly_dependence (dep, dep_cost (dep), 0))
24255 return true;
24259 return false;
24262 /* Utility of the function redefine_groups.
24263 Check if it is too costly to schedule NEXT_INSN together with GROUP_INSNS
24264 in the same dispatch group. If so, insert nops before NEXT_INSN, in order
24265 to keep it "far" (in a separate group) from GROUP_INSNS, following
24266 one of the following schemes, depending on the value of the flag
24267 -minsert_sched_nops = X:
24268 (1) X == sched_finish_regroup_exact: insert exactly as many nops as needed
24269 in order to force NEXT_INSN into a separate group.
24270 (2) X < sched_finish_regroup_exact: insert exactly X nops.
24271 GROUP_END, CAN_ISSUE_MORE and GROUP_COUNT record the state after nop
24272 insertion (has a group just ended, how many vacant issue slots remain in the
24273 last group, and how many dispatch groups were encountered so far). */
24275 static int
24276 force_new_group (int sched_verbose, FILE *dump, rtx *group_insns,
24277 rtx next_insn, bool *group_end, int can_issue_more,
24278 int *group_count)
24280 rtx nop;
24281 bool force;
24282 int issue_rate = rs6000_issue_rate ();
24283 bool end = *group_end;
24284 int i;
24286 if (next_insn == NULL_RTX || DEBUG_INSN_P (next_insn))
24287 return can_issue_more;
24289 if (rs6000_sched_insert_nops > sched_finish_regroup_exact)
24290 return can_issue_more;
24292 force = is_costly_group (group_insns, next_insn);
24293 if (!force)
24294 return can_issue_more;
24296 if (sched_verbose > 6)
24297 fprintf (dump,"force: group count = %d, can_issue_more = %d\n",
24298 *group_count ,can_issue_more);
24300 if (rs6000_sched_insert_nops == sched_finish_regroup_exact)
24302 if (*group_end)
24303 can_issue_more = 0;
24305 /* Since only a branch can be issued in the last issue_slot, it is
24306 sufficient to insert 'can_issue_more - 1' nops if next_insn is not
24307 a branch. If next_insn is a branch, we insert 'can_issue_more' nops;
24308 in this case the last nop will start a new group and the branch
24309 will be forced to the new group. */
24310 if (can_issue_more && !is_branch_slot_insn (next_insn))
24311 can_issue_more--;
24313 while (can_issue_more > 0)
24315 nop = gen_nop ();
24316 emit_insn_before (nop, next_insn);
24317 can_issue_more--;
24320 *group_end = true;
24321 return 0;
24324 if (rs6000_sched_insert_nops < sched_finish_regroup_exact)
24326 int n_nops = rs6000_sched_insert_nops;
24328 /* Nops can't be issued from the branch slot, so the effective
24329 issue_rate for nops is 'issue_rate - 1'. */
24330 if (can_issue_more == 0)
24331 can_issue_more = issue_rate;
24332 can_issue_more--;
24333 if (can_issue_more == 0)
24335 can_issue_more = issue_rate - 1;
24336 (*group_count)++;
24337 end = true;
24338 for (i = 0; i < issue_rate; i++)
24340 group_insns[i] = 0;
24344 while (n_nops > 0)
24346 nop = gen_nop ();
24347 emit_insn_before (nop, next_insn);
24348 if (can_issue_more == issue_rate - 1) /* new group begins */
24349 end = false;
24350 can_issue_more--;
24351 if (can_issue_more == 0)
24353 can_issue_more = issue_rate - 1;
24354 (*group_count)++;
24355 end = true;
24356 for (i = 0; i < issue_rate; i++)
24358 group_insns[i] = 0;
24361 n_nops--;
24364 /* Scale back relative to 'issue_rate' (instead of 'issue_rate - 1'). */
24365 can_issue_more++;
24367 /* Is next_insn going to start a new group? */
24368 *group_end
24369 = (end
24370 || (can_issue_more == 1 && !is_branch_slot_insn (next_insn))
24371 || (can_issue_more <= 2 && is_cracked_insn (next_insn))
24372 || (can_issue_more < issue_rate &&
24373 insn_terminates_group_p (next_insn, previous_group)));
24374 if (*group_end && end)
24375 (*group_count)--;
24377 if (sched_verbose > 6)
24378 fprintf (dump, "done force: group count = %d, can_issue_more = %d\n",
24379 *group_count, can_issue_more);
24380 return can_issue_more;
24383 return can_issue_more;
24386 /* This function tries to synch the dispatch groups that the compiler "sees"
24387 with the dispatch groups that the processor dispatcher is expected to
24388 form in practice. It tries to achieve this synchronization by forcing the
24389 estimated processor grouping on the compiler (as opposed to the function
24390 'pad_goups' which tries to force the scheduler's grouping on the processor).
24392 The function scans the insn sequence between PREV_HEAD_INSN and TAIL and
24393 examines the (estimated) dispatch groups that will be formed by the processor
24394 dispatcher. It marks these group boundaries to reflect the estimated
24395 processor grouping, overriding the grouping that the scheduler had marked.
24396 Depending on the value of the flag '-minsert-sched-nops' this function can
24397 force certain insns into separate groups or force a certain distance between
24398 them by inserting nops, for example, if there exists a "costly dependence"
24399 between the insns.
24401 The function estimates the group boundaries that the processor will form as
24402 follows: It keeps track of how many vacant issue slots are available after
24403 each insn. A subsequent insn will start a new group if one of the following
24404 4 cases applies:
24405 - no more vacant issue slots remain in the current dispatch group.
24406 - only the last issue slot, which is the branch slot, is vacant, but the next
24407 insn is not a branch.
24408 - only the last 2 or less issue slots, including the branch slot, are vacant,
24409 which means that a cracked insn (which occupies two issue slots) can't be
24410 issued in this group.
24411 - less than 'issue_rate' slots are vacant, and the next insn always needs to
24412 start a new group. */
24414 static int
24415 redefine_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail)
24417 rtx insn, next_insn;
24418 int issue_rate;
24419 int can_issue_more;
24420 int slot, i;
24421 bool group_end;
24422 int group_count = 0;
24423 rtx *group_insns;
24425 /* Initialize. */
24426 issue_rate = rs6000_issue_rate ();
24427 group_insns = XALLOCAVEC (rtx, issue_rate);
24428 for (i = 0; i < issue_rate; i++)
24430 group_insns[i] = 0;
24432 can_issue_more = issue_rate;
24433 slot = 0;
24434 insn = get_next_active_insn (prev_head_insn, tail);
24435 group_end = false;
24437 while (insn != NULL_RTX)
24439 slot = (issue_rate - can_issue_more);
24440 group_insns[slot] = insn;
24441 can_issue_more =
24442 rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more);
24443 if (insn_terminates_group_p (insn, current_group))
24444 can_issue_more = 0;
24446 next_insn = get_next_active_insn (insn, tail);
24447 if (next_insn == NULL_RTX)
24448 return group_count + 1;
24450 /* Is next_insn going to start a new group? */
24451 group_end
24452 = (can_issue_more == 0
24453 || (can_issue_more == 1 && !is_branch_slot_insn (next_insn))
24454 || (can_issue_more <= 2 && is_cracked_insn (next_insn))
24455 || (can_issue_more < issue_rate &&
24456 insn_terminates_group_p (next_insn, previous_group)));
24458 can_issue_more = force_new_group (sched_verbose, dump, group_insns,
24459 next_insn, &group_end, can_issue_more,
24460 &group_count);
24462 if (group_end)
24464 group_count++;
24465 can_issue_more = 0;
24466 for (i = 0; i < issue_rate; i++)
24468 group_insns[i] = 0;
24472 if (GET_MODE (next_insn) == TImode && can_issue_more)
24473 PUT_MODE (next_insn, VOIDmode);
24474 else if (!can_issue_more && GET_MODE (next_insn) != TImode)
24475 PUT_MODE (next_insn, TImode);
24477 insn = next_insn;
24478 if (can_issue_more == 0)
24479 can_issue_more = issue_rate;
24480 } /* while */
24482 return group_count;
24485 /* Scan the insn sequence between PREV_HEAD_INSN and TAIL and examine the
24486 dispatch group boundaries that the scheduler had marked. Pad with nops
24487 any dispatch groups which have vacant issue slots, in order to force the
24488 scheduler's grouping on the processor dispatcher. The function
24489 returns the number of dispatch groups found. */
24491 static int
24492 pad_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail)
24494 rtx insn, next_insn;
24495 rtx nop;
24496 int issue_rate;
24497 int can_issue_more;
24498 int group_end;
24499 int group_count = 0;
24501 /* Initialize issue_rate. */
24502 issue_rate = rs6000_issue_rate ();
24503 can_issue_more = issue_rate;
24505 insn = get_next_active_insn (prev_head_insn, tail);
24506 next_insn = get_next_active_insn (insn, tail);
24508 while (insn != NULL_RTX)
24510 can_issue_more =
24511 rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more);
24513 group_end = (next_insn == NULL_RTX || GET_MODE (next_insn) == TImode);
24515 if (next_insn == NULL_RTX)
24516 break;
24518 if (group_end)
24520 /* If the scheduler had marked group termination at this location
24521 (between insn and next_insn), and neither insn nor next_insn will
24522 force group termination, pad the group with nops to force group
24523 termination. */
24524 if (can_issue_more
24525 && (rs6000_sched_insert_nops == sched_finish_pad_groups)
24526 && !insn_terminates_group_p (insn, current_group)
24527 && !insn_terminates_group_p (next_insn, previous_group))
24529 if (!is_branch_slot_insn (next_insn))
24530 can_issue_more--;
24532 while (can_issue_more)
24534 nop = gen_nop ();
24535 emit_insn_before (nop, next_insn);
24536 can_issue_more--;
24540 can_issue_more = issue_rate;
24541 group_count++;
24544 insn = next_insn;
24545 next_insn = get_next_active_insn (insn, tail);
24548 return group_count;
24551 /* We're beginning a new block. Initialize data structures as necessary. */
24553 static void
24554 rs6000_sched_init (FILE *dump ATTRIBUTE_UNUSED,
24555 int sched_verbose ATTRIBUTE_UNUSED,
24556 int max_ready ATTRIBUTE_UNUSED)
24558 last_scheduled_insn = NULL_RTX;
24559 load_store_pendulum = 0;
24562 /* The following function is called at the end of scheduling BB.
24563 After reload, it inserts nops at insn group bundling. */
24565 static void
24566 rs6000_sched_finish (FILE *dump, int sched_verbose)
24568 int n_groups;
24570 if (sched_verbose)
24571 fprintf (dump, "=== Finishing schedule.\n");
24573 if (reload_completed && rs6000_sched_groups)
24575 /* Do not run sched_finish hook when selective scheduling enabled. */
24576 if (sel_sched_p ())
24577 return;
24579 if (rs6000_sched_insert_nops == sched_finish_none)
24580 return;
24582 if (rs6000_sched_insert_nops == sched_finish_pad_groups)
24583 n_groups = pad_groups (dump, sched_verbose,
24584 current_sched_info->prev_head,
24585 current_sched_info->next_tail);
24586 else
24587 n_groups = redefine_groups (dump, sched_verbose,
24588 current_sched_info->prev_head,
24589 current_sched_info->next_tail);
24591 if (sched_verbose >= 6)
24593 fprintf (dump, "ngroups = %d\n", n_groups);
24594 print_rtl (dump, current_sched_info->prev_head);
24595 fprintf (dump, "Done finish_sched\n");
24600 struct _rs6000_sched_context
24602 short cached_can_issue_more;
24603 rtx last_scheduled_insn;
24604 int load_store_pendulum;
24607 typedef struct _rs6000_sched_context rs6000_sched_context_def;
24608 typedef rs6000_sched_context_def *rs6000_sched_context_t;
24610 /* Allocate store for new scheduling context. */
24611 static void *
24612 rs6000_alloc_sched_context (void)
24614 return xmalloc (sizeof (rs6000_sched_context_def));
24617 /* If CLEAN_P is true then initializes _SC with clean data,
24618 and from the global context otherwise. */
24619 static void
24620 rs6000_init_sched_context (void *_sc, bool clean_p)
24622 rs6000_sched_context_t sc = (rs6000_sched_context_t) _sc;
24624 if (clean_p)
24626 sc->cached_can_issue_more = 0;
24627 sc->last_scheduled_insn = NULL_RTX;
24628 sc->load_store_pendulum = 0;
24630 else
24632 sc->cached_can_issue_more = cached_can_issue_more;
24633 sc->last_scheduled_insn = last_scheduled_insn;
24634 sc->load_store_pendulum = load_store_pendulum;
24638 /* Sets the global scheduling context to the one pointed to by _SC. */
24639 static void
24640 rs6000_set_sched_context (void *_sc)
24642 rs6000_sched_context_t sc = (rs6000_sched_context_t) _sc;
24644 gcc_assert (sc != NULL);
24646 cached_can_issue_more = sc->cached_can_issue_more;
24647 last_scheduled_insn = sc->last_scheduled_insn;
24648 load_store_pendulum = sc->load_store_pendulum;
24651 /* Free _SC. */
24652 static void
24653 rs6000_free_sched_context (void *_sc)
24655 gcc_assert (_sc != NULL);
24657 free (_sc);
24661 /* Length in units of the trampoline for entering a nested function. */
24664 rs6000_trampoline_size (void)
24666 int ret = 0;
24668 switch (DEFAULT_ABI)
24670 default:
24671 gcc_unreachable ();
24673 case ABI_AIX:
24674 ret = (TARGET_32BIT) ? 12 : 24;
24675 break;
24677 case ABI_DARWIN:
24678 case ABI_V4:
24679 ret = (TARGET_32BIT) ? 40 : 48;
24680 break;
24683 return ret;
24686 /* Emit RTL insns to initialize the variable parts of a trampoline.
24687 FNADDR is an RTX for the address of the function's pure code.
24688 CXT is an RTX for the static chain value for the function. */
24690 static void
24691 rs6000_trampoline_init (rtx m_tramp, tree fndecl, rtx cxt)
24693 int regsize = (TARGET_32BIT) ? 4 : 8;
24694 rtx fnaddr = XEXP (DECL_RTL (fndecl), 0);
24695 rtx ctx_reg = force_reg (Pmode, cxt);
24696 rtx addr = force_reg (Pmode, XEXP (m_tramp, 0));
24698 switch (DEFAULT_ABI)
24700 default:
24701 gcc_unreachable ();
24703 /* Under AIX, just build the 3 word function descriptor */
24704 case ABI_AIX:
24706 rtx fnmem = gen_const_mem (Pmode, force_reg (Pmode, fnaddr));
24707 rtx fn_reg = gen_reg_rtx (Pmode);
24708 rtx toc_reg = gen_reg_rtx (Pmode);
24710 /* Macro to shorten the code expansions below. */
24711 # define MEM_PLUS(MEM, OFFSET) adjust_address (MEM, Pmode, OFFSET)
24713 m_tramp = replace_equiv_address (m_tramp, addr);
24715 emit_move_insn (fn_reg, MEM_PLUS (fnmem, 0));
24716 emit_move_insn (toc_reg, MEM_PLUS (fnmem, regsize));
24717 emit_move_insn (MEM_PLUS (m_tramp, 0), fn_reg);
24718 emit_move_insn (MEM_PLUS (m_tramp, regsize), toc_reg);
24719 emit_move_insn (MEM_PLUS (m_tramp, 2*regsize), ctx_reg);
24721 # undef MEM_PLUS
24723 break;
24725 /* Under V.4/eabi/darwin, __trampoline_setup does the real work. */
24726 case ABI_DARWIN:
24727 case ABI_V4:
24728 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__trampoline_setup"),
24729 LCT_NORMAL, VOIDmode, 4,
24730 addr, Pmode,
24731 GEN_INT (rs6000_trampoline_size ()), SImode,
24732 fnaddr, Pmode,
24733 ctx_reg, Pmode);
24734 break;
24739 /* Returns TRUE iff the target attribute indicated by ATTR_ID takes a plain
24740 identifier as an argument, so the front end shouldn't look it up. */
24742 static bool
24743 rs6000_attribute_takes_identifier_p (const_tree attr_id)
24745 return is_attribute_p ("altivec", attr_id);
24748 /* Handle the "altivec" attribute. The attribute may have
24749 arguments as follows:
24751 __attribute__((altivec(vector__)))
24752 __attribute__((altivec(pixel__))) (always followed by 'unsigned short')
24753 __attribute__((altivec(bool__))) (always followed by 'unsigned')
24755 and may appear more than once (e.g., 'vector bool char') in a
24756 given declaration. */
24758 static tree
24759 rs6000_handle_altivec_attribute (tree *node,
24760 tree name ATTRIBUTE_UNUSED,
24761 tree args,
24762 int flags ATTRIBUTE_UNUSED,
24763 bool *no_add_attrs)
24765 tree type = *node, result = NULL_TREE;
24766 enum machine_mode mode;
24767 int unsigned_p;
24768 char altivec_type
24769 = ((args && TREE_CODE (args) == TREE_LIST && TREE_VALUE (args)
24770 && TREE_CODE (TREE_VALUE (args)) == IDENTIFIER_NODE)
24771 ? *IDENTIFIER_POINTER (TREE_VALUE (args))
24772 : '?');
24774 while (POINTER_TYPE_P (type)
24775 || TREE_CODE (type) == FUNCTION_TYPE
24776 || TREE_CODE (type) == METHOD_TYPE
24777 || TREE_CODE (type) == ARRAY_TYPE)
24778 type = TREE_TYPE (type);
24780 mode = TYPE_MODE (type);
24782 /* Check for invalid AltiVec type qualifiers. */
24783 if (type == long_double_type_node)
24784 error ("use of %<long double%> in AltiVec types is invalid");
24785 else if (type == boolean_type_node)
24786 error ("use of boolean types in AltiVec types is invalid");
24787 else if (TREE_CODE (type) == COMPLEX_TYPE)
24788 error ("use of %<complex%> in AltiVec types is invalid");
24789 else if (DECIMAL_FLOAT_MODE_P (mode))
24790 error ("use of decimal floating point types in AltiVec types is invalid");
24791 else if (!TARGET_VSX)
24793 if (type == long_unsigned_type_node || type == long_integer_type_node)
24795 if (TARGET_64BIT)
24796 error ("use of %<long%> in AltiVec types is invalid for "
24797 "64-bit code without -mvsx");
24798 else if (rs6000_warn_altivec_long)
24799 warning (0, "use of %<long%> in AltiVec types is deprecated; "
24800 "use %<int%>");
24802 else if (type == long_long_unsigned_type_node
24803 || type == long_long_integer_type_node)
24804 error ("use of %<long long%> in AltiVec types is invalid without "
24805 "-mvsx");
24806 else if (type == double_type_node)
24807 error ("use of %<double%> in AltiVec types is invalid without -mvsx");
24810 switch (altivec_type)
24812 case 'v':
24813 unsigned_p = TYPE_UNSIGNED (type);
24814 switch (mode)
24816 case DImode:
24817 result = (unsigned_p ? unsigned_V2DI_type_node : V2DI_type_node);
24818 break;
24819 case SImode:
24820 result = (unsigned_p ? unsigned_V4SI_type_node : V4SI_type_node);
24821 break;
24822 case HImode:
24823 result = (unsigned_p ? unsigned_V8HI_type_node : V8HI_type_node);
24824 break;
24825 case QImode:
24826 result = (unsigned_p ? unsigned_V16QI_type_node : V16QI_type_node);
24827 break;
24828 case SFmode: result = V4SF_type_node; break;
24829 case DFmode: result = V2DF_type_node; break;
24830 /* If the user says 'vector int bool', we may be handed the 'bool'
24831 attribute _before_ the 'vector' attribute, and so select the
24832 proper type in the 'b' case below. */
24833 case V4SImode: case V8HImode: case V16QImode: case V4SFmode:
24834 case V2DImode: case V2DFmode:
24835 result = type;
24836 default: break;
24838 break;
24839 case 'b':
24840 switch (mode)
24842 case DImode: case V2DImode: result = bool_V2DI_type_node; break;
24843 case SImode: case V4SImode: result = bool_V4SI_type_node; break;
24844 case HImode: case V8HImode: result = bool_V8HI_type_node; break;
24845 case QImode: case V16QImode: result = bool_V16QI_type_node;
24846 default: break;
24848 break;
24849 case 'p':
24850 switch (mode)
24852 case V8HImode: result = pixel_V8HI_type_node;
24853 default: break;
24855 default: break;
24858 /* Propagate qualifiers attached to the element type
24859 onto the vector type. */
24860 if (result && result != type && TYPE_QUALS (type))
24861 result = build_qualified_type (result, TYPE_QUALS (type));
24863 *no_add_attrs = true; /* No need to hang on to the attribute. */
24865 if (result)
24866 *node = lang_hooks.types.reconstruct_complex_type (*node, result);
24868 return NULL_TREE;
24871 /* AltiVec defines four built-in scalar types that serve as vector
24872 elements; we must teach the compiler how to mangle them. */
24874 static const char *
24875 rs6000_mangle_type (const_tree type)
24877 type = TYPE_MAIN_VARIANT (type);
24879 if (TREE_CODE (type) != VOID_TYPE && TREE_CODE (type) != BOOLEAN_TYPE
24880 && TREE_CODE (type) != INTEGER_TYPE && TREE_CODE (type) != REAL_TYPE)
24881 return NULL;
24883 if (type == bool_char_type_node) return "U6__boolc";
24884 if (type == bool_short_type_node) return "U6__bools";
24885 if (type == pixel_type_node) return "u7__pixel";
24886 if (type == bool_int_type_node) return "U6__booli";
24887 if (type == bool_long_type_node) return "U6__booll";
24889 /* Mangle IBM extended float long double as `g' (__float128) on
24890 powerpc*-linux where long-double-64 previously was the default. */
24891 if (TYPE_MAIN_VARIANT (type) == long_double_type_node
24892 && TARGET_ELF
24893 && TARGET_LONG_DOUBLE_128
24894 && !TARGET_IEEEQUAD)
24895 return "g";
24897 /* For all other types, use normal C++ mangling. */
24898 return NULL;
24901 /* Handle a "longcall" or "shortcall" attribute; arguments as in
24902 struct attribute_spec.handler. */
24904 static tree
24905 rs6000_handle_longcall_attribute (tree *node, tree name,
24906 tree args ATTRIBUTE_UNUSED,
24907 int flags ATTRIBUTE_UNUSED,
24908 bool *no_add_attrs)
24910 if (TREE_CODE (*node) != FUNCTION_TYPE
24911 && TREE_CODE (*node) != FIELD_DECL
24912 && TREE_CODE (*node) != TYPE_DECL)
24914 warning (OPT_Wattributes, "%qE attribute only applies to functions",
24915 name);
24916 *no_add_attrs = true;
24919 return NULL_TREE;
24922 /* Set longcall attributes on all functions declared when
24923 rs6000_default_long_calls is true. */
24924 static void
24925 rs6000_set_default_type_attributes (tree type)
24927 if (rs6000_default_long_calls
24928 && (TREE_CODE (type) == FUNCTION_TYPE
24929 || TREE_CODE (type) == METHOD_TYPE))
24930 TYPE_ATTRIBUTES (type) = tree_cons (get_identifier ("longcall"),
24931 NULL_TREE,
24932 TYPE_ATTRIBUTES (type));
24934 #if TARGET_MACHO
24935 darwin_set_default_type_attributes (type);
24936 #endif
24939 /* Return a reference suitable for calling a function with the
24940 longcall attribute. */
24943 rs6000_longcall_ref (rtx call_ref)
24945 const char *call_name;
24946 tree node;
24948 if (GET_CODE (call_ref) != SYMBOL_REF)
24949 return call_ref;
24951 /* System V adds '.' to the internal name, so skip them. */
24952 call_name = XSTR (call_ref, 0);
24953 if (*call_name == '.')
24955 while (*call_name == '.')
24956 call_name++;
24958 node = get_identifier (call_name);
24959 call_ref = gen_rtx_SYMBOL_REF (VOIDmode, IDENTIFIER_POINTER (node));
24962 return force_reg (Pmode, call_ref);
24965 #ifndef TARGET_USE_MS_BITFIELD_LAYOUT
24966 #define TARGET_USE_MS_BITFIELD_LAYOUT 0
24967 #endif
24969 /* Handle a "ms_struct" or "gcc_struct" attribute; arguments as in
24970 struct attribute_spec.handler. */
24971 static tree
24972 rs6000_handle_struct_attribute (tree *node, tree name,
24973 tree args ATTRIBUTE_UNUSED,
24974 int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
24976 tree *type = NULL;
24977 if (DECL_P (*node))
24979 if (TREE_CODE (*node) == TYPE_DECL)
24980 type = &TREE_TYPE (*node);
24982 else
24983 type = node;
24985 if (!(type && (TREE_CODE (*type) == RECORD_TYPE
24986 || TREE_CODE (*type) == UNION_TYPE)))
24988 warning (OPT_Wattributes, "%qE attribute ignored", name);
24989 *no_add_attrs = true;
24992 else if ((is_attribute_p ("ms_struct", name)
24993 && lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (*type)))
24994 || ((is_attribute_p ("gcc_struct", name)
24995 && lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (*type)))))
24997 warning (OPT_Wattributes, "%qE incompatible attribute ignored",
24998 name);
24999 *no_add_attrs = true;
25002 return NULL_TREE;
25005 static bool
25006 rs6000_ms_bitfield_layout_p (const_tree record_type)
25008 return (TARGET_USE_MS_BITFIELD_LAYOUT &&
25009 !lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (record_type)))
25010 || lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (record_type));
25013 #ifdef USING_ELFOS_H
25015 /* A get_unnamed_section callback, used for switching to toc_section. */
25017 static void
25018 rs6000_elf_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
25020 if (DEFAULT_ABI == ABI_AIX
25021 && TARGET_MINIMAL_TOC
25022 && !TARGET_RELOCATABLE)
25024 if (!toc_initialized)
25026 toc_initialized = 1;
25027 fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);
25028 (*targetm.asm_out.internal_label) (asm_out_file, "LCTOC", 0);
25029 fprintf (asm_out_file, "\t.tc ");
25030 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1[TC],");
25031 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
25032 fprintf (asm_out_file, "\n");
25034 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
25035 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
25036 fprintf (asm_out_file, " = .+32768\n");
25038 else
25039 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
25041 else if (DEFAULT_ABI == ABI_AIX && !TARGET_RELOCATABLE)
25042 fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);
25043 else
25045 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
25046 if (!toc_initialized)
25048 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
25049 fprintf (asm_out_file, " = .+32768\n");
25050 toc_initialized = 1;
25055 /* Implement TARGET_ASM_INIT_SECTIONS. */
25057 static void
25058 rs6000_elf_asm_init_sections (void)
25060 toc_section
25061 = get_unnamed_section (0, rs6000_elf_output_toc_section_asm_op, NULL);
25063 sdata2_section
25064 = get_unnamed_section (SECTION_WRITE, output_section_asm_op,
25065 SDATA2_SECTION_ASM_OP);
25068 /* Implement TARGET_SELECT_RTX_SECTION. */
25070 static section *
25071 rs6000_elf_select_rtx_section (enum machine_mode mode, rtx x,
25072 unsigned HOST_WIDE_INT align)
25074 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
25075 return toc_section;
25076 else
25077 return default_elf_select_rtx_section (mode, x, align);
25080 /* For a SYMBOL_REF, set generic flags and then perform some
25081 target-specific processing.
25083 When the AIX ABI is requested on a non-AIX system, replace the
25084 function name with the real name (with a leading .) rather than the
25085 function descriptor name. This saves a lot of overriding code to
25086 read the prefixes. */
25088 static void
25089 rs6000_elf_encode_section_info (tree decl, rtx rtl, int first)
25091 default_encode_section_info (decl, rtl, first);
25093 if (first
25094 && TREE_CODE (decl) == FUNCTION_DECL
25095 && !TARGET_AIX
25096 && DEFAULT_ABI == ABI_AIX)
25098 rtx sym_ref = XEXP (rtl, 0);
25099 size_t len = strlen (XSTR (sym_ref, 0));
25100 char *str = XALLOCAVEC (char, len + 2);
25101 str[0] = '.';
25102 memcpy (str + 1, XSTR (sym_ref, 0), len + 1);
25103 XSTR (sym_ref, 0) = ggc_alloc_string (str, len + 1);
25107 static inline bool
25108 compare_section_name (const char *section, const char *templ)
25110 int len;
25112 len = strlen (templ);
25113 return (strncmp (section, templ, len) == 0
25114 && (section[len] == 0 || section[len] == '.'));
25117 bool
25118 rs6000_elf_in_small_data_p (const_tree decl)
25120 if (rs6000_sdata == SDATA_NONE)
25121 return false;
25123 /* We want to merge strings, so we never consider them small data. */
25124 if (TREE_CODE (decl) == STRING_CST)
25125 return false;
25127 /* Functions are never in the small data area. */
25128 if (TREE_CODE (decl) == FUNCTION_DECL)
25129 return false;
25131 if (TREE_CODE (decl) == VAR_DECL && DECL_SECTION_NAME (decl))
25133 const char *section = TREE_STRING_POINTER (DECL_SECTION_NAME (decl));
25134 if (compare_section_name (section, ".sdata")
25135 || compare_section_name (section, ".sdata2")
25136 || compare_section_name (section, ".gnu.linkonce.s")
25137 || compare_section_name (section, ".sbss")
25138 || compare_section_name (section, ".sbss2")
25139 || compare_section_name (section, ".gnu.linkonce.sb")
25140 || strcmp (section, ".PPC.EMB.sdata0") == 0
25141 || strcmp (section, ".PPC.EMB.sbss0") == 0)
25142 return true;
25144 else
25146 HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (decl));
25148 if (size > 0
25149 && size <= g_switch_value
25150 /* If it's not public, and we're not going to reference it there,
25151 there's no need to put it in the small data section. */
25152 && (rs6000_sdata != SDATA_DATA || TREE_PUBLIC (decl)))
25153 return true;
25156 return false;
25159 #endif /* USING_ELFOS_H */
25161 /* Implement TARGET_USE_BLOCKS_FOR_CONSTANT_P. */
25163 static bool
25164 rs6000_use_blocks_for_constant_p (enum machine_mode mode, const_rtx x)
25166 return !ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode);
25169 /* Return a REG that occurs in ADDR with coefficient 1.
25170 ADDR can be effectively incremented by incrementing REG.
25172 r0 is special and we must not select it as an address
25173 register by this routine since our caller will try to
25174 increment the returned register via an "la" instruction. */
25177 find_addr_reg (rtx addr)
25179 while (GET_CODE (addr) == PLUS)
25181 if (GET_CODE (XEXP (addr, 0)) == REG
25182 && REGNO (XEXP (addr, 0)) != 0)
25183 addr = XEXP (addr, 0);
25184 else if (GET_CODE (XEXP (addr, 1)) == REG
25185 && REGNO (XEXP (addr, 1)) != 0)
25186 addr = XEXP (addr, 1);
25187 else if (CONSTANT_P (XEXP (addr, 0)))
25188 addr = XEXP (addr, 1);
25189 else if (CONSTANT_P (XEXP (addr, 1)))
25190 addr = XEXP (addr, 0);
25191 else
25192 gcc_unreachable ();
25194 gcc_assert (GET_CODE (addr) == REG && REGNO (addr) != 0);
25195 return addr;
25198 void
25199 rs6000_fatal_bad_address (rtx op)
25201 fatal_insn ("bad address", op);
25204 #if TARGET_MACHO
25206 typedef struct branch_island_d {
25207 tree function_name;
25208 tree label_name;
25209 int line_number;
25210 } branch_island;
25212 DEF_VEC_O(branch_island);
25213 DEF_VEC_ALLOC_O(branch_island,gc);
25215 static VEC(branch_island,gc) *branch_islands;
25217 /* Remember to generate a branch island for far calls to the given
25218 function. */
25220 static void
25221 add_compiler_branch_island (tree label_name, tree function_name,
25222 int line_number)
25224 branch_island *bi = VEC_safe_push (branch_island, gc, branch_islands, NULL);
25226 bi->function_name = function_name;
25227 bi->label_name = label_name;
25228 bi->line_number = line_number;
25231 /* Generate far-jump branch islands for everything recorded in
25232 branch_islands. Invoked immediately after the last instruction of
25233 the epilogue has been emitted; the branch islands must be appended
25234 to, and contiguous with, the function body. Mach-O stubs are
25235 generated in machopic_output_stub(). */
25237 static void
25238 macho_branch_islands (void)
25240 char tmp_buf[512];
25242 while (!VEC_empty (branch_island, branch_islands))
25244 branch_island *bi = VEC_last (branch_island, branch_islands);
25245 const char *label = IDENTIFIER_POINTER (bi->label_name);
25246 const char *name = IDENTIFIER_POINTER (bi->function_name);
25247 char name_buf[512];
25248 /* Cheap copy of the details from the Darwin ASM_OUTPUT_LABELREF(). */
25249 if (name[0] == '*' || name[0] == '&')
25250 strcpy (name_buf, name+1);
25251 else
25253 name_buf[0] = '_';
25254 strcpy (name_buf+1, name);
25256 strcpy (tmp_buf, "\n");
25257 strcat (tmp_buf, label);
25258 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
25259 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
25260 dbxout_stabd (N_SLINE, bi->line_number);
25261 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
25262 if (flag_pic)
25264 strcat (tmp_buf, ":\n\tmflr r0\n\tbcl 20,31,");
25265 strcat (tmp_buf, label);
25266 strcat (tmp_buf, "_pic\n");
25267 strcat (tmp_buf, label);
25268 strcat (tmp_buf, "_pic:\n\tmflr r11\n");
25270 strcat (tmp_buf, "\taddis r11,r11,ha16(");
25271 strcat (tmp_buf, name_buf);
25272 strcat (tmp_buf, " - ");
25273 strcat (tmp_buf, label);
25274 strcat (tmp_buf, "_pic)\n");
25276 strcat (tmp_buf, "\tmtlr r0\n");
25278 strcat (tmp_buf, "\taddi r12,r11,lo16(");
25279 strcat (tmp_buf, name_buf);
25280 strcat (tmp_buf, " - ");
25281 strcat (tmp_buf, label);
25282 strcat (tmp_buf, "_pic)\n");
25284 strcat (tmp_buf, "\tmtctr r12\n\tbctr\n");
25286 else
25288 strcat (tmp_buf, ":\nlis r12,hi16(");
25289 strcat (tmp_buf, name_buf);
25290 strcat (tmp_buf, ")\n\tori r12,r12,lo16(");
25291 strcat (tmp_buf, name_buf);
25292 strcat (tmp_buf, ")\n\tmtctr r12\n\tbctr");
25294 output_asm_insn (tmp_buf, 0);
25295 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
25296 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
25297 dbxout_stabd (N_SLINE, bi->line_number);
25298 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
25299 VEC_pop (branch_island, branch_islands);
25303 /* NO_PREVIOUS_DEF checks in the link list whether the function name is
25304 already there or not. */
25306 static int
25307 no_previous_def (tree function_name)
25309 branch_island *bi;
25310 unsigned ix;
25312 FOR_EACH_VEC_ELT (branch_island, branch_islands, ix, bi)
25313 if (function_name == bi->function_name)
25314 return 0;
25315 return 1;
25318 /* GET_PREV_LABEL gets the label name from the previous definition of
25319 the function. */
25321 static tree
25322 get_prev_label (tree function_name)
25324 branch_island *bi;
25325 unsigned ix;
25327 FOR_EACH_VEC_ELT (branch_island, branch_islands, ix, bi)
25328 if (function_name == bi->function_name)
25329 return bi->label_name;
25330 return NULL_TREE;
25333 /* INSN is either a function call or a millicode call. It may have an
25334 unconditional jump in its delay slot.
25336 CALL_DEST is the routine we are calling. */
25338 char *
25339 output_call (rtx insn, rtx *operands, int dest_operand_number,
25340 int cookie_operand_number)
25342 static char buf[256];
25343 if (darwin_emit_branch_islands
25344 && GET_CODE (operands[dest_operand_number]) == SYMBOL_REF
25345 && (INTVAL (operands[cookie_operand_number]) & CALL_LONG))
25347 tree labelname;
25348 tree funname = get_identifier (XSTR (operands[dest_operand_number], 0));
25350 if (no_previous_def (funname))
25352 rtx label_rtx = gen_label_rtx ();
25353 char *label_buf, temp_buf[256];
25354 ASM_GENERATE_INTERNAL_LABEL (temp_buf, "L",
25355 CODE_LABEL_NUMBER (label_rtx));
25356 label_buf = temp_buf[0] == '*' ? temp_buf + 1 : temp_buf;
25357 labelname = get_identifier (label_buf);
25358 add_compiler_branch_island (labelname, funname, insn_line (insn));
25360 else
25361 labelname = get_prev_label (funname);
25363 /* "jbsr foo, L42" is Mach-O for "Link as 'bl foo' if a 'bl'
25364 instruction will reach 'foo', otherwise link as 'bl L42'".
25365 "L42" should be a 'branch island', that will do a far jump to
25366 'foo'. Branch islands are generated in
25367 macho_branch_islands(). */
25368 sprintf (buf, "jbsr %%z%d,%.246s",
25369 dest_operand_number, IDENTIFIER_POINTER (labelname));
25371 else
25372 sprintf (buf, "bl %%z%d", dest_operand_number);
25373 return buf;
25376 /* Generate PIC and indirect symbol stubs. */
25378 void
25379 machopic_output_stub (FILE *file, const char *symb, const char *stub)
25381 unsigned int length;
25382 char *symbol_name, *lazy_ptr_name;
25383 char *local_label_0;
25384 static int label = 0;
25386 /* Lose our funky encoding stuff so it doesn't contaminate the stub. */
25387 symb = (*targetm.strip_name_encoding) (symb);
25390 length = strlen (symb);
25391 symbol_name = XALLOCAVEC (char, length + 32);
25392 GEN_SYMBOL_NAME_FOR_SYMBOL (symbol_name, symb, length);
25394 lazy_ptr_name = XALLOCAVEC (char, length + 32);
25395 GEN_LAZY_PTR_NAME_FOR_SYMBOL (lazy_ptr_name, symb, length);
25397 if (flag_pic == 2)
25398 switch_to_section (darwin_sections[machopic_picsymbol_stub1_section]);
25399 else
25400 switch_to_section (darwin_sections[machopic_symbol_stub1_section]);
25402 if (flag_pic == 2)
25404 fprintf (file, "\t.align 5\n");
25406 fprintf (file, "%s:\n", stub);
25407 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
25409 label++;
25410 local_label_0 = XALLOCAVEC (char, sizeof ("\"L00000000000$spb\""));
25411 sprintf (local_label_0, "\"L%011d$spb\"", label);
25413 fprintf (file, "\tmflr r0\n");
25414 fprintf (file, "\tbcl 20,31,%s\n", local_label_0);
25415 fprintf (file, "%s:\n\tmflr r11\n", local_label_0);
25416 fprintf (file, "\taddis r11,r11,ha16(%s-%s)\n",
25417 lazy_ptr_name, local_label_0);
25418 fprintf (file, "\tmtlr r0\n");
25419 fprintf (file, "\t%s r12,lo16(%s-%s)(r11)\n",
25420 (TARGET_64BIT ? "ldu" : "lwzu"),
25421 lazy_ptr_name, local_label_0);
25422 fprintf (file, "\tmtctr r12\n");
25423 fprintf (file, "\tbctr\n");
25425 else
25427 fprintf (file, "\t.align 4\n");
25429 fprintf (file, "%s:\n", stub);
25430 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
25432 fprintf (file, "\tlis r11,ha16(%s)\n", lazy_ptr_name);
25433 fprintf (file, "\t%s r12,lo16(%s)(r11)\n",
25434 (TARGET_64BIT ? "ldu" : "lwzu"),
25435 lazy_ptr_name);
25436 fprintf (file, "\tmtctr r12\n");
25437 fprintf (file, "\tbctr\n");
25440 switch_to_section (darwin_sections[machopic_lazy_symbol_ptr_section]);
25441 fprintf (file, "%s:\n", lazy_ptr_name);
25442 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
25443 fprintf (file, "%sdyld_stub_binding_helper\n",
25444 (TARGET_64BIT ? DOUBLE_INT_ASM_OP : "\t.long\t"));
25447 /* Legitimize PIC addresses. If the address is already
25448 position-independent, we return ORIG. Newly generated
25449 position-independent addresses go into a reg. This is REG if non
25450 zero, otherwise we allocate register(s) as necessary. */
25452 #define SMALL_INT(X) ((UINTVAL (X) + 0x8000) < 0x10000)
25455 rs6000_machopic_legitimize_pic_address (rtx orig, enum machine_mode mode,
25456 rtx reg)
25458 rtx base, offset;
25460 if (reg == NULL && ! reload_in_progress && ! reload_completed)
25461 reg = gen_reg_rtx (Pmode);
25463 if (GET_CODE (orig) == CONST)
25465 rtx reg_temp;
25467 if (GET_CODE (XEXP (orig, 0)) == PLUS
25468 && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx)
25469 return orig;
25471 gcc_assert (GET_CODE (XEXP (orig, 0)) == PLUS);
25473 /* Use a different reg for the intermediate value, as
25474 it will be marked UNCHANGING. */
25475 reg_temp = !can_create_pseudo_p () ? reg : gen_reg_rtx (Pmode);
25476 base = rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 0),
25477 Pmode, reg_temp);
25478 offset =
25479 rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 1),
25480 Pmode, reg);
25482 if (GET_CODE (offset) == CONST_INT)
25484 if (SMALL_INT (offset))
25485 return plus_constant (base, INTVAL (offset));
25486 else if (! reload_in_progress && ! reload_completed)
25487 offset = force_reg (Pmode, offset);
25488 else
25490 rtx mem = force_const_mem (Pmode, orig);
25491 return machopic_legitimize_pic_address (mem, Pmode, reg);
25494 return gen_rtx_PLUS (Pmode, base, offset);
25497 /* Fall back on generic machopic code. */
25498 return machopic_legitimize_pic_address (orig, mode, reg);
25501 /* Output a .machine directive for the Darwin assembler, and call
25502 the generic start_file routine. */
25504 static void
25505 rs6000_darwin_file_start (void)
25507 static const struct
25509 const char *arg;
25510 const char *name;
25511 int if_set;
25512 } mapping[] = {
25513 { "ppc64", "ppc64", MASK_64BIT },
25514 { "970", "ppc970", MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64 },
25515 { "power4", "ppc970", 0 },
25516 { "G5", "ppc970", 0 },
25517 { "7450", "ppc7450", 0 },
25518 { "7400", "ppc7400", MASK_ALTIVEC },
25519 { "G4", "ppc7400", 0 },
25520 { "750", "ppc750", 0 },
25521 { "740", "ppc750", 0 },
25522 { "G3", "ppc750", 0 },
25523 { "604e", "ppc604e", 0 },
25524 { "604", "ppc604", 0 },
25525 { "603e", "ppc603", 0 },
25526 { "603", "ppc603", 0 },
25527 { "601", "ppc601", 0 },
25528 { NULL, "ppc", 0 } };
25529 const char *cpu_id = "";
25530 size_t i;
25532 rs6000_file_start ();
25533 darwin_file_start ();
25535 /* Determine the argument to -mcpu=. Default to G3 if not specified. */
25536 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
25537 if (rs6000_select[i].set_arch_p && rs6000_select[i].string
25538 && rs6000_select[i].string[0] != '\0')
25539 cpu_id = rs6000_select[i].string;
25541 /* Look through the mapping array. Pick the first name that either
25542 matches the argument, has a bit set in IF_SET that is also set
25543 in the target flags, or has a NULL name. */
25545 i = 0;
25546 while (mapping[i].arg != NULL
25547 && strcmp (mapping[i].arg, cpu_id) != 0
25548 && (mapping[i].if_set & target_flags) == 0)
25549 i++;
25551 fprintf (asm_out_file, "\t.machine %s\n", mapping[i].name);
25554 #endif /* TARGET_MACHO */
25556 #if TARGET_ELF
25557 static int
25558 rs6000_elf_reloc_rw_mask (void)
25560 if (flag_pic)
25561 return 3;
25562 else if (DEFAULT_ABI == ABI_AIX)
25563 return 2;
25564 else
25565 return 0;
25568 /* Record an element in the table of global constructors. SYMBOL is
25569 a SYMBOL_REF of the function to be called; PRIORITY is a number
25570 between 0 and MAX_INIT_PRIORITY.
25572 This differs from default_named_section_asm_out_constructor in
25573 that we have special handling for -mrelocatable. */
25575 static void
25576 rs6000_elf_asm_out_constructor (rtx symbol, int priority)
25578 const char *section = ".ctors";
25579 char buf[16];
25581 if (priority != DEFAULT_INIT_PRIORITY)
25583 sprintf (buf, ".ctors.%.5u",
25584 /* Invert the numbering so the linker puts us in the proper
25585 order; constructors are run from right to left, and the
25586 linker sorts in increasing order. */
25587 MAX_INIT_PRIORITY - priority);
25588 section = buf;
25591 switch_to_section (get_section (section, SECTION_WRITE, NULL));
25592 assemble_align (POINTER_SIZE);
25594 if (TARGET_RELOCATABLE)
25596 fputs ("\t.long (", asm_out_file);
25597 output_addr_const (asm_out_file, symbol);
25598 fputs (")@fixup\n", asm_out_file);
25600 else
25601 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
25604 static void
25605 rs6000_elf_asm_out_destructor (rtx symbol, int priority)
25607 const char *section = ".dtors";
25608 char buf[16];
25610 if (priority != DEFAULT_INIT_PRIORITY)
25612 sprintf (buf, ".dtors.%.5u",
25613 /* Invert the numbering so the linker puts us in the proper
25614 order; constructors are run from right to left, and the
25615 linker sorts in increasing order. */
25616 MAX_INIT_PRIORITY - priority);
25617 section = buf;
25620 switch_to_section (get_section (section, SECTION_WRITE, NULL));
25621 assemble_align (POINTER_SIZE);
25623 if (TARGET_RELOCATABLE)
25625 fputs ("\t.long (", asm_out_file);
25626 output_addr_const (asm_out_file, symbol);
25627 fputs (")@fixup\n", asm_out_file);
25629 else
25630 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
25633 void
25634 rs6000_elf_declare_function_name (FILE *file, const char *name, tree decl)
25636 if (TARGET_64BIT)
25638 fputs ("\t.section\t\".opd\",\"aw\"\n\t.align 3\n", file);
25639 ASM_OUTPUT_LABEL (file, name);
25640 fputs (DOUBLE_INT_ASM_OP, file);
25641 rs6000_output_function_entry (file, name);
25642 fputs (",.TOC.@tocbase,0\n\t.previous\n", file);
25643 if (DOT_SYMBOLS)
25645 fputs ("\t.size\t", file);
25646 assemble_name (file, name);
25647 fputs (",24\n\t.type\t.", file);
25648 assemble_name (file, name);
25649 fputs (",@function\n", file);
25650 if (TREE_PUBLIC (decl) && ! DECL_WEAK (decl))
25652 fputs ("\t.globl\t.", file);
25653 assemble_name (file, name);
25654 putc ('\n', file);
25657 else
25658 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
25659 ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
25660 rs6000_output_function_entry (file, name);
25661 fputs (":\n", file);
25662 return;
25665 if (TARGET_RELOCATABLE
25666 && !TARGET_SECURE_PLT
25667 && (get_pool_size () != 0 || crtl->profile)
25668 && uses_TOC ())
25670 char buf[256];
25672 (*targetm.asm_out.internal_label) (file, "LCL", rs6000_pic_labelno);
25674 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
25675 fprintf (file, "\t.long ");
25676 assemble_name (file, buf);
25677 putc ('-', file);
25678 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
25679 assemble_name (file, buf);
25680 putc ('\n', file);
25683 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
25684 ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
25686 if (DEFAULT_ABI == ABI_AIX)
25688 const char *desc_name, *orig_name;
25690 orig_name = (*targetm.strip_name_encoding) (name);
25691 desc_name = orig_name;
25692 while (*desc_name == '.')
25693 desc_name++;
25695 if (TREE_PUBLIC (decl))
25696 fprintf (file, "\t.globl %s\n", desc_name);
25698 fprintf (file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
25699 fprintf (file, "%s:\n", desc_name);
25700 fprintf (file, "\t.long %s\n", orig_name);
25701 fputs ("\t.long _GLOBAL_OFFSET_TABLE_\n", file);
25702 if (DEFAULT_ABI == ABI_AIX)
25703 fputs ("\t.long 0\n", file);
25704 fprintf (file, "\t.previous\n");
25706 ASM_OUTPUT_LABEL (file, name);
25709 static void
25710 rs6000_elf_end_indicate_exec_stack (void)
25712 if (TARGET_32BIT)
25713 file_end_indicate_exec_stack ();
25715 #endif
25717 #if TARGET_XCOFF
25718 static void
25719 rs6000_xcoff_asm_output_anchor (rtx symbol)
25721 char buffer[100];
25723 sprintf (buffer, "$ + " HOST_WIDE_INT_PRINT_DEC,
25724 SYMBOL_REF_BLOCK_OFFSET (symbol));
25725 ASM_OUTPUT_DEF (asm_out_file, XSTR (symbol, 0), buffer);
25728 static void
25729 rs6000_xcoff_asm_globalize_label (FILE *stream, const char *name)
25731 fputs (GLOBAL_ASM_OP, stream);
25732 RS6000_OUTPUT_BASENAME (stream, name);
25733 putc ('\n', stream);
25736 /* A get_unnamed_decl callback, used for read-only sections. PTR
25737 points to the section string variable. */
25739 static void
25740 rs6000_xcoff_output_readonly_section_asm_op (const void *directive)
25742 fprintf (asm_out_file, "\t.csect %s[RO],%s\n",
25743 *(const char *const *) directive,
25744 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR);
25747 /* Likewise for read-write sections. */
25749 static void
25750 rs6000_xcoff_output_readwrite_section_asm_op (const void *directive)
25752 fprintf (asm_out_file, "\t.csect %s[RW],%s\n",
25753 *(const char *const *) directive,
25754 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR);
25757 /* A get_unnamed_section callback, used for switching to toc_section. */
25759 static void
25760 rs6000_xcoff_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
25762 if (TARGET_MINIMAL_TOC)
25764 /* toc_section is always selected at least once from
25765 rs6000_xcoff_file_start, so this is guaranteed to
25766 always be defined once and only once in each file. */
25767 if (!toc_initialized)
25769 fputs ("\t.toc\nLCTOC..1:\n", asm_out_file);
25770 fputs ("\t.tc toc_table[TC],toc_table[RW]\n", asm_out_file);
25771 toc_initialized = 1;
25773 fprintf (asm_out_file, "\t.csect toc_table[RW]%s\n",
25774 (TARGET_32BIT ? "" : ",3"));
25776 else
25777 fputs ("\t.toc\n", asm_out_file);
25780 /* Implement TARGET_ASM_INIT_SECTIONS. */
25782 static void
25783 rs6000_xcoff_asm_init_sections (void)
25785 read_only_data_section
25786 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
25787 &xcoff_read_only_section_name);
25789 private_data_section
25790 = get_unnamed_section (SECTION_WRITE,
25791 rs6000_xcoff_output_readwrite_section_asm_op,
25792 &xcoff_private_data_section_name);
25794 read_only_private_data_section
25795 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
25796 &xcoff_private_data_section_name);
25798 toc_section
25799 = get_unnamed_section (0, rs6000_xcoff_output_toc_section_asm_op, NULL);
25801 readonly_data_section = read_only_data_section;
25802 exception_section = data_section;
25805 static int
25806 rs6000_xcoff_reloc_rw_mask (void)
25808 return 3;
25811 static void
25812 rs6000_xcoff_asm_named_section (const char *name, unsigned int flags,
25813 tree decl ATTRIBUTE_UNUSED)
25815 int smclass;
25816 static const char * const suffix[3] = { "PR", "RO", "RW" };
25818 if (flags & SECTION_CODE)
25819 smclass = 0;
25820 else if (flags & SECTION_WRITE)
25821 smclass = 2;
25822 else
25823 smclass = 1;
25825 fprintf (asm_out_file, "\t.csect %s%s[%s],%u\n",
25826 (flags & SECTION_CODE) ? "." : "",
25827 name, suffix[smclass], flags & SECTION_ENTSIZE);
25830 static section *
25831 rs6000_xcoff_select_section (tree decl, int reloc,
25832 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
25834 if (decl_readonly_section (decl, reloc))
25836 if (TREE_PUBLIC (decl))
25837 return read_only_data_section;
25838 else
25839 return read_only_private_data_section;
25841 else
25843 if (TREE_PUBLIC (decl))
25844 return data_section;
25845 else
25846 return private_data_section;
25850 static void
25851 rs6000_xcoff_unique_section (tree decl, int reloc ATTRIBUTE_UNUSED)
25853 const char *name;
25855 /* Use select_section for private and uninitialized data. */
25856 if (!TREE_PUBLIC (decl)
25857 || DECL_COMMON (decl)
25858 || DECL_INITIAL (decl) == NULL_TREE
25859 || DECL_INITIAL (decl) == error_mark_node
25860 || (flag_zero_initialized_in_bss
25861 && initializer_zerop (DECL_INITIAL (decl))))
25862 return;
25864 name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
25865 name = (*targetm.strip_name_encoding) (name);
25866 DECL_SECTION_NAME (decl) = build_string (strlen (name), name);
25869 /* Select section for constant in constant pool.
25871 On RS/6000, all constants are in the private read-only data area.
25872 However, if this is being placed in the TOC it must be output as a
25873 toc entry. */
25875 static section *
25876 rs6000_xcoff_select_rtx_section (enum machine_mode mode, rtx x,
25877 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
25879 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
25880 return toc_section;
25881 else
25882 return read_only_private_data_section;
25885 /* Remove any trailing [DS] or the like from the symbol name. */
25887 static const char *
25888 rs6000_xcoff_strip_name_encoding (const char *name)
25890 size_t len;
25891 if (*name == '*')
25892 name++;
25893 len = strlen (name);
25894 if (name[len - 1] == ']')
25895 return ggc_alloc_string (name, len - 4);
25896 else
25897 return name;
25900 /* Section attributes. AIX is always PIC. */
25902 static unsigned int
25903 rs6000_xcoff_section_type_flags (tree decl, const char *name, int reloc)
25905 unsigned int align;
25906 unsigned int flags = default_section_type_flags (decl, name, reloc);
25908 /* Align to at least UNIT size. */
25909 if (flags & SECTION_CODE)
25910 align = MIN_UNITS_PER_WORD;
25911 else
25912 /* Increase alignment of large objects if not already stricter. */
25913 align = MAX ((DECL_ALIGN (decl) / BITS_PER_UNIT),
25914 int_size_in_bytes (TREE_TYPE (decl)) > MIN_UNITS_PER_WORD
25915 ? UNITS_PER_FP_WORD : MIN_UNITS_PER_WORD);
25917 return flags | (exact_log2 (align) & SECTION_ENTSIZE);
25920 /* Output at beginning of assembler file.
25922 Initialize the section names for the RS/6000 at this point.
25924 Specify filename, including full path, to assembler.
25926 We want to go into the TOC section so at least one .toc will be emitted.
25927 Also, in order to output proper .bs/.es pairs, we need at least one static
25928 [RW] section emitted.
25930 Finally, declare mcount when profiling to make the assembler happy. */
25932 static void
25933 rs6000_xcoff_file_start (void)
25935 rs6000_gen_section_name (&xcoff_bss_section_name,
25936 main_input_filename, ".bss_");
25937 rs6000_gen_section_name (&xcoff_private_data_section_name,
25938 main_input_filename, ".rw_");
25939 rs6000_gen_section_name (&xcoff_read_only_section_name,
25940 main_input_filename, ".ro_");
25942 fputs ("\t.file\t", asm_out_file);
25943 output_quoted_string (asm_out_file, main_input_filename);
25944 fputc ('\n', asm_out_file);
25945 if (write_symbols != NO_DEBUG)
25946 switch_to_section (private_data_section);
25947 switch_to_section (text_section);
25948 if (profile_flag)
25949 fprintf (asm_out_file, "\t.extern %s\n", RS6000_MCOUNT);
25950 rs6000_file_start ();
25953 /* Output at end of assembler file.
25954 On the RS/6000, referencing data should automatically pull in text. */
25956 static void
25957 rs6000_xcoff_file_end (void)
25959 switch_to_section (text_section);
25960 fputs ("_section_.text:\n", asm_out_file);
25961 switch_to_section (data_section);
25962 fputs (TARGET_32BIT
25963 ? "\t.long _section_.text\n" : "\t.llong _section_.text\n",
25964 asm_out_file);
25966 #endif /* TARGET_XCOFF */
25968 /* Compute a (partial) cost for rtx X. Return true if the complete
25969 cost has been computed, and false if subexpressions should be
25970 scanned. In either case, *TOTAL contains the cost result. */
25972 static bool
25973 rs6000_rtx_costs (rtx x, int code, int outer_code, int *total,
25974 bool speed)
25976 enum machine_mode mode = GET_MODE (x);
25978 switch (code)
25980 /* On the RS/6000, if it is valid in the insn, it is free. */
25981 case CONST_INT:
25982 if (((outer_code == SET
25983 || outer_code == PLUS
25984 || outer_code == MINUS)
25985 && (satisfies_constraint_I (x)
25986 || satisfies_constraint_L (x)))
25987 || (outer_code == AND
25988 && (satisfies_constraint_K (x)
25989 || (mode == SImode
25990 ? satisfies_constraint_L (x)
25991 : satisfies_constraint_J (x))
25992 || mask_operand (x, mode)
25993 || (mode == DImode
25994 && mask64_operand (x, DImode))))
25995 || ((outer_code == IOR || outer_code == XOR)
25996 && (satisfies_constraint_K (x)
25997 || (mode == SImode
25998 ? satisfies_constraint_L (x)
25999 : satisfies_constraint_J (x))))
26000 || outer_code == ASHIFT
26001 || outer_code == ASHIFTRT
26002 || outer_code == LSHIFTRT
26003 || outer_code == ROTATE
26004 || outer_code == ROTATERT
26005 || outer_code == ZERO_EXTRACT
26006 || (outer_code == MULT
26007 && satisfies_constraint_I (x))
26008 || ((outer_code == DIV || outer_code == UDIV
26009 || outer_code == MOD || outer_code == UMOD)
26010 && exact_log2 (INTVAL (x)) >= 0)
26011 || (outer_code == COMPARE
26012 && (satisfies_constraint_I (x)
26013 || satisfies_constraint_K (x)))
26014 || ((outer_code == EQ || outer_code == NE)
26015 && (satisfies_constraint_I (x)
26016 || satisfies_constraint_K (x)
26017 || (mode == SImode
26018 ? satisfies_constraint_L (x)
26019 : satisfies_constraint_J (x))))
26020 || (outer_code == GTU
26021 && satisfies_constraint_I (x))
26022 || (outer_code == LTU
26023 && satisfies_constraint_P (x)))
26025 *total = 0;
26026 return true;
26028 else if ((outer_code == PLUS
26029 && reg_or_add_cint_operand (x, VOIDmode))
26030 || (outer_code == MINUS
26031 && reg_or_sub_cint_operand (x, VOIDmode))
26032 || ((outer_code == SET
26033 || outer_code == IOR
26034 || outer_code == XOR)
26035 && (INTVAL (x)
26036 & ~ (unsigned HOST_WIDE_INT) 0xffffffff) == 0))
26038 *total = COSTS_N_INSNS (1);
26039 return true;
26041 /* FALLTHRU */
26043 case CONST_DOUBLE:
26044 if (mode == DImode && code == CONST_DOUBLE)
26046 if ((outer_code == IOR || outer_code == XOR)
26047 && CONST_DOUBLE_HIGH (x) == 0
26048 && (CONST_DOUBLE_LOW (x)
26049 & ~ (unsigned HOST_WIDE_INT) 0xffff) == 0)
26051 *total = 0;
26052 return true;
26054 else if ((outer_code == AND && and64_2_operand (x, DImode))
26055 || ((outer_code == SET
26056 || outer_code == IOR
26057 || outer_code == XOR)
26058 && CONST_DOUBLE_HIGH (x) == 0))
26060 *total = COSTS_N_INSNS (1);
26061 return true;
26064 /* FALLTHRU */
26066 case CONST:
26067 case HIGH:
26068 case SYMBOL_REF:
26069 case MEM:
26070 /* When optimizing for size, MEM should be slightly more expensive
26071 than generating address, e.g., (plus (reg) (const)).
26072 L1 cache latency is about two instructions. */
26073 *total = !speed ? COSTS_N_INSNS (1) + 1 : COSTS_N_INSNS (2);
26074 return true;
26076 case LABEL_REF:
26077 *total = 0;
26078 return true;
26080 case PLUS:
26081 case MINUS:
26082 if (FLOAT_MODE_P (mode))
26083 *total = rs6000_cost->fp;
26084 else
26085 *total = COSTS_N_INSNS (1);
26086 return false;
26088 case MULT:
26089 if (GET_CODE (XEXP (x, 1)) == CONST_INT
26090 && satisfies_constraint_I (XEXP (x, 1)))
26092 if (INTVAL (XEXP (x, 1)) >= -256
26093 && INTVAL (XEXP (x, 1)) <= 255)
26094 *total = rs6000_cost->mulsi_const9;
26095 else
26096 *total = rs6000_cost->mulsi_const;
26098 else if (mode == SFmode)
26099 *total = rs6000_cost->fp;
26100 else if (FLOAT_MODE_P (mode))
26101 *total = rs6000_cost->dmul;
26102 else if (mode == DImode)
26103 *total = rs6000_cost->muldi;
26104 else
26105 *total = rs6000_cost->mulsi;
26106 return false;
26108 case FMA:
26109 if (mode == SFmode)
26110 *total = rs6000_cost->fp;
26111 else
26112 *total = rs6000_cost->dmul;
26113 break;
26115 case DIV:
26116 case MOD:
26117 if (FLOAT_MODE_P (mode))
26119 *total = mode == DFmode ? rs6000_cost->ddiv
26120 : rs6000_cost->sdiv;
26121 return false;
26123 /* FALLTHRU */
26125 case UDIV:
26126 case UMOD:
26127 if (GET_CODE (XEXP (x, 1)) == CONST_INT
26128 && exact_log2 (INTVAL (XEXP (x, 1))) >= 0)
26130 if (code == DIV || code == MOD)
26131 /* Shift, addze */
26132 *total = COSTS_N_INSNS (2);
26133 else
26134 /* Shift */
26135 *total = COSTS_N_INSNS (1);
26137 else
26139 if (GET_MODE (XEXP (x, 1)) == DImode)
26140 *total = rs6000_cost->divdi;
26141 else
26142 *total = rs6000_cost->divsi;
26144 /* Add in shift and subtract for MOD. */
26145 if (code == MOD || code == UMOD)
26146 *total += COSTS_N_INSNS (2);
26147 return false;
26149 case CTZ:
26150 case FFS:
26151 *total = COSTS_N_INSNS (4);
26152 return false;
26154 case POPCOUNT:
26155 *total = COSTS_N_INSNS (TARGET_POPCNTD ? 1 : 6);
26156 return false;
26158 case PARITY:
26159 *total = COSTS_N_INSNS (TARGET_CMPB ? 2 : 6);
26160 return false;
26162 case NOT:
26163 if (outer_code == AND || outer_code == IOR || outer_code == XOR)
26165 *total = 0;
26166 return false;
26168 /* FALLTHRU */
26170 case AND:
26171 case CLZ:
26172 case IOR:
26173 case XOR:
26174 case ZERO_EXTRACT:
26175 *total = COSTS_N_INSNS (1);
26176 return false;
26178 case ASHIFT:
26179 case ASHIFTRT:
26180 case LSHIFTRT:
26181 case ROTATE:
26182 case ROTATERT:
26183 /* Handle mul_highpart. */
26184 if (outer_code == TRUNCATE
26185 && GET_CODE (XEXP (x, 0)) == MULT)
26187 if (mode == DImode)
26188 *total = rs6000_cost->muldi;
26189 else
26190 *total = rs6000_cost->mulsi;
26191 return true;
26193 else if (outer_code == AND)
26194 *total = 0;
26195 else
26196 *total = COSTS_N_INSNS (1);
26197 return false;
26199 case SIGN_EXTEND:
26200 case ZERO_EXTEND:
26201 if (GET_CODE (XEXP (x, 0)) == MEM)
26202 *total = 0;
26203 else
26204 *total = COSTS_N_INSNS (1);
26205 return false;
26207 case COMPARE:
26208 case NEG:
26209 case ABS:
26210 if (!FLOAT_MODE_P (mode))
26212 *total = COSTS_N_INSNS (1);
26213 return false;
26215 /* FALLTHRU */
26217 case FLOAT:
26218 case UNSIGNED_FLOAT:
26219 case FIX:
26220 case UNSIGNED_FIX:
26221 case FLOAT_TRUNCATE:
26222 *total = rs6000_cost->fp;
26223 return false;
26225 case FLOAT_EXTEND:
26226 if (mode == DFmode)
26227 *total = 0;
26228 else
26229 *total = rs6000_cost->fp;
26230 return false;
26232 case UNSPEC:
26233 switch (XINT (x, 1))
26235 case UNSPEC_FRSP:
26236 *total = rs6000_cost->fp;
26237 return true;
26239 default:
26240 break;
26242 break;
26244 case CALL:
26245 case IF_THEN_ELSE:
26246 if (!speed)
26248 *total = COSTS_N_INSNS (1);
26249 return true;
26251 else if (FLOAT_MODE_P (mode)
26252 && TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS)
26254 *total = rs6000_cost->fp;
26255 return false;
26257 break;
26259 case EQ:
26260 case GTU:
26261 case LTU:
26262 /* Carry bit requires mode == Pmode.
26263 NEG or PLUS already counted so only add one. */
26264 if (mode == Pmode
26265 && (outer_code == NEG || outer_code == PLUS))
26267 *total = COSTS_N_INSNS (1);
26268 return true;
26270 if (outer_code == SET)
26272 if (XEXP (x, 1) == const0_rtx)
26274 if (TARGET_ISEL && !TARGET_MFCRF)
26275 *total = COSTS_N_INSNS (8);
26276 else
26277 *total = COSTS_N_INSNS (2);
26278 return true;
26280 else if (mode == Pmode)
26282 *total = COSTS_N_INSNS (3);
26283 return false;
26286 /* FALLTHRU */
26288 case GT:
26289 case LT:
26290 case UNORDERED:
26291 if (outer_code == SET && (XEXP (x, 1) == const0_rtx))
26293 if (TARGET_ISEL && !TARGET_MFCRF)
26294 *total = COSTS_N_INSNS (8);
26295 else
26296 *total = COSTS_N_INSNS (2);
26297 return true;
26299 /* CC COMPARE. */
26300 if (outer_code == COMPARE)
26302 *total = 0;
26303 return true;
26305 break;
26307 default:
26308 break;
26311 return false;
26314 /* Debug form of r6000_rtx_costs that is selected if -mdebug=cost. */
26316 static bool
26317 rs6000_debug_rtx_costs (rtx x, int code, int outer_code, int *total,
26318 bool speed)
26320 bool ret = rs6000_rtx_costs (x, code, outer_code, total, speed);
26322 fprintf (stderr,
26323 "\nrs6000_rtx_costs, return = %s, code = %s, outer_code = %s, "
26324 "total = %d, speed = %s, x:\n",
26325 ret ? "complete" : "scan inner",
26326 GET_RTX_NAME (code),
26327 GET_RTX_NAME (outer_code),
26328 *total,
26329 speed ? "true" : "false");
26331 debug_rtx (x);
26333 return ret;
26336 /* Debug form of ADDRESS_COST that is selected if -mdebug=cost. */
26338 static int
26339 rs6000_debug_address_cost (rtx x, bool speed)
26341 int ret = TARGET_ADDRESS_COST (x, speed);
26343 fprintf (stderr, "\nrs6000_address_cost, return = %d, speed = %s, x:\n",
26344 ret, speed ? "true" : "false");
26345 debug_rtx (x);
26347 return ret;
26351 /* A C expression returning the cost of moving data from a register of class
26352 CLASS1 to one of CLASS2. */
26354 static int
26355 rs6000_register_move_cost (enum machine_mode mode,
26356 reg_class_t from, reg_class_t to)
26358 int ret;
26360 /* Moves from/to GENERAL_REGS. */
26361 if (reg_classes_intersect_p (to, GENERAL_REGS)
26362 || reg_classes_intersect_p (from, GENERAL_REGS))
26364 if (! reg_classes_intersect_p (to, GENERAL_REGS))
26365 from = to;
26367 if (from == FLOAT_REGS || from == ALTIVEC_REGS || from == VSX_REGS)
26368 ret = (rs6000_memory_move_cost (mode, from, false)
26369 + rs6000_memory_move_cost (mode, GENERAL_REGS, false));
26371 /* It's more expensive to move CR_REGS than CR0_REGS because of the
26372 shift. */
26373 else if (from == CR_REGS)
26374 ret = 4;
26376 /* Power6 has slower LR/CTR moves so make them more expensive than
26377 memory in order to bias spills to memory .*/
26378 else if (rs6000_cpu == PROCESSOR_POWER6
26379 && reg_classes_intersect_p (from, LINK_OR_CTR_REGS))
26380 ret = 6 * hard_regno_nregs[0][mode];
26382 else
26383 /* A move will cost one instruction per GPR moved. */
26384 ret = 2 * hard_regno_nregs[0][mode];
26387 /* If we have VSX, we can easily move between FPR or Altivec registers. */
26388 else if (VECTOR_UNIT_VSX_P (mode)
26389 && reg_classes_intersect_p (to, VSX_REGS)
26390 && reg_classes_intersect_p (from, VSX_REGS))
26391 ret = 2 * hard_regno_nregs[32][mode];
26393 /* Moving between two similar registers is just one instruction. */
26394 else if (reg_classes_intersect_p (to, from))
26395 ret = (mode == TFmode || mode == TDmode) ? 4 : 2;
26397 /* Everything else has to go through GENERAL_REGS. */
26398 else
26399 ret = (rs6000_register_move_cost (mode, GENERAL_REGS, to)
26400 + rs6000_register_move_cost (mode, from, GENERAL_REGS));
26402 if (TARGET_DEBUG_COST)
26403 fprintf (stderr,
26404 "rs6000_register_move_cost:, ret=%d, mode=%s, from=%s, to=%s\n",
26405 ret, GET_MODE_NAME (mode), reg_class_names[from],
26406 reg_class_names[to]);
26408 return ret;
26411 /* A C expressions returning the cost of moving data of MODE from a register to
26412 or from memory. */
26414 static int
26415 rs6000_memory_move_cost (enum machine_mode mode, reg_class_t rclass,
26416 bool in ATTRIBUTE_UNUSED)
26418 int ret;
26420 if (reg_classes_intersect_p (rclass, GENERAL_REGS))
26421 ret = 4 * hard_regno_nregs[0][mode];
26422 else if (reg_classes_intersect_p (rclass, FLOAT_REGS))
26423 ret = 4 * hard_regno_nregs[32][mode];
26424 else if (reg_classes_intersect_p (rclass, ALTIVEC_REGS))
26425 ret = 4 * hard_regno_nregs[FIRST_ALTIVEC_REGNO][mode];
26426 else
26427 ret = 4 + rs6000_register_move_cost (mode, rclass, GENERAL_REGS);
26429 if (TARGET_DEBUG_COST)
26430 fprintf (stderr,
26431 "rs6000_memory_move_cost: ret=%d, mode=%s, rclass=%s, in=%d\n",
26432 ret, GET_MODE_NAME (mode), reg_class_names[rclass], in);
26434 return ret;
26437 /* Returns a code for a target-specific builtin that implements
26438 reciprocal of the function, or NULL_TREE if not available. */
26440 static tree
26441 rs6000_builtin_reciprocal (unsigned int fn, bool md_fn,
26442 bool sqrt ATTRIBUTE_UNUSED)
26444 if (optimize_insn_for_size_p ())
26445 return NULL_TREE;
26447 if (md_fn)
26448 switch (fn)
26450 case VSX_BUILTIN_XVSQRTDP:
26451 if (!RS6000_RECIP_AUTO_RSQRTE_P (V2DFmode))
26452 return NULL_TREE;
26454 return rs6000_builtin_decls[VSX_BUILTIN_VEC_RSQRT_V2DF];
26456 case VSX_BUILTIN_XVSQRTSP:
26457 if (!RS6000_RECIP_AUTO_RSQRTE_P (V4SFmode))
26458 return NULL_TREE;
26460 return rs6000_builtin_decls[VSX_BUILTIN_VEC_RSQRT_V4SF];
26462 default:
26463 return NULL_TREE;
26466 else
26467 switch (fn)
26469 case BUILT_IN_SQRT:
26470 if (!RS6000_RECIP_AUTO_RSQRTE_P (DFmode))
26471 return NULL_TREE;
26473 return rs6000_builtin_decls[RS6000_BUILTIN_RSQRT];
26475 case BUILT_IN_SQRTF:
26476 if (!RS6000_RECIP_AUTO_RSQRTE_P (SFmode))
26477 return NULL_TREE;
26479 return rs6000_builtin_decls[RS6000_BUILTIN_RSQRTF];
26481 default:
26482 return NULL_TREE;
26486 /* Load up a constant. If the mode is a vector mode, splat the value across
26487 all of the vector elements. */
26489 static rtx
26490 rs6000_load_constant_and_splat (enum machine_mode mode, REAL_VALUE_TYPE dconst)
26492 rtx reg;
26494 if (mode == SFmode || mode == DFmode)
26496 rtx d = CONST_DOUBLE_FROM_REAL_VALUE (dconst, mode);
26497 reg = force_reg (mode, d);
26499 else if (mode == V4SFmode)
26501 rtx d = CONST_DOUBLE_FROM_REAL_VALUE (dconst, SFmode);
26502 rtvec v = gen_rtvec (4, d, d, d, d);
26503 reg = gen_reg_rtx (mode);
26504 rs6000_expand_vector_init (reg, gen_rtx_PARALLEL (mode, v));
26506 else if (mode == V2DFmode)
26508 rtx d = CONST_DOUBLE_FROM_REAL_VALUE (dconst, DFmode);
26509 rtvec v = gen_rtvec (2, d, d);
26510 reg = gen_reg_rtx (mode);
26511 rs6000_expand_vector_init (reg, gen_rtx_PARALLEL (mode, v));
26513 else
26514 gcc_unreachable ();
26516 return reg;
26519 /* Generate an FMA instruction. */
26521 static void
26522 rs6000_emit_madd (rtx target, rtx m1, rtx m2, rtx a)
26524 enum machine_mode mode = GET_MODE (target);
26525 rtx dst;
26527 dst = expand_ternary_op (mode, fma_optab, m1, m2, a, target, 0);
26528 gcc_assert (dst != NULL);
26530 if (dst != target)
26531 emit_move_insn (target, dst);
26534 /* Generate a FMSUB instruction: dst = fma(m1, m2, -a). */
26536 static void
26537 rs6000_emit_msub (rtx target, rtx m1, rtx m2, rtx a)
26539 enum machine_mode mode = GET_MODE (target);
26540 rtx dst;
26542 /* Altivec does not support fms directly;
26543 generate in terms of fma in that case. */
26544 if (optab_handler (fms_optab, mode) != CODE_FOR_nothing)
26545 dst = expand_ternary_op (mode, fms_optab, m1, m2, a, target, 0);
26546 else
26548 a = expand_unop (mode, neg_optab, a, NULL_RTX, 0);
26549 dst = expand_ternary_op (mode, fma_optab, m1, m2, a, target, 0);
26551 gcc_assert (dst != NULL);
26553 if (dst != target)
26554 emit_move_insn (target, dst);
26557 /* Generate a FNMSUB instruction: dst = -fma(m1, m2, -a). */
26559 static void
26560 rs6000_emit_nmsub (rtx dst, rtx m1, rtx m2, rtx a)
26562 enum machine_mode mode = GET_MODE (dst);
26563 rtx r;
26565 /* This is a tad more complicated, since the fnma_optab is for
26566 a different expression: fma(-m1, m2, a), which is the same
26567 thing except in the case of signed zeros.
26569 Fortunately we know that if FMA is supported that FNMSUB is
26570 also supported in the ISA. Just expand it directly. */
26572 gcc_assert (optab_handler (fma_optab, mode) != CODE_FOR_nothing);
26574 r = gen_rtx_NEG (mode, a);
26575 r = gen_rtx_FMA (mode, m1, m2, r);
26576 r = gen_rtx_NEG (mode, r);
26577 emit_insn (gen_rtx_SET (VOIDmode, dst, r));
26580 /* Newton-Raphson approximation of floating point divide with just 2 passes
26581 (either single precision floating point, or newer machines with higher
26582 accuracy estimates). Support both scalar and vector divide. Assumes no
26583 trapping math and finite arguments. */
26585 static void
26586 rs6000_emit_swdiv_high_precision (rtx dst, rtx n, rtx d)
26588 enum machine_mode mode = GET_MODE (dst);
26589 rtx x0, e0, e1, y1, u0, v0;
26590 enum insn_code code = optab_handler (smul_optab, mode);
26591 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (code);
26592 rtx one = rs6000_load_constant_and_splat (mode, dconst1);
26594 gcc_assert (code != CODE_FOR_nothing);
26596 /* x0 = 1./d estimate */
26597 x0 = gen_reg_rtx (mode);
26598 emit_insn (gen_rtx_SET (VOIDmode, x0,
26599 gen_rtx_UNSPEC (mode, gen_rtvec (1, d),
26600 UNSPEC_FRES)));
26602 e0 = gen_reg_rtx (mode);
26603 rs6000_emit_nmsub (e0, d, x0, one); /* e0 = 1. - (d * x0) */
26605 e1 = gen_reg_rtx (mode);
26606 rs6000_emit_madd (e1, e0, e0, e0); /* e1 = (e0 * e0) + e0 */
26608 y1 = gen_reg_rtx (mode);
26609 rs6000_emit_madd (y1, e1, x0, x0); /* y1 = (e1 * x0) + x0 */
26611 u0 = gen_reg_rtx (mode);
26612 emit_insn (gen_mul (u0, n, y1)); /* u0 = n * y1 */
26614 v0 = gen_reg_rtx (mode);
26615 rs6000_emit_nmsub (v0, d, u0, n); /* v0 = n - (d * u0) */
26617 rs6000_emit_madd (dst, v0, y1, u0); /* dst = (v0 * y1) + u0 */
26620 /* Newton-Raphson approximation of floating point divide that has a low
26621 precision estimate. Assumes no trapping math and finite arguments. */
26623 static void
26624 rs6000_emit_swdiv_low_precision (rtx dst, rtx n, rtx d)
26626 enum machine_mode mode = GET_MODE (dst);
26627 rtx x0, e0, e1, e2, y1, y2, y3, u0, v0, one;
26628 enum insn_code code = optab_handler (smul_optab, mode);
26629 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (code);
26631 gcc_assert (code != CODE_FOR_nothing);
26633 one = rs6000_load_constant_and_splat (mode, dconst1);
26635 /* x0 = 1./d estimate */
26636 x0 = gen_reg_rtx (mode);
26637 emit_insn (gen_rtx_SET (VOIDmode, x0,
26638 gen_rtx_UNSPEC (mode, gen_rtvec (1, d),
26639 UNSPEC_FRES)));
26641 e0 = gen_reg_rtx (mode);
26642 rs6000_emit_nmsub (e0, d, x0, one); /* e0 = 1. - d * x0 */
26644 y1 = gen_reg_rtx (mode);
26645 rs6000_emit_madd (y1, e0, x0, x0); /* y1 = x0 + e0 * x0 */
26647 e1 = gen_reg_rtx (mode);
26648 emit_insn (gen_mul (e1, e0, e0)); /* e1 = e0 * e0 */
26650 y2 = gen_reg_rtx (mode);
26651 rs6000_emit_madd (y2, e1, y1, y1); /* y2 = y1 + e1 * y1 */
26653 e2 = gen_reg_rtx (mode);
26654 emit_insn (gen_mul (e2, e1, e1)); /* e2 = e1 * e1 */
26656 y3 = gen_reg_rtx (mode);
26657 rs6000_emit_madd (y3, e2, y2, y2); /* y3 = y2 + e2 * y2 */
26659 u0 = gen_reg_rtx (mode);
26660 emit_insn (gen_mul (u0, n, y3)); /* u0 = n * y3 */
26662 v0 = gen_reg_rtx (mode);
26663 rs6000_emit_nmsub (v0, d, u0, n); /* v0 = n - d * u0 */
26665 rs6000_emit_madd (dst, v0, y3, u0); /* dst = u0 + v0 * y3 */
26668 /* Newton-Raphson approximation of floating point divide DST = N/D. If NOTE_P,
26669 add a reg_note saying that this was a division. Support both scalar and
26670 vector divide. Assumes no trapping math and finite arguments. */
26672 void
26673 rs6000_emit_swdiv (rtx dst, rtx n, rtx d, bool note_p)
26675 enum machine_mode mode = GET_MODE (dst);
26677 if (RS6000_RECIP_HIGH_PRECISION_P (mode))
26678 rs6000_emit_swdiv_high_precision (dst, n, d);
26679 else
26680 rs6000_emit_swdiv_low_precision (dst, n, d);
26682 if (note_p)
26683 add_reg_note (get_last_insn (), REG_EQUAL, gen_rtx_DIV (mode, n, d));
26686 /* Newton-Raphson approximation of single/double-precision floating point
26687 rsqrt. Assumes no trapping math and finite arguments. */
26689 void
26690 rs6000_emit_swrsqrt (rtx dst, rtx src)
26692 enum machine_mode mode = GET_MODE (src);
26693 rtx x0 = gen_reg_rtx (mode);
26694 rtx y = gen_reg_rtx (mode);
26695 int passes = (TARGET_RECIP_PRECISION) ? 2 : 3;
26696 REAL_VALUE_TYPE dconst3_2;
26697 int i;
26698 rtx halfthree;
26699 enum insn_code code = optab_handler (smul_optab, mode);
26700 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (code);
26702 gcc_assert (code != CODE_FOR_nothing);
26704 /* Load up the constant 1.5 either as a scalar, or as a vector. */
26705 real_from_integer (&dconst3_2, VOIDmode, 3, 0, 0);
26706 SET_REAL_EXP (&dconst3_2, REAL_EXP (&dconst3_2) - 1);
26708 halfthree = rs6000_load_constant_and_splat (mode, dconst3_2);
26710 /* x0 = rsqrt estimate */
26711 emit_insn (gen_rtx_SET (VOIDmode, x0,
26712 gen_rtx_UNSPEC (mode, gen_rtvec (1, src),
26713 UNSPEC_RSQRT)));
26715 /* y = 0.5 * src = 1.5 * src - src -> fewer constants */
26716 rs6000_emit_msub (y, src, halfthree, src);
26718 for (i = 0; i < passes; i++)
26720 rtx x1 = gen_reg_rtx (mode);
26721 rtx u = gen_reg_rtx (mode);
26722 rtx v = gen_reg_rtx (mode);
26724 /* x1 = x0 * (1.5 - y * (x0 * x0)) */
26725 emit_insn (gen_mul (u, x0, x0));
26726 rs6000_emit_nmsub (v, y, u, halfthree);
26727 emit_insn (gen_mul (x1, x0, v));
26728 x0 = x1;
26731 emit_move_insn (dst, x0);
26732 return;
26735 /* Emit popcount intrinsic on TARGET_POPCNTB (Power5) and TARGET_POPCNTD
26736 (Power7) targets. DST is the target, and SRC is the argument operand. */
26738 void
26739 rs6000_emit_popcount (rtx dst, rtx src)
26741 enum machine_mode mode = GET_MODE (dst);
26742 rtx tmp1, tmp2;
26744 /* Use the PPC ISA 2.06 popcnt{w,d} instruction if we can. */
26745 if (TARGET_POPCNTD)
26747 if (mode == SImode)
26748 emit_insn (gen_popcntdsi2 (dst, src));
26749 else
26750 emit_insn (gen_popcntddi2 (dst, src));
26751 return;
26754 tmp1 = gen_reg_rtx (mode);
26756 if (mode == SImode)
26758 emit_insn (gen_popcntbsi2 (tmp1, src));
26759 tmp2 = expand_mult (SImode, tmp1, GEN_INT (0x01010101),
26760 NULL_RTX, 0);
26761 tmp2 = force_reg (SImode, tmp2);
26762 emit_insn (gen_lshrsi3 (dst, tmp2, GEN_INT (24)));
26764 else
26766 emit_insn (gen_popcntbdi2 (tmp1, src));
26767 tmp2 = expand_mult (DImode, tmp1,
26768 GEN_INT ((HOST_WIDE_INT)
26769 0x01010101 << 32 | 0x01010101),
26770 NULL_RTX, 0);
26771 tmp2 = force_reg (DImode, tmp2);
26772 emit_insn (gen_lshrdi3 (dst, tmp2, GEN_INT (56)));
26777 /* Emit parity intrinsic on TARGET_POPCNTB targets. DST is the
26778 target, and SRC is the argument operand. */
26780 void
26781 rs6000_emit_parity (rtx dst, rtx src)
26783 enum machine_mode mode = GET_MODE (dst);
26784 rtx tmp;
26786 tmp = gen_reg_rtx (mode);
26788 /* Use the PPC ISA 2.05 prtyw/prtyd instruction if we can. */
26789 if (TARGET_CMPB)
26791 if (mode == SImode)
26793 emit_insn (gen_popcntbsi2 (tmp, src));
26794 emit_insn (gen_paritysi2_cmpb (dst, tmp));
26796 else
26798 emit_insn (gen_popcntbdi2 (tmp, src));
26799 emit_insn (gen_paritydi2_cmpb (dst, tmp));
26801 return;
26804 if (mode == SImode)
26806 /* Is mult+shift >= shift+xor+shift+xor? */
26807 if (rs6000_cost->mulsi_const >= COSTS_N_INSNS (3))
26809 rtx tmp1, tmp2, tmp3, tmp4;
26811 tmp1 = gen_reg_rtx (SImode);
26812 emit_insn (gen_popcntbsi2 (tmp1, src));
26814 tmp2 = gen_reg_rtx (SImode);
26815 emit_insn (gen_lshrsi3 (tmp2, tmp1, GEN_INT (16)));
26816 tmp3 = gen_reg_rtx (SImode);
26817 emit_insn (gen_xorsi3 (tmp3, tmp1, tmp2));
26819 tmp4 = gen_reg_rtx (SImode);
26820 emit_insn (gen_lshrsi3 (tmp4, tmp3, GEN_INT (8)));
26821 emit_insn (gen_xorsi3 (tmp, tmp3, tmp4));
26823 else
26824 rs6000_emit_popcount (tmp, src);
26825 emit_insn (gen_andsi3 (dst, tmp, const1_rtx));
26827 else
26829 /* Is mult+shift >= shift+xor+shift+xor+shift+xor? */
26830 if (rs6000_cost->muldi >= COSTS_N_INSNS (5))
26832 rtx tmp1, tmp2, tmp3, tmp4, tmp5, tmp6;
26834 tmp1 = gen_reg_rtx (DImode);
26835 emit_insn (gen_popcntbdi2 (tmp1, src));
26837 tmp2 = gen_reg_rtx (DImode);
26838 emit_insn (gen_lshrdi3 (tmp2, tmp1, GEN_INT (32)));
26839 tmp3 = gen_reg_rtx (DImode);
26840 emit_insn (gen_xordi3 (tmp3, tmp1, tmp2));
26842 tmp4 = gen_reg_rtx (DImode);
26843 emit_insn (gen_lshrdi3 (tmp4, tmp3, GEN_INT (16)));
26844 tmp5 = gen_reg_rtx (DImode);
26845 emit_insn (gen_xordi3 (tmp5, tmp3, tmp4));
26847 tmp6 = gen_reg_rtx (DImode);
26848 emit_insn (gen_lshrdi3 (tmp6, tmp5, GEN_INT (8)));
26849 emit_insn (gen_xordi3 (tmp, tmp5, tmp6));
26851 else
26852 rs6000_emit_popcount (tmp, src);
26853 emit_insn (gen_anddi3 (dst, tmp, const1_rtx));
26857 /* Return an RTX representing where to find the function value of a
26858 function returning MODE. */
26859 static rtx
26860 rs6000_complex_function_value (enum machine_mode mode)
26862 unsigned int regno;
26863 rtx r1, r2;
26864 enum machine_mode inner = GET_MODE_INNER (mode);
26865 unsigned int inner_bytes = GET_MODE_SIZE (inner);
26867 if (FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
26868 regno = FP_ARG_RETURN;
26869 else
26871 regno = GP_ARG_RETURN;
26873 /* 32-bit is OK since it'll go in r3/r4. */
26874 if (TARGET_32BIT && inner_bytes >= 4)
26875 return gen_rtx_REG (mode, regno);
26878 if (inner_bytes >= 8)
26879 return gen_rtx_REG (mode, regno);
26881 r1 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno),
26882 const0_rtx);
26883 r2 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno + 1),
26884 GEN_INT (inner_bytes));
26885 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
26888 /* Target hook for TARGET_FUNCTION_VALUE.
26890 On the SPE, both FPs and vectors are returned in r3.
26892 On RS/6000 an integer value is in r3 and a floating-point value is in
26893 fp1, unless -msoft-float. */
26896 rs6000_function_value (const_tree valtype,
26897 const_tree fn_decl_or_type ATTRIBUTE_UNUSED,
26898 bool outgoing ATTRIBUTE_UNUSED)
26900 enum machine_mode mode;
26901 unsigned int regno;
26903 /* Special handling for structs in darwin64. */
26904 if (TARGET_MACHO
26905 && rs6000_darwin64_struct_check_p (TYPE_MODE (valtype), valtype))
26907 CUMULATIVE_ARGS valcum;
26908 rtx valret;
26910 valcum.words = 0;
26911 valcum.fregno = FP_ARG_MIN_REG;
26912 valcum.vregno = ALTIVEC_ARG_MIN_REG;
26913 /* Do a trial code generation as if this were going to be passed as
26914 an argument; if any part goes in memory, we return NULL. */
26915 valret = rs6000_darwin64_record_arg (&valcum, valtype, true, /* retval= */ true);
26916 if (valret)
26917 return valret;
26918 /* Otherwise fall through to standard ABI rules. */
26921 if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DImode)
26923 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
26924 return gen_rtx_PARALLEL (DImode,
26925 gen_rtvec (2,
26926 gen_rtx_EXPR_LIST (VOIDmode,
26927 gen_rtx_REG (SImode, GP_ARG_RETURN),
26928 const0_rtx),
26929 gen_rtx_EXPR_LIST (VOIDmode,
26930 gen_rtx_REG (SImode,
26931 GP_ARG_RETURN + 1),
26932 GEN_INT (4))));
26934 if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DCmode)
26936 return gen_rtx_PARALLEL (DCmode,
26937 gen_rtvec (4,
26938 gen_rtx_EXPR_LIST (VOIDmode,
26939 gen_rtx_REG (SImode, GP_ARG_RETURN),
26940 const0_rtx),
26941 gen_rtx_EXPR_LIST (VOIDmode,
26942 gen_rtx_REG (SImode,
26943 GP_ARG_RETURN + 1),
26944 GEN_INT (4)),
26945 gen_rtx_EXPR_LIST (VOIDmode,
26946 gen_rtx_REG (SImode,
26947 GP_ARG_RETURN + 2),
26948 GEN_INT (8)),
26949 gen_rtx_EXPR_LIST (VOIDmode,
26950 gen_rtx_REG (SImode,
26951 GP_ARG_RETURN + 3),
26952 GEN_INT (12))));
26955 mode = TYPE_MODE (valtype);
26956 if ((INTEGRAL_TYPE_P (valtype) && GET_MODE_BITSIZE (mode) < BITS_PER_WORD)
26957 || POINTER_TYPE_P (valtype))
26958 mode = TARGET_32BIT ? SImode : DImode;
26960 if (DECIMAL_FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
26961 /* _Decimal128 must use an even/odd register pair. */
26962 regno = (mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN;
26963 else if (SCALAR_FLOAT_TYPE_P (valtype) && TARGET_HARD_FLOAT && TARGET_FPRS
26964 && ((TARGET_SINGLE_FLOAT && (mode == SFmode)) || TARGET_DOUBLE_FLOAT))
26965 regno = FP_ARG_RETURN;
26966 else if (TREE_CODE (valtype) == COMPLEX_TYPE
26967 && targetm.calls.split_complex_arg)
26968 return rs6000_complex_function_value (mode);
26969 else if (TREE_CODE (valtype) == VECTOR_TYPE
26970 && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI
26971 && ALTIVEC_VECTOR_MODE (mode))
26972 regno = ALTIVEC_ARG_RETURN;
26973 else if (TREE_CODE (valtype) == VECTOR_TYPE
26974 && TARGET_VSX && TARGET_ALTIVEC_ABI
26975 && VSX_VECTOR_MODE (mode))
26976 regno = ALTIVEC_ARG_RETURN;
26977 else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
26978 && (mode == DFmode || mode == DCmode
26979 || mode == TFmode || mode == TCmode))
26980 return spe_build_register_parallel (mode, GP_ARG_RETURN);
26981 else
26982 regno = GP_ARG_RETURN;
26984 return gen_rtx_REG (mode, regno);
26987 /* Define how to find the value returned by a library function
26988 assuming the value has mode MODE. */
26990 rs6000_libcall_value (enum machine_mode mode)
26992 unsigned int regno;
26994 if (TARGET_32BIT && TARGET_POWERPC64 && mode == DImode)
26996 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
26997 return gen_rtx_PARALLEL (DImode,
26998 gen_rtvec (2,
26999 gen_rtx_EXPR_LIST (VOIDmode,
27000 gen_rtx_REG (SImode, GP_ARG_RETURN),
27001 const0_rtx),
27002 gen_rtx_EXPR_LIST (VOIDmode,
27003 gen_rtx_REG (SImode,
27004 GP_ARG_RETURN + 1),
27005 GEN_INT (4))));
27008 if (DECIMAL_FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
27009 /* _Decimal128 must use an even/odd register pair. */
27010 regno = (mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN;
27011 else if (SCALAR_FLOAT_MODE_P (mode)
27012 && TARGET_HARD_FLOAT && TARGET_FPRS
27013 && ((TARGET_SINGLE_FLOAT && mode == SFmode) || TARGET_DOUBLE_FLOAT))
27014 regno = FP_ARG_RETURN;
27015 else if (ALTIVEC_VECTOR_MODE (mode)
27016 && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI)
27017 regno = ALTIVEC_ARG_RETURN;
27018 else if (VSX_VECTOR_MODE (mode)
27019 && TARGET_VSX && TARGET_ALTIVEC_ABI)
27020 regno = ALTIVEC_ARG_RETURN;
27021 else if (COMPLEX_MODE_P (mode) && targetm.calls.split_complex_arg)
27022 return rs6000_complex_function_value (mode);
27023 else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
27024 && (mode == DFmode || mode == DCmode
27025 || mode == TFmode || mode == TCmode))
27026 return spe_build_register_parallel (mode, GP_ARG_RETURN);
27027 else
27028 regno = GP_ARG_RETURN;
27030 return gen_rtx_REG (mode, regno);
27034 /* Given FROM and TO register numbers, say whether this elimination is allowed.
27035 Frame pointer elimination is automatically handled.
27037 For the RS/6000, if frame pointer elimination is being done, we would like
27038 to convert ap into fp, not sp.
27040 We need r30 if -mminimal-toc was specified, and there are constant pool
27041 references. */
27043 bool
27044 rs6000_can_eliminate (const int from, const int to)
27046 return (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM
27047 ? ! frame_pointer_needed
27048 : from == RS6000_PIC_OFFSET_TABLE_REGNUM
27049 ? ! TARGET_MINIMAL_TOC || TARGET_NO_TOC || get_pool_size () == 0
27050 : true);
27053 /* Define the offset between two registers, FROM to be eliminated and its
27054 replacement TO, at the start of a routine. */
27055 HOST_WIDE_INT
27056 rs6000_initial_elimination_offset (int from, int to)
27058 rs6000_stack_t *info = rs6000_stack_info ();
27059 HOST_WIDE_INT offset;
27061 if (from == HARD_FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
27062 offset = info->push_p ? 0 : -info->total_size;
27063 else if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
27065 offset = info->push_p ? 0 : -info->total_size;
27066 if (FRAME_GROWS_DOWNWARD)
27067 offset += info->fixed_size + info->vars_size + info->parm_size;
27069 else if (from == FRAME_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
27070 offset = FRAME_GROWS_DOWNWARD
27071 ? info->fixed_size + info->vars_size + info->parm_size
27072 : 0;
27073 else if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
27074 offset = info->total_size;
27075 else if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
27076 offset = info->push_p ? info->total_size : 0;
27077 else if (from == RS6000_PIC_OFFSET_TABLE_REGNUM)
27078 offset = 0;
27079 else
27080 gcc_unreachable ();
27082 return offset;
27085 static rtx
27086 rs6000_dwarf_register_span (rtx reg)
27088 rtx parts[8];
27089 int i, words;
27090 unsigned regno = REGNO (reg);
27091 enum machine_mode mode = GET_MODE (reg);
27093 if (TARGET_SPE
27094 && regno < 32
27095 && (SPE_VECTOR_MODE (GET_MODE (reg))
27096 || (TARGET_E500_DOUBLE && FLOAT_MODE_P (mode)
27097 && mode != SFmode && mode != SDmode && mode != SCmode)))
27099 else
27100 return NULL_RTX;
27102 regno = REGNO (reg);
27104 /* The duality of the SPE register size wreaks all kinds of havoc.
27105 This is a way of distinguishing r0 in 32-bits from r0 in
27106 64-bits. */
27107 words = (GET_MODE_SIZE (mode) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD;
27108 gcc_assert (words <= 4);
27109 for (i = 0; i < words; i++, regno++)
27111 if (BYTES_BIG_ENDIAN)
27113 parts[2 * i] = gen_rtx_REG (SImode, regno + 1200);
27114 parts[2 * i + 1] = gen_rtx_REG (SImode, regno);
27116 else
27118 parts[2 * i] = gen_rtx_REG (SImode, regno);
27119 parts[2 * i + 1] = gen_rtx_REG (SImode, regno + 1200);
27123 return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (words * 2, parts));
27126 /* Fill in sizes for SPE register high parts in table used by unwinder. */
27128 static void
27129 rs6000_init_dwarf_reg_sizes_extra (tree address)
27131 if (TARGET_SPE)
27133 int i;
27134 enum machine_mode mode = TYPE_MODE (char_type_node);
27135 rtx addr = expand_expr (address, NULL_RTX, VOIDmode, EXPAND_NORMAL);
27136 rtx mem = gen_rtx_MEM (BLKmode, addr);
27137 rtx value = gen_int_mode (4, mode);
27139 for (i = 1201; i < 1232; i++)
27141 int column = DWARF_REG_TO_UNWIND_COLUMN (i);
27142 HOST_WIDE_INT offset
27143 = DWARF_FRAME_REGNUM (column) * GET_MODE_SIZE (mode);
27145 emit_move_insn (adjust_address (mem, mode, offset), value);
27150 /* Map internal gcc register numbers to DWARF2 register numbers. */
27152 unsigned int
27153 rs6000_dbx_register_number (unsigned int regno)
27155 if (regno <= 63 || write_symbols != DWARF2_DEBUG)
27156 return regno;
27157 if (regno == MQ_REGNO)
27158 return 100;
27159 if (regno == LR_REGNO)
27160 return 108;
27161 if (regno == CTR_REGNO)
27162 return 109;
27163 if (CR_REGNO_P (regno))
27164 return regno - CR0_REGNO + 86;
27165 if (regno == CA_REGNO)
27166 return 101; /* XER */
27167 if (ALTIVEC_REGNO_P (regno))
27168 return regno - FIRST_ALTIVEC_REGNO + 1124;
27169 if (regno == VRSAVE_REGNO)
27170 return 356;
27171 if (regno == VSCR_REGNO)
27172 return 67;
27173 if (regno == SPE_ACC_REGNO)
27174 return 99;
27175 if (regno == SPEFSCR_REGNO)
27176 return 612;
27177 /* SPE high reg number. We get these values of regno from
27178 rs6000_dwarf_register_span. */
27179 gcc_assert (regno >= 1200 && regno < 1232);
27180 return regno;
27183 /* target hook eh_return_filter_mode */
27184 static enum machine_mode
27185 rs6000_eh_return_filter_mode (void)
27187 return TARGET_32BIT ? SImode : word_mode;
27190 /* Target hook for scalar_mode_supported_p. */
27191 static bool
27192 rs6000_scalar_mode_supported_p (enum machine_mode mode)
27194 if (DECIMAL_FLOAT_MODE_P (mode))
27195 return default_decimal_float_supported_p ();
27196 else
27197 return default_scalar_mode_supported_p (mode);
27200 /* Target hook for vector_mode_supported_p. */
27201 static bool
27202 rs6000_vector_mode_supported_p (enum machine_mode mode)
27205 if (TARGET_PAIRED_FLOAT && PAIRED_VECTOR_MODE (mode))
27206 return true;
27208 if (TARGET_SPE && SPE_VECTOR_MODE (mode))
27209 return true;
27211 else if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode))
27212 return true;
27214 else
27215 return false;
27218 /* Target hook for invalid_arg_for_unprototyped_fn. */
27219 static const char *
27220 invalid_arg_for_unprototyped_fn (const_tree typelist, const_tree funcdecl, const_tree val)
27222 return (!rs6000_darwin64_abi
27223 && typelist == 0
27224 && TREE_CODE (TREE_TYPE (val)) == VECTOR_TYPE
27225 && (funcdecl == NULL_TREE
27226 || (TREE_CODE (funcdecl) == FUNCTION_DECL
27227 && DECL_BUILT_IN_CLASS (funcdecl) != BUILT_IN_MD)))
27228 ? N_("AltiVec argument passed to unprototyped function")
27229 : NULL;
27232 /* For TARGET_SECURE_PLT 32-bit PIC code we can save PIC register
27233 setup by using __stack_chk_fail_local hidden function instead of
27234 calling __stack_chk_fail directly. Otherwise it is better to call
27235 __stack_chk_fail directly. */
27237 static tree
27238 rs6000_stack_protect_fail (void)
27240 return (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
27241 ? default_hidden_stack_protect_fail ()
27242 : default_external_stack_protect_fail ();
27245 void
27246 rs6000_final_prescan_insn (rtx insn, rtx *operand ATTRIBUTE_UNUSED,
27247 int num_operands ATTRIBUTE_UNUSED)
27249 if (rs6000_warn_cell_microcode)
27251 const char *temp;
27252 int insn_code_number = recog_memoized (insn);
27253 location_t location = locator_location (INSN_LOCATOR (insn));
27255 /* Punt on insns we cannot recognize. */
27256 if (insn_code_number < 0)
27257 return;
27259 temp = get_insn_template (insn_code_number, insn);
27261 if (get_attr_cell_micro (insn) == CELL_MICRO_ALWAYS)
27262 warning_at (location, OPT_mwarn_cell_microcode,
27263 "emitting microcode insn %s\t[%s] #%d",
27264 temp, insn_data[INSN_CODE (insn)].name, INSN_UID (insn));
27265 else if (get_attr_cell_micro (insn) == CELL_MICRO_CONDITIONAL)
27266 warning_at (location, OPT_mwarn_cell_microcode,
27267 "emitting conditional microcode insn %s\t[%s] #%d",
27268 temp, insn_data[INSN_CODE (insn)].name, INSN_UID (insn));
27273 /* Mask options that we want to support inside of attribute((target)) and
27274 #pragma GCC target operations. Note, we do not include things like
27275 64/32-bit, endianess, hard/soft floating point, etc. that would have
27276 different calling sequences. */
27278 struct rs6000_opt_mask {
27279 const char *name; /* option name */
27280 int mask; /* mask to set */
27281 bool invert; /* invert sense of mask */
27282 bool valid_target; /* option is a target option */
27285 static struct rs6000_opt_mask const rs6000_opt_masks[] =
27287 { "altivec", MASK_ALTIVEC, false, true },
27288 { "cmpb", MASK_CMPB, false, true },
27289 { "dlmzb", MASK_DLMZB, false, true },
27290 { "fprnd", MASK_FPRND, false, true },
27291 { "hard-dfp", MASK_DFP, false, true },
27292 { "isel", MASK_ISEL, false, true },
27293 { "mfcrf", MASK_MFCRF, false, true },
27294 { "mfpgpr", MASK_MFPGPR, false, true },
27295 { "mulhw", MASK_MULHW, false, true },
27296 { "multiple", MASK_MULTIPLE, false, true },
27297 { "update", MASK_NO_UPDATE, true , true },
27298 { "popcntb", MASK_POPCNTB, false, true },
27299 { "popcntd", MASK_POPCNTD, false, true },
27300 { "powerpc-gfxopt", MASK_PPC_GFXOPT, false, true },
27301 { "powerpc-gpopt", MASK_PPC_GPOPT, false, true },
27302 { "recip-precision", MASK_RECIP_PRECISION, false, true },
27303 { "string", MASK_STRING, false, true },
27304 { "vsx", MASK_VSX, false, true },
27305 #ifdef MASK_64BIT
27306 #if TARGET_AIX_OS
27307 { "aix64", MASK_64BIT, false, false },
27308 { "aix32", MASK_64BIT, true, false },
27309 #else
27310 { "64", MASK_64BIT, false, false },
27311 { "32", MASK_64BIT, true, false },
27312 #endif
27313 #endif
27314 #ifdef MASK_EABI
27315 { "eabi", MASK_EABI, false, false },
27316 #endif
27317 #ifdef MASK_LITTLE_ENDIAN
27318 { "little", MASK_LITTLE_ENDIAN, false, false },
27319 { "big", MASK_LITTLE_ENDIAN, true, false },
27320 #endif
27321 #ifdef MASK_RELOCATABLE
27322 { "relocatable", MASK_RELOCATABLE, false, false },
27323 #endif
27324 #ifdef MASK_STRICT_ALIGN
27325 { "strict-align", MASK_STRICT_ALIGN, false, false },
27326 #endif
27327 { "power", MASK_POWER, false, false },
27328 { "power2", MASK_POWER2, false, false },
27329 { "powerpc", MASK_POWERPC, false, false },
27330 { "soft-float", MASK_SOFT_FLOAT, false, false },
27331 { "string", MASK_STRING, false, false },
27334 /* Option variables that we want to support inside attribute((target)) and
27335 #pragma GCC target operations. */
27337 struct rs6000_opt_var {
27338 const char *name; /* option name */
27339 size_t global_offset; /* offset of the option in global_options. */
27340 size_t target_offset; /* offset of the option in target optiosn. */
27343 static struct rs6000_opt_var const rs6000_opt_vars[] =
27345 { "friz",
27346 offsetof (struct gcc_options, x_TARGET_FRIZ),
27347 offsetof (struct cl_target_option, x_TARGET_FRIZ), },
27348 { "avoid-indexed-addresses",
27349 offsetof (struct gcc_options, x_TARGET_AVOID_XFORM),
27350 offsetof (struct cl_target_option, x_TARGET_AVOID_XFORM) },
27351 { "paired",
27352 offsetof (struct gcc_options, x_rs6000_paired_float),
27353 offsetof (struct cl_target_option, x_rs6000_paired_float), },
27354 { "longcall",
27355 offsetof (struct gcc_options, x_rs6000_default_long_calls),
27356 offsetof (struct cl_target_option, x_rs6000_default_long_calls), },
27359 /* Inner function to handle attribute((target("..."))) and #pragma GCC target
27360 parsing. Return true if there were no errors. */
27362 static bool
27363 rs6000_inner_target_options (tree args, bool attr_p)
27365 bool ret = true;
27367 if (args == NULL_TREE)
27370 else if (TREE_CODE (args) == STRING_CST)
27372 char *p = ASTRDUP (TREE_STRING_POINTER (args));
27373 char *q;
27375 while ((q = strtok (p, ",")) != NULL)
27377 bool error_p = false;
27378 bool not_valid_p = false;
27379 const char *cpu_opt = NULL;
27381 p = NULL;
27382 if (strncmp (q, "cpu=", 4) == 0)
27384 int cpu_index = rs6000_cpu_name_lookup (q+4);
27385 if (cpu_index >= 0)
27386 rs6000_cpu_index = cpu_index;
27387 else
27389 error_p = true;
27390 cpu_opt = q+4;
27393 else if (strncmp (q, "tune=", 5) == 0)
27395 int tune_index = rs6000_cpu_name_lookup (q+5);
27396 if (tune_index >= 0)
27397 rs6000_tune_index = tune_index;
27398 else
27400 error_p = true;
27401 cpu_opt = q+5;
27404 else
27406 size_t i;
27407 bool invert = false;
27408 char *r = q;
27410 error_p = true;
27411 if (strncmp (r, "no-", 3) == 0)
27413 invert = true;
27414 r += 3;
27417 for (i = 0; i < ARRAY_SIZE (rs6000_opt_masks); i++)
27418 if (strcmp (r, rs6000_opt_masks[i].name) == 0)
27420 int mask = rs6000_opt_masks[i].mask;
27422 if (!rs6000_opt_masks[i].valid_target)
27423 not_valid_p = true;
27424 else
27426 error_p = false;
27427 target_flags_explicit |= mask;
27429 if (rs6000_opt_masks[i].invert)
27430 invert = !invert;
27432 if (invert)
27433 target_flags &= ~mask;
27434 else
27435 target_flags |= mask;
27437 break;
27440 if (error_p && !not_valid_p)
27442 for (i = 0; i < ARRAY_SIZE (rs6000_opt_vars); i++)
27443 if (strcmp (r, rs6000_opt_vars[i].name) == 0)
27445 size_t j = rs6000_opt_vars[i].global_offset;
27446 ((int *) &global_options)[j] = !invert;
27447 error_p = false;
27448 break;
27453 if (error_p)
27455 const char *eprefix, *esuffix;
27457 ret = false;
27458 if (attr_p)
27460 eprefix = "__attribute__((__target__(";
27461 esuffix = ")))";
27463 else
27465 eprefix = "#pragma GCC target ";
27466 esuffix = "";
27469 if (cpu_opt)
27470 error ("invalid cpu \"%s\" for %s\"%s\"%s", cpu_opt, eprefix,
27471 q, esuffix);
27472 else if (not_valid_p)
27473 error ("%s\"%s\"%s is not allowed", eprefix, q, esuffix);
27474 else
27475 error ("%s\"%s\"%s is invalid", eprefix, q, esuffix);
27480 else if (TREE_CODE (args) == TREE_LIST)
27484 tree value = TREE_VALUE (args);
27485 if (value)
27487 bool ret2 = rs6000_inner_target_options (value, attr_p);
27488 if (!ret2)
27489 ret = false;
27491 args = TREE_CHAIN (args);
27493 while (args != NULL_TREE);
27496 else
27497 gcc_unreachable ();
27499 return ret;
27502 /* Print out the target options as a list for -mdebug=target. */
27504 static void
27505 rs6000_debug_target_options (tree args, const char *prefix)
27507 if (args == NULL_TREE)
27508 fprintf (stderr, "%s<NULL>", prefix);
27510 else if (TREE_CODE (args) == STRING_CST)
27512 char *p = ASTRDUP (TREE_STRING_POINTER (args));
27513 char *q;
27515 while ((q = strtok (p, ",")) != NULL)
27517 p = NULL;
27518 fprintf (stderr, "%s\"%s\"", prefix, q);
27519 prefix = ", ";
27523 else if (TREE_CODE (args) == TREE_LIST)
27527 tree value = TREE_VALUE (args);
27528 if (value)
27530 rs6000_debug_target_options (value, prefix);
27531 prefix = ", ";
27533 args = TREE_CHAIN (args);
27535 while (args != NULL_TREE);
27538 else
27539 gcc_unreachable ();
27541 return;
27545 /* Hook to validate attribute((target("..."))). */
27547 static bool
27548 rs6000_valid_attribute_p (tree fndecl,
27549 tree ARG_UNUSED (name),
27550 tree args,
27551 int flags)
27553 struct cl_target_option cur_target;
27554 bool ret;
27555 tree old_optimize = build_optimization_node ();
27556 tree new_target, new_optimize;
27557 tree func_optimize = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl);
27559 gcc_assert ((fndecl != NULL_TREE) && (args != NULL_TREE));
27561 if (TARGET_DEBUG_TARGET)
27563 tree tname = DECL_NAME (fndecl);
27564 fprintf (stderr, "\n==================== rs6000_valid_attribute_p:\n");
27565 if (tname)
27566 fprintf (stderr, "function: %.*s\n",
27567 (int) IDENTIFIER_LENGTH (tname),
27568 IDENTIFIER_POINTER (tname));
27569 else
27570 fprintf (stderr, "function: unknown\n");
27572 fprintf (stderr, "args:");
27573 rs6000_debug_target_options (args, " ");
27574 fprintf (stderr, "\n");
27576 if (flags)
27577 fprintf (stderr, "flags: 0x%x\n", flags);
27579 fprintf (stderr, "--------------------\n");
27582 old_optimize = build_optimization_node ();
27583 func_optimize = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl);
27585 /* If the function changed the optimization levels as well as setting target
27586 options, start with the optimizations specified. */
27587 if (func_optimize && func_optimize != old_optimize)
27588 cl_optimization_restore (&global_options,
27589 TREE_OPTIMIZATION (func_optimize));
27591 /* The target attributes may also change some optimization flags, so update
27592 the optimization options if necessary. */
27593 cl_target_option_save (&cur_target, &global_options);
27594 rs6000_cpu_index = rs6000_tune_index = -1;
27595 ret = rs6000_inner_target_options (args, true);
27597 /* Set up any additional state. */
27598 if (ret)
27600 ret = rs6000_option_override_internal (false);
27601 new_target = build_target_option_node ();
27603 else
27604 new_target = NULL;
27606 new_optimize = build_optimization_node ();
27608 if (!new_target)
27609 ret = false;
27611 else if (fndecl)
27613 DECL_FUNCTION_SPECIFIC_TARGET (fndecl) = new_target;
27615 if (old_optimize != new_optimize)
27616 DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl) = new_optimize;
27619 cl_target_option_restore (&global_options, &cur_target);
27621 if (old_optimize != new_optimize)
27622 cl_optimization_restore (&global_options,
27623 TREE_OPTIMIZATION (old_optimize));
27625 return ret;
27629 /* Hook to validate the current #pragma GCC target and set the state, and
27630 update the macros based on what was changed. If ARGS is NULL, then
27631 POP_TARGET is used to reset the options. */
27633 bool
27634 rs6000_pragma_target_parse (tree args, tree pop_target)
27636 tree cur_tree;
27637 bool ret;
27639 if (TARGET_DEBUG_TARGET)
27641 fprintf (stderr, "\n==================== rs6000_pragma_target_parse\n");
27642 fprintf (stderr, "args:");
27643 rs6000_debug_target_options (args, " ");
27644 fprintf (stderr, "\n");
27646 if (pop_target)
27648 fprintf (stderr, "pop_target:\n");
27649 debug_tree (pop_target);
27651 else
27652 fprintf (stderr, "pop_target: <NULL>\n");
27654 fprintf (stderr, "--------------------\n");
27657 if (! args)
27659 ret = true;
27660 cur_tree = ((pop_target)
27661 ? pop_target
27662 : target_option_default_node);
27663 cl_target_option_restore (&global_options,
27664 TREE_TARGET_OPTION (cur_tree));
27666 else
27668 rs6000_cpu_index = rs6000_tune_index = -1;
27669 ret = rs6000_inner_target_options (args, false);
27670 cur_tree = build_target_option_node ();
27672 if (!cur_tree)
27673 ret = false;
27676 if (cur_tree)
27677 target_option_current_node = cur_tree;
27679 return ret;
27683 /* Remember the last target of rs6000_set_current_function. */
27684 static GTY(()) tree rs6000_previous_fndecl;
27686 /* Establish appropriate back-end context for processing the function
27687 FNDECL. The argument might be NULL to indicate processing at top
27688 level, outside of any function scope. */
27689 static void
27690 rs6000_set_current_function (tree fndecl)
27692 tree old_tree = (rs6000_previous_fndecl
27693 ? DECL_FUNCTION_SPECIFIC_TARGET (rs6000_previous_fndecl)
27694 : NULL_TREE);
27696 tree new_tree = (fndecl
27697 ? DECL_FUNCTION_SPECIFIC_TARGET (fndecl)
27698 : NULL_TREE);
27700 if (TARGET_DEBUG_TARGET)
27702 bool print_final = false;
27703 fprintf (stderr, "\n==================== rs6000_set_current_function");
27705 if (fndecl)
27706 fprintf (stderr, ", fndecl %s (%p)",
27707 (DECL_NAME (fndecl)
27708 ? IDENTIFIER_POINTER (DECL_NAME (fndecl))
27709 : "<unknown>"), (void *)fndecl);
27711 if (rs6000_previous_fndecl)
27712 fprintf (stderr, ", prev_fndecl (%p)", (void *)rs6000_previous_fndecl);
27714 fprintf (stderr, "\n");
27715 if (new_tree)
27717 fprintf (stderr, "\nnew fndecl target specific options:\n");
27718 debug_tree (new_tree);
27719 print_final = true;
27722 if (old_tree)
27724 fprintf (stderr, "\nold fndecl target specific options:\n");
27725 debug_tree (old_tree);
27726 print_final = true;
27729 if (print_final)
27730 fprintf (stderr, "--------------------\n");
27733 /* Only change the context if the function changes. This hook is called
27734 several times in the course of compiling a function, and we don't want to
27735 slow things down too much or call target_reinit when it isn't safe. */
27736 if (fndecl && fndecl != rs6000_previous_fndecl)
27738 rs6000_previous_fndecl = fndecl;
27739 if (old_tree == new_tree)
27742 else if (new_tree)
27744 cl_target_option_restore (&global_options,
27745 TREE_TARGET_OPTION (new_tree));
27746 target_reinit ();
27749 else if (old_tree)
27751 struct cl_target_option *def
27752 = TREE_TARGET_OPTION (target_option_current_node);
27754 cl_target_option_restore (&global_options, def);
27755 target_reinit ();
27761 /* Save the current options */
27763 static void
27764 rs6000_function_specific_save (struct cl_target_option *ptr)
27766 ptr->rs6000_target_flags_explicit = target_flags_explicit;
27769 /* Restore the current options */
27771 static void
27772 rs6000_function_specific_restore (struct cl_target_option *ptr)
27774 target_flags_explicit = ptr->rs6000_target_flags_explicit;
27775 (void) rs6000_option_override_internal (false);
27778 /* Print the current options */
27780 static void
27781 rs6000_function_specific_print (FILE *file, int indent,
27782 struct cl_target_option *ptr)
27784 size_t i;
27785 int flags = ptr->x_target_flags;
27787 /* Print the various mask options. */
27788 for (i = 0; i < ARRAY_SIZE (rs6000_opt_masks); i++)
27789 if ((flags & rs6000_opt_masks[i].mask) != 0)
27791 flags &= ~ rs6000_opt_masks[i].mask;
27792 fprintf (file, "%*s-m%s%s\n", indent, "",
27793 rs6000_opt_masks[i].invert ? "no-" : "",
27794 rs6000_opt_masks[i].name);
27797 /* Print the various options that are variables. */
27798 for (i = 0; i < ARRAY_SIZE (rs6000_opt_vars); i++)
27800 size_t j = rs6000_opt_vars[i].target_offset;
27801 if (((signed char *) ptr)[j])
27802 fprintf (file, "%*s-m%s\n", indent, "",
27803 rs6000_opt_vars[i].name);
27808 /* Hook to determine if one function can safely inline another. */
27810 static bool
27811 rs6000_can_inline_p (tree caller, tree callee)
27813 bool ret = false;
27814 tree caller_tree = DECL_FUNCTION_SPECIFIC_TARGET (caller);
27815 tree callee_tree = DECL_FUNCTION_SPECIFIC_TARGET (callee);
27817 /* If callee has no option attributes, then it is ok to inline. */
27818 if (!callee_tree)
27819 ret = true;
27821 /* If caller has no option attributes, but callee does then it is not ok to
27822 inline. */
27823 else if (!caller_tree)
27824 ret = false;
27826 else
27828 struct cl_target_option *caller_opts = TREE_TARGET_OPTION (caller_tree);
27829 struct cl_target_option *callee_opts = TREE_TARGET_OPTION (callee_tree);
27831 /* Callee's options should a subset of the caller's, i.e. a vsx function
27832 can inline an altivec function but a non-vsx function can't inline a
27833 vsx function. */
27834 if ((caller_opts->x_target_flags & callee_opts->x_target_flags)
27835 == callee_opts->x_target_flags)
27836 ret = true;
27839 if (TARGET_DEBUG_TARGET)
27840 fprintf (stderr, "rs6000_can_inline_p:, caller %s, callee %s, %s inline\n",
27841 (DECL_NAME (caller)
27842 ? IDENTIFIER_POINTER (DECL_NAME (caller))
27843 : "<unknown>"),
27844 (DECL_NAME (callee)
27845 ? IDENTIFIER_POINTER (DECL_NAME (callee))
27846 : "<unknown>"),
27847 (ret ? "can" : "cannot"));
27849 return ret;
27852 /* Allocate a stack temp and fixup the address so it meets the particular
27853 memory requirements (either offetable or REG+REG addressing). */
27856 rs6000_allocate_stack_temp (enum machine_mode mode,
27857 bool offsettable_p,
27858 bool reg_reg_p)
27860 rtx stack = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
27861 rtx addr = XEXP (stack, 0);
27862 int strict_p = (reload_in_progress || reload_completed);
27864 if (!legitimate_indirect_address_p (addr, strict_p))
27866 if (offsettable_p
27867 && !rs6000_legitimate_offset_address_p (mode, addr, strict_p))
27868 stack = replace_equiv_address (stack, copy_addr_to_reg (addr));
27870 else if (reg_reg_p && !legitimate_indexed_address_p (addr, strict_p))
27871 stack = replace_equiv_address (stack, copy_addr_to_reg (addr));
27874 return stack;
27877 /* Given a memory reference, if it is not a reg or reg+reg addressing, convert
27878 to such a form to deal with memory reference instructions like STFIWX that
27879 only take reg+reg addressing. */
27882 rs6000_address_for_fpconvert (rtx x)
27884 int strict_p = (reload_in_progress || reload_completed);
27885 rtx addr;
27887 gcc_assert (MEM_P (x));
27888 addr = XEXP (x, 0);
27889 if (! legitimate_indirect_address_p (addr, strict_p)
27890 && ! legitimate_indexed_address_p (addr, strict_p))
27892 if (GET_CODE (addr) == PRE_INC || GET_CODE (addr) == PRE_DEC)
27894 rtx reg = XEXP (addr, 0);
27895 HOST_WIDE_INT size = GET_MODE_SIZE (GET_MODE (x));
27896 rtx size_rtx = GEN_INT ((GET_CODE (addr) == PRE_DEC) ? -size : size);
27897 gcc_assert (REG_P (reg));
27898 emit_insn (gen_add3_insn (reg, reg, size_rtx));
27899 addr = reg;
27901 else if (GET_CODE (addr) == PRE_MODIFY)
27903 rtx reg = XEXP (addr, 0);
27904 rtx expr = XEXP (addr, 1);
27905 gcc_assert (REG_P (reg));
27906 gcc_assert (GET_CODE (expr) == PLUS);
27907 emit_insn (gen_add3_insn (reg, XEXP (expr, 0), XEXP (expr, 1)));
27908 addr = reg;
27911 x = replace_equiv_address (x, copy_addr_to_reg (addr));
27914 return x;
27917 #include "gt-rs6000.h"